Chapter 22 - Interface Library Routines

This chapter contains technical descriptions of the routines discussed in Chapters 12 “Files for Data and Output” and 14 “Interface Elements.” The routines are contained in three library files: TRUECTRL.TRC, TRUEDIAL.TRC, and EXECLIB.TRC. The routines in the TRUECTRL.TRC library all have names that begin with “TC_”. The routines in the TRUEDIAL.TRC library all have names that begin with “TD_”. The routines in the EXECLIB.TRC library all have names that begin with “EXEC_”. In addition, this chapter contains the descriptions of the routines provided for communications support. These routines are contained in the library file COMMLIB.TRC. The routines in the COMMLIB.TRC library all have names that begin with “Com_”. (The libraries COMLIB.TRU and COMLIB.TRC contains the same routines but with the traditional subroutine names.)

TRUECTRL.TRC contains routines for creating and manipulating objects and controls, including windows, menus, graphical objects, buttons and such, and text editors. These routines, known collectively as True Controls, provide easy access to the built-in subroutines Object and Sys_Event.

TRUEDIAL.TRC contains routines for creating and using modal dialog boxes. (Modal dialog boxes require a response before the program can continue.) Variations include dialog boxes for: issuing warnings, receiving input, file opening and file saving, and displaying a selection list. These routines, known collectively as True Dials, provide simple access to the built-in subroutine TBD.

EXECLIB.TRC contains routines for manipulating directories. The routines provide simple access to the built- in subroutine System.

COMMLIB.TRC contains routines supporting communication through the serial ports. The routines provide simple access to the built-in subroutines ComOpen and ComLib.

The source code for all four libraries is included. This lets you examine the detailed use of the built-in subroutines Object, Sys_Event, TBD, System, ComOpen, and ComLib, and it provides a starting point if you wish to write your own subroutines.

The rest of this chapter is organized by library. With each library, the routines are grouped according to function, and not alphabetically. (See the Index of True BASIC Constructs for an alphabetical list of all True BASIC statements, functions, subroutines, whether built-in or in a library.)

True Controls
The True Controls subroutines can be grouped into several categories including general routines that apply to all objects and controls as well as other routines that apply only to specific objects or controls.

Almost all subroutines that create objects or controls have the same calling sequence:
CALL TC_XXX_Create (id, type$, xl, xr, yb, yt)
If the creation is successful, the newly assigned ID number is returned in id. The argument type$ varies according to the object or control – it is either a string or a string array.

The four coordinates xl (x-left), xr (x-right), yb (y-bottom), and yt (y-top) specify (in almost all cases) the rectangular region in which the object or control is defined. Either pixel coordinates or window coordinates can be
352 True BASIC Language System

used. For pixel coordinates, the useful (client) area of the window will be placed with respect to the full screen. Graphics objects and controls will be placed with respect to the containing physical window.

User coordinates for placing windows can be used only in conjunction with the True Controls routines TC_Win_Create and TC_Win_ChildCreate. Here, the user coordinates behave like SCREEN coordinates in True BASIC; that is, 0 refers to the left and bottom edges, and 1 to the right and top edges, of the full screen. In addition, True Controls adjusts the client area so that all the embellishments (title bars, borders, etc.) are visible. User coordinates for placing graphical objects or controls refer to the window coordinates for the current logical window.

Pixel coordinates always have the (0,0) location at the top-left corner. The x value increases to the right. The y value increases down the window or screen. (This is the reverse of the usual True BASIC coordinate system in which the y value increases as you move up.)

The SET WINDOW statement establishes the user coordinates as follows:
SET WINDOW xleft, xright, ybottom, ytop
(Note that you may establish a coordinate system in which increasing y-values move down.) In the absence of a
SET WINDOW statement, the default coordinates are (0, 1, 0, 1).

Location of windows, graphical objects, other controls is in user coordinates, by default. If you prefer to use pixel coordinates, you can call the subroutine TC_SetUnitsToPixels.

Numerous errors can arise if windows, graphical objects, and other controls are improperly specified or located. These errors are of two types. Errors identified by the system subroutine Object are outlined at the end of Chapter
19 “Object Subroutine” and are not repeated here; in general they deal with such conditions as specifying an ID number that does not exist, or an invalid type or option. Other errors are detected and generated within the True Controls subroutines; these are included in this chapter.

General Purpose Subroutines
TC_Init
This routine “initializes” the event handler, allowing TC_Event to operate properly. There are no arguments to this subroutine.
CALL TC_Init
Exceptions: 800 Can’t call TC_Init during module startup.

TC_Cleanup
This routine must be called after completing all tasks that require TC_Event and before the program terminates. Failure to do so may leave the operating system in an inconsistent state. There are no arguments to this subroutine.
CALL TC_Cleanup

Exceptions: 800 Can’t call TC_Cleanup during module startup.

TC_Event
All activity generated through the use of windows and the various controls is reported to the program in the form of events. This subroutine returns the next event from the event queue.
CALL TC_Event (timer, event$, window, x1, x2)
Timer specifies the amount of time, in seconds, to wait for an event to occur if there is none on the event queue. If there is an event, or if timer = 0, the return from this subroutine will be immediate, except in the case of certain scrolling events arising from a text edit control.

Event$ contains the name of the event, which can be the null string. A complete list of events is given in Chapter
20 “Sys_Event Subroutine.” This current chapter describes the events appropriate for each type of object or control along with the convenience routines for that object or control.
Interface Library Routines

353

Window is a numeric variable that contains the ID number of the window in which the event occurred. The event can be a window event, or it can be an event associated with a control located in that window.

X1 and x2 provide additional information. In general, x2 will be the ID number of the control causing the event. In the case of a KEYPRESS event, x1 will be the ASCII code of the key.

In addition to merely returning the event produced by Sys_Event, TC_Event carries out certain routine tasks associated with the controls that have been created and the menus. The events and actions are as follows. Note that graphical objects, static text controls, and group box controls do not generate events.

MENU TC_Event returns the menu number in x1 and the item number in x2. In addition, if you have created a text edit control and notified True Controls of the menu equivalents for Cut, Copy, and Paste, TC_Event carries out these operations on the text edit control.

DOWN, UP, LEFT, RIGHT, PAGEDOWN, PAGEUP, PAGELEFT, PAGERIGHT, VSCROLL, HSCROLL, END VSCROLL, END HSCROLL
TC_Event carries out the appropriate scroll bar operation. If the scroll bar is associated with a text edit control, TC_Event moves the text accordingly.

CONTROL If an edit field has been deselected by means of a trap character (i.e., carriage
DESELECTED return,) TC_Event advances the focus to the next available edit field.

If a check box is being deselected, TC_Event changes the state of the check box.

If a radio button is being deselected, TC_Event change the state of the radio button. In addition, TC_Event returns the id number of the radio button group, not the id number of the button itself.

SIZE If a text edit control has been “attached” to the window, TC_Event also resizes the text edit control so that it continues to fill the window, and adjusts the scroll bar parameters accordingly.

TXE KEYPRESS If the character is an EOL, TC_Event updates the vertical scroll bar, if any.

TXE HSCROLL TC_Event initiates bookkeeping to keep track of text scrolling so it can properly
TXE VSCROLL update the scroll bars, if any, at the end of the text scrolling. While the text is being scrolled, i.e., while TXE HSCROLL or TXE VSCROLL keeps occurring, TC_Event keeps looping, so that these events are never actually returned by TC_Event.

TC_Set
This general purpose subroutine lets you specify or “set” the value(s) of any attribute(s) defined for the object or control whose ID is given.
CALL TC_Set (id, attributes$, value$, values())
The second argument must be a string expression that contains the attribute names, separated by vertical bars (|). The third and fourth arguments contain the string values and the numeric values required by the attributes, in the same order as the attribute names themselves. Multiple string values are separated by vertical bars. Multiple numeric values appear in consecutive entries in the list values(). The lowest subscript of the list must be 1, and the list must be dimensioned large enough to contain all the numeric attribute values expected.

This calling sequence is similar to that described in Chapter 19 “Object Subroutine” for use with the OBJM_SET method. If id does not refer to an existing object or control, or if an attribute name is invalid for that type of object or control, or if it is not possible to set the value of an attribute, an error occurs. See Chapter 19 for details.
354 True BASIC Language System

TC_Get
This general purpose subroutine lets you obtain or “get” the value(s) for any attribute(s) defined for the object or control whose ID is given.
CALL TC_Get, (id, attributes$, value$, values())
The second argument must be a string expression that contains the attributes names, separated by vertical bars (|). The third and fourth arguments contain the current values, string or numeric, of the attributes, in the same order as the attribute names themselves. Multiple string values are separated by vertical bars. Multiple numeric values appear as consecutive values in the numeric list. The lowest subscript of the list is 1, and the list values() is redimensioned to the exact size needed.
This calling sequence is similar to that described in Chapter 19 “Object Subroutine” for use with the OBJM_GET method. If id does not refer to an existing object or control, or if an attribute name is invalid for that type of object or control, an error occurs. See Chapter 19 for details.

TC_GetSysInfo
This subroutine provides a simpler interface to the OBJM_SYSINFO method with the built-in Object subroutine.
CALL TC_GetSysInfo (attribute$, value$, values())
For any valid attribute, the attribute values, string or numeric, will be returned. For details on valid attribute names, see Chapter 19 “Object Subroutine.”

TC_Erase
This routine hides (erases or makes invisible) any True Controls object or control. It should be called with the ID
number of the object or control to be erased. The statement:
CALL TC_Erase (id)
will erase the object or control whose ID is specified.
Remember that erasing (making invisible) a window also makes all graphics objects and controls contained within it not visible. All contained objects and controls that were visible will again become visible when the window is made visible again.

TC_Show
This routine reveals (shows or makes visible) any window, graphics object, or control. It should be called with the
ID number of the object or control to be shown, as follows:
CALL TC_Show (id)
Remember that the window must be visible for the graphics objects and controls contained within it to be visible.

TC_Show_Default
CALL TC_Show_Default (flag)
Calling this routine with flag = 0 specifies that subsequently created graphics objects and controls will not automatically be shown upon creation. Calling this routine with flag = 1 specifies that they will be shown or displayed. Remember that the visibility of a window overrides the visibility of any control. Therefore, showing a control will not make it visible unless the containing window is also shown. Remember also that the value of the show-default flag does not affect windows; windows must be specifically shown using:
CALL TC_Show (wid)

TC_Select
CALL TC_Select (id)
This subroutine allows selecting selectable controls: push buttons, radio buttons, check boxes, edit fields, list edit buttons, and text edit controls. When applied to an edit field or a text edit control, that control becomes active and
Interface Library Routines

355

absorbs keystrokes. When applied to a push button, that button is selected and will be deselected when the Enter or Return key is pressed. When applied to a radio button or a check box, the result will be as if the user clicked on the button or box. A SELECT or CONTROL SELECT event will be generated as well. This operation may have no effect if the containing window hasn't been shown for the first time. (This routine is an interface to the SELECT method; see Chapter 19 “Object Subroutine.”)

This routine cannot be used for windows. Instead use TC_Win_Switch, TC_Win_Active, or TC_Win_Target.

TC_Sensitize
CALL TC_Sensitize (id, flag)
If flag = 0, the control will be desensitized; that is, it will not respond to mouse clicks, etc. If flag = 1, the control will be made sensitive. If id does not refer to a control that can be made sensitive, no action will occur and no error will result.

TC_Free
CALL TC_Free (id)
This subroutine is the opposite of a “create” subroutine; it deletes the object or control, and frees all internal memory formerly associated with it. The ID number becomes invalid, although it may reappear in a subsequent “create” operation.

Freeing a window will free all menus and controls associated with it.

This routine should not be used to free an entire menu structure; there is a special subroutine for that purpose
(see TC_Menu_Free, later.)

TC_SetUnitsToPixels
TC_SetUnitsToUsers
Calling one of these routines tells True Controls what units to use in placing windows on the screen, and controls and graphics objects within windows. The units remain in effect until changed by a call to the other routine.

When True Controls creates a new physical window it also opens a logical window within it whose default user coordinates are (0, 1, 0, 1).

TC_PixToUser
TC_UserToPix
Controls and graphics objects can be placed within windows in either the pixel coordinates of the physical window or user coordinates specified by the programmer. All True BASIC graphical output (PLOT, BOX LINES, etc.) are placed in user coordinates. These two routines transform one set of coordinates into the other.
CALL TC_PixToUser (px, py, wx, wy)
will convert the pixel point (px,py) into the user-coordinates point (wx,wy).
CALL TC_UserToPix (wx, wy, px, py)
will convert the user point (wx,wy) into the pixel-coordinates point (px,py).

Warning: when using either of these routines, it is imperative that control be in the correct logical windows. If the logical window is the default logical window within a physical window, this can be assured by using
CALL TC_Win_Target (mywin)
If the logical window is one that you created using the OPEN SCREEN statement, this can be assured by using
WINDOW #n
356 True BASIC Language System

TC_SetRect
Normally, objects and controls are placed on the screen or in the physical window upon creation. But the program can move them around dynamically by re-specifying their location coordinates. If cid is the ID of a control, then
CALL TC_SetRect (cid, newxl, newxr, newyb, newyt)
will move that control to a new location in the window. If cid is the ID of a window, then calling this routine will move the window to a new location on the screen.

Warning: this routine makes no assumptions about the UNITS being used to locate a window or control. If the object is a window, the four values will be taken to be pixel coordinates of the full screen. If the object is a control or graphics object, the four values will be taken to be in whatever the current UNITS of the object or control. Furthermore, to use user coordinates, you must make sure you are in the correct logical window; otherwise, True BASIC will take the window coordinates of the current logical window to figure the new location of the object or control.

TC_GetRect
CALL TC_GetRect (cid, xl, xr, yb, yt)

This routine finds the current location, in pixels, of a window, graphics object, or control on the screen or within the containing window. As an example, if you want to move a control 10 pixels up and to the right, and if the control was placed originally using pixel coordinates, you might use:
CALL TC_GetRect (cid, xl, xr, yb, yt)
CALL TC_SetRect (cid, xl+10, xr+10, yb-10, yt-10)
Remember that in pixel coordinates smaller y values are closer to the top of the screen.

If the control or graphics object was placed originally using user coordinates, the procedure is more complicated. Suppose you want to move a control 0.1 user units up and to the right. You first must make sure you are in the correct logical window. This you must convert 0.1 into a certain number of pixels. Finally, you can now move the control. The following code illustrates these steps:

CALL TC_Win_Target (mywin) ! Only one of this statement WINDOW #n ! and this statement is needed. CALL TC_UserToPix (0, 0, x1, y1)
CALL TC_UserToPix (.1, .1, x2, y2) LET xdelta = x2 - x1
LET ydelta = y2 - y1
CALL TC_GetRect (cid, xl, xr, yb, yt)
CALL TC_SetRect (cid, xl+xdelta, xr+xdelta, yb+ydelta, yt+ydelta)
Note: since pixels coordinates increase from top to bottom, ydelta will probably be negative.

Two other routines, TC_SetRectUsers and TC_SetRectPixels, can be used to bypass the UNITS setting of the object or control. (Windows have no such setting; their location internally is always in pixels.)

Warning: as suggested in the description of TC_SetRect, use of the TC_GetRect subroutine is for expert use only;
strange results can occur if misused.

