Quad-WIN in APL*PLUS/PC Vn.5
Vector 3:1, page 119
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 119
Abstract¶
One of the problems of using APL*PLUS PC in the past has been the relative difficulty of accessing the screen via some form of “full-screen” mode. Release 5.0 includes two new system functions which enable this form of application to be created much more easily – ⎕WIN and its associated function ⎕WKEY.
Using these functions, an easy to use, full-screen interface can be constructed without the need to resort to packages such as Toolkit 1 or Power Tools. A full screen interface which closely emulates the full-screen interface supplied by IBM in the FSC12x workspaces can also be implemented very easily. This will allow systems implemented on VS APL to be transported to the PC much more easily.
Introducing ⎕WIN¶
The ⎕WIN system function emulates the facilities provided by the SFOR, SCUR and SREA functions in the FSC12X workspaces supplied by IBM for fullscreen processing in VS APL. That is, it establishes the fields on the screen, positions the cursor in a specific field and then waits for data to be typed and an interrupt made (ENTER or PF-Key).
The only remaining functions to be implemented are those which write and read data to and from fields on the screen – SWRI and \<SGET>. These can be emulated using the ⎕WPUT and ⎕WGET functions implemented in earlier releases of APL*PLUS PC.
The Format Array.¶
The screen layout is defined in terms of the “format array”, which is passed as the right argument to the ⎕WIN function. The format array is similar to that used in mainframe applications, but some differences are apparent.
| COLUMN | Description |
|---|---|
| [1 2] | Field start position, row and column. The top right of the screen is position 0,0 on the PC, but position 1,1 on the mainframe. |
| [3 4] | Field width and depth in rows and columns. Identical to mainframe implementation. |
| [5] | Field type – 0=Protected (mf=2), 1=Alphameric (mf=0), 2=Numeric (mf=1). Additional field types can be user defined, to only accept specific characters from the keyboard, e.g. to set up a field which will only accept the Y or N keys. |
| [6] | Special feature code: 1=Autoskip when field is full (ASFEND under GDDM). Other features are available, such as automatic numeric validation etc. |
| [7 8] | Attributes to be used with/without the cursor. The PC attribute combines colour, intensity and extended attributes in one value. It is therefore more difficult to manipulate than the separate values used on the mainframe. Additionally different attribute values are required for colour or monochrome screens. |
Since the attributes on the PC are more difficult to handle than on the mainframe, and it is desirable to be able to convert from a mainframe type format to a PC format, a function \<fCNVT> has been written to perform the conversion. This function takes a mainframe format array as its right argument and returns a PC format array which will emulate the mainframe functionality as closely as possible. The function is capable of handling all the GDDM extended attributes (colour, reverse video etc).
The \<fCNVT> function can also take advantage of column seven of the PC format array. If a left argument is supplied, it is assumed to be an array of attributes to be adopted when the cursor enters the field. The columns must be supplied in the same order as in the mainframe format array (intensity, colour, extended attribute). The ability to change attributes depending on the presence or otherwise of the cursor makes it very easy to implement 1-2-3 or Symphony type menus. The attribute in column 8 (without cursor) displays the field normally, that in column 7 puts it into reverse video when the cursor enters the field.
Positioning the Cursor¶
The position of the cursor is initialised by the left argument of ⎕WIN. This argument is a numeric vector of up to 4 elements, the first three define the current cursor position in terms of a field number, and the row and column within that field. The field number is the row index of the desired field in the format array, and is therefore ⎕IO dependent.
The fourth element is a time-out factor – if no keys are pressed before the time-out is exceeded, control will be returned to the application. If the time-out is omitted, an infinite value is assumed.
Detecting an interrupt¶
Once ⎕WIN has been called, control is normally only returned to the user’s application when a key defined for that purpose is pressed. By default, the ESCAPE and CTRL-ENTER keys are defined. The meaning of keys on the keyboard can be changed by using the ⎕WKEY function (described over page).
The result of ⎕WIN includes the following information:
| ELEMENT | Description |
|---|---|
| [1] | Reason for exiting ⎕WIN, normally zero if a valid exit key is used. |
| [2] | Numeric value of the key causing the exit. |
| [3] | Number of field containing the cursor (in origin-zero). |
| [4 5] | Row and column in field of cursor position (origin 0). |
| [6...] | Boolean elements indicating if the equivalent field in the right argument was modified or not. |
If the special features (such as numeric validation) are specified in column 6 of the format array, then other reason codes may be set in the first element of the return vector.
Emulating Mainframe Screen Processing¶
One of the major features of screen processing via GDDM is that all I/O to the screen is buffered by GDDM until a request to update the screen is received (ASREAD or FSFRCE). Since, on the PC, no shared variables are involved, I/O must either occur immediately, or must be buffered by being stored in an APL variable. The second approach allows the panel to be placed on the screen using just one call to ⎕WPUT, which is very quick and efficient.
Similarly, by establishing attributes on the physical screen as late as possible, multiple uses of ⎕WIN can be avoided. This is achieved by storing the requested format array in a global variable. Any changes to attributes can be effected simply by changing the relevant element of the global format array.
This process is made even easier if the format array is kept in mainframe format until it is output to the screen. The \<SINT> function listed below gives an example of this. The format array is only processed through the \<fCNVT> function immediately before use by ⎕WIN.
Reading the Screen¶
When a screen read is requested, two calls to ⎕WIN are required. The first is made to establish attributes for all fields on the screen. This call cannot be used for the actual screen read, since the cursor can be moved to any field on the screen, even to protected fields. To avoid a delay while the attributes are established, a zero time-out is requested. After this, ⎕WPUT is used to write the text of the panel image to the screen.
The second call to ⎕WIN is then made, this time only INPUT fields are passed in the argument. Since only these fields are defined, the cursor cannot be moved to any protected part of the screen. Once control is returned to the application, the updated panel is retrieved using ⎕WGET.
In order to retrieve the data in the input fields, the information is read from the global panel image variable. This is illustrated by the \<SGET> function listed below.
Using Function Keys¶
⎕WIN cannot detect the keyboard codes associated with the PF keys. In order to allow the PF keys to be detected, an alternative key code must be assigned using ⎕PFKEY. This alternative key code is then detected by ⎕WIN and can be interpreted by the application as a PF key. The best key codes to use appear to be 480-510.
In order to detect these keys, ⎕WKEY must be used in order to change the interpretation of the key. ⎕WKEY allows the interpretation of any key on the keyboard to be changed, either to an alternative character or some other special meaning such as TAB. The \<initialise> function listed below sets up some required global variables and changes the codes associated with the function keys. These new codes are then reinterpreted by ⎕WKEY to mean “return control to the application”. In addition the CAPS-LOCK key is given the same meaning, since CAPS-LOCK is in a similar position to ENTER on the IBM 327X keyboard.
Conclusions¶
The presence of ⎕WIN in APL*PLUS PC release 5.0 makes the implementation of full-screen processing on the PC very simple. This style of processing can be made as close to the mainframe style as is desired, even to the extent of redefining the keyboard.
The format conversion function, in conjunction with a suitable set of cover functions on the PC, means that systems can be transferred directly from mainframe implementations of APL to the PC with very little conversion work being involved.
The ambivalent implementation of the format conversion function also allows full use to be made of the PC’s extended features, such as changing field characteristics as the cursor enters the field.
∇ OF←AA fCNVT FF;AT;BO
[1] ⍝ Convert Mainframe format to PC format array
[2] ⍝ FF - Numeric array MF style format array
[3] ⍝ AA - Numeric array Alternate attributes with cursor
[4] ⍝ OF - Numeric array Equivalent PC stype format array
[5] ⍝ Make sure input array has 10 columns
[6] FF←((1↑⍴FF),10)↑FF
[7] ⍝ If AA not specified, default is FF[;6 7 9]
[8] →(2=⎕NC 'AA')/dy
[9] AA←FF[; 6 7 9]
[10] ⍝ If AA has missing columns, replace from FF
[11] dy:AA←AA,((1↑⍴AA),(¯1↑⍴AA)-3)↑FF[; 6 7 9]
[12] ⍝ Adjust start position to origin zero.
[13] OF←(FF[; 1 2]-1), 0 ¯5 ↓ 0 2 ↓FF
[14] ⍝ Add in 'feature' col
[15] OF←OF,~FF[;10]
[16] ⍝ Change field type value.
[17] OF[;5]← 1 2 0 [3⌊1+FF[;5]]
[18] ⍝ Check for colour/mono screen
[19] →(3=⎕CRT[7])/co
[20] ⍝ Add in hi-lighting/intensity options
[21] OF←OF,(∆MONO AA[; 1 3]),∆MONO FF[; 6 9]
[22] →0
[23] ⍝ Add in hi-lighting/colour/intensity options
[24] co:OF←OF,(∆COLOUR FF[;5],AA),∆COLOUR FF[; 5 6 7 9]
∇
∇ FN SINT IN;AT;AV;BO
[1] ⍝ Set intensity of fields
[2] ⍝ IN - Numeric vector Intensities to be set
[3] ⍝ FN - Char/num vector Field names/numbers
[4] ⍝ Convert to field numbers
[5] FN←FIELDS FN
[6] ⍝ Reassign intensities.
[7] format[FN;6]←(⍴FN)↑IN
∇
∇ DA←SGET FL;CO;CL;RW
[1] ⍝ Get data in screen fields <FL>
[2] ⍝ FL - Num/Char array fields to be read(names or numbers)
[3] ⍝ DA - Character array data entered in fields
[4] DA←''
[5] ⍝ Convert to field numbers
[6] →(0=⍴FL←FIELDS FL)/0
[7] CO←1
[8] ⍝ Calculate RoW and CoLumn indexes
[9] 10:RW←(¯1+format[FL[CO];1])+⍳format[FL[CO];3]
[10] CL←(¯1+format[FL[CO];2])+⍳format[FL[CO];4]
[11] ⍝ Retrieve text
[12] DA←DA,⎕TCNL,,screen[RW;CL]
[13] →((⍴FL)≥CO←CO+1)/10
[14] ⍝ Convert to array
[15] DA←⎕TCNL bOX 1↓DA
∇
∇ initialise;CO;RC
[1] ⍝ Initialise globals and keyboard
[2] ⍝ Set up status line window.
[3] RC← 1 0 0 0 ⎕WIN fCNVT 1 9 ⍴ 25 1 1 80 2 1 0 0 2
[4] ⍝ Output processing message.
[5] sTATUS 'PROCESSING'
[6] ⍝ Initialise <alarm>.
[7] →(2=⎕NC 'alarm')/cp
[8] alarm←0
[9] ⍝ Turn APL keyboard off.
[10] cp:⎕KEYW←1
[11] ⍝ Initialise pf keys to return codes 480-510.
[12] ck:→(∧/¯1=⎕WKEY 428,479+⍳30)/0
[13] CO←1
[14] 10:(479+CO)⎕PFKEY CO
[15] →(30≥CO←CO+1)/10
[16] ⍝ CAPS LOCK and PF Keys return to application.
[17] RC←¯1 ⎕WKEY 428,479+⍳30
∇