DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T x

⟦770f30fbc⟧ TextFile

    Length: 13964 (0x368c)
    Types: TextFile
    Names: »xinteract.c«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./DVIware/crt-viewers/dviapollo/xinteract.c« 
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/crt-viewers/dviapollo/xinteract.c« 

TextFile

/* @(#)xinteract.c	1.6 2/18/87 */
#include "header.h"
#include <X/Xlib.h>
#include "gray1.bitmap"
#define DEFAULTFONT "vtsingle"
#define BUTTONMARGIN 4
Window frame;
Window panel;
Window textwindow;
int screenheight = 0;
int screenwidth = 0;
int textwindowheight = 0;
/* State information for the filename item. */
Window filename_button;
char *current_file_name;
int current_file_name_index;
int current_file_name_length;
/* State information for the region that displays the error messages. */
Window error_button;
char *error_message;
/* State information for the page number slider. */
/* This window has all of the graphics for the slider. */
Window page_window;
/* This window just has the slider bar itself.  It's a subwindow of */
 /* page_window. */
Window page_subwindow;
Pixmap page_tile;
int page_max = 1;
int page_current = 1;
int page_displayed;
/* X coordinate of page_subwindow in page_window. */
int pager_x = 0;
#define PAGER_WIDTH 100
/* Whether or not to carry on in reverse video. */
BOOLEAN reversevideo;
Pixmap foreground, background;
XAssocTable *callouttable; /* Assoc table for storing mapping from */
/* buttons to callout routines. */
XAssocTable *offsets; /* Assoc table to remember how much the labels */
		      /* need to be shifted right to be centered. */
Font font;
FontInfo fontinfo;

BOOLEAN reverse_video_p ();
char *realloc ();

/* On window w, coordinates (x,y) draw the text in chars. */
void dotext (w, x, y, chars)
     Window w;
     int x, y;
     char *chars;
{
  XTextPad (w, x, y, chars, strlen (chars), font, 0, 0,
	    WhitePixel, BlackPixel, reversevideo?GXor:GXandInverted,
	    AllPlanes);
}

void black_box (x, y, width, height)
     int x, y, width, height;
{
  XPixFill (textwindow, x, y, width, height,
	    reversevideo?WhitePixel:BlackPixel, 0,
	    GXcopy, AllPlanes);
}

int screen_height ()
{
  return (textwindowheight);
}

/* Cribbed from /usr/misc/X/libsun/initial.c. */
static unsigned char InvPix[256];

SetUpInvPix()
{
    register int i;

    for (i = 255; i >= 0; i--) {
	register int j = 1, k = 128, l = 8;

	while (l--) {
	    if ((i & j) != 0)
		InvPix[i] |= k;
	    j <<= 1;
	    k >>= 1;
	}
    }
}

/* Cribbed from /usr/misc/X/libsun/util.c. */
InvertPixelOrder(p, n)
	register unsigned short *p;
	register int n;
{
	for (; n--; p++) {
	    register unsigned short l = (*p & 0xff), h = (*p >> 8)&0xff;
	    unsigned short         old = *p;

	    *p = (unsigned short) ((InvPix[l] << 8) | InvPix[h]);
	}
}

/* Read a character from a font file, with the given width and height. */
 /* For X, a CharImage is a Pixmap. */
CharImage read_char (pxlfp, width, height)
     FILE *pxlfp;
     int width, height;
{
  static short *bitmapbuf = NULL;
  static int bitmapbufsize = 0;
  register int nshorts, i, col, nints;
  register short *dp, *sp;
  static int buffer[8];
  Bitmap result;

  if (!bitmapbuf) {
    bitmapbuf = (short *) malloc (1);
    bitmapbufsize = 1;
  };
  if (bitmapbufsize < BitmapSize (width, height)) {    
    bitmapbufsize = BitmapSize (width, height);
    bitmapbuf = (short *)realloc (bitmapbuf, bitmapbufsize);
  };
  if (!bitmapbuf) {
    fprintf (stderr, "Memory allocation failed in read_char.\n");
    exit (1);
  }
  nshorts = (width + 15) >> 4;
  nints = (nshorts + 1) >> 1;
  dp = bitmapbuf;
  for (col = 0; col < height; col++) {
    fread(buffer, 4, nints, pxlfp);
    sp = (short *) &buffer[0];
    for (i = nshorts; i > 0; i--) *dp++ = *sp++;
  }
  InvertPixelOrder (bitmapbuf, BitmapSize (width, height) >> 1);
  result = XStorePixmapXY (width, height, bitmapbuf);
  if (!result) {
    fprintf (stderr, "Pixmap creation failed in read_char.\n");
    exit (1);
  }
  return ((CharImage) result);
}

