[comp.lang.ada] Keyboard input

stelmack@screamer.csee.usf.edu (Gregory M. Stelmack) (09/19/90)

Is there any way in Ada to read single keystrokes from the keyboard? Not the
GET from TEXT_IO which requires a carriage return before sending the data, but
as soon as a key is pressed have it sent? We have a whole Ada class that would
like to know, and no one here can help figure it out. So, I ask the net.
We've checked books and can't figure it out.

This is for a Data Structures class where we want to write our own I/O
routines to validate data. But to do what we want to do, we need keys as soon
as they are hit.

There should be an easy way to do it, but we can't find it. Any ideas? E-mail
if its simple so this group doesn't get cluttered due to my ignorance...

Thanks, 
-- Greg Stelmack
-- Email: stelmack@sol.csee.usf.edu
-- USmail: USF Box 1510, Tampa, FL 33620-1510
-- Amiga: the only way to compute!

westley@corsair.uucp (Terry J. Westley) (09/20/90)

In article <39@screamer.csee.usf.edu> stelmack@screamer.csee.usf.edu (Gregory M. Stelmack) writes:
>Is there any way in Ada to read single keystrokes from the keyboard? Not the
>GET from TEXT_IO which requires a carriage return before sending the data, but
>as soon as a key is pressed have it sent? We have a whole Ada class that would
>like to know, and no one here can help figure it out. So, I ask the net.
>We've checked books and can't figure it out.
>
>Thanks, 
>-- Greg Stelmack
>-- Email: stelmack@sol.csee.usf.edu
>-- USmail: USF Box 1510, Tampa, FL 33620-1510
>-- Amiga: the only way to compute!

This is typically a function of the terminal driver, not Ada.  In Unix
(SunOS), you have to call ioctl to put the terminal in "raw" mode and
call fcntl to request that the SIGIO signal be delivered to your process.
If SIGIO is being used for anything else (such as socket communication),
you've got a conflict that must be resolved.  I've also done it for VxWorks.

I can see where one could implement a different Text_IO that does this, but I
doubt if any vendors supply it automatically.


Terry J. Westley
Arvin/Calspan Advanced Technology Center
P.O. Box 400, Buffalo, NY 14225
acsu.buffalo.edu!planck!hercules!westley

stelmack@screamer.csee.usf.edu (Gregory M. Stelmack) (09/21/90)

Thanks to the net for all of your help with this question. Since this is for
programs for a class and portability is not a concern, I'll try some of the
UNIX suggestions and talk to the professor about them.

Thanks to all who responded!

-- Greg Stelmack
-- Email: stelmack@sol.csee.usf.edu
-- USmail: USF Box 1510, Tampa, FL 33620-1510
-- Amiga: the only way to compute!

sampson@cod.NOSC.MIL (Charles H. Sampson) (09/21/90)

In article <1990Sep19.192717.13113@planck.uucp> westley%hercules@planck.UUCP (Terry J. Westley) writes:
>In article <39@screamer.csee.usf.edu> stelmack@screamer.csee.usf.edu (Gregory M. Stelmack) writes:
>>Is there any way in Ada to read single keystrokes from the keyboard? Not the
>>GET from TEXT_IO which requires a carriage return before sending the data, but
>>as soon as a key is pressed have it sent? We have a whole Ada class that would
>>like to know, and no one here can help figure it out. So, I ask the net.
>>We've checked books and can't figure it out.

>This is typically a function of the terminal driver, not Ada.  In Unix
>(SunOS), you have to call ioctl to put the terminal in "raw" mode and
>call fcntl to request that the SIGIO signal be delivered to your process.
>If SIGIO is being used for anything else (such as socket communication),
>you've got a conflict that must be resolved.  I've also done it for VxWorks.

     Lots of operating systems give the programmer the ability to read
individual keystrokes, in addition to reading entire lines.  I've always
assumed that the "usual" Ada approach to inputting single characters
(above) was an implementation decision:  If the individual keystrokes
are read, the system's line-editing features (backspace, start over, etc.)
are either lost or must be duplicated in the Ada program.  If they're
lost, the program becomes very user-unfriendly.  For example, if the
user enters "A-backspace-B", more than likely only the "B" appears on
the screen, but the Ada program has seen all three characters and might
even emit an error message about them, which looks like it's complaining
about the "B".  Implementors, is my assumption about your decision right?

                             Charlie Sampson

