home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-15 | 53.8 KB | 1,684 lines |
- Path: uunet!samsung!munnari.oz.au!metro!sunaus.oz!newstop!sun!hpcvlx.cv.hp.com
- From: brianw@hpcvlx.cv.hp.com (Brian Wilson)
- Newsgroups: comp.sources.x
- Subject: v08i057: wscrawl, Part05/05
- Message-ID: <138942@sun.Eng.Sun.COM>
- Date: 15 Jul 90 18:57:36 GMT
- Sender: news@sun.Eng.Sun.COM
- Lines: 1673
- Approved: argv@sun.com
-
- Submitted-by: Brian Wilson <brianw@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@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@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@sun.com / argv@ora.com
- Opinions expressed reflect those of the author only.
-