Newsgroups: comp.sources.misc
From: ijp@doc.ic.ac.uk (Ian Palmer)
Subject:  v26i031:  scamper - Cellular Automata Simulator, Part08/10
Message-ID: <1991Nov20.234143.14900@sparky.imd.sterling.com>
X-Md4-Signature: c31d629dc2d102abf17237f9789fe2be
Date: Wed, 20 Nov 1991 23:41:43 GMT
Approved: kent@sparky.imd.sterling.com

Submitted-by: ijp@doc.ic.ac.uk (Ian Palmer)
Posting-number: Volume 26, Issue 31
Archive-name: scamper/part08
Environment: X11R4, SunOS

---- CUT HERE -------- CUT HERE -------- CUT HERE -------- CUT HERE ----
#! /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 shell archive."
# Contents:  windows.c
# Wrapped by ijp@swan.doc.ic.ac.uk on Thu Nov  7 10:14:40 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'windows.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'windows.c'\"
else
echo shar: Extracting \"'windows.c'\" \(25080 characters\)
sed "s/^X//" >'windows.c' <<'END_OF_FILE'
X/*
X
X
X
X   *****                 *****                   *****                 *****
X  *     *               *     *                 *     *               *     *
X  *                     *     *                 *     *               *     *
X   **         *****     *     *    *       *    *     *     ******    *     *
X     *       *     *    *******    **     **    ******     *          ******
X      **     *          *     *    * *   * *    *          *          * *
X        *    *          *     *    *  * *  *    *          *          *  *
X  *     *    *          *     *    *   *   *    *           *****     *   *
X   *****     *          *     *    *       *    *          *          *    *
X             *                     *       *               *
X             *     *               *       *               *
X              *****                *       *                ******
X
X
X
X                                 by Ian Palmer
X
X                                      at
X
X              Imperial College of Science, Technology and Medicine
X                             University of London
X
X
X
X
X--------------------------------------------------------------------------------
X| Scamper is supplied "as is", without express or implied warranty.            |
X|                                                                              |
X| Permission to use, copy, modify and distribute this software, and any        |
X| documentation, for any non-commercial purpose is hereby granted without fee, |
X| provided that all copyright messages, and permission notices, remain intact. |
X|                                                                              |
X| Copyright 1991 by Ian Palmer of Imperial College of Science, Technology      |
X| and Medicine, University of London.                                          |
X--------------------------------------------------------------------------------
X
X   _____
X  /_  _/  Let Total Chaos reign forever !       I.J.Palmer,
X   / /  ___      ______________                 Department of Computing,
X  / /  / __\      |    _                        Imperial College,
X /_/  / /         | <> | /-\ |_                 180 Queen's Gate,
X      \ \__           /             _           London SW7 2BZ.
X       \___/          \ |-| /-\ <> <
X                      ______________>           ijp@doc.ic.ac.uk
X  PANIC NOW
X  and avoid       23. Add to Celt's pub meal and produce utter turmoil. (6,8)
X  the rush.       -----------------------------------------------------------
X
X
X*/
X
X/*
X      Program Segment      : windows.c
X
X      Task                 : Supply an interface between Scamper and X windows,
X                             including :
X                             - Dynamic Colour Allocation
X                             - Window creation and management
X                             - X Events
X                             - Drawing filled rectangles converting from 
X                               absolute coordinates to X coordinates
X                             - Font creation and management
X                             - Colour selection
X                             - Cursor creation and management
X
X*/
X
X#include <X11/Xlib.h>
X#include <X11/Xatom.h>
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X#include <stdio.h>
X#include "windows.h"
X#include "curtain.h"
X
X#define MaxWins 7
X
Xextern GC   XCreateGC();
X
XDisplay         *dpy;
XGC              gc;
XWindow          win ;
Xint             cols[11];
Xstruct colour   colours[256];
XXPoint          hexagon[6] ;
XPixmap          small ;
XGC              smallgc ;
XWindow          rootwin, wins[MaxWins];
XGC              gcs[MaxWins] ;
XXFontStruct     *fontstruct[2];
Xunsigned long   fontH[2];
Xint             planes, thefont ;
Xint             maxcolours, thescreen, tablesize ;
Xfloat           diffR,diffB,diffG ;
XColormap        cmap;
XCursor          user_cursor, busy_cursor, enter_cursor, error_cursor ;
Xunsigned long   fg, bg, Black ;
XXColor          backT , foreT ;
X
X#define swap(x,y) {int t; t=x; x=y; y=t; }
X
Xint AllocRGB(level,old,use) int old,use ; XColor level ;
X/* Allocate a colour from it's RGB values, see also AllocColour */
X{
X  int pointer,found , near , grey , dist ;
X
X  if (old != -1) {
X    if (colours[old].used != old) 
X      if ((colours[colours[old].used].count -= 1) == 0) {
X        XFreeColors(dpy,cmap,&(colours[colours[old].used].mapno),1,0);
X        colours[colours[old].used].used = -1 ;
X        colours[colours[old].used].num = -1 ;
X        };
X    colours[old].count -= 1 ;
X    if (colours[old].count == 0) {
X      if (colours[old].used == old)
X        XFreeColors(dpy,cmap,&(colours[old].mapno),1,0);
X      colours[old].used = -1 ;
X      colours[old].num = -1 ;
X      };
X    };
X
X  found = -1;
X  for(pointer=0 ; pointer<256 ; ++pointer)
X    if (colours[pointer].used == -1) {
X      found = pointer ;
X      pointer = 256 ;
X      };
X  if (found != -1) {
X    if (XAllocColor(dpy,cmap,&level)) {
X      colours[found].used = found ;
X      colours[found].mapno = level.pixel ;
X      colours[found].num = 255 ;
X      colours[found].grey = 0.33*level.red + 0.5*level.green + 0.17*level.blue ;
X      colours[found].count += 1 ;
X      pointer = 0 ;
X      while(((colours[pointer].mapno != level.pixel) || (pointer == found) || (colours[pointer].used == -1)) && (pointer != 255))
X        ++pointer ;
X      if ((colours[pointer].mapno == level.pixel) && (pointer != found) && (colours[pointer].used != -1)) {
X        colours[found].used = colours[pointer].used ;
X        colours[colours[found].used].count += 1 ;
X        };
X      return found ;
X      }
X    else {
X      colours[found].used = colours[cols[fore]].used ;
X      colours[found].mapno = colours[cols[fore]].mapno ;
X      colours[found].num = 255 ;
X      colours[found].grey = colours[cols[fore]].grey ;
X      colours[found].count += 1 ;
X      colours[cols[fore]].count += 1 ;
X      return found ;
X      };
X    };
X  printf("Can't allocate colour \n");
X  printf("Major error ! No colourmap spaces\n");
X  abort();
X}
X
Xint fade(num,old) int num,old ;
X/* Produce the next colour for the fancy title */
X{
X  XColor level ;
X
X  level.red = backT.red + (int) ( diffR * (float) num) ;
X  level.green = backT.green + (int) ( diffG * (float) num) ;
X  level.blue = backT.blue + (int) ( diffB * (float) num) ;
X
X  return AllocRGB(level,old,old) ;
X
X}
X
Xint AllocColour(n,old,use) int n,old,use ;
X/* Allocate a colour from it's colour number. n = colour number, old = old colour for that state (or -1)
Xuse if not -1 tells what colour to use if can't allocate */
X{
X  int pointer,found , near , grey , dist ;
X  XColor hw, rgb;
X
X  if (old != -1) {                                                        /* Deallocate the old colour */
X    if (colours[old].used != old)                                         /* chacking for colours actually used */
X      if ((colours[colours[old].used].count -= 1) == 0) {
X        XFreeColors(dpy,cmap,&(colours[colours[old].used].mapno),1,0);
X        colours[colours[old].used].used = -1 ;
X        colours[colours[old].used].num = -1 ;
X        };
X    colours[old].count -= 1 ;
X    if (colours[old].count == 0) {
X      if (colours[old].used == old)
X        XFreeColors(dpy,cmap,&(colours[old].mapno),1,0);
X      colours[old].used = -1 ;
X      colours[old].num = -1 ;
X      };
X    };
X
X  found = -1;                                                             /* See if colour already exists */
X  for(pointer=0 ; pointer<256 ; ++pointer)
X    if (colours[pointer].num == n)
X      found = pointer ;
X  if (found != -1) {                                                      /* If so, increment it's count, return it */
X    colours[found].count += 1 ;
X    if (colours[found].used != found)
X      colours[colours[found].used].count += 1 ;
X    return found ;
X    }
X  for(pointer=0 ; pointer<256 ; ++pointer)                                /* Find a free space in the colour table */
X    if (colours[pointer].used == -1) {
X      found = pointer ;
X      pointer = 256 ;
X      };
X  if (found != -1) {
X    if (XAllocNamedColor(dpy,cmap,colour_names[n], &hw, &rgb )) {         /* Ask X to allocate it */
X      colours[found].used = found ;
X      colours[found].mapno = hw.pixel ;                                   /* Store some variables */
X      colours[found].num = n ;
X      colours[found].grey = 0.33*rgb.red + 0.5*rgb.green + 0.17*rgb.blue ;
X      colours[found].count += 1 ;
X      pointer = 0 ;
X      while(((colours[pointer].mapno != hw.pixel) || (pointer == found) || (colours[pointer].used == -1)) && (pointer != 255))
X        ++pointer ;
X      if ((colours[pointer].mapno == hw.pixel) && (pointer != found) && (colours[pointer].used != -1)) {
X        colours[found].used = colours[pointer].used ;
X        colours[colours[found].used].count += 1 ;
X        };
X      return found ;
X      };
X    if (XLookupColor(dpy,cmap,colour_names[n], &hw, &rgb)) {              /* If X can't allocate it, find the closest colour */
X      near = -1 ;                                                         /* or use the specified `use' colour */
X      grey = 0.33*rgb.red + 0.5*rgb.green + 0.17*rgb.blue ;
X      if (use == -1) {
X        for(pointer = 0 ; pointer<256 ; ++pointer)
X          if ( ((near == -1) || (abs(grey - colours[pointer].grey) < dist)) && (colours[pointer].used != -1) ) {
X            near = colours[pointer].used ;
X            dist = abs(grey - colours[pointer].grey) ;
X            };
X        }
X      else
X        near = colours[use].used ;
X      if (near != -1) {
X        colours[found].used = colours[near].used ;
X        colours[found].mapno = colours[near].mapno ;
X        colours[found].num = n ;
X        colours[found].grey = grey ;
X        colours[found].count += 1 ;
X        colours[near].count += 1 ;
X        return found ;
X        };
X      };
X
X    };
X  printf("Can't allocate colour %s\n",colour_names[n]);                   /* If all else fails PANIC! */
X  printf("Major error ! No colourmap spaces\n");
X  abort();
X}
X
Xint GetDefault(n) int n ;
X/* See if the user has specified colours in resources, otherwise set up default colours */
X{
X  int val ;
X
X  char *string ;
X
X  string = XGetDefault( dpy,"Scamper", defaults[n] );                     /* See if a resource exists */
X  val = -1 ;
X  if (string)
X    val = GetColourValue(string) ;                                        /* If so use that colour */
X  if (val == -1)
X    val = GetColourValue(defvals[n]);                                     /* otherwise use the default */
X  return val ;
X}
X
Xvoid InitialiseColour()
X/* Initialise the colours */
X{
X  int i,n;
X  XColor hw;
X  char *string ;
X
X  for (tablesize = 0 ; colour_names[tablesize] != NULL ; ++tablesize);    /* Get the number of colours known to Scamper */
X  cmap = DefaultColormap( dpy, thescreen );                               /* Get a pointer to the colour map */
X  maxcolours = 1<<planes;                                                 /* make a note of the number of bit planes */
X
X  for( i=0; i<256; ++i ) {                                                /* Reset entries of colour table */
X    colours[i].count = 0 ;
X    colours[i].used = -1 ;
X    colours[i].num = -1 ;
X    };
X
X  Black = AllocColour(0,-1,-1);                                           /* Allocate colours for menus, etc. */
X  for(n = 0; n<11 ; ++n) {
X    i = GetDefault(n) ;
X    cols[n] = AllocColour(i,-1,-1);
X    };
X  XLookupColor(dpy,cmap,colour_names[colours[cols[back]].num],&hw,&backT);      /* and the title */
X  XLookupColor(dpy,cmap,colour_names[colours[cols[title]].num],&hw,&foreT);
X  diffR = ( ((float) foreT.red) - ((float) backT.red) ) / 50 ;
X  diffG = ( ((float) foreT.green) - ((float) backT.green) ) / 50 ;
X  diffB = ( ((float) foreT.blue) - ((float) backT.blue) ) / 50 ;
X
X}
X
Xvoid On()
X/* Initialise the GC for a window, setting up `pen type'
X*/
X{
X  XGCValues xgcv;
X
X  XSetPlaneMask( dpy, gc, AllPlanes );
X  xgcv.function = GXcopy;
X  XChangeGC( dpy, gc, GCFunction, &xgcv );
X  XSetForeground( dpy, gc, fg );
X  XSetBackground( dpy, gc, bg );
X}
X
Xvoid InitialiseWindows()
X/* Initialise X for Scamper's windows, plus load fonts, etc. */
X{
X  if( !(dpy=XOpenDisplay(NULL)) )
X    abort();
X
X  thescreen = DefaultScreen(dpy);                     /* Get some important info */
X  rootwin = RootWindow( dpy, thescreen );
X  planes = DefaultDepth( dpy, thescreen );
X
X  InitialiseColour();                                 /* Set up colours */
X
X  fontstruct[Small_Font] = XLoadQueryFont(dpy, FONT1);    /* Load fonts */
X  fontH[Small_Font] = fontstruct[Small_Font]->max_bounds.ascent + fontstruct[Small_Font]->max_bounds.descent;
X
X  fontstruct[Large_Font] = XLoadQueryFont(dpy,FONT2) ;
X  fontH[Large_Font] = fontstruct[Large_Font]->max_bounds.ascent + fontstruct[Large_Font]->max_bounds.descent;
X
X  thefont = Small_Font ;
X
X  user_cursor = XCreateFontCursor( dpy, XC_left_ptr );  /* Create cursors */
X  busy_cursor = XCreateFontCursor( dpy, XC_watch );
X  enter_cursor = XCreateFontCursor( dpy, XC_xterm );
X  error_cursor = XCreateFontCursor( dpy, XC_hand2 );
X
X
X}
X
Xvoid MakeWindows() 
X/* Create the windows for Scamper */
X{
X  unsigned int          xswamask;
X  XSetWindowAttributes  xswa;
X  XGCValues             values;
X  XSizeHints            size_h;
X
X  xswa.border_pixel   = colours[cols[fore]].mapno ;                       /* Set up window mask */
X  xswamask            = CWBorderPixel | CWBackingStore | CWColormap ;
X  xswa.colormap       = cmap;
X  xswa.backing_store  = WhenMapped ;
X
X  wins[Main_Window] = XCreateWindow( dpy, rootwin, 120, 120, DispX+100, DispY+100, 2, 0, 
X                      CopyFromParent, CopyFromParent, xswamask, &xswa );
X  XSetWindowColormap( dpy, wins[Main_Window], cmap );
X  XSelectInput( dpy, wins[Main_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask |
X                      PointerMotionMask | ButtonMotionMask );
X  gcs[Main_Window]  = XCreateGC( dpy, wins[Main_Window], 0L, &values );
X  XChangeProperty( dpy, wins[Main_Window], XA_WM_NAME, XA_STRING, 8,
X                      PropModeReplace, "Scamper", 7 );
X  size_h.flags      = PSize | PMaxSize | PMinSize ;
X  size_h.max_width  = size_h.min_width = size_h.width = DispX+100 ;
X  size_h.max_height = size_h.min_height = size_h.height = DispY+100 ;
X  XSetNormalHints( dpy, wins[Main_Window], &size_h );
X  XMapWindow( dpy, wins[Main_Window] ); 
X
X  wins[Display_Window]  = XCreateWindow( dpy, wins[Main_Window], 50,50,DispX, DispY,2,0,CopyFromParent,
X                          CopyFromParent, xswamask, &xswa);
X  XSetWindowColormap( dpy, wins[Display_Window], cmap );
X  XSelectInput( dpy, wins[Display_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask |
X                          PointerMotionMask | ButtonMotionMask );
X  gcs[Display_Window] = XCreateGC( dpy, wins[Display_Window], 0L, &values );
X
X  wins[Message_Window]  = XCreateWindow( dpy, wins[Main_Window], 50, DispY-50, 256 , 80, 2, 0, CopyFromParent,
X                          CopyFromParent, xswamask, &xswa );
X  XSetWindowColormap( dpy, wins[Message_Window], cmap );
X  XSelectInput( dpy, wins[Message_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask |
X                          PointerMotionMask | ButtonMotionMask );
X  gcs[Message_Window] = XCreateGC( dpy, wins[Message_Window], 0L, &values );
X
X  wins[File_Window] = XCreateWindow( dpy, wins[Main_Window], DispX-206, DispY-50,256,80,2,0,
X                      CopyFromParent, CopyFromParent, xswamask, &xswa );
X  XSetWindowColormap( dpy, wins[File_Window], cmap );
X  XSelectInput( dpy, wins[File_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
X                      ButtonMotionMask );
X  gcs[File_Window] = XCreateGC( dpy, wins[File_Window], 0L, &values );
X
X  wins[Multi_Window]  = XCreateWindow( dpy, wins[Main_Window], DispX-206, DispY-250,256,200,2,0,
X                        CopyFromParent, CopyFromParent, xswamask, &xswa );
X  XSetWindowColormap( dpy, wins[Multi_Window], cmap );
X  XSelectInput( dpy, wins[Multi_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask |
X                        PointerMotionMask|ButtonMotionMask );
X  gcs[Multi_Window] = XCreateGC( dpy, wins[Multi_Window], 0L, &values );
X
X  wins[Error_Window]  = XCreateWindow( dpy, wins[Main_Window], 50,100,DispX, 150,2,0,
X                        CopyFromParent, CopyFromParent, xswamask, &xswa );
X  XSetWindowColormap( dpy, wins[Error_Window], cmap );
X  XSelectInput( dpy, wins[Error_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask |
X                        PointerMotionMask | ButtonMotionMask );
X  gcs[Error_Window] = XCreateGC( dpy, wins[Error_Window], 0L, &values );
X
X  wins[Title_Window]  = XCreateWindow( dpy, wins[Main_Window], 200,5,DispX-300,40,0,0,
X                        CopyFromParent, CopyFromParent, xswamask, &xswa );
X  XSetWindowColormap( dpy, wins[Title_Window], cmap );
X  XSelectInput( dpy, wins[Title_Window], KeyPressMask | ExposureMask | ButtonPressMask | ButtonReleaseMask |
X                        PointerMotionMask | ButtonMotionMask );
X  gcs[Title_Window] = XCreateGC( dpy, wins[Title_Window], 0L, &values );
X
X  small = XCreatePixmap(dpy,rootwin,DispX,DispY,planes);
X  smallgc = XCreateGC( dpy,small, 0L, &values );
X
X  SetWindow(Title_Window);                  /* Set up colours of windows, etc. */
X  On();
X  SetBackColour( cols[back] );
X  XMapWindow( dpy,wins[Title_Window]);
X  SetWindow(Error_Window);
X  On();
X  SetColour( cols[errorfg] );
X  SetBackColour( cols[errorbg] );
X  SetWindow(Multi_Window);
X  On();
X  SetColour( cols[filefg] );
X  SetBackColour( cols[filebg] );
X  SetWindow(File_Window);
X  On();
X  SetColour( cols[filefg] );
X  SetBackColour( cols[filebg] );
X  SetWindow(Message_Window);
X  On();
X  SetColour( cols[verbfg] );
X  SetBackColour( cols[verbbg] );
X  SetWindow(Display_Window);
X  On();
X  SetColour( cols[domainfg] );
X  SetBackColour( cols[domainbg] );
X  XMapWindow( dpy , wins[Message_Window] );
X  XMapWindow( dpy , wins[File_Window] );
X  SetWindow(Main_Window);
X  On();
X  SetBackColour( cols[back] );
X  ClearScreen();
X  OnCursor();
X}
X
Xvoid CloseDownWindows()
X/* Close all Scamper's windows, free fonts, cursors, etc. */
X{
X  int f;
X
X  XFlush( dpy );
X  XDestroyWindow( dpy, wins[Title_Window] );
X  XDestroyWindow( dpy, wins[Error_Window] );
X  XDestroyWindow( dpy, wins[Multi_Window] );
X  XDestroyWindow( dpy, wins[File_Window] );
X  XDestroyWindow( dpy, wins[Error_Window] );
X  XDestroyWindow( dpy, wins[Display_Window] );
X  XDestroyWindow( dpy, wins[Main_Window] );
X
X  XFreeFont( dpy, fontstruct[Large_Font] );
X  XFreeFont( dpy, fontstruct[Small_Font] );
X
X  XFreeCursor( dpy, user_cursor );
X  XFreeCursor( dpy, busy_cursor );
X  XFreeCursor( dpy, enter_cursor );
X  XFreeCursor( dpy, error_cursor );
X}
X
Xvoid GetNextEvent( Event, Ch, X, Y, Button , Winnum)
X/* Get the next X enent, returningit in a convenient manner */
XEventType *Event;
Xchar *Ch;
Xint *X, *Y;
Xint *Button;
Xint *Winnum;
X{
X  char  retstr[5];
X  XEvent  xev;
X  int w ;
X
X  *Event = NoEvent;
X  *X = 0;
X  *Y = 0;
X  *Winnum = 0 ;
X  *Ch = '\0';
X  *Button = 0;
X
X  XNextEvent(dpy, &xev);
X
X  switch ( xev.type ) {
X
X    case Expose:                                        /* Expose Event, windows need redrawing */
X      if( xev.xexpose.count == 0 ) {
X        for( w=0 ; w<MaxWins ; ++w )
X          if (xev.xexpose.window == wins[w])
X            *Winnum = w ;
X        *Event = EventExpose;
X        }
X      break;
X  
X    case ButtonRelease:                                 /* Mouse button event */
X    case ButtonPress: {
X      XButtonEvent *xevb = (XButtonEvent *) &xev;
X      int Butt;
X      for( w=0 ; w<MaxWins ; ++w )
X        if (xevb->window == wins[w])
X          *Winnum = w ;
X      *X = xevb->x;
X      *Y = xevb->y;
X      switch( xevb->button ) {
X        case Button1: Butt = 1; break;
X        case Button2: Butt = 2; break;
X        default:  Butt = 3; break;
X        }
X      *Event = xev.type == ButtonPress ?
X        EventMouseDown : EventMouseUp;
X      *Button = Butt;
X      };
X      break;
X
X    case MotionNotify: {                                /* Mouse movement event */
X      XMotionEvent *xevm = (XMotionEvent *) &xev;
X      for( w=0 ; w<MaxWins ; ++w )
X        if (xevm->window == wins[w])
X          *Winnum = w ;
X      *X = xevm->x;
X      *Y = xevm->y;
X      *Event = EventMove ;
X      };
X      break;
X
X    case KeyPress:                                      /* Key press event */
X      retstr[0] = 0;
X      XLookupString( &xev, retstr, 1, NULL, NULL );
X      *Ch = retstr[0];  
X      *Event = EventKeypress;
X      break;
X    }
X}
X
Xint EventPending()
X/* Tell if there is an event pending */
X{
X  if( XPending(dpy) == 0 )
X    return 0;
X  else
X    return 1;
X}
X
Xvoid SetColour( colour ) int colour;
X/* Select the foreground colour in colour table entry `colour'. */
X{
X    XSetForeground( dpy, gc, fg = colours[colour].mapno );
X}
X
X
Xvoid SetBackColour( colour ) int colour;
X/* Select the background colour in colour table entry `colour'. */
X{
X    XSetBackground( dpy, gc, bg = colours[colour].mapno );
X    XSetWindowBackground( dpy, win, bg );
X}
X
X
Xchar *ColourName( colour ) int colour;
X/* Return the colour name of teble entry number `colour'. Returns pointer only, caller must not change string */
X{
X  return colour_names[colours[colour].num];
X}
X
Xint ColourNumber( colour ) int colour ;
X/* Return the colour map entry number of colour table entry number `colour' */
X{
X  return colours[colour].num ;
X}
X
Xvoid FillRectangle( x1, y1, x2, y2 ) int x1, y1, x2, y2;
X/* Given two coordinates of a rectangle, draw a filled rectangle with these coordinates */
X{
X  XSetFillStyle( dpy, gc, FillSolid );
X  if( x1 > x2 ) swap(x1,x2);
X  if( y1 > y2 ) swap(y1,y2);
X  XFillRectangle( dpy, win, gc, x1, y1, x2-x1, y2-y1 );
X}
X
Xvoid SelectFont( num ) int num ;
X/* Select the font : 0 - small --- 1 - large */
X{
X  thefont = num ;
X}
X
Xvoid PrintString( x, y, mesg ) int x, y; char *mesg;
X/* Print the string `mesg' at (x,y) using current font */
X{
X  XSetFont(dpy,gc,fontstruct[thefont]->fid);
X  XDrawString( dpy, win, gc, x, y, mesg, strlen(mesg) );
X}
X
X
Xvoid TextSize( mesg, w, h ) char *mesg; int *w, *h;
X/* Return the size of a string `mesg' in current font */
X{
X  *h = fontH[thefont];
X  *w = XTextWidth( fontstruct[thefont], mesg, strlen(mesg) );
X}
X
X
Xvoid OnCursor()
X/* Set cursors to `on' position */
X{
X  XDefineCursor( dpy, wins[Main_Window], user_cursor );
X  XDefineCursor( dpy, wins[Display_Window], user_cursor );
X  XDefineCursor( dpy, wins[Message_Window], error_cursor );
X  XDefineCursor( dpy, wins[File_Window], enter_cursor );
X  XDefineCursor( dpy, wins[Multi_Window], user_cursor );
X  XDefineCursor( dpy, wins[Error_Window], user_cursor );
X  XDefineCursor( dpy, wins[Title_Window], user_cursor );
X}
X
X
Xvoid BusyCursor()
X/* Set cursors to `busy' position */
X{
X  XDefineCursor( dpy, wins[Main_Window], busy_cursor );
X  XDefineCursor( dpy, wins[Display_Window], busy_cursor );
X  XDefineCursor( dpy, wins[Message_Window], busy_cursor );
X  XDefineCursor( dpy, wins[File_Window], busy_cursor );
X  XDefineCursor( dpy, wins[Multi_Window], busy_cursor );
X  XDefineCursor( dpy, wins[Error_Window], busy_cursor );
X  XDefineCursor( dpy, wins[Title_Window], busy_cursor );
X}
X
Xvoid EnterCursor()
X/* Set the cursor of the current window to `Enter cursor' */
X{
X  XDefineCursor( dpy , win, enter_cursor );
X}
X
Xvoid ErrorCursor()
X/* Set the cursor of the current window to `Error cursor' */
X{
X  XDefineCursor( dpy , win, error_cursor );
X}
X
Xvoid OffCursor()
X/* Switch the cursor off in the current window */
X{
X  XUndefineCursor( dpy, win );
X}
X
Xvoid ClearScreen()
X/* Clear the current window */
X{
X  XClearWindow( dpy, win );
X}
X
Xvoid FlushQueue()
X/* Flush the X events still pending */
X{
X  XFlush( dpy );
X}
X
Xint GetPlanes()
X/* Get the number of bit planes for the screen */
X{
X  return planes ;
X}
X
Xvoid SetWindow( num ) int num ;
X/* Select the window to be current window */
X{
X  win = wins[num] ;
X  gc = gcs[num] ;
X}
X
Xvoid DisplayOff()
X/* Switch display window off */
X{
X  XUnmapWindow(dpy,wins[1]);
X  XMapWindow(dpy,wins[3]);
X  XMapWindow(dpy,wins[2]);
X  XFlush(dpy);
X}
X
Xvoid DisplayOn()
X/* Switch display window on */
X{
X  XMapWindow(dpy,wins[1]);
X  XUnmapWindow(dpy,wins[3]);
X  XUnmapWindow(dpy,wins[2]);
X  XFlush(dpy);
X}
X
Xvoid AskOn(n) int n ;
X/* Switch Multi window on */
X{
X  if (n == 1)
X    XMoveWindow(dpy,wins[Multi_Window],DispX-206, DispY-250);
X  else
X    XMoveWindow(dpy,wins[Multi_Window],DispX-378, DispY-300);
X
X  XMapWindow(dpy,wins[Multi_Window]);
X}
X
Xvoid AskOff()
X/* Switch Multi window off */
X{
X  XUnmapWindow(dpy,wins[Multi_Window]);
X}
X
Xint GetColourValue( string ) char *string ;
X/* Get the colour number for colour named `string' */
X{
Xint n ;
X
X  n=0;
X  while(n<tablesize)
X    if (strcmp(string,color_names[n])==0)
X      return n ;
X    else
X      ++n ;
X  return 1;
X}
X
Xint GetGreyLevel( n ) int n ;
X/* return the grey level (0 to 65535) of a colour n */
X{
X  return colours[n].grey ;
X}
X
Xvoid ErrorWindow( n ) int n ;
X/* Switch error window 0 off, 1 on */
X{
X  if (n)
X    XMapWindow(dpy,wins[Error_Window]);
X  else
X    XUnmapWindow(dpy,wins[Error_Window]);
X}
X
Xint NumberOfColours()
X/* return the number of colours known to Scamper */
X{
X  return tablesize ;
X}
X
END_OF_FILE
if test 25080 -ne `wc -c <'windows.c'`; then
    echo shar: \"'windows.c'\" unpacked with wrong size!
fi
# end of 'windows.c'
fi
echo shar: End of shell archive.
exit 0
---- CUT HERE -------- CUT HERE -------- CUT HERE -------- CUT HERE ----


-- 
   _____            _____________________        Ian Palmer
  /_  _/           |                     |       Department of Computing,
   / /  ___        |                     |       Imperial College, 
  / /  / __\       | This space for rent |       180 Queen's Gate,
 /_/  / /          |                     |       London SW7 2BZ.
      \ \__        |_____________________|       
       \___/                 | |                 ijp@doc.ic.ac.uk
                            \|_|/                ijp=ack@doc.ic.ac.uk
  PANIC NOW
  and avoid       23. Add to Celt's pub meal and produce utter turmoil. (6,8)
  the rush.       -----------------------------------------------------------
Smoking is one of the leading causes of statistics.
		-- Fletcher Knebel

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.