TC_SetRectUsers
TC_SetRectPixels
CALL TC_SetRectUsers (cid, newxl, newxr, newyb, newyt) CALL TC_SetRectPixels (cid, newxl, newxr, newyb, newyt)
These two routines are similar to TC_SetRect, except that they bypass the current value of the UNITS setting. That is, if user units were in effect upon the creation of the graphical object or control, then True BASIC will assume you mean user coordinates if you use TC_SetRect. If you need to use pixel coordinates for some special purpose, you can use TC_SetRectPixels. This routine first sets the UNITS to pixels coordinates, changes the location, and then sets the UNITS back to their original setting.
Interface Library Routines

357

TC_SetRectUsers behaves similarly.

If you use TC_SetRectUsers to locate a new position for a window, the routine will convert from screen coordinates to pixel coordinates, and then relocate the window. However, no attempt will be made to make sure the window embellishments are entirely visible.

Warning: use of these two routines is for special purposes only. Misuse can result in strange behavior.

TC_SetText
CALL TC_SetText (id, text$)

This subroutine can be used with any control that allows setting the text – edit fields, static text fields, push buttons, check boxes, individual radio buttons, and text edit controls. (Edit fields and text edit controls also have similar routines that do the same thing. If you use this routine for a text edit control, the scroll bars will not be adjusted.)

TC_GetText
CALL TC_GetText (id, text$)

This subroutine can be used with any control that allows retrieving the text – edit fields, static text fields, push buttons, check boxes, and text edit controls. (Edit fields and text edit controls also have similar routines that do the same thing.)

TC_SetTextJustify
CALL TC_SetTextJustify (cid, justify$)

This subroutine alters the text justification for any control that permits it. The permissible values of justify$ are: “LEFT”, “CENTER”, and “RIGHT”. Case doesn’t matter. To have an effect, this routine must be called before the control is shown the first time. Furthermore, setting the justification may work only for static text boxes; certain operating systems might also allow justification for push buttons, check boxes, and rodir buttons.
Exception: 801 Invalid text justify option: ooooo

TC_SetList
CALL TC_SetList (cid, text$())
This routine can be used to set (or re-set) the list of a list button, a list edit button, or a list box. The subscript lower bound of text$() must be 0 or 1. If used to set the text of a list edit button, the 0-th entry, if any, will be used to set the contents of the list edit button itself.

TC_FontsAvailable
This subroutine returns the names of the fonts available on the current computer system.
CALL TC_FontsAvailable (fonts$())
will return the names, in the string list fonts$(), of the fonts currently available on the system.

TC_GetScreenSize
CALL TC_GetScreenSize (left, right, bottom, top)
This subroutines gives the size of the full screen in pixels. Specifically, left is the leftmost pixel, which is always numbered 0. Right is the rightmost pixel, which is always positive. Bottom is the bottom-most pixel, which is always positive. And top is the topmost pixel, which is always 0.

The number of horizontal pixels is right - left + 1, or simply right+1, since left = 0. The number of vertical pixels is bottom - top + 1, or simply bottom+1, since top = 0.
358 True BASIC Language System

TC_Env_Set
This subroutine can be used only on Unix machines! On Unix machines:
CALL TC_Env_Set (attribute$, value$)
will set the environmental attribute named to the value specified. If used with non-Unix systems, an error will occur.

Window Subroutines
TC_Win_Create
CALL TC_Win_Create (wid, options$, xl, xr, yb, yt)
creates a physical window. The rectangular coordinates do not define the outer dimensions of the window, but rather the interior portion of the window available to the user; this interior portion is known as the client area.. If you are using pixel coordinates (see TC_SetUnitsToPixels,) the actual placement of the window may depend on the operating system. Suppose you specify a rectangle that forces some portion of the window, either the client area or the embellishments, to be off the screen. On Windows, the size of the client area may be diminished so that the total size of the window, including embellishments, is no larger than the viewing screen, although the window may be offset. On the Macintosh, the client area will not be diminished, and could be partly or entirely off the screen.

If you are using True BASIC screen coordinates (see TC_SetUnitsToUsers,) True Controls will adjust the size and position of the client area, if necessary, so that it and all the embellishments (title bars, borders, etc.) will be visible on the screen. The screen coordinates are interpreted relative to the full screen.

Window number 0 is always created by the system and placed in a central location on the screen. It will be shown (i.e., made visible) upon a call to TC_Show with argument 0, or upon the first True BASIC output statement (PRINT or PLOT for example, but not CLEAR.)

The option$ string may be a string variable or a string expression. This string will contain a sequence of words that will specify certain aspects of the window. The words may be in uppercase, lowercase, or mixed case, and they may be separated by spaces or vertical bars (|). The options are as follows:
TITLE A title bar will be created. SIZE A resize box will be created. CLOSE A close box will be created.
SHOW The window will be shown upon its creation HSCROLL A horizontal scroll bar will be attached. VSCROLL A vertical scroll bar will be attached.
BORDER FULL The window will have a full border, and can have a title bar, close box, and resize box (default).
BORDER SINGLE The window will have a single-line border, and cannot have a title bar, etc. An error may occur on some systems.
BORDER DOUBLE The window will have a double-line border, and cannot have a title bar, etc. An error may occur on some systems.
IMMUNE The window will be an immune window (default).
NONIMMUNE The window will not be an immune window.
ICONIZABLE The window can be made into an icon on those platforms that allow it. Also, “BORDER FULL” windows may automatically have a title bar on some systems.
Windows are not shown as they are created unless the “SHOW” option is included. You can always show a window with:
CALL TC_Show (wid)
Interface Library Routines

359

Exceptions: 802 Can’t have BORDER NONE for a regular window.
802 Can’t specify two or more border types.
802 Can’t have features in non-document windows.
803 Can’t create a child window with this routine.

TC_Win_ChildCreate
CALL TC_Win_ChildCreate (wid, options$, pwid, xl, xr, yb, yt)
creates a physical window that is a child window to the parent window identified by pwid. The properties of child windows may vary across systems. For example, on the Macintosh, a child window will always be in front of (i.e., active) relative to its parent.

The placement of child windows is always relative to the client area of the parent window. The child window will be clipped at the edges of the parent window.

The rectangular coordinates do not define the outer dimensions of the window, but rather the interior portion of the window available to the user; this interior portion is known as the client area.. If you are using pixel coordinates (see TC_SetUnitsToPixels,) the actual placement of the window may depend on the operating system. Suppose you specify a rectangle that forces some portion of the window, either the client area or the embellishments, to be outside the parent window. On Windows, the size of the client area may be diminished so that the total size of the window, including the border, is no larger than the viewing screen, although the window may be offset. On the Macintosh, the client area will not be diminished, and could be partly or entirely off the screen.

If you are using True BASIC screen coordinates (see TC_SetUnitsToUsers,) True Controls will adjust the size and position of the client area, if necessary, so that it and its border, if any, will be visible in the parent window. The screen coordinates will be interpreted relative to the client area of the parent window.

The option$ string may be a string variable or a string expression. This string will contain a sequence of words that will specify certain aspects of the child window. The words may be in uppercase, lowercase, or mixed case, and they may be separated by spaces or vertical bars (|). The options are as follows:

BORDER SINGLE The child window will have a single-line border.

BORDER NONE The child window will have no border.

SHOW The window will be shown upon its creation, provided the parent window is visible.

IMMUNE The child window will be an immune window (default).

NONIMMUNE The child window will not be an immune window.

Windows are not shown as they are created unless the “SHOW” option is included. You can always show the window with:

CALL TC_Show (wid)
Exceptions: 802 Can’t specify two or more border types.
804 Must specify type of border.
804 Child window must have BORDER SINGLE or BORDER NONE.
804 Can’t have embellishments on child windows.

TC_Win_Target
This subroutine directs output to a specific physical window. The statement:

CALL TC_Win_Target (wid)
will direct subsequent output to physical window whose ID is given. Calling this subroutine will not affect either the window’s visibility or, if visible, its placement (front and back) on the screen.
360 True BASIC Language System

To direct output to a specific logical window within the physical window, the call to TC_Win_Target should be followed by a True BASIC WINDOW statement; otherwise, output will be directed to the default logical window that fills the physical window. If the desired logical window was created using an OPEN SCREEN statement, then it is necessary only to use a True BASIC WINDOW statement; the call to TC_Win_Target may be omitted.

Exception: 805 Can’t make this window the target: nnn

TC_Win_Active
CALL TC_Win_Active (wid)
This subroutine can be used to move a visible window to the front position on the screen. Calling it has no effect on where the output is directed.

Exception: 806 Can’t make this window active: nnn
TC_Win_Switch
CALL TC_Win_Switch (wid)
This subroutine will both direct output to the physical window specified and, if the window is visible, move it to the front of the screen; it combines the actions of TC_Win_Target and TC_Win_Active.
Exception: 807 Can’t switch to this window: nnn

TC_Win_SwitchCurrent
CALL TC_Win_SwitchCurrent
This subroutine switches to the logical window that fills the currently-targeted physical window. You cannot use a WINDOW statement because this logical window’s number is hidden. If you know the window ID of the currently-targeted window, you can also use:
CALL TC_Win_Switch (wid)

TC_Win_NoHide
CALL TC_Win_NoHide (wid, flag)
Normally, when the user clicks on the close box of a window and TC_Init has been called, True BASIC erases the window but doesn’t stop running the program. Calling this routine with flag = 1 will prevent this automatic erasing. Calling it with flag = 0 will restore the default situation.

TC_Win_MouseMove
CALL TC_Win_MouseMove (wid, flag)
This subroutine is used to activate or inhibit (default) the mouse move event in a particular window. If flag = 0, mouse move events will be inhibited (i.e., not be returned by TC_Event); if flag = 1, mouse move events will be generated (i.e., returned by TC_Event).
The mouse move event is “MOUSE MOVE”. It can be used to track the mouse within a given window. Alternatively, the True BASIC statement GET MOUSE can also be used.

TC_Win_Valid
TC_Win_Valid (wid)
Calling this subroutine will be a “no operation” if the window ID wid refers to an existing window. If the window
ID is not valid, an error will occur.
Exception: 808 Illegal window number: nnn
Interface Library Routines

361

TC_Win_SetTitle
If the window has previously been created with a “BORDER FULL” and “TITLE” options, this subroutine should be used to set the title.
CALL TC_Win_SetTitle (wid, “My New Window”)
The title of a visible window can be changed at any time, and takes effect immediately.

TC_Win_GetTitle
This subroutine finds the current title of a window as follows:
CALL TC_Win_GetTitle (wid, title$)

TC_Win_SetCursor
This subroutine sets the type of cursor to be used with the window.
CALL TC_Win_SetCursor (wid, cursor$)
The cursor type can be “ARROW”, “IBEAM”, “CROSS”, “PLUS”, “WAIT”, and “USER”. The system will then show the I-beam when the mouse position is inside the edit field or text editor, but will show in another form when the mouse is outside. (Note: Type “USER” is not yet implemented.)
Exception: 809 Invalid cursor shape: ccccc

TC_Win_SetPen
CALL TC_Win_SetPen (wid, width, color, style$, pattern$)
This subroutine sets certain attributes of the pen for the window. These include: the pen width, the pen color, the pen style, and the pen pattern. Attributes will not be changed if the arguments to this subroutine are < -2 (if numeric) or the null string (if string).

The pen width is specified in pixels. The default is one pixel.

The pen color is specified by an index into the current color mix table (see Chapter 13 “Graphics”). The default color is -1 (black.)

The pen style must be one of:
“SOLID” Solid line (default) “DOT” Dotted line “DASH” Dashed line
The pen pattern must be one of:
“SOLID” Solid (default)
“HOLLOW” The line traced by the pen is invisible
“RUBBER” Small dashed lines that move on some systems.

There are several restrictions on combinations of width, style, and pattern. If the width is one pixel, then styles DOT and DASH override the pattern, making it SOLID. If the width is greater than one pixel, then style SOLID and pattern SOLID override. In other words, DOT, DASH, and RUBBER can only happen with one-pixel pens. And the style setting overrides the pattern setting.

For example:
CALL TC_Win_SetPen (0, 1, 4, “DOT”, “”)
will set the pen in the standard output window to width one pixel, color 4 (usually red), and style dotted.
Exception: 810 Invalid window pen setting.
362 True BASIC Language System

TC_Win_SetBrush
CALL TC_Win_SetBrush (wid, backcolor, color, pattern$)
This subroutine controls the color and pattern for the brush, as well as the background color for both the pen and the brush.

The background color refers to the current color mix table. If backcolor is < -2, the current background color will not be changed. The default background color is -2 (white.)
The brush color, like the pen color, refers to the color mix table. If color is < -2, the current brush color will not be changed. The default color is -1 (black.)
The brush pattern must be one of: “SOLID” (default) “HOLLOW”
“HORIZ” “VERT” “FDIAG” “BDIAG” “CROSS” “DIAGCROSS”

For example,
CALL TC_Win_SetBrush (0, 3, -1, “diagcross”)
will change the background color for the standard output window to color number 3, and will set the brush to a diagonal crosshatch pattern. Note: the background color will not take effect immediately, but only after a CLEAR or similar operation.
Exception: 811 Invalid window brush setting.

TC_Win_RealizePalette
CALL TC_Win_RealizePalette (wid)
Calling this subroutine causes True BASIC to add to the system color mix table those entries in the True BASIC color mix table that are not already there. This may eliminate “dithering” on some systems. (Dithering occurs when there isn’t an exact match in the system color mix table corresponding to the color desired. The system may then attempt to construct the desired color by mixing two or more of the existing colors in its color mix table. This process is called dithering.)

TC_Win_SetDrawmode
CALL TC_Win_SetDrawmode (wid, mode$)
The string values allowed for mode$ are as follows; note that where there is a space in the string, there must be exactly one space:
“COPY” ignore current contents, draw over anything that is there (default)
“OR” perform bitwise OR between bit plans of each currently displayed pixel and the new pixel which is to overlay it
“XOR” perform bitwise XOR between bit plans of each currently displayed pixel and the new pixel which is to overlay it
“CLEAR” clear the screen to the extent covered by the item being drawn
“NOT COPY” the bitwise negation of COPY “NOT OR” the bitwise negation of OR “NOT XOR” the bitwise negation of XOR “NOT CLEAR” the bitwise negation of CLEAR
Interface Library Routines

363

The drawing mode determines how the window’s pen and brush interact with the background, including what has already been drawn. As an example, assume there are four bit planes (i.e., there are sixteen entries in the color map table), the background is color 6 (binary 0110), and the pen is color 10 (binary 1010). Then the above drawing modes would give the following results for each pixel covered by the pen:

“COPY” Color 10 (binary 1010) “OR” Color 14 (binary 1110) “XOR” Color 12 (binary 1100) “CLEAR” Color 0 (binary 0000) “NOT COPY” Color 5 (binary 0101) “NOT OR” Color 1 (binary 0001) “NOT XOR” Color 3 (binary 0011) “NOT CLEAR” Color 15 (binary 1111)

Exception: 812 Invalid window drawmode setting.
Something similar may operate for a larger number of bit planes, and will sometimes yield strange-looking results. But the modes “COPY” and “CLEAR” should work as expected. And “XOR” should have the property that, if you draw the object twice, you will get back the original background.

TC_Win_SetFont
CALL TC_Win_SetFont (window, fontname$, fontsize, fontstyle$)
This subroutine sets certain attributes of the font used in PRINT statements. The fontname$ must be a legal font name; the names “Helvetica”, “Fixed”, “Times”, and “System” will always be legal.
The fontsize is given in points, which are approximately 1/72 of an inch. (How big the font is on the screen will depend on the characteristics of the monitor.)
The fontstyle$ may be one of “Plain”, “Bold”, “Italic”, or “Bold Italic”.
The font name and font style may be given in uppercase, lowercase, or mixed case.
If fontsize is a negative number, the font size will not be changed. If fontname$ or fontstyle$ is the null string, then it will not be changed.
For example:
CALL TC_Win_SetFont (0, “Fixed”, 10, “Bold”)
will set the printing font for the standard output window to 10 point fixed (nonproportional) bold. The Fixed font is usually something like Courier.
Exceptions: 813 Invalid window font name: nnnnn
814 Invalid window font size: sss
815 Invalid window font style: sssss