defaria@hpclapd.HP.COM (Andy DeFaria) (09/22/90)

>/ hpclapd:comp.lang.ada / sampson@cod.NOSC.MIL (Charles H. Sampson) /  4:20 pm  Sep 20, 1990 /

>     Lots of operating systems give the programmer the ability to read
>individual keystrokes, in addition to reading entire lines.  I've always
>assumed that the "usual" Ada approach to inputting single characters
>(above) was an implementation decision:  If the individual keystrokes
>are read, the system's line-editing features (backspace, start over, etc.)
>are either lost or must be duplicated in the Ada program.  If they're
>lost, the program becomes very user-unfriendly.  For example, if the
>user enters "A-backspace-B", more than likely only the "B" appears on
>the screen, but the Ada program has seen all three characters and might
>even emit an error message about them, which looks like it's complaining
>about the "B".  Implementors, is my assumption about your decision right?

Sure, sure, sure... But what if he Ada programmer, like the initial poster,
*WANTS*  to  do  their own  single  character I/O   and handle any editting
process,  perhaps   to provide  a different,   more  friendly or consistent
editting process, huh?  How does he/she do it?

P.S.	I hate when people don't answer the question posed
P.S.S.	I'm  also not answering the  question but  I don't know the answer.
	Perhaps the solution is  to call the OS  routine (read or getc) but
	that isn't Ada or portable.

naasif@eyrie.img.uu.oz.au (Naasif Gierdien) (09/22/90)

In article <39@screamer.csee.usf.edu>, stelmack@screamer.csee.usf.edu (Gregory M. Stelmack) writes:

> Is there any way in Ada to read single keystrokes from the keyboard? Not the
> GET from TEXT_IO which requires a carriage return before sending the data, but
> as soon as a key is pressed have it sent? We have a whole Ada class that would
> like to know, and no one here can help figure it out. So, I ask the net.
> We've checked books and can't figure it out.
> 
> This is for a Data Structures class where we want to write our own I/O
> routines to validate data. But to do what we want to do, we need keys as soon
> as they are hit.


I've had the same problem trying to read single keystrokes from the keyboard.
The main difference is i'm running Janus ADA on a standalone
IBM 286/386 compatable. I also have access to the Meridian
ADA Compiler and libraries but being a relatively new user
to ADA i'm not yet sure what it can do. 

> There should be an easy way to do it, but we can't find it. Any ideas? E-mail
> if its simple so this group doesn't get cluttered due to my ignorance...
> 

At least you're not the one :-)

My second question is :-

I want to be able to put higher order ASCII values ( greater than 127 ) 
to the screen..using the same ADA and hardware as above.

Any suggestions please post here or email me. (Please excuse my ignorance :-)

naasif@eyrie.img.uu.oz.au (Naasif Gierdien) (09/22/90)

In the previous article i forgot to include my email address :-)


 _____________________________________________________________________________ 
| Naasif Gierdien                                                             |
|           _    _    _     ____    \_/                                       |
|    /   / /_\  /_)  /_)  /  /      ( )                                       |
|   (_/_/ /  / /__) /__) /  /      (   )       ".....More INPUT....."         |
|                                                                             |
| Internet: naasif%eyrie@labtam.oz.au                                         |
| UUCP    : ...!uunet!labtam.oz!eyrie!naasif          #include <disclaimer.h> |
|_____________________________________________________________________________|

mfeldman@seas.gwu.edu (Michael Feldman) (09/23/90)