void show_char (x, y, width, height, image)
     int x, y, width, height;
     CharImage image;
{
  if (((x + width) >= 0) &&
      (x < screenwidth) &&
      ((y + height) >= 0) &&
      (y < screenheight)) {
      XPixmapPut (textwindow, 0, 0, x, y, width, height, (Pixmap) image,
		  reversevideo?GXor:GXandInverted, AllPlanes);
    }
};

void clearscreen ()
{
  XClear (textwindow);
}

void lock_canvas ()
{
}

void unlock_canvas ()
{
}

char *curfilename ()
{
  return (current_file_name);
}

/* Refresh the image of the slider. */
void refresh_slider ()
{
  char buffer [20];
  XClear (page_window);
  XClear (page_subwindow);
  if (page_max > 1) {
    sprintf (buffer, "Pages: [%d]", page_displayed);
    dotext (page_window, BUTTONMARGIN, BUTTONMARGIN, buffer);
    XTileSet (page_subwindow, 0, 0,
	      (int) ((float) (page_displayed - 1) / (page_max - 1) * PAGER_WIDTH),
	      fontinfo.height, page_tile);
  }
}

/* Set the slider so that it has pages pages displayed. */
void show_slider (pages)
     int pages;
{
  char buffer [20];

  page_max = pages;
  page_current = 1;
  page_displayed = 1;
  if (page_max == 1) {
    XUnmapWindow (page_subwindow);
  } else {
    XMapWindow (page_subwindow);
    sprintf (buffer, "%d", page_max);
    XConfigureWindow (page_subwindow,
		      BUTTONMARGIN +
		      (strlen ("Page: [] ") + strlen (buffer) + 1) *
		      fontinfo.width,
		      BUTTONMARGIN,
		      PAGER_WIDTH,
		      fontinfo.height);
  }
  refresh_slider ();
}

/* Update the current (not the maximum) number of pages displayed on */
/* the slider.*/
void update_slider (pages)
     int pages;
{
  page_current = pages;
  page_displayed = pages;
  refresh_slider ();
}

void curpage_from_x (event)
     XEvent *event;
{
  int new_displayed;
  if (page_max > 1) {
    new_displayed = (int) ((float) ((XKeyEvent *) event) -> x /
			   PAGER_WIDTH * (page_max - 1) + 0.5) + 1;
    if (new_displayed != page_displayed) {
      page_displayed = new_displayed;
      refresh_slider ();
    };
  }
}

int lines_to_y (lines)
     int lines;
{
  return (lines * (fontinfo.height + 3 * BUTTONMARGIN) +
	  BUTTONMARGIN);
}

int chars_to_x (chars)
     int chars;
{
  return (chars * fontinfo.width - BUTTONMARGIN);
}
 
/* This puts a button image on the screen.  It is called by 
   create_buttons.
   name is the label for the button.  It needs to be centered.
   width is the width in characters of the button.
   x,y, are the position of the button on a character grid.
   callout is the procedure to call when the button is pushed.
   */
void create_a_button (name, width, x, y, callout)
     char *name;
     int width, x, y;
     void (*callout) ();
{
  Window created;
  created = XCreateWindow (panel, chars_to_x (x), lines_to_y (y),
			   width * fontinfo.width + 2 * BUTTONMARGIN,
			   fontinfo.height + 2 * BUTTONMARGIN, 1,
			   foreground, background);
  XStoreName (created, name);
  XMakeAssoc (callouttable, created, callout);
  XMakeAssoc (offsets, created,
	      ((width - strlen (name)) >> 1) * fontinfo.width);
  XSelectInput (created, ButtonReleased | ExposeWindow);
}