If you have included attached scroll bars, the following twelve routines can be used to manipulate them. They operate the same as the corresponding routines for scroll bars that are not attached to windows.

TC_WinHSBar_SetPosition
CALL TC_WinHSBar_SetPosition (wid, position)
This subroutine sets the position of the slider (the thumb) of an attached horizontal scroll bar. The position is defined in terms of the scrollbar parameters srange, erange, and prop. If the position is <= srange, the slider will be moved to the left of the scroll bar. If the position is >= erange - prop, the slider will be moved to the right of the scroll bar. If the position is in between, the slider will be moved to the corresponding location. The default value is 0.
364 True BASIC Language System

TC_WinVSBar_SetPosition
CALL TC_WinVSBar_SetPosition (wid, position)
This subroutine sets the position of the slider (the thumb) of an attached vertical scroll bar. The position is defined in terms of the scrollbar parameters srange, erange, and prop. If the position is <= srange, the slider will be moved to the top of the scroll bar. If the position is >= erange - prop, the slider will be moved to the bottom of the scroll bar. If the position is in between, the slider will be moved to the corresponding location. The default value is 0.

TC_WinHSBar_GetPosition
CALL TC_WinHSBar_GetPosition (wid, position)
This subroutine finds out the current location of an attached horizontal scroll bar slider. The current position must be interpreted in terms of the scrollbar parameters srange, erange, and prop.

TC_WinVSBar_GetPosition
CALL TC_WinVSBar_GetPosition (wid, position)
This subroutine finds out the current location of an attached vertical scroll bar slider. The current position must be interpreted in terms of the scrollbar parameters srange, erange, and prop.

TC_WinHSBar_SetRange
CALL TC_WinHSBar_SetRange (wid, srange, erange, prop)
This subroutine is used to set the scrollbar parameters that specify the extreme positions of the slider for an attached horizontal scroll bar, as well as the proportional size of the slider on those systems that provide for varying-sized sliders.

These parameters are arbitrary. The relation to the position (and size of the slider on certain systems) is as follows: When the slider is at the left, its position is equal to srange. When the slider is at the right, its position is equal to erange - prop. On certain systems, the size of the slider relative to the size of the slider trough (the region in which the slider moves) is given by prop/(erange - srange), but it is never greater than one. The default values are 0, 100, and 1, respectively.

TC_WinVSBar_SetRange
CALL TC_WinVSBar_SetRange (wid, srange, erange, prop)
This subroutine is used to set the scrollbar parameters that specify the extreme positions of the slider for an attached vertical scroll bar, as well as the proportional size of the slider on those systems that provide for varying sized sliders.

These parameters are arbitrary. The relation to the position (and size of the slider on certain systems) is as follows: When the slider is at the top its position is equal to srange. When the slider is at the bottom, its position is equal to erange - prop. On certain systems, the size of the slider relative to the size of the slider trough (the region in which the slider moves) is given by prop/(erange - srange), but never greater than one. The default values are 0, 100, and 1, respectively.

TC_WinHSBar_GetRange
CALL TC_WinHSBar_GetRange (wid, srange, erange, prop)
This subroutine finds out the current values of the scrollbar parameters for an attached horizontal scroll bar.

TC_WinVSBar_GetRange
CALL TC_WinVSBar_GetRange (wid, srange, erange, prop)
This subroutine finds out the current values of the scrollbar parameters for an attached vertical scroll bar.
Interface Library Routines

365

TC_WinHSBar_SetIncrements
CALL TC_WinHSBar_SetIncrements (wid, single, page)
This subroutine is used to set the scrollbar increments for an attached horizontal scroll bar. The single increment defines how far the slider (thumb) moves when the user clicks in the left-arrow or right-arrow boxes at the ends of the scroll bar. The page increment defines how far the slider moves when the user clicks in the gray area either left or right of the slider. The default values are 1 and 10, respectively.

The actual movement of the slider is in terms of the parameters (see TC_WinHSBar_SetRange for details.)

TC_WinVSBar_SetIncrements
CALL TC_WinVSBar_SetIncrements (wid, single, page)
This subroutine is used to set the scrollbar increments for an attached vertical scroll bar. The single increment defines how far the slider (thumb) moves when the user clicks in the up-arrow or down-arrow boxes at the ends of the scroll bar. The page increment defines how far the slider moves when the user clicks in the gray area either above or below of the slider. The default values are 1 and 10, respectively.
The actual movement of the slider is in terms of the parameters (see TC_WinVSBar_SetRange for details.)

TC_WinHSBar_GetIncrements
CALL TC_WinHSBar_GetIncrements (wid, single, page)
This subroutine finds out the current values of the increments for an attached horizontal scroll bar.

TC_WinVSBar_GetIncrements
CALL TC_WinVSBar_GetIncrements (wid, single, page)
This subroutine finds out the current values of the increments for an attached vertical scroll bar.

TC_Win_PageSetup
CALL TC_Win_PageSetup (wid)
This subroutine causes a page setup dialog box to be displayed. The properties specified then apply to all printing that takes place from that window, or printing to a file that occurs while that window is the target window.

TC_Win_Print
CALL TC_Win_Print (wid)
This subroutine prints the contents of the window, including graphics, to the current printer. Note: printed text can be sent directly to the printer by first OPENing the printer, as in
OPEN #1: printer
and then using the PRINT statement, as in
PRINT #1: ...

The text will be printed in the font type, size, style, and color of the currently targeted physical window.

TC_Win_Update
CALL TC_Win_Update (wid, left, right, bottom, top)
This subroutine will update the contents of the window specified, or a sub-portion thereof. Generally, you will not need to use this process if you are using immune windows.
366 True BASIC Language System

Menu Subroutines
TC_Menu_Set
CALL TC_Menu_Set (wid, menu$(,))
This subroutine sets, or resets, the menus for the given window. The rows of the menu$ matrix correspond to the menus. They must be numbered starting with 0 or 1. (At present, the 0-th row is ignored.) The columns of the menu$ matrix correspond to the menu items. They must be numbered starting with 0.
The entries in the menu matrix are the words that are displayed in the menu header and in the individual menus. The 0-th column gives the menu header names. The remaining columns give the menu item names.

When the event handler TC_Event returns an event of type MENU, the menu and item numbers are also returned; they refer to the original menu$(,) matrix.

The number of columns in menu$(,) must be large enough to contain the longest menu. For shorter menus, the remaining entries should consist of the null string.

The words that form the menu header and the menu items are displayed exactly as provided by the menu$(,) matrix. (The words may be changed at any time by calling the subroutine TC_Menu_SetText.) They may contain any letters or other characters, except the at-sign “@”, which has special meanings.

If a menu item consists of “@” alone, a dashed-line separator will appear in that position. If the final two characters of a menu item consist of “@” followed by a letter, that letter will be used as a hot-key alternative for activating the menu. (The conventions differ on different platforms. For Windows and OS/2, the letter following the “@” must be contained within the menu item itself. When the menu is displayed, that letter will be underlined.)

Hierarchical menus can also be constructed. First, remember that all menus, hierarchical or not, occupy a single row in the menu$(,) matrix. The hierarchical part is indicated as follows: The last two characters of the parent menu item consist of the sequence “@@”. And the menu header (the entry in the 0-th column of menu$(,)) must start with a single “@” but then contain the same word as the parent. For example, if “Color” is to be the start of a hierarchical menu, it should appear as “Color@@”. Correspondingly, at a later row in the menu$(,) matrix, there must be a menu header that appears as “@Color”.

Note that although the menus will appear on the screen as hierarchical menus, you will treat them simply as rows and columns in the menu$(,) matrix.

You can specify platform-dependent menu items. The following example illustrates this use:
MAT READ menus$(2, 0 to 3)
DATA |MAC|File|OTHER|File@F|, Open@O, Save@S, |MAC|Quit@Q|OTHER|Exit@X| DATA |MAC|Edit|OTHER|Edit@E|, |MAC|Cut@X|OTHER|Cut@T|, Copy@C, |MAC|Paste@V|OTHER|Paste@P|
Acceptable platform names are MAC, WIN32, OS/2, and UNIX. WIN32 refers to all Windows platforms: Windows
3.1 with Win32s, Windows 95, and Windows NT.

Exceptions: 820 Lower bound for menu$ rows must be 0 or 1.
821 Lower bound for menu$ columns must be zero.
822 Menu$ array must have elements.
823 Don’t recognize menu item: iiiii
824 Can’t find parent menu: ppppp

TC_Menu_AddItem
CALL TC_Menu_AddItem (wid, menu, text$)
This subroutine adds a menu item at the end of an existing menu. The new menu item may be a separator, or may have a hot-key equivalent. But such an item cannot be the start of a new hierarchical menu.

Note that the added menu item does not appear in your original menu$(,) matrix. You must therefore be careful when using this subroutine. Furthermore, if you wish to change a menu item in the middle of a menu, it will be
Interface Library Routines

367

much safer to delete the entire menu structure, make the changes in the menu$(,) matrix, and then call
TC_Menu_Set afresh.

Exceptions: 825 Menu or item number must not be negative.
826 To add a menu item, menu must already exist.
827 Added menu item cannot be hierarchical.

TC_Menu_DelItem
CALL TC_Menu_DelItem (wid, menu, item)
This subroutine deletes a specific menu item from a menu. However, TC_Event will report menu events in terms of the row and column of the original menu$(,) matrix. So, you must be quite careful when using this subroutine. It would be much safer to delete the entire menu structure, make the changes in the menu$(,) matrix, and then call TC_Menu_Set afresh.

TC_Menu_AddMenu
CALL TC_Menu_AddMenu (wid, menu$())
This subroutine is used to add an entirely new menu onto the end of the current menu structure. The new menu is given in the list menu$(), which must have a 0-th entry to contain the menu header. This subroutine will normally be used to add a special menu, one that will later be deleted.

TC_Menu_DelMenu
CALL TC_Menu_DelMenu (wid)
This subroutine will delete the last menu of the menu structure. Used in conjunction with TC_Menu_AddMenu, this subroutine will delete a special menu previously added.

TC_Menu_SetText
CALL TC_Menu_SetText (wid, menu, item, newtext$)
This subroutine changes the word or text that appears in the given menu position. The new word cannot contain a
“@”; in other words, separators, hot keys, and hierarchical menus cannot be specified with this subroutine.
Exception: 828 Invalid window, id, menu, item combination.

TC_Menu_GetText
CALL TC_Menu_GetText (wid, menu, item, text$)
This subroutine returns the word or text that appears in the given menu position.
Exception: 828 Invalid window, id, menu, item combination.

TC_Menu_SetCheck
CALL TC_Menu_SetCheck (wid, menu, item, flag)
This subroutine sets, or unsets, the check mark that can appear just to the left of the menu item word. If flag =
1, the check mark will be added; if flag = 0, it will be removed.

It is not permitted to “check” a menu header or a separator. Moreover, the menu item must be “checkable” to permit adding a check; that is, there must be a character space to the left of the menu item as it is displayed. (Menu items are checkable by default. To make them non-checkable, perhaps to save space, use the Object subroutine directly; see Chapter 19.)
Exception: 828 Invalid window, id, menu, item combination.
368 True BASIC Language System

TC_Menu_GetCheck
CALL TC_Menu_GetCheck (wid, menu, item, flag)
This subroutine is used to determine the check mark status of a menu item. If the item is checked, the value of
flag will be 1; if not checked, the value of flag will be 0.
Exception: 828 Invalid window, id, menu, item combination.

TC_Menu_SetEnable
CALL TC_Menu_SetEnable (wid, menu, item, flag)
This subroutine is used to “gray” or “ungray” a menu item. If flag = 0, the menu item will be “grayed” or disabled; that is, it will appear dimmed. Such an item cannot be selected. If flag = 1, the menu item will be enabled and will appear normal. If you disable a menu header (item 0,) the entire menu will be disabled. Menu separators cannot be disabled.
Exception: 828 Invalid window, id, menu, item combination.

TC_Menu_GetEnable
CALL TC_Menu_GetEnable (wid, menu, item, flag)
This subroutine is used to determine the state – “gray” or “ungray” – of a menu item. If flag = 0, the menu item is now “grayed” or disabled; that is, it will appear dimmed. Such an item cannot be selected. If flag = 1, the menu item is now enabled and appears normal.
Exception: 828 Invalid window, id, menu, item combination.

TC_Menu_Free
CALL TC_Menu_Free (wid)
This subroutine should be used to free the entire menu structure associated with the window. For example, you may wish to replace the menu structure with an entirely different one.

It is not necessary to call this subroutine if you intend to “free” the window itself; freeing a window automatically frees all entities associated with it.
Interface Library Routines

369

Check Box Subroutines
TC_Checkbox_Create
CALL TC_Checkbox_Create (cid, text$, xl, xr, yb, yt)
This subroutine creates a check box, which is a small square box that can either be empty or can contain an “X”. The text provided will appear just to the right of the check box and will be left-justified.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of a checkbox will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of a check box will be used.

The check box will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.
If text$ ends with "|LEFT", "CENTER", or "|RIGHT", and the operating system permits, the checkbox text will be justified accordingly.

TC_Checkbox_Set
CALL TC_Checkbox_Set (cid, state)
If state = 1, an “X” will appear in the check box. If state = 0, the check box will be cleared.

TC_Checkbox_Get
CALL TC_Checkbox_Get (cid, state)
This subroutine finds the state of a check box. If the check box is checked, state =1; if the check box is not checked, state = 0.

You can change the text of a check box using
CALL TC_SetText (cid, newtext$)
370 True BASIC Language System

Edit Field Subroutines
TC_Edit_Create
CALL TC_Edit_Create (cid, initialtext$, xl, xr, yb, yt)
This subroutine creates a one-line editable field that allows the usual editing operations — left and right cursor controls, mouse clicks, keystrokes, delete and/or backspace — according to the conventions of the operating system.
The initial text of the edit field can also be set at this time.
If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of an edit field will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of an edit field will be used.
The edit field will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

TC_Edit_SetText
CALL TC_Edit_SetText (cid, newtext$)
This subroutine sets or changes the text that appears in the edit field. You can also change the text of an edit field with
CALL TC_SetText (cid, newtext$)

TC_Edit_GetText
CALL TC_Edit_GetText (cid, text$)
This subroutine finds out the text in an edit field. This can be done at any time. However, the user may still be making modifications to the text. It is a good idea to require the user to select another control, or to select some push button, to determine that the user has, in fact, completed his or her editing.

TC_Edit_SetFormat
CALL TC_Edit_SetFormat (cid, format$)
This subroutine sets a format for the edit field against which the text can be compared. Allowable formats are:
null string No checking is done
ALPHA Only letters of the alphabet and spaces are allowed
ALPHANUM Only letters, digits, and spaces are allowed
NUMBER Only numbers are allowed (True BASIC numeric constants)
INTEGER Only digits are allowed
RANGE Only integers in the range specified are allowed (see later) FRANGE Only numbers in the range specified are allowed (see later) ZIP Only five-digit or nine-digit zip codes are allowed
PHONE Only phone numbers are allowed (several formats permitted)
SS Only Social Security numbers are allowed
DATE Only dates are allowed (several formats permitted)
LENGTH Only sequences of a certain length are allowed (see later)
FORMAT Only sequences that match, character by character, the format string provided are allowed
LIST Only entries that match one of the items in a list are allowed
The NUMBER and INTEGER checks are made by attempting to use the True BASIC VAL function. In the case of
INTEGER, the entry is first checked to see if it contains anything but digits.
Interface Library Routines