In article <920031@hpclapd.HP.COM> defaria@hpclapd.HP.COM (Andy DeFaria) writes:
>>/ hpclapd:comp.lang.ada / sampson@cod.NOSC.MIL (Charles H. Sampson) /  4:20 pm  Sep 20, 1990 /
>
>Sure, sure, sure... But what if he Ada programmer, like the initial poster,
>*WANTS*  to  do  their own  single  character I/O   and handle any editting
>process,  perhaps   to provide  a different,   more  friendly or consistent
>editting process, huh?  How does he/she do it?
Actually, your PPS has the answer.
>
>P.S.	I hate when people don't answer the question posed
>P.S.S.	I'm  also not answering the  question but  I don't know the answer.
>	Perhaps the solution is  to call the OS  routine (read or getc) but
>	that isn't Ada or portable.
Indeed the solution is to call a routine from the operating system,
preferably by writing exactly the IO routine you need in C (for instance)
and making it Ada-callable by using pragma INTERFACE.

I'm not sure what you mean by "it isn't Ada or portable." If you mean that
it should have been included as a standard I/O package, you may be right;
I think I'd agree. But the fact is that is was _not_ included, and every
Text_IO implementation I'm aware of uses buffered input which requires a
CR to transmit the buffer contents. Some implementers have provided
additional I/O packages; some have not.

There are _lots_ of things that people could say should have been included
in the standard; undoubtedly your list would not be exactly the same list
as mine. That's the way it goes; the standard can't include everything in
the whole world. So we all cope by adding additional packages. If they
have to be written in another language and "pragma INTERFACE-d" to make
them Ada-callable, that is not sinful. Indeed, why else would this pragma
be in the language? At least the standard foresaw that OS services or
"foreign-language" programs would have to be called and provided the "hooks"
to do it. 

I would like very much to see a portable character-IO library -
portable in the sense that there would be an implementation-independent
package spec. The routine described by Rick Conn in a previous posting is
a good start in this direction. I will see if I have a copy and post it.
The package _body_ will necessarily be OS-dependent, because it's something
that can't be directly written in Ada.
---------------------------------------------------------------------------
Prof. Michael Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
202-994-5253
mfeldman@seas.gwu.edu
---------------------------------------------------------------------------

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (09/24/90)

In article <2166@sparko.gwu.edu>, mfeldman@seas.gwu.edu (Michael Feldman) writes:
[about signle-keystroke input]
> I'm not sure what you mean by "it isn't Ada or portable." If you mean that
> it should have been included as a standard I/O package, you may be right;
> I think I'd agree.

I would like to know how such a package could be implemented under CMS
or TSO.  (Any "power of 2" fan know what CANDE will let you do these days?)
IBM's operating systems really don't believe in character transput to
terminals.  Perhaps IBM _ought_ to be ignored, but _could_ it have been?

-- 
Heuer's Law:  Any feature is a bug unless it can be turned off.

mfeldman@seas.gwu.edu (Michael Feldman) (09/24/90)

