Mercurial > hg > aim92
view xaim/xreview.c @ 0:5242703e91d3 tip
Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author | tomwalters |
---|---|
date | Fri, 20 May 2011 15:19:45 +0100 |
parents | |
children |
line wrap: on
line source
/* Copyright (c) Applied Psychology Unit, Medical Research Council. 1993 =========================================================================== Permission to use, copy, modify, and distribute this software without fee is hereby granted for research purposes, provided that this copyright notice appears in all copies and in all supporting documentation, and that the software is not redistributed for any fee (except for a nominal shipping charge). Anyone wanting to incorporate all or part of this software in a commercial product must obtain a license from the Medical Research Council. The MRC makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL THE A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * xreview * ---------- * * A program for animating an AIM 'cartoon bitmap'. * Requires X windows, but most varieties, r4, r5, Sun OpenWindows * (but see also the makefile) * * The underlying algorithm is: * 1. load the entire cartoon into memory, as one contiguos block. * 2. compute, and save, the memory locations of each frame's start. * 3. Set the memory pointer of an XImage structure to the first one, and draw * 4. Reset the pointer to the next frame, and redraw ... * 5. Continue for however many frames there are. * * * * A large proportion of this was inspired by the "basic window" * program of the O'Reilly X manuals, vol 1. More inspiritaion came from * John Holdsworth's code. * * * M.Akeroyd July 1993. version 1.00 * * revisions: MAA: Christmas 1993. rewrites for public release, also some * bug fixes. * Includes the linux hacks. */ #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/Xos.h> #include <X11/Xatom.h> #include <X11/Xmu/Xmu.h> #include <X11/keysym.h> #include <X11/cursorfont.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> #include "xreview.h" #include "./stipple_a" /* for the Control Window background */ /* Function declarations */ /*-------------------------------------------------------------------------*/ void parsecommandline (int argc, char *argv[], char inputfn[], char titlestring[], char fontname[]); int readheader(FILE *inputfp, char filefn[]); FILE *open_file (char filefn[], FILE *dir_default, int streamtype); void close_files (FILE *fp); void initialise_control_window(char *inputfn, char *titlestring, FILE *inputfp, char *argv[], int argc); void initialise_axes_window(char *inputfn, char *titlestring, FILE *inputfp, char *argv[], int argc); void initialise_buttons(); void initialise_image(); void drawimage(int frame); void drawtext(Window win, GC gc, XFontStruct *font_info, unsigned int width, \ unsigned int height, char *text); void drawbutton(Window control_win, Window button_local, GC *button_local_gc,\ int width, int height, char *text, int fill_ground, \ int text_ground); void flashbutton(Window top_win, Window button_local, GC *button_local_gc, \ int width, int height, char *text); void initialise_X_screen(); void load_font(); /* Data arrays: global */ /*-------------------------------------------------------------------------*/ char *data_pointer; char *data_pointer_sideways; long location[MAX_FRAMES]; /* frames: a reasonably big number */ int frame = 1; /* start frame */ FILE *inputfp; char inputfn[MAX_STRING_LENGTH]; /* .ctn header */ /*-------------------------------------------------------------------------*/ char header[MAX_LINES_HEADER][MAX_LINE_LENGTH]; int header_lines; int no_frames; int frameheight; /* number of channels */ int framewidth_samples; /* pwidth + nwidth * samplerate */ int frameshift_samples; /* frstep_aid * samplerate */ double frstep_aid; /* msecs */ double pwidth; /* msecs */ double nwidth; /* msecs: NEGATIVE */ int width_ctn; /* pixels */ int height_ctn; /* pixels */ int x_ctn; /* pixels */ int y_ctn; /* pixels */ long samplerate; /* samples per sec */ int mincf; /* Hz */ int maxcf; /* Hz */ /* misc */ /*-------------------------------------------------------------------------*/ char progname[MAX_STRING_LENGTH]; char fontname[MAX_STRING_LENGTH]; char display_name[MAX_STRING_LENGTH]; int verboseflag = OFF; /* -v option */ int axes_xflag = OFF; /* -image_x option */ int axes_yflag = OFF; /* -image_y option */ int controls_xflag = OFF; /* -controls_x option */ int controls_yflag = OFF; /* -controls_y option */ int titleflag = OFF; /* -title option */ int bytesflag = OFF; /* -lsb, -msb options */ int bitmap_pad_flag = OFF; /* ditto */ int new_axes_x, new_axes_y; int new_control_x, new_control_y; int controlwindowflag = OFF; /* -controls option */ double scale = 1.0; long waittime_millisecs = 1; /* time to wait imbetween frames */ long waittime_microsecs ; int animate_start = 1; /* animation start frame */ int animate_stop = 9999; /* animation end frame: gets set to EOF */ int animate_skip = 1; /* animation skip */ int sidewaysflag = OFF; /* X variables */ /*-------------------------------------------------------------------------*/ /* There are 3 classes of window: * "axes window": where the cartoon itself is. Called "axes" for historical * reasons. Button presses cause (1) animations, or (2) mapping * of the Controls Window, or (3) exit. This window CANNOT * be resized. * Used, reasonably interchangealby, with 'image' * "controls window": where the Animation Control buttons are. Button presses * --- if not on a 'button' --- do nothing. This window * can't be resized either. * "buttons": there are lots of them. eg button_startf. These are subwindows * of the Controls Window. Pressing the left mouse button causes * something exciting to happen. * There are also 'information buttons', which say things * like the filename, number of frames, etc. Pressing one of these * doesn't do anything. */ Display *display; int screen_num; Screen *screen_ptr; int depth = 1; unsigned int display_width_X, display_height_X; unsigned int display_width, display_height; Pixmap stipple_pixmap; /* Windows */ toplevelWindow axes; toplevelWindow control; buttonWindow button_quit, button_close; buttonWindow button_animate; buttonWindow button_startf, button_startb, button_stopf, button_stopb; buttonWindow button_skipf, button_skipb, button_faster, button_slower; buttonWindow button_firstframe, button_lastframe, button_middle; buttonWindow button_stepb, button_stepbb; buttonWindow button_stepf, button_stepff; buttonWindow info_speed, info_start, info_stop, info_skip; buttonWindow info_title, info_frame; buttonWindow info_time, info_freq, info_frstep; XFontStruct *font_info; int pointsize = DEFAULT_POINTSIZE; GC button_gc; int button_borderwidth = 0; XImage *reviewimage; int reviewimage_bytesperline = BYTES_PER_LINE; int reviewimage_bitmap_pad = BITMAP_PAD; Cursor cursor; XEvent report; int depthflag = MONO; /* assume a monochrome screen */ int planemask = 0x1; /* works with my colour sparc */ int xsyncflag = OFF; int reversevideoflag = OFF; /* gets set to ON if DECstation */ int byteorderflag = SERVER; /* ie, the physical screen */ /* ...................... Main ..............................*/ /* .........................................................................*/ /* .........................................................................*/ void main (int argc, char *argv[]) { int n; int header_bytes = 0; int alreadydrawnflag = OFF; char titlestring[MAX_STRING_LENGTH]; char tempstring[MAX_STRING_LENGTH]; int required_bytes; long status; long starttime, localtime; long x; /*-----------------------------*/ strcpy(progname, argv[0]); strcpy(fontname, ""); strcpy(inputfn, ""); strcpy(titlestring, ""); /* Machine specific defaults */ #ifdef HOST_SPARC byteorderflag = SUN; reversevideoflag = OFF; #endif #ifdef HOST_DECSTATION byteorderflag = DEC; reversevideoflag = ON; #endif #ifdef HOST_LINUXPC byteorderflag = DEC; reversevideoflag = ON; #endif parsecommandline(argc, argv, inputfn, titlestring, fontname); /*-----------------------------*/ /* Open Display: this also finds the screen size */ initialise_X_screen(); /*-----------------------------*/ if (xsyncflag == ON) { XSynchronize(display, True); fprintf(stderr, "XSynchronize on \n");} inputfp = open_file(inputfn, stdin, READ); header_bytes = readheader(inputfp, inputfn); /*-----------------------------*/ /* define bytes_per_line of the XImage. This seems to be, at least on a * Colour SS-10, to be * (width-1) * ( --------- +1 ) *4 * 32 * where the INTEGER part of the division is all that is needed. * * Examples: * width=100 to 128 bytes=16 (100 is the smallest AIM window allowed.- * 129 -- 160 20 * 161 -- 192 24 * 193 -- 224 28 */ reviewimage_bytesperline = (int) ((int) ((width_ctn -1) / 32) +1) *4; /*-----------------------------*/ /* Allocate lots of space: * no of frames by .ctn size */ if (depthflag == MONO) depth = 1; else depth = DefaultDepth(display, screen_num); required_bytes = no_frames*height_ctn*reviewimage_bytesperline*depth; if (verboseflag == ON) { fprintf(stderr, "xreview : reserving %i * %i * %i = %i bytes.\n", no_frames, (height_ctn*reviewimage_bytesperline), depth, required_bytes); } data_pointer = (char *) malloc((size_t) required_bytes); if (data_pointer == NULL) { fprintf(stderr, "xreview : unable to allocate %i bytes for XImage.\n", required_bytes); fclose(inputfp); exit(-1);} /* sideways scroll */ if (sidewaysflag == ON) { required_bytes = no_frames*height_ctn*reviewimage_bytesperline*depth; if (verboseflag == ON) { fprintf(stderr, "xreview : reserving %i * %i = %i bytes.\n", (no_frames*height_ctn*reviewimage_bytesperline), depth, required_bytes); } data_pointer_sideways = (char *) malloc((size_t) required_bytes); if (data_pointer_sideways == NULL) { fprintf(stderr, "xreview : unable to allocate %i bytes for XImage.\n", required_bytes); fclose(inputfp); exit(-1);}} /*-----------------------------*/ /* load .ctn data */ loaddata(inputfp); close_files(inputfp); if (animate_stop == 9999) animate_stop = no_frames; if (sidewaysflag == ON) { for (x=location[0]; x<=location[0]+required_bytes-1; x++) data_pointer_sideways[x] = data_pointer[x];} /*-----------------------------*/ /* Find a font, in this order: * 1. command-line * 2. Times family * 3. Lucida family. * If can't find any, should crash. */ font_info = NULL; if ((strcmp(fontname, "") == 0 ) || ((font_info = XLoadQueryFont(display, fontname)) == NULL)) { sprintf(fontname, "-adobe-times-medium-r-normal--%i-*-*-*-*-*-*-*", pointsize); if ((font_info = XLoadQueryFont(display, fontname)) == NULL) { sprintf(fontname, "-b&h-lucida-medium-r-normal-sans-%i-*-*-*-*-*-*-*", pointsize); if ((font_info = XLoadQueryFont(display, fontname)) == NULL) { fprintf(stderr, "xreview : unable to find fonts.\n"); exit(-1); }}} /*-----------------------------*/ /* define a cursor */ cursor = XCreateFontCursor(display, XC_top_left_arrow); /*-----------------------------*/ initialise_axes_window(inputfn, titlestring, inputfp, argv, argc); XMapWindow(display, axes.win); /* define the background pixmap */ stipple_pixmap = XCreatePixmapFromBitmapData(display, \ RootWindow(display, screen_num), stipple_a_bits, \ stipple_a_width, stipple_a_height, \ BlackPixel(display, screen_num), \ WhitePixel(display, screen_num), \ DefaultDepth(display, screen_num)); initialise_control_window(inputfn, titlestring, inputfp, argv, argc); if (controlwindowflag == ON) XMapWindow(display, control.win); initialise_buttons(); initialise_image(); /*------------------------------*/ /*----------------------------- * EVENT LOOP *----------------------------- */ while (1) { XNextEvent(display, &report); if (report.xany.window == axes.win) switch_axes(); else if (report.xany.window == control.win) switch_control(); else switch_buttons(); } /* while */ /*---------------------------------------------------------*/ } /* main */ /*......................................................................*/ /*......................................................................*/ void parsecommandline(int argc, char *argv[], char inputfn[], char titlestring[], char fontname[]) { int x=1, helpflag = OFF; int control_width =0; char control_size[MAX_STRING_LENGTH]; strcpy(control_size, ""); while (x < argc){ if (!strcmp(argv[x], "-input")) {strcpy(inputfn, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-inp")) {strcpy(inputfn, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-i")) {strcpy(inputfn, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-help")) {helpflag = ON; x+=1;} else if (!strcmp(argv[x], "-h")) {helpflag = ON; x+=1;} else if (!strcmp(argv[x], "-verbose")) {verboseflag = ON; x+=1;} else if (!strcmp(argv[x], "-ver")) {verboseflag = ON; x+=1;} else if (!strcmp(argv[x], "-v")) {verboseflag = ON; x+=1;} else if (!strcmp(argv[x], "-side")) {sidewaysflag = ON; x+=1;} else if (!strcmp(argv[x], "-sideways")) {sidewaysflag = ON; x+=1;} else if (!strcmp(argv[x], "-controls")) {controlwindowflag = ON; x+=1;} else if (!strcmp(argv[x], "-con")) {controlwindowflag = ON; x+=1;} else if (!strcmp(argv[x], "-c")) {controlwindowflag = ON; x+=1;} else if (!strcmp(argv[x], "-controls_x")) {controls_xflag = ON; new_control_x = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-cx")) {controls_xflag = ON; new_control_x = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-controls_y")) {controls_yflag = ON; new_control_y = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-cy")) {controls_yflag = ON; new_control_y = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-image_x")) {axes_xflag = ON; new_axes_x = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-ix")) {axes_xflag = ON; new_axes_x = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-image_y")) {axes_yflag = ON; new_axes_y = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-iy")) {axes_yflag = ON; new_axes_y = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-controls_scale")) {scale = atof(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-cscale")) {scale = atof(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-controls_width")) {control_width = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-cw")) {control_width = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-controls_size")) {strcpy(control_size, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-csize")) {strcpy(control_size, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-display")) {strcpy(display_name, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-d")) {strcpy(display_name, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-font")) {strcpy(fontname, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-fn")) {strcpy(fontname, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-point")) {pointsize = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-p")) {pointsize = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-wait")) {waittime_millisecs = atol(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-w")) {waittime_millisecs = atol(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-speed")) {waittime_millisecs = atol(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-start")) {animate_start = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-stop")) {animate_stop = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-skip")) {animate_skip = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-frame")) {frame = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-fra")) {frame = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-title")) {titleflag = ON; strcpy(titlestring, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-tit")) {titleflag = ON; strcpy(titlestring, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-t")) {titleflag = ON; strcpy(titlestring, argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-mono")) {depthflag = MONO; x+=1;} else if (!strcmp(argv[x], "-colour")) {depthflag = COLOUR; planemask = AllPlanes; x+=1; } else if (!strcmp(argv[x], "-planemask")) {planemask = atoi(argv[x+1]); x+=2;} else if (!strcmp(argv[x], "-xsync")) {xsyncflag = ON; x+=1;} else if (!strcmp(argv[x], "-rv")) {if (reversevideoflag == ON) reversevideoflag = OFF; else reversevideoflag = ON; x+=1;} else if (!strcmp(argv[x], "-lsb")) {byteorderflag = DEC; x+=1;} else if (!strcmp(argv[x], "-msb")) {byteorderflag = SUN; x+=1;} else if (!strcmp(argv[x], "-dec")) {byteorderflag = DEC; reversevideoflag = ON; x+=1;} else if (!strcmp(argv[x], "-sun")) {byteorderflag = SUN; reversevideoflag = OFF; x+=1;} else if (x = (argc-1)) {strcpy(inputfn, argv[x]); x+=1;} else {fprintf(stderr, "xreview: unknown option %s\n", argv[x]); exit(-1);} } if (helpflag == ON) { fprintf(stderr, "\n"); fprintf(stderr, "--------------------------------------------------------------------------------\n"); fprintf(stderr, " xreview\n"); fprintf(stderr, "--------------------------------------------------------------------------------\n\n"); fprintf(stderr, " usage: xreview -input 'filename.ctn' <options> \n"); fprintf(stderr, " or xreview <options> 'filename.ctn' \n"); fprintf(stderr, " or cat 'filename.ctn' | xreview <options> \n\n\n"); fprintf(stderr, " Command line options Abbrev.\n"); fprintf(stderr, "--------------------------------------------------------------------------------\n"); fprintf(stderr, "-input <.ctn file> Input file (default = stdin). -i\n"); fprintf(stderr, "\n"); fprintf(stderr, "-controls Map Controls window. -con\n"); fprintf(stderr, "-controls_x <int> Controls window position (pixels). -cx\n"); fprintf(stderr, "-controls_y <int> Controls window position (pixels). -cy\n"); fprintf(stderr, "-controls_width <int> Controls window width (pixels). -cw\n"); fprintf(stderr, "-controls_scale <flt> Scale factor for size of Controls Window. -cscale\n"); fprintf(stderr, "-controls_size Controls Window size: 'tiny', 'small' or 'normal'. -csize\n"); fprintf(stderr, "-image_x <int> Image position (pixels). -ix\n"); fprintf(stderr, "-image_y <int> Image position (pixels). -iy\n"); fprintf(stderr, "\n"); fprintf(stderr, "-display <string> X Display server to use. -d\n"); fprintf(stderr, "-font <string> Font. -fn\n"); fprintf(stderr, "-point <int> Point-size of default font (Times, medium weight). -p\n"); fprintf(stderr, "-title <string> Title of Image window & icon. -t\n"); fprintf(stderr, "-mono Assume Monochrome (single-plane) cartoons. (default) \n"); fprintf(stderr, "-colour Assume Colour (multiplane) cartoons. \n"); fprintf(stderr, "-planemask <int> Value of PlaneMask for copying XImage (default=1) \n"); fprintf(stderr, "-rv Reverse-video the cartoon window colours. \n"); fprintf(stderr, "-lsb Assume cartoon's bit & byte orders are LSBFirst (ie, DEC).\n"); fprintf(stderr, "-msb Assume cartoon's bit & byte orders are MSBFirst (ie, Sun).\n"); fprintf(stderr, "-dec Alias for -lsb -rv \n"); fprintf(stderr, "-sun Alias for -msb \n"); fprintf(stderr, "\n"); fprintf(stderr, "-speed <int> Wait-time between frames (msecs) (default = %i). -speed\n", waittime_millisecs); fprintf(stderr, "-start <int> Animation start (frames) (default=1). -start\n"); fprintf(stderr, "-stop <int> Animation stop (frames) (default=last frame). -stop\n"); fprintf(stderr, "-skip <int> Animation skip (frames) (default=1). -skip\n"); fprintf(stderr, "-frame <int> Initial display frame (default=1). -fra\n"); fprintf(stderr, "-sideways Scroll cartoon sideways (right->left) -side\n"); fprintf(stderr, "\n"); fprintf(stderr, "-verbose Print some running information (to stderr). -v\n"); fprintf(stderr, "-help Print this page (to stderr). -h\n"); fprintf(stderr, "\n\n" ); fprintf(stderr, " Image Window Controls \n"); fprintf(stderr, "--------------------------------------------------------------------------------\n"); fprintf(stderr, " Left button Animate cartoon. \n"); fprintf(stderr, " Middle button Map Controls window. \n"); fprintf(stderr, " Right button Quit. \n\n"); fprintf(stderr, " SPACE or RET Animate cartoon. \n"); fprintf(stderr, " F or f Set speed faster by x2. \n"); fprintf(stderr, " S or s Set speed slower by x2. \n"); fprintf(stderr, " N or n Next frame. \n"); fprintf(stderr, " P or p Previous frame. \n"); fprintf(stderr, " Q or q Quit. \n"); fprintf(stderr, "\n\n"); exit(-1);} if (strcmp(control_size, "") != 0){ if (strcmp(control_size, "normal") == 0) { scale=1.00; pointsize=18;} else if (strcmp(control_size, "small") == 0) { scale=0.80; pointsize=14;} else if (strcmp(control_size, "tiny") == 0) { scale=0.60; pointsize=10;} else { fprintf(stderr, "xreview : illegal control_size value.\n"); exit(-1);} } if (control_width != 0) scale = (double) control_width / CONTROL_WIDTH; } /* The end.*/ /*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/