371

To use the RANGE format, you must supply the smallest integer and the largest integer that will be allowed. These integers follow the word RANGE with but one space between. For example:
“RANGE 20 35”
will allow the user to enter any integer number in the range 20 to 35, inclusive.

Similarly, with FRANGE you supply the smallest and largest general numbers that will be allowed, separated by one space. For example,
“FRANGE -2.7 12.3”
will allow any general number between -2.7 and 12.3, inclusive.

The ZIP format will accept any sequence of five digits, or any sequence of five digits followed by a hyphen and followed by another four digits.

The PHONE format will accept phone numbers in three formats: 999-9999, 999-999-9999, or 999/999-9999. The SS format will accept only sequences in the format 999-99-9999.
The DATE format will accept strings in any of these format: YYYYMMDD, YYYY_MMM_DD, YYYY/MMM/DD, DD MMM YYYY, and MMM DD, YYYY. (MM stands for the month number, while MMM stands for the three- letter abbreviation of the month name.)

The LENGTH format may require the user to supply exactly the correct number of characters, or a number of characters in some range. For example:
LENGTH 15
LENGTH 12 24
The first case requires the user to supply exactly 15 characters, while the second requires a number of characters between 12 and 24, inclusive.

The FORMAT format allows you to specify the type of each character supplied by the user. The character types are: A The character must be a letter or space
9 The character must be a digit
X The character must be a letter or a digit or a space
? The character can be anything
all others The character must match exactly

For example, if you wish the user to enter a dollar value of the form “$1,234.56”, you might specify as the format
“$9,999.99”.

Finally, for the LIST format, the user’s entry is required to match one of a sequence of words, without regard to case. The words may be separated by spaces or commas. For example, if you require the user to enter M or F, you might use
“LIST M F”

TC_Edit_CheckField
CALL TC_Edit_CheckField (cid, errormess$)
This routine checks the contents of the edit field specified by cid against the format (see TC_Edit_SetFormat). If the contents are consistent with the format, errormess$ is the null string; otherwise, errormess$ contains the reason for the inconsistency.
372 True BASIC Language System

Graphical Subroutines
TC_Graph_Create
CALL TC_Graph_Create (gid, type$, xl, xr, yb, yt)
This subroutine creates a graphics object of the type specified. The types available are:
CIRCLE A circle or ellipse
RECTANGLE A rectangle
ROUNDRECT A rectangle with rounded corners
LINE A straight line segment
ALINE A line segment with arrow heads
ARC An arc of a circle or ellipse
PIE A pie section of a circle or ellipse
POLYLINE A set of joined line segments, but not necessarily closed
POLYGON A set of line segments forming a closed region
IMAGE An image (bmp, pict, etc.) from a file.
The graphical object will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window.

For the CIRCLE, RECTANGLE, and ROUNDRECT, the coordinates define the bounding rectangle. The roundness of the corners of the rounded rectangle is set separately. For the LINE and ALINE, the coordinates are interpreted as follows: starting point (xl, yb), ending point (xr, yt). The presence or absence of arrowheads in the ALINE is set separately.

For a LINE or ALINE, the four coordinates define the start and end of the line or arrowed line as follows:
xl = starting x yb = starting y xr = ending x yt = ending y
Thus, to draw a line from (1,2) to (3,4), you would use:
CALL TC_Graph_Create (gid, “LINE”, 1, 3, 2, 4)
ARC and PIE start with the circle or ellipse defined by the coordinates. ARC consists of a portion of the circumference of the circle or ellipse. PIE consists of an arc plus straight lines from the ends of the arc to the center of the circle or ellipse. The extent of the ARC or PIE is specified separately.

POLYLINE consists of a set of (x,y) points joined with straight line segments. POLYGON is a polyline with the first and last point joined. For these objects, the location coordinates are ignored, except for applying TC_Graph_Scale.
IMAGE prepares the way for importing an image (such as a BMP or PICT) from a file. The filename from which the image is to be imported, or the box keep string, is specified separately.

Graphics objects float above the True BASIC output canvas as do controls such as push buttons. But, if the window is cleared with a CLEAR statement, visible graphics objects are made invisible. They must individually be reshown using a call to TC_Show.

Exception: 840 Invalid graphics type: ttttt
Interface Library Routines

373

TC_Graph_SetPoly
CALL TC_Graph_SetPoly (gid, pts(,))
This subroutine provides the (x,y) points that define the polyline. The two-dimensional matrix is assumed to have exactly two columns, and to have exactly the number of rows as there are point-pairs. (It is not necessary that the lower bounds be 1, or anything else.)
The new polyline or polygon is shown as soon as the points, or the new points, are specified.
Exception: 841 POINTS must be in pairs for vertices.

TC_Graph_SetArc
TC_Graph_SetArc (gid, starta, stopa)
This subroutine defines the starting and ending points of an arc, or those points of the arc that is a part of a pie segment. The ends of the ARC are defined as follows: the arc is a section of the circumference of the largest circle or ellipse contained in the rectangular region specified in the call to TC_Graph_Create. The starting angle starta defines a radius starting at the center of the circle or ellipse. The intersection of this radius with the circumference defines the starting point of the arc. The ending angle stopa similarly defines a radius, the intersection of which with the circumference defines the ending point of the arc. The angles are measured in degrees starting with the positive x-axis, and increasing counterclockwise. The arc is drawn counterclockwise from the starting point to the ending point, regardless of the coordinate system.
For the PIE type, the straight lines between the center of the circle or ellipse and the starting and ending points are made visible .

TC_Graph_SetRoundRect
CALL TC_Graph_SetRoundRect (gid, owidth, oheight)
This subroutine sets the degree of roundness for the corners of a rounded rectangle. It works like this: Imagine an ellipse with half-length equal to owidth, and half-height equal to oheight. Cut this ellipse into four quadrant parts. These four parts become the four corners of the rounded rectangle.

If the units for placing the object are in pixels, then these values should also be in pixels. If the units are in user coordinates, then these values should also be given in user coordinates.

TC_Graph_SetAline
CALL TC_Graph_SetAline (gid, start, end)
This subroutine adds or removes arrowheads from either end of an ALINE. If start = 1, an arrowhead will be placed at the beginning of the line; if start = 0, such an arrowhead will be removed. If end = 1, an arrowhead will be placed at the end of the line; if end = 0, such an arrowhead will be removed.

TC_Graph_SetImage
CALL TC_Graph_SetImage (gid, filename$, adjustflag)
This subroutine causes an image to be imported from the file specified. The value of adjustflag specifies how the image will be displayed in terms of the rectangle specified in the call to TC_Graph_Create.

This subroutine merely calls TC_Graph_SetImageFromFile with a null filetype, and is retained for compatibility only. A description of adjustflag is given in the description of TC_Graph_SetImageFromFile.

TC_Graph_SetImageFromFile
CALL TC_Graph_SetImageFromFile (gid, filename$, filetype$, adjustflag)
This subroutine causes an image to be imported from the file specified. If you know the file type, you should supply it. Allowable file types are: JPEG, PICT (Macintosh only), MS BMP, OS/2 BMP, and possibly PCX. Spaces are important but case (upper or lower) is not.
374 True BASIC Language System

Adjustflag Action
1 The image will be centered at the center of the rectangle specified at the creation of the graphics object. The size of the image will not be changed. Other than its center, the actual size of the rectangle will be ignored. Part or all of the image may be off the screen.

0 The image will be forced into the rectangle specified at the creation of the graphics object. The image will be expanded or contracted as needed.

-1 The image will be centered in the window, and will retain its original size. The rectangle specified at creation time will be ignored. If the image is larger than the window, portions of the image may not show.

In cases +1 and -1, the defining rectangle for the graphics object will be changed.

TC_Graph_SetImageFromBox
CALL TC_Graph_SetImageFromBox (gid, boxstring$)
This subroutine causes an image to be constructed from a box keep string, which must be in the local format.

If you need to adjust the size of the image, you will have to save the box string into an image file using CALL Write_Image, and then use CALL TC_Graph_SetImageFromFile to display the image, possibly with adjustment of its size.

See also the subroutines Read_Image and Write_Image, described in Chapter 18. Read_Image reads a bit-mapped image (i.e., BMP) from a file and converts it into a box keep string. Write_Image converts a box keep string into a bit-mapped image and writes it to a file.

TC_Graph_GetImageToBox
CALL TC_Graph_GetImageToBox (gid, boxstring$)
This subroutine takes an image being displayed on the screen and converts it into a box keep string in the local format.

See also the subroutines Read_Image and Write_Image, described in Chapter 18. Read_Image reads a bit-mapped image (i.e., BMP) from a file and converts it into a box keep string. Write_Image converts a box keep string into a bit-mapped image and writes it to a file.

TC_Graph_Shift
TC_Graph_Shift (gid, deltax, deltay)
This subroutine allows you to move or shift a graphics object by the amount deltax in the x-direction and deltay in the y-direction. The actual movement on the screen depends on the orientation of the coordinate system. For example, if you used pixel coordinates when creating the object and you specify a positive value for deltay, the object will be moved downward.

TC_Graph_Scale
TC_Graph_Scale (gid, scalex, scaley)
This subroutine allows you to change the size of a graphics object. The object will be stretched in the x-direction is scalex is greater than 1, or shrunk if scalex is less than 1; similarly for the y-direction. The stretching or shrinking is done relative to the center of the graphics object, and not in relation to the origin of the coordinate system (as with the SHIFT transformation with the DRAW statement.)

Certain graphics objects may be distorted if expanded beyond the edges of the window.
Interface Library Routines

375

TC_Graph_SetPen
CALL TC_Graph_SetPen (gid, width, color, style$, pattern$)
This subroutine can be used to set certain attributes of the pen that draws the particular graphics object. These include: the pen width, the pen color, the pen style, and the pen pattern. The width will not be changed if it is negative; the color will not be changed if it is < -2. The style or pattern will not be changed if the null string is provided. Each graphics entity can have its own pen characteristics.

The pen width is specified in pixels. The default width is one pixel.
The pen color is specified by an index into the current color mix table. The default color is -1 (black.) The pen style must be one of:
SOLID Solid line (default)
DOT Dotted line
DASH Dashed line
The pen pattern must be one of:
SOLID Solid (default)
HOLLOW The line drawn is invisible
RUBBER Small dashed lines that move on some systems.
There are several restrictions on combinations of width, style, and pattern. If the width is one pixel, then styles DOT and DASH override the pattern, taking it to be SOLID. If the width is greater than one pixel, then style SOLID and pattern SOLID override. In other words, DOT, DASH, and RUBBER can only happen with one-pixel pens. And the style setting overrides the pattern setting. If the width is more than one pixel, the approximate center of the curve or line will follow the path specified.

For example
CALL TC_Graph_SetPen (gid, 10, 4, “”, “”)
will set the pen for graphics object gid to width ten pixels, color 4 (usually red), and with no change to the style or pattern.
(The conventions are identical with those of TC_Win_SetPen.) Exceptions: 842 Invalid pen style: sssss
844 Invalid pen pattern: ppppp

TC_Graph_SetBrush
CALL TC_Graph_SetBrush (gid, backcolor, color, pattern$)
This subroutine controls the color and pattern for the brush that is used to fill the interior of several of the graphics objects, as well as the background color for both the pen and the brush.

The brush color, like the pen color, refers to the color mix table. If color is < -2, the current brush color will not be changed. The default value is -1 (black.)

The brush pattern must be one of: SOLID (default) HOLLOW
HORIZ VERT FDIAG BDIAG CROSS
DIAGCROSS
The background color also refers to the current color mix table. If backcolor is < -2, the current background color will not be changed. The default background color is -2 (white.)
376 True BASIC Language System

For example,
CALL TC_Graph_SetBrush (gid, -1, 3, “cross”)
will not change the background color for the graphics object, will set the brush color to 3, and will set the brush to a crosshatch pattern.
(These conventions are identical to those of TC_Win_SetBrush.) Exception: 845 Invalid brush pattern: ppppp

TC_Graph_SetDrawmode
CALL TC_Graph_SetDrawmode (gid, mode$)
The string values allowed for mode$ are as follows; note that where there is a space in the string, there must be exactly one space:
“COPY” ignore current contents, draw over anything that is there (default)
“OR” perform bitwise OR between bit plans of each currently displayed pixel and the new pixel which is to overlay it
“XOR” perform bitwise XOR between bit plans of each currently displayed pixel and the new pixel which is to overlay it
“CLEAR” clear the screen to the extent covered by the item being drawn
“NOT COPY” the bitwise negation of COPY “NOT OR” the bitwise negation of OR “NOT XOR” the bitwise negation of XOR “NOT CLEAR” the bitwise negation of CLEAR

The drawing mode determines how the graphical object’s pen and brush interact with the background, including what has already been drawn. As an example, assume there are four bit planes (i.e., there are sixteen entries in the color map table), the background is color 6 (binary 0110), and the pen is color 10 (binary 1010). Then the above drawing modes would give the following results for each pixel covered by the pen:
“COPY” Color 10 (binary 1010) “OR” Color 14 (binary 1110) “XOR” Color 12 (binary 1100) “CLEAR” Color 0 (binary 0000) “NOT COPY” Color 5 (binary 0101) “NOT OR” Color 1 (binary 0001) “NOT XOR” Color 3 (binary 0011) “NOT CLEAR” Color 15 (binary 1111)
Exception: 843 Invalid draw mode: mmmmm
Something similar may operate for a larger number of bit planes, and will sometimes yield strange-looking results. But the modes “COPY” and “CLEAR” should work as expected. And “XOR” should have the property that, if you draw the object twice, you will get back the original background.
Interface Library Routines

377

Group Box Subroutines
TC_Groupbox_Create
CALL TC_Groupbox_Create (gbid, title$, xl, xr, yb, yt)
This subroutine draws a rectangular box, with title.

The four coordinates refer to the inside of the currently targeted (for output) physical window or, if in user coordinates, the current logical window.

The group box will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

The group box is opaque, and should be created or shown before generating the output or showing the controls contained within it.

List Button Subroutines
TC_ListBtn_Create
CALL TC_ListBtn_Create (lbid, text$(), xl, xr, yb, yt)
This subroutine creates a list button. A list button appears as an ordinary push button but, when selected, reveals a scrollable list of items that can be selected.

The list text$() must have a subscript lower bound <= 1. The text of the button is the same as item one in the list.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of a list button will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of a list button will be used.

The list button will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

You can change the contents of a list button using
CALL TC_SetList (lbid, text$())

TC_ListBtn_Get
CALL TC_ListBtn_Get (lbid, selection)

This subroutine returns the number, starting with one, of the item currently showing in the list button. Note that the user may still be in the process of manipulating the list. It is a good idea to require the user to select another control, or to select some push button, to determine that the user has, in fact, made a selection from the list button. At this point, the list button could be erased.

TC_ListBtn_Set
CALL TC_ListBtn_Set (lbid, selection)

This subroutine sets the item, starting with one, initially highlighted in a list button.
378 True BASIC Language System

