[comp.sys.apollo] Reading from stdin when using GPR

bernie@cidam.rmit.oz (Bernard Kirby) (01/06/88)

I have a few questions about using GPR routines and input/output from the 
key board of a DN3000 DOMAIN/IX BSD4.2 (SR 9.5)

I am _required_ to read from stdin, so opening an input pad isn't much use as
you have to use whatever stream ID the display manager gives it.

If I initiate the graphics in direct mode then the "input pad" at the bottom
of the window will accept input read from stdin, however, you still can't 
read from anyplace in the graphics window. This is annoying, as is the fact
that if you don't position the cursor at the extreame left of the window
the extra space is actually read in as spaces - thus a mis-positioned
string results (at best, or some information gets written over on the screen).

If I initiate the graphics in frame mode the situation improves somewhat, I
can read some things from stdin, but not all (may be this is a bug - see 
example program below). In particular, when I want to read in strings, (with
"gets" for instance) direct mode works, but frame mode doesn't. This has me 
terribly confused as both modes will read in a number OK (with "scanf").
Frame mode has the disadvantage of redrawing things all the time - it looks
really stupid sometimes.

Of course, for borrow mode, it out of the question for this kind of thing.

My questions are:

	a) Is there any simple way of reading and writing using stdin/stdout
	   when using gpr routines. 

	b) Are there any pad calls that can be used to setup the desired
	   type of IO.

I've included a sample mickey mouse program that combines graphical IO with
normal IO. This is only intended to be an experimental program so I could 
see the effects/problems of trying the different modes with normal IO calls,
in particular, the calls to read in the radius of a circle, and a text string.
The call to scanf to read the radius of a circle works fine in frame mode, but
the call to gets to read a string doesn't (I've replaced with about every 
other conceivable method for reading a string with no changes in behavior).
Any hints on how other people handle these problems would be appreciated.


/*
	A simple mickey mouse test program.
	User selects Borrow mode, Direct mode or Frame mode, then
	sees what happens regarding input from keyboard.
	In general, the user positions the cursor with the mouse
	(or whatever) and hits the apropriate key (on the keyboard)
	from the menu. When "t" is hit the program tries to read in a 
	text string to display. When "c" is hit the program tries to 
	read a value for the radius of a circle.

	Note:- there are lots of "acquire_display" and "release_display" calls
	       that are not needed in all modes - they shouldn't make any
	       difference.
 */

#include "/sys/ins/base.ins.c"
#include "/sys/ins/gpr.ins.c"
#include "/sys/ins/pad.ins.c"
#include <stdio.h>

gpr_$offset_t        init_bitmap_size;   /* size of the initial bitmap    */
gpr_$bitmap_desc_t   init_bitmap;        /* descriptor of initial bitmap  */
gpr_$display_mode_t  mode;               /* display mode                  */
gpr_$plane_t         hi_plane_id = 3;    /* highest plane in bitmap       */
boolean              delete_display;     /* This value ignored in borrow mode */
status_$t            status;             /* error code                    */
gpr_$keyset_t        keys;


#define MIN(x,y) (x < y ? (x) : (y))

/*
	Set up the size of the bit map so it fits in the current window.
	Also set up color and text font.
*/
setup()
{
	short i, font_id;
	int size;
	pad_$window_list_t window_info;
	short n_windows;

	pad_$set_scale(stream_$stdout,
		       1,
		       1,
		       status);

	n_windows = 0;
	pad_$inq_windows(stream_$stdout,
			 window_info,
				  10,
			   n_windows,   /* <====== HOW???  */
			     status);
	fprintf(stderr,"n_windows = %d\n",n_windows);

	size = MIN(window_info[0].width, window_info[0].height);

        init_bitmap_size.x_size = size;
        init_bitmap_size.y_size = size; 

        gpr_$init(mode,
                  stream_$stdout,
                  init_bitmap_size,
                  hi_plane_id,
                  init_bitmap,
                  status);
  
	gpr_$set_cursor_active(false,status);

        /*  create a key set for the event interupts  */

        lib_$init_set(keys,(short)256);

        for (i=32; i < 128; i++) 
            lib_$add_to_set(keys,(short)256,i);

        /*  set default color (colour)   */

        gpr_$set_draw_value(7L,status); 
        gpr_$set_text_value(7L,status);
        gpr_$set_text_background_value(0L,status);

	/*  Load in a font  */

        gpr_$load_font_file("f16.b",(short)5,font_id,status);
        gpr_$set_text_font(font_id,status);

	/*  Clear screen  */

	gpr_$acquire_display(status);
        gpr_$clear(0L,status); /* clear to black */
	gpr_$release_display(status);
}