In article <3808@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
>[about single-keystroke input]
>
>I would like to know how such a package could be implemented under CMS
>or TSO.  (Any "power of 2" fan know what CANDE will let you do these days?)
>IBM's operating systems really don't believe in character transput to
>terminals.  Perhaps IBM _ought_ to be ignored, but _could_ it have been?
>
My impression (from only limited experience with CMS) is that single-character
I/O is difficult at best under CMS because the CMS device drivers (or "access
methods" in IBM parlance) assume non-scrolling terminals and line-oriented
input (hence the MORE...) message at the bottom of every screen. This is not
an Ada problem, rather an OS one. In fact, I tried using an _ASCII_ terminal
driver (provided, I think, for interactive APL users among others). Using
Text_IO to send escape sequences to the terminal, so that I could control
my own _output_ formatting, failed: the driver was willing to give up on the
MORE... dialog, but it mapped my nonprintable ASCII characters to blanks,
so the terminal-control sequences were ignored. 

I conjecture that a sufficiently adept assembler programmer could figure out
how to end-run the CMS device drivers and then write an interface package
to make it Ada-callable, but I don't think it would be easy. 

Given the differences between ASCII and EBCDIC character sets, I find it
amazing that a decent Ada could have been implemented at all on IBM mainframe
iron. There are in fact at least two quite decent systems out there, one
sold by Alsys, the other by IBM, supported, I believe, out of Toronto.

I take it you are using the IBM Ada "program product" for Ada on CMS. If so,
the system is really a TeleSoft product (I am not revealing any secrets here).
Anyone at TeleSoft know whether this sort of thing has been done?
---------------------------------------------------------------------------
Prof. Michael Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
202-994-5253
mfeldman@seas.gwu.edu
---------------------------------------------------------------------------

defaria@hpclapd.HP.COM (Andy DeFaria) (09/24/90)

>/ hpclapd:comp.lang.ada / mfeldman@seas.gwu.edu (Michael Feldman) /  1:13 pm  Sep 22, 1990 /

>Indeed the solution is to call a routine from the operating system,
>preferably by writing exactly the IO routine you need in C (for instance)
>and making it Ada-callable by using pragma INTERFACE.
>
>I'm not sure what you mean by "it isn't Ada or portable." If you mean that
>it should have been included as a standard I/O package, you may be right;
>I think I'd agree. 

I think it's pretty simple: If  you  have to  resort to  using C instead of
Ada then it's not Ada is it?  What so  hard to understand  about that?  And
what happens when  you port this to a  system that  doesn't have C huh?   I
mean, what if the poor guy doesn't have anything but Ada?

>There are _lots_ of things that people could say should have been included
>in the standard; undoubtedly your list would not be exactly the same list
>as mine. That's the way it goes; the standard can't include everything in
>the whole world. So we all cope by adding additional packages. If they
>have to be written in another language and "pragma INTERFACE-d" to make
>them Ada-callable, that is not sinful.

Yeah it's not standard, it's not contained in TEXT_IO and all  that.  Also,
I've probably done more pragma INTERFACE'ing than you have.  But that don't
make it portable.    At best   it opens  up   opportunties for   portablity
problems. 

But still  how can you do this  in Ada?  (A:  You can't.) Well   what about
people who only have Ada? (A: They're stuck.)

ecragg@GMUVAX.GMU.EDU ("EDWARD CRAGG") (09/25/90)

> From: seas.gwu.edu!mfeldman@uunet.uu.net  (Michael Feldman)
> Subject: Keyboard input
> 
   [ text deleted ]

> I would like very much to see a portable character-IO library -
> portable in the sense that there would be an implementation-independent
> package spec. The routine described by Rick Conn in a previous posting is
> a good start in this direction. I will see if I have a copy and post it.
> The package _body_ will necessarily be OS-dependent, because it's something
> that can't be directly written in Ada.

The ALS/N project has taken the approach of writing a package
IMMEDIATE_IO (using VMS QIOW's) which is effectively a TEXT_IO clone
for all the objects for which it makes sense.  (All the various
column/line/page related objects are eliminated).  As a result, it is
interchangeable with TEXT_IO (assuming WITHs and USEs) and does not
require a "thought pattern" change when writing code. When live
keyboard input is required, IMMEDIATE_IO is used, otherwise TEXT_IO is
used.  I have found the package to be very practical and effective. 

ed
 ............................................................
Edward E Cragg                Bitnet:   ECRAGG@GMUVAX
                              Internet: ECRAGG@GMUVAX.GMU.EDU

stt@inmet.inmet.com (09/25/90)

Re: Single-character Terminal I/O, Portability, etc.

This really has nothing to do with C vs. Ada.

This is an O/S interface issue.  If you are talking
Unix, then there is a "standard" (almost) way of
accomplishing "raw" I/O.  If you are talking about`
some other operating system, then it will certainly
be different, if possible at all.  If you are talking
Posix, there are a number of options for "non-canonical"
terminal processing, which provide essentially all of
the capabilities you would want.  There is now a proposed standard
Ada binding to these capabilities (package POSIX_Terminal_Functions).

As far as portability, you will have to survey the O/Ss of
interest, come up with an interface which you can
implement everywhere, and then implement it as appropriate.
Ultimately, I suspect there will be some assembly language
involved, either written by you or by the vendor, since
neither C nor Ada compilers will normally generate
direct O/S system calls.  Of course, if you are using Unix,
then a C library is provided which already has the necessary
interfaces.  Most compiler vendors on Unix provide a similar
library for Ada.  Ideally, they will begin to converge
on the Posix proposed standard for providing these capabilities.

In any language, if you refuse to ever go outside of the language
to interface with the O/S or external subsystems, you may end up
talking only with yourself.  In any case, it usually only takes
a few lines of Assembler or other language.  You may not notice
it in C since you don't have to announce your intentions
with a "pragma Interface" to call an assembler routine, but you
can rest assured that most C system-call libraries are implemented
in assembler by someone.

S. Tucker Taft
Intermetrics, Inc.
Cambridge, MA  02138

falis@ajpo.sei.cmu.edu (Edward Falis) (09/25/90)

I've been reading this topic with some interest: it's not an easy one
to address, given the language definition. With our products, we've
taken several approaches to solving the problem, but they're not
portable in the sense of using the same source for different target
environments.

For our 68K and 386 Unix products, we use the form parameter to designate
whether terminal input should be on a per line or per character basis.
This is probably the most "Ada" solution. On our MS-DOS products, an
Ada interface to MS-DOS INT21 functions is provided, and the manuals 
explain how to use this interface to do character by character input.
For our embedded application oriented products, the choice is made
in the board support packages, and the interface for the application
is through the standard I/O packages.  Unfortunately, for the two
IBM 370 OS's we have no solution at this time.  - Ed Falis, Alsys

mfeldman@seas.gwu.edu (Michael Feldman) (09/25/90)

In article <920032@hpclapd.HP.COM> defaria@hpclapd.HP.COM (Andy DeFaria) writes:
>>/ hpclapd:comp.lang.ada / mfeldman@seas.gwu.edu (Michael Feldman) /  1:13 pm  Sep 22, 1990 /
>
>I think it's pretty simple: If  you  have to  resort to  using C instead of
>Ada then it's not Ada is it?  What so  hard to understand  about that?  And
>what happens when  you port this to a  system that  doesn't have C huh?   I
>mean, what if the poor guy doesn't have anything but Ada?

It's a bit hard to understand why you are flaming. Let's see if we can cool
tempers a bit. 
>
>Yeah it's not standard, it's not contained in TEXT_IO and all  that.  Also,
>I've probably done more pragma INTERFACE'ing than you have.  But that don't
>make it portable.    At best   it opens  up   opportunties for   portablity
>problems. 

Undoubtedly you've done more interfacing than I have; I'm only a professor.
But I have done _some_ and understand what the issues are. I took the
question as a serious one; obviously you meant it rhetorically because you
knew the answer already.

>But still  how can you do this  in Ada?  (A:  You can't.) Well   what about
>people who only have Ada? (A: They're stuck.)

Or they can make a library call, if the library exists for their
implementation. If it doesn't, they are stuck. That's why there should be a
standard library (i.e. portable) for this. Unfortunately, I don't think
this is possible, as the discussions on this group regarding the virtual
impossibility of doing it on IBM mainframe iron point out. There are some
things that just ain't portable. Period. No matter what language. This
problem will persist until the end of time, or until OS designers all agree
on a standard, whichever comes first (undoubtedly the former will).

I don't want to get into a flame war over languages. Let's see if we can get
an even-tempered discussion going. In my experience there are always things
one can dream up to do that a high-level language doesn't support directly.
The standard way to do this, it seems to me, is to jump into assembler, say,
or use C to make direct calls to an operating system DEPENDENT library. 

There are C libraries for DOS machines that are different from the functionally
similar ones on Unix; there are Unix libraries for functionalities that
don't even exist in DOS (signals come to mind). A direct call to a Unix
routine will NOT be portable if the same routine doesn't exist in DOS. 
We can go the other way, too: interrupt calls that work on DOS won't
work under Unix, especially if the underlying CPU's are different.

Indeed the Unix folks are embroiled in lengthy discussions on "merging" 
the main dialects of Unix. The preamble to the POSIX standard indicates that 
POSIX is not likely to be 100% compatible with ANY existing Unix. 

Since POSIX defines the programmer's interface to "something like Unix" - 
meaning a bunch of C-callable routines - it will be possible to write a
C call which won't work on _some_ system that isn't POSIX-compliant.

The bottom line is that complete portability is, for most nontrivial programs,
an ideal to strive for but, in the end, only an ideal.  We may bemoan this 
state of affairs, but we have to agree that it _is_ the state of affairs and 
is likely to continue to be so in our lifetimes.

None of this is to defend the agonizingly slow development of standard
Ada libraries that go beyond TEXT_IO. I know some of the folks working on
numerics and understand some of the issues there, but I still wish we had
a standard Ada library more-or-less equivalent to <math.h> (although <math.h>
ain't entirely portable either!). I wish we had a standard library for
string handling (the string stuff in <stdio.h> ain't bad for starters, but
could be improved upon). 

And I certainly wish we had a standard library for single-keystroke I/O. 
But we don't. And even if we did, there'd always be machines for which it
would be useless (IBM iron again). The point I tried to make in the note
that was so bitterly flamed is that Ada, like all the other languages,
has hooks (like pragma INTERFACE) to let us write these other packages.
And it is not sinful to use the hooks.

I wish that the Ada compiler community would agree on specs for these
packages and build them already.
---------------------------------------------------------------------------
Prof. Michael Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
202-994-5253
mfeldman@seas.gwu.edu
---------------------------------------------------------------------------

jpren@alumni.colorado.edu (John Prentice) (09/26/90)

>I think it's pretty simple: If  you  have to  resort to  using C instead of
>Ada then it's not Ada is it?  What so  hard to understand  about that?  And
>what happens when  you port this to a  system that  doesn't have C huh?   I
>mean, what if the poor guy doesn't have anything but Ada?
>
If the system has only Ada, then in all likelyhood, all OS functions will
be accessible via Ada subprogram/task entry calls, and there will be no need
for C routines.  If the operating system is written in Ada and designed to
support Ada, then C code written for such a system might well have to resort
to calling various Ada routines.
>
>Yeah it's not standard, it's not contained in TEXT_IO and all  that.  Also,
>I've probably done more pragma INTERFACE'ing than you have.  But that don't
>make it portable.    At best   it opens  up   opportunties for   portablity
>problems. 
>
As long as there are different HW architecures and different OSs, then
complete portability is a myth.  C code is often highly portable accross
similar architures using Unix, but this portability is not an intrinsic property
of C; it is a funtion of the similar HW and common OS. 

In general, the goal of writing "portable" code is to minimize and localize 
non-portable code.  In terms of intrinsic language properties, Ada is no
worse off than C (perhaps better).  The Ada package provides a very nice
mechanism for isolating low-level dependencies behind a common interface.
Also, Ada's tasking facilities (for example) can support multi-processing or 
multi-programming without a need to make calls to the underlying OS, again 
enhancing portability. 

choll@telesoft.com (Chris Holl @adonna) (09/26/90)

Posted for Brian Nettleton:
-----------------------------------------------------------------------------
In article written 06:58 Mon Sep 24, 1990 by mfeldman@seas.gwu.edu he states:

>My impression (from only limited experience with CMS) is that single-character
>I/O is difficult at best under CMS because the CMS device drivers (or "access
>methods" in IBM parlance) assume non-scrolling terminals and line-oriented
>input (hence the MORE...) message at the bottom of every screen. This is not
>an Ada problem, rather an OS one. In fact, I tried using an _ASCII_ terminal
>driver (provided, I think, for interactive APL users among others).

Prof. Feldman is essentially correct here, I haven't seen any single-
character I/O through standard IBM terminal controllers.  However, the 
problem isn't with the OS so much as the hardware.  IBM 3270-series 
terminals are block-mode devices.  Keystrokes modify a local buffer.
The user can alter the contents of the local buffer.  Transfer of data 
to the CPU doesn't happen until the user hits enter.

We've had some success doing character I/O through a different IBM 
peripheral called a 3705 Communication Controller (or any 37xx 
Communication Controller).  What we did was to get the mainframe 
to talk to a MC68000 board for a (now unsupported) 370 to 68k cross-
compiler, but the RS-232 cable could have as easily been connected to 
a terminal and single-character I/O made to work well.

-Brian Nettleton

TeleSoft