List Edit Button Subroutines
TC_ListEdit_Create
CALL TC_ListEdit_Create (leid, text$(), xl, xr, yb, yt)
This subroutine creates a list edit button. A list edit button appears as an ordinary list button but with two exceptions. First, it can be edited, like an edit field. Second, a scrollable list of choices appears when it is selected. Selecting one of the choices moves that choice to the editable field.

The items are given in the text$() list. In addition, the initial text of the list edit button is taken from
text$(0). Thus, the smallest subscript of text$() must be <=0.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of a list edit button will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of a list edit button will be used.

The list edit button will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

You can change the contents of a list edit button with

CALL TC_SetList (leid, text$())
If there is a 0-th element, it will be used to set the text of the button itself.

Exception: 855 List Edit list subscript must start with 0.

TC_ListEdit_Get
CALL TC_ListEdit_Get (leid, text$)
This subroutine finds out the text left by the user in the list edit button. Note that the user may still be in the process of editing the text. It is a good idea to require the user to select another control, or to select some push button, to determine that the user has, in fact, made a selection from the list button. At this point, the list button could be erased.

TC_ListEdit_Set
CALL TC_ListEdit_Set (leid, text$)
This subroutine sets the text shown in a list edit field. The text may be changed at any time with this subroutine.
Interface Library Routines

379

List Box Subroutines
TC_ListBox_Create
CALL TC_ListBox_Create (lbid, mode$, xl, xr, yb, yt)
This subroutine will present a selection list box. This list box is similar to others that appear in, for example, file open dialog boxes, but consists only of the selection list part. The list itself is scrollable, and must be set by TC_SetList.

The selection mode is given by mode$. Its possible values are: SINGLE Only single selections permitted (default) MULTIPLE Multiple selections permitted
READONLY No selections permitted
You can set or change the list of a selection list box using:

CALL TC_SetList (lbid, text$())

Note that the calling sequence TC_ListBox_Create differs from the calling sequences for TC_ListBtn_Create and
TC_ListEdit_Create. Here, a separate call to TC_SetList is required to set the list.

TC_ListBox_Set
CALL TC_ListBox_Set (lbid, selection)
This subroutine allows you to preselect a particular entry in the list. The value of selection must be in the range from 1 to the number of entries in the list.

Note: this subroutine is not to be confused with TC_SetList, which is used to specify the entries in the list box.

TC_ListBox_Clear
CALL TC_ListBox_Clear (lbid, selection)
This subroutine allows you to “unselect” an entry in the list that might have been selected previously using
TC_ListBox_Set. The value of selection must be in the range of 1 to the number of entries in the list.

TC_ListBox_Get

CALL TC_ListBox_Get (lbid, selection())
This subroutine retrieves the selection(s) of the user. Since it is possible in certain systems to make multiple selections, this subroutine returns a numeric vector selection() whose entries are those selections. The number of selections is given by the upper bound of selection(). If only one selection is allowed, then selection(1) = the item selected. If no selection has yet been made then the selection list will have no entries.
380 True BASIC Language System

Push Button Subroutines
TC_PushBtn_Create
CALL TC_PushBtn_Create (pbid, text$, xl, xr, yb, yt)
This routine creates a push button with the specified text at the location and of the size specified.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of a push button will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of a push button will be used.

The push button will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

If text$ ends with “|LEFT", “|CENTER”, or “|RIGHT”, and the operating system permits, the push button text will be justified accordingly.

Push buttons created in this way cannot be outlined; that is, they cannot be activated by pressing the Return or Enter key. Selecting a push button with the mouse and releasing it causes the subroutine TC_Event to produce an event pair: CONTROL SELECT, CONTROL DESELECTED.

You can change the text of a push button at any time using
CALL TC_SetText (pbid, text$)

Radio Button Group Subroutines
TC_RadioGroup_Create
CALL TC_RadioGroup_Create (rgid, text$(), xl, xr, yb, yt)
This routine creates a group of radio buttons at the location specified. The number of buttons is determined from the size of the string list text$(), which also supplies the text that appears just to the right of each button. The smallest subscript of text$() must be one.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of a radio button will be used to determine the height of the group. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of a radio button will be used to determine the height of the group.

The radio group will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

If text$(1) ends with “|LEFT", “|CENTER”, or “|RIGHT”, and the operating system permits, the push button text will be justified accordingly.

A radio group has the property that no more than one button may be “on” at a time. Selecting any button to be “on”
turns off any other button that happens to be on. Initially, no button is on.

Selecting a radio button with the mouse and releasing it causes the subroutine TC_Event to produce an event pair: CONTROL SELECT, CONTROL DESELECTED. At this point you can call the subroutine TC_RadioGroup_On to determine which button is now on.

Exceptions: 865 Radio button group list must start with 1.
866 Radio button group must have at least one button.
Interface Library Routines

381

TC_RadioGroup_SetText
You can change the text of a radio button at any time using
CALL TC_RadioGroup_SetText (rgid, button, newtext$)

TC_RadioGroup_On
CALL TC_RadioGroup_On (rgid, button)
This subroutine reports which radio button is on. The numbering refers to the original text$() list used to create the group. Rgid is the ID of the group as a whole. If no button happens to be on, button will be 0.

TC_RadioGroup_Set
CALL TC_RadioGroup_Set (rgid, button)
This subroutine turns on the button specified. If any other one is on, it will be turned off.

Scroll Bar Subroutines
TC_SBar_Create
CALL TC_SBar_Create (sbid, type$, xl, xr, yb, yt)
This subroutine creates a scroll bar of the type specified and at the location specified. The type must be either
“HSCROLL” or “VSCROLL”, but the case doesn’t matter.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either xl or xr < 0, or if either yb or yt < 0, the default width or height of a scroll will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If either xl or xr = -99999, or if either yb or yt = -99999, the default width or height of a scroll bar will be used.

The scroll bar will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

The subroutine TC_Event processes all scroll bar actions, using the parameter and increment values specified by TC_SBar_SetRange and TC_Sbar_SetIncrements. The possible scroll bar events that can be returned by TC_Event are: UP, DOWN, PAGEUP, PAGEDOWN, END VSCROLL, END HSCROLL, LEFT, RIGHT, PAGELEFT, and PAGERIGHT, but it must be remembered that TC_Event has already taken care of adjusting the scroll bars. The manner in which these events interact with the visual scroll bar, and the values of the parameters and increments, is discussed later.

Note that scroll bars may be created and associated with windows, or created with text edit controls. Like ordinary scroll bars, they are handled automatically, and the events are reported as noted above. TC_Event also adjusts the text of a text edit control to correspond to the movement of the associated scroll bars.

Exception: 870 Scroll bar type must be VSCROLL or HSCROLL.

TC_SBar_SetPosition
CALL TC_SBar_SetPosition (sbid, position)
This subroutine sets the position of the slider (the thumb). The position is defined in terms of the scrollbar parameters srange, erange, and prop. If the position is <= srange, the slider will be moved to the top (left) of the scroll bar. If the position is >= erange - prop, the slider will be moved to the bottom (right) of the scroll bar. If the position is in between, the slider will be moved to the corresponding location. The default value is 0.
382 True BASIC Language System

TC_SBar_GetPosition
CALL TC_SBar_GetPosition (sbid, position)
This subroutine finds out the current location of the scrollbar slider. The current position must be interpreted in terms of the scrollbar parameters srange, erange, and prop.

TC_SBar_SetRange
CALL TC_SBar_SetRange (sbid, srange, erange, prop)
This subroutine is used to set the parameters that specify the extreme positions of the slider, as well as the proportional size of the slider on those systems that provide for varying sized sliders.

These parameters are arbitrary. The relation to the position (and size of the slider on certain systems) is as follows: When the slider is at the top (left), its position is equal to srange. When the slider is at the bottom (right), its position is equal to erange - prop. On certain systems, the size of the slider relative to the size of the slider trough (the region in which the slider moves) is given by prop/(erange - srange), but never greater than one. The default values are 0, 100, and 1, respectively.
For scroll bars associated with text edit controls, the subroutine TC_Event takes care of setting the parameters to match the length and width of the actual text.

TC_SBar_GetRange
CALL TC_SBar_GetRange (sbid, srange, erange, prop)
This subroutine finds out the current values of the scroll bar parameters.

TC_Sbar_SetIncrements
CALL TC_Sbar_SetIncrements (sbid, single, page)
This subroutine is used to set the scrollbar increments. The single increment defines how far the slider (thumb) moves when the user clicks in the up-arrow or down-arrow boxes (or left-arrow or right-arrow boxes) at the ends of the scroll bar. The page increment defines how far the slider moves when the user clicks in the gray area either above or below (left or right) of the slider. The default values are 1 and 10, respectively.
The actual movement of the slider is in terms of the parameters (see TC_SBar_SetRange for details.)
For scroll bars defined in connection with text edit controls, the subroutine TC_Event takes care of setting the increments.
It should be noted that the increments of a scroll bar are not used by the True BASIC subroutine Object. They are simply convenient storage locations for the programmer. However, the subroutine TC_Event does use these values to define scroll bar slider movements.

TC_SBar_GetIncrements
CALL TC_SBar_GetIncrements (sbid, single, page)
This subroutine finds out the current values of the increments.
Interface Library Routines

383

Static Text Subroutines
TC_SText_Create
CALL TC_SText_Create (stid, text$, xl, xr, yb, yt)
This subroutine creates a static text field with initial text as given by text$.
If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If either yb or yt < 0, the default height of a static text box will be used. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window. If yb or yt = -99999, the default height of a static text box will be used.
The font is the “System” font. Its type, style, and size may be changed but not by True Controls. If the text is longer than can be contained in the field, it will be truncated on the right.
Static text fields cannot generate any events.

You can change the text of a static text field at any time using
CALL TC_SetText (stid, text$)
If text$ ends with “|LEFT", “|CENTER”, or “|RIGHT”, and the operating system permits, the push button text will be justified accordingly.

Text Editor Subroutines
TC_Txed_Create
CALL TC_Txed_Create (txid, options$, xl, xr, yb, yt)
This subroutine creates a text-editor control with the specified options and location.

If the units are pixels (TC_SetUnitsToPixels,) the four coordinates refer to the containing physical window. If the units are users (TC_SetUnitsToUsers,) the four coordinates refer to the window coordinates of the current logical window.

The text-edit control will not be shown if the show default is set to 0 or the physical window is not showing, but will be shown if the show default is 1 and the containing window is visible.

The options$ string contains the options to be used. The particular options may be separated by spaces or vertical bars, and may be given in upper, lower, or mixed case. The options are:

ATTACHED The text edit control will fill the physical window, and will be resized if the window is resized. Scroll bars, if any, must be associated with the window. See TC_Win_Create.
READONLY The text can be read but not modified.
WRAP The lines of the text are “wrapped” or “folded” at the margin of the text edit control.
MARGIN ddd The margin is set to ddd pixels. (There must be one space between the word “MARGIN” and the digits.) This defines the width of the text, and the point at which the lines of the text are wrapped or folded. If the text is not wrapped, the margin is ignored. If ATTACHED, the margin is determined automatically.
BORDER There will be a border around the text edit control. If the text edit control is
ATTACHED to a physical window, an additional border will be superfluous.
KEY EVENTS Keystroke events will be processed by the text edit and returned as TXE KEYPRESS events by TC_Event. If this option is not included, keystroke events will not be turned by TC_Event, except those generated by trap characters. By default, a text edit control created with this subroutine will return the event TXE KEYPRESS when the return or enter key is pressed; the value of x1 returned by TC_Event will be the
384 True BASIC Language System

ASCII code of the key. Additional so-called trap characters may be set with the subroutine TC_Txed_SetTrapChar.
MOUSE EVENTS Mouse events that occur within the text edit control will be acted on the by control and returned by TC_Event as TXE MOUSE events.
VSCROLL A vertical scroll bar will be attached to the text edit control. This attribute is ignored if the attribute ATTACHED is present.
HSCROLL A horizontal scroll bar will be attached to the text edit control. This attribute is ignored if the attribute ATTACHED is present.
The text portion of a text edit control must be supplied by a subsequent call to TC_Txed_ReadTextFromFile or
TC_Txed_ReadTextFromArray.

TC_Txed_ReadTextFromFile TC_Txed_WriteTextToFile TC_Txed_ReadTextFromArray TC_Txed_WriteTextToArray
These first two routines can be used to read and write the text edit text from and to a file, which is assumed to be in a “flat file” format with the system end-of-line character at the end of each paragraph. The calling sequences are”
CALL TC_Txed_ReadTextFromFile (txid, filename$) CALL TC_Txed_WriteTextToFile (txid, filename$)
The latter routine will overwrite the previous contents of the file.

The last two routines can be used to read and write the text edit text from and to a string array. Their calling sequences are:
CALL TC_Txed_ReadTextFromArray (txid, list$()) CALL TC_Txed_WriteTextToArray (txid, list$())
In the second routine, the string list will be dimensioned to the exact length needed.

TC_Txed_SetText
CALL TC_Txed_SetText (txid, text$)
This routine supplies the entire text of a text edit control. The text is a flat file in the same format as it might be stored on disk.

You can append additional text lines to the text by using TC_Txed_Append.

TC_Txed_GetText
CALL TC_Txed_GetText (txid, text$)
This subroutine retrieves the text from a text edit control, including all user modifications up to that point. The text is a flat file in the same format as it might be stored on disk.

TC_Txed_Append
CALL TC_Txed_Append (txid, text$, revealflag)
This subroutine will append the text supplied to the end of the text in the text edit control. The text must consist of a single paragraph without an end-of-line. (With unwrapped text, a paragraph is the same as a line.)

If revealflag = 0, the text will not be scrolled; thus, the new line may be out of view. If revealflag = 1, the cursor will be set to the end of the last paragraph, thus forcing the new line to be visible.
Interface Library Routines

385

TC_Txed_SetFont
CALL TC_Txed_SetFont (txid, fontname$, fontsize, fontstyle$)
This subroutine changes the characteristics of the font used in the text edit control. If the fontname$ or the fontstyle$ is the null string, that characteristic will not be changed. If the fontsize is <= 0, the font size will not be changed. Case doesn’t matter in the specification of the font name or font style.

The font name must be a legal font name. The available fonts will differ from system to system, but will always include: “Helvetica”, “Fixed”, “Times”, and “System”. The Fixed font is a fixed width font that might be a Courier or similar font. The System font varies depending on the operating system. The default font is Helvetica. You may learn about other available fonts by calling TC_FontsAvailable.

The font size is given in points; one point is approximately 1/72 of an inch. The font size is not necessarily related to the size of the font as displayed on the screen, or to any particular number of pixels. The default size is 10 points. If the System font is being used, it may not be possible change its size.

The font style must be one of “Plain”, “Bold”, “Italic”, or “Bold Italic”. The default style is Plain. If the System font is being used, not all styles may be available.

TC_Txed_SetColor
CALL TC_Txed_SetColor (txid, forecolor, backcolor, bordercolor)
This subroutine allows changing the colors associated with a text edit control. The color numbers refer to entries in the color mix table. The default colors for forecolor and border color are black (-1), and the default color for backcolor is white (-2.)

TC_Txed_SetTrapChar
TC_Txed_SetTrapChar (txid, char, action)
This subroutine sets additional so-called “trap” characters. Such characters are returned by TC_Event as TXE KEYPRESS events even if KEY EVENTS had not been chosen as an option in TC_Txed_Create.
Char is the number of the key to be trapped, and action is what is to happen when that key is pressed by the user. Possible actions are:
1 The key code is returned as a TXE KEYPRESS event.
The text edit control is suspended.
The key is not absorbed by the text edit control.
2 The key code is returned as a TXE KEYPRESS event.
The text edit control is not suspended.
The key is absorbed by the text edit control.
3 Exactly like stop code 1, but will be treated as an ordinary character unless there is selected text.
< 0 The particular key code is unregistered.
By default, the Return or Enter key is established as a type 2 trap character.

