|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T x
Length: 13964 (0x368c) Types: TextFile Names: »xinteract.c«
└─⟦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«
/* @(#)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 (¤t_file_name_index, ¤t_file_name_length, ¤t_file_name, sizeof (char)); current_file_name [current_file_name_index - 1] = *thisch; } } } vector_push_extend (¤t_file_name_index, ¤t_file_name_length, ¤t_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 (¤t_file_name_index, ¤t_file_name_length, ¤t_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; }; }; };