v08i057: wscrawl, Part05/05
Brian Wilson
brianw at hpcvlx.cv.hp.com
Mon Jul 16 04:57:36 AEST 1990
Submitted-by: Brian Wilson <brianw at hpcvlx.cv.hp.com>
Posting-number: Volume 8, Issue 57
Archive-name: wscrawl/part05
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
# "End of archive 5 (of 5)."
# Contents: wscrawl/image_f_io.c wscrawl/xab
# Wrapped by argv at turnpike on Sun Jul 15 11:47:13 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'wscrawl/image_f_io.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'wscrawl/image_f_io.c'\"
else
echo shar: Extracting \"'wscrawl/image_f_io.c'\" \(17959 characters\)
sed "s/^X//" >'wscrawl/image_f_io.c' <<'END_OF_FILE'
X/*
X * This file: image_f_io.c (part of the WSCRAWL program)
X *
X * This file contains the "Image File I/O" package for wscrawl (or anything
X * for that matter.) The format used is the standard X-Window Dump form
X * that the MIT client "xwd" uses. This File I/O was made possible by the
X * help and extensive source code of Mark Cook of Hewlett-Packard, who I
X * bothered endlessly to get this working.
X *
X * I tried to make this file of routines as self-contained and portable as
X * possible. Please feel free to use this file as is, or with modifications,
X * for any and all applications. -- Brian Wilson
X *
X * This file was last modified: 7/14/90
X */
X
X#define TRUE 1
X#define FALSE 0
X#define BAD_CHOICE -1
X#define NO_DUPLICATE -1
X#define UNALLOCATED -1
X
X#include <X11/Xos.h>
X#include <X11/XWDFile.h>
X#include <X11/Xlib.h>
X#include <stdio.h>
X
Xextern char *malloc();
XXImage *read_image_from_disk();
X
X
X/*
X * save_image_on_disk - this routine saves the region specified by the various
X * parameters out to disk in the "defacto standard" (xwd) format.
X */
Xsave_image_on_disk(disp, win_id, x, y, width, height, name_of_file)
XDisplay *disp;
XWindow win_id;
Xint x, y, width, height;
Xchar *name_of_file;
X{
X unsigned long swaptest = TRUE;
X XRectangle box2;
X XRectangle *box;
X FILE *out_file_ptr;
X XColor *colors;
X unsigned buffer_size;
X int win_name_size;
X int header_size;
X int format=ZPixmap;
X int ncolors, i;
X XWindowAttributes win_info;
X XImage *ImagePix;
X XWDFileHeader header;
X
X /*
X * convert to form this code understands (I got code from Mark Cook)
X */
X box = &box2;
X box->x = x;
X box->y = y;
X box->width = width;
X box->height = height;
X
X /*
X * Open the file in which the image is to be stored
X */
X if ((out_file_ptr = fopen(name_of_file, "w")) == NULL)
X {
X printf("ERROR: Could not open file %s.\n", name_of_file);
X return(0);
X }
X else
X { /* Dump the image to the specified file */
X
X if (!XGetWindowAttributes(disp, win_id, &win_info))
X {
X printf("Can't get window attributes.\n");
X return(0);
X }
X
X /*
X * sizeof(char) is included for the null string terminator.
X */
X win_name_size = strlen(name_of_file) + sizeof(char);
X
X ImagePix = XGetImage(disp, win_id, box->x, box->y, box->width,
X box->height, AllPlanes, format);
X XFlush(disp);
X
X if (ImagePix == NULL)
X {
X printf("GetImage failed.\n");
X return(0);
X }
X
X buffer_size = Image_Size(ImagePix,format);/*determines size of pixmap*/
X
X /*
X * Get the RGB values for the current color cells
X */
X if ((ncolors = Get_Colors(&colors, disp)) == 0)
X {
X printf("Cannot alloc memory for color structs.\n");
X return(0);
X }
X XFlush(disp);
X
X header_size = sizeof(header) +win_name_size; /*Calculates header size*/
X
X /*
X * Assemble the file header information
X */
X header.header_size = (xwdval) header_size;
X header.file_version = (xwdval) XWD_FILE_VERSION;
X header.pixmap_format = (xwdval) format;
X header.pixmap_depth = (xwdval) ImagePix->depth;
X
X header.pixmap_width = (xwdval) ImagePix->width;
X header.pixmap_height = (xwdval) ImagePix->height;
X header.xoffset = (xwdval) ImagePix->xoffset;
X header.byte_order = (xwdval) ImagePix->byte_order;
X header.bitmap_unit = (xwdval) ImagePix->bitmap_unit;
X header.bitmap_bit_order = (xwdval) ImagePix->bitmap_bit_order;
X header.bitmap_pad = (xwdval) ImagePix->bitmap_pad;
X header.bits_per_pixel = (xwdval) ImagePix->bits_per_pixel;
X header.bytes_per_line = (xwdval) ImagePix->bytes_per_line;
X header.visual_class = (xwdval) win_info.visual->class;
X header.red_mask = (xwdval) win_info.visual->red_mask;
X header.green_mask = (xwdval) win_info.visual->green_mask;
X header.blue_mask = (xwdval) win_info.visual->blue_mask;
X header.bits_per_rgb = (xwdval) win_info.visual->bits_per_rgb;
X header.colormap_entries = (xwdval) win_info.visual->map_entries;
X header.ncolors = ncolors;
X header.window_width = (xwdval) ImagePix->width;
X header.window_height = (xwdval) ImagePix->height;
X header.window_x = (xwdval) 0;
X header.window_y = (xwdval) 0;
X header.window_bdrwidth = (xwdval) 0;
X
X if (*(char *) &swaptest)
X {
X _swaplong((char *) &header, sizeof(header));
X for (i = 0; i < ncolors; i++)
X {
X _swaplong((char *) &colors[i].pixel, sizeof(long));
X _swapshort((char *) &colors[i].red, 3 * sizeof(short));
X }
X }
X
X /*
X * Write out the file header information
X */
X (void) fwrite((char *)&header, sizeof(header), 1, out_file_ptr);
X (void) fwrite(name_of_file, win_name_size, 1, out_file_ptr);
X
X /*
X * Write out the color cell RGB values
X */
X (void) fwrite((char *) colors, sizeof(XColor), ncolors, out_file_ptr);
X
X /*
X * Write out the buffer
X */
X (void) fwrite(ImagePix->data, (int) buffer_size, 1, out_file_ptr);
X
X if(ncolors > 0)
X free(colors); /*free the color buffer*/
X
X fclose(out_file_ptr);
X XFlush(disp);
X }
X}
X
X
X/*
X * Image_Size - this routine takes an XImage and returns it's total byte count
X */
Xint Image_Size(image, format)
XXImage *image;
Xint format;
X{
X if (format != ZPixmap)
X return(image->bytes_per_line * image->height * image->depth);
X else
X return(image->bytes_per_line * image->height);
X}
X
X
X/*
X * Get_Colors - takes a pointer to an XColor struct and returns the total
X * number of cells in the current colormap, plus all of their
X * RGB values.
X */
XGet_Colors(colors, disp)
XXColor **colors;
XDisplay *disp;
X{
X int i, ncolors;
X
X ncolors = DisplayCells(disp, DefaultScreen(disp));
X
X if ((*colors = (XColor *) malloc (sizeof(XColor) * ncolors)) == NULL)
X return(FALSE);
X
X for (i=0; i<ncolors; i++)
X (*colors)[i].pixel = i;
X
X XQueryColors(disp, XDefaultColormapOfScreen(XDefaultScreenOfDisplay(disp)),
X *colors, ncolors);
X return(ncolors);
X}
X
X
X/*
X * _swapshort - this routine is stolen, and I don't know what it does
X */
X_swapshort (bp, n)
Xregister char *bp;
Xregister unsigned n;
X{
X register char c;
X /* register char *ep = bp + n; */
X register char *ep;
X
X ep = bp + n;
X while (bp < ep)
X {
X c = *bp;
X *bp = *(bp + 1);
X bp++;
X *bp++ = c;
X }
X}
X
X
X/*
X * _swaplong - this routine is stolen, and I don't know what it does
X */
X_swaplong (bp, n)
Xregister char *bp;
Xregister unsigned n;
X{
X register char c;
X /* register char *ep = bp + n; */
X register char *sp;
X register char *ep;
X
X ep = bp + n;
X while (bp < ep)
X {
X sp = bp + 3;
X c = *sp;
X *sp = *bp;
X *bp++ = c;
X sp = bp + 1;
X c = *sp;
X *sp = *bp;
X *bp++ = c;
X bp += 2;
X }
X}
X
X
X/*
X * read_image_from_disk - this routine reads the file indicated and allocates
X * and loads up and then finally returns the XImage structure
X * ready to blow out to the indicated display. If at all
X * possible, it attempts to return an image with the
X * depth equalling the depth of the disp passed in. Either
X * way, it will return the depth it managed to get.
X */
XXImage *read_image_from_disk(disp, win_id, name_of_file, width, height, depth)
XDisplay *disp;
XWindow win_id;
Xchar *name_of_file;
Xint *width, *height, *depth;
X{
X XImage *ImagePix;
X unsigned long swaptest = TRUE;
X unsigned buffer_size;
X char *buffer;
X char *win_name;
X int format;
X int i, name_size, ncolors;
X XColor *colors;
X FILE *in_file;
X XWDFileHeader header;
X
X if ((in_file = fopen(name_of_file, "r")) == NULL) /*open file for read*/
X {
X printf("ERROR: could not open file %s.\n", name_of_file);
X return(0);
X }
X
X if(fread((char *)&header, sizeof(header), 1, in_file) != 1) /*read header*/
X {
X printf("ERROR: unable to read imagefile header.\n");
X return(0);
X }
X
X if (*(char *) &swaptest)
X _swaplong((char *) &header, sizeof(header));
X
X /*
X * check to see if the dump file is in the proper format
X */
X if (header.file_version != XWD_FILE_VERSION)
X {
X printf("ERROR: Imagefile format version mismatch.\n");
X return(0);
X }
X
X if (header.header_size < sizeof(header))
X {
X printf("ERROR: Imagefile header is too small.\n");
X return(0);
X }
X
X name_size = (header.header_size - sizeof(header)); /*space for window name*/
X
X if((win_name = malloc((unsigned) name_size*sizeof(char))) == NULL)
X {
X printf("ERROR: Can't malloc window name storage.\n");
X return(0);
X }
X
X /*
X * Read in window name
X */
X if(fread(win_name, sizeof(char), name_size, in_file) != name_size)
X {
X printf("ERROR: Unable to read window name from file.\n");
X return(0);
X }
X
X /*
X * Malloc the image data space and initialize it
X */
X if((ImagePix = (XImage *) malloc(sizeof(XImage))) == NULL)
X {
X printf("ERROR: Can't malloc space for the image.\n");
X return(0);
X }
X
X ImagePix->width = (int) header.pixmap_width;
X ImagePix->height = (int) header.pixmap_height;
X ImagePix->xoffset = (int) header.xoffset;
X ImagePix->format = (int) header.pixmap_format;
X ImagePix->byte_order = (int) header.byte_order;
X ImagePix->bitmap_unit = (int) header.bitmap_unit;
X ImagePix->bitmap_bit_order = (int) header.bitmap_bit_order;
X ImagePix->bitmap_pad = (int) header.bitmap_pad;
X ImagePix->depth = (int) header.pixmap_depth;
X ImagePix->bits_per_pixel = (int) header.bits_per_pixel;
X ImagePix->bytes_per_line = (int) header.bytes_per_line;
X ImagePix->red_mask = header.red_mask;
X ImagePix->green_mask = header.green_mask;
X ImagePix->blue_mask = header.blue_mask;
X ImagePix->obdata = NULL;
X _XInitImageFuncPtrs(ImagePix);
X
X format = ImagePix->format;
X
X /* malloc memory for the RGB values from the old colormap and read
X * in the values
X */
X if (ncolors = header.ncolors)
X {
X if ((colors = (XColor *) malloc(ncolors * sizeof(XColor))) == NULL)
X {
X printf("ERROR: Can't malloc space for the image cmap.\n");
X if (win_name)
X free(win_name);
X if (ImagePix)
X XDestroyImage(ImagePix);
X return(0);
X }
X
X if (fread((char *)colors, sizeof(XColor), ncolors, in_file) != ncolors)
X {
X printf("ERROR: Unable to read cmap from imagefile.\n");
X if (win_name)
X free(win_name);
X if (ImagePix)
X XDestroyImage(ImagePix);
X if (colors)
X free((char *) colors);
X return(0);
X }
X
X if (*(char *) &swaptest)
X {
X for (i = 0; i < ncolors; i++)
X {
X _swaplong((char *) &colors[i].pixel, sizeof(long));
X _swapshort((char *) &colors[i].red, 3 * sizeof(short));
X }
X }
X }
X
X buffer_size = Image_Size(ImagePix, format); /*malloc the pixel buffer*/
X if ((buffer = malloc(buffer_size * sizeof(char))) == NULL)
X {
X printf("ERROR: Can't malloc the data buffer.\n");
X if (win_name)
X free(win_name);
X if(ImagePix)
X XDestroyImage(ImagePix);
X if (colors)
X free((char *) colors);
X return(0);
X }
X ImagePix->data = buffer;
X
X /*
X * Read in the pixmap buffer
X */
X if(fread(buffer, sizeof(char), (int)buffer_size, in_file) != buffer_size)
X {
X printf("ERROR: Unable to read pixmap from imagefile.\n");
X if (win_name)
X free(win_name);
X if(ImagePix)
X XDestroyImage(ImagePix);
X if (colors)
X free((char *) colors);
X if (buffer)
X free((char *) buffer);
X return(0);
X }
X
X (void) fclose(in_file); /*we are done with the infile*/
X
X *depth = ImagePix->depth; /*even if the rest fails, return the dimensions*/
X *width = ImagePix->width;
X *height = ImagePix->height;
X
X if (win_name && (name_size > 0))
X free(win_name);
X if (allocate_colors_and_assign_em(disp, win_id, &ImagePix, colors)
X != TRUE)
X {
X /* the above
X * converts the pixels in the xwd file over to the current colormap,
X * and also swaps the image to a new depth if the depth the
X * image was stored on disk as disagrees with the depth of the window
X * it is to be blasted into. This block is if that fails.
X */
X printf("ERROR: Can't convert xwd file to usuable format.\n");
X printf(" Probably because the display is a wimpy non-HP.\n");
X if(ImagePix)
X XDestroyImage(ImagePix);
X if (colors)
X free((char *) colors);
X return(0);
X }
X else if (colors)
X free((char *) colors);
X
X *depth = ImagePix->depth; /*the depth may have changed*/
X return(ImagePix);
X}
X
X
X/*
X * allocate_colors_and_assign_em - this function takes an XImage and it's
X * colormap as it was at the time the image was created, and
X * allocates cells in the system colormap matching those old colors
X * and shuffles the pixels in the image to point to our new color
X * cells instead of those old color cells.
X */
Xallocate_colors_and_assign_em(disp, win_id, image_ptr, cells)
XDisplay *disp;
XWindow win_id;
XXImage **image_ptr;
XXColor *cells;
X{
X int width, height, i, j, num_cells_in_colormap;
X unsigned long *opv, *npv; /*old and new pixel values*/
X unsigned long tmp_pixel_value;
X XColor screen_in_out;
X XImage *diff_depth_im, *image;
X XWindowAttributes win_attr;
X int buffer_size;
X char *buffer;
X
X image = *image_ptr; /*for my sanity*/
X height = image->height;
X width = image->width;
X
X /*
X * determine the number of cells in the colormap by taking 2 to the power
X * of the number of bits of depth this display has.
X */
X for (i=0, num_cells_in_colormap=1; i<(*image_ptr)->depth; i++)
X num_cells_in_colormap *= 2;
X
X if (num_cells_in_colormap > 256)
X {
X printf("WARNING: This is a monster deep display image, dude. This ");
X printf("image\n");
X printf(" will take %d mega-bytes of free memory to process.\n",
X ((num_cells_in_colormap * sizeof(unsigned long))/1024)/1024);
X }
X
X /*
X * set up temporary storage for the old and new pixel values
X */
X opv = (unsigned long *) malloc(num_cells_in_colormap*sizeof(unsigned long));
X npv = (unsigned long *) malloc(num_cells_in_colormap*sizeof(unsigned long));
X
X if (!opv || !npv)
X {
X printf("ERROR: unable to malloc the temporary pixel storage.\n");
X if (opv)
X free((char *) opv);
X if (npv)
X free((char *) npv);
X return(0);
X }
X
X /*
X * Each opv value is a flag indicating whether or not that pixel is
X * present in the image. Each npv value is it's replacement value.
X */
X for (i=0; i<num_cells_in_colormap; i++)
X {
X opv[i] = FALSE;
X npv[i] = UNALLOCATED;
X }
X
X for (i=0; i<height;i++) /*examine each pxl in image; recrd all used values*/
X for (j=0; j<width; j++)
X {
X tmp_pixel_value = XGetPixel(image, j, i);
X if (tmp_pixel_value >= num_cells_in_colormap)
X {
X printf("ERROR: Bad pixel value at x=%d, y=%d, pixel=%ld\n",
X j, i, tmp_pixel_value);
X }
X else
X opv[tmp_pixel_value] = TRUE;
X }
X
X /*
X * For each TRUE opv allocate the colors
X */
X for (i=0; i<num_cells_in_colormap; i++)
X {
X if (opv[i])
X {
X screen_in_out.red = cells[i].red;
X screen_in_out.green = cells[i].green;
X screen_in_out.blue = cells[i].blue;
X screen_in_out.flags = DoRed | DoGreen | DoBlue;
X
X if (XAllocColor(disp,
X XDefaultColormapOfScreen(XDefaultScreenOfDisplay(disp)),
X &screen_in_out) == 0)
X {
X printf("ERROR: out of colors on this display. ");
X printf("Cannot import image.\n");
X return(0);
X }
X else
X npv[i] = screen_in_out.pixel;
X }
X }
X
X XGetWindowAttributes(disp, win_id, &win_attr);
X
X if (win_attr.depth == image->depth) /*cool, this is easy*/
X {
X for (i=0; i<height; i++)
X for (j=0; j<width; j++)
X XPutPixel(image, j, i, npv[XGetPixel(image, j, i)]);
X }
X else /*oh darn it, this is tough*/
X {
X /*
X * the concept here is to creat a new image that IS the correct
X * depth and then do "PutPixel" into it, filling it with the correct
X * color pixels.
X */
X diff_depth_im = XCreateImage(disp, win_attr.visual, win_attr.depth,
X image->format, image->xoffset, NULL, width,
X height, image->bitmap_pad, 0);
X
X buffer_size = Image_Size(diff_depth_im,
X diff_depth_im->format); /*malloc pixel buffer*/
X if ((buffer = malloc(buffer_size * sizeof(char))) == NULL)
X {
X printf("ERROR: Can't malloc data buffer for differing depth.\n");
X return(0);
X }
X diff_depth_im->data = buffer;
X
X for (i=0; i<height; i++)
X for (j=0; j<width; j++)
X XPutPixel(diff_depth_im, j, i,
X npv[XGetPixel(image, j, i)]);
X
X *image_ptr = diff_depth_im;
X XDestroyImage(image); /*free up space of wrong depth image*/
X }
X
X if (opv)
X free((char *) opv);
X if (npv)
X free((char *) npv);
X
X return(1);
X}
X
END_OF_FILE
if test 17959 -ne `wc -c <'wscrawl/image_f_io.c'`; then
echo shar: \"'wscrawl/image_f_io.c'\" unpacked with wrong size!
fi
# end of 'wscrawl/image_f_io.c'
fi
if test -f 'wscrawl/xab' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'wscrawl/xab'\"
else
echo shar: Extracting \"'wscrawl/xab'\" \(33168 characters\)
sed "s/^X//" >'wscrawl/xab' <<'END_OF_FILE'
X (*num_people_drawing)++; /*another dude is now drawing*/
X return(1);
X }
X else if ((the_event->window == disp_info[disp_num].status_win_id) ||
X (the_event->window == disp_info[disp_num].eraser_win_id) ||
X (the_event->window == disp_info[disp_num].dialog_win_id))
X { /*it is in the status window*/
X return(1); /*no action taken*/
X }
X else /*it is in a menu, determine which menu*/
X {
X for (i=0, menu_num = -1; i<NUM_OF_MENUS; i++)
X if (the_event->window == disp_info[disp_num].menu[i].win_id)
X {
X menu_num = i;
X break;
X }
X if (menu_num == -1)
X {
X printf("\nSome error occured. ButtonPress in WHAT window?\n");
X return(0);
X }
X
X /*if we got this far, the button press is in a menu*/
X disp_info[disp_num].current_menu = menu_num;
X disp_info[disp_num].pointer_state = IN_MENU;
X disp_info[disp_num].menu[menu_num].item_selected = 0;
X if (disp_info[disp_num].scrawl_mode != TYPING)
X (*num_people_drawing)++; /*another dude is now drawing*/
X draw_menu(disp_num); /*draw the menus with this new info*/
X }
X }
X}
X
X
X/*
X * handle_Expose_event - this function handles an Expose event in any window.
X * The most important windows are the menu and status windows,
X * which contain text that must always be there. Therefore,
X * this preserves that text.
X */
Xhandle_Expose_event(our_event, disp_num)
XXEvent *our_event;
Xint disp_num;
X{
X XExposeEvent *the_event;
X int menu_num;
X
X the_event = (XExposeEvent *) our_event;
X
X if ((the_event->window == disp_info[disp_num].win_id) ||
X (the_event->window == disp_info[disp_num].eraser_win_id))
X {
X return(1); /*we don't care about these window expose events*/
X }
X else if (the_event->window == disp_info[disp_num].dialog_win_id)
X {
X draw_dialog_win_message(disp_num);
X return(1);
X }
X else if (the_event->window == disp_info[disp_num].status_win_id)
X {
X draw_status_win_message(disp_num);
X return(1);
X }
X else /*It must be in a menu. Determine which menu and draw text.*/
X {
X for (menu_num=0; menu_num<NUM_OF_MENUS; menu_num++)
X {
X if (the_event->window == disp_info[disp_num].menu[menu_num].win_id)
X break;
X }
X
X if (menu_num >= NUM_OF_MENUS)
X {
X printf("\nERROR: unknown window in handle_Expose_event().\n");
X exit(0);
X }
X
X draw_menu_text(disp_num, menu_num); /*draw the menu text*/
X }
X}
X
X
X/*
X * handle_KeyPress_event - this function handles a KeyPress event in
X * this particular scrawler's window.
X */
Xhandle_KeyPress_event(our_event, disp_num)
XXEvent *our_event;
Xint disp_num;
X{
X XKeyPressedEvent *the_event;
X
X the_event = (XKeyPressedEvent *) our_event;
X
X if ((disp_info[disp_num].scrawl_mode == TYPING) &&
X (disp_info[disp_num].pointer_state != IN_MENU))
X {
X XPutBackEvent(disp_info[disp_num].disp, (XEvent *) the_event);
X }
X else if ((disp_info[disp_num].scrawl_mode == RESPONDING_TO_DIALOG) &&
X (the_event->window == disp_info[disp_num].dialog_win_id))
X {
X XPutBackEvent(disp_info[disp_num].disp, (XEvent *) the_event);
X }
X}
X
X
X/*
X * handle_ConfigureNotify_event - this function handles the resizing of a
X * window. If a person resizes their window, it resizes
X * ALL the windows associated with this session. In this
X * way, the scrawlers share the size of their window.
X * NOTE: This routine is not full proof. I never figured
X * out how to remove all contention problems. For instance,
X * if two people resize their windows simultaneously, there
X * occurs this wierd bouncing action. If you can figure
X * something better than this out, you're a stud. As for
X * me, it's 3am and I'm going home now.
X */
Xhandle_ConfigureNotify_event(our_event, disp_num)
XXEvent *our_event;
Xint disp_num;
X{
X XConfigureEvent *the_event, *tmp_event, *(event_history[50]);
X XEvent *the_new_event;
X int i, history_index;
X
X the_event = (XConfigureEvent *) our_event;
X
X if ((the_event->window != disp_info[disp_num].win_id) ||
X (disp_info[disp_num].in_session_bool == FALSE))
X {
X return(0); /*we are not interested in this event*/
X }
X
X if ((the_event->width == disp_info[disp_num].win_width) &&
X (the_event->height == disp_info[disp_num].win_height))
X {
X return(0); /*we are not interested in this event*/
X }
X else
X {
X disp_info[disp_num].win_width = the_event->width; /*the new height*/
X disp_info[disp_num].win_height = the_event->height;
X }
X
X /*
X * first go through ALL the resize events for ALL scrawl windows and
X * throw away all that do not agree exactly with this one. Put the
X * ones that do agree back on the queue, as those are for other windows.
X *
X * this was necessary to avoid a perpetual loop that occurs if two people
X * try to resize at the same time.
X */
X the_new_event = (XEvent *) malloc (sizeof(XEvent));
X
X for (i=0; i<num_of_disps; i++)
X {
X history_index=0;
X
X if (disp_info[i].in_session_bool == TRUE)
X {
X while (XCheckTypedWindowEvent(disp_info[i].disp,
X disp_info[i].win_id,
X ConfigureNotify, the_new_event))
X {
X tmp_event = (XConfigureEvent *) the_new_event;
X
X if ((the_event->width == tmp_event->width) &&
X (the_event->height == tmp_event->height))
X {
X event_history[history_index] = tmp_event;
X history_index++;
X the_new_event = (XEvent *) malloc (sizeof(XEvent));
X }
X }
X
X /*put all the events back onto the queue*/
X for (history_index--; history_index>=0; history_index--)
X {
X XPutBackEvent(disp_info[i].disp,
X (XEvent *) event_history[history_index]);
X free(event_history[history_index]);
X }
X }
X }
X
X
X for (i=0; i<num_of_disps; i++)
X {
X if (disp_info[i].in_session_bool == TRUE)
X {
X if ((disp_info[i].win_width != the_event->width) ||
X (disp_info[i].win_height != the_event->height))
X {
X XResizeWindow(disp_info[i].disp, disp_info[i].win_id,
X the_event->width, the_event->height);
X disp_info[i].win_width = the_event->width;
X disp_info[i].win_height = the_event->height;
X
X XSync(disp_info[i].disp, False);
X }
X }
X }
X
X for (i=0; i<num_of_disps; i++)
X {
X if (disp_info[i].in_session_bool == TRUE)
X {
X XSync(disp_info[i].disp, False);
X /*
X XClearWindow(disp_info[i].disp, disp_info[i].win_id);
X */
X XFlush(disp_info[i].disp);
X
X if (disp_info[i].cursor_on == TRUE)
X { /*then turn it BACK on from the "clear window turnoff"*/
X XDrawLine(disp_info[i].disp,
X disp_info[i].win_id,
X disp_info[i].cursor_gc,
X disp_info[i].cur_pos.x,
X disp_info[i].cur_pos.y,
X disp_info[i].cur_pos.x +
X disp_info[i].prompt_width,
X disp_info[i].cur_pos.y);
X }
X XSync(disp_info[i].disp, False); /*all the XSyncs are trying*/
X } /*to avoid a bad timing prob*/
X }
X
X for (i=0; i<num_of_disps; i++)
X {
X if (disp_info[i].in_session_bool == TRUE)
X {
X XSync(disp_info[i].disp, False);
X place_and_draw_status_win(i);
X }
X }
X /*
X NOTHING_DRAWN_YET = TRUE;
X */
X}
X
X
X/*
X * handle_ButtonRelease_event - this function handles a ButtonRelease event in
X * this particular scrawler's window. It is probably a
X * scrawler stopping drawing, but it could be a menu selection
X * or a "select area" finishing, so those are checked for
X * also.
X */
Xhandle_ButtonRelease_event(our_event, disp_num, num_people_drawing)
XXEvent *our_event;
Xint disp_num, *num_people_drawing;
X{
X XButtonPressedEvent *the_event;
X int menu_num, item_selected, tot_num_items, i;
X int start_x, start_y, last_x, last_y, temp, oldleft, oldtop;
X
X the_event = (XButtonPressedEvent *) our_event;
X
X if (disp_info[disp_num].scrawl_mode == RESPONDING_TO_DIALOG)
X return(0); /*not allowed to do anything else*/
X
X if (the_event->button == Button1)
X {
X if (the_event->window == disp_info[disp_num].win_id)
X {
X disp_info[disp_num].pointer_state = NOT_PRESSED;
X if (disp_info[disp_num].scrawl_mode != TYPING)
X (*num_people_drawing)--; /*a dude has stopped drawing*/
X
X if (disp_info[disp_num].scrawl_mode == ERASING)
X {
X XUnmapWindow(disp_info[disp_num].disp,
X disp_info[disp_num].eraser_win_id);
X }
X else if (disp_info[disp_num].scrawl_mode == RUBBER_POINTING)
X {
X /*erase last pointer*/
X oldleft = disp_info[disp_num].last_point.x;
X oldtop = disp_info[disp_num].last_point.y -
X disp_info[disp_num].rubber_pointer.height;
X disp_info[disp_num].rubber_pointer.is_mapped_bool = FALSE;
X for (i=0; i<num_of_disps; i++)
X {
X if (disp_info[i].in_session_bool)
X {
X XCopyArea(disp_info[i].disp,
X disp_info[disp_num].rubber_pointer.rubber_pointer_pix[i],
X disp_info[i].win_id, disp_info[disp_num].win_gc[i],
X 0, 0, disp_info[disp_num].rubber_pointer.width,
X disp_info[disp_num].rubber_pointer.height, oldleft,
X oldtop);
X XFlush(disp_info[i].disp);
X }
X }
X }
X else if ((disp_info[disp_num].scrawl_mode == PLACING_A_BITMAP) ||
X (disp_info[disp_num].scrawl_mode == PLACING_AN_IMAGE) ||
X (disp_info[disp_num].scrawl_mode == PLACING_A_TEXTFILE))
X {
X if (disp_info[disp_num].just_placed_something_bool == TRUE)
X {
X disp_info[disp_num].just_placed_something_bool = FALSE;
X return(0); /*throw this event away*/
X }
X }
X else if (disp_info[disp_num].scrawl_mode == SELECTING_AN_AREA)
X {
X /*erase select rectangle*/
X start_x = disp_info[disp_num].select_start_pos.x;
X start_y = disp_info[disp_num].select_start_pos.y;
X last_x = disp_info[disp_num].cur_pos.x;
X last_y = disp_info[disp_num].cur_pos.y;
X
X if (start_x > last_x) /*switch so lesser coordinate is first*/
X {
X temp = start_x;
X start_x = last_x;
X last_x = temp;
X }
X if (start_y > last_y) /*switch so lesser coordinate is first*/
X {
X temp = start_y;
X start_y = last_y;
X last_y = temp;
X }
X XDrawRectangle(disp_info[disp_num].disp,
X disp_info[disp_num].win_id,
X disp_info[disp_num].rubber_band_gc,
X start_x, start_y, last_x - start_x, last_y - start_y);
X
X /*
X * shapes was really hacked in here. This is a kludge.
X */
X if (disp_info[disp_num].dialog_what == DRAW_SHAPE)
X {
X start_x = disp_info[disp_num].select_start_pos.x;
X start_y = disp_info[disp_num].select_start_pos.y;
X last_x = disp_info[disp_num].cur_pos.x;
X last_y = disp_info[disp_num].cur_pos.y;
X draw_shape(disp_num, start_x, start_y, last_x, last_y);
X return(1);
X }
X
X if (start_x > last_x) /*switch so lesser coordinate is first*/
X {
X temp = start_x;
X start_x = last_x;
X last_x = temp;
X }
X if (start_y > last_y) /*switch so lesser coordinate is first*/
X {
X temp = start_y;
X start_y = last_y;
X last_y = temp;
X }
X if (disp_info[disp_num].dialog_what == SAVE_BITMAP)
X {
X disp_info[disp_num].dialog_text_prompt =
X "File To Save Bitmap To:";
X }
X else if (disp_info[disp_num].dialog_what == SAVE_IMAGE)
X {
X disp_info[disp_num].dialog_text_prompt =
X "File To Save Image To:";
X }
X disp_info[disp_num].dialog_text_return[0] = '\0';
X disp_info[disp_num].dialog_reply_index = 0;
X put_up_dialog(disp_num);
X disp_info[disp_num].scrawl_mode = RESPONDING_TO_DIALOG;
X }
X return(1);
X }
X else if ((the_event->window == disp_info[disp_num].status_win_id) ||
X (the_event->window == disp_info[disp_num].eraser_win_id) ||
X (the_event->window == disp_info[disp_num].dialog_win_id))
X { /*it is in a boring window*/
X return(1); /*no action taken*/
X }
X else /*it is in a menu*/
X {
X menu_num = disp_info[disp_num].current_menu;
X item_selected = disp_info[disp_num].menu[menu_num].item_selected;
X tot_num_items = disp_info[disp_num].menu[menu_num].num_items;
X
X if (disp_info[disp_num].scrawl_mode != TYPING)
X (*num_people_drawing)--; /*a dude has stopped input for now*/
X
X if ((item_selected > 0) && (item_selected < tot_num_items))
X {
X menu_selection(disp_num, menu_num, num_people_drawing,
X item_selected);
X }
X
X disp_info[disp_num].pointer_state = NOT_PRESSED;
X if (disp_info[disp_num].in_session_bool)
X draw_menu(disp_num); /*draw the menus with this new info*/
X }
X }
X}
X
X
X/*
X * get_dimensions_of_text_file - this function finds and returns the
X * dimensions (in in screen pixels) of the text file that
X * is passed in as an argument.
X */
Xget_dimensions_of_text_file(disp_num, text_file_ptr, width, height)
Xint disp_num;
XFILE *text_file_ptr;
Xint *width, *height;
X{
X int c, length, current_width, current_height, max_width_found;
X char current_line[512];
X
X disp_info[disp_num].char_height =
X (disp_info[disp_num].the_font_struct)->max_bounds.ascent +
X (disp_info[disp_num].the_font_struct)->max_bounds.descent;
X
X for (max_width_found=0, current_height=0; (c=getc(text_file_ptr)) != EOF;)
X {
X ungetc(c, text_file_ptr);
X fgets(current_line, 510, text_file_ptr); /*get the line*/
X for (length=0; current_line[length] != '\n'; length++)
X ;
X
X current_height += disp_info[disp_num].char_height;
X
X if ((current_width = XTextWidth(disp_info[disp_num].the_font_struct,
X current_line, length)) > max_width_found)
X {
X max_width_found = current_width;
X }
X }
X
X *width = max_width_found;
X *height = current_height;
X}
X
X
X/*
X * draw_dialog_win_message - this function draws the contents of the
X * dialog box in case of expose event, etc.
X */
Xdraw_dialog_win_message(disp_num)
X{
X int i;
X char the_char[10];
X
X XDrawString(disp_info[disp_num].disp, disp_info[disp_num].dialog_win_id,
X disp_info[disp_num].fg_menu_gc, 8, 14,
X disp_info[disp_num].dialog_text_prompt,
X strlen(disp_info[disp_num].dialog_text_prompt));
X XDrawRectangle(disp_info[disp_num].disp,disp_info[disp_num].dialog_win_id,
X disp_info[disp_num].fg_menu_gc, 8, 20, DIALOG_WIN_WIDTH - 15,
X DIALOG_WIN_HEIGHT - 24);
X
X for (i=0; i<disp_info[disp_num].dialog_reply_index; i++)
X {
X the_char[0] = disp_info[disp_num].dialog_text_return[i];
X
X XDrawString(disp_info[disp_num].disp,
X disp_info[disp_num].dialog_win_id,
X disp_info[disp_num].fg_menu_gc,
X 14 + i*FIXED_CHAR_WIDTH, DIALOG_WIN_HEIGHT - 12,
X the_char, 1);
X }
X XFlush(disp_info[disp_num].disp);
X}
X
X
X/*
X * put_up_dialog - this function displays the dialog box with the text
X * passed in. The text is usually something like:
X * "Enter the file name:".
X */
Xput_up_dialog(disp_num)
Xint disp_num;
X{
X XMapWindow(disp_info[disp_num].disp, disp_info[disp_num].dialog_win_id);
X XFlush(disp_info[disp_num].disp);
X
X draw_dialog_win_message(disp_num);
X}
X
X
X/*
X * do_dialog_action - this is called when a dialog is finally unmapped. This
X * then takes the appropriate action.
X */
Xdo_dialog_action(disp_num)
Xint disp_num;
X{
X int width, height, depth, xhr, yhr;
X Pixmap the_pixmap;
X int temp, start_x, start_y, last_x, last_y;
X FILE *fp;
X XImage *the_image;
X
X switch(disp_info[disp_num].dialog_what)
X {
X case SAVE_BITMAP:
X if (disp_info[disp_num].dialog_reply_index == 0)
X printf("Bitmap Save was canceled.\n");
X else
X {
X start_x = disp_info[disp_num].select_start_pos.x;
X start_y = disp_info[disp_num].select_start_pos.y;
X last_x = disp_info[disp_num].cur_pos.x;
X last_y = disp_info[disp_num].cur_pos.y;
X if (start_x > last_x) /*switch so lesser coordinate is first*/
X {
X temp = start_x;
X start_x = last_x;
X last_x = temp;
X }
X if (start_y > last_y) /*switch so lesser coordinate is first*/
X {
X temp = start_y;
X start_y = last_y;
X last_y = temp;
X }
X
X set_paused_cursors(); /*this may take a while*/
X save_bitmap_on_disk(disp_num, start_x, start_y,
X last_x - start_x, last_y - start_y,
X disp_info[disp_num].dialog_text_return);
X unset_paused_cursors(); /*done*/
X }
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X break;
X case READ_IN_BITMAP:
X if (disp_info[disp_num].dialog_reply_index == 0)
X {
X printf("Bitmap Read In was canceled.\n");
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X return(0);
X }
X else if (XReadBitmapFile(disp_info[disp_num].disp,
X disp_info[disp_num].win_id,
X disp_info[disp_num].dialog_text_return,
X &width, &height, &the_pixmap, &xhr, &yhr)==BitmapSuccess)
X {
X disp_info[disp_num].rubber_band_width = width;
X disp_info[disp_num].rubber_band_height = height;
X disp_info[disp_num].first_point_bool = TRUE;
X disp_info[disp_num].scrawl_mode = PLACING_A_BITMAP;
X }
X else
X {
X printf("ERROR: Not a valid bitmap file.\n");
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X }
X break;
X case ADD_A_DISPLAY:
X if (disp_info[disp_num].dialog_reply_index == 0)
X {
X printf("Add Display was canceled.\n");
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X return(0);
X }
X else
X {
X add_a_new_display(disp_info[disp_num].dialog_text_return);
X /*go back to whatever you were doing before*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X }
X break;
X case READ_TEXTFILE:
X if (disp_info[disp_num].dialog_reply_index == 0)
X {
X printf("Read In Textfile was canceled.\n");
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X return(0);
X }
X else if ((fp = fopen(disp_info[disp_num].dialog_text_return,"r"))
X != NULL)
X {
X set_paused_cursors(); /*this may take a while*/
X get_dimensions_of_text_file(disp_num, fp, &width, &height);
X fclose(fp);
X unset_paused_cursors(); /*done*/
X disp_info[disp_num].rubber_band_width = width;
X disp_info[disp_num].rubber_band_height = height;
X disp_info[disp_num].first_point_bool = TRUE;
X disp_info[disp_num].scrawl_mode = PLACING_A_TEXTFILE;
X XDefineCursor(disp_info[disp_num].disp,
X disp_info[disp_num].win_id,
X XCreateFontCursor(disp_info[disp_num].disp,
X XC_xterm));
X }
X else
X {
X printf("ERROR: Not a valid text file.\n");
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X }
X break;
X case SAVE_IMAGE:
X if (disp_info[disp_num].dialog_reply_index == 0)
X printf("Image Save was canceled.\n");
X else
X {
X start_x = disp_info[disp_num].select_start_pos.x;
X start_y = disp_info[disp_num].select_start_pos.y;
X last_x = disp_info[disp_num].cur_pos.x;
X last_y = disp_info[disp_num].cur_pos.y;
X if (start_x > last_x) /*switch so lesser coordinate is first*/
X {
X temp = start_x;
X start_x = last_x;
X last_x = temp;
X }
X if (start_y > last_y) /*switch so lesser coordinate is first*/
X {
X temp = start_y;
X start_y = last_y;
X last_y = temp;
X }
X set_paused_cursors(); /*this may take a while*/
X save_image_on_disk(disp_info[disp_num].disp,
X disp_info[disp_num].win_id, start_x, start_y,
X last_x - start_x, last_y - start_y,
X disp_info[disp_num].dialog_text_return);
X unset_paused_cursors(); /*done*/
X }
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X break;
X case READ_IN_IMAGE:
X if (disp_info[disp_num].dialog_reply_index == 0)
X {
X printf("Image Read In was canceled.\n");
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X return(0);
X }
X else
X {
X set_paused_cursors(); /*this may take a while*/
X if ((fp = fopen(disp_info[disp_num].dialog_text_return,"r"))
X != NULL)
X {
X fclose(fp);
X depth = -1; /*to see if it actually worked at all*/
X the_image = read_image_from_disk(disp_info[disp_num].disp,
X disp_info[disp_num].win_id,
X disp_info[disp_num].dialog_text_return, &width,
X &height, &depth);
X
X unset_paused_cursors(); /*done*/
X if ((depth == -1) || (the_image == NULL)) /*it failed*/
X {
X printf("ERROR: Something went wrong with the ");
X printf("Read Image.\n");
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X return(0);
X }
X else
X {
X XDestroyImage(the_image);
X disp_info[disp_num].rubber_band_width = width;
X disp_info[disp_num].rubber_band_height = height;
X disp_info[disp_num].first_point_bool = TRUE;
X disp_info[disp_num].scrawl_mode = PLACING_AN_IMAGE;
X }
X }
X else
X {
X printf("ERROR: Not a valid file.\n");
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X unset_paused_cursors(); /*done*/
X return(0);
X }
X }
X break;
X default:
X printf("ERROR: unknown action in do_dialog_action().\n");
X break;
X }
X}
X
X
X/*
X * draw_shape - this function draws the current shape on all displays with
X * dimensions indicated
X */
Xdraw_shape(disp_num, start_x, start_y, last_x, last_y)
Xint disp_num, start_x, start_y, last_x, last_y;
X{
X int i, temp, width, height;
X
X if (disp_info[disp_num].current_shape != STRAIGHT_LINE)
X {
X if (start_x > last_x) /*switch so lesser coordinate is first*/
X {
X temp = start_x;
X start_x = last_x;
X last_x = temp;
X }
X if (start_y > last_y) /*switch so lesser coordinate is first*/
X {
X temp = start_y;
X start_y = last_y;
X last_y = temp;
X }
X }
X
X width = last_x - start_x;
X height = last_y - start_y;
X
X switch(disp_info[disp_num].current_shape)
X {
X case STRAIGHT_LINE:
X for (i=0; i < num_of_disps; i++)
X if (disp_info[i].in_session_bool)
X XDrawLine(disp_info[i].disp, disp_info[i].win_id,
X disp_info[disp_num].win_gc[i], start_x, start_y,
X last_x, last_y);
X break;
X case OUTLINE_RECT:
X for (i=0; i < num_of_disps; i++)
X if (disp_info[i].in_session_bool)
X XDrawRectangle(disp_info[i].disp, disp_info[i].win_id,
X disp_info[disp_num].win_gc[i], start_x, start_y,
X width, height);
X break;
X case FILLED_RECT:
X for (i=0; i < num_of_disps; i++)
X if (disp_info[i].in_session_bool)
X XFillRectangle(disp_info[i].disp, disp_info[i].win_id,
X disp_info[disp_num].win_gc[i], start_x, start_y,
X width, height);
X break;
X case OUTLINE_OVAL:
X for (i=0; i < num_of_disps; i++)
X if (disp_info[i].in_session_bool)
X XDrawArc(disp_info[i].disp, disp_info[i].win_id,
X disp_info[disp_num].win_gc[i], start_x, start_y,
X width, height, 0, 23040);
X break;
X case FILLED_OVAL:
X for (i=0; i < num_of_disps; i++)
X if (disp_info[i].in_session_bool)
X XFillArc(disp_info[i].disp, disp_info[i].win_id,
X disp_info[disp_num].win_gc[i], start_x, start_y,
X width, height, 0, 23040);
X break;
X default:
X printf("ERROR: in draw_shape routine.\n");
X break;
X }
X}
X
X
X/*
X * read_in_and_place_bitmap - this function reads the bitmap named in the
X * second parameter and puts it at the indicated spot on
X * all the displays. It does this in a hokey way, reading
X * it from the file for every display. It is a bit slow,
X * but is short and easy for me.
X */
Xread_in_and_place_bitmap(disp_num, bitmap_filename, x, y)
Xint disp_num;
Xchar *bitmap_filename;
Xint x, y;
X{
X int width, height, xhr, yhr, i;
X
X Pixmap the_pixmap;
X
X set_paused_cursors(); /*this may take a while*/
X
X for (i=0; i<num_of_disps; i++)
X {
X if (disp_info[i].in_session_bool)
X {
X if (XReadBitmapFile(disp_info[i].disp, disp_info[i].win_id,
X bitmap_filename, &width, &height, &the_pixmap, &xhr, &yhr) ==
X BitmapSuccess)
X { /*we got it! run with it!*/
X XCopyPlane(disp_info[i].disp, the_pixmap, disp_info[i].win_id,
X disp_info[disp_num].win_gc[i], 0, 0, width, height, x, y, 1);
X XFlush(disp_info[i].disp);
X }
X else
X {
X printf("ERROR: Not a valid bitmap file.\n");
X break;
X }
X }
X }
X
X unset_paused_cursors(); /*this may take a while*/
X /*simulate choosing the "scrawl" menu selection*/
X menu_selection(disp_num, 0, &num_people_drawing,
X disp_info[disp_num].previous_scrawl_mode);
X}
X
X
X/*
X * save_bitmap_on_disk - this routine saves the region selected as a bitmap
X * on the disk. The background is saved as a 0, and any
X * and all foreground colors (anything different from the
X * background) is stored as a 1.
X */
Xsave_bitmap_on_disk(disp_num, x, y, width, height, bitmap_name)
Xint disp_num, x, y, width, height;
Xchar *bitmap_name;
X{
X XImage *the_image;
X int x_cord, y_cord, cur_left_byte, cur_right_byte;
X int num_on_this_line, done, i;
X FILE *bitmap_file;
X
X /*
X * the width must be an even multiple of 8 for a standard bitmap file
X */
X width = ((width/8) + 1) * 8;
X
X if ((the_image = XGetImage(disp_info[disp_num].disp,
X disp_info[disp_num].win_id, x, y, width, height,
X (~0), ZPixmap)) == NULL)
X {
X printf("ERROR: XGetImage failed.\n");
X return(0);
X }
X else if ((bitmap_file = fopen(bitmap_name, "w")) == NULL)
X {
X /*fopen failed*/
X XDestroyImage(the_image);
X printf("ERROR: attempt to save bitmap to a file failed.\n");
X return(0);
X }
X
X fprintf(bitmap_file, "#define %s_width %d\n", bitmap_name, width);
X fprintf(bitmap_file, "#define %s_height %d\n", bitmap_name, height);
X fprintf(bitmap_file, "static char %s_bits[] = {\n", bitmap_name);
X fprintf(bitmap_file, " ");
X
X /*
X * the following blows the data out to the file on disk
X */
X num_on_this_line = 0;
X for (y_cord=0, done=FALSE; done==FALSE; y_cord++)
X {
X for (x_cord=0; x_cord < width; x_cord+=8)
X {
X cur_right_byte = 0;
X cur_left_byte = 0;
X
X for (i=0; i<4; i++)
X {
X if (XGetPixel(the_image, x_cord+i, y_cord) !=
X disp_info[disp_num].background)
X {
X cur_right_byte |= 1<<i;
X }
X }
X for (i=0; i<4; i++)
X {
X if (XGetPixel(the_image, x_cord+i+4, y_cord) !=
X disp_info[disp_num].background)
X {
X cur_left_byte |= 1<<i;
X }
X }
X fprintf(bitmap_file, "0x%x%x", cur_left_byte, cur_right_byte);
X num_on_this_line++;
X
X if ((y_cord == height-1) && (x_cord == (width-8)))
X {
X fprintf(bitmap_file, "};\n");
X done = TRUE;
X break;
X }
X else if (num_on_this_line == 12)
X {
X fprintf(bitmap_file, ",\n");
X fprintf(bitmap_file, " ");
X num_on_this_line = 0;
X }
X else
X fprintf(bitmap_file, ", ");
X }
X }
X fclose(bitmap_file);
X XDestroyImage(the_image);
X}
X
X
X/*
X * handle_SelectionNotify_event - this function handles a SelectionNotify event
X * in this particular scrawler's window. It is probably a
X * "paste" of characters from the window manager.
X */
Xhandle_SelectionNotify_event(the_event, disp_num)
XXEvent *the_event;
Xint disp_num;
X{
X XSelectionEvent *temp_event;
X int i, alive;
X
X temp_event = (XSelectionEvent *) the_event;
X printf("Hey! We just got a Selection Notify event!\n");
X}
X
X
X/*
X * handle_ClientMessage_event - this function handles a ClientMessage event in
X * this particular scrawler's window. It is probably a
X * a "WM_DESTROY" from the window manager.
X */
Xhandle_ClientMessage_event(the_event, disp_num)
XXEvent *the_event;
Xint disp_num;
X{
X XClientMessageEvent *temp_event;
X int i, alive;
X
X temp_event = (XClientMessageEvent *) the_event;
X if (temp_event->data.l[0] == disp_info[disp_num].xa_WM_DELETE_WINDOW)
X {
X XDestroyWindow(disp_info[disp_num].disp, disp_info[disp_num].win_id);
X disp_info[disp_num].in_session_bool = FALSE; /*no window*/
X XCloseDisplay(disp_info[disp_num].disp);
X
X for (i=alive=0; i< num_of_disps; i++)
X {
X if (disp_info[i].in_session_bool)
X {
X alive = TRUE;
X break;
X }
X }
X if (alive)
X {
X for (i=0; i<num_of_disps; i++)
X place_and_draw_status_win(i);
X }
X else
X exit(0);/*if no one is still in session, stop running*/
X }
X else
X printf("ERROR: in handle_ClientMessage_event.\n");
X}
X
X
X/*
X * load_moron_fonts - this function loads fonts for real morons and owners
X * of Sun workstations. The thing is, both morons and
X * owners of Sun workstations have systems that are so screwed
X * up, they can't find R4 fonts when you try to allocate them
X * using the font name. Therefore, this is a really, really ugly
X * hack to allow their systems to find ONLY MY default fonts
X * using xlfd strings. This will work with NO OTHER fonts.
X * This function returns TRUE if it allocated a font, and FALSE
X * if not. Hopefully this function will keep 90% of the Sun
X * users happy, and thinking they got their moneys worth when
X * buying Sun, when actually they made a drastic mistake.
X */
Xload_moron_fonts(disp_num, i, font_file_name)
Xint disp_num, i;
Xchar *font_file_name;
X{
X char xlfd_string[512];
X XFontStruct *the_font_struct;
X
X if (strcmp(font_file_name, "fixed") == 0)
X strcpy(xlfd_string, "fixed");
X else if (strcmp(font_file_name, "variable") == 0)
X strcpy(xlfd_string, "-*-helvetica-bold-r-normal-*-*-120-*-*-*-*-*-*");
X else if (strcmp(font_file_name, "timR12") == 0)
X strcpy(xlfd_string,
X "-adobe-times-medium-r-normal--12-120-75-75-p-64-iso8859-1");
X else if (strcmp(font_file_name, "helvO12") == 0)
X strcpy(xlfd_string,
X "-adobe-helvetica-medium-o-normal--12-120-75-75-p-67-iso8859-1");
X else if (strcmp(font_file_name, "courR12") == 0)
X strcpy(xlfd_string,
END_OF_FILE
if test 33168 -ne `wc -c <'wscrawl/xab'`; then
echo shar: \"'wscrawl/xab'\" unpacked with wrong size!
fi
# end of 'wscrawl/xab'
fi
echo shar: End of archive 5 \(of 5\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 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
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list