TC_Txed_Resume
CALL TC_Txed_Resume (txid)
This routine should be used to “resume” the activity of a text edit control that has been suspended. A text edit control can be suspended if the user presses a “trap character” of type 1 or type 3.

TC_Txed_Suspend
CALL TC_Txed_Suspend (txid)
This routine can be used to “suspend” the activity of a text edit control. One use may be to reduce flicker caused by appending more than one line to the text in the control. A suspended text edit control can be made active by calling TC_Txed_Resume.
386 True BASIC Language System

TC_Txed_Cut
CALL TC_Txed_Cut (txid)
This subroutine “cuts” or removes text that has been selected, and places the text onto the system clipboard, erasing the prior contents of the clipboard. If no text has been selected, no action takes place, and the prior contents of the system clipboard remain.

TC_Txed_Copy
CALL TC_Txed_Copy (txid)
This subroutine “copies” text that has been selected, placing it onto the system clipboard and erasing the prior contents of the clipboard. If no text has been selected, no action takes place, and the prior contents of the system clipboard remain.

TC_Txed_Paste
CALL TC_Txed_Paste (txid)
This subroutine “pastes” the current contents of the system clipboard into the text of the text edit control. If there is selected text, the clipboard contents replace that text, and the selected text disappears. If no text has been selected, the clipboard contents are inserted at the current cursor location of the text edit text. The contents of the clipboard remain intact.

TC_Txed_SetCutCopyPaste
CALL TC_Txed_SetCutCopyPaste (txid, xmenu, xitem, cmenu, citem, pmenu, pitem)
If the text edit control is “attached” to the containing window, and the window is equipped with menus that include the Cut, Copy, and Paste possibilities, calling this subroutine allows TC_Event to carry out those particular functions directly. You specify the menu and item numbers of the three menu selections.

If you establish these menu associations, you should not also call TC_Txed_Cut, TC_Txed_Copy, or
TC_Txed_Paste as TC_Event will carry out these functions.

TC_Txed_Find
CALL TC_Txed_Find (txid, case, word, key$, p, l1, c1, l2, c2, found)
This subroutine “finds” certain text. The search string is provided in key$. If case = 1, the search will be case- sensitive; that is, case (upper or lower) will be taken into account. If case = 0, case will be ignored in the search. If word = 1, only whole word matches be accepted. If word = 0, finding the search string within another word will be allowed. If the search is successful, the returned value of found will be 1; if not successful, it will be 0.

At the call, the values of p, l1, and c1 specify the paragraph, line, and character in the line for the commencement of the search. At the return, if found = 1, these parameters give the paragraph, line, and character with the line of the first character of the match; l2 and c2 give the line and character of the last character of the match, which must be contained in a single paragraph. If found = 0, these parameters are not changed.

Note: paragraph, line, and character numbering start with 0, not 1. Paragraphs are text strings that end with an EOL when stored in a file. If the text is not wrapped, paragraphs and lines are the same, whereas if the text is wrapped, a paragraph may contain several lines. Finally, the lines will depend on the current margin; thus, if a text edit control that uses wrapped text is resized, then the lines will change, while the paragraphs will not.

TC_Txed_SetSelection
CALL TC_Txed_SetSelection (txid, p1, l1, c1, p2, l2, c2)
This subroutine “selects” text. The selected text will start at paragraph p1, line l1, character c1, and extend to paragraph p2, line l2, character c2, inclusive. This can be done following a successful “find” operation to show
Interface Library Routines

387

the user the location of the found text.
Remember that paragraph, line, and character counting start at 0, not 1.

TC_Txed_GetSelection
CALL TC_Txed_GetSelection (txid, p1, l1, c1, p2, l2, c2)
This subroutine allows you to identify text that may have been selected by the user. The selected text starts as paragraph p1, line l1, character c1, and ends at paragraph p2, line l2, character c2, inclusive. If no text has been selected, then p2 = p1, l2 = l1, and c2 = c1, where p1, l1, c1 is the current location of the cursor (i.e., the cursor is immediately in front of characters c1.)

Remember that paragraph, line, and character counting start at 0, not 1.

TC_Txed_SetCursor
TC_Txed_SetCursor (txid, p, l, c)
This subroutine allows you to set the cursor to any desired position. The cursor will be set to just in front of character c, in line l of paragraph p. This routine merely calls TC_Txed_SetSelection with the starting and ending paragraph, line, and character the same. That is, it “deselects” any text that may have been selected.

Remember that paragraph, line, and character counting start at 0, not 1.

TC_Txed_GetCursor
TC_Txed_GetCursor (txid, p, l, c)
This subroutine allows you to locate the current position of the cursor. The cursor will be just in front of character c in line l, paragraph p. This routine merely calls TC_Txed_GetSelection and returns the starting position of any selected text. The presence of selected text or the position of the cursor is not changed.

Remember that paragraph, line, and character counting start at 0, not 1.

TC_Txed_SetMargin
TC_Txed_SetMargin (txid, margin)
This subroutine can be used to set the margin for a text edit control. The margin must be specified in pixels. If margin <0, the margin will be set to the actual width of the test edit control.

Setting the margin has effect only if the WRAP option is in effect. The margin is set automatically for text edit controls ATTACHED to windows.
388 True BASIC Language System

True Dials

True Dials is a library of subroutines that give easy access to the True BASIC built-in subroutine TBD. (See
Chapter 21 “TBD Subroutine” for details on it.) These subroutines are contained in a library file TRUEDIAL.TRC.

These routines are all higher level calls to the built-in TBD subroutine. For a better understanding of how they work, see the source code of this library: TRUEDIAL.TRU.
The dialog boxes displayed by TBD are modal dialog boxes. That is, no other activity (such as menu selection) is permitted until the user has complete the use of the dialog box or it has timed out.
The subroutines have several features in common. Two of the subroutines (TC_Message and TC_InputM) allow you to specify a title, except on the Macintosh platform where titles are not available. This will appear at the top of the dialog box. Except for file dialog boxes, a message can be specified. If the message string message$ contains vertical bars “|”, they will be taken as line breaks. Messages of up to ten lines can be displayed.
The text of the buttons to show in the lower portion of the dialog box are specified in a single string, separated by vertical bars. For example, to display three buttons with text “Yes”, “No”, and “Cancel”, use the button string “Yes|No|Cancel”. From one to four buttons are required.
The number of the button the user selected is returned in result. Which of the buttons is initially outlined can be specified by the value of default.
Finally, a timeout limit can be set. If the user does not select one of the buttons, or does not press the Return key to activate the outlined button, before the time specified elapses, the dialog box will close with result = 0 if none of the buttons is outlined, or the number of the outlined button. The length of the timeout is expressed in seconds. If the timeout is zero, no timeout will occur.

Several errors can arise if the following subroutines are improperly specified or located. They are described at the end of Chapter 21 “TBD Subroutine” and are not repeated here. No additional errors are generated by misuse of the following subroutines.

TD_SetLocation
CALL TD_SetLocation (xloc, yloc)
This Dialog boxes (except for TB_GetFile and TD_SaveFile) are ordinarily centered in the currently-targeted physical window. By calling this routine, you can position the upper-left corner of a dialog box at the pixel screen coordinates (xloc, yloc). To return to the default positioning, use -1 for xloc and yloc.

If you require control over the size of your dialog boxes, in addition to the location of the upper-left corner, use the
TBDX subroutine directly.

TD_Warn

CALL TD_Warn (message$, button$, default, result)
This subroutine displays a (warning) message. To query the user about whether to continue or cancel an operation, you might use

CALL TD_Warn (“What is your pleasure?”, “Continue|Cancel”, 1, result)
When the dialog box is displayed initially, the “Continue” button, button number 1, will be outlined. The value of
result tells which button the user actually selected.

TD_Message
CALL TD_Message (title$, message$, button$, default, result)
This subroutine displays a dialog box similar to TD_Warn except that a title can be included. The operation is the same as with TD_Warn. For example:
Interface Library Routines

389

LET title$ = “Report from the Boss”
LET message$ = “When are you going back to work?” LET button$ = “Now|Later|Never”
CALL TD_Message (title$, message$, button$, 2, result)
The above code displays a titled dialog box with a one-line message, along with three buttons from which the user can choose. The second button “Later” will be outlined initially. (The title is not available on the Macintosh.)

TD_YN
CALL TD_YN (message$, default, result)
This subroutine displays a message with two buttons: “Yes” and “No”. In all other respects it is like TD_Warn. In fact, the calling sequence above displays a dialog box identical to that displayed by:

CALL TD_Warn (message$, “Yes|No”, default, result)

TD_YNC
CALL TD_YNC (message$, default, result)
This subroutine is a slight extension of TD_YN in that there are three buttons: “Yes”, “No”, and “Cancel”. The calling sequence above displays a dialog box identical to that displayed by:

CALL TD_Warn (message$, “Yes|No|Cancel”, default, result)

TD_LineInput
CALL TD_LineInput (message$, text$)
This dialog box can be used to input a single line of text. The user can edit this text using the usual methods: selecting the position of the cursor using the mouse, typing characters, and using the left and right cursor keys. For example:

CALL TD_LineInput (“Enter your name”, intext)
displays a dialog box with a one-line message, and a boxed editable field. It will have a single button "Ok". Upon return, what the user typed is returned in the string variable intext$.

TD_Input
CALL TD_Input (message$, buttons$, text$, default, result)
This dialog box can be used to input a single line of text. The user can edit this text using the usual methods: selecting the position of the cursor using the mouse, typing characters, and using the left and right cursor keys. For example:
CALL TD_Input (“Enter your name”, “Done|Cancel”, intext$, 1, result)
displays a dialog box with a one-line message, with a boxed editable field, and with two buttons. Upon return, what the user typed is returned in the string variable intext$.

TD_InputM
CALL TC_InputM (title$, message$, buttons$, labels$(), text$(), highlight, default, result)
This subroutine displays an input box with multiple editable lines. This dialog box can have a title bar and a title much like a window. (The title is not available on the Macintosh.) In addition, the editable lines can have labels to the left of each line. For example:
LET title$ = “Data Entry Box”
LET message$ = “Enter your name.” LET button$ = “Ok|Cancel”
DIM labels$(3), text$(3)
390 True BASIC Language System

MAT READ First name, Middle name, Last name
CALL TD_InputM (title$, message$, button$, labels$(), text$(), 1, 2, result)
displays a titled dialog box with the title bar displaying “Data Entry Box”, with an inside message “Enter your name.”, and with three editable fields. These boxes will be labeled on the left. There will be two buttons, “Ok” and “Cancel”. The first editable field will be highlighted, and the second (“Cancel”) will be outlined.

The number of editable text fields displayed is the larger of the sizes of the labels array and the initial text array, except that no more than ten fields will be displayed. Upon return, the text array will have a size consistent with the number of fields.

TD_GetFile
CALL TD_GetFile (extension$, filename$, changedir)
This subroutine displays a typical File Open dialog box. The user may change directories while looking for the file; if changedir = 0, the current directory will not be changed, and the full path name of the file will be returned in filename$. If changedir = 1, the current directory will be changed, and only the local name of the file will be returned.

On Windows and similar platforms, if extension$ is a valid file extension(such as “tru”,) then only matching files will be displayed; if extension$ is the null string, all files will be displayed. On the Macintosh, extension$ can be a file type, such as TEXT or TEXTTRUE; there is no way to limit the file names based on a possible extension to the file names.

Two buttons are displayed, “Ok” and “Cancel”. If “Ok” is clicked and no selection has been made, the dialog box stays on the screen. If “Cancel” is clicked, a null string is returned in filename$ whether or not any name has been selected.
This dialog box cannot be timed out.
Note: this subroutine does NOT actually open the file; that is up to the programmer. For example, on Windows:
CALL TD_GetFile (“tru”, filename$, 1)
presents only file names having the extension “.tru”, but will allow the user to change the current directory. Only the local name of the file will be returned in filename$.

TD_SaveFile
CALL TD_SaveFile (extension$, filename$)
This subroutine displays a typical Save File dialog box.
On Windows and similar platforms, if extension$ is a valid file extension(such as “tru”,) then only matching files will be displayed; if extension$ is the null string, all files will be displayed. On the Macintosh, extension$ can be a file type, such as TEXT or TEXTTRUE; there is no way to limit the file names based on a possible extension to the file names.

The initial value of filename$ will appear as the suggested file name. Upon return, filename$ will contain the full pathname of the file name selected by the user. The current directory is not changed.

Two buttons are displayed, “Ok” and “Cancel”. If “Ok” is clicked but the file name box is empty, the dialog box stays on the screen. If “Cancel” is clicked, a null string is returned in filename$ whether or not any name appears in the file name box.

This dialog box cannot be timed out.

Note: this subroutine does NOT actually save the file; that is up to the programmer. For example, on Windows:
LET filename$ = “MyFile.tru”
Interface Library Routines

391

CALL TD_SaveFile (“tru”, filename$)
will present a Save File dialog box displaying only file names with the extension “.tru”, and with “MyFile.tru” as the suggested name of the file to be saved. Upon return, filename$ will contain the full path name of the name actually selected by the user.

TD_List
CALL TD_List (message$, button$, list$(), choice, default, result)
This subroutine presents a selection list box. The message$ appears near the top of the box. The list of names is provided in a string list list$(). The particular name to be highlighted initially is specified in choice. If choice is < 1, then the first item is highlighted; if choice is > the number of items, then none of the items is highlighted. There may be up to four buttons specified in button$ with text for each button separated by vertical bars (|). Default specifies which one, if any, is to be highlighted initially. Upon return, choice contains the number of the selected entry, while result contains the number of the selected button.

If a timeout occurs before the use has selected a button, the number of the highlighted button is returned; this may or may not be the same as the default button. The highlighted item number will be returned in choice; if none is highlighted, 0 is returned.

TD_SetTimeout
CALL TD_SetTimeout (timeout)
This routine sets the timeout, in seconds, for all subsequent uses of the True Dials subroutines except for
TD_GetFile and TD_SaveFile. If the argument is 0, no timeout will occur. For example:
CALL TD_SetTimeout (10)
sets the timeout to be 10 seconds, while:
CALL TD_SetTimeout (0)
will prevent any timeout from happening.

TD_GetTimeout
CALL TD_GetTimeout (timeout)
This subroutine finds out what the current timeout value is.

TD_SetDelimiter
CALL TD_SetDelimiter (demin$)
This subroutine changes the delimiter used internally to break up lines for TD_Warn, TD_Message, TD_Input, TD_InputM, etc. (i.e., dialog boxes of type 1.) The default value of the delimiter is the vertical bar “|”. If your messages must include the vertical bar, of if you expect the user response to TD_Input or TD_InputM to include vertical bars, you can use this routine to change the delimiter to a neutral value.

TD_AskDelimiter
CALL TD_AskDelimiter (delim$)
This subroutine returns the current delimiter (default is the vertical bar “|”) used internally to break up lines for TD_Warn, TD_Message, TD_Input, TD_InputM, etc.
392 True BASIC Language System

ExecLib
ExecLib is a library of subroutines that provide access to directory information. The subroutines are in the library file EXECLIB.TRC. The names of the subroutines in this library all begin with “EXEC_”.

These routines are all higher level calls to the built-in System subroutine. For a better understanding of how they work, see the source code of this library in EXECLIB.TRU.