char get_location( wx, wy )
	short *wx, *wy;
{
        gpr_$event_t     et;
        char             ed;
        gpr_$position_t  pos;
        boolean          wait;

	gpr_$acquire_display(status);

        gpr_$set_cursor_active(true,status);

        gpr_$enable_input(gpr_$keystroke,keys,status);
        gpr_$enable_input(gpr_$buttons,keys,status);

        wait = gpr_$event_wait(et,ed,pos,status);

        gpr_$set_cursor_active(false,status);

        gpr_$disable_input(gpr_$keystroke,status);
        gpr_$disable_input(gpr_$buttons,status);

        *wx = pos.x_coord ;
        *wy = pos.y_coord ;

	gpr_$release_display(status);
        return(ed);
}

draw()
{
	char c, s[120];
	short x, y;
	int rad;
	gpr_$position_t center;

	gpr_$acquire_display(status);
	gpr_$move(20,20,status);
	gpr_$text("q - quit, m - move, d - draw, c - circle, t - text",51,status);
	gpr_$release_display(status);

	while( ( c = get_location(&x, &y)) != 'q')
		switch (c) {
			case 'm' : gpr_$move(x, y, status);
				   break;
			case 'd' : gpr_$acquire_display(status);
				   gpr_$line(x, y, status);
				   gpr_$release_display(status);
				   break;
			case 'c' : gpr_$move(20,40,status);
				   gpr_$acquire_display(status);
				   gpr_$text("Enter radius (in pixels): ",25,status);
				   gpr_$release_display(status);
				   scanf("%d",&rad); getchar();
				   center.x_coord = x;
				   center.y_coord = y;
				   gpr_$acquire_display(status);
				   gpr_$circle(center,(short)rad,status);
			           gpr_$move(20,40,status);
				   gpr_$text("                          ",25,status);
				   gpr_$release_display(status);
				   break;
			case 't' : gpr_$move(20,40,status);
				   gpr_$acquire_display(status);
				   gpr_$text("Enter text: ",12,status);
				   gpr_$release_display(status);
				   gets(s);
				   gpr_$acquire_display(status);
			           gpr_$move(x, y, status);
				   gpr_$text(s[0],(short)strlen(s),status);
			           gpr_$move(20,40,status);
				   gpr_$text("            ",12,status);
				   gpr_$release_display(status);

		}
}

main()
{
	char c;

	printf("Enter display mode [B|D|F]: ");
	c = getchar(); getchar();

	switch (c) {
		case 'b':
		case 'B': mode = gpr_$borrow;
			  break;
		case 'd':
		case 'D': mode = gpr_$direct;
			  break;
		case 'f':
		case 'F': mode = gpr_$frame;
			  break;
		default:  fprintf(stderr,"Unknown mode '%c'\n",c);
			  exit(1);
	}

	setup();

	draw();

	gpr_$terminate(delete_display,status);
}


------------------------------------------------------------------------
PS. Take a look at the  line labeled " <===== HOW ????? " in the program
    above. I have this variable called "n_windows" which is declared
    locally as (as per an example in one of the manuals)

		short n_windows;

    _NO_ asterisk (*) in front of it at all.

    Then there is the call to pad_$inq_winows, with _NO_ ampersand (&)
    infront of the variable n_windows.
    How does n_windows attain the correct value of one (usually) as a result
    of this call?
    This is a problem that has also confused me somewhat, as I always thought
    that you had to pass a pointer or an address to get values like this
    back out of a routine. This kind of thing is all through the apollo
    manuals, I mean look at the variable font_id above and how it's 
    declared - how does it get it's value assigned?
    (I just thought I'd ask)

Bernie Kirby.

Arpanet:  bernie%cidam.oz.au@uunet.uu.net
Uucp:     bernie%cidam.oz.au@uunet.uucp