[comp.sources.x] v02i024: monitor X11 Server/Client communications, Part03/04

mikew@wyse.wyse.com (Mike Wexler) (11/29/88)

Submitted-by:  peterson@sw.mcc.com (James Peterson)
Posting-number: Volume 2, Issue 24
Archive-name: xmonitor/part03

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 4)."
# Contents:  common.c decode11.c patchlevel.h prtype.c
# Wrapped by mikew@wyse on Mon Nov 28 10:13:38 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'common.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'common.c'\"
else
echo shar: Extracting \"'common.c'\" \(5292 characters\)
sed "s/^X//" >'common.c' <<'END_OF_FILE'
X/* ************************************************************ *\
X *								*
X *    Common support routines for sockets			*
X *								*
X *       James L. Peterson	 				*
X *	(c) Copyright MCC, 1987                                 *
X * 				  				*
X * 				  				*
X \* *********************************************************** */
X
X#include "scope.h"
X
X/* ********************************************** */
X/*						  */
X/*       Debugging support routines               */
X/*						  */
X/* ********************************************** */
X
Xenterprocedure(s)
X     char   *s;
X{
X  debug(2,(stderr, "-> %s\n", s));
X}
X
Xwarn(s)
X     char   *s;
X{
X  fprintf(stderr, "####### %s\n", s);
X}
X
Xpanic(s)
X     char   *s;
X{
X  fprintf(stderr, "%s\n", s);
X  exit(1);
X}
X
X/* ********************************************** */
X/*						  */
X/*  Debugging forms of memory management          */
X/*						  */
X/* ********************************************** */
X
Xextern char *malloc();
X
Xchar   *Malloc (n)
X     long    n;
X{
X  char   *p;
X  p = (char *)malloc((unsigned int)n);
X  debug(64,(stderr, "%x = malloc(%d)\n", p, n));
X  if (p == NULL)
X    panic("no more malloc space");
X  return(p);
X}
X
XFree(p)
X     char   *p;
X{
X  debug(64,(stderr, "%x = free\n", p));
X  free(p);
X}
X
X
X
X/* ************************************************************ */
X/*								*/
X/*    Signal Handling support					*/
X/*								*/
X/* ************************************************************ */
X
X#include <signal.h>
X
XSignalURG()
X{
X  debug(1,(stderr, "==> SIGURG received\n"));
X}
X
XSignalPIPE()
X{
X  debug(1,(stderr, "==> SIGPIPE received\n"));
X}
X
XSignalINT()
X{
X  debug(1,(stderr, "==> SIGINT received\n"));
X  exit(1);
X}
X
XSignalQUIT()
X{
X  debug(1,(stderr, "==> SIGQUIT received\n"));
X  exit(1);
X}
X
XSignalTERM()
X{
X  debug(1,(stderr, "==> SIGTERM received\n"));
X  exit(1);
X}
X
XSignalTSTP()
X{
X  debug(1,(stderr, "==> SIGTSTP received\n"));
X}
X
XSignalCONT()
X{
X  debug(1,(stderr, "==> SIGCONT received\n"));
X}
X
XSetSignalHandling()
X{
X  enterprocedure("SetSignalHandling");
X  signal(SIGURG, SignalURG);
X  signal(SIGPIPE, SignalPIPE);
X  signal(SIGINT, SignalINT);
X  signal(SIGQUIT, SignalQUIT);
X  signal(SIGTERM, SignalTERM);
X  signal(SIGTSTP, SignalTSTP);
X  signal(SIGCONT, SignalCONT);
X}
X
X
X
X/* ************************************************************ */
X/*								*/
X/*   Create a socket for a service to listen for clients        */
X/*								*/
X/* ************************************************************ */
X
X#include <sys/types.h>	       /* needed by sys/socket.h and netinet/in.h */
X#include <sys/uio.h>	       /* for struct iovec, used by socket.h */
X#include <sys/socket.h>	       /* for AF_INET, SOCK_STREAM, ... */
X#include <sys/ioctl.h>	       /* for FIONCLEX, FIONBIO, ... */
X#include <netinet/in.h>	       /* struct sockaddr_in */
X#include <netdb.h>	       /* struct servent * and struct hostent *  */
X
Xstatic int  ON = 1 /* used in ioctl */ ;
X#define	BACKLOG	5
X
X/* for use in the UsingFD call -- defined later */
Xextern int  NewConnection ();
X
X
XSetUpConnectionSocket(port)
X     int     port;
X{
X  FD ConnectionSocket;
X  struct sockaddr_in  sin;
X
X  enterprocedure("SetUpConnectionSocket");
X
X  /* create the connection socket and set its parameters of use */
X  ConnectionSocket = socket(AF_INET, SOCK_STREAM, 0);
X  if (ConnectionSocket < 0)
X    {
X      perror("socket");
X      exit(-1);
X    }
X  (void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_REUSEADDR,   (char *)NULL, 0);
X  (void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_USELOOPBACK, (char *)NULL, 0);
X  (void)setsockopt(ConnectionSocket, SOL_SOCKET, SO_DONTLINGER,  (char *)NULL, 0);
X
X  /* define the name and port to be used with the connection socket */
X  bzero((char *)&sin, sizeof(sin));
X  sin.sin_family = AF_INET;
X
X  /* the address of the socket is composed of two parts: the host machine and
X     the port number.  We need the host machine address for the current host
X   */
X  {
X    /* define the host part of the address */
X    char    MyHostName[256];
X    struct hostent *hp;
X
X    (void) gethostname(MyHostName, sizeof(MyHostName));
X    ScopeHost = (char *) Malloc((long)strlen(MyHostName));
X    strcpy(ScopeHost, MyHostName);
X    hp = gethostbyname(MyHostName);
X    if (hp == NULL)
X      panic("No address for our host");
X    bcopy((char *)hp->h_addr, (char*)&sin.sin_addr, hp->h_length);
X  }
X    /* new code -- INADDR_ANY should be better than using the name of the
X       host machine.  The host machine may have several different network
X       addresses.  INADDR_ANY should work with all of them at once. */
X  sin.sin_addr.s_addr = INADDR_ANY;
X
X  sin.sin_port = port;
X  ScopePort = port;
X
X  /* bind the name and port number to the connection socket */
X  if (bind(ConnectionSocket, (struct sockaddr *)&sin, sizeof(sin)) < 0)
X    {
X      perror("bind");
X      exit(-1);
X    }
X
X  debug(4,(stderr, "Socket is FD %d for %s,%d\n",
X	   ConnectionSocket, ScopeHost, ScopePort));
X
X  /* now activate the named connection socket to get messages */
X  if (listen(ConnectionSocket, BACKLOG) < 0)
X    {
X      perror("listen");
X      exit(-1);
X    };
X
X  /* a few more parameter settings */
X  ioctl(ConnectionSocket, FIOCLEX, 0);
X  ioctl(ConnectionSocket, FIONBIO, &ON);
X
X  debug(4,(stderr, "Listening on FD %d\n", ConnectionSocket));
X  UsingFD(ConnectionSocket, NewConnection);
X}
X
X
END_OF_FILE
if test 5292 -ne `wc -c <'common.c'`; then
    echo shar: \"'common.c'\" unpacked with wrong size!