Several errors can arise if the following routines are improperly used. These errors are of two types. Errors identified by the system subroutine System are outlined where that subroutine is described in Chapter 18. Several other errors are detected by the ExecLib subroutines; these are included below.

Exec_AskDir
CALL Exec_AskDir (dirname$)
This subroutine returns the full path name of the current directory.

Exec_ChDir
CALL Exec_ChDir (newdir$)
This subroutine changes from the current directory to the new directory specified. You may specify the new directory relatively in terms of the current directory, or absolutely by providing the full pathname of the new directory. If the new directory is either invalid or does not exist, then an error will occur.
Exception: 895 Bad new directory in Exec_ChDir: nnnnn

Exec_DiskSpace
CALL Exec_DiskSpace (used,free)
This subroutine returns the amount of disk space in use, and the amount still free. Units are in bytes.

Exec_MkDir
CALL Exec_MkDir (newdir$)
This subroutine creates a new directory. You may specify either the full path name of the new directory, or give it relatively in terms of the current directory. If the directory you specify already exists, or the name is invalid, an error will occur.
Exception: 896 Bad new directory in Exec_MkDir: nnnnn

Exec_RmDir
CALL Exec_RmDir (baddir$)
This subroutine removes (deletes) the directory named. On some operating systems, this cannot be done until the directory is emptied of contents. If the directory does not exist, or is invalid, an error occurs.
Exception: 897 Can’t remove directory in Exec_RmDir: ddddd

Exec_ReadDir
CALL Exec_ReadDir (template$, name$(), size(), dlm$(), tlm$(), type$(), vname$)
This subroutine returns a list of names of the files and directories in the current directory. The names in the string list name$() will be the short names, not the full path names. The sizes of the files are given in bytes. The dates- last-modified and times-last-modified are given in the format of the True BASIC DATE$ and TIME$ functions. For example, the date might be “19950201” and the time might be “14:22:07” if it is 2:22 and 7 seconds PM on February 1, 1995.
Interface Library Routines

393

The template is specified in a standard form across platforms. For example, “*.tru” will yield file names whose extensions are “.tru”; note that the “*” is a “wild card” that matches anything.

The type consists of a four-character string of the form “drwx”. In each position, either the letter or a hyphen “-” will appear. If the “d” is present, the file is actually a directory; if a hyphen appears in that position, it is a true file. If the “r” is present, reading the file is allowed; if a hyphen appears in that position, the file cannot be read. If the “w” is present, the file can be written to or appended to; if a hyphen appears in that position, the file cannot be written. Finally, if an “x” appears, the file can be executed (i.e., run as a free-standing program.) If a hyphen appears in the last position, the file cannot be directly executed. If the “x” appears but the file does not contain a free-standing program, an error of some sort will occur.

Vname$ will simply contain the name of the current directory.

Exec_ClimbDir
CALL Exec_ClimbDir (dir$, template$, name$(), size(), dlm$(), tlm$(), type$())
This subroutine is similar to Exec_ReadDir with these exceptions:

First, a list of file and directory names contained in the directory specified in the first argument, and all subdirectories, will be given.

Second, the full path names of all files and directories are given.

Exec_Rename
CALL Exec_Rename (oldname$, newname$)
This subroutine is the only one that deals with files rather than directories. It allows you to rename a file without having to copy the file. If the old file does not exist or is in an invalid format, or if the new file already exists or is in an invalid format, an error will occur.

Exception: 897 Bad old or new name in Exec_Rename: ooooo, nnnnn

Exec_SetDate
CALL Exec_SetDate (new_date$)
This subroutine can be used to set the computer’s current date. The format is "YYYYMMDD". An exception occurs for an invalid format.

Exec_SetTime
CALL Exec_SetTime (new_time$)
This subroutine can be used to set the computer’s current time. The format is "HH:MM:SS". An exception occurs for an invalid format.
394 True BASIC Language System

CommLib
CommLib is a library of subroutines that provide access to the serial ports. They allow you to interface True BASIC to anything you can hook up to the serial port — printers, modems, lab instruments, or bulletin boards. The subroutines are contained in the file COMMLIB.TRC. The source code for this library file is in COMMLIB.TRU. (For past users of True BASIC, the files COMLIB.TRC and its source code companion COMLIB.TRU contain the same suboutines but with the traditional names.)

Getting Started
This library supports asynchronous, RS-232 communications using the asynchronous communications adaptor or equivalent. Both input and output are buffered and interrupt-driven, and the routines can support one or two ports at speeds up to 38,400 baud, and sometimes higher. There is optional flow control for input and output, and full control of the modem signals, parity, byte length, and stop bits.

Buffering
If the speed of the communications line is 1200 baud, the number of bytes you can get across it in a second is 1/10th of that, or 120 characters. If the other side is sending at full speed, you’ll receive a character every 1/120th of a second, ready or not. That’s probably enough time to save the character in a string, but not too much more — if your program ever blinks, if it takes a half-second out to read the disk, you’ll just lose 60 characters.

That’s where buffering can help you. This library sets up a separate process (an “interrupt handler”) to watch the communication line no matter what your program is doing. If a character comes in, it saves it (in a buffer) until the next time the program’s ready to read it. It’ll save up to 20480 bytes, so at 1200 baud, your program could “blink” for more than 10 seconds, instead of only 1/120th sec.

Even at 19,200 baud, there’s enough room for a full second’s worth of data. The output buffer is smaller — 10240 bytes on the Macintosh, system-dependent on Windows and OS/2 — but it’s still usually enough to keep the line running at full speed.

A Short Example
Here’s a simple program that will make your PC act like a dumb terminal:

