[comp.sys.amiga.tech] How do I enable instant IO on console window

rss@ece-csc.UUCP (Ralph Scherp) (06/02/88)

Got a question which should be simple for all you Amiga wizards out there...

How can I disable buffering on a console window so that functions like
"getchar()" return key-strokes as keys are pressed, rather than after
the user hits the RETURN key?

Ideally, I'd like to be able to just switch the window from normal "cooked"
mode input into "raw" input, and use the stdio functions.  If absolutely
necessary, a routine to the effect of "GetKey()" which waited for a keypress
and then returned the character would be acceptible.  

I've tried to put such a GetKey() routine together, trying various tacks
varying from "setnbf(stdin)" to direct communication with the console.device;
but all I've been able to accomplish in any circumstance is the generation
of the dreaded "Software Error" requester.

My attempts to communicate with "console.device" have failed mostly due to
lack of documentation about how to accomplish things with the machine.
I have the RKM, but it's an almost completely useless mess, being woefully
incomplete & poorly indexed (even with the autodocs, unfortunately). 
Can any of you provide answers to a few questions:

  1.  How can I obtain a pointer to my console window?  In order to
      `OpenDevice("console.device")', I need to pass the address of
      the window via the io_Data field of the IOStdReq structure.
      However, since I don't HAVE that information available...

  2.  How can I obtain a pointer to my current "Process" structure?
      Does "FindTask(0)" actually return a pointer to my "Process"
      structure if the program is a "Process" rather than a "Task"?
      [From looking at Lattice's _main.c; I got the impression that
      this was the case].

  3.  What are the fields in the Process structure?  Nowhere that I could
      find in the RKM (not even in the DOS Developer's Manual, which discusses
      CreateProc() and related calls) is the Process structure discussed.
      I made a guess as to the meanings of the fields from looking at 
      the file "libraries/dosextens.h" but apparently guessed wrong.
      In case you're wondering; I tried to get a pointer to the current
      window by a stunt like:

        process = (struct Process *) FindTask(0);
        CurWin  = (struct Window *) process->pr_WindowPtr
      
      in an attempt to use "CurWin" as the window pointer in a call to
      OpenDevice with "console.device", but all I got was a Guru on
      the call to OpenDevice.

  4.  Since one can normally communicate with a console window, it seems
      logical to assume that the console.device is already attached to
      to the window, so trying to open it again is a bit silly.  If I
      knew how to get to the current console.device;  I'd try implementing
      the aforementioned GetKey() routine by issuing a DoIO() call
      using CMD_READ and io_Length set to 1  [Would this work?]. Again,
      this seems like something that might be found in the Process
      structure, but...


Well, enough questions for one posting.  I'd really appreciate any help
you can provide for me.

	Thanks in advance,
	Mark Lanzo
   via  ...ece-csc!rss

rss@ece-csc.UUCP (06/03/88)

In a previous article I wrote:
>How can I disable buffering on a console window so that functions like
>"getchar()" return key-strokes as keys are pressed, rather than after
>the user hits the RETURN key?
>
>Ideally, I'd like to be able to just switch the window from normal "cooked"
>mode input into "raw" input, and use the stdio functions....

Many Thanks Folks.  Problem solved.  Special thanks to Chuck McManis
who sent me routines which did exactly what I wanted.

I also found that I'd overlooked my "AmigaDos Technical Reference Manual"
when looking for info, which helps explain why I couldn't find some things
documented.  However, it does not document the ACTION_SCREEN_MODE packet
which I guess is new for 1.2.

One question:  I looked at the FileHandle structure defined in dosextens.h
and was comparing it with the information in the manual and embedded
in Chuck's routines -- and got the impression that the include file
has a mistake in the structure definition:

  Are the fields "fh_Type" and "fh_Port" in backwards order in the 
  include file?

From the manual, I'd have assumed fh_Type was meant to indicate whether
or not the file was interactive (i.e. IsInteractive(fh) returns the
fh_Type field) and that fh_Port was the port to the console handler.
The manual shows the fields in reverse order (labeled as "Interact"
and "ProcessID" incidentally); and Chuck's code seems to bear this
out since he uses the fh_Type field as a pointer to the console task.

If this is indeed an error in the include file, will it be fixed in
a future release?

 
    Thanks again,
	Mark Lanzo
    via  ...ece-csc!rss

andy@cbmvax.UUCP (Andy Finkel) (06/04/88)

In article <3635@ece-csc.UUCP> rss@ece-csc.UUCP (Ralph Scherp) writes:
>In a previous article I wrote:
>One question:  I looked at the FileHandle structure defined in dosextens.h
>and was comparing it with the information in the manual and embedded
>in Chuck's routines -- and got the impression that the include file
>has a mistake in the structure definition:
>
>  Are the fields "fh_Type" and "fh_Port" in backwards order in the 
>  include file?
>

No, they are in the correct order in the include files.  The
manual is incorrect.

Are you aure Chuck's example is looking into a filehandle to find the
console.device ?  Rather than getting the console process
by a FindTask(0) and using the process pointer to the
ConsoleTask, then sending a packet to the console task, and
getting a return value ?

-- 
andy finkel		{ihnp4|seismo|allegra}!cbmvax!andy 
Commodore-Amiga, Inc.

"C combines the power of assembly language with the flexibility of
 assembly language."
		
Any expressed opinions are mine; but feel free to share.
I disclaim all responsibilities, all shapes, all sizes, all colors.

elg@killer.UUCP (Eric Green) (06/04/88)

in article <3630@ece-csc.UUCP>, rss@ece-csc.UUCP (Ralph Scherp) says:
> Got a question which should be simple for all you Amiga wizards out there...
> 
> How can I disable buffering on a console window so that functions like
> "getchar()" return key-strokes as keys are pressed, rather than after
> the user hits the RETURN key?

You might just want to open your own window, and do all i/o to there. It's
friendlier, anyhow... if someone says "run myprog", they don't expect "myprog"
to be garbaging up the current CLI window.

Of course the difficulty there is that you have to write your own I/O routines
to deal with your custom window. No big deal, really.... the stdio functions
are pretty useless for all custom screen handling, anyhow.

A good source of examples is MicroEmacs. I ripped my console I/O stuff right
out of it (and Mike et. al. before me ripped it straight out of the RKM).

--
    Eric Lee Green                     {cuae2,ihnp4}!killer!elg
         Snail Mail P.O. Box 92191 Lafayette, LA 70509              
"Is a dream a lie if it don't come true, or is it something worse?"

rss@ece-csc.UUCP (Ralph Scherp) (06/05/88)

]
In] article <3928@cbmvax.UUCP> andy@cbmvax.UUCP (Andy Finkel) writes:
]>In article <3635@ece-csc.UUCP> rss@ece-csc.UUCP (Ralph Scherp) writes:
]>>In a previous article I wrote:
]>>One question:  I looked at the FileHandle structure defined in dosextens.h
]>>and was comparing it with the information in the manual and embedded
]>>in Chuck's routines -- and got the impression that the include file
]>>has a mistake in the structure definition:
]>>
]>>  Are the fields "fh_Type" and "fh_Port" in backwards order in the 
]>>  include file?
]>>
]>
]>No, they are in the correct order in the include files.  The
]>manual is incorrect.
]>
]>Are you aure Chuck's example is looking into a filehandle to find the
]>console.device ?  Rather than getting the console process
]>by a FindTask(0) and using the process pointer to the
]>ConsoleTask, then sending a packet to the console task, and
]>getting a return value ?
]>

Yes, I'm sure.  His code does not enable raw io mode for the console
per se, but rather any level 2 file:

     raw(fp)
       FILE * fp;
and  cooked(fp)

I did a lot of poking around with the various structures I could get access
to; i.e, process structures, filehandles, FILE *, etc. and it became obvious
after awhile that doing raw(stdin) did indeed end up accessing the same
FileHandles ultimately as I got by looking at the fields in the Process
structure.  So this gives you two completely different ways of approaching
the problem.  I like Chuck's method in that in works for any arbitrary
input stream (as if I had fopen'ed CON:xxxx and suddenly wanted that window
switched to RAW mode) -- assuming an interactive input source of course --
rather than my original method of poking at the Process structure, which
only works to switch my initial CLI window.  However, Chuck's method does
have the disadvantage of being compiler specific in that the means of getting
to the console.device from an open "FILE *" is strictly dependent on 
the way your stdio library is put together.

As for the reversed order of things in the include files:  I wrote several
C programs which poked at and/or displayed all the process fields et al and
it still seems to me that the include file is backwards.  The fh_Port field
was normally $FFFFFFFF (-1) which sure looks like the "Interactive" field
to me; whereas the fh_Type field contained a value which was the same
as the FileHandle pointer I obtained by several other methods (such as
"fileno(stdin)", and Process->pr_ConsoleTask.  In my manual the Filehandle
fields are documented as:

    LONG Link		not used
    LONG Interact	boolean, true if interactive
    LONG ProcessID	process ID of handler process
    BPTR Buffer		buffer for internal use
    ...

whereas the include file has:

    struct FileHandle {
       struct Message * fh_Link;
       struct MsgPort * fh_Port;
       struct MsgPort * fh_Type;
       LONG             fh_Buf;
       ...


Now; it seemed strange to me that I have to use fh_Type rather than fh_Port
to get at the console handler.  Even if this usage is correct; but then,
what purpose does fh_Port serve?  And is it really a pointer to a MsgPort
or just a long integer [as the manual claims].  I thought fh_Port was
the interactive flag since it was set to -1; plus it goes to zero if
I redirect input from somewhere else (like NIL:).

      Just curious,

        Mark Lanzo

cmcmanis%pepper@Sun.COM (Chuck McManis) (06/07/88)

In article <3928@cbmvax.UUCP> andy@cbmvax.UUCP (Andy Finkel) writes:
->Are you aure Chuck's example is looking into a filehandle to find the
->console.device ?  Rather than getting the console process
->by a FindTask(0) and using the process pointer to the
->ConsoleTask, then sending a packet to the console task, and
->getting a return value ?
->andy finkel		{ihnp4|seismo|allegra}!cbmvax!andy 

Yes, he's sure. I needed to turn an arbitrary level 2 FILE * pointer 
into a RAW: or CON: window, and looked at the ConsPkts code (which only
worked on StdIn) and made it work on anything (in the Lattice world).
They have a pointer to the DOS FileHandle that is returned when you 
use Open() to open a console window. (as in Open("CON:",..))


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.