void update_filename ()
{
  char *namestart;

  if (strlen (current_file_name) > 19) {
    namestart = current_file_name + (strlen (current_file_name) - 19);
  } else {
    namestart = current_file_name;
  }
  XClear (filename_button);
  {
    char buffer [35];

    sprintf (buffer, "Filename: %s", namestart);
    dotext (filename_button, BUTTONMARGIN, BUTTONMARGIN, buffer);
  }
}

void update_error ()
{
  XClear (error_button);
  dotext (error_button, BUTTONMARGIN, BUTTONMARGIN, error_message);
}

void showerror (string)
     char *string;
{
  error_message = string;
  update_error ();
}

void clearerror ()
{
  error_message = "";
  update_error ();
}

void main (argc, argv)
     int argc;
     char **argv;
{
  int downx = 0, downy = 0;
  int panelheight;

  SetUpInvPix ();
  if ((PXLpath = getenv ("BGPXLPATH")) == NULL)
    PXLpath = FONTAREA;
  error_message = "";
  current_file_name = malloc (10);
  current_file_name_index = 0;
  current_file_name_length = 10;
  { 
    char *thisch = argv [1];
    if (thisch) {
      for (;*thisch;thisch++) {
	vector_push_extend (&current_file_name_index,
			    &current_file_name_length,
			    &current_file_name,
			    sizeof (char));
	current_file_name [current_file_name_index - 1] = *thisch;
      }
    }
  }
  vector_push_extend (&current_file_name_index,
		      &current_file_name_length,
		      &current_file_name,
		      sizeof (char));
  current_file_name [current_file_name_index - 1] = '\0';
  if (!XOpenDisplay ("unix:0")) {
    fprintf (stderr, "Could not open the display.\n");
    exit (1);
  };
  reversevideo = reverse_video_p (argv [0]);
  foreground = reversevideo?WhitePixmap:BlackPixmap;
  background = reversevideo?BlackPixmap:WhitePixmap;
  page_tile = XStorePixmapXY (gray1_width, gray1_height, gray1_bits);
  {
    char *fontname = XGetDefault (argv [0], "Font");
    if (fontname == NULL) fontname = DEFAULTFONT;
    if (!(font = XGetFont (fontname))) {
      fprintf (stderr, "Couldn't open font %s for buttons.\n", fontname);
      exit (1);
    };
    XQueryFont (font, &fontinfo);
  }
  /* This is the inside height. */
  panelheight = lines_to_y (2);
  {
    OpaqueFrame oframe;
    WindowInfo info;
    char defgeom [20];
    
    oframe.border =     foreground;
    oframe.background = background;
    oframe.bdrwidth = 1;
    sprintf (defgeom, "=%dx%d+0+0",
	     DisplayWidth()-2,
	     DisplayHeight()-2);
    frame = XCreate (argv [0], argv [0],
		      0, defgeom,
		      &oframe,
		     chars_to_x (70) + BUTTONMARGIN +PAGER_WIDTH,
		     2 * panelheight);
    XSelectInput (frame, ExposeWindow | ButtonPressed
		  | ButtonReleased
		  | KeyPressed);
    XQueryWindow (frame, &info);
    screenwidth = info.width;
    screenheight = info.height;
    panel = XCreateWindow (frame, -1, -1, screenwidth,
			   panelheight, 1, foreground, background);
    textwindowheight = screenheight - panelheight;
    /* The border pixmap below is background so we can have an */
    /* invisible border.  We want a border, though, so that this */
    /* window lines up with the buttons. */
    filename_button = XCreateWindow (panel,
				     chars_to_x (0), lines_to_y (0),
				     chars_to_x (30), lines_to_y (1),
				     1, background, background);
    XSelectInput (filename_button, ExposeWindow);
    error_button = XCreateWindow (panel,
				  chars_to_x (0), lines_to_y (1),
				  chars_to_x (30), lines_to_y (1),
				  1, background, background);
    XSelectInput (error_button, ExposeWindow);
    page_window = XCreateWindow (panel,
				 chars_to_x (57), lines_to_y (0),
				 chars_to_x (30) + PAGER_WIDTH,
				 lines_to_y (1),
				 1, background, background);
    XSelectInput (page_window, ExposeWindow);
    /* The real shape of the page_subwindow will be determined when */
    /* show_slider is called. */
    page_subwindow = XCreateWindow (page_window, 1, 1, 1, 1,
				    1,
				    foreground, background);
    XSelectInput (page_subwindow, LeaveWindow | MouseMoved |
		  ButtonPressed | ButtonReleased);
    callouttable = XCreateAssocTable (2);
    offsets = XCreateAssocTable (2);
    create_buttons ();
    XMapSubwindows (panel);
    /* + 1 and -1 below are to account for the border around the pane. */ 
    textwindow =
      XCreateWindow (frame, 0, panelheight + 1,
		     screenwidth, textwindowheight,
		     0, foreground, background);
    XSelectInput (textwindow, ExposeWindow);
  }
  XMapSubwindows (frame);
  XMapWindow (frame);
  reset_scroll ();
  if (current_file_name [0]) {
    load_proc ();
  };
  for (;;) {
    char *string;
    XEvent e;
    void (*callout) ();

    XNextEvent (&e);
    callout = (void (*)()) XLookUpAssoc (callouttable, e.window);
    switch (e.type) {
    case KeyPressed:
      {
	int length;
	char *string;
	string = XLookupMapping (&e, &length);
	if (length) {
	  for (;length; string++,length--) {
	    if (*string == '\010' || *string == '\177') {
	      if (*current_file_name) {
		current_file_name_index--;
		current_file_name [current_file_name_index - 1] = '\0';
	      }
	    } else {
	      current_file_name [current_file_name_index - 1] = *string;
	      vector_push_extend (&current_file_name_index,
				  &current_file_name_length,
				  &current_file_name,
				  sizeof (char));
	      current_file_name [current_file_name_index - 1] = '\0';
	    }
	  }
	}
	update_filename ();
      }
      break;
    case MouseMoved:
      /* The event must be in page_subwindow. */
      curpage_from_x (&e);
      break;
    case LeaveWindow:
      /* The event must be in page_subwindow. */
      page_displayed = page_current;
      refresh_slider ();
      break;
    case ButtonPressed:
      if (e.window == page_subwindow) {
	curpage_from_x (&e);
	page_current = page_displayed;
	goto_page (page_current);
      } else if (!callout) {
	buttondown (((XKeyEvent *) &e) -> x,
		    ((XKeyEvent *) &e) -> y);
      };
      break;
    case ButtonReleased:
      if (e.window == page_subwindow) {
	/* Do nothing. */
      } else if (callout) {
	(*callout) ();
      } else {
	buttonup (((XKeyEvent *) &e) -> x,
		  ((XKeyEvent *) &e) -> y);
      };
      break;
    case ExposeWindow:
      if (e.window == filename_button) {
	update_filename ();
      } else if (e.window == error_button) {
	update_error ();
      } else if (e.window == page_window ) {
	refresh_slider ();
      } else if (callout) {
	char *name;
	int offset;

	offset = (int) XLookUpAssoc (offsets, e.window);
	XFetchName (e.window, &name);
	dotext (e.window,
		BUTTONMARGIN + offset, BUTTONMARGIN,
		name);
	free (name);
      } else if ((e.window == frame) &&
		 (((XExposeEvent *) &e) -> subwindow == 0)) {
	if ((screenwidth != ((XExposeEvent *) &e) -> width) ||
	    (screenheight != ((XExposeEvent *) &e) -> height)) {
	      screenwidth = ((XExposeEvent *) &e) -> width;
	      screenheight = ((XExposeEvent *) &e) -> height;
	      textwindowheight = screenheight - panelheight;
	      XChangeWindow (panel, screenwidth, panelheight);
	      XChangeWindow (textwindow, screenwidth,
			     textwindowheight);
	    }
      } else if (e.window == textwindow) {
	refresh_proc ();
      };
      break;
    };
  };
};