library “Commlib.trc”
call Com_Open (#1, 1, 14400, ““) ! Open comm line at 14400 baud call Com_SendCR (“ATD 6436300”) ! Dial up the computer

do
call Com_Receive (s$) ! get any input from computer call Output (s$) ! routine to print it on screen if key input then ! get anything the user’s typed
get key k select case k
case 323 ! F9 = end session stop
case 315 ! F1 = break call Com_SendBreak
case else ! else send to the computer call Com_Send (Chr$(k))
end select end if
loop

SUB Output (s$) ! Handle CR & LF characters
Interface Library Routines

395

do ! first strip all CRs let i = Pos(s$,Chr$(13)) ! find first CR
if i = 0 then exit do ! none = all done let s$[i:i] = ““ ! remove the first
loop

do ! now end line on line-feed let i = Pos(s$,Chr$(10)) ! find next line-feed
if i = 0 then exit do
print s$[1:i-1] ! print each separate line let s$ = s$[i+1:maxnum] ! remove that line
loop

print s$; ! print partial line end sub
end

How the program works
The program uses routines to access the communications line. All of them are from the library COMMLIB.TRC
which is the compiled version of the communications library. Here’s what they do:
CALL Com_Open (#1, 1, 14400, “”)
Starts up the communication routines. You must call it first. #1 is a dummy file, that’ll be associated with the line. Don’t try to do normal file I/O with it — things like READ or PRINT. The only thing you can do with it is close it, which shuts down the buffering. The “1” is which communication port to use (in case you have two). “14400” is the baud rate, and the last argument is a string of options.
CALL Com_SendCR (““ATD 6436300””)
This sends the string argument out over the communication line followed by a carriage-return. In this case, the string is just a dial-up command for an auto-dial modem. Com_SendCR is a special case of Com_Send.

CALL Com_Receive (s$)
Com_Receive sets its argument to a string containing all characters that have come in from the other end since the last time you called Com_Receive. If nothing new has come in, it will return the null string. That will usually be the case, in this program.

When things are idle, the program will sit looping, alternately checking “key input” and calling Com_Receive. In the meantime, the program will harmlessly print the null string (without new-line) repeatedly on the screen.

CALL Com_Send (Chr$(k))
This sends the key the user typed to the “other end” (the modem, or whatever the line is hooked up to). The string argument can be as long as you want.

CALL Com_SendBreak
A break isn’t a character, and can’t be sent with the normal Com_Send routine. Com_SendBreak transmits the same signal over the line as the break key on most terminals.

The rest of the program (the subroutine Output) is there to treat carriage-returns and line-feeds more like a terminal does.

There’s a complete technical description of all the routines at the end of this section. The routines let you get at almost every feature of the communications hardware, mostly through the option string for Com_open. There are quite a lot of bells and whistles. If you really need to, for example, you can support the 75 baud 5-bit code that AP and UPI wire services use.
396 True BASIC Language System

Options and Controls
There are lots of controls and options available. If you’re very knowledgeable about communications, you may want to skip to the technical descriptions of the library routines in the back of this manual. If you’re not already an expert, it can be difficult to know what to pay attention to and what to ignore.

Here’s a rough road map: if you’re using the communication line to transfer binary files, you should know about parity and number of data bits. If you’re doing file transfers from the PC, you should read about XOFF / XON flow control. You probably won’t need to pay attention to modem control and status signals unless you already know about them.

Parity, Data Bits, and Stop Bits
These can be set when you open the line, or changed in the middle of things with Com_control. Virtually all communication uses 8 bit characters, with one start and one stop bit (10 bits total, which is why the baud rate is
10 times the number of characters per second). Having two stop bits will slow things down slightly, but otherwise won’t make a difference. Only old 10 cps teletypes require 2 stop bits.

To get a total of 8 bits in each character, you should either have 8 data bits and no parity (“D8 P–” in the options), or 7 data bits and a parity bit. In general, it’s better to use 7 bits and “even” or “space” parity unless you’re doing binary file transfers, in which case you should use 8 bits and no parity. If you are receiving normal text, you should avoid 8-bit no-parity mode. Otherwise, the parity bits may turn

innocent letters into strange hieroglyphics (the characters above 128 in the IBM character set). Note also that
Receive_line won’t recognize a carriage-return with the parity bit set if you’ve requested 8 data bits.

XOFF / XON Flow Control
Flow control is a way for one end to make the other stop sending temporarily if it’s getting behind. The side that’s getting behind sends an XOFF character (control-S), and the other side stops sending. When it’s caught up again, the one that sent the XOFF sends an XON (control-Q), and the other side resumes sending. This is a pretty common convention, but not universal.

The SXOFF option will make the communication routines automatically send an XOFF if its input buffer is nearly full (within 256 bytes). It’s on by default. The RXOFF option makes output stop whenever an XOFF is received. It’s off by default. If you’re sending files from the PC, you probably want RXOFF on, so you won’t send

too much too fast. If you’re receiving binary files, you probably want RXOFF off, so that you can receive the XOFF
character just like any other. These options can be set when you call Com_open.

Modem Control and Status
The control signals (RTS and DTR) can be set by Com_control or Com_open, and you can check the status lines (CTS, DSR, RI and RLSD) with Com_status. If you want to, you can find out whether your modem is really hooked up or whether it has detected a carrier signal. You almost never need to pay attention to these. Often the wires aren’t even connected. CTS and RTS are for half-duplex lines, which aren’t often seen nowadays.

Hardware Requirements
To use the communication library, you’ll need a “serial port.” You can use either serial port, or both at the same time, with this library.
Interface Library Routines

397

Summary of COMMLIB
The following routines can all be found in the library COMMLIB.TRC on your communications disk. The routines are described in more detail in the following pages. First, the subroutines:
Com_Open (#1, port, speed, opt$) Opens communication line.
Com_Switch (p) Switches to port p.
Com_Control (opt$) Resets options and modem signals. Com_Send (s$) Sends s$ (starts sending). Com_SendLine (line$) Sends line$ followed by CR/LF. Com_SendCR (line$) Sends line$ followed by CR. Com_SendBreak Sends a break.
Com_Receive (buf$) Gets all bytes received since last call. Com_ReceiveLine (line$) Gets the next line, up to a CR. Com_WaitLine (wtime, f, l$) Like Com_ReceiveLine, with timeout. Com_WaitPrompt (p$, wtime, f, s$) Waits for specified prompt, with timeout.

There are also two numeric functions that give the current status of the communication line:
Com_Buf (type) Returns buffer space, in bytes, according to type:
0 — bytes waiting to be sent
1 — free space in output buffer
2 — bytes in input buffer
3 — free space in input buffer.

Com_Status (type$) Returns line status; type$ may be DSR, CTS, RLSD, RI, ERR, RXOFF, SXOFF, or CR.

Com_Open
CALL Com_Open (#1, port, speed, options$)
Before you use any other communication library routine, you have to use Com_open to tell the system what port you’re using, what speed to run, and a host of other details, like whether to set Data Terminal Ready, that you usually needn’t worry about.

The file number you pass isn’t used by the other routines. The only time you’ll need it again is when you close the file. You simply use the CLOSE statement to close the communications port. Remember that local files (files used inside external subroutines or functions that weren’t passed as parameters) are automatically closed when that routine returns.

You can’t use any normal True BASIC file operations (READ, PRINT, etc.) on that file number, except for the
CLOSE statement.

Port is the number of the communications port, and can be from 1 to n, where n is the number of available ports. Note that 1 can stand for what DOS calls COM1 and so on.

Speed is the number of bits per second to send across the line, also known as the baud rate. The machine on the other side must also be using the same speed. Usually the speed should be 14400 or 28800 if you’re using a modem. If the wire from the PC is plugged directly into another piece of equipment, you may be able to use an even higher rate.

If you pass a zero, the baud rate won’t be changed.

Options$ is a string containing additional parameters, separated by spaces. See Com_control for a full explanation of the parameters. The default setting will work well in most cases. If you just use the null string, the line will be set up for 7-bit characters, even parity, and one stop bit. Data Terminal Ready and Request To Send will both be set, and the receiver will be programmed to send an XOFF character when its buffer is nearly full but not to respond to one from the other end. This corresponds to an option string of “D7 PE S1 DTR RTS SXOFF RXOFF–.”
398 True BASIC Language System

Exceptions: 9003 No such file.
7003 Channel is already open.
7001 Channel number must be 1 to 1000.
960 Unknown communication option.

CLOSE
CLOSE #1
Instead of calling a subroutine to close the communications port, simply use the True BASIC CLOSE statement. The port will be closed automatically when your program stops, or when the subroutine owning the file returns. The modem control signals (DTR & RTS) aren’t changed, so closing the port doesn’t force disconnection; you should be careful to disconnect cleanly.

Com_Switch
CALL Com_Switch (port)
If you are using more than one port, Com_switch will switch between them. All the operations (other than open and close) will apply to the last port number used with Com_switch or Com_open. The port number you use as the argument should be 1, 2, etc. It is not the file number you passed to Com_open, but rather the port number — Com_open’s second argument.
Some things to keep in mind when using both ports:
You can’t use the same file number for both ports. You don’t need the file number for any purpose other than closing the port at the end, but the file must stay open while you’re using it. If you call Com_open from a subroutine, the port will be closed when you leave the subroutine unless the channel number was a parameter.
There is a 20480 byte input buffer for each port, and Com_buf(3) gives back the same number for both. There are also separate output buffers, however, each with a system-dependent size.

Example:
! Copy port 1 to port 2, changing speed

call Com_Open (#5,2,1200,”d8 rxoff sxoff”)
call Com_Open (#6,1,300,”d8 rxoff sxoff”)

do until key input
call Com_Receive (x$) call Com_Switch (2) call Com_Send (x$) call Com_Switch (1)
loop
Exceptions: 7004 Channel isn’t open.

Com_Control
SUB Com_Control (options$)
Once a port has been opened, you can change the options by calling Com_control. These options have exactly the same meaning as they do for Com_open. The string options$ can contain any number of these separated by spaces, in either upper or lower case.
DTR Turn on Data Terminal Ready. DTR– Turn off Data Terminal Ready. RTS Turn on Request To Send. RTS– Turn off Request To Send. RXOFF Turn on input flow control. RXOFF– Turn off input flow control. SXOFF Turn on output flow control.
Interface Library Routines

399

SXOFF– Turn off output flow control.
Dn Use n data bits per character (5, 6, 7, or 8). S1 Send one stop bit after each character.
S2 Send two stop bits after each character. PE Use even parity.
PO Use odd parity.
PS Use space parity (parity bit always zero). (Macintosh only) PM Use mark parity (parity bit always one). (PC only)
P– Don’t send any parity bit (used with D8).

Almost all data transmission uses 8 bits followed by a stop bit. Sometimes the eighth bit is used for parity, other times as another data bit. The only reasonable combinations of parity and number of data bits are “D8 P–,” “D7
PE,” or “D7 PS” (except for odd applications like news wire services).

The parity bit is both generated and checked by the same method. If it’s wrong, an error will be recorded, so the next time you look at Com_status (“ERR”), you’ll see that there was a parity error. In most cases, you should just ignore parity errors, since whatever’s sending you characters may not be using the same algorithm (some use even, some use space). Almost no-one checks parity.

Exceptions: 7004 Channel isn’t open.
960 Unknown communication option: XXX

Com_Send
CALL Com_Send (s$)
Com_Send simply sends the string s$ over the communications line. It actually just puts the string into an output buffer and starts sending. The transmission goes on in background, while your program continues to run. The output buffer is 10240 bytes long, typically, and Com_Send won’t return immediately if your program gets farther ahead than that — it will have to wait for some of the data to actually be sent over the communication line.

If you need to know when the output is finished, see Com_buf.

Com_Send is the workhorse sending subroutine. Subroutines that send lines terminated with a CR-LF or just a
CR are Com_SendLine and Com_SendCR.
(Use CALL Send (s$) if you are using COMLIB.TRC.)

Com_SendLine
CALL Com_SendLine (line$)
Com_SendLine is just like Com_Send except that it sends a carriage-return and a line-feed after sending line$. It’s useful for line printers. If you want the line to be terminated with a different character sequence, just change the code in CommLib.tru and recompile. Or, just use the Com_Send subroutine and overtly send the line termination character sequence you need.
(Use CALL Send_Line (line$) if you are using COMLIB.TRC.)

Com_SendCR
CALL Com_SendCR (line$)
Com_SendCR is just like Com_Send, except that it sends a carriage-return (but no line-feed) after sending line$. It’s useful for impersonating a person at a terminal, sending command lines to a remote computer system for example. If you want the line to be terminated with a different character sequence, just change the code in CommLib.tru and recompile. Or, just use the Com_Send subroutine and overtly send the line termination character sequence you need.
(Use CALL Send_CR (line$) if you are using COMLIB.TRC.)
400 True BASIC Language System

Com_SendBreak
CALL Com_SendBreak
A break is not a character, and so can’t simply be put into a string and given to the Com_Send subroutine. Com_SendBreak waits for all other output to stop, then sends a break (which means holding the line in the zero, or spacing, state for 200 ms.), then returns. This allows you to simulate the effect of the break key on most terminals.

If your program needs to recognize breaks received from the communications line, take a look at Com_status
(“ERR”). That will tell you if a break has been received.

Exceptions: 7004 Channel isn’t open.
(Use CALL Send_Break if you are using COMLIB.TRC.)

Com_Receive
CALL Com_Receive (buf$)
Com_Receive sets buf$ to whatever data has been received since the last time it was called. It never waits. If nothing has yet come in, buf$ will be set to the null string.

Com_Receive is the workhorse receiving subroutine. A subroutines that look for CR in the received string is
Com_ReceiveLine.

(Use CALL Receive (buf$) if you are using COMLIB.TRC.)

Example:
call Com_SendLine (command$) ! request another block let block$ = “”
do ! should get 2k bytes call Com_Receive (x$)
let block$ = block$ & x$ ! accumulate bytes loop while len(block$)#<2048 ! until we get all 2K

Com_ReceiveLine
CALL Com_ReceiveLine (line$)
Com_ReceiveLine gets the next line of input, up to a carriage-return character. The carriage-return is removed, as is a line-feed (if present). It may have to wait, unlike Com_Receive, until the line is complete.
This subroutine is not recommended for very high data rates. Instead, you should try to use Com_Receive. It should generally not be used with the “D8” option (see Com_control), since it looks for a carriage-return character without a parity bit. If the carriage-return was sent with even parity, and received with the “D8” option, it won’t be recognized.
To be exact, an initial line-feed character (if one is present) is removed from the line, but the routine won’t wait to see if a line-feed follows the carriage-return. This will be important only if you mix calls to Com_Receive and Com_ReceiveLine.
If there’s nothing coming in on the communication line, Com_ReceiveLine will just keep waiting forever. See
Com_WaitLine if your program needs to time out and take corrective action in such cases.

If you prefer to scan for a terminating character other than a CR, simply make the change in the source code in
CommLib.tru and recompile.
Exceptions: 7004 Channel isn’t open.
Parity errors and the like don’t cause exceptions. They will just be recorded, and can be checked for with
Com_status (“ERR”).

(Use CALL Receive_Line (line$) if you are using COMLIB.TRC.)
Interface Library Routines

401

Com_Buf
DEF COM_BUF (type)
Com_buf returns the amount of buffer space (in bytes) currently free or currently used, for either the send or receive buffers, depending on the parameter type.
Type Result

0 Number of bytes waiting to be sent (when this number goes to zero, the transmitter is idle)

1 Number of bytes free in output buffer (number of bytes you can send without waiting)
2 Number of bytes waiting in input buffer (if you called
Receive, this is how long the string would be)

3 Number of bytes free in input buffer

Example:
declare def Com_Buf do
loop until Com_Buf(0) = 0 ! wait til all data is out call Com_Control (“DTR-”) ! then hang up the phone
Exceptions: 7004 Channel isn’t open.

Com_Status
DEF Com_Status (type$)
The function Com_Status provides for a grab-bag of rarely-used information. It can tell you are the modem status lines, various kinds of transmission errors, and whether either input or output are currently pausing because of an XOFF (control-s) character. You use type$ to say what you’re checking for. Usually the result is either 0 or 1 (“ERR” is the only exception). If the information is not available, or if type$ is misspelled, result will be -1.Type$ may be in upper or lower case.
Type Result
DSR 1 if Data Set Ready is on.
RLSD 1 if Receive Line Signal Detected (Carrier). DCD Same as RLSD (“Data Carrier Detected”). CTS 1 if Clear To Send.
RI 1 if the phone is Ringing.
RXOFF 1 if output stopped because we received an XOFF. SXOFF 1 if we sent an XOFF because the input buffer was full. CR 1 if there’s a Carriage-Return in the input buffer
(so Receive_line won’t have to wait).
ERR Returns the highest-numbered error since the last call, or zero if none.

Error types returned by Com_status (“ERR”) Type Result
0 No error since the last call.
1 Parity error (usually this should be ignored, most computers are pretty lax about parity).
2 Framing error (the stop bit was a zero, not a 1).
3 A break was received (a null character will mark the spot in the input stream).
4 Chip overrun (another character came in before the computer could respond to the last one).
5 Input buffer overrun (too many characters came in since the last time you called Receive).
402 True BASIC Language System

Example:

print “Connecting...
call Com_open (#1,1,1200,””) ! Open up the modem
let start_time = Time ! Wait up to 60 sec for carrier do
if Time > start_time + 60 then cause error 1, “Modem Timeout.”
loop until Com_status(“RLSD”) = 1 print “Connected.”
Exceptions: 7004 Channel isn’t open.
961 Unknown communication status type: YYY

Com_WaitLine
CALL Com_WaitLine (wtime, tflag, line$)
Com_WaitLine waits for the next line of input (up to a carriage-return), but will time-out after wtime seconds. If a carriage-return is received within the specified time, Com_WaitLine will set line$ to the line received (without carriage-return or line-feed), then set tflag to zero, and return. But if more than wtime seconds go by before a carriage-return is received, Com_WaitLine will return with tflag set to 1 and line$ to the partial line received so far.

Com_WaitLine is useful if you want your program to retry when the thing you’re communicating with doesn’t respond. It’s very much like Com_ReceiveLine, except that it won’t wait forever like Com_ReceiveLine will. In fact, Call Com_ReceiveLine (l$) is equivalent to Call Com_WaitLine (maxnum, xxx, l$).

(Use CALL WaitLine (wtime, tflag, line$) if you are using COMLIB.TRC.)

Com_WaitPrompt
CALL Com_WaitPrompt (prompt$, wtime, tflag, buf$)
Com_WaitPrompt waits for the specified string, prompt$, to be received. It will return as soon as that string is received, or when wtime seconds have gone by. The time-out flag tflag will be set to zero if the prompt string was received, otherwise it will be one. In either case, buf$ will contain everything Com_WaitPrompt receives from the port up to the time it returns.

If you want Com_WaitPrompt to wait indefinitely, without time-out, pass MAXNUM for wtime.

(Use CALL Wait_Prompt (prompt$, wtime, tflag, buf$) if you are using COMLIB.TRC.)

Example:
! Subroutine to sign on to time-sharing system

sub Signon (#1)
call Open_com (#1,1,9600,””) ! open the port
call Com_WaitPrompt (“login:”,10,t,s$) ! wait for prompt if t = 0 then
call Com_SendCR (“vicki”) ! send username
call Com_WaitLine (1,t,s$) ! first line is echo
call Com_WaitLine (5,t,s$) ! next is message of the day end if
if t = 0 then
print s$ ! print message of the day else
print “System isn’t responding. end if
end sub
Exceptions: 7004 Channel isn’t open.
403

A Note About Speed
The communication library is capable of supporting speeds up to 38400 baud fairly easily. But it’s quite easy to write programs that can’t keep up. Obviously the more processing you do for each character (or each line) of input, the lower the line speed you’ll be able to handle. That may not matter for output — there’s usually no penalty, except time, for sending fewer bytes per second than the line could support. It may not matter for input either, if you use input flow control (the SXOFF option). But even so, you’ll probably want to get the best performance you can from the communication line.

Here are a few hints for high-speed communication. The most important one is avoid character-by-character processing. The subroutines in the communication library work most efficiently with large blocks, rather than individual characters. When you receive input from the communication line, it comes in a string, containing whatever was received since the last time you checked. The higher your loop overhead, the more data you’ll get each time you call Com_Receive. But if you avoid looking at every byte of the string, your loop will be more efficient for longer strings. A natural equilibrium will be reached that depends on how fast the bytes are coming in.

More hints for high data rates:

• Don’t process either input or output one byte at a time.

• Don’t use Com_ReceiveLine — use Com_Receive instead. Com_ReceiveLine doesn’t allow the kind of equilibrium mentioned above. It’s also less efficient.

• If you must look at every byte of a string, use Unpackb, rather than taking single-character substrings.
It’s convenient to use a loop with a step size of 8 when using Unpackb.

• Use flow control (the SXOFF and RXOFF options) if possible. This at least means speed mismatches won’t result in lost data. Sometimes it’s just not possible to process input at the full line speed.

• If you’re using files, use byte files. Use a fairly large record size for reading or writing them. Byte files are faster than text or record files, but their chief advantage is to allow you to process the data in large batches.

Low Level Subroutines
All the subroutines and functions previously described depend on two low-level builtin subroutines. The are: ComOpen and ComLib.

ComOpen Subroutine
CALL ComOpen (method, #1, port, speed, options$)
The ComOpen subroutine provides for opening a communications port. The methods are:
Method 0 Open the communications port. P1 is the port number. P2 is the intended data speed. Options$ are the same as desribed for Com_Open The port number must be from 1 to whatever the number of ports available on your platform. P2 must be as described for Com_Open.
Method 8 Close the communications port. This may also be done with the CLOSE #1 statement.

ComLib Subroutine
CALL ComLib (method, p1, p2, ps$)
The ComLib subroutine provides access to the communications ports. The methods are numbered from 0 to 8. The description of each method is as follows:
Method 0: Open
This method opens a communications port. The ports are numbered from 1 to n, where n is the number of communications ports available. On Windows and similar machines port 1 is the same as COM1, port 2 is the same as COM2, and so on. P2 is the desired speed. Most implementations can handle any speed up to a system-
404 True BASIC Language System

dependent maximum. Ps$ provides the options, which are the same as for Com_Open.

Opening a communications port in this way is not recommended. Using ComOpen or Com_Open is preferred as
True BASIC automatically closes all channels on program termination.
Method 1: Switch
This method allow you to switch to another port, which, of course, must have been previously opened. P1 specifies the new port. P2 and ps$ are ignored.

Method 2: Control
This method allows you to send control options to a communications port. Typical options are: DTR Turn on Data Terminal Ready.
DTR– Turn off Data Terminal Ready.
RTS Turn on Request To Send. RTS– Turn off Request To Send. RXOFF Turn on input flow control. RXOFF– Turn off input flow control. SXOFF Turn on output flow control. SXOFF– Turn off output flow control.
Dn Use n data bits per character (5, 6, 7, or 8). S1 Send one stop bit after each character.
S2 Send two stop bits after each character. PE Use even parity.
PO Use odd parity.
PS Use space parity (parity bit always zero). PM Use mark parity (parity bit always one). P– Don’t send any parity bit (used with D8).

Method 3: Send
This method is the workhorse method for sending a character string to a communications port. Ps$ contains the string of characters to be sent. P1 contains the number of bytes sent. P2 is ignored.

Method 4: Receive
This method is the workhorse method for receiving characters from a communications port. If p1 = 0, then all bytes present are returned in ps$. Otherwise, p1 gives the number of bytes returned; more may still be out there. P2 is ignored.

Method 5: Status
This method allows you to determine the status of any of several conditions. Use ps$ to specify the condition you wish to check. Its status is returned in p1. If the status is unavailable, or if it is spelled wrong, p1 will be -1. P2 is ignored. Typical conditions are:
DSR 1 if Data Set Ready is on.
RLSD 1 if Receive Line Signal Detected (Carrier). DCD Same as RLSD (“Data Carrier Detected”). CTS 1 if Clear To Send.
RI 1 if the phone is Ringing.
RXOFF 1 if output stopped because we received an XOFF. SXOFF 1 if we sent an XOFF because the input buffer was full. CR 1 if there’s a Carriage-Return in the input buffer
(so Com_ReceiveLine won’t have to wait).
Additional Library Routines

405

ERR Returns the highest-numbered error since the last call, or zero if none. The error numbers are:

0 No error since the last call.
1 Parity error (usually this should be ignored, most computers are pretty lax about parity).
2 Framing error (the stop bit was a zero, not a 1).
3 A break was received (a null character will mark the spot in the input stream).
4 Chip overrun (another character came in before the computer could respond to the last one).
5 Input buffer overrun (too many characters came in since the last time you called Com_Receive).

Method 6: Scan
This method allows you to scan the characters that have been received so far for the presence of a certain character or character string. Place the search key in ps$. P1 contains the first location in the characters received so far that matches the search key; p1 is 0-based, that is, p1 = 0 refers to the first character. If no match was found, p1 = -1.

Method 7: Break
This method sends a break. The other arguments are ignored.

Method 8: Close
This method can be used to close a communications port. P1 is the port to be closed. P2 and ps$ are ignored. If you use ComOpen or Com_Open to open a communications port (recommended,) then you can close the port using a CLOSE #1 or similar statement.
406 True BASIC Language System
407