$! ................... Cut between dotted lines and save. ................... $!........................................................................... $! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989. $! $! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from $! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au). $! $! To unpack, simply save, concatinate all parts into one file and $! execute (@) that file. $! $! This archive was created by user JONESD $! on 15-JAN-1992 13:04:59.78. $! $! It contains the following 22 files: $! README.VMS $! XV-H.DIF $! XV.DIF $! XVDFLT.DIF $! XVDIR.DIF $! XVEVENT.DIF $! XVGAM.DIF $! XVGIF.DIF $! XVIMAGE.DIF $! XVJPEG.DIF $! XVMISC.DIF $! XVPOPUP.DIF $! XVPS.DIF $! XV_FIXUP_VMS.COM $! XV_MAKE.COM $! JPEG_MAKE.COM $! VMS.C $! READDR.C $! DIRENT.H $! PSEUDO_ROOT.C $! GIFDECOMP.MAR $! GIFMAPF.C $! $!============================================================================ $ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL ) $ VERSION = F$GETSYI( "VERSION" ) $ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK $ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", - "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher." $ EXIT 44 ! SS$_ABORT $VERSION_OK: $ GOTO START $! $UNPACK_FILE: $ WRITE SYS$OUTPUT "Creating ''FILE_IS'" $ DEFINE/USER_MODE SYS$OUTPUT NL: $ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION - VMS_SHARE_DUMMY.DUMMY b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) ) ; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE , b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors := 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN & "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION ( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail & LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP ; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK ( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 ) ; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF ; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ) ; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ) ; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF ; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE ; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1 ; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF ; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors := i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT ( "The following line could not be unpacked properly:" ); SPLIT_LINE ; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL ( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH ( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1 ); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP ; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION ( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO ( "The following !UL errors were detected while unpacking !AS", i_errors , s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" ) ; ENDIF; EXIT; $ DELETE VMS_SHARE_DUMMY.DUMMY;* $ CHECKSUM 'FILE_IS $ WRITE SYS$OUTPUT " CHECKSUM ", - F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." ) $ RETURN $! $START: $ FILE_IS = "README.VMS" $ CHECKSUM_IS = 1946517090 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X`009`009`009`009`009`009`009`00915-JAN-1992 X XRelease notes for VMS port of XV 2.0 (xv-2.00.tar, released 2-JAN-1992), Vrevision B. Port was done by David Jones, jonesd@kcgl1.eng.ohio-state.edu`03 X2 Xusing the VMS VAXC compiler. X XCommand procedures: X X XV_FIXUP_VMS.COM X`009This procedure uses applies the source file modifications to the X`009original files on the XV release as extracted from the tar file. X`009It assumes the directory heirarchy on the tar tape is preserved X`009([.bitmaps] and [.jpeg] directories). X`009Note: If you applied the revision A patches and left the X`009 '-orig' files created by its XV_FIXUP_VMS.COM intact, you can X`009 just invoke this procedure and XV_MAKE to build a new image. X X XV_MAKE.COM X`009This procedure compiles the source files and links the XV image, X`009invoke this procedure AFTER applying the patches. X X JPEG_MAKE.COM X`009This procedure is called by XV_MAKE to compile and build the JPEG X`009library. X XModified files: X V XV.H -`009Made several changes to file to select proper #include fil Xes X`009`009and define macros for substitute 'block memory' functions. X`009 Also made macros to redefine popUp and cols to work around X`009`009compiler/linker conflicts (case problems). X X`009`009Replace qsort calls with privately writtne routine to X`009`009avoid bug in VAXC's version. X X XV.C - Initialize virtual root window using pseudo_root() function. X`009`009Add calls to do_vms_wildcard() and getredirection() to redo X`009`009argument vector: expand wildcards and convert to unix X`009`009filename syntax. Improve startup time for case where X`009`009user has no DECW$XDEFAULTS.DAT file (XGetDefault is brain X`009`009dead). X V XVDFLT.C -`009Fix problem with include file specifications (VAXC compile Xr X`009`009assumes ".h" file type when not specified). X X XVDIR.C -`009Replace stat() calls with lstat() calls under VMS. X`009`009Make several changes to deal with idiosyncracies in the X`009`009UNIX filename support built into the run-time library. X X`009`009Changed behavior of failed chdir() requests: leave default X`009`009directory as it was instead of going to "/". X X`009`009Add a hack that supports the top-level root ("/") concept X`009`009with a concealed device directory, DEVICE_LIST_ROOT:[*]. X`009`009Create a concealed device with the name DEVICE_LIST_ROOT and X`009`009create a directory on this device for each device on the X`009`009system (e.g. create/dir device_list_root:[sys$sysdevice]). X`009`009When a user selects "/" from the directory window, he will X`009`009see the directories in device_list_root:[000000] and will X`009`009be able to select a directory in order to change devices. X X XVEVENT.C -`009Modified resize routine to work under DECWindows, which X`009`009allows the control buttons to change the image. X`009`009Fixed keyboard bug caused by improper call to XLookupString. X`009`009(bug also in XVGAM.C, XVJPEG.C, XVPOPUP.C, and XVPS.C). X X`009`009Fiddle with dispWIDE and dispHIGH globals so that maximize X`009`009functions account for title bars and such. X X XVGIF.C -`009Changed decompressor so that under VMS, loadGIF uses X`009`009routines in GIFDECOMP.MAR and GIFMAPF.C. The VMS tuned X`009`009version is 3 times faster at decompressing GIF files than X`009`009the original C version. X X XVIMAGE.C -`009Fixed memory leak, image data area was not being freed. X`009`009I'm not sure if this is a bug in xlib or xv, probably DEC's X`009`009version of xlib. X V XVMISC.C -`009Modified Timer() function so that under VMS it calls LIB$W XAIT. X XNew source files: X X VMS.C -`009Miscellaneous routines to support UNIX functions missing X`009`009from the C run-time library. Also define do_vms_wildcard() X`009`009function used to fixup the argument vector. X V READDR.C -`009Susbstitute routines for UNIX directory scan routines (ope Xndir), X`009`009perform equivalent VMS system calls. X V DIRENT.H -`009Include file to use in conjunction with routines in READDR X.C. X X gifmapf.c -`009VMS optimized GIF file access routines, maps the file X`009`009to virtual memory and treats it as an array. X X PSEUDO_ROOT.C - Finds virtual root window for decwindows window manager. X X gifdecomp.mar - Optimized GIF decompressor routines, written in MACRO. X XInstallation: X X 0.`009You need to have installed the DECWindows programmer kit with the X`009C language file selected. You need a C compiler compatible with the X`009VAXC installed as well, including the .h files in SYS$LIBRARY. X X 1. Make sure that your current default directory is the one containing X`009the XV 2.0 source files and that it contains all the files unpacked X`009by the VMSSHARE patch kit. X X 2.`009Make sure that the copies of the modified files listed above X`009are the same as the ones from the orignal XV 2.0 source file X`009(XV-2.00.tar or XV2.TLB). X X`009`009`009`009OR X X`009Copy the original versions of the modified files listed above X`009to the the current directory with a "-ORIG" appended to the`032 X`009file type (e.g. "xv.h" -> "xv.h-orig"). The revision A patch X`009kit will have made these files if applied. X X 3.`009Invoke the procedure XV_FIXUP_VMS.COM to edit the source files. X`009This procedure will use the "-orig" version of a source file if X`009found or create one if not. The object file for modified modules X`009will be deleted. X X 4.`009Invoke the XV_MAKE.COM procedure to compile and link the XV image. X`009This procedure isn't very bright about deciding whether a source X`009file needs re-compiled, a source file is only re-compiled if X`009an object file by that name doesn't exist. $ GOSUB UNPACK_FILE $ FILE_IS = "XV-H.DIF" $ CHECKSUM_IS = 376469152 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 46, 47 V#if (defined(SVR4) && !defined(sgi) && !defined(__UMAXV__)) `124`124 define Xd(_IBMR2)`032 X- 59, 59 X#if defined(SVR4) `124`124 defined(VMS) X- 82, 84 X#ifndef VMS Xextern int errno; /* this SHOULD be in errno.h */ Xextern char *sys_errlist[]; /* this SHOULD be in errno.h */ X- 89, 95 X#else X#define DIRENT 1 X#define MAXPATHLEN 512 X#define popUp xv_popup X#define qsort xv_qsort X#define bzero(s,size) memset(s,0,size) X#define bcmp(s1,s2,size) xv_bcmp((char *)s1,(char *)s2,size) X#define random rand X#define cols xv_cols Xtypedef unsigned long u_long; X#include /* in VMS they *are* in errno.h */ X#include /* and perror.h */ X#endif X X */ X#ifndef VMS X#if !defined(ibm032) && \ X !defined(__convexc__) && \ X !(defined(vax) && !defined(ultrix)) && \ X !defined(mips) && \ X- 105 X#endif X- 151, 151 X#ifdef VMS X#include X#include X#include "dirent.h" X X#else X- 162, 162 X- 165 X#endif`009`009`009/* NEEDSDIR */ X- 551 XWHERE XComposeStatus xv_compose; `032 X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XV.DIF" $ CHECKSUM_IS = 475467948 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 6 X * Modified for VMS by: X *`009`009David Jones, the Ohio State University X *`009`009 (jonesd@kcgl1.eng.ohio-state.edu) X * X- 64 X#ifdef VMS Xextern Window pseudo_root(); X#endif X X- 150 X#ifdef VMS X /* convert VMS style arguments to unix names and glob */ X do_vms_wildcard(&argc,&argv); X getredirection(&argc,&argv); X#endif X X- 490 X xv_compose.compose_ptr = NULL;`009/* variable is IN_OUT, so be clean */ X xv_compose.chars_matched = 0;`009`009/* and initialize it */ X- 537 X#ifndef VMS X- 556 X#else X vrootW = pseudo_root(theDisp,theScreen); X#endif X- 955 X#ifdef VMS X if ( i>2 && (`032 X`009(strcmp(fullname+i-2,".Z") == 0) `124`124`032 X`009(strstr(fullname,".Z.") != NULL) ) ) `123 X strcpy(filename,"sys$scratch:xvXXXXXX"); X mktemp(filename); X if ( vms_do_uncompress ( fullname, filename ) ) `123 X#else X- 959, 961 X sprintf(str, "%s -c %s >%s", UNCOMPRESS,fullname,filename); X SetISTR(ISTR_INFO,"Uncompressing '%s'...",basename); X if (system(str)) `123 X#endif X- 989, 993 X#ifdef VMS X /* Open with optional arguments to force stream access in order to X get around problems with stream_CR created by pathworks (mac) */`032 X fp=fopen (filename,"r","ctx=stm"); X#else X fp=fopen(filename,"r"); X#endif X if (!fp)`123 X static char *foo[] = `123 "\nBummer!" `125; X char str[512]; X sprintf(str,"Can't open '%s'\n\n %s.", filename, X#ifdef VMS X`009`009strerror(errno,vaxc$errno) ); X#else X`009`009sys_errlist[errno] ); X#endif X- 1896, 1896 X /* for getpwnam() prototype and passwd struct */ X#define FILE_STAT stat X#else X#define FILE_STAT lstat X#endif X- 321, 322 X char tmppath[MAXPATHLEN+1], *trunc_point; X /* end 'path' by changing trailing '/' (of dir name) to a '\0' */ X trunc_point = (dirs[(ndirs-1)-dirMB.selected + 1] - 1); X *trunc_point = '\0'; X- 327, 339 X if (path[0] == '\0') strcpy(tmppath,"/"); X#else X if (path[0] == '\0') strcpy(tmppath,"//"); X#endif X else strcpy ( tmppath, path ); X X#ifdef VMS X /* X * The VMS chdir always needs 2 components (device and directory), X * so convert "/device" to "/device/000000" and convert X * "/" to "/DEVICE_LIST_ROOT/000000" (device_list_root is special X * concealed device setup to provide list of available disks). X */ X if ( ((ndirs-dirMB.selected) == 2) && (strlen(tmppath) > 1) )`032 X`009strcat ( tmppath, "/000000" ); /* add root dir for device */ X else if ((ndirs-dirMB.selected) == 1 ) `123 X`009strcpy ( tmppath, "/device_list_root/000000" ); /* fake top level */ X `125 X#endif X if (chdir(tmppath)) `123 X static char *foo[] = `123 "\nWhatever" `125; X char str[512]; X sprintf(str,"Unable to cd to '%s'\n%s\n",tmppath, X`009 "Cd-ing to '.' instead."); X *trunc_point = '/';`009/* restore the path */ X dirMB.selected = 0; X MBRedraw(&dirMB); X PopUp(str, foo, 1); X X- 454, 455 X if ( FILE_STAT(fnames[i]+1, &st) == 0 ) `123 X- 906, 907 X#ifdef VMS X /* X * Convert names of form "/device.dir" to "/device/000000.DIR"`032 X */ X if ( strrchr ( newpath, '/' ) == newpath ) `123 X strcpy ( strrchr ( newpath, '.' ), "/000000.DIR" ); X `125 X#endif X if (FILE_STAT(newpath, &st)==0) `123 X- 916 X#ifdef VMS X /* X * remove the .DIR from the path so that false 000000 directories work X */ X char *dirext; X dirext = strrchr ( newpath, '/' ); X if ( dirext == NULL ) dirext = newpath; else dirext++; X dirext = strstr ( dirext, "." ); X *dirext = '\0'; X#endif X- 934, 934 X#ifdef VMS X return 1; X#else X- 967 X#endif X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVEVENT.DIF" $ CHECKSUM_IS = 1630295132 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 160 X#ifdef VMS X static int borders_sized = 0; X X if ( !borders_sized && !useroot ) if ( exp_event->window == mainW ) `123 X`009/* X`009 * Initial expose of main window, find the size of the ancestor X`009 * window just prior to the root window and adjust saved size X`009 * of display so that maximize functions will allow for window X`009 * decorations. X`009 */ X`009int status, count, mwid, mhgt, x, y, w, h, b, d, mbrd; X`009Window root, parent, *children, crw = exp_event->window; X`009borders_sized = 1; X`009status = XGetGeometry(theDisp, crw,`032 X`009`009`009&root, &x, &y, &mwid, &mhgt, &mbrd, &d); X X`009for ( parent = crw, w=mwid, h=mhgt; X`009`009status && (parent != root) && (parent != vrootW); ) `123 X`009 crw = parent; X`009 status = XQueryTree ( theDisp, crw, &root, &parent,`032 X`009`009`009&children, &count ); X`009 if ( children != NULL ) XFree ( children ); X`009`125 X`009status = XGetGeometry(theDisp, crw, &root, &x, &y, &w, &h, &b, &d); X`009if ( status ) `123 X`009 dispWIDE = dispWIDE + mwid - w + (2*b); X`009 dispHIGH = dispHIGH + mhgt - h + b; X`009 /*printf("New display dims: %d %d\n", dispWIDE, dispHIGH ); */ X`009`125 X `125 X#endif X- 362, 365 X char buf[128]; KeySym ks; `032 X int stlen, dealt, shift; X`009 X stlen = XLookupString(key_event,buf,128,&ks,&xv_compose); X- 820 X#ifdef VMS X if ( 1 ) `123 X XSizeHints xsh; X XMoveResizeWindow(theDisp, mainW, xwa->x, xwa->y, xwa->width, xwa->height); X xsh.x = xwa->x - xwa->border_width;`009/* adjust so window doesn't creep */ X xsh.y = xwa->y - xwa->border_width; X xsh.width = xwa->width; X xsh.height = xwa->height; X xsh.flags = USPosition `124 USSize; X XSetNormalHints(theDisp, mainW, &xsh); X `125 X#endif X X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVGAM.DIF" $ CHECKSUM_IS = 1682859015 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 538, 541 X char buf[128]; KeySym ks; X int stlen; X`009 X stlen = XLookupString(e,buf,128,&ks,&xv_compose); X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVGIF.DIF" $ CHECKSUM_IS = 941582828 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 127 X#ifdef VMS X int status, gif_fget_counted(), ii; X char vms_name[256]; X typedef struct `123 X`009unsigned char *pos, *start, *end;`009/* file positions */ X`009int chan, size; X `125 map_block; X map_block *gif_fopen(), *map;`009/* routine to map file to memory */ X#endif X- 139, 139 X X#ifdef VMS X (void) fgetname ( fp, vms_name, 1 ); X map = gif_fopen ( vms_name ); X filesize = map->size; X if ( filesize == -1 ) return ( GifError ( "Can't map file to memory") ); X gif_fgetc();`009/* get first segment */ X ptr = RawGIF = map->start; X X#else X X- 154 X#endif X- 345, 387 X- 391, 393 X CodeSize = NEXTBYTE; X#ifdef VMS X GIF_DECOMPRESS_INIT ( &CodeSize ); X map->pos = ptr; X- 397 X if (!pic)`032 X return( GifError("not enough memory for 'pic'") ); X if ( !Interlace ) X status = GIF_DECOMPRESS ( gif_fget_counted, map, maxpixels, picptr ); X else `123 X /* X * decompress a line at a time into the proper position. X */ X int pass, step, i, y; X step = 8; X y = pass = 0; X for ( i = 0; i < Height; i++ ) `123 X`009 status = GIF_DECOMPRESS X`009`009( gif_fget_counted, map, Width, &picptr[y*Width] ); X`009 if ( (status&1) != 1 ) break; X X`009 y += step; X`009 if ( y >= Height ) `123 X`009 /* X`009 * Stepsize/start-Y progression: 8/0, 8/4, 4/2, 2/1`032 X`009 */ X`009 if ( pass > 0 ) step = step/2; X`009 y = step/2; X`009 pass++; X`009 `125 X `125 X `125 X `032 X gif_fclose(); X if ( (status&1) == 0 ) `123 X char msg[256]; X SetISTR(ISTR_WARNING, X`009 "Error decompressing data. Winging it."); X sprintf ( msg, "Error decompressing data, code %d, start: %x, pos: %x", X`009`009status, map->start, map->pos ); X return( GifError(msg) ); X `125 X#else X ClearCode = (1 << CodeSize); X EOFCode = ClearCode + 1; X FreeCode = FirstFree = ClearCode + 2; X `032 X /* The GIF spec has it that the code size is the code size used to X * compute the above values is the code size given in the file, but the X * code size used in compression/decompression is the code size given in X * the file plus one. (thus the ++). X */ X `032 X CodeSize++; X InitCodeSize = CodeSize; X MaxCode = (1 << CodeSize); X ReadMask = MaxCode - 1; X `032 X X X /* UNBLOCK: X * Read the raster data. Here we just transpose it from the GIF array X * to the Raster array, turning it from a series of blocks into one long X * data stream, which makes life much easier for ReadCode(). X */ X `032 X ptr1 = Raster; X do `123 X ch = ch1 = NEXTBYTE; X while (ch--) `123 *ptr1 = NEXTBYTE; ptr1++; `125 X if ((ptr - RawGIF) > filesize) `123 X SetISTR(ISTR_WARNING, X`009 "This GIF file seems to be truncated. Winging it."); X break; X `125 X `125 while(ch1); X free(RawGIF);`009 RawGIF = NULL; `009/* We're done with the raw data now */ X X X X if (DEBUG) `123 V fprintf(stderr,"xv: LoadGIF() - picture is %dx%d, %d bits, %sinterlaced\n X", X`009 Width, Height, BitsPerPixel, Interlace ? "" : "non-"); X `125 X `032 X /* Allocate the 'pic' */ X pWIDE = Width; pHIGH = Height; X maxpixels = Width*Height; X picptr = pic = (byte *) malloc(maxpixels); X- 504 X#endif X- 592, 594 X#ifndef VMS X if (RawGIF != NULL) free(RawGIF); X if (Raster != NULL) free(Raster); X#endif X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVIMAGE.DIF" $ CHECKSUM_IS = 1443784498 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 664, 664 X int i, nullidata = 0; X static byte *prev_image = NULL; X- 692, 693 X if (theImage) `123 X`009if ( theImage->data ) `123 X`009 free ( theImage->data ); X`009 theImage->data = NULL; X`009`125 else `123 nullidata = 1; printf ( "theImage->data was null" ); `125 X`009XDestroyImage(theImage); X `125 else nullidata = 1; X if ( prev_image && nullidata ) free ( prev_image ); X theImage = prev_image = NULL; X- 708 X prev_image = imagedata; X- 734 X prev_image = imagedata; X- 753 X prev_image = imagedata; X- 826 X prev_image = imagedata; X- 845 X prev_image = imagedata; X- 872 X prev_image = imagedata; X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVJPEG.DIF" $ CHECKSUM_IS = 1615685626 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 168, 171 X char buf[128]; KeySym ks; X int stlen; X`009 X stlen = XLookupString(e,buf,128,&ks,&xv_compose); X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVMISC.DIF" $ CHECKSUM_IS = 1293180237 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 428 X#ifndef VMS X- 466 X#else X`123float ftime; X ftime = n / 1000.0; X lib$wait(&ftime);`125 X#endif X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVPOPUP.DIF" $ CHECKSUM_IS = 241778991 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 232, 235 X char buf[128]; KeySym ks; X int stlen, i; X`009 X stlen = XLookupString(e,buf,128,&ks,&xv_compose); X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XVPS.DIF" $ CHECKSUM_IS = 1733127419 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X- 272, 275 X char buf[128]; KeySym ks; X int stlen; X`009 X stlen = XLookupString(e,buf,128,&ks,&xv_compose); X/ $ GOSUB UNPACK_FILE $ FILE_IS = "XV_FIXUP_VMS.COM" $ CHECKSUM_IS = 659819119 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$! X$! apply fixes to XV source files based upon contents of .DIF files X$! X$ call dclslp xv.h xv-h.dif X$ call dclslp xv.c X$ call dclslp xvdflt.c X$ call dclslp xvdir.c X$ call dclslp xvevent.c X$ call dclslp xvgam.c X$ call dclslp xvgif.c X$ call dclslp xvimage.c X$ call dclslp xvjpeg.c X$ call dclslp xvmisc.c X$ call dclslp xvpopup.c X$ call dclslp xvps.c X$! X$ if f$search("VMS.OBJ;") .nes. "" then delete/log vms.obj;* X$! X$ exit X$! X$ DCLSLP: SUBROUTINE X$! X$! edit file based upon DIFF/SLP output. X$! X$! parameters: X$! P1`009Name of original source file. X$! P2`009Name of differences file (default 'P1'.dif) X$! P3`009Name of output file. X$! X$ say = "write sys$output" X$ if p1 .eqs. "" then inquire p1 "File to edit" X$ if p1 .eqs. "" then exit X$ ifile_name = f$search(p1) X$ if ifile_name .eqs. "" X$ then X$ say "Input file not found" X$ exit X$ endif X$ ifile_type = f$parse(p1,,,"TYPE") + "-orig;" X$ ifile_orig = f$search(f$parse(ifile_type,ifile_name)) X$ if ifile_orig .nes. "" X$ then X$ say "Found existing original file..." X$ else X$ copy/log 'ifile_name' 'f$parse(ifile_type,ifile_name)' X$ ifile_orig = ifile_name X$ endif X$ obj_file = f$parse(".obj;",ifile_name) X$ if f$search(obj_file) .nes. "" then delete/log 'obj_file'* X$! X$ on control_y then goto cleanup X$ open/read ifile 'ifile_orig'/err=no_input_file X$ say "Processing file ", ifile_orig V$ open/read dfile 'f$search(f$parse(P2,".dif;",ifile_name))'/error=no_dif_fil Xe X$ on error then goto cleanup X$ ofile_name = f$parse(p3,"",ifile_name) X$ create 'ofile_name' X$ open/append ofile 'ofile_name' X$ cur_line = 0 X$ read dfile dif_line/end=dif_eof X$! X$ get_range: X$ dif_line = f$edit(dif_line,"collapse") - "-" X$ dif_start_line = f$integer(f$element(0,",",dif_line)) X$ dif_end_line = f$element(1,",",dif_line) X$ if dif_end_line .eqs. "," .or. dif_end_line .eqs. "" X$ then dif_end_line = dif_start_line - 1 X$ else`032 X$`009dif_start_line = dif_start_line - 1 X$`009dif_end_line = f$integer(dif_end_line) X$ endif X$! X$ find_position: X$ if cur_line .ge. dif_start_line then goto skip_changed X$ read ifile line/end=cleanup X$ write ofile line X$ cur_line = cur_line + 1 X$ goto find_position X$! X$ skip_changed: X$ if cur_line .ge. dif_end_line then goto insert_new X$ read ifile line /end=cleanup X$ cur_line = cur_line + 1 X$ goto skip_changed X$! X$ insert_new: X$ read dfile dif_line/end=dif_eof X$ col1 = f$extract(0,1,dif_line) X$ if col1 .eqs. "-" then goto get_range X$ if dif_line .eqs. "/" then goto dif_eof X$ if col1 .eqs. "<" then dif_line = dif_line - col1 X$ write ofile dif_line X$ goto insert_new X$! X$ dif_eof: X$ read ifile line/end=cleanup X$ write ofile line X$ goto dif_eof X$! X$ cleanup: X$ close ifile X$ close dfile X$ close ofile X$ exit X$! X$! error exits X$! X$ no_input_file: X$ say "Error opening input file" X$ exit X$! X$ no_dif_file: X$ EXIT X$ENDSUBROUTINE $ GOSUB UNPACK_FILE $ FILE_IS = "XV_MAKE.COM" $ CHECKSUM_IS = 251723754 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$! X$! compile and build XV program from source files. X$! X$ if f$trnlnm("X11") .eqs. "" then define x11 decw$include X$ if f$trnlnm("SYS") .eqs. "" then define sys sys$share X$ cc = "cc/define=HAVE_JPEG/include=[.jpeg]" X$! X$ if f$search("argproc.c") .eqs. "" then copy [.unsupt.vms]argproc.c [] X$ if f$search("includes.h") .eqs. "" then copy [.unsupt.vms]includes.h [] X$! V$ sources = "xv,xvmisc,xvevent,xvcolor,xvimage,pseudo_root,xvroot,vms,xvdir," X+ - X`009"xvgam,readdr,xvbutt,xvdial,vprintf,xv24to8,xvsmooth,xvctrl,xvdflt,"+ - X`009"xvgif,xvgifwr,gifmapf,xvgraf,xvps,xvinfo,xvscrl,xvpm," + - X`009"xvpbm,xvpopup,xvsunras,xvxbm,xvjpeg,argproc" X$! X$ if f$search("bitmaps.h") .eqs. "" then gosub copy_bitmaps X$ new_objects = "" X$ if f$search("[.jpeg]jpeglib.olb") .eqs. "" X$ then X$ default = f$environment("default") X$ set def [.jpeg] X$ write sys$Output "Building JPEG library..." X$ @[-]jpeg_make X$ set default 'default' X$ new_objects = ",[.jpeg]jpeglib/lib" X$ endif X$! X$ if f$search("gifdecomp.obj") .eqs. "" X$ then X$ write sys$Output "Assembling GIFDECOMP.MAR X$ macro gifdecomp X$ new_objects = ",gifdecomp" X$ endif X$! X$! search for missing object files. X$! X$ sndx = 0 X$ next_source: X$ sfile = f$element(sndx,",",sources) X$ sndx = sndx + 1 X$ if sfile .eqs. "," then goto sources_done X$ ofile = f$parse(".OBJ",sfile) X$ if f$search(ofile) .nes. "" then goto next_source X$ write sys$Output "Compiling ", sfile, ".c ..." X$ cc 'sfile'.c X$ if f$search(ofile) .nes. "" then new_objects = new_objects + "," + sfile X$ goto next_source X$! X$ sources_done: X$ if new_objects .eqs. "" .and. p1 .eqs. "" then exit X$ new_objects = new_objects - "," X$! X$ write sys$Output "Linking new XV image..." X$ link/exe=xv.exe sys$input/opt 'p1' Xxv,xvmisc,xvevent,xvcolor,xvimage,pseudo_root,xvroot,vms,argproc,xvdir Vxvgam,readdr,xvbutt,xvdial,vprintf,xv24to8,xvsmooth,xvctrl,xvdflt,xvgif,xvgif Xwr Xgifmapf,gifdecomp,xvgraf,xvps,xvinfo,xvscrl,xvpm,xvpbm,xvpopup,xvsunras,xvxbm Xxvjpeg,[.jpeg]jpeglib/lib Xsys$share:decw$xlibshr/share,decw$dwtlibshr/share,vaxcrtl/share X$ exit $status X$! X$! subroutine to generate new bitmaps.h file. X$! X$ copy_bitmaps: X$ create bitmaps.h X$ bmlist = "grasp,penn,down,down1,up,up1,scrlgray,gray50,gray25,i_fifo," + - X "i_chr,i_dir,i_blk,i_lnk,i_sock,i_reg,rb_off,rb_on,rb_off1,rb_on1," + - V "fc_left,fc_leftm,fc_mid,fc_midm,fc_right,fc_rightm,fc_left1,fc_left1m," X+ - X "fc_right1,fc_right1m,icon,dial_cw1,dial_cw2,dial_ccw1,dial_ccw2,"+ - X "iconmask,gf1_addh,gf1_delh,gf1_line,gf1_rst,gf1_spln,gf1_gamma," + - V "h_rotl,h_rotr,h_sinc,h_sdec,h_flip,cb_off,cb_on,cb_off1,cb_on1,h_sat," X +- X "h_desat,root_weave,cboard50,mb_chk" X$! X$ ndx = 0 X$ append_next: X$ name = f$element(ndx,",",bmlist) X$ if name .eqs. "," then return X$ ndx = ndx + 1 X$ append [.bitmaps]'name'. []bitmaps.h X$ goto append_next $ GOSUB UNPACK_FILE $ FILE_IS = "JPEG_MAKE.COM" $ CHECKSUM_IS = 1866994362 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$! X$! build library for JPEG compression. Default directory must be the same X$! directory that contains the JPEG source files. X$! X$ cc = "cc/define=__STDC__" X$ sources = "jbsmooth,jcarith,jccolor,jcdeflts,jcexpand,jchuff," + - X "jcmaster,jcmcu,jcpipe,jcsample,jdarith,jdcolor,"+ - X "jddeflts,jdhuff,jdmaster,jdmcu,jdpipe,jdsample," + - X "jerror,jquant1,jquant2,jfwddct,jrevdct,jutils,jvirtmem,jrdjfif,"+ - X`009"jrdgif,jrdppm,jrdrle,jrdtarga,jwrjfif,jwrgif,jwrppm,jwrrle,jwrtarga" X$ X$ INCLUDES= "jinclude.h,jconfig.h,jpegdata.h,jversion.h,egetopt.c" X$! X$ sndx = 0 X$ new_objects = "" X$ next_source: X$ sfile = f$element(sndx,",",sources) X$ sndx = sndx + 1 X$ if sfile .eqs. "," then goto sources_done X$ ofile = f$parse(".OBJ",sfile) X$ if f$search(ofile) .nes. "" then goto next_source X$ write sys$Output "Compiling ", sfile, ".c ..." X$ cc 'sfile'.c X$ if f$search(ofile) .nes. "" then new_objects = new_objects + sfile + "," X$ goto next_source X$! X$ sources_done: X$ if new_objects .eqs. "" then exit X$ new_objects = f$extract(0,f$length(new_objects)-1,new_objects) X$ if f$search("jpeglib.olb") .eqs. "" then library/create jpeglib.olb X$ library/replace jpeglib 'new_objects' X$ exit $ GOSUB UNPACK_FILE $ FILE_IS = "VMS.C" $ CHECKSUM_IS = 1449184596 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* Some unix emulation procedures to make XV happy */ X/* 1-NOV-1990 GJC@MITECH.COM */ X X#include X X#include X#include X#include X#include X#include X X Xint xv_bcmp ( s1, s2, size ) X char *s1, *s2; X int size; X`123 X int i; X for ( i = 0; i < size; i++ ) if ( *s1++ != *s2++ ) `123 X`009if ( *(--s1) > *(--s2) ) return 1; else return -1; X `125 X return 0; X`125 X Xbcopy(x,y,n) X char *x,*y; X long n; X`123memmove(y,x,n);`125`009/* reverse order of arguments */ X Xstatic char *getwd_tmp = NULL; X Xchar *getwd(p) X char *p; X`123int c; X char *root_dir,*l2; X getcwd(p,512,0);`009/* get current working directory in unix format*/ X X root_dir = strstr ( p, "/000000" ); X if ( root_dir != NULL ) `123 X /* trim root directory out of specification */ X if ( (strlen(root_dir) == 7) &&`032 X`009 (strpbrk(p+1,"/") == root_dir) ) *root_dir = '\0'; X `125 X /* special kludge for "/" directory */ X if ( strcmp ( p, "/DEVICE_LIST_ROOT" ) == 0 ) strcpy ( p, "/" ); X return(p); X`125 X Xunlink(p) X char *p; X`123printf("unlink: '%s'\n",p); delete(p);`125 X Xrindex(p,c) X char *p; X int c; X`123return(strrchr(p,c));`125 X Xint lstat(f,st)`009`009/* fake a stat operation to return file type */ X char *f; X stat_t *st; X`123 X char *dirext, *name; X int extlen; X X st->st_mode = S_IFREG;`009/* default to normal file */ X name = strrchr ( f, '/' );`009/* locate rightmost slash */ X if ( name == NULL ) name = f; else name++; X X dirext = strstr ( name, ".DIR" ); X if ( dirext != NULL ) `123 X`009/* make it an exact match */ X`009extlen = strcspn(&dirext[1],".;"); X if ( (extlen == 0) `124`124 (extlen == 3) ) `123 X`009 st->st_mode = S_IFDIR; X`009 if ( strncmp ( name, "000000.", 7 ) == 0 ) return 0; X`009 else return (stat ( f, st )); X`009`125 X `125 X return 0; X`125 X Xdo_vms_wildcard(pargc,pargv) X int *pargc; X char ***pargv; X`123int j,vsize; X int argc; char **argv; X argc = *pargc; X argv = *pargv; X *pargc = 0; X vsize = 3; X *pargv = (char **) malloc(sizeof (char *) * vsize); X for(j=0;j unix: '%s'\n", s, uname ); */ X if ( strlen(s) >= strlen(uname) ) `123 strcpy(s,uname); free(uname); `125 X else s = uname; /* will lose s's old allocation */ X `125`032 X (*pargv)[(*pargc)++] = s;`125 X X Xset_dsc(x,buff,len) X struct dsc$descriptor *x; X char *buff; X int len; X`123(*x).dsc$w_length = len; X (*x).dsc$a_pointer = buff; X (*x).dsc$b_class = DSC$K_CLASS_S; X (*x).dsc$b_dtype = DSC$K_DTYPE_T; X return(x);`125 X X struct dsc$descriptor * Xset_dsc_cst(x,buff) X struct dsc$descriptor *x; X char *buff; X`123return(set_dsc(x,buff,strlen(buff)));`125 X X Xvms_wild_put_wild(s,pargc,pargv,pvsize) X char *s; int *pargc; char ***pargv; int *pvsize; X`123struct dsc$descriptor fnamed,foutd,rfnamed; X char *ns,*p; X int rval; X long context; X set_dsc_cst(&rfnamed,";"); X set_dsc_cst(&fnamed,s); X set_dsc(&foutd,0,0); X foutd.dsc$b_class = DSC$K_CLASS_D; X context = 0; X while(1) X `123rval = lib$find_file(&fnamed,&foutd,&context,0,&rfnamed,0,0); X if (rval == RMS$_NMF) break; X if (rval == RMS$_FNF) break; X if (rval != RMS$_NORMAL) exit(rval); X ns = (char *) malloc(foutd.dsc$w_length + 1); X ns[foutd.dsc$w_length] = 0; X memcpy(ns,foutd.dsc$a_pointer,foutd.dsc$w_length); X /*if (p = strchr(ns,']')) ns = p+1;*/ X /* if (p = strchr(ns,';')) *p = 0; */ X vms_wild_put_one(ns,pargc,pargv,pvsize);`125 X if (foutd.dsc$a_pointer) lib$sfree1_dd(&foutd); X if (context) X `123rval = lib$find_file_end(&context); X if (rval != SS$_NORMAL) exit(rval);`125`125 X X/* X * define routine to build the uncompress command to spawn. X */ Xstatic char uncompress_cmd[500]; Xstatic char *uncompress_ofile; Xstatic int translate_action(infile) X char *infile; X`123 X sprintf ( uncompress_cmd, "mcr xv_uncompress -b %s %s", infile, X`009`009uncompress_ofile ); X return 1; X`125 X Xint vms_do_uncompress ( infile, outfile ) X char *infile, *outfile; X`123 X int status; X strcpy(uncompress_cmd, "exit 20" ); X uncompress_ofile = outfile; X SHELL$TO_VMS ( infile, translate_action, 0 ); /* no wildcards */ X X status = system(uncompress_cmd); X if ( (status&1) == 1 ) return 0;`009/* success ! */ X printf("Error in compress: %d\n", status ); X return 1; X`125 X X/* X * Define substitue qsort for one that dec broke. Only handle case where X * element size is 4 (same as integer). X */ X#ifdef qsort X#undefine qsort X#endif Xvoid xv_qsort ( array, size, unit, compare ) X int array[1000];`009/* array to be sorted */ X int size;`009`009/* size of array to sort, should be at least 100 */ X int unit;`009`009/* Size of array element */ X int compare();`009/* comaparison function */ X`123 X int stack[68], *top;`009/* work array, depth of stack is bounded */ X int start, finish, lbound, hbound, pivot, temp, i, j; X X if ( unit != sizeof(int) ) `123`009/* punt */ X`009qsort ( array, size, unit, compare ); X`009return; X `125 X if ( size <= 1 ) return; X /* set up initial partition on top of stack */ X top = &stack[68]; X *--top = 0;`009`009/* push lbound */ X *--top = size-1;`009/* push initial hbound */ X X /* loop until stack is emtpy */ X X while ( top < &stack[68] ) `123 X X /* pop next range from stack and see if it has at least 3 elements */ X X finish = *top++; start = *top++; X pivot = array[start]; X if ( finish > start + 1 ) `123 X /* X * more than 2 elements, split range into 2 sections according to X * the relation to the pivot value. X */ X`009 array[start] = array[(start+finish)/2];`009/* avoid sequence */ X`009 array[(start+finish)/2] = pivot; pivot = array[start]; X lbound = start; hbound = finish; X while ( lbound < hbound ) `123 X if ( compare(&pivot, &array[lbound+1]) > 0 ) `123 X lbound++; X `125 else `123 X temp = array[hbound]; X array[hbound] = array[lbound+1]; X hbound--; X array[lbound+1] = temp; X `125 X `125 X /* determine which parition is bigger and push onto stack */ X if ( lbound + lbound < (start+finish) ) `123 X /* push high partition first. */ X *--top = lbound + 1; X *--top = finish; X finish = start;`009`009/* skip add step below */ X /* either push low partition or sort by inspection */ X if ( lbound - start > 1 ) `123 X *--top = start; X *--top = lbound; X `125 else `123 X /* 2 element parition (start+1=lbound), sort by looking */ X if ( pivot > array[lbound] ) `123 X array[start] = array[lbound]; X array[lbound] = pivot; X `125 X `125 X `125 else if ( lbound != finish ) `123 X /* either push low partition or sort by inspection */ X if ( lbound - start > 1 ) `123 X *--top = start; X *--top = lbound; X `125 else if ( lbound > start ) `123 X /* 2 element parition (start+1=lbound), sort by looking */ X if ( compare(&pivot, &array[lbound]) > 0 ) `123 X array[start] = array[lbound]; X array[lbound] = pivot; X `125 X `125 X /* push high partition or sort by inspection */ X if ( lbound < finish - 2 ) `123 X *--top = lbound + 1; X *--top = finish; X `125 else if ( lbound < finish - 1 ) `123 /* 2 in partition */ X if ( compare(&array[lbound+1], &array[finish]) > 0 ) `123 X temp = array[lbound+1]; X array[lbound+1] = array[finish]; X array[finish] = temp; X `125 X `125 X `125 else `123 X /* X * Special case: high partition is empty, indicating that pivot X * value is at maximum. Move to end and re-push remainder. X */ X array[start] = array[finish]; X array[finish] = pivot; X *--top = start; X *--top = finish - 1; X `125 X X `125 else `123 X /* only 2 elements in partition, sort inline */ X if ( compare(&pivot,&array[finish]) > 0 ) `123 X array[start] = array[finish]; X array[finish] = pivot; X `125 X `125 X `125 X`125`032 $ GOSUB UNPACK_FILE $ FILE_IS = "READDR.C" $ CHECKSUM_IS = 1530424964 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* X** VMS readdir() routines. X** Written by Rich $alz, in August, 1990. X** This code has no copyright. X*/ X V/* 12-NOV-1990 added d_namlen field and special case "." name -GJC@MITECH.COM X`032 X */ X X#include X#include X#include X#include X#include X#include "dirent.h" X X /* Uncomment the next line to get a test routine. */ X/*#define TEST*/ X X /* Number of elements in vms_versions array */ X#define VERSIZE(e)`009(sizeof e->vms_versions / sizeof e->vms_versions[0]) X X /* Linked in later. */ Xextern char`009*malloc(); Xextern char`009*strrchr(); Xextern char`009*strcpy(); X X X/* X** Open a directory, return a handle for later use. X*/ XDIR * Xopendir(name) X char`009*name; X`123 X DIR`009`009*dd; X X /* Get memory for the handle and the pattern string. */ X if ((dd = (DIR *)malloc(sizeof *dd)) == NULL) `123 X`009errno = ENOMEM; X`009return NULL; X `125 X `032 X if (strcmp(".",name) == 0) name = ""; X `032 X dd->pattern = malloc((unsigned int)(strlen(name) + sizeof "*.*" + 1)); X if (dd->pattern == NULL) `123 X`009free((char *)dd); X`009errno = ENOMEM; X`009return NULL; X `125 X X /* Fill in the fields; mainly playing with the descriptor. */ X (void)sprintf(dd->pattern, "%s*.*", name); X dd->context = 0; X dd->vms_wantversions = 0; X dd->pat.dsc$a_pointer = dd->pattern; X dd->pat.dsc$w_length = strlen(dd->pattern); X dd->pat.dsc$b_dtype = DSC$K_DTYPE_T; X dd->pat.dsc$b_class = DSC$K_CLASS_S; X X return dd; X`125 X X X/* X** Set the flag to indicate we want versions or not. X*/ Xvoid Xvmsreaddirversions(dd, flag) X DIR`009`009*dd; X int`009`009flag; X`123 X dd->vms_wantversions = flag; X`125 X X X/* X** Free up an opened directory. X*/ Xvoid Xclosedir(dd) X DIR`009`009*dd; X`123 X free(dd->pattern); X free((char *)dd); X`125 X X X/* X** Collect all the version numbers for the current file. X*/ Xstatic void Xcollectversions(dd) X DIR`009`009`009`009*dd; X`123 X struct dsc$descriptor_s`009pat; X struct dsc$descriptor_s`009res; X struct dirent`009`009*e; X char`009`009`009*p; X char`009`009`009buff[sizeof dd->entry.d_name]; X int`009`009`009`009i; X char`009`009`009*text; X long`009`009`009context; X X /* Convenient shorthand. */ X e = &dd->entry; X X /* Add the version wildcard, ignoring the "*.*" put on before */ X i = strlen(dd->pattern); X text = malloc((unsigned int)(i + strlen(e->d_name)+ 2 + 1)); X if (text == NULL) X`009return; X (void)strcpy(text, dd->pattern); X (void)sprintf(&text[i - 3], "%s;*", e->d_name); X X /* Set up the pattern descriptor. */ X pat.dsc$a_pointer = text; X pat.dsc$w_length = strlen(text); X pat.dsc$b_dtype = DSC$K_DTYPE_T; X pat.dsc$b_class = DSC$K_CLASS_S; X X /* Set up result descriptor. */ X res.dsc$a_pointer = buff; X res.dsc$w_length = sizeof buff - 2; X res.dsc$b_dtype = DSC$K_DTYPE_T; X res.dsc$b_class = DSC$K_CLASS_S; X X /* Read files, collecting versions. */ X for (context = 0; e->vms_verscount < VERSIZE(e); e->vms_verscount++) `123 V`009if (lib$find_file(&pat, &res, &context) == RMS$_NMF `124`124 context == 0 X) X`009 break; X`009buff[sizeof buff - 1] = '\0'; X`009if (p = strchr(buff, ';')) X`009 e->vms_versions[e->vms_verscount] = atoi(p + 1); X`009else X`009 e->vms_versions[e->vms_verscount] = -1; X `125 X X free(text); X`125 X X X/* X** Read the next entry from the directory. X*/ Xstruct dirent * Xreaddir(dd) X DIR`009`009`009`009*dd; X`123 X struct dsc$descriptor_s`009res; X char`009`009`009*p; X char`009`009`009buff[sizeof dd->entry.d_name]; X int`009`009`009`009i; X X /* Set up result descriptor, and get next file. */ X res.dsc$a_pointer = buff; X res.dsc$w_length = sizeof buff - 2; X res.dsc$b_dtype = DSC$K_DTYPE_T; X res.dsc$b_class = DSC$K_CLASS_S; X X if (lib$find_file(&dd->pat, &res, &dd->context) == RMS$_NMF X `124`124 dd->context == 0L) X`009/* None left... */ X`009return NULL; X X /* Force the buffer to end with a NUL. */ X buff[sizeof buff - 1] = '\0'; X for (p = buff; !isspace(*p); p++) X`009; X *p = '\0'; X X /* Skip any directory component and just copy the name. */ X if (p = strchr(buff, ']')) X`009(void)strcpy(dd->entry.d_name, p + 1); X else X`009(void)strcpy(dd->entry.d_name, buff); X X /* Clobber the version. */ X if (p = strchr(dd->entry.d_name, ';')) X`009*p = '\0'; X dd->entry.d_namlen = strlen(dd->entry.d_name); X X dd->entry.vms_verscount = 0; X if (dd->vms_wantversions) X`009collectversions(dd); X return &dd->entry; X`125 X X X/* X** Return something that can be used in a seekdir later. X*/ Xlong Xtelldir(dd) X DIR`009`009*dd; X`123 X return dd->context; X`125 X X X/* X** Return to a spot where we used to be. X*/ Xvoid Xseekdir(dd, pos) X DIR`009`009*dd; X long`009pos; X`123 X dd->context = pos; X`125 X X X#ifdef`009TEST Xmain() X`123 X char`009`009buff[256]; X DIR`009`009`009*dd; X struct dirent`009*dp; X int`009`009`009i; X int`009`009`009j; X X for ( ; ; ) `123 X`009printf("\n\nEnter dir: "); X`009(void)fflush(stdout); X`009(void)gets(buff); X`009if (buff[0] == '\0') X`009 break; X`009if ((dd = opendir(buff)) == NULL) `123 X`009 perror(buff); X`009 continue; X`009`125 X X`009/* Print the directory contents twice, the second time print X`009 * the versions. */ X`009for (i = 0; i < 2; i++) `123 X`009 while (dp = readdir(dd)) `123 X`009`009printf("%s%s", i ? "\t" : " ", dp->d_name); X`009`009for (j = 0; j < dp->vms_verscount; j++) X`009`009 printf(" %d", dp->vms_versions[j]); X`009`009printf("\n"); X`009 `125 X`009 rewinddir(dd); X`009 vmsreaddirversions(dd, 1); X`009`125 X`009closedir(dd); X `125 X exit(0); X`125 X#endif`009/* TEST */ $ GOSUB UNPACK_FILE $ FILE_IS = "DIRENT.H" $ CHECKSUM_IS = 1210384751 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* X** Header file for VMS readdir() routines. X** Written by Rich $alz, in August, 1990. X** This code has no copyright. X** X** You must #include before this file. X*/ X X/* 12-NOV-1990 added d_namlen field -GJC@MITECH.COM */ X X /* Data structure returned by READDIR(). */ Xstruct dirent `123 X char`009d_name[100];`009`009/* File name`009`009*/ X int d_namlen; X int`009`009vms_verscount;`009`009/* Number of versions`009*/ X int`009`009vms_versions[20];`009/* Version numbers`009*/ X`125; X X /* Handle returned by opendir(), used by the other routines. You X * are not supposed to care what's inside this structure. */ Xtypedef struct _dirdesc `123 X long`009`009`009context; X int`009`009`009`009vms_wantversions; X char`009`009`009*pattern; X struct dirent`009`009entry; X struct dsc$descriptor_s`009pat; X`125 DIR; X X X#define rewinddir(dirp)`009`009seekdir((dirp), 0L) X X Xextern DIR`009`009*opendir(); Xextern struct dirent`009*readdir(); Xextern long`009`009telldir(); Xextern void`009`009seekdir(); Xextern void`009`009closedir(); Xextern void`009`009vmsreaddirversions(); $ GOSUB UNPACK_FILE $ FILE_IS = "PSEUDO_ROOT.C" $ CHECKSUM_IS = 688377861 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* X`009pseudo_root - Return the Window ID of the Pseudo Root X X`009NOTE: This routine is required for DECwindows X`009because the true root window is hidden behind X`009a pseudo-root window created by the window manager. X X`009Calling Sequence: X`009`009root_win = pseudo_root(display, screen); X`009where: X`009`009display must already be opened and X`009`009screen is usually DefaultScreen(display). X X*/ X X#include X X#define`009NULL`0090L X Xstatic void chase_root(); X Xstatic int done; Xstatic Window last_win; Xstatic int root_x, root_y, root_width, root_height; Xstatic int root_bw, root_depth; X X XWindow pseudo_root(dpy, screen) XDisplay *dpy; Xint screen; X`123 X Window root, win; X X /* Start at the real root */ X root = RootWindow(dpy, screen); X X /* Get the geometry of the root */ X if (XGetGeometry(dpy, root, &win, &root_x, &root_y,`032 X`009`009`009&root_width, &root_height, X`009`009`009&root_bw, &root_depth)) X `123 X`009/* Set up for the tree walk */ X`009done = False; X`009last_win = root; X X`009/* Run down the tree to find the pseudo root */ X`009chase_root(dpy, root); X`009return last_win; X `125 X else X`009/* Classic case of "this should never happen" */ X`009return root; X X`125 /*** End pseudo_root() ***/ X X X/* X`009chase_root - Internal to this module X X`009This is a recursive routine for descending the window tree. X X`009It looks for the first window which does NOT overlay the root, X`009then returns with the ID of the last window it saw in the X`009global variable last_win. X X`009NOTE: The parameters of the root window must be set up before X`009calling chase_root(). X*/ X Xstatic void chase_root (dpy, w) XDisplay *dpy; XWindow w; X`123 X Window root, parent; X unsigned int nchildren; X Window *children = NULL; X Status status; X int n; X int x, y, rx, ry; X unsigned int width, height, bw, depth; X X /* Insurance */ X if (done) X`009return; X X if (XGetGeometry(dpy, w, &root, &x, &y, &width, &height, &bw, &depth)) X `123 X`009/* X`009 If this window does not exactly overlay the root X`009 then we have gone one too far, i.e., we have finished. X`009*/ X`009if ( (x != root_x) `124`124 X`009 (y != root_y) `124`124 X`009 (width != root_width) `124`124 X`009 (height != root_height) ) X`009`123 X`009 done = True; X`009 return; X`009`125 X X`009/* Otherwise, remember where we got up to and continue */ X`009else X`009 last_win = w; X `125 X X else X`009/* We are in trouble if this happens!!! */ X`009return; X X if (!XQueryTree (dpy, w, &root, &parent, &children, &nchildren)) X`009/* Likewise, we hope we never get here!!! */ X`009return; X X for (n = 0; n < nchildren; n++) X `123 X`009chase_root (dpy, children[n]); X`009if (done) X`009 break; X `125 X#ifdef VMS X if (children) XFree ((char *) children); X#else X if (children) free ((char *) children); X#endif X return; X X`125 /*** End chase_root() ***/ X $ GOSUB UNPACK_FILE $ FILE_IS = "GIFDECOMP.MAR" $ CHECKSUM_IS = 1815272943 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X`009.title GIF_DECOMPRESSOR X;++ X; Define optimized routines for decompressing GIF files. X; X; procedure GIF_DECOMPRESS_INIT X; Initialize internal tables used by the GIF_DECOMPRESS procedure. X; arguments: X;`0094(AP)`009address of byte containing sizeof output data in bits. X;`009`009must be in range 2 - 8. X; X; procedure GIF_DECOMPRESS X;`009Decompress stream of input codes into user buffer. X; arguments: X;`0094(AP)`009Address of input procedure. X;`0098(AP)`009Unspecified. Additional argument for input procedure. X;`00912(AP)`009Number of output bytes to produce. X;`00916(AP)`009Address of output buffer. X; X; User-supplied input procedure: X; arguments: X;`0094(AP)`009Argument specified in call to GIF_DECOMPRESS X;`0098(AP)`009Address of quadword to receive output descriptor. The X;`009`009input routine must fill in the count and buffer address field X;`009`009of this descritor. X;`009 X;-- X; X; Define data area that holds string table X`009.PSECT GIF_DECOMP_STABLE, WRT, LONG XGIF_MAC_STABLE:: XCODE_BITS:`009.LONG 0`009`009`009; Current input size XBITS_USED:`009.LONG 0`009`009`009; Number of bits used with cur buffer. XTABLE_SIZE: `009.LONG 0`009`009`009; Highest code defined in table XPREV_CODE: `009.LONG 0`009`009`009; Previous input code XSTACK_PTR:`009.LONG 0`009`009`009; Output stack pointer XCLEAR_CODE: `009.LONG 0`009`009`009; Code value to signal table clears XEOI_CODE: `009.LONG 0`009`009`009; Code value to signal data end XINBUF:`009`009.BLKL 2`009`009`009; Descriptor filled in by input routine X; make tables 4100 instead of 4096 to avoid cache stride. XPREFIX:`009`009.BLKW 4100`009`009; prefix code table. XEXTENSION:`009.BLKB 4100`009`009; last char in code's expansion. XSTACK:`009`009.BLKB 4100`009`009; Decoder output stack. XSTACK_TOP: XARG_LIST: .BLKL 5`009`009`009; Copy of argument list. X X`009.PSECT GIF_DECOMP_CODE, NOWRT, LONG, EXE X; X; Define initialization routine. Initialize the GIF_DECOMP_STABLE psect. X; X`009.ENTRY GIF_DECOMPRESS_INIT, `094M X; X; Compute the clear and EOI codes for the specified data size and initial X; input code size. X; X`009ASHL @4(AP), #1, G`094CLEAR_CODE`009; Convert Root size to input. X`009ADDL3 G`094CLEAR_CODE, #1, - X`009 G`094EOI_CODE X`009CVTBL`009@4(AP), R0 X`009ADDL3 R0, #1, G`094CODE_BITS`009; Initial code size X; X; Initialize the decoder table so, each code less than CLEAR_CODE expands X; to itself. Clear and EOI have special prefix values to aid testing for X; those special codes. X; X`009CLRL R0 X`009MOVAW`009G`094PREFIX, R1`009`009; Base address of code table X`009MOVAB`009G`094EXTENSION, R2`009`009; Base address of suffix table. X`009MOVL`009G`094CLEAR_CODE, R3`009; Loop end value. X10$: X`009MNEGW`009#1, (R1)[R0]`009`009; Mark code as having no prefix (-1). X`009MOVB`009R0, (R2)[R0]`009`009; Suffix value is save as code value. X`009AOBLSS`009R3, R0, 10$`009`009; Do next code value. X`009MOVW`009#-2, (R1)[R0]`009`009; Mark clear code specially X`009INCL`009R0`009`009`009; EOI code is 1 after clear code. X`009MOVW`009#-2, (R1)[R0]`009`009; Mark EOI code specially X X`009INCL `009R0 X20$:`009CLRW`009(R1)[R0] X`009AOBLEQ`009#257, R0, 20$`009`009; Zero rest of table up to 8 bits. X X; X; Initialize input state and output stack to prepare for first call to X; GIF_DECOMPRESS. X; X30$:`009CLRL`009G`094BITS_USED`009`009; Init buffer pointer. X`009CLRL`009G`094INBUF`009`009`009; Zero length of input buffer. X`009MNEGL`009#1, G`094PREV_CODE`009`009; No previous code. X`009MNEGL`009#1, G`094TABLE_SIZE`009; Indicates table just cleared. X`009MOVAB`009G`094STACK_TOP, -`009`009; Output stack is initially empty. X`009`009G`094STACK_PTR X`009MOVL #1, R0`009`009`009; Return success. X`009RET X; X; Define main routine for decompressing. X; X`009.ENTRY GIF_DECOMPRESS, `094M X; X; Move variables into registers and make copy of argument list. Note that X; the value of AP was made to correspond to the top of the output stack`032 X; in order to simplify testing for an empty stack (R10 >= AP). X; X`009ASHL`009G`094CODE_BITS, #1, R1`009; Compute new max value. X`009DECL`009R1`009`009`009; as 2`094code_bits - 1 X;`009CLRL`009R2`009`009`009; R2 is input code value. X`009MOVAW`009G`094PREFIX, R3`009`009; Base address of PREFIX table X`009MOVAB`009G`094EXTENSION, R4`009`009; Base address of EXTENSION table X`009MOVL`009G`094TABLE_SIZE, R5`009; Number of codes defined. X`009MOVL`009G`094PREV_CODE, R6`009`009; Previous input code V`009MOVL`009G`094BITS_USED, R7`009`009; Number of bit within cur. buffer used X. X`009MOVL`009G`094CODE_BITS, R8`009`009; Input code size. X`009MOVZWL`009G`094INBUF, R9`009`009; Current # of bytes in input buffer. X`009ASHL`009#3, R9, R9`009`009; Convert to number of bits in buffer. X`009MOVL`009G`094STACK_PTR, R10`009; Recover current output stack position. X`009MOVL`00916(AP), R11`009`009; Output pointer. X`009MOVQ`0094(AP), G`094`009; Copy args 1 and 2. X`009MOVQ`00912(AP), G`094`009; Copy args 3 and 4. X`009MOVAL`009G`094, AP`009; Make new AP that overlaps with X`009`009`009`009`009; the address of the stack top. X`009MOVL`00912(AP), R0`009`009; Size of output buffer. X`009MOVAB`009(R11)[R0], 12(AP)`009; 12(AP) now has overflow address X`009BRB`009CHECK_IF_DONE`009`009; Jump into loop. X; X; When done, save registers back to memory to preserve for next call. X; XDONE: X`009MOVL`009R5, G`094TABLE_SIZE`009; Save table size X`009MOVL`009R6, G`094PREV_CODE `009; Save previous code X`009MOVL`009R7, G`094BITS_USED`009`009; Save # bits used out of input buffer. X`009MOVL`009R8, G`094CODE_BITS`009`009; save current code bits. X`009MOVL`009R10, G`094STACK_PTR`009; Save stack pointer. X`009MOVL`009#1, R0`009`009`009; Set success status X`009RET`009`009`009`009; and return X; X; Handle case where input code is split between buffers. XREFILL: X`009BSBW`009SPAN_BUFFER`009`009; do work. X`009ASHL`009R8, #1, R1`009`009; Regenerate max value. X`009DECL`009R1`009`009`009; as 2`094code_bits - 1 X`009BRB`009CHECK_CODE`009`009; Rejoin loop to process R2. X; X; Main loop processes input codes until we've filled the user's buffer. X; take 26 instructions/input code with 1 branch and 12 memory references. X; X; Optimally, each input code executes 18 instructions plus 8 instructions X; for each output byte produced. The number of branches taken is one less X; than twice the number of output bytes produced. Each input code results X; in 1 PC relative deferred, 1 register deferred, 3 indexed register deferred X; and 2 immediate data memory references. Each output byte results in X; 3 autoinc/dec, 1 byte displacement, and 2 indexed register deferred memory X; references. X; X`009.ALIGN`009LONG XOUTPUT_BYTE: X`009MOVB`009(R10)+, (R11)+`009`009; Pop byte from stack, append to output XCHECK_IF_DONE: X`009CMPL`009R11, 12(AP)`009`009; Any room left in output buffer? X`009BGEQ`009DONE`009`009`009; No, we are done X`009CMPL`009R10, AP`009`009`009; Stack empty? X`009BLSS`009OUTPUT_BYTE`009`009; No, copy to output buffer X; X; process next input code, producing result on stack. X; X`009ADDL3`009R7, R8, R0`009`009; bits-used + code_bits -> R0 X`009CMPL`009R0, R9`009`009`009; Is R0 > than number of bits in buffer X`009BGTR`009REFILL `009`009`009; Yes, do special stuff. X`009EXTZV`009R7, R8, @, R2`009; No, directly extract code. X`009MOVL`009R0, R7`009`009`009; update pointer by code_bits amount X XCHECK_CODE: X`009CMPW`009(R3)[R2], #-2`009`009; is Code a special code (prefix -2)? X`009BEQL`009SPECIAL_CODE`009`009; Yes, handle it. X`009CMPL`009R2, R5`009`009`009; Is code in table? X`009BGTR`009OUT_OF_RANGE`009`009; No, handle it. X X`009MOVL`009R2, R0`009`009`009; Yes, init loop variable to CODE X10$: X`009MOVB`009(R4)[R0], -(R10)`009; Push extension char onto stack X`009CVTWL`009(R3)[R0], R0`009`009; Replace code with prefix code X`009BGEQ`00910$`009`009`009; If another code, continue X`009`009`009`009`009; else add to table. XEXPAND_TABLE: X`009INCL`009R5`009`009`009; Bump table size. X`009CMPL`009R5, #4096`009`009; at max? X`009BGTR`00940$ `009`009`009; Yes, skip. X10$: X`009MOVW`009R6, (R3)[R5]`009`009; Prefix for previous code in new code X`009MOVB`009(R10), (R4)[R5]`009`009; Extension is last thing put on stack X`009MOVL`009R2, R6`009`009`009; new previous code. X20$: X`009CMPL`009R5, R1`009`009`009; Is table size < max for code size? X`009BLSS`009OUTPUT_BYTE`009`009; yes, leave it alone X`009CMPL`009R8, #12`009`009`009; no, is code_bits at max? X`009BGEQ`009OUTPUT_BYTE`009`009; yes, leave alone X`009INCL`009R8`009`009`009; no, go to next higher size. X`009ASHL`009R8, #1, R1`009`009; Compute new max value. X`009DECL`009R1 X`009BRB`00920$`009`009`009; test the new size. X40$: X`009MOVL`009#4096, R5`009`009; Set to dummy entry. X`009BRB`00910$ X;-------------------------- XSPECIAL_CODE: X`009CMPL`009R2, G`094EOI_CODE`009`009; Is code end of information code. X`009BEQL`009END_OF_INFORMATION X X`009CLRL`009R8`009`009`009; Reset code size X10$: X`009INCL`009R8`009`009`009; Increase size of code_bits. X`009ASHL`009R8, #1, R1`009`009; max value for code bits. X`009DECL`009R1 X`009CMPL`009G`094EOI_CODE, R1`009`009; Is table size > max value forcode_bits X`009BGEQ`00910$`009`009`009; Yes, try higher code size. X X`009MNEGL`009#1, R5`009`009`009; Flag table size for first code. X`009BRW`009CHECK_IF_DONE X;----------------------------------- X XOUT_OF_RANGE: X`009ADDL3`009R5, #1, R0`009`009; Compute table_size + 1? X`009BLEQ`009FIRST_CODE`009`009; Table size was negative. X`009CMPL`009R0, R2`009`009`009; Is code = table_size+1? X`009BNEQ`009BAD_CODE `009`009; No abort. X; V; Special case, expand previous code onto stack and place final char in front X. X`009DECL`009R10`009`009`009; Make gap on stack. X`009MOVL`009R6, R0`009`009`009; Set loop variable to prev_code X20$: X`009MOVB`009(R4)[R0], -(R10)`009; Push onto stack X`009CVTWL`009(R3)[R0], R0`009`009; Get prefix string X`009BGEQ`00920$ X`009MOVB`009(R10), G`094`009; Copy last char to front. X`009BRW`009EXPAND_TABLE`009`009; Add new code to table. X;----------------------------------- XBAD_CODE: X`009MOVL`009#20, R0`009`009`009; Bad parameter status. X`009RET XEND_OF_INFORMATION: X`009MOVL`009#2160, R0 X`009RET X;----------------------------------- XFIRST_CODE: X`009MOVL`009R2, R6`009`009`009; Update previous code. X`009MOVB`009(R4)[R2], -(R10)`009; Push onto stack X`009MOVL`009G`094EOI_CODE, R5 X`009BRW`009OUTPUT_BYTE X;----------------------------------- X; X; Define subroutine to handle getting input code when buffer spans X; boundaries. X; X; Input: X;`009R7`009Number of bits used in INBUF X;`009R8`009Code size (number of bits to extract). X;`009R9`009Number of bits in INBUF, we assume (R7+R8) > R9 X; X; Output: X;`009R0,R1`009Destroyed X;`009R2`009Code. X;`009R7`009Number of bits used in INBUF X;`009R9`009Totoal number of bits in INBUF X; XSPAN_BUFFER: X`009SUBL3`009R7, R9, R0`009`009; Calculate bits left in buffer X`009PUSHL`009R0`009`009`009; save for later use X`009EXTZV`009R7, R0, @, R2`009; Get remaining bits. X`009ADDL`009R8, R7`009`009`009; Make phantom bits-used. X50$: X`009MOVAL`009G`094INBUF, -(SP)`009`009; Output descriptor X`009MOVL`0098(AP), -(SP)`009`009; user arg for input routine X`009CALLS`009#2, @4(AP)`009`009; Get input X`009BLBC `009R0, 100$`009`009; abort if error. X`009MOVL`009(SP)+, R0`009`009; Recover # bits taken from last buffer X`009SUBL`009R9, R7`009`009`009; Number of overflow bits becomes # used X`009MOVZWL`009G`094INBUF, R9`009`009; Current # of bytes in input buffer. X`009ASHL`009#3, R9, R9`009`009; Convert to number of bits. X`009CMPL`009R9, R7`009`009`009; Is number of bits to take more X`009BLSS`009110$`009`009`009; Yes, go to special case. X`009EXTZV`009#0, R7, @, R1`009; No, extract the bits. X`009ASHL`009R0, R1, R0`009`009; Shift over by overflow amount X`009BISL`009R0, R2`009`009`009; OR into output code. X`009RSB X100$: X`009RET X; X; Handle the rare case where more bits left to extract than bits in X; buffer read. X110$: X`009EXTZV #0, R9, -`009`009`009; Extract entire buffer. X`009`009@, R1 X`009ASHL`009R0, R1, R0`009`009; Shift over X`009BISL`009R0, R2`009`009`009; Add to result X`009ADDL3`009R9, R0, -(SP)`009`009; update number of bits to shift X`009BRB `00950$`009`009`009; read another buffer. X; X`009.END $ GOSUB UNPACK_FILE $ FILE_IS = "GIFMAPF.C" $ CHECKSUM_IS = 1747466858 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X/* X * Define substitute routines for the fopen/fclose/fread/fgetc calls done by X * the gif decoder. Map the gif file to memory and access via page faults. X */ X#include stdio X#include atrdef X#include fab X#include fibdef X#include nam X#include iodef X#include secdef Xtypedef struct `123 X unsigned char *pos;`009`009/* points to next char to read */ X unsigned char *start; X unsigned char *end; X int chan, size; X`125 map_block; X Xstatic int map_block_in_use = 0; Xstatic int max_mapped = 0;`009/* largest address region used */ Xstatic unsigned char *max_region = NULL; Xstatic map_block giffile; X/* X * Open file for access. A returned size of -1 indicates error. X */ Xmap_block *gif_fopen ( Filestring ) X char *Filestring; X`123 X unsigned char *address, *inadr[2], *retadr[2]; X int size, status, channel, func_code; X int sys$assign(), sys$qiow(), sys$crmpsc(), sys$expreg(); X short int iosb[4]; X struct `123 long length; char *adr; `125 desc, fib_desc; X struct `123 X`009unsigned char rtype, rattrib; X`009unsigned short int rsize, hiblk[2], efblk[2], ffbyte; X`009unsigned char bktsize, vfcsize; X`009unsigned short int maxrec, defext, gbc, fill[4], versions; X `125 fat;`009`009`009/* File attributes block (RMS) */ X struct FAB fab;`009`009/* File access block (RMS) */ X struct NAM nam;`009`009/* Name block (RMS) */ X struct fibdef fib;`009`009/* File information block (XQP) */ X struct atrdef atr[2];`009/* Read attributes descriptor list */ X char esa[256], rsa[256];`009/* aux storage for nam block */ X X /* X * Close currently open file and init block to error status (size = -1). X */ X if ( map_block_in_use ) (void) gif_fclose(); X giffile.start = giffile.end = giffile.pos = ""; X giffile.size = -1; X X /* Use RMS services to lookup fspec, initialize FAB and NAM blocks */ X X fab = cc$rms_fab; X fab.fab$l_fna = Filestring; fab.fab$b_fns = strlen ( Filestring ); X fab.fab$l_dna = ".GIF"; fab.fab$b_dns = strlen ( fab.fab$l_dna ); X fab.fab$l_fop = FAB$M_NAM;`009/* file options */ X fab.fab$l_nam = &nam; X nam = cc$rms_nam; X nam.nam$b_ess = 255; X nam.nam$l_esa = &esa; X nam.nam$b_rss = 255; X nam.nam$l_rsa = &rsa; X V /* use $parse and $search for find file, device and FID will end up in` X032 X nam block */ X X status = sys$parse ( &fab ); if ((status&3) != 1) return &giffile; X status = sys$search ( &fab ); if ((status&3) != 1) return &giffile; X X /* Define descriptor to assign and load FID in FIB */ X X desc.length = nam.nam$t_dvi[0];`009`009/* length */ X desc.adr = &nam.nam$t_dvi[1]; X func_code = IO$_ACCESS + IO$M_ACCESS; /* actually open the file */ X fib.fib$r_fid_overlay.fib$w_fid[0] = nam.nam$w_fid[0]; X fib.fib$r_fid_overlay.fib$w_fid[1] = nam.nam$w_fid[1]; X fib.fib$r_fid_overlay.fib$w_fid[2] = nam.nam$w_fid[2]; X X /* build atrribute descriptor list for returning record attributes */ X X atr[0].atr$w_size = sizeof(fat); X atr[0].atr$w_type = ATR$C_RECATTR; X atr[0].atr$l_addr = &fat; X atr[1].atr$w_size = 0; atr[1].atr$w_type = 0; X X /* assign channel to disk specified in NAM block. */ X X channel = 0; X status = sys$assign ( &desc, &channel, 0, 0 ); X if ((status&3) != 1) return &giffile; X `032 X /* build FIB and access (open file) */ X fib_desc.length = 10; fib_desc.adr = (char *) &fib; X fib.fib$r_acctl_overlay.fib$l_acctl = 0; X status = sys$qiow`032 X`009( 0, channel, func_code, &iosb, 0, 0, &fib_desc, 0, 0, 0, &atr, 0 ); X if ( (status&1) == 1 ) status = iosb[0]; X if ( (status&1) != 1 ) return &giffile; X X /* Determine size of file and create section */ X size = fat.efblk[0]; X size = (size<<16) `124 fat.efblk[1];`009/* invert word order */ X size = (size-1)*512 + fat.ffbyte; X X /* X * Make a large region of P0 space to hold contents of file plus X * 500 blocks spare. X */ X if ( max_mapped <= size ) `123 X`009int pages; X`009pages = ((size+511)/512) + 500; X status = sys$expreg ( pages, &retadr, 0, 0 ); X if ( (status&1) != 1 ) return &giffile; X max_region = retadr[0]; X max_mapped = (pages*512) - 1; X `125 X X /* Map file into address space. */ X inadr[0] = max_region; X inadr[1] = &max_region[size-1]; X status = sys$crmpsc ( &inadr, &retadr, 0, 0, 0, 0, 0, X`009`009channel, (size+511)/512, 0, 0, 64 ); X if ( (status&1) != 1 ) return &giffile; X address = retadr[0]; X map_block_in_use = 1; X X /* X * Allocate structure to store file state and initialize it. X */ X giffile.start = address; X giffile.end = &address[size]; X giffile.pos = address; X giffile.chan = channel; X giffile.size = size; X return &giffile; X`125 X Xint gif_fclose ( ) X`123 X void sys$dassgn(); V if ( map_block_in_use && (giffile.size > 0) ) sys$purgws ( &giffile.start X ); X map_block_in_use = 0; X sys$dassgn ( giffile.chan ); X return 0;`032 X`125 X Xint gif_fgetc ( ) X`123 X int result; X if ( giffile.pos >= giffile.end ) return -1; X result = *giffile.pos++; X return result; X`125 X Xint gif_fread ( buffer, unit, count ) X unsigned char *buffer; X unsigned int unit, count;`009/* max count is 65535 */ X`123 X unsigned char *next_pos; X /* determin number of charaters to move */ X count *= unit; X if ( giffile.pos >= giffile.end ) return 0; X next_pos = &giffile.pos[count]; X while ( next_pos >= giffile.end ) next_pos = &giffile.pos[--count]; X X LIB$MOVC3 ( &count, giffile.pos, buffer ); X giffile.pos = next_pos; X return count; X`125 X Xunsigned char *gif_freadm ( unit, count ) X unsigned int unit, count;`009/* max count is 65535 */ X`123 X unsigned char *cur_pos, *next_pos; X /* determin number of charaters to move */ X count *= unit; X if ( giffile.pos >= giffile.end ) return NULL; X cur_pos = giffile.pos; X next_pos = &cur_pos[count]; X while ( next_pos >= giffile.end ) --next_pos; X giffile.pos = next_pos; X return cur_pos; X`125 X Xint gif_fget_counted ( map, desc ) X map_block *map; X struct `123 int len; char *addr; `125 *desc; X`123 X int length; X if ( map->pos < map->end ) `123 X`009/* Get length of record and truncate to EOF if needed */ X`009for ( length = *map->pos++; &map->pos[length] > map->end; --length); X X`009/* fill out descriptor and update position pointer */ X`009desc->len = length; X`009desc->addr = map->pos; X`009map->pos = &map->pos[length]; X`009return 1; X `125 X return 2160; X`125 $ GOSUB UNPACK_FILE $ EXIT