Multiple Input Sources and Concurrent Input

This section suggests some solutions to difficulties that are commonly experienced when multiple input sources are defined.

Applications almost always require input to be presented from an OSDI on a per field, per input device basis. In other words, for a given field, input is not interleaved from more than one input device, even when multiple input devices are defined.

For example, input may be requested for a field from both a keyboard and a bar-code reader. The application may wait for either device to start sending characters via the OSDI. However, once input begins from, say, the bar-reader, it is not acceptable for keyboard input to be presented until the current bar read is complete.

The general rule for input sequencing is that the OSDI should present complete fields from a single input device and the fields should be presented in input sequence.

This raises two questions: What is a complete field, and what defines input sequence?

Field Termination

A DP4 field is completed by one of either:

To manage concurrent input your OSDI must know how field input is terminated - either how many characters constitute a fixed-length field or what character terminates a field. Terminators may be dynamically specified from an application. A useful way of dynamically assigning field characteristics is to define a POD to specify them. You may then print a string of terminator information to this POD.

There are problems associated with this method, notably the fact that keys may have their values reassigned under DP4. This means that the OSDI has to find out which hardware-generated key value matches a given DP4 key value. This can be achieved by reading the DP4 USERDATA.SYS file within the OSDI.

A more convenient method may be to make the application tell the OSDI when input has terminated for a field. In QA Build the OSDI is automatically informed by a call to inp_restart() when input for a given field is complete and input is commencing for another field. The same effect can be achieved from DP4 C by specifying dvc_redirect() between each field input. Your code in inp_restart() can decide where input should come from next.

Of course, your OSDI could have field-termination values hard-coded, but obviously this is a less flexible approach.

Concurrent Input Handling

Recognition of termination is only part of the solution to handling concurrent input to a field. Ensuring that field input occurs from a single input device requires your OSDI to make some decisions about how to handle the other active input devices. There are various strategies that may be adopted to manage concurrent input, and some are outlined below :

  1. In this scenario the OSDI does not accept concurrent input. It may wait for input on multiple sources, but as soon as input arrives from one input device input is discarded for all other devices until termination is reached. This approach has the advantage of simplicity, but the application may be unable to complete if termination is never reached from the currently active input device.

    In practice, it is unlikely that an input device that implicitly returns whole fields (such a bar reader) will fail to terminate. Similarly, field-termination from a keyboard is user-dependent for termination.

  2. Concurrent input is accepted by the OSDI. As soon as input is received from one source it is immediately passed to the application (by calling inp_avail()). This process continues until termination is seen by the OSDI. Meanwhile, any input that arrives for the other active input devices is buffered. After the first termination occurs the buffered data should be scanned to see whether any other sources have reached termination, and if so their data should be passed to the application.

    Note that this approach is vulnerable to the "never-terminated" scenario as in (1). Furthermore, your OSDI must buffer not only data but also an identifier for the source of that data. This is required so that the parameters for the call to inp_avail() are correct. Also, you should store some notion of the order in which input devices began to receive input.

    A further problem with this approach is that certain input devices signal to the user that data has been entered. The user may be unaware that the data has not yet passed through the OSDI. For example, if the OSDI is awaiting keyboard termination and the user scans an item with a bar reader, it is likely that the reader will emit a beep to signal scan completion. A user will typically accept the beep as a sign to continue - despite the fact that the data has not reached the application.

  3. In a similar fashion to (2), concurrent input is accepted by the OSDI. Input is buffered for each active input device. When termination is reached for a certain input device, all input buffered for that input device (and that device only) is passed to the application (by calling inp_avail()).

    This scheme gives the advantage of avoiding the never-terminated scenario above. However, it is not usually suitable for keyboard input because users typically expect to view keyboard input on their monitor as they type. They do not expect it to appear after termination.

The buffering in points 2 and 3 above could be managed in one of two ways:

Either: A separate buffer is managed for each input device that may be simultaneously active. Each buffer is identified such that the input source can be passed to inp_avail() on field termination. If a large number of input devices are available the corresponding number of buffers and associated management may provide a large overhead.

or:  A single buffer is used to store all outstanding data. This requires that every piece of data in that buffer is marked with its input source. This may be an overhead but a single buffer provides an inherent way of tracking the order problem outlined in (2) above.

In any case where buffering is involved you must be aware of exhausting resources and losing data. It is usually unacceptable to lose data from an input device. This is particularly important when the user is notified by the device itself that input has occurred (for example, when a bar reader beeps the user will assume their application has received the input).

Buffering input may cause subtle problems. For example, you may choose to buffer keyboard data. The user may be prompted for a response to some input taken before the keyboard data was physically input (a previous bar code may require a price confirmation). The application could easily end up with your buffered keyboard data in response to the prompt - the keyboard data will then be discarded. The result is lost data. You must be aware of the demands your particular application may make and design a suitable protocol for handling any contingencies.

You do not have to follow any particular advice when handling input sources in your OSDI, you can, for example, interleave concurrent input for a field if you wish (although this is not recommended). The purpose of the above is to provide some advice about some of the pitfalls you may encounter when handling multiple input sources.

You should note that the OSDI (via inp_avail()) identifies the input source to the DP4 Terminal Manager. The DP4 Terminal Manager will automatically discard input from any device not currently selected by the application.