[comp.sources.x] REPOST: v11i095: Another Star Trek Game, Part09/14

pfuetz@agd.fhg.de (03/01/91)

Submitted-by: pfuetz@agd.fhg.de
Posting-number: Volume 11, Issue 95
Archive-name: xstrek/part09

#!/bin/sh
# To unshare, sh or unshar this file
echo xstrek/gpr.c 1>&2
sed -e 's/^X//' > xstrek/gpr.c <<'E!O!F! xstrek/gpr.c'
X#include "gpr.h"
X
X/*  
X  I took the original code of Dan Lovinger, Dec, 1990, CMU  and the code
X  of Tood W Mummert, Dec 1990, CMU and hacked it in order to get it work
X  with the game strek written by Justin S.  Revenaugh Jul, 1987, MIT.
X
X  I also added some comments about the original GPR routines so that any
X  user of  this package might  get a  small inside in what this routines
X  are meant to do. This package tries to emulate the APOLLO GPR (Graphic
X  Primitive   routines) routines that are part   of their OS (Domain OS)
X  (AEGIS) version 9.5  or 9.7.   I've included  the include   files  for
X  reference purposes,  so that anyone  trying  to  build a proper  gpr2X
X  library can see how the datatypes are defined.
X*/
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void cal_$decode_local_time (decoded_clock)                        */
X/*                                                                    */
X/* output:                                                            */
X/* cal_$timedate_rec_t  decoded_clock;                                */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Returns the local time in integer format ("year, month, day, hour, */
X/*                                            minute, second").       */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid  caldecodelocaltime_ (array)
X
Xshort int   array[6];
X
X{
X   time_t      clock;
X   struct tm   *lt;
X
X
X
X   (void) time(&clock);
X   lt = localtime(&clock);
X   array[0] = lt->tm_year + 1900;
X   array[1] = lt->tm_mon + 1;
X   array[2] = lt->tm_mday;
X   array[3] = lt->tm_hour;
X   array[4] = lt->tm_min;
X   array[5] = lt->tm_sec;
X} /* caldecodelocaltime_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void cal_$float_clock (clock, float_seconds)                       */
X/*                                                                    */
X/* input:                                                             */
X/* time_$clock_t  clock;                                              */
X/*                                                                    */
X/* output:                                                            */
X/* double         float_seconds;   # this is 8 byte long              */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Converts a system clock representation to the equivilent number of */
X/* seconds in double-precision floating-point format. Unlike          */
X/* cal_$clock_to_sec this routine does not truncate the fractional    */
X/* portion of the conversion.                                         */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid calfloatclock_ (clock, floatclock)
X
Xshort int   clock[3];
Xdouble      *floatclock;
X
X{
X   *floatclock = (double) (clock[0] * 65536) +
X                 (double) (clock[1]) +
X                 ((double) (clock [2]) / (1000000/4));
X
X/*
X   *floatclock = ((((clock[0] * 65536) + clock[1]) * 65536) + clock[3]) 
X                 / 250000;
X*/
X} /* calfloatclock_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void cal_$get_local_time (clock)                                   */
X/*                                                                    */
X/* output:                                                            */
X/* time_$clock_t  clock;                                              */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Returns the current local time in system clock representation.     */
X/* This is the number of 4-microsecond periods that have elapsed      */
X/* since January 1, 1980, 00:00.                                      */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid calgetlocaltime_ (clock)
X
Xshort int   clock[3];
X
X{
X   struct timeval tv;
X   long           tmp_micro;
X
X
X
X   gettimeofday(&tv, 0);
X
X   clock[0] = tv.tv_sec >> 16;
X   clock[1] = tv.tv_sec & 0xffff;
X   clock[2] = tv.tv_usec/4;
X
X/*
X   tmp_micro = tv.tv_sec * 250000 + tv.tv_usec/4;
X
X   clock[2] = tmp_micro & 0x000000ff;
X   clock[1] = (tmp_micro & 0x0000ff00) >> 16;
X   clock[0] = (tmp_micro & 0x00ff0000) >> 32;
X*/
X} /* calgetlocaltime_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void cal_$sec_to_clock (seconds, clock)                            */
X/*                                                                    */
X/* input:                                                             */
X/* int  seconds;     # 4-byte integer                                 */
X/*                                                                    */
X/* output:                                                            */
X/* time_$clock_t  clock;                                              */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Converts seconds to system clock units. No overflow detection is   */
X/* performed.                                                         */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid calsectoclock_ (seconds, clock)
X
Xint         *seconds;
Xshort int   clock[3];
X
X{
X   long tmp;
X   long tmp_micro;
X
X
X
X   tmp = (long) *seconds;
X
X   clock[0] = tmp >> 16;
X   clock[1] = tmp & 0xffff;
X   clock[2] = 0;
X/*
X   tmp_micro = *seconds * 250000;
X
X   clock[2] = tmp_micro & 0x000000ff;
X   clock[1] = (tmp_micro & 0x0000ff00) >> 16;
X   clock[0] = (tmp_micro & 0x00ff0000) >> 32;
X*/
X} /* calsectoclock_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* Where does this come from?                                         */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid getusername_ (name, namlen)
X
Xchar  *name;
Xlong  *namlen;
X
X{
X   struct passwd        *pwd;
X   char                 *tname;
X   int                  i;
X   extern char          *getenv();
X   extern struct passwd *getpwuid();
X
X
X
X   if ((pwd = getpwuid(getuid())) != NULL)
X   {
X      tname = pwd->pw_name;
X   }
X   else
X   if ((tname = getenv("USER")) == NULL &&
X       (tname = getenv("LOGNAME")) == NULL)
X   {
X      tname = "intruder\0";
X   }
X   (void) strncpy(name, tname, 8);
X   for (i=strlen(tname);i<10;i++)
X      name[i] = ' ';
X   name[10] = '\0';
X} /* getusername_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$bit_blt (source_bitmap_desc, source_window,              */
X/*                    source_plane, dest_origin, dest_plane, status)  */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$bitmap_desc_t  source_bitmap_desc;                            */
X/* gpr_$window_t       source_window;                                 */
X/* gpr_$plane_t        source_plane;                                  */
X/* gpr_$position_t     dest_origin;                                   */
X/* gpr_$plane_t        dest_plane;                                    */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t           status;                                        */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Performs a bit block transfer from a single plane of any bitmap to */
X/* a single plane of the current bitmap. source_window is a           */
X/* rectangular section of the bitmap from which to transfer pixels.   */
X/* source_plane is the identifier of the single plane of the source   */
X/* bitmap to move. dest_origin is the start position (top left        */
X/* coordinate position) of the destination rectangle. status is the   */
X/* completion status.                                                 */
X/* Both the source and destination bitmaps can be in either display   */
X/* memory or main memory. If the source bitmap is a Display Manager   */
X/* frame, the only allowed raster op codes are 0, 5, A, and F. These  */
X/* are the raster operations in which the source plays no role. If a  */
X/* rectangle is transferred by a BLT to a Display Manager frame and   */
X/* the frame is refreshed for any reason, the BLT is re-executed.     */
X/* Therefore, if the information in the source bitmap has changed,    */
X/* the appearance of the frame changes accordingly.                   */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprbitblt_ (bitmap, window, plane, dsto, dstp, status)
X
Xbitmap_desc_t  *bitmap;
Xshort          window[4];
Xplane_t        *plane;
Xshort          dsto[2];
Xplane_t        *dstp;
Xlong           *status;
X
X{  
X   if (lop==6)
X      XFillRectangle(d, w, EraseGC, (int)dsto[0], (int)dsto[1],
X                     (int)window[2], (int) window[3]);
X   else
X   {
X      XCopyArea (d, w, w, FillGC,
X                 (int)window[0],(int) window[1],
X                 (int)window[2],(int) window[3],
X                 (int)dsto[0], (int)dsto[1]);
X   }
X   *status = 0;
X} /* gprbitblt_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$circle (center, radius, status)                          */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$position_t  center;                                           */
X/* short            radius;   # 2-byte integer in 1-32767             */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t        status;                                           */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws a circle with the specified radius around the specified      */
X/* center point. gpr_$circle does not change the current position.    */
X/* When you have clipping enabled, you can specify coordinates        */
X/* outside the bitmap limits. With clipping disabled, specifying      */
X/* coordinates outside the bitmap limits results in an error.         */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprcircle_ (center, radius, status)
X
Xshort int   center[2];
Xshort int   *radius;
Xlong        *status;
X
X{
X   long           size = *radius;
X   int            x = center[0] - size;
X   int            y = center[1] - size;
X   unsigned int   width = size+size;
X   unsigned int   height = size+size;
X   long           moon = 1;
X
X
X
X    if (moon) /* Release 3 server paint circles awfully slow */
X       if ((strncmp(ServerVendor(d), "MIT", 3) == 0) &&
X           VendorRelease(d) < 4)
X          return;
X
X   XDrawArc (d, w, DrawGC, x, y, width, height, (int)0, (int)360*64);
X} /* gprcircle_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$circle_filled (center, radius, status)                   */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$position_t  center;                                           */
X/* short            radius;   # 2-byte integer in 1-32767             */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t        status;                                           */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws and fills a circle with the specified radius around the      */
X/* specified center point. gpr_$circle_filled does not change the     */
X/* current position. When you have clipping enabled, you can specify  */
X/* coordinates outside the bitmap limits. With clipping disabled,     */
X/* specifying coordinates outside the bitmap limits results in an     */
X/* error.                                                             */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprcirclefilled_ (center, radius, status)
X
Xshort int   center[2];
Xshort int   *radius;
Xlong        *status;
X
X{
X   long           size = *radius;
X   int            x = center[0] - size;
X   int            y = center[1] - size;
X   unsigned int   width = size+size;
X   unsigned int   height = size+size;
X
X   XFillArc (d, w, FillGC, x, y, width, height, (int)360*64, (int)-360*64);
X} /* gprcirclefilled_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* Boolean gpr_$cond_event_wait (event_type, event_data, position,    */
X/*                               status)                              */
X/*                                                                    */
X/* return value:                                                      */
X/* Boolean gpr_$cond_event_wait( ... )                                */
X/*                                                                    */
X/* output:                                                            */
X/* gpr_$event_t  event_type;                                          */
X/* char          *event_data;                                         */
X/* gpr_$position_t  position;                                         */
X/* status_$t     status;                                              */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Returns information about the occurrence of any event without      */
X/* entering a wait state. The boolean return value indicates whether  */
X/* or not the window is obscured; a false value means that the window */
X/* is obscured. This value is always true unless the program has      */
X/* called gpr_$set_obscured_opt(...) and specified an option of       */
X/* gpr_$ok_if_obs. The event_type is the type of event that occurred. */
X/* It is one of the following: gpr_$keystroke (input from a keyboard) */
X/* gpr_$buttons (Input from mouse or bitpad puck buttons)             */
X/* gpr_$locator (input from a touchpad or mouse) gpr_$entered_window  */
X/* (cursor has entered window) gpr_$left_window (cursor has left      */
X/* window) gpr_$locator_stop (input from a locator has stopped) and   */
X/* gpr_$no event (no event has occurred). event_data is the keystroke */
X/* or button character associated with the event, or the character    */
X/* that identifies the window associated with an entered window event.*/
X/* This parameter is not modified for other events. position is the   */
X/* position on the screen or within the window at which graphics      */
X/* input occurred. status is the completion status.                   */
X/*                                                                    */
X/* When called this routine returns immediately and reports           */
X/* information about any event that has occured. The routine allows   */
X/* the program to obtain information about an event without having to */
X/* suspend all of its activities. Unless locator data has been        */
X/* processed since the last event was reported, position will be the  */
X/* last position given to gpr_$set_cursor_position(...). If locator   */
X/* data is received during this call, and gpr_$locator events are not */
X/* enabled, the GPR software will display the arrow cursor and will   */
X/* set the keyboard cursor position. Although this call never waits   */
X/* it may release the display if it receives an unenabled event that  */
X/* needs to be handled by the Display Manager. The input routines     */
X/* report button events as ASCII characters. "Down" transitions range */
X/* from "a" to "d"; "up" transitions range from "A" to "D". The three */
X/* mouse keys start with (a/A) on the leftside. As with keystroke     */
X/* events, button events can be selectively enabled by specifying a   */
X/* button keyset.                                                     */
X/*                                                                    */
X/* ================================================================== */
X
Xint gprcondeventwait_ (event, key, posn, status)
X
Xshort       *event;
Xchar        *key;
Xposition_t  *posn;
Xlong        *status;
X
X{
X   static unsigned long flag[16] = {0, 0, 0, 0};
X   XEvent               ev;
X   int                  paused = 0;
X   char                 keystr;
X   int                  early_return;
X   XWindowAttributes    wattr;
X   Window               dummywin;
X   int                  rx, ry;
X
X
X
X   *event=0;
X   *key=0;
X
X   if (was_placed)
X   {
X      XSync(d, False);
X      XSelectInput(d,w, ExposureMask|PointerMotionMask|
X                        ButtonPressMask|ButtonReleaseMask|
X                        KeyPressMask| StructureNotifyMask );
X      was_placed = False;
X   }
X
X   XFlush(d);
X   if (XPending(d))
X      while (XPending(d) || paused)
X      {
X         if (!paused)
X            XNextEvent(d, &ev);
X         else
X            XWindowEvent(d,w,KeyPressMask|StructureNotifyMask,&ev);
X      }
X   else
X      return 0;
X
X   switch(ev.type)
X   {
X/*
X      case Expose:
X         if (((XExposeEvent*) &ev)->count)
X            break;
X
X         XSelectInput(d, w, StructureNotifyMask);
X         XSync(d, True);
X
X	 XMoveResizeWindow(d, w, 0, 0, wid+1, hei+1);  
X	 XWindowEvent(d, w, StructureNotifyMask, &ev);
X
X	 XGetWindowAttributes(d, w, &wattr);
X	 XTranslateCoordinates(d, w, wattr.root, 0, 0,
X			       &rx, &ry, &dummywin);
X
X	 XMoveResizeWindow(d, w, -rx, -ry, wid, hei);  
X	 XWindowEvent(d, w, StructureNotifyMask, &ev);
X
X	 XSelectInput(d, w, NoEventMask);
X	 XSync(d, False);
X	 was_placed = True;
X
X	 mouse_posn.x = ev.xexpose.x;
X	 mouse_posn.y = ev.xexpose.y;
X	 *posn = mouse_posn;
X	 return 1;
X
X      case UnmapNotify:
X	 paused = 1;
X         return 0;
X
X      case MapNotify:
X	 paused = 0;
X	 return 0;
X
X      case MotionNotify:
X	 mouse_posn.x = ev.xmotion.x;
X	 mouse_posn.y = ev.xmotion.y;
X	 return 0;
X
X      case ButtonPress:
X	 mouse_posn.x = ev.xbutton.x;
X	 mouse_posn.y = ev.xbutton.y;	    
X	 *key = ev.xbutton.button + 'a' - 1;
X	 flag[ev.xbutton.button]=1;
X	 *posn = mouse_posn;
X	 return 1;
X
X      case ButtonRelease:
X	 mouse_posn.x = ev.xbutton.x;
X	 mouse_posn.y = ev.xbutton.y;
X	 *key = ev.xbutton.button + 'A' - 1;
X	 flag[ev.xbutton.button]=0;
X	 *posn = mouse_posn;
X	 return 1;
X*/
X
X      case KeyPress:
X      {
X	 early_return = False;
X
X	 mouse_posn.x = ev.xmotion.x;
X	 mouse_posn.y = ev.xmotion.y;
X         *posn = mouse_posn;
X
X	 XLookupString(&ev.xkey,&keystr,1,(KeySym *) 0,
X		       (XComposeStatus *) 0);
X/*
X         if (XLookupString(&ev.xkey,&keystr,1,(KeySym *) 0,
X                           (XComposeStatus *) 0) == 1)
X            switch (keystr)
X	    {
X	       case 'p': case 'P':
X	          paused = 1;
X		  break;
X               case 'c': case 'C':
X	          paused = 0;
X		  break;
X               case 'i': case 'I': case ' ':
X                  XIconifyWindow(d, w, d->default_screen);
X		  break;
X               case 'r': case 'R':
X                  XSelectInput(d, w, StructureNotifyMask);
X		  XSync(d, True);
X		  XMoveResizeWindow(d, w, 0, 0, wid+1, hei+1);  
X		  XWindowEvent(d, w, StructureNotifyMask, &ev);
X
X		  XGetWindowAttributes(d, w, &wattr);
X		  XTranslateCoordinates(d, w, wattr.root, 0, 0,
X		                        &rx, &ry, &dummywin);
X
X		  XMoveResizeWindow(d, w, -rx, -ry, wid, hei);  
X		  XWindowEvent(d, w, StructureNotifyMask, &ev);
X
X		  XSelectInput(d, w, NoEventMask);
X		  XSync(d, False);
X		  was_placed = True;
X
X		  *key = 'R';
X		  early_return = True;
X		  break;
X               case '\003': case 'q': case 'Q':
X                  *key = 'Q';
X		  early_return = True;
X		  break;
X               default:
X                  break;
X            }
X         if (early_return)
X	 {
X            mouse_posn.x = ev.xkey.x;
X	    mouse_posn.y = ev.xkey.y;
X	    *posn = mouse_posn;
X	    return 1;
X         }
X*/
X         *event = 1;
X	 *key = keystr;
X	 return 1;
X      }  
X   }
X   *posn = mouse_posn;
X   return 0;
X} /* gprcondeventwait_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$enable_input (event_type, key_set, status)               */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$event_t  event_type;                                          */
X/* gpr_$keyset_t key_set;                                             */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t     status;                                              */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Enables an event type and a selected set of keys.                  */
X/* For event_type look at gpr_$cond_event_wait(...). key_set is a set */
X/* of specifically enabled characters when the event class is in      */
X/* gpr_$keyset_t format. In Pascal (AEGIS, e.g. DomainOS was written  */
X/* in pascal!), this is a set of characters. In Fortran and C this    */
X/* can be implemented as an eight element array of 4-byte integers.   */
X/* This parameter is specified for event types of gpr_$keystroke and  */
X/* gpr_$butons. status is, as always, the completion status.          */
X/* This routine will release and reacquire the display. This routine  */
X/* specifies the type of event and event input for which              */
X/* gpr_$event_wait(...) is to wait. This routine applies to the       */
X/* current bitmap. However, enabled input events are stored in        */
X/* attribute blocks (not with bitmaps) in much the same way as        */
X/* attributes are. When a program chnages attribute blocks for a      */
X/* bitmap during a graphics session, the input events you enabled are */
X/* lost unless you enable those events for the new attribute block.   */
X/* Programsmust call this routine once for each event type to be      */
X/* enabled. No event types are enabled by default. The keyset must    */
X/* correspond to the specified event type. For example, use           */
X/* ['#'...'~'] (in Pascal) to enable all normal printing graphics.    */
X/* Use [chr(0)..chrchr(127)] to enable the entire ASCII character set.*/
X/* Except in borrow-display mode, it is a good idea to leave at least */
X/* the CMD and NEXT_WINDOW keys out of the keyset so that the user    */
X/* can access other Display Manager windows. The insert files         */
X/* /sys/ins/kbd.ins.[c,pas,ftn] contain definitions for the non-ASCII */
X/* keyboard keys in the range 128-255. Events and keyset data not     */
X/* enabled with this routine will be handled by the Display Manager   */
X/* in frame or direct mode and discarded in borrow-display mode. When */
X/* locator events are disabled, the GPR software will display the     */
X/* arrow cursor and will set the keyboard cursor position when        */
X/* locator data is received.                                          */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprenableinput_ (event_type, key_set, status)
X
Xshort *event_type;
Xlong  key_set[8];
Xlong  *status;
X
X{
X   /* XXX noop */
X} /* gprenableinput */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$init (op_mode, unit, size, hi_plane_id,                  */
X/*                 init_bitmap_desc, status)                          */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$display_mode_t  op_mode;                                      */
X/* stream_$id_t         unit;                                         */
X/* gpr_$offset_t        size;                                         */
X/* gpr_$plane_t         hi_plane_id;                                  */
X/*                                                                    */
X/* output:                                                            */
X/* gpr_$bitmap_desc_t   init_bitmap_desc;                             */
X/* status_$t            status;                                       */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Initializes the graphics primitive package.                        */
X/* op_mode is one of the following: gpr_$borrow (program borrows the  */
X/* full screen and the keyboard from the Display Manager and uses the */
X/* display driver directly through GPR software) gpr_$borrow_nc (same */
X/* as gpr_$borrow except that all the pixels are not set to zero      */
X/* [screen is not cleared]) gpr_$direct (program borrows a window     */
X/* from the Display Manager instead of borrowing the whol display)    */
X/* gpr_$frame (program executes within a frame of a Display Manager   */
X/* Pad) gpr_$no_display (GPR allocates a bitmap inmain memory. No     */
X/* graphics is displayed on the screen). unit has three possible      */
X/* meanings, as follows: 1.) the display unit, if in gpr_$borrow or   */
X/* gpr_$borrow_nc. The only valid display unit number is 1. 2.) The   */
X/* stream identifier for the pad, if the graphics routines are to     */
X/* operate in frame or direct mode. 3.) Any value, if in              */
X/* gpr_$no_display mode. size is the size of the initial bitmap (and  */
X/* the size of the frame, in frame mode). Possible values are:        */
X/*                                      x            y                */
X/* Borrow-display or direct mode:  1 to 1024    1 to 1024             */
X/* (limits are reduced to display                                     */
X/*  or window size if necessary)                                      */
X/* Display Manager Frame:          1 to 32767   1 to 32767            */
X/* Main Memory Bitmap:             1 to 8192    1 to 8192             */
X/* hi_plane_id is the identifier of the bitmap's highest plane.       */
X/* Possible values are: 0 for monochromatic displays, 0-3 for         */
X/* colordisplays in two-board colfiguration, 0-7 for color displays   */
X/* in three-board configuration, 0-7 for main memory bitmaps.         */
X/* init_bitmap_desc is the descriptor of the initial bitmap that      */
X/* uniquely identifies the bitmap. status is the completion status.   */
X/*                                                                    */
X/* To use multiple windows, you must call gpr_$init for each window.  */
X/* If a program executes in borrow-display mode or direct-mode, the   */
X/* size of the initial bitmap can be equal to or smaller than the     */
X/* display. If the program executes in a frame of a Display Manager   */
X/* Pad, "size" specifies the size of both the frame and the initial   */
X/* bitmap. (In frame mode, the frame and the bitmap must be the same  */
X/* size.) If the program does not use the display, gpr_$init(...)     */
X/* creates a bitmap in main memory of the given size. To use imaging  */
X/* formats, aprogram must be initialized in borrow display mode.      */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprinit_ (flag, xx, size, yy, bitmapdesc, status)
X
Xfloat       *flag;
Xint         *xx;
Xshort int   size[2];
Xint         *yy;
Xlong int    *bitmapdesc;
Xlong        *status;
X
X{
X   XEvent            ev;
X   XWindowAttributes wattr;
X   Window            dummywin;
X   int               rx, ry;
X
X
X
X   XSelectInput(d, w, ExposureMask|PointerMotionMask|
X                      ButtonPressMask|ButtonReleaseMask|KeyPressMask);
X/*
X   XMapWindow(d, w);
X   XWindowEvent(d, w, ExposureMask, &ev);
X#if 0
X   while (XGrabPointer (d, w, False,
X		        PointerMotionMask|ButtonPressMask|ButtonReleaseMask,
X		        GrabModeAsync,
X		        GrabModeAsync,
X		        w, None, ev.xmotion.time) != GrabSuccess)
X   {
X      printf("couldn't grab cursor.. waiting 1 second..\n");
X      sleep(1);
X   }
X   printf("cursor grabbed..\n");
X#endif
X   XGrabServer(d);
X*/
X
X   XMapRaised(d, w);
X   do
X      XWindowEvent(d, w, ExposureMask, &ev);
X   while(((XExposeEvent*) &ev)->count);
X
X   XSelectInput(d, w, StructureNotifyMask);
X   XSync(d, True);               /*  get rid of anything outstanding */
X
X  /* i cheat and change width and height by 1....this almost guarantees
X     i'll generate a ConfigureRequest event.
X   */
X   XMoveResizeWindow(d, w, 0, 0, wid+1, hei+1);  
X   XWindowEvent(d, w, StructureNotifyMask, &ev);
X
X   XGetWindowAttributes(d, w, &wattr);           /* check to see where the */
X   XTranslateCoordinates(d, w, wattr.root, 0, 0, /* wm actually placed it */
X			 &rx, &ry, &dummywin);
X
X   XMoveResizeWindow(d, w, -rx, -ry, wid, hei);  
X   XWindowEvent(d, w, StructureNotifyMask, &ev);
X
X   XSelectInput(d, w, NoEventMask);
X   XSync(d, False);
X   was_placed = True;
X
X   *status = 0;		/* XXX most args */
X} /* gprinit_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$inq_config (config, status)                              */
X/*                                                                    */
X/* output:                                                            */
X/* gpr_$display_config_t  config;                                     */
X/* status_$t              status;                                     */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Returns the current display configuration.                         */
X/* config can be one of the predifined values: gpr_$bw_800x1024,      */
X/* gpr_$bw_1280x1024, gpr_$color_1024x1024x8, gpr_$color_1280x1024x8, */
X/* ... status is the completion status. gpr_$inq_config(...) can be   */
X/* used before gpr_$init(...). This is useful to determine the number */
X/* of possible planes in bitmaps on color displays before initializing*/
X/* GPR.                                                               */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprinqconfig_ (config, status)
X
Xlong  *config;
Xlong  *status;
X
X{
X   XSetWindowAttributes attr;
X   XColor               color;
X   Cursor               c;
X   Font                 f;
X   XGCValues            xgcv;
X   unsigned long        fcolor;
X   unsigned long        bcolor;
X   Colormap             cmap;
X   XColor               exact;
X   XColor               closest;
X   XWMHints             wmhints;
X   int                  i;
X   int                  ncolors  = MAX_COLORS;
X   /* These colors chosen at random */
X   static char          *ColorName[]   =  {"Black",
X                                           "White",
X                                           "Red",
X                                           "Blue",
X                                           "Yellow",
X                                           "Green",
X                                           "Orange",
X                                           "Sea Green",
X                                           "Coral",
X                                           "Maroon",
X                                           "Orange Red",
X                                           "Sky Blue",
X                                           "Violet Red",
X                                           "Brown",
X                                           "Lime Green",
X                                           "Gold"};
X
X
X
X   if (d == 0)
X      d = XOpenDisplay (0);
X   if (d == 0)
X   {
X      printf("can't open display! bye.\n");
X      exit(1);
X   }
X
X   colortrans[1] = fcolor = WhitePixelOfScreen(DefaultScreenOfDisplay(d));
X   colortrans[0] = bcolor = BlackPixelOfScreen(DefaultScreenOfDisplay(d));
X
X   *config = DisplayPlanes(d,0);
X   if (*config != 1)
X   {
X      cmap = XDefaultColormap(d,0);
X      for (i = 0; i < MAX_COLORS; i++)
X      {
X         if (!XParseColor(d, cmap, ColorName[i], &exact))
X         {
X	    fprintf(stderr,"XParseColor: color name %s \
X		            is not in database\n", ColorName[i]);
X	    exit(1);
X	 }
X	 if (!XAllocColor(d,cmap, &exact))
X         {
X	    fprintf(stderr, "XAllocColor: Couldn't allocate %s\n",
X		    ColorName[i]);
X	    exit(1);
X	 }
X	 colortrans[i] = exact.pixel;
X      }
X   }
X   wid = WidthOfScreen(DefaultScreenOfDisplay(d))-4;
X   hei = HeightOfScreen(DefaultScreenOfDisplay(d))-4;
X   w = XCreateSimpleWindow (d, DefaultRootWindow(d),
X			    0, 0,
X			    wid,
X		            hei,
X		            2,
X			    fcolor,
X			    bcolor);
X
X   /* Tell the WM that we want input... */
X   wmhints.input = True;
X   wmhints.flags = InputHint;
X   XSetWMHints(d, w, &wmhints);
X
X   /* Name and raise the window */
X   XStoreName(d, w,"XStrek");
X   XSetIconName(d, w, "XStrek");
X
X/*
X   attr.override_redirect = True;
X   XChangeWindowAttributes (d, w, CWOverrideRedirect, &attr);
X*/
X   xgcv.background = bcolor;
X   xgcv.foreground = fcolor;
X   FillGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
X   xgcv.background = bcolor;
X   xgcv.foreground = bcolor;
X   EraseGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
X   xgcv.background = bcolor;
X   xgcv.foreground = fcolor;
X   DrawGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
X   TextGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
X   f = XLoadFont (d, "fixed");
X   c = XCreateGlyphCursor (d, f, f, ' ', ' ',
X			   &color, &color);
X   XDefineCursor(d, w, c);
X   XSetGraphicsExposures (d, FillGC, False);
X   XSetGraphicsExposures (d, DrawGC, False);
X   XSetGraphicsExposures (d, TextGC, False);    
X   *status = 0;
X} /* gprinqconfig_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$inq_cursor (curs_pat, curs_raster_op, active, position,  */
X/*                       origin, status)                              */
X/*                                                                    */
X/* output:                                                            */
X/* gpr_$bitmap_desc_t      cursor_pat;                                */
X/* gpr_$raster_op_array_t  cursor_raster_op;                          */
X/* Boolean                 active;                                    */
X/* gpr_$position_t         position;                                  */
X/* gpr_$position_t         origin;                                    */
X/* status_$t               status;                                    */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Returns information about the cursor.                              */
X/* cursor_pat is ithe identifier of the cursor pattern bitmap.        */
X/* cursor_raster_op is is operation code. The default value is three. */
X/* (The operation assigns all source values to the new destination.)  */
X/* active is a boolean which indicateswhether the cursor is displayed.*/
X/* True when displayed. position is the current position of the       */
X/* cursor on the screen. origin is the pixel curently set as the      */
X/* cursor origin. status is the completion status.                    */
X/*                                                                    */
X/* In borrow-display mode the position is the absolute position on    */
X/* the screen. In direct or frame mode position is relative to the    */
X/* top left corner of the frame.                                      */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprinqcursor_ (cursor, ops, active, posn, origin, status)
X
Xlong        *active;
Xposition_t  *posn;
Xposition_t  *origin;
Xlong        *status;
X
X{
X   *posn = mouse_posn;
X   *status = 0;
X} /* gprinqcursor_ */
X
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$line (x, y, status)                                      */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$coordinate_t  x;                                              */
X/* gpr_$coordinate_t  y;                                              */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t          status;                                         */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws a line from the current position to the end point supplied.  */
X/* The current position is updated to the end point. When you have    */
X/* cliping enabled, you can specify coordinates outside the bitmap    */
X/* limits. With clipping disabled, specifying coordinates outside the */
X/* bitmap limits results in an error. To set a new position without   */
X/* drawing a line, use gpr_$move(...).                                */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprline_ (x, y, status)
X
Xshort *x;
Xshort *y;
Xlong  *status;
X
X{
X
X   *status = 0;
X   XDrawLine(d, w, DrawGC, curpoint.x, curpoint.y, (int) *x, (int) *y );
X   curpoint.x = *x;
X   curpoint.y = *y;
X} /* gprline_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$load_font_file (pathname, pathname_length, font_id,      */
X/*                           status)                                  */
X/*                                                                    */
X/* input:                                                             */
X/* name_$pname_t  pathname;                                           */
X/* short          pathname_length;       # 2-byte integer             */
X/*                                                                    */
X/* output:                                                            */
X/* short          font_id;               # 2-byte integer             */
X/* status_$t      status;                                             */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Loads a font from a file into the display's font storage area.     */
X/* Use the font_id returned as input for gpr_$set_text_font(...)      */
X/* To unload fonts use gpr_$unload_font_file(...)                     */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprloadfontfile_ (path, pnlen, fontid, status)
X
Xchar  *path;
Xlong  *pnlen;
Xlong  *fontid;
Xlong  *status;
X
X{
X   int i;
X
X
X
X   for (i=0; fontmap[i].gprname; i++)
X   {
X      if (strcmp(path, fontmap[i].gprname) == 0)
X      {
X         *fontid = XLoadFont (d, fontmap[i].xname);
X	 return;
X      }
X   }
X   *fontid = XLoadFont(d, "fixed");
X} /* gprloadfontfile_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$move (x, y, status)                                      */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$coordinate_t  x;                                              */
X/* gpr_$coordinate_t  y;                                              */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t          status;                                         */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Sets the current position to the given position. When you have     */
X/* cliping enabled, you can specify coordinates outside the bitmap    */
X/* limits. With clipping disabled, specifying coordinates outside the */
X/* bitmap limits results in an error.                                 */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprmove_ (x, y, status)
X
Xshort int   *x;
Xshort int   *y;
Xlong        *status;
X
X{
X   curpoint.x = *x;
X   if (curpoint.x == 0)
X      curpoint.x = *(long *)x;
X   curpoint.y = *y;
X   if (curpoint.y == 0)
X      curpoint.y = *(long *)y;
X   *status = 0;
X} /* gprmove_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$multiline (x, y, npositions, status)                     */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$coordinate_array_t  x;                                        */
X/* gpr_$coordinate_array_t  y;                                        */
X/* short                    npositions;      # 2-byte int in 1-32767  */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t          status;                                         */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws a series of disconnected lines. It moves alternately to a    */
X/* new position and draws lines: it moves to the first given position */
X/* then draws a line from the first to the second given position,     */
X/* updates the current position, moves to the third, etc. After all   */
X/* that the last point becomes the current position. When you have    */
X/* cliping enabled, you can specify coordinates outside the bitmap    */
X/* limits. With clipping disabled, specifying coordinates outside the */
X/* bitmap limits results in an error.                                 */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprmultiline_ (x, y, number, status)
X
Xshort *x;
Xshort *y;
Xint   *number;
Xlong  *status;
X
X{
X   int      i;
X   int      count;
X   XSegment *segments;
X
X
X
X   *status = 0;
X   count = *number;
X   /*
X    * gross hack.  we may be passed an integer*2 or an integer*4;
X    * neither is likely to be greater than 2<<16
X    */
X   if (count == 0)
X      count = *((long *)number);
X
X   if (count & 1)
X      printf("odd multiline??\n");
X   /* not exactly what you want.. */
X   segments = (XSegment *)malloc (sizeof(XSegment) * (count/2));
X   for (i=0; i<count; i+= 2)
X   {
X      segments[i/2].x1 = x[i];
X      segments[i/2].y1 = y[i];
X      segments[i/2].x2 = x[i+1];
X      segments[i/2].y2 = y[i+1];
X   }
X   curpoint.x = segments[count/2].x2;
X   curpoint.y = segments[count/2].y2;    
X   XDrawSegments (d, w, DrawGC, segments, count/2);
X   free(segments);
X} /* gprmultiline_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$polyline (x, y, npositions, status)                      */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$coordinate_array_t  x;                                        */
X/* gpr_$coordinate_array_t  y;                                        */
X/* short                    npositions;      # 2-byte int in 1-32767  */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t          status;                                         */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws a series of connected lines. Drawing begins at the current   */
X/* position, draws to the first given coordinat position, then sets   */
X/* the current position to the first given position. This is repeated */
X/* for all given positions. When you have                             */
X/* cliping enabled, you can specify coordinates outside the bitmap    */
X/* limits. With clipping disabled, specifying coordinates outside the */
X/* bitmap limits results in an error.                                 */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprpolyline_ (x, y, number, status)
X
Xshort *x;
Xshort *y;
Xint   *number;
Xlong  *status;
X
X{
X   int      i;
X   int      count;
X   XPoint   *points;
X
X
X
X   *status = 0;
X   count = *number;
X
X   /*
X    * gross hack.  we may be passed an integer*2 or an integer*4;
X    * neither is likely to be greater than 2<<16
X    */
X   if (count == 0)
X      count = *((long *)number);
X	
X   points = (XPoint *) malloc (sizeof(XPoint) * (count + 1));
X   points[0] = curpoint;
X   for (i=0; i<count; i++)
X   {
X      points[i+1].x = x[i];
X      points[i+1].y = y[i];
X   }
X   curpoint = points[count];
X   XDrawLines(d, w, DrawGC, points, count+1, CoordModeOrigin);
X   free(points);
X} /* gprpolyline_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$rectangle (rectangle, status)                            */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$window_t  rectangle;                                          */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t      status;                                             */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws and fills a rectangle in the current bitmap. It fills the    */
X/* rectangle with the color/intensity value specified with            */
X/* gpr_$set_fill_value(...). For unfilled rectangles use              */
X/* gpr_$draw_box(...) or gpr_$polyline(...)                           */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprrectangle_ (window, status)
X
Xshort int   window[4];
Xlong        *status;
X
X{
X   XPoint   tr[4];
X
X
X
X   tr[0].x = window[0];
X   tr[0].y = window[1];
X   tr[1].x = window[0] + window[2];
X   tr[1].y = window[1];
X   tr[2].x = window[0] + window[2];
X   tr[2].y = window[1] + window[3];
X   tr[3].x = window[0];
X   tr[3].y = window[1] + window[3];
X   XFillPolygon (d, w, FillGC, tr, 4, Convex, CoordModeOrigin);
X} /* gprrectangle_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_clipping_active (active, status)                     */
X/*                                                                    */
X/* input:                                                             */
X/* Boolean  active;                                                   */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t  status;                                                 */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Enables/disables a clipping window for the current bitmap. active  */
X/* is a boolean (logical) value that specifies whether or not to      */
X/* enable the clipping window. True => clipping enabled. status is,   */
X/* as always, the completetion status. To specify a clipping window,  */
X/* use gpr_$set_clip_window(...). Initially, in borrow-display mode,  */
X/* the clip window is disabled. In direct mode, the clip window is    */
X/* enabled and clipped to the size of the window. Clipping cannot be  */
X/* enabled in a bitmap corresponding to a Display Manager frame.      */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsetclippingactive_ (flag, status)
X
Xint   *flag;
Xlong  *status;
X
X{
X   if (*flag)
X   {
X      XSetClipRectangles (d, FillGC, 0, 0, &clipr, 1, YXBanded);
X      XSetClipRectangles (d, DrawGC, 0, 0, &clipr, 1, YXBanded);
X      XSetClipRectangles (d, TextGC, 0, 0, &clipr, 1, YXBanded);
X   }
X   else
X   {
X      XSetClipMask (d, FillGC, None);
X      XSetClipMask (d, DrawGC, None);
X      XSetClipMask (d, TextGC, None);		
X   }
X} /* gprsetclippingactive_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_clip_window (window, status)                         */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$window_t  window;                                             */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t      status;                                             */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Changes the clipping window for the current bitmap. The default    */
X/* clip window is the entire bitmap. This call is not allowed on the  */
X/* bitmap corresponding to the Display Manager frame.                 */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsetclipwindow_ (window, status)
X
Xshort int   window[4];
Xlong        *status;
X
X{
X   clipr.x = window[0];
X   clipr.y = window[1];
X   clipr.width = window[2];
X   clipr.height =  window[3];
X} /* gprsetclipwindow_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_color_map (start_index, n_entries, values, status)   */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$pixel_value_t  start_index;                                   */
X/* short               n_entries;          # 2-byte integer           */
X/* gpr_$color_vector_t values;                                        */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t           status;                                        */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Establishes new values for the color map. start_index is the index */
X/* of the first color value entry. n_entries is the number of entries.*/
X/* Valid values are: 2 for monochromatic displays, 1-16 for color     */
X/* displays in 4-bit pixel format, 1-256 for color displays in 8-bit  */
X/* or 24-bit pixel format. values are the color value entries. status */
X/* is the completion status. For the monochromatic display, the       */
X/* default start-index is 0, n-entries is 2, and the values are       */
X/* gpr_$black and gpr_$white. For the monochromatic display, if the   */
X/* program provides fewer than two values, or if the first two vales  */
X/* are the same, the routine returns an error. For the monochromatic  */
X/* display, the graphics primitives simultae a color map by modifying */
X/* the contents of display memory. In direct mode, you must acquire   */
X/* the display before establishing new values for the color map. On a */
X/* monochromatic display in direct mode, the color map can not be     */
X/* modified.                                                          */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsetcolormap_ (start, nentries, values, status)
X
Xpixel_t  *start;
Xlong     *nentries;
Xlong     *values;
Xlong     *status;
X
X{
X   Colormap cmap;
X   XColor   exact;
X   XColor   closest;
X} /* gprsetcolormap_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_cursor_position (position, status)                   */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$position_t  position;                                         */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t        status;                                           */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Establishes a position on the screen for display of the cursor.    */
X/* posistion is the screen coordinate position for display of the     */
X/* cursor. The values must be within the limits of the display in use.*/
X/* (Frame: 0-32767 for x and y). status is the completion status. If  */
X/* the coordinate position would cause any part of the cursor to be   */
X/* outside the screen or frame, the cursor moves only as far as the   */
X/* edge of the screen. The cursor is neither clipped nor made to      */
X/* disappear. In a Display Manager frame, this routine moves the      */
X/* cursor only if the cursor is in the window viewing this frame when */
X/* the call is issued. If not, a "next window" command which moves to */
X/* that window will move the cursor to its new position.              */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsetcursorposition_ (posn, status)
X
Xposition_t  *posn;
Xlong        *status;
X
X{
X   XWarpPointer (d, None, w, 0, 0, 0, 0, posn->x, posn->y);
X} /* gprsetcursorposition_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_draw_value (index, status)                           */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$pixel_value_t  index;                                         */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t           status;                                        */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Specifies the color/intensity value to use to draw lines. index is */
X/* the color map index. If this value equals -2 this specifies using  */
X/* the color/intensity value of the bitmap background as the line     */
X/* drawing value. For borrowed displays and memory bitmaps, the fill  */
X/* background is always zero. For Display Manager frames, this is the */
X/* pixel value in use for the window background. status is the        */
X/* completion status. The default draw value is 1. For monochromatic  */
X/* displays, only the low-order bit of the draw value is considered,  */
X/* because monochromatic displays have only one plane. For color      */
X/* displays in 4-bit pixel format, only the four lowest-order bits of */
X/* the draw value are considered, because these displays have four    */
X/* planes.                                                            */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsetdrawvalue_ (pixel, status)
X
Xlong  *pixel;
Xlong  *status;
X
X{
X   XSetForeground(d, DrawGC, colortrans[*pixel]);
X   *status = 0;
X} /* gprsetdrawvalue_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_fill_value (index, status)                           */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$pixel_value_t  index;                                         */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t           status;                                        */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Specifies the color/intensity value to use to fill circles,        */
X/* rectangle, triangles, and trapezoids. index is                     */
X/* the color map index.  status is the                                */
X/* completion status. The default fill value is 1. For monochromatic  */
X/* displays, only the low-order bit of the draw value is considered,  */
X/* because monochromatic displays have only one plane. For color      */
X/* displays in 4-bit pixel format, only the four lowest-order bits of */
X/* the draw value are considered, because these displays have four    */
X/* planes.                                                            */
X/*                                                                    */
X/* ================================================================== */
X
X
Xvoid gprsetfillvalue_ (pixel, status)
X
Xlong  *pixel;
Xlong  *status;
X
X{
X   XSetForeground(d, FillGC, colortrans[*pixel]);
X   *status = 0;
X} /* gprsetfillvalue_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_raster_op (plane_id, raster_op, status)              */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$plane_t          plane_id;                                    */
X/* gpr_$raster_op_t      raster_op;                                   */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t             status;                                      */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Specifies the raster operation for both BLTs and lines. plane_id   */
X/* identifies the bitmap plane involved in the raster operation.      */
X/* Valid values are zero through the identifier of the bitmap's       */
X/* highest plane. raster_op is the raster operation code. Possible    */
X/* values are zero through fifteen. status is the completion status.  */
X/* The initial raster operation is 3. This operation assigns all      */
X/* source bit values to new destination bit values. Following is a    */
X/* truth table for all sixteen operation codes:                       */
X/*                      result dest                                   */
X/* source   dest        0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15         */
X/*  0        0          0 0 0 0 0 0 0 0 1 1 1  1  1  1  1  1          */
X/*  0        1          0 0 0 0 1 1 1 1 0 0 0  0  1  1  1  1          */
X/*  1        0          0 0 1 1 0 0 1 1 0 0 1  1  0  0  1  1          */
X/*  1        1          0 1 0 1 0 1 0 1 0 1 0  1  0  1  0  1          */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsetrasterop_ (plane, op, status)
X
Xshort int   *plane;
Xshort int   *op;
Xlong        *status;
X
X{
X   lop = (long) *op;
X   /*
X    * When we invert, invert only one bit.
X    */
X   if (lop == 10)
X   {
X      XSetPlaneMask(d, FillGC, 0x00000001);
X      XSetPlaneMask(d, TextGC, 0x00000001);
X      XSetPlaneMask(d, EraseGC, 0x00000001);
X   }
X   else
X   {
X      XSetPlaneMask(d, FillGC, 0xffffffff);
X      XSetPlaneMask(d, TextGC, 0xffffffff);
X      XSetPlaneMask(d, EraseGC, 0xffffffff);
X   }
X	
X   XSetFunction(d, FillGC, lop);
X   XSetFunction(d, TextGC, lop);
X   XSetFunction(d, EraseGC, lop);
X#if 0
X   XSetFunction(d, DrawGC, lop);
X#endif
X} /* gprsetrasterop_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_text_background_value (index, status)                */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$pixel_value_t  index;                                         */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t           status;                                        */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Specifies the color/intensity value to use for text background.    */
X/* index is                                                           */
X/* the color map index. If this value equals -2 this specifies using  */
X/* the color/intensity value of the bitmap background as the line     */
X/* drawing value. For borrowed displays and memory bitmaps, the fill  */
X/* background is always zero. For Display Manager frames, this is the */
X/* pixel value in use for the window background. If this value equals */
X/* -1 this specifies that the text background is transparent; that is */
X/* the old values of the pixels are not changed. status is the        */
X/* completion status. The default value is -2. For monochromatic      */
X/* displays, only the low-order bit of the draw value is considered,  */
X/* because monochromatic displays have only one plane. For color      */
X/* displays in 4-bit pixel format, only the four lowest-order bits of */
X/* the draw value are considered, because these displays have four    */
X/* planes.                                                            */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsettextbackgroundvalue_ (pixel, status)
X
Xlong  *pixel;
Xlong  *status;
X
X{
X   XSetBackground(d, TextGC, colortrans[*pixel]);
X   *status = 0;
X} /* gprsettextbackgroundvalue_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_text_font (font_id, status)                          */
X/*                                                                    */
X/* input:                                                             */
X/* short     font_id;       # 2-byte integer                          */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t status;                                                  */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Establishes a new font for subsequent text operations. font_id is  */
X/* the identifier of the new text font. status is the completion      */
X/* status. There is no default text font. A program must load and set */
X/* the font. Call gpr_$set text_font(...) for each main memory bitmap.*/
X/* Otherwise an error is returned (invalid font id).                  */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsettextfont_ (font, status)
X
Xlong  *font;
Xlong  *status;
X
X{
X   /* XXX fill in font here */
X   XSetFont(d, TextGC, *font);
X   *status = 0;
X} /* gprsettextfont_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_text_path (direction, status)                        */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$direction_t  direction;                                       */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t         status;                                          */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Specifies the direction for writing a line of text. direction is   */
X/* on of gpr_$up, gpr_$down. gpr_$left, gpr_$right. The default text  */
X/* path is gpr_$right. status is the completion status.               */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsettextpath_ (direction, status)
X
Xlong  *status;
X
X{
X   /*XXX noop */
X   *status = 0;
X} /* gprsettextpath_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$set_text_value (index, status)                           */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$pixel_value_t  index;                                         */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t           status;                                        */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Specifies the color/intensity value to use for writing text. index */
X/* is the color map index. status is the                              */
X/* completion status. The default value is 1 for borrowed displays,   */
X/* memory bitmaps, and Display Manager frames on monochromatic        */
X/* displays; 0 for Display Manager frames on color displays.          */
X/* For monochromatic                                                  */
X/* displays, only the low-order bit of the draw value is considered,  */
X/* because monochromatic displays have only one plane. For color      */
X/* displays in 4-bit pixel format, only the four lowest-order bits of */
X/* the draw value are considered, because these displays have four    */
X/* planes.                                                            */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprsettextvalue_ (pixel, status)
X
Xlong  *pixel;
Xlong  *status;
X
X{
X   XSetForeground(d, TextGC, colortrans[*pixel]);
X   *status = 0;
X} /* gprsettextvalue_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$terminate (delete_display, status)                       */
X/*                                                                    */
X/* input:                                                             */
X/* Boolean     delete_display;                                        */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t  status;                                                 */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Terminates the graphics primitives package. delete_display         */
X/* specifies whether to delete the frame of the Display Manager pad.  */
X/* If the program has operated in a Display Manager frame and needs   */
X/* to delete the frame at the end of a graphics sesion, set this      */
X/* value to True. If the program needs to close, but not to delete    */
X/* the frame, set this value to false. If the program has not used a  */
X/* Display Manager frame, the value is ignored. status is the         */
X/* completion status. gpr_$terminate(...) deletes the frame           */
X/* regardless of the value of the delete-display argument in the      */
X/* following case. A BLT operation from a memory bitmap has been done */
X/* to a Display Manager frame since the last time gpr_$clear was      */
X/* called for the frame.                                              */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprterminate_ (flag, status)
X
Xint   *flag;
Xlong  *status;
X
X{
X/*
X   XUngrabServer(d);
X   XUngrabPointer(d, CurrentTime);
X*/
X   XCloseDisplay(d);
X   *status = 0;
X} /* gprterminate_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$text (string, string_length, status)                     */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$string_t  string;                                             */
X/* short          string_length;     # 2-byte integer ( <257 )        */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t      status;                                             */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Writes text to the current bitmap, beginning at the current        */
X/* position. gpr_$text(...) always clips to the edge of the bitmap,   */
X/* regardless of whether clipping is enabled. It writes the characters*/
X/* in the current font which correspond to the ASCII values of the    */
X/* characters in the specified string. If the font does not have a    */
X/* character which corresponds to a character in the string,          */
X/* gpr_$text(...) leaves a space. The size of the space is set by     */
X/* gpr_$set_space_size(...). The origin of the first character of the */
X/* string is placed at the current position. Generally, the origin is */
X/* is at the bottom left, excluding descenders of the character. Upon */
X/* completion of the gpr_$text routine, the current position is       */
X/* updated to the coordinate position where a next character would be */
X/* written. This is the case even if the string is partly or completly*/
X/* clipped. However, the current position always remains within the   */
X/* boundaries of the bitmap.                                          */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprtext_ (string, nchars, status)
X
Xchar  *string;
Xint   *nchars;
Xlong  *status;
X
X{
X#if 0
X   printf("%d: (%.*s) show at %d, %d\n", *nchars, *nchars, string,
X	                                 curpoint.x, curpoint.y);
X#endif
X   XDrawImageString (d, w, TextGC, curpoint.x, curpoint.y, string, *nchars);
X   *status = 0;
X} /* gprtext_ */
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void gpr_$trapezoid (trapezoid, status)                            */
X/*                                                                    */
X/* input:                                                             */
X/* gpr_$trap_t  trapezoid;                                            */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t    status;                                               */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Draws and fills a trapezoid. trapezoid is the trapezoid to be      */
X/* drawn. status is the completion status. gpr_$trapezoid(...) fills  */
X/* in a trapezoid with the color/intensity value specified with       */
X/* gpr_$set_fill_value(...) or the pattern set by                     */
X/* gpr_$set_fill_pattern(...). The GPR routines define a trapezoid as */
X/* a quadrilateral with two horizontal parallel sides. To draw an     */
X/* unfilled trapezoid use gpr_$polyline(...).                         */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid gprtrapezoid_ (trap, status)
X
Xtrap_t   *trap;
Xlong     *status;
X
X{
X   XPoint tr[4];
X
X
X
X   tr[0].x = trap->top.x_coord_l;
X   tr[0].y = trap->top.y_coord;
X   tr[1].x = trap->top.x_coord_r;
X   tr[1].y = trap->top.y_coord;    
X   tr[2].x = trap->bot.x_coord_r;
X   tr[2].y = trap->bot.y_coord;    
X   tr[3].x = trap->bot.x_coord_l;
X   tr[3].y = trap->bot.y_coord;    
X   XFillPolygon (d, w, FillGC, tr, 4, Convex, CoordModeOrigin);
X} /* gprtrapezoid_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void time_$clock (clock)                                           */
X/*                                                                    */
X/* output:                                                            */
X/* time_$clock_t  clock;                                              */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Returns the current UTC (Coordinated Universal) time. It is        */
X/* represented as the number of 4-microsecond periods that have       */
X/* elapsed since January1, 1980 at 00:00. To get the local time, use  */
X/* cal_$get_local_time(...). To compute the local time from the value */
X/* returned by time_$clock(...), use cal_$apply_local_offset(...).    */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid timeclock_ (clock)
X
Xshort int  clock[3];
X
X{
X   struct timeval tv;
X   long   tmp_micro;
X
X
X
X   XSync(d,0);
X   gettimeofday(&tv, 0);
X
X   clock[0] = tv.tv_sec >> 16;
X   clock[1] = tv.tv_sec & 0xffff;
X   clock[2] = tv.tv_usec/4;
X
X/*
X   tmp_micro = tv.tv_sec * 250000 + tv.tv_usec/4;
X
X   clock[2] = tmp_micro & 0x000000ff;
X   clock[1] = (tmp_micro & 0x0000ff00) >> 16;
X   clock[0] = (tmp_micro & 0x00ff0000) >> 32;
X*/
X} /* timeclock_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void time_$wait (rel_abs, clock, status)                           */
X/*                                                                    */
X/* input:                                                             */
X/* time_$rel_abs_t  rel_abs;                                          */
X/* time_$clock_t    clock;                                            */
X/*                                                                    */
X/* output:                                                            */
X/* status_$t        status;                                           */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Suspends the calling process for a specified time. rel_abs is one  */
X/* of the following: time_$relative (clock specifies the number of    */
X/* 4-microsecond periods to wait), time_$absolute (clock contains the */
X/* UTC system time for which to wait). status is, as always, the      */
X/* completion status.                                                 */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid timewait_ (delta, clock, status)
X
Xfloat       *delta;
Xshort int   clock[3];
Xlong        *status;
X
X{
X   struct timeval tv;
X   long           tmp_micro;
X
X
X
X   XSync(d, 0);
X
X   tv.tv_sec = ((clock[0] <<16) + clock[1])>>1;
X   tv.tv_usec = clock[2] * 4;
X
X/*
X   tmp_micro = ((((clock[0] * 65536) + clock[1]) * 65536) + clock[2]);
X
X   tv.tv_sec = tmp_micro / 250000;
X   tv.tv_usec = (tmp_micro && 0x000000ff);
X*/
X   select (0, 0, 0, 0, &tv);
X} /* timewait_ */
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* void tone_$time (time)                                             */
X/*                                                                    */
X/* input:                                                             */
X/* time_$clock_t  time;                                               */
X/*                                                                    */
X/* ================================================================== */
X/*                                                                    */
X/* Makes a tone. The tone remains on for the time indicated in the    */
X/* call.                                                              */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid tonetime_ (time)
X
Xlong  *time;
X
X{
X   XBell(d, 0);
X}
X
X
X
X
X
X/* ================================================================== */
X/*                                                                    */
X/* Where does this come from?                                         */
X/*                                                                    */
X/* ================================================================== */
X
Xvoid rand_ (x)
X
Xfloat *x;
X
X{
X   unsigned long  r = random();
X   double         dr = r % 566927;
X    
X   *x = dr / 566927;
X} /* rand_ */
E!O!F! xstrek/gpr.c
exit
=====
            @work:            | Matthias Pfuetzner  |         @home:
  ZGDV, Wilhelminenstrasse 7  | 6100 Darmstadt, FRG |  Lichtenbergstrasse 73
    +49 6151 155-164 or -101  \    <- Tel.nr. ->    /     +49 6151 75717
   pfuetzner@agd.fhg.de    pfuetzner@zgdvda.UUCP    XBR1YD3U@DDATHD21.BITNET

--
Dan Heller
------------------------------------------------
O'Reilly && Associates		 Z-Code Software
Senior Writer			       President
argv@ora.com			argv@zipcode.com