fi
# end of 'common.c'
fi
if test -f 'decode11.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'decode11.c'\"
else
echo shar: Extracting \"'decode11.c'\" \(21640 characters\)
sed "s/^X//" >'decode11.c' <<'END_OF_FILE'
X/* ************************************************************ *
X *						     		*
X *  Decoding and switching routines for the X11 protocol	*
X *						      		*
X *	James Peterson, 1988			      		*
X *	(c) Copyright MCC, 1988 		      		*
X *						      		*
X * ************************************************************ */
X
X#include "scope.h"
X#include "x11.h"
X
X/*
X  There are 4 types of things in X11: requests, replies, errors, and events.
X
X  Each of them has a format defined by a small integer that defines
X  the type of the thing.
X
X  Requests have an opcode in the first byte.
X  Events have a code in the first byte.
X  Errors have a code in the second byte (the first byte is 0)
X  Replies ...
X
X  Replies have a sequence number in bytes 2 and 3.  The sequence
X  number should be used to identify the request that was sent, and
X  from that request we can determine the type of the reply.
X*/
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X
X/*
X  We need to keep the sequence number for a request to match it with
X  an expected reply.  The sequence number is associated only with the
X  particular connection that we have. We would expect these replies
X  to be handled as a FIFO queue.
X*/
X
Xstruct QueueEntry
X{
X  struct QueueEntry  *Next;
X  long    SequenceNumber;
X  short   Request;
X};
X
X/* free space list of Q entries */
X
Xstatic struct QueueEntry   *FreeQEntries = NULL;
X
X/* ************************************************************ */
Xstruct QueueEntry  *NewQEntry (SequenceNumber, Request)
X     long    SequenceNumber;
X     short   Request;
X{
X  struct QueueEntry  *p;
X
X  /* Get a Queue Entry */
X  if (FreeQEntries == NULL)
X    {
X      /* create new queue entry */
X      p = (struct QueueEntry *) Malloc ((long)(sizeof (*p)));
X    }
X  else
X    {
X      /* reuse an old queue entry */
X      p = FreeQEntries;
X      FreeQEntries = FreeQEntries->Next;
X    }
X
X  /* fill in its values */
X  p->Next = NULL;
X  p->SequenceNumber = SequenceNumber;
X  p->Request = Request;
X  return(p);
X}
X/* ************************************************************ */
X
X/* define a queue of entries for each FD */
X
Xstruct QueueHeader
X{
X  struct QueueEntry  *Head;
X  struct QueueEntry  *Tail;
X};
X
Xstruct QueueHeader  ReplyQ[StaticMaxFD];
X
X/* ************************************************************ */
X
XInitReplyQ()
X{
X  short   i;
X  for (i = 0; i < StaticMaxFD; i++)
X    {
X      ReplyQ[i].Head = NULL;
X      ReplyQ[i].Tail = NULL;
X    }
X}
X
XFlushReplyQ(fd)
XFD fd;
X{
X  struct QueueEntry  *p;
X  struct QueueEntry  *NextQEntry;
X
X  /* go down the reply queue and free all entries */
X  for (p = ReplyQ[fd].Head; p != NULL; p = NextQEntry)
X    {
X      NextQEntry = p->Next;
X      
X      /* put freed entry on list of free entries (for later reuse)  */
X      p->Next = FreeQEntries;
X      FreeQEntries = p;
X    }
X  
X  ReplyQ[fd].Head = NULL;
X  ReplyQ[fd].Tail = NULL;
X}
X
X
XDumpReplyQ(fd)
X     FD fd;
X{
X  fprintf(stderr, "ReplyQ[%d] = { Head 0x%x; Tail 0x%x }\n", 
X	  fd, ReplyQ[fd].Head, ReplyQ[fd].Tail);
X  {
X    struct QueueEntry  *p;
X    for (p = ReplyQ[fd].Head; p != NULL; p = p->Next)
X      fprintf(stderr, "0x%x = { Next 0x%x; SequenceNumber %d; Request %d }\n",
X	      p, p->Next, p->SequenceNumber, p->Request);
X  }
X}
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/* A reply is expected to the type of request given for the fd associated
X   with this one */
X
XSequencedReplyExpected(fd, SequenceNumber, RequestType)
X     FD fd;
X     long SequenceNumber;
X     short   RequestType;
X{
X  struct QueueEntry  *p;
X
X  debug(8,(stderr, "Reply expected: sequence %d and request type %d for fd %d\n",
X	   SequenceNumber, RequestType, fd));
X  /* create a new queue entry */
X  p = NewQEntry(SequenceNumber, RequestType);
X
X  /* find the server associated with this client */
X  fd = FDPair(fd);
X  if (fd < 0 || fd >= StaticMaxFD) return;
X
X  /* attach the new queue entry to the end of the queue for the Server */
X  if (ReplyQ[fd].Tail != NULL)
X    (ReplyQ[fd].Tail)->Next = p;
X  else
X    ReplyQ[fd].Head = p;
X  ReplyQ[fd].Tail = p;
X
X  debug(8,(stderr, "Save sequence %d and request type %d for fd %d\n",
X	   p->SequenceNumber, p->Request, fd));
X}
X
X
Xstatic FD Lastfd;
Xstatic long LastSequenceNumber;
Xstatic short LastReplyType;
X
X/* search for the type of request that is associated with a reply
X   to the given sequence number for this fd */
X
Xshort   CheckReplyTable (fd, SequenceNumber)
X     FD fd;
X     short   SequenceNumber;
X{
X  struct QueueEntry  *p;
X  struct QueueEntry  *trailer;
X
X  if (debuglevel & 128) DumpReplyQ(fd);
X  for (trailer = NULL, p = ReplyQ[fd].Head;
X       p != NULL;
X       trailer = p, p = p->Next)
X    {
X      /* look for matching sequence number in queue of this fd */
X      if (SequenceNumber == ((short)(0xFFFF & p->SequenceNumber)))
X	{
X	  /* save the Request type */
X	  Lastfd = fd;
X	  LastSequenceNumber = p->SequenceNumber;
X	  LastReplyType = p->Request;
X
X	  /* pull the queue entry out of the queue for this fd */
X	  if (trailer == NULL)
X	      ReplyQ[fd].Head = p->Next;
X	  else
X	    trailer->Next = p->Next;
X	  if (ReplyQ[fd].Tail == p) ReplyQ[fd].Tail = trailer;
X
X
X	  /* put freed entry on list of free entries (for later reuse)  */
X	  p->Next = FreeQEntries;
X	  FreeQEntries = p;
X
X	  debug(8,(stderr, "Reply on fd %d for sequence %d is type %d\n",
X		   fd, SequenceNumber, LastReplyType));
X	  return(LastReplyType);
X	}
X    }
X
X  /* not expecting a reply for that sequence number */
X  debug(8,(stderr, "Reply on fd %d for sequence %d is not found\n",
X	   fd, SequenceNumber));
X  return(0);
X}
X
X
X/* ************************************************************ */
X/* A reply is expected to the type of request given for the
X   sequence number associated with this fd */
X
XReplyExpected(fd, Request)
X     FD fd;
X     short   Request;
X{
X  SequencedReplyExpected(fd, CS[fd].SequenceNumber, Request);
X}
X
X/* ************************************************************ */
X/* another reply is expected for the same reply as we just had */
X/* This is only used with ListFontsWithInfo */
X
XKeepLastReplyExpected()
X{
X  SequencedReplyExpected(Lastfd, LastSequenceNumber, LastReplyType);
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X
XDecodeRequest(fd, buf, n)
X     FD fd;
X     unsigned char *buf;
X     long    n;
X{
X  short   Request = IByte (&buf[0]);
X  CS[fd].SequenceNumber += 1;
X  bcopy ((char *)&(CS[fd].SequenceNumber), (char *)SBf, sizeof(long));
X  SetIndentLevel(PRINTCLIENT);
X
X  if (Verbose > 3)
X    DumpItem("Request", fd, buf, n);
X  if (Request <= 0 || 127 < Request)
X    warn("Extended request opcode");
X  else switch (Request)
X    {
X	    case 1:
X		    CreateWindow(buf);
X		    break;
X	    case 2:
X		    ChangeWindowAttributes(buf);
X		    break;
X	    case 3:
X		    GetWindowAttributes(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 4:
X		    DestroyWindow(buf);
X		    break;
X	    case 5:
X		    DestroySubwindows(buf);
X		    break;
X	    case 6:
X		    ChangeSaveSet(buf);
X		    break;
X	    case 7:
X		    ReparentWindow(buf);
X		    break;
X	    case 8:
X		    MapWindow(buf);
X		    break;
X	    case 9:
X		    MapSubwindows(buf);
X		    break;
X	    case 10:
X		    UnmapWindow(buf);
X		    break;
X	    case 11:
X		    UnmapSubwindows(buf);
X		    break;
X	    case 12:
X		    ConfigureWindow(buf);
X		    break;
X	    case 13:
X		    CirculateWindow(buf);
X		    break;
X	    case 14:
X		    GetGeometry(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 15:
X		    QueryTree(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 16:
X		    InternAtom(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 17:
X		    GetAtomName(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 18:
X		    ChangeProperty(buf);
X		    break;
X	    case 19:
X		    DeleteProperty(buf);
X		    break;
X	    case 20:
X		    GetProperty(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 21:
X		    ListProperties(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 22:
X		    SetSelectionOwner(buf);
X		    break;
X	    case 23:
X		    GetSelectionOwner(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 24:
X		    ConvertSelection(buf);
X		    break;
X	    case 25:
X		    SendEvent(buf);
X		    break;
X	    case 26:
X		    GrabPointer(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 27:
X		    UngrabPointer(buf);
X		    break;
X	    case 28:
X		    GrabButton(buf);
X		    break;
X	    case 29:
X		    UngrabButton(buf);
X		    break;
X	    case 30:
X		    ChangeActivePointerGrab(buf);
X		    break;
X	    case 31:
X		    GrabKeyboard(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 32:
X		    UngrabKeyboard(buf);
X		    break;
X	    case 33:
X		    GrabKey(buf);
X		    break;
X	    case 34:
X		    UngrabKey(buf);
X		    break;
X	    case 35:
X		    AllowEvents(buf);
X		    break;
X	    case 36:
X		    GrabServer(buf);
X		    break;
X	    case 37:
X		    UngrabServer(buf);
X		    break;
X	    case 38:
X		    QueryPointer(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 39:
X		    GetMotionEvents(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 40:
X		    TranslateCoordinates(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 41:
X		    WarpPointer(buf);
X		    break;
X	    case 42:
X		    SetInputFocus(buf);
X		    break;
X	    case 43:
X		    GetInputFocus(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 44:
X		    QueryKeymap(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 45:
X		    OpenFont(buf);
X		    break;
X	    case 46:
X		    CloseFont(buf);
X		    break;
X	    case 47:
X		    QueryFont(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 48:
X		    QueryTextExtents(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 49:
X		    ListFonts(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 50:
X		    ListFontsWithInfo(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 51:
X		    SetFontPath(buf);
X		    break;
X	    case 52:
X		    GetFontPath(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 53:
X		    CreatePixmap(buf);
X		    break;
X	    case 54:
X		    FreePixmap(buf);
X		    break;
X	    case 55:
X		    CreateGC(buf);
X		    break;
X	    case 56:
X		    ChangeGC(buf);
X		    break;
X	    case 57:
X		    CopyGC(buf);
X		    break;
X	    case 58:
X		    SetDashes(buf);
X		    break;
X	    case 59:
X		    SetClipRectangles(buf);
X		    break;
X	    case 60:
X		    FreeGC(buf);
X		    break;
X	    case 61:
X		    ClearArea(buf);
X		    break;
X	    case 62:
X		    CopyArea(buf);
X		    break;
X	    case 63:
X		    CopyPlane(buf);
X		    break;
X	    case 64:
X		    PolyPoint(buf);
X		    break;
X	    case 65:
X		    PolyLine(buf);
X		    break;
X	    case 66:
X		    PolySegment(buf);
X		    break;
X	    case 67:
X		    PolyRectangle(buf);
X		    break;
X	    case 68:
X		    PolyArc(buf);
X		    break;
X	    case 69:
X		    FillPoly(buf);
X		    break;
X	    case 70:
X		    PolyFillRectangle(buf);
X		    break;
X	    case 71:
X		    PolyFillArc(buf);
X		    break;
X	    case 72:
X		    PutImage(buf);
X		    break;
X	    case 73:
X		    GetImage(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 74:
X		    PolyText8(buf);
X		    break;
X	    case 75:
X		    PolyText16(buf);
X		    break;
X	    case 76:
X		    ImageText8(buf);
X		    break;
X	    case 77:
X		    ImageText16(buf);
X		    break;
X	    case 78:
X		    CreateColormap(buf);
X		    break;
X	    case 79:
X		    FreeColormap(buf);
X		    break;
X	    case 80:
X		    CopyColormapAndFree(buf);
X		    break;
X	    case 81:
X		    InstallColormap(buf);
X		    break;
X	    case 82:
X		    UninstallColormap(buf);
X		    break;
X	    case 83:
X		    ListInstalledColormaps(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 84:
X		    AllocColor(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 85:
X		    AllocNamedColor(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 86:
X		    AllocColorCells(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 87:
X		    AllocColorPlanes(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 88:
X		    FreeColors(buf);
X		    break;
X	    case 89:
X		    StoreColors(buf);
X		    break;
X	    case 90:
X		    StoreNamedColor(buf);
X		    break;
X	    case 91:
X		    QueryColors(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 92:
X		    LookupColor(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 93:
X		    CreateCursor(buf);
X		    break;
X	    case 94:
X		    CreateGlyphCursor(buf);
X		    break;
X	    case 95:
X		    FreeCursor(buf);
X		    break;
X	    case 96:
X		    RecolorCursor(buf);
X		    break;
X	    case 97:
X		    QueryBestSize(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 98:
X		    QueryExtension(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 99:
X		    ListExtensions(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 100:
X		    ChangeKeyboardMapping(buf);
X		    break;
X	    case 101:
X		    GetKeyboardMapping(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 102:
X		    ChangeKeyboardControl(buf);
X		    break;
X	    case 103:
X		    GetKeyboardControl(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 104:
X		    Bell(buf);
X		    break;
X	    case 105:
X		    ChangePointerControl(buf);
X		    break;
X	    case 106:
X		    GetPointerControl(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 107:
X		    SetScreenSaver(buf);
X		    break;
X	    case 108:
X		    GetScreenSaver(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 109:
X		    ChangeHosts(buf);
X		    break;
X	    case 110:
X		    ListHosts(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 111:
X		    SetAccessControl(buf);
X		    break;
X	    case 112:
X		    SetCloseDownMode(buf);
X		    break;
X	    case 113:
X		    KillClient(buf);
X		    break;
X	    case 114:
X		    RotateProperties(buf);
X		    break;
X	    case 115:
X		    ForceScreenSaver(buf);
X		    break;
X	    case 116:
X		    SetPointerMapping(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 117:
X		    GetPointerMapping(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 118:
X		    SetModifierMapping(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 119:
X		    GetModifierMapping(buf);
X		    ReplyExpected(fd, Request);
X		    break;
X	    case 127:
X		    NoOperation(buf);
X		    break;
X	    default:
X		    warn("Unimplemented request opcode");
X		    break;
X   }
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
XDecodeReply(fd, buf, n)
X     FD fd;
X     unsigned char *buf;
X     long    n;
X{
X  short   SequenceNumber = IShort (&buf[2]);
X  short   Request = CheckReplyTable (fd, SequenceNumber);
X  if (Request == 0)
X    {
X      warn("Unexpected reply");
X      return;
X    }
X  SetIndentLevel(PRINTSERVER);
X  RBf[0] = Request /* for the PrintField in the Reply procedure */ ;
X  if (Verbose > 3)
X    DumpItem("Reply", fd, buf, n);
X  if (Request <= 0 || 127 < Request)
X    warn("Extended reply opcode");
X  else switch (Request)
X    {
X	    case 3:
X		    GetWindowAttributesReply(buf);
X		    break;
X	    case 14:
X		    GetGeometryReply(buf);
X		    break;
X	    case 15:
X		    QueryTreeReply(buf);
X		    break;
X	    case 16:
X		    InternAtomReply(buf);
X		    break;
X	    case 17:
X		    GetAtomNameReply(buf);
X		    break;
X	    case 20:
X		    GetPropertyReply(buf);
X		    break;
X	    case 21:
X		    ListPropertiesReply(buf);
X		    break;
X	    case 23:
X		    GetSelectionOwnerReply(buf);
X		    break;
X	    case 26:
X		    GrabPointerReply(buf);
X		    break;
X	    case 31:
X		    GrabKeyboardReply(buf);
X		    break;
X	    case 38:
X		    QueryPointerReply(buf);
X		    break;
X	    case 39:
X		    GetMotionEventsReply(buf);
X		    break;
X	    case 40:
X		    TranslateCoordinatesReply(buf);
X		    break;
X	    case 43:
X		    GetInputFocusReply(buf);
X		    break;
X	    case 44:
X		    QueryKeymapReply(buf);
X		    break;
X	    case 47:
X		    QueryFontReply(buf);
X		    break;
X	    case 48:
X		    QueryTextExtentsReply(buf);
X		    break;
X	    case 49:
X		    ListFontsReply(buf);
X		    break;
X	    case 50:
X		    ListFontsWithInfoReply(buf);
X		    break;
X	    case 52:
X		    GetFontPathReply(buf);
X		    break;
X	    case 73:
X		    GetImageReply(buf);
X		    break;
X	    case 83:
X		    ListInstalledColormapsReply(buf);
X		    break;
X	    case 84:
X		    AllocColorReply(buf);
X		    break;
X	    case 85:
X		    AllocNamedColorReply(buf);
X		    break;
X	    case 86:
X		    AllocColorCellsReply(buf);
X		    break;
X	    case 87:
X		    AllocColorPlanesReply(buf);
X		    break;
X	    case 91:
X		    QueryColorsReply(buf);
X		    break;
X	    case 92:
X		    LookupColorReply(buf);
X		    break;
X	    case 97:
X		    QueryBestSizeReply(buf);
X		    break;
X	    case 98:
X		    QueryExtensionReply(buf);
X		    break;
X	    case 99:
X		    ListExtensionsReply(buf);
X		    break;
X	    case 101:
X		    GetKeyboardMappingReply(buf);
X		    break;
X	    case 103:
X		    GetKeyboardControlReply(buf);
X		    break;
X	    case 106:
X		    GetPointerControlReply(buf);
X		    break;
X	    case 108:
X		    GetScreenSaverReply(buf);
X		    break;
X	    case 110:
X		    ListHostsReply(buf);
X		    break;
X	    case 116:
X		    SetPointerMappingReply(buf);
X		    break;
X	    case 117:
X		    GetPointerMappingReply(buf);
X		    break;
X	    case 118:
X		    SetModifierMappingReply(buf);
X		    break;
X	    case 119:
X		    GetModifierMappingReply(buf);
X		    break;
X	    default:
X		    warn("Unimplemented reply opcode");
X		    break;
X    }
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
XDecodeError(fd, buf, n)
X     FD fd;
X     unsigned char *buf;
X     long    n;
X{
X  short   Error = IByte (&buf[1]);
X  SetIndentLevel(PRINTSERVER);
X  if (Verbose > 3)
X    DumpItem("Error", fd, buf, n);
X  (void)CheckReplyTable (fd, (short)IShort(&buf[2]));
X  if (Error < 1 || Error > 17)
X    warn("Extended Error code");
X  else switch (Error)
X    {
X	    case 1:
X		    RequestError(buf);
X		    break;
X	    case 2:
X		    ValueError(buf);
X		    break;
X	    case 3:
X		    WindowError(buf);
X		    break;
X	    case 4:
X		    PixmapError(buf);
X		    break;
X	    case 5:
X		    AtomError(buf);
X		    break;
X	    case 6:
X		    CursorError(buf);
X		    break;
X	    case 7:
X		    FontError(buf);
X		    break;
X	    case 8:
X		    MatchError(buf);
X		    break;
X	    case 9:
X		    DrawableError(buf);
X		    break;
X	    case 10:
X		    AccessError(buf);
X		    break;
X	    case 11:
X		    AllocError(buf);
X		    break;
X	    case 12:
X		    ColormapError(buf);
X		    break;
X	    case 13:
X		    GContextError(buf);
X		    break;
X	    case 14:
X		    IDChoiceError(buf);
X		    break;
X	    case 15:
X		    NameError(buf);
X		    break;
X	    case 16:
X		    LengthError(buf);
X		    break;
X	    case 17:
X		    ImplementationError(buf);
X		    break;
X	    default:
X		    warn("Unimplemented error code");
X		    break;
X    }
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
XDecodeEvent(fd, buf, n)
X     FD fd;
X     unsigned char *buf;
X     long    n;
X{
X  short   Event = IByte (&buf[0]);
X  SetIndentLevel(PRINTSERVER);
X  if (Verbose > 3)
X    DumpItem("Event", fd, buf, n);
X  if (Event < 2 || Event > 34)
X    warn("Extended Event code");
X  else switch (Event)
X    {
X	    case 2:
X		    KeyPressEvent(buf);
X		    break;
X	    case 3:
X		    KeyReleaseEvent(buf);
X		    break;
X	    case 4:
X		    ButtonPressEvent(buf);
X		    break;
X	    case 5:
X		    ButtonReleaseEvent(buf);
X		    break;
X	    case 6:
X		    MotionNotifyEvent(buf);
X		    break;
X	    case 7:
X		    EnterNotifyEvent(buf);
X		    break;
X	    case 8:
X		    LeaveNotifyEvent(buf);
X		    break;
X	    case 9:
X		    FocusInEvent(buf);
X		    break;
X	    case 10:
X		    FocusOutEvent(buf);
X		    break;
X	    case 11:
X		    KeymapNotifyEvent(buf);
X		    break;
X	    case 12:
X		    ExposeEvent(buf);
X		    break;
X	    case 13:
X		    GraphicsExposureEvent(buf);
X		    break;
X	    case 14:
X		    NoExposureEvent(buf);
X		    break;
X	    case 15:
X		    VisibilityNotifyEvent(buf);
X		    break;
X	    case 16:
X		    CreateNotifyEvent(buf);
X		    break;
X	    case 17:
X		    DestroyNotifyEvent(buf);
X		    break;
X	    case 18:
X		    UnmapNotifyEvent(buf);
X		    break;
X	    case 19:
X		    MapNotifyEvent(buf);
X		    break;
X	    case 20:
X		    MapRequestEvent(buf);
X		    break;
X	    case 21:
X		    ReparentNotifyEvent(buf);
X		    break;
X	    case 22:
X		    ConfigureNotifyEvent(buf);
X		    break;
X	    case 23:
X		    ConfigureRequestEvent(buf);
X		    break;
X	    case 24:
X		    GravityNotifyEvent(buf);
X		    break;
X	    case 25:
X		    ResizeRequestEvent(buf);
X		    break;
X	    case 26:
X		    CirculateNotifyEvent(buf);
X		    break;
X	    case 27:
X		    CirculateRequestEvent(buf);
X		    break;
X	    case 28:
X		    PropertyNotifyEvent(buf);
X		    break;
X	    case 29:
X		    SelectionClearEvent(buf);
X		    break;
X	    case 30:
X		    SelectionRequestEvent(buf);
X		    break;
X	    case 31:
X		    SelectionNotifyEvent(buf);
X		    break;
X	    case 32:
X		    ColormapNotifyEvent(buf);
X		    break;
X	    case 33:
X		    ClientMessageEvent(buf);
X		    break;
X	    case 34:
X		    MappingNotifyEvent(buf);
X		    break;
X	    default:
X		    warn("Unimplemented event code");
X		    break;
X    }
X}
END_OF_FILE
if test 21640 -ne `wc -c <'decode11.c'`; then
    echo shar: \"'decode11.c'\" unpacked with wrong size!
fi
# end of 'decode11.c'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(22 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVEL 0
X
END_OF_FILE
if test 22 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'prtype.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'prtype.c'\"
else
echo shar: Extracting \"'prtype.c'\" \(21160 characters\)
sed "s/^X//" >'prtype.c' <<'END_OF_FILE'
X/* ************************************************** *
X *						      *
X *  Type Printing for X11 protocol		      *
X *						      *
X *	James Peterson, 1988			      *
X *	(c) Copyright MCC, 1988 		      *
X *						      *
X * ************************************************** */
X
X#include "scope.h"
X#include "x11.h"
X
X/*
X  For each of the types we need a way to print that type.
X  Types are of varieties:
X
X  (1) BUILTIN -- we have a separate routine to interpret and print
X  each built-in type.
X  (2) ENUMERATED, SET -- we have one routine which prints, given the
X  data and the list of values.
X  (3) RECORDS -- a separate routine for each to print each field.
X
X*/
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X
X/* print representation of a character for debugging */
Xchar   *printrep (c)
X     unsigned short  c;
X{
X  static char pr[8];
X
X  if (c < 32)
X    {
X      /* control characters */
X      pr[0] = '^';
X      pr[1] = c + 64;
X      pr[2] = '\0';
X    }
X  else if (c < 127)
X      {
X	/* printing characters */
X	pr[0] = c;
X	pr[1] = '\0';
X      }
X    else if (c == 127)
X	return("<del>");
X      else if (c <= 0377)
X	  {
X	    /* upper 128 codes from 128 to 255;  print as \ooo - octal  */
X	    pr[0] = '\\';
X	    pr[3] = '0' + (c & 7);
X	    c = c >> 3;
X	    pr[2] = '0' + (c & 7);
X	    c = c >> 3;
X	    pr[1] = '0' + (c & 3);
X	    pr[4] = '\0';
X	  }
X	else
X	  {
X	    /* very large number -- print as 0xffff - 4 digit hex */
X	    sprintf(pr, "0x%04x", c);
X	  }
X  return(pr);
X}
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/*
X  we use indentation for two purposes:
X
X   (1) To show substructure of records inside records ...
X   (2) To separate the bytes from the client (on the left) from
X       those from the server (on the right).
X
X   Each indention level is one tab (8 spaces).
X*/
X
X#define MaxIndent 10
Xstatic char Leader[MaxIndent + 1];
Xstatic short    CurrentLevel = 0;
X
XSetIndentLevel(which)
X     short   which;
X{
X  short   i;
X
X  if (which > MaxIndent)
X    which = MaxIndent;
X  if (which < 0)
X    which = 0;
X  if (which == CurrentLevel)
X    return;
X
X  /* set the indent level to <which> */
X  /* -> set the Print Leader to <which> tabs */
X  for (i = 0; i < which; i++)
X    Leader[i] = '\t';
X  Leader[which] = '\0';
X  CurrentLevel = which;
X}
X
XModifyIndentLevel(amount)
X     short   amount;
X{
X  SetIndentLevel(CurrentLevel + amount);
X}
X
Xshort   SizeofLeader ()
X{
X  return (CurrentLevel * 8);
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/* if we want verbose enough output, we will dump the buffer in hex */
X
XDumpItem(name, fd, buf, n)
X     char   *name;
X     FD      fd;
X     unsigned char *buf;
X     long    n;
X{
X  if (n == 0)
X    return;
X
X  fprintf(stdout, "%s%20s (fd %d): ", Leader, name, fd);
X
X  DumpHexBuffer(buf, n);
X  fprintf(stdout, "\n");
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
XPrintINT8(buf)
X     unsigned char *buf;
X{
X  /* print a INT8 -- 8-bit signed integer */
X  short   n = IByte (buf);
X  if (n > 127)
X    n = 256 - n;
X  fprintf(stdout, "%d", n);
X}
X
XPrintINT16(buf)
X     unsigned char *buf;
X{
X  /* print a INT16 -- 16-bit signed integer */
X  long    n = IShort (buf);
X  if (n > 32767)
X    n = 65536 - n;
X  fprintf(stdout, "%d", n);
X}
X
XPrintINT32(buf)
X     unsigned char *buf;
X{
X  /* print a INT32 -- 32-bit signed integer */
X  long    n = ILong (buf);
X  fprintf(stdout, "%d", n);
X}
X
X/* ************************************************************ */
X
XPrintCARD8(buf)
X     unsigned char *buf;
X{
X  /* print a CARD8 -- 8-bit unsigned integer */
X  short   n = IByte (buf);
X  fprintf(stdout, "%02x", (unsigned)(n & 0xff));
X}
X
XPrintCARD16(buf)
X     unsigned char *buf;
X{
X  /* print a CARD16 -- 16-bit unsigned integer */
X  unsigned long   n = IShort (buf);
X  fprintf(stdout, "%04x", (unsigned)(n & 0xffff));
X}
X
XPrintCARD32(buf)
X     unsigned char *buf;
X{
X  /* print a CARD32 -- 32-bit unsigned integer */
X  unsigned long   n = ILong (buf);
X  fprintf(stdout, "%08x", n);
X  return(4);
X}
X
X/* ************************************************************ */
X
XPrintBYTE(buf)
X     unsigned char *buf;
X{
X  /* print a BYTE -- 8-bit value */
X  short   n = IByte (buf);
X  fprintf(stdout, "%02x", n);
X  return(1);
X}
X
X
XPrintCHAR8(buf)
X     unsigned char *buf;
X{
X  /* print a CHAR8 -- 8-bit character */
X  unsigned short   n = IByte (buf);
X  fprintf(stdout, "%s", printrep(n));
X  return(1);
X}
X
X
XPrintSTRING16(buf)
X     unsigned char *buf;
X{
X  /* print a CHAR16 -- 16-bit character */
X  unsigned short   n = IShort (buf);
X  fprintf(stdout, "%s", printrep(n));
X  return(1);
X}
X
XPrintSTR(buf)
X     unsigned char *buf;
X{
X  /* STR have the length (1 byte) then a string of CHAR8 */
X  short   n;
X  short   i;
X
X  n = IByte(buf++);
X  for (i = 0; i < n; i++)
X    fprintf(stdout, "%s", printrep(buf[i]));
X  return(n+1);
X}
X
X/* ************************************************************ */
X
XPrintWINDOW(buf)
X     unsigned char *buf;
X{
X  /* print a WINDOW -- CARD32  plus 0 = None */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else
X    fprintf(stdout, "WIN %08x", n);
X  return(4);
X}
X
XPrintWINDOWD(buf)
X     unsigned char *buf;
X{
X  /* print a WINDOWD -- CARD32  plus 0 = PointerWindow, 1 = InputFocus */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "PointerWindow");
X  else if (n == 1)
X      fprintf(stdout, "InputFocus");
X    else
X      PrintWINDOW(buf);
X}
X
XPrintWINDOWNR(buf)
X     unsigned char *buf;
X{
X  /* print a WINDOWNR -- CARD32  plus 0 = None, 1 = PointerRoot */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else if (n == 1)
X      fprintf(stdout, "PointerRoot");
X    else
X      PrintWINDOW(buf);
X}
X
X
XPrintPIXMAP(buf)
X     unsigned char *buf;
X{
X  /* print a PIXMAP -- CARD32  plus 0 = None */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else
X    fprintf(stdout, "PXM %08x", n);
X}
X
XPrintPIXMAPNPR(buf)
X     unsigned char *buf;
X{
X  /* print a PIXMAPNPR -- CARD32  plus 0 = None, 1 = ParentRelative */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else if (n == 1)
X      fprintf(stdout, "ParentRelative");
X    else
X      PrintPIXMAP(buf);
X}
X
XPrintPIXMAPC(buf)
X     unsigned char *buf;
X{
X  /* print a PIXMAPC -- CARD32  plus 0 = CopyFromParent */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "CopyFromParent");
X  else
X    PrintPIXMAP(buf);
X}
X
X
XPrintCURSOR(buf)
X     unsigned char *buf;
X{
X  /* print a CURSOR -- CARD32  plus 0 = None */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else
X    fprintf(stdout, "CUR %08x", n);
X}
X
X
XPrintFONT(buf)
X     unsigned char *buf;
X{
X  /* print a FONT -- CARD32  plus 0 = None */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else
X    fprintf(stdout, "FNT %08x", n);
X}
X
X
XPrintGCONTEXT(buf)
X     unsigned char *buf;
X{
X  /* print a GCONTEXT -- CARD32 */
X  long    n = ILong (buf);
X  fprintf(stdout, "GXC %08x", n);
X}
X
X
XPrintCOLORMAP(buf)
X     unsigned char *buf;
X{
X  /* print a COLORMAP -- CARD32 plus 0 = None */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else
X    fprintf(stdout, "CMP %08x", n);
X  return(4);
X}
X
XPrintCOLORMAPC(buf)
X     unsigned char *buf;
X{
X  /* print a COLORMAPC -- CARD32 plus 0 = CopyFromParent */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "CopyFromParent");
X  else
X    PrintCOLORMAP(buf);
X}
X
X
XPrintDRAWABLE(buf)
X     unsigned char *buf;
X{
X  /* print a DRAWABLE -- CARD32 */
X  long    n = ILong (buf);
X  fprintf(stdout, "DWB %08x", n);
X}
X
XPrintFONTABLE(buf)
X     unsigned char *buf;
X{
X  /* print a FONTABLE -- CARD32 */
X  long    n = ILong (buf);
X  fprintf(stdout, "FTB %08x", n);
X}
X
X/* ************************************************************ */
X
X#define NumberofAtoms 68
X
Xchar   *AtomTable[NumberofAtoms + 1] =
X{
X  "NONE", "PRIMARY", "SECONDARY", "ARC", "ATOM", "BITMAP", "CARDINAL",
X  "COLORMAP", "CURSOR", "CUT_BUFFER0", "CUT_BUFFER1", "CUT_BUFFER2",
X  "CUT_BUFFER3", "CUT_BUFFER4", "CUT_BUFFER5", "CUT_BUFFER6",
X  "CUT_BUFFER7", "DRAWABLE", "FONT", "INTEGER", "PIXMAP", "POINT",
X  "RECTANGLE", "RESOURCE_MANAGER", "RGB_COLOR_MAP", "RGB_BEST_MAP",
X  "RGB_BLUE_MAP", "RGB_DEFAULT_MAP", "RGB_GRAY_MAP", "RGB_GREEN_MAP",
X  "RGB_RED_MAP", "STRING", "VISUALID", "WINDOW", "WM_COMMAND",
X  "WM_HINTS", "WM_CLIENT_MACHINE", "WM_ICON_NAME", "WM_ICON_SIZE",
X  "WM_NAME", "WM_NORMAL_HINTS", "WM_SIZE_HINTS", "WM_ZOOM_HINTS",
X  "MIN_SPACE", "NORM_SPACE", "MAX_SPACE", "END_SPACE", "SUPERSCRIPT_X",
X  "SUPERSCRIPT_Y", "SUBSCRIPT_X", "SUBSCRIPT_Y", "UNDERLINE_POSITION",
X  "UNDERLINE_THICKNESS", "STRIKEOUT_ASCENT", "STRIKEOUT_DESCENT",
X  "ITALIC_ANGLE", "X_HEIGHT", "QUAD_WIDTH", "WEIGHT", "POINT_SIZE",
X  "RESOLUTION", "COPYRIGHT", "NOTICE", "FONT_NAME", "FAMILY_NAME",
X  "FULL_NAME", "CAP_HEIGHT", "WM_CLASS", "WM_TRANSIENT_FOR"
X  };
X
X/* for atoms, we print the built-in atoms.  We could expand to printing
X   the user defined ones, too. */
X
XPrintATOM(buf)
X     unsigned char *buf;
X{
X  /* print a ATOM -- CARD32 plus 0 = None */
X  long    n = ILong (buf);
X  if (0 <= n && n <= NumberofAtoms)
X    fprintf(stdout, "<%s>", AtomTable[n]);
X  else
X    fprintf(stdout, "ATM %08x", n);
X  return(4);
X}
X
XPrintATOMT(buf)
X     unsigned char *buf;
X{
X  /* print a ATOMT -- CARD32 plus 0 = AnyPropertyType */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "AnyPropertyType");
X  else
X    PrintATOM(buf);
X}
X
X
XPrintVISUALID(buf)
X     unsigned char *buf;
X{
X  /* print a VISUALID -- CARD32 plus 0 = None */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "None");
X  else
X    fprintf(stdout, "VIS %08x", n);
X}
X
XPrintVISUALIDC(buf)
X     unsigned char *buf;
X{
X  /* print a VISUALIDC -- CARD32 plus 0 = CopyFromParent */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "CopyFromParent");
X  else
X    PrintVISUALID(buf);
X}
X
X
XPrintTIMESTAMP(buf)
X     unsigned char *buf;
X{
X  /* print a TIMESTAMP -- CARD32 plus 0 as the current time */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "CurrentTime");
X  else
X    fprintf(stdout, "TIM %08x", n);
X}
X
X
XPrintRESOURCEID(buf)
X     unsigned char *buf;
X{
X  /* print a RESOURCEID -- CARD32 plus 0 = AllTemporary */
X  long    n = ILong (buf);
X  if (n == 0)
X    fprintf(stdout, "AllTemporary");
X  else
X    fprintf(stdout, "RID %08x", n);
X}
X
X
XPrintKEYSYM(buf)
X     unsigned char *buf;
X{
X  /* print a KEYSYM -- CARD32 */
X  long    n = ILong (buf);
X  fprintf(stdout, "KYS %08x", n);
X  return(4);
X}
X
XPrintKEYCODE(buf)
X     unsigned char *buf;
X{
X  /* print a KEYCODE -- CARD8 */
X  unsigned short n = IByte (buf);
X  fprintf(stdout, "%d (%s)", n, printrep(n));
X  return(1);
X}
X
XPrintKEYCODEA(buf)
X     unsigned char *buf;
X{
X  /* print a KEYCODEA -- CARD8 plus 0 = AnyKey */
X  long    n = IByte (buf);
X  if (n == 0)
X    fprintf(stdout, "AnyKey");
X  else
X    PrintKEYCODE(buf);
X}
X
X
XPrintBUTTON(buf)
X     unsigned char *buf;
X{
X  /* print a BUTTON -- CARD8 */
X  unsigned short n = IByte (buf);
X  fprintf(stdout, "%d (%s)", n, printrep(n));
X}
X
XPrintBUTTONA(buf)
X     unsigned char *buf;
X{
X  /* print a BUTTONA -- CARD8 plus 0 = AnyButton */
X  long    n = IByte (buf);
X  if (n == 0)
X    fprintf(stdout, "AnyButton");
X  else
X    PrintBUTTON(buf);
X}
X
X
X/* this is an interesting cheat -- we call DecodeEvent to print an event */
X/* should work, but its never been tried */
XPrintEVENTFORM(buf)
X     unsigned char *buf;
X{
X  /* print an EVENT_FORM -- event format */
X  DecodeEvent(-1, buf, (long)-1);
X}
X
X/* ************************************************************ */
X
XPrintENUMERATED(buf, length, ValueList)
X     unsigned char *buf;
X     short   length;
X     struct ValueListEntry  *ValueList;
X{
X  long   n;
X  struct ValueListEntry  *p;
X
X  if (length == 1)
X    n = IByte(buf);
X  else if (length == 2)
X      n = IShort(buf);
X    else
X      n = ILong(buf);
X
X  p = ValueList;
X  while (p != NULL && p->Value != n)
X    p = p->Next;
X
X  if (p != NULL)
X    fprintf(stdout, "%s", p->Name);
X  else
X    fprintf(stdout, "**INVALID** (%d)", n);
X}
X
X/* ************************************************************ */
X
XPrintSET(buf, length, ValueList)
X     unsigned char *buf;
X     short   length;
X     struct ValueListEntry  *ValueList;
X{
X  unsigned long   n;
X  struct ValueListEntry  *p;
X  Boolean MatchesAll = false;
X  Boolean FoundOne = false;
X
X  if (length == 1)
X    n = IByte(buf);
X  else if (length == 2)
X      n = IShort(buf);
X    else
X      n = ILong(buf);
X
X  if (n != 0)
X    {
X      /* first check if the value matches ALL of the bits. */
X      MatchesAll = true;
X      for (p = ValueList; MatchesAll && (p != NULL); p = p->Next)
X	{
X	  if ((p->Value & n) == 0)
X	      MatchesAll = false;
X	}
X
X      if (!MatchesAll)
X	/* if it matches some, but not all, print only those it matches */
X	for (p = ValueList; p != NULL; p = p->Next)
X	  {
X	    if ((p->Value & n) != 0)
X	      {
X		if (FoundOne)
X		  fprintf(stdout, " | ");
X		fprintf(stdout, "%s", p->Name);
X		FoundOne = true;
X	      }
X	  }
X    }
X
X  if (MatchesAll)
X    fprintf(stdout, "<ALL>");
X  else if (!FoundOne)
X    fprintf(stdout, "0");
X}
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
XPrintField(buf, start, length, FieldType, name)
X     unsigned char *buf;
X     short   start;
X     short   length;
X     short   FieldType;
X     char   *name;
X{
X  if (length == 0)
X    return;
X
X  fprintf(stdout, "%s%20s: ", Leader, name);
X
X  if (debuglevel & 8)
X    DumpHexBuffer(&(buf[start]), (long)length);
X
X  switch (TD[FieldType].Type)
X    {
X	  case BUILTIN:
X		 (*TD[FieldType].PrintProc)(&buf[start]);
X		 break;
X
X	  case ENUMERATED:
X		 PrintENUMERATED(&buf[start], length, TD[FieldType].ValueList);
X		 break;
X
X	  case SET:
X		 PrintSET(&buf[start], length, TD[FieldType].ValueList);
X		 break;
X
X	  case RECORD:
X		 ModifyIndentLevel(1);
X		 fprintf(stdout, "\n");
X		 if (Verbose < 3)
X		   return;
X		 (*TD[FieldType].PrintProc)(&buf[start]);
X		 ModifyIndentLevel(-1);
X		 break;
X    }
X  fprintf(stdout, "\n");
X  fflush(stdout);
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/* print a list of things.  The things are of type <ListType>.
X   They start at <buf>.  There are <number> things in the list */
X
Xlong PrintList(buf, number, ListType, name)
X     unsigned char *buf;
X     long   number;
X     short   ListType;
X     char   *name;
X{
X  long    n;
X  long    i;
X  long    sum;
X
X  if (number == 0)
X    return(0);
X
X  fprintf(stdout, "%s%20s: (%d)\n", Leader, name, number);
X  if (Verbose < 2)
X    return(0);
X
X  ModifyIndentLevel(1);
X  sum = 0;
X  for (i = 0; i < number; i++)
X    {
X      switch (TD[ListType].Type)
X	{
X		    case BUILTIN:
X			    n = (*TD[ListType].PrintProc)(buf);
X			    break;
X		    case RECORD:
X			    n = (*TD[ListType].PrintProc)(buf);
X			    break;
X		    default:
X			    fprintf(stdout, "**INVALID**");
X			    n = 0;
X			    break;
X	}
X      buf = buf + n;
X      sum = sum + n;
X      fprintf(stdout, "%s---\n", Leader);
X    }
X
X  ModifyIndentLevel(-1);
X  return(sum);
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/* print a list of STRs.  Similar to PrintList
X   They start at <buf>.  There are <number> things in the list */
X
Xlong PrintListSTR(buf, number, name)
X     unsigned char *buf;
X     long   number;
X     char   *name;
X{
X  long    n;
X  long    i;
X  long    sum;
X
X  if (number == 0)
X    return(0);
X
X  fprintf(stdout, "%s%20s: (%d)\n", Leader, name, number);
X  if (Verbose < 2)
X    return(0);
X
X  ModifyIndentLevel(1);
X  sum = 0;
X  for (i = 0; i < number; i++)
X    {
X      fprintf(stdout, "%s", Leader);
X      n = PrintSTR(buf);
X      buf = buf + n;
X      sum = sum + n;
X      fprintf(stdout, "\n");
X    }
X
X  ModifyIndentLevel(-1);
X  return(sum);
X}
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X
XPrintBytes(buf, number, name)
X     unsigned char   buf[];
X     long   number;
X     char   *name;
X{
X  /* print a list of BYTE -- 8-bit character */
X  long   i;
X  short   column;
X
X  if (number == 0)
X    return(0);
X
X  fprintf(stdout, "%s%20s: ", Leader, name);
X  column = SizeofLeader() + 25;
X  for (i = 0; i < number; i++)
X    {
X      if (column > 80)
X	{
X	  if (Verbose < 2)
X	    break;
X	  fprintf(stdout, "\n%s%20s: ", Leader, "");
X	  column = SizeofLeader() + 25;
X	}
X      fprintf(stdout, "%02x ",((unsigned int) buf[i]));
X      column += 3;
X    }
X  fprintf(stdout, "\n");
X
X  return(number);
X}
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X
X/* print a String of CHAR8 -- 8-bit characters */
X
XPrintString8(buf, number, name)
X     unsigned char    buf[];
X     short   number;
X     char   *name;
X{
X  short   i;
X
X  if (number == 0)
X    return(0);
X
X  fprintf(stdout, "%s%20s: \"", Leader, name);
X  for (i = 0; i < number; i++)
X    fprintf(stdout, "%s", printrep(buf[i]));
X  fprintf(stdout, "\"\n");
X
X  return(number);
X}
X
X
X/* print a String of CHAR16 -- 16-bit characters */
X
XPrintString16(buf, number, name)
X     unsigned char    buf[];
X     short   number;
X     char   *name;
X{
X  short   i;
X  unsigned short   c;
X
X  if (number == 0)
X    return(0);
X
X  fprintf(stdout, "%s%20s: \"", Leader, name);
X  for (i = 0; i < number; i += 2)
X    {
X      c = IShort(&buf[i]);
X      fprintf(stdout, "%s", printrep(c));
X    }
X  fprintf(stdout, "\"\n");
X
X  return(number);
X}
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/*
X  A Value List is two things:
X
X  (1) A controlling bitmask.  For each one bit in the control,
X  a value is in the list.
X  (2) A list of values.
X*/
X
XPrintValues(control, clength, ctype, values, name)
X     unsigned char   *control;
X     short   clength;
X     short   ctype;
X     unsigned char   *values;
X     char   *name;
X{
X  long    cmask;
X  struct ValueListEntry  *p;
X
X  /* first get the control mask */
X  if (clength == 1)
X    cmask = IByte(control);
X  else if (clength == 2)
X      cmask = IShort(control);
X    else
X      cmask = ILong(control);
X
X  /* now if it is zero, ignore and return */
X  if (cmask == 0)
X    return;
X
X  /* there are bits in the controlling bitmask, figure out which */
X  /* the ctype is a set type, so this code is similar to PrintSET */
X  fprintf(stdout, "%s%20s:\n", Leader, name);
X  ModifyIndentLevel(1);
X  for (p = TD[ctype].ValueList; p != NULL; p = p->Next)
X    {
X      if ((p->Value & cmask) != 0)
X	{
X	  short   m = 4 - p->Length;
X	  PrintField(values, m, p->Length, p->Type, p->Name);
X	  values += 4;
X	}
X    }
X  ModifyIndentLevel(-1);
X}
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X/* PolyText8 and PolyText16 take lists of characters with possible
X   font changes in them. */
X
XPrintTextList8(buf, length, name)
X     unsigned char *buf;
X     short   length;
X     char   *name;
X{
X  short   n;
X
X  fprintf(stdout, "%s%20s:\n", Leader, name);
X  while (length > 1)
X    {
X      n = IByte(&buf[0]);
X      if (n != 255)
X	{
X	  PrintField(buf, 1, 1, INT8, "delta");
X	  PrintString8(&buf[2], n, "text item 8 string");
X	  buf += n + 2;
X	  length -= n + 2;
X	}
X      else
X	{
X	  PrintField(buf, 1, 4, FONT, "font-shift-id");
X	  buf += 4;
X	  length -= 4;
X	}
X    }
X}
X
XPrintTextList16(buf, length, name)
X     unsigned char *buf;
X     short   length;
X     char   *name;
X{
X  short   n;
X
X  fprintf(stdout, "%s%20s:\n", Leader, name);
X  while (length > 1)
X    {
X      n = IByte(&buf[0]);
X      if (n != 255)
X	{
X	  PrintField(buf, 1, 1, INT8, "delta");
X	  PrintString16(&buf[2], n, "text item 16 string");
X	  buf += n + 2;
X	  length -= n + 2;
X	}
X      else
X	{
X	  PrintField(buf, 1, 4, FONT, "font-shift-id");
X	  buf += 4;
X	  length -= 4;
X	}
X    }
X}
X
X
X/* ************************************************************ */
X/*								*/
X/*								*/
X/* ************************************************************ */
X
X#define MAXline 78
X
XDumpHexBuffer(buf, n)
X     unsigned char *buf;
X     long    n;
X{
X  short   i;
X  short   column;
X  char    h[6] /* one hex or octal character */ ;
X
X  column = 27 + SizeofLeader();
X  for (i = 0; i < n; i++)
X    {
X      /* get the hex representations */
X      sprintf(h, "%02x",(0xff & buf[i]));
X
X      /* check if these characters will fit on this line */
X      if ((column + strlen(h) + 1) > MAXline)
X	{
X	  /* line will be too long -- print it */
X	  fprintf(stdout, "\n");
X	  column = 0;
X	}
X      fprintf(stdout, "%s ", h);
X      column += 3;
X    }
X}
END_OF_FILE
if test 21160 -ne `wc -c <'prtype.c'`; then
    echo shar: \"'prtype.c'\" unpacked with wrong size!
fi
# end of 'prtype.c'
fi
echo shar: End of archive 3 \(of 4\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
Moderator of comp.sources.x