Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v05i026: xgifroot - use gif images to set root background, Part01/01

25 views
Skip to first unread message

Dan Heller

unread,
Nov 12, 1989, 2:34:08 PM11/12/89
to
Submitted-by: mcdre3.INTEL.COM!bpaauwe (B.Paauwe)
Posting-number: Volume 5, Issue 26
Archive-name: xgifroot/part01

[ Moderator's note: I didn't test this program. --dan ]

This is a program that will display GIF images as the root window. It
resizes the images to fill the display. It was written under X11R2 but
should work for X11R3. I got a lot of the code from the xgif program
so it handles GIF images the same way that does.

Bob Paauwe bpa...@mcdre3.intel.com


#!/bin/sh
# shar: Shell Archiver (v1.22)
#
# Run the following text with /bin/sh to create:
# AUTHOR
# Makefile
# README
# patchlevel.h
# xgif.h
# xgifload.c
# xgifroot.c
# xgifroot.man
#
sed 's/^X//' << 'SHAR_EOF' > AUTHOR &&
XWritten by Bob Paauwe (bpa...@mcdre3.intel.com)
X
XDo whatever you want with this program, though it *would* be nice if my name
Xremained on it somewhere... Other than that, it may be freely modified,
Xdistributed, and used to fill up disk space.
X
X--bp
SHAR_EOF
chmod 0644 AUTHOR || echo "restore of AUTHOR fails"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
XOBJS = xgifroot.o xgifload.o
XCFLAGS= -O -I/usr/X/include
XLDFLAGS= -s
XLIBS= -L/usr/X/lib -lXaw -lXt -lX11_s -lc_s -lnsl_s -lpt
X
Xxgifroot: $(OBJS)
X $(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o xgifroot
SHAR_EOF
chmod 0644 Makefile || echo "restore of Makefile fails"
sed 's/^X//' << 'SHAR_EOF' > README &&
Xxgifroot is a program that converts GIF images to a X11 root window
Xbackground. Sort of like xsetroot & xphoon. It is based on the xgif
Xprogram written by John Bradley. All I did was remove the code to
Xcreate a window and add some code to put the image in the root window
Xbackground. The image is resized to fit the display and the number
Xof color planes is reduced if needed.
X
XBob Paauwe - bpa...@mcdre3.intel.com
X
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
X#define PATCHLEVEL 1
SHAR_EOF
chmod 0644 patchlevel.h || echo "restore of patchlevel.h fails"
sed 's/^X//' << 'SHAR_EOF' > xgif.h &&
X/*
X * xgif.h - header file for xgif, but you probably already knew as much
X */
X
X
X#define REVDATE "Rev: 2/13/89"
X#define MAXEXPAND 16
X
X/* include files */
X#include <stdio.h>
X#include <math.h>
X#include <ctype.h>
X#include <signal.h>
X
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X
X
X#ifndef MAIN
X#define WHERE extern
X#else
X#define WHERE
X#endif
X
Xtypedef unsigned char byte;
X
X#define CENTERX(f,x,str) ((x)-XTextWidth(f,str,strlen(str))/2)
X#define CENTERY(f,y) ((y)-((f->ascent+f->descent)/2)+f->ascent)
X
X
X/* X stuff */
XWHERE Display *theDisp;
XWHERE int theScreen, dispcells;
XWHERE Colormap theCmap;
XWHERE Window rootW, mainW;
XWHERE XWindowAttributes mainWattributes;
XWHERE GC theGC;
XWHERE unsigned long fcol,bcol;
XWHERE Font mfont;
XWHERE XFontStruct *mfinfo;
XWHERE Visual *theVisual;
XWHERE XImage *theImage, *expImage, *dispImage;
X
X/* global vars */
XWHERE int iWIDE,iHIGH,eWIDE,eHIGH,expand,numcols,strip,nostrip;
XWHERE int pausetime;
XWHERE unsigned long cols[256];
XWHERE XColor defs[256];
XWHERE char *cmd;
SHAR_EOF
chmod 0644 xgif.h || echo "restore of xgif.h fails"
sed 's/^X//' << 'SHAR_EOF' > xgifload.c &&
X/*
X * xgifload.c - based strongly on...
X *
X * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
X *
X * Copyright (c) 1988, 1989 by Patrick J. Naughton
X *
X * Author: Patrick J. Naughton
X * naug...@wind.sun.com
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation.
X *
X * This file is provided AS IS with no warranties of any kind. The author
X * shall have no liability with respect to the infringement of copyrights,
X * trade secrets or any patents by this file or any part thereof. In no
X * event will the author be liable for any lost revenue or profits or
X * other special, indirect and consequential damages.
X *
X */
X
X#include "xgif.h"
X
Xtypedef int boolean;
X
X#define NEXTBYTE (*ptr++)
X#define IMAGESEP 0x2c
X#define INTERLACEMASK 0x40
X#define COLORMAPMASK 0x80
X
XFILE *fp;
X
Xint BitOffset = 0, /* Bit Offset of next code */
X XC = 0, YC = 0, /* Output X and Y coords of current pixel */
X Pass = 0, /* Used by output routine if interlaced pic */
X OutCount = 0, /* Decompressor output 'stack count' */
X RWidth, RHeight, /* screen dimensions */
X Width, Height, /* image dimensions */
X LeftOfs, TopOfs, /* image offset */
X BitsPerPixel, /* Bits per pixel, read from GIF header */
X BytesPerScanline, /* bytes per scanline in output raster */
X ColorMapSize, /* number of colors */
X Background, /* background color */
X CodeSize, /* Code size, read from GIF header */
X InitCodeSize, /* Starting code size, used during Clear */
X Code, /* Value returned by ReadCode */
X MaxCode, /* limiting value for current code size */
X ClearCode, /* GIF clear code */
X EOFCode, /* GIF end-of-information code */
X CurCode, OldCode, InCode, /* Decompressor variables */
X FirstFree, /* First free code, generated per GIF spec */
X FreeCode, /* Decompressor, next free slot in hash table */
X FinChar, /* Decompressor variable */
X BitMask, /* AND mask for data size */
X ReadMask; /* Code AND mask for current code size */
X
Xboolean Interlace, HasColormap;
Xboolean Verbose = False;
X
Xbyte *Image; /* The result array */
Xbyte *RawGIF; /* The heap array to hold it, raw */
Xbyte *Raster; /* The raster data stream, unblocked */
X
X /* The hash table used by the decompressor */
Xint Prefix[4096];
Xint Suffix[4096];
X
X /* An output array used by the decompressor */
Xint OutCode[1025];
X
X /* The color map, read from the GIF header */
Xbyte Red[256], Green[256], Blue[256], used[256];
Xint numused;
X
Xchar *id = "GIF87a";
X
X
X
X/*****************************/
XLoadGIF(fname)
X char *fname;
X/*****************************/
X{
X int filesize;
X register byte ch, ch1;
X register byte *ptr, *ptr1;
X register int i;
X
X if (strcmp(fname,"-")==0) { fp = stdin; fname = "<stdin>"; }
X else fp = fopen(fname,"r");
X
X if (!fp) FatalError("file not found");
X
X /* find the size of the file */
X fseek(fp, 0L, 2);
X filesize = ftell(fp);
X fseek(fp, 0L, 0);
X
X if (!(ptr = RawGIF = (byte *) malloc(filesize)))
X FatalError("not enough memory to read gif file");
X
X if (!(Raster = (byte *) malloc(filesize)))
X FatalError("not enough memory to read gif file");
X
X if (fread(ptr, filesize, 1, fp) != 1)
X FatalError("GIF data read failed");
X
X if (strncmp(ptr, id, 6))
X FatalError("not a GIF file");
X
X ptr += 6;
X
X/* Get variables from the GIF screen descriptor */
X
X ch = NEXTBYTE;
X RWidth = ch + 0x100 * NEXTBYTE; /* screen dimensions... not used. */
X ch = NEXTBYTE;
X RHeight = ch + 0x100 * NEXTBYTE;
X
X if (Verbose)
X fprintf(stderr, "screen dims: %dx%d.\n", RWidth, RHeight);
X
X ch = NEXTBYTE;
X HasColormap = ((ch & COLORMAPMASK) ? True : False);
X
X BitsPerPixel = (ch & 7) + 1;
X numcols = ColorMapSize = 1 << BitsPerPixel;
X BitMask = ColorMapSize - 1;
X
X Background = NEXTBYTE; /* background color... not used. */
X
X if (NEXTBYTE) /* supposed to be NULL */
X FatalError("corrupt GIF file (bad screen descriptor)");
X
X
X/* Read in global colormap. */
X
X if (HasColormap) {
X if (Verbose)
X fprintf(stderr, "%s is %dx%d, %d bits per pixel, (%d colors).\n",
X fname, Width,Height,BitsPerPixel, ColorMapSize);
X for (i = 0; i < ColorMapSize; i++) {
X Red[i] = NEXTBYTE;
X Green[i] = NEXTBYTE;
X Blue[i] = NEXTBYTE;
X used[i] = 0;
X }
X numused = 0;
X
X }
X
X else { /* no colormap in GIF file */
X fprintf(stderr,"%s: warning! no colortable in this file. Winging it.\n",cmd);
X if (!numcols) numcols=256;
X for (i=0; i<numcols; i++) cols[i] = (unsigned long) i;
X }
X
X/* Check for image seperator */
X
X if (NEXTBYTE != IMAGESEP)
X FatalError("corrupt GIF file (no image separator)");
X
X/* Now read in values from the image descriptor */
X
X ch = NEXTBYTE;
X LeftOfs = ch + 0x100 * NEXTBYTE;
X ch = NEXTBYTE;
X TopOfs = ch + 0x100 * NEXTBYTE;
X ch = NEXTBYTE;
X Width = ch + 0x100 * NEXTBYTE;
X ch = NEXTBYTE;
X Height = ch + 0x100 * NEXTBYTE;
X Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
X
X if (Verbose)
X fprintf(stderr, "Reading a %d by %d %sinterlaced image...",
X Width, Height, (Interlace) ? "" : "non-");
X
X else
X fprintf(stderr, "%s: %s is %dx%d, %d colors ",
X cmd, fname, Width,Height,ColorMapSize);
X
X
X/* Note that I ignore the possible existence of a local color map.
X * I'm told there aren't many files around that use them, and the spec
X * says it's defined for future use. This could lead to an error
X * reading some files.
X */
X
X/* Start reading the raster data. First we get the intial code size
X * and compute decompressor constant values, based on this code size.
X */
X
X CodeSize = NEXTBYTE;
X ClearCode = (1 << CodeSize);
X EOFCode = ClearCode + 1;
X FreeCode = FirstFree = ClearCode + 2;
X
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
X CodeSize++;
X InitCodeSize = CodeSize;
X MaxCode = (1 << CodeSize);
X ReadMask = MaxCode - 1;
X
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
X ptr1 = Raster;
X do {
X ch = ch1 = NEXTBYTE;
X while (ch--) *ptr1++ = NEXTBYTE;
X if ((Raster - ptr1) > filesize)
X FatalError("corrupt GIF file (unblock)");
X } while(ch1);
X
X free(RawGIF); /* We're done with the raw data now... */
X
X if (Verbose) {
X fprintf(stderr, "done.\n");
X fprintf(stderr, "Decompressing...");
X }
X
X
X/* Allocate the X Image */
X Image = (byte *) malloc(Width*Height);
X if (!Image) FatalError("not enough memory for XImage");
X
X theImage = XCreateImage(theDisp,theVisual,8,ZPixmap,0,Image,
X Width,Height,8,Width);
X if (!theImage) FatalError("unable to create XImage");
X
X BytesPerScanline = Width;
X
X
X/* Decompress the file, continuing until you see the GIF EOF code.
X * One obvious enhancement is to add checking for corrupt files here.
X */
X
X Code = ReadCode();
X while (Code != EOFCode) {
X
X/* Clear code sets everything back to its initial value, then reads the
X * immediately subsequent code as uncompressed data.
X */
X
X if (Code == ClearCode) {
X CodeSize = InitCodeSize;
X MaxCode = (1 << CodeSize);
X ReadMask = MaxCode - 1;
X FreeCode = FirstFree;
X CurCode = OldCode = Code = ReadCode();
X FinChar = CurCode & BitMask;
X AddToPixel(FinChar);
X }
X else {
X
X/* If not a clear code, then must be data: save same as CurCode and InCode */
X
X CurCode = InCode = Code;
X
X/* If greater or equal to FreeCode, not in the hash table yet;
X * repeat the last character decoded
X */
X
X if (CurCode >= FreeCode) {
X CurCode = OldCode;
X OutCode[OutCount++] = FinChar;
X }
X
X/* Unless this code is raw data, pursue the chain pointed to by CurCode
X * through the hash table to its end; each code in the chain puts its
X * associated output code on the output queue.
X */
X
X while (CurCode > BitMask) {
X if (OutCount > 1024) {
X fprintf(stderr,"\nCorrupt GIF file (OutCount)!\n");
X _exit(-1); /* calling 'exit(-1)' dumps core, so I don't */
X }
X OutCode[OutCount++] = Suffix[CurCode];
X CurCode = Prefix[CurCode];
X }
X
X/* The last code in the chain is treated as raw data. */
X
X FinChar = CurCode & BitMask;
X OutCode[OutCount++] = FinChar;
X
X/* Now we put the data out to the Output routine.
X * It's been stacked LIFO, so deal with it that way...
X */
X
X for (i = OutCount - 1; i >= 0; i--)
X AddToPixel(OutCode[i]);
X OutCount = 0;
X
X/* Build the hash table on-the-fly. No table is stored in the file. */
X
X Prefix[FreeCode] = OldCode;
X Suffix[FreeCode] = FinChar;
X OldCode = InCode;
X
X/* Point to the next slot in the table. If we exceed the current
X * MaxCode value, increment the code size unless it's already 12. If it
X * is, do nothing: the next code decompressed better be CLEAR
X */
X
X FreeCode++;
X if (FreeCode >= MaxCode) {
X if (CodeSize < 12) {
X CodeSize++;
X MaxCode *= 2;
X ReadMask = (1 << CodeSize) - 1;
X }
X }
X }
X Code = ReadCode();
X }
X
X free(Raster);
X
X if (Verbose)
X fprintf(stderr, "done.\n");
X else
X fprintf(stderr,"(of which %d are used)\n",numused);
X
X if (fp != stdin)
X fclose(fp);
X
X ColorDicking(fname);
X}
X
X
X/* Fetch the next code from the raster data stream. The codes can be
X * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
X * maintain our location in the Raster array as a BIT Offset. We compute
X * the byte Offset into the raster array by dividing this by 8, pick up
X * three bytes, compute the bit Offset into our 24-bit chunk, shift to
X * bring the desired code to the bottom, then mask it off and return it.
X */
XReadCode()
X{
Xint RawCode, ByteOffset;
X
X ByteOffset = BitOffset / 8;
X RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
X if (CodeSize >= 8)
X RawCode += (0x10000 * Raster[ByteOffset + 2]);
X RawCode >>= (BitOffset % 8);
X BitOffset += CodeSize;
X return(RawCode & ReadMask);
X}
X
X
XAddToPixel(Index)
Xbyte Index;
X{
X if (YC<Height)
X *(Image + YC * BytesPerScanline + XC) = Index;
X
X if (!used[Index]) { used[Index]=1; numused++; }
X
X/* Update the X-coordinate, and if it overflows, update the Y-coordinate */
X
X if (++XC == Width) {
X
X/* If a non-interlaced picture, just increment YC to the next scan line.
X * If it's interlaced, deal with the interlace as described in the GIF
X * spec. Put the decoded scan line out to the screen if we haven't gone
X * past the bottom of it
X */
X
X XC = 0;
X if (!Interlace) YC++;
X else {
X switch (Pass) {
X case 0:
X YC += 8;
X if (YC >= Height) {
X Pass++;
X YC = 4;
X }
X break;
X case 1:
X YC += 8;
X if (YC >= Height) {
X Pass++;
X YC = 2;
X }
X break;
X case 2:
X YC += 4;
X if (YC >= Height) {
X Pass++;
X YC = 1;
X }
X break;
X case 3:
X YC += 2;
X break;
X default:
X break;
X }
X }
X }
X}
X
X
X
X/*************************/
XColorDicking(fname)
Xchar *fname;
X{
X /* we've got the picture loaded, we know what colors are needed. get 'em */
X
X register int i,j;
X static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
X byte lmask, *ptr;
X
X
X if (!HasColormap) return;
X /* no need to allocate any colors if no colormap in GIF file */
X
X /* Allocate the X colors for this picture */
X
X if (nostrip) { /* nostrip was set. try REAL hard to do it */
X for (i=j=0; i<numcols; i++) {
X if (used[i]) {
X defs[i].red = Red[i]<<8;
X defs[i].green = Green[i]<<8;
X defs[i].blue = Blue[i]<<8;
X defs[i].flags = DoRed | DoGreen | DoBlue;
X if (!XAllocColor(theDisp,theCmap,&defs[i])) {
X j++; defs[i].pixel = 0xffff;
X }
X cols[i] = defs[i].pixel;
X }
X }
X
X if (j) { /* failed to pull it off */
X XColor ctab[256];
X int dc;
X
X dc = (dispcells<256) ? dispcells : 256;
X
X fprintf(stderr,"failed to allocate %d out of %d colors. Trying extra hard.\n",j,numused);
X
X /* read in the color table */
X for (i=0; i<dc; i++) ctab[i].pixel = i;
X XQueryColors(theDisp,theCmap,ctab,dc);
X
X /* run through the used colors. any used color that has a pixel
X value of 0xffff wasn't allocated. for such colors, run through
X the entire X colormap and pick the closest color */
X
X for (i=0; i<numcols; i++)
X if (used[i] && cols[i]==0xffff) { /* an unallocated pixel */
X int d, mdist, close;
X unsigned long r,g,b;
X
X mdist = 100000; close = -1;
X r = Red[i];
X g = Green[i];
X b = Blue[i];
X for (j=0; j<dc; j++) {
X d = abs(r - (ctab[j].red>>8)) +
X abs(g - (ctab[j].green>>8)) +
X abs(b - (ctab[j].blue>>8));
X if (d<mdist) { mdist=d; close=j; }
X }
X if (close<0) FatalError("simply can't do it. Sorry.");
X bcopy(&defs[close],&defs[i],sizeof(XColor));
X cols[i] = ctab[close].pixel;
X }
X } /* end 'failed to pull it off' */
X }
X
X else { /* strip wasn't set, do the best auto-strip */
X j = 0;
X while (strip<8) {
X lmask = lmasks[strip];
X for (i=0; i<numcols; i++)
X if (used[i]) {
X defs[i].red = (Red[i] &lmask)<<8;
X defs[i].green = (Green[i]&lmask)<<8;
X defs[i].blue = (Blue[i] &lmask)<<8;
X defs[i].flags = DoRed | DoGreen | DoBlue;
X if (!XAllocColor(theDisp,theCmap,&defs[i])) break;
X cols[i] = defs[i].pixel;
X }
X
X if (i<numcols) { /* failed */
X strip++; j++;
X for (i--; i>=0; i--)
X if (used[i]) XFreeColors(theDisp,theCmap,cols+i,1,0L);
X }
X else break;
X }
X
X if (j && strip<8)
X fprintf(stderr,"%s: %s stripped %d bits\n",cmd,fname,strip);
X
X if (strip==8) {
X fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n");
X for (i=0; i<numcols; i++) cols[i]=i;
X }
X }
X
X ptr = Image;
X for (i=0; i<Height; i++)
X for (j=0; j<Width; j++,ptr++)
X *ptr = (byte) cols[*ptr];
X}
SHAR_EOF
chmod 0644 xgifload.c || echo "restore of xgifload.c fails"
sed 's/^X//' << 'SHAR_EOF' > xgifroot.c &&
X/*
X * xgifroot.c - displays GIF pictures on an X11 root window
X *
X * Author: Bob Paauwe, Intel Corp. (bpa...@mcdre3.intel.com)
X *
X * This is a hacked version of John Bradley's xgif program. I
X * removed all the stuff to display the image in a window and added
X * the code to make it become the root window background. All the
X * code for reading and converting the GIF image is John's
X *
X * xgif: John Bradly, University of Pennsylvania (bra...@cis.upenn.edu)
X */
X
X#define MAIN
X#include <X11/Xatom.h>
X#include "xgif.h"
X
X
X/*******************************************/
Xmain(argc, argv)
X int argc;
X char *argv[];
X/*******************************************/
X{
X int i;
X char *display, *geom, *fname;
X XEvent event;
X
X cmd = argv[0];
X display = geom = fname = NULL;
X expImage = NULL;
X dispImage = NULL;
X
X expand = 1; strip = 0; nostrip = 0;
X pausetime = 0;
X
X /*********************Options*********************/
X
X for (i = 1; i < argc; i++) {
X char *strind;
X
X if (!strncmp(argv[i],"-d",2)) { /* display */
X i++;
X display = argv[i];
X continue;
X }
X
X strind = index(argv[i], ':'); /* old-style display */
X if(strind != NULL) {
X display = argv[i];
X continue;
X }
X
X if (argv[i][0] != '-') { /* the file name */
X fname = argv[i];
X continue;
X }
X
X Syntax(cmd);
X }
X
X if (fname==NULL) fname="-";
X
X /*****************************************************/
X
X /* Open up the display. */
X
X if ( (theDisp=XOpenDisplay(display)) == NULL) {
X fprintf(stderr, "%s: Can't open display\n",argv[0]);
X exit(1);
X }
X
X theScreen = DefaultScreen(theDisp);
X theCmap = DefaultColormap(theDisp, theScreen);
X rootW = RootWindow(theDisp,theScreen);
X theGC = DefaultGC(theDisp,theScreen);
X fcol = WhitePixel(theDisp,theScreen);
X bcol = BlackPixel(theDisp,theScreen);
X theVisual = DefaultVisual(theDisp,theScreen);
X
X dispcells = DisplayCells(theDisp, theScreen);
X if (dispcells<=2)
X FatalError("This program requires a color display, pref. 8 bits.");
X
X
X /****************** Open/Read the File *****************/
X LoadGIF(fname);
X iWIDE = theImage->width; iHIGH = theImage->height;
X
X eWIDE = DisplayWidth(theDisp,theScreen);
X eHIGH = DisplayHeight(theDisp,theScreen);
X
X /**************** Draw image *****************/
X Resize(eWIDE,eHIGH);
X DrawWindow ( 0, 0, eWIDE, eHIGH );
X}
X
X
X
X
X/***********************************/
XSyntax()
X{
X printf("Usage: %s filename [[-display] display]\n",cmd);
X exit(1);
X}
X
X
X/***********************************/
XFatalError (identifier)
X char *identifier;
X{
X fprintf(stderr, "%s: %s\n",cmd, identifier);
X exit(-1);
X}
X
X
X/***********************************/
XQuit()
X{
X exit(0);
X}
X
X
X/***********************************/
XDrawWindow(x,y,w,h)
X{
X Pixmap pic;
X GC gc;
X XGCValues gcv;
X Atom prop, type;
X unsigned char *data;
X unsigned long length, after;
X int format;
X
X CheckDepth();
X gcv.foreground = BlackPixel( theDisp, theScreen );
X gcv.background = WhitePixel( theDisp, theScreen );
X gc = XCreateGC ( theDisp, rootW, GCForeground|GCBackground, &gcv );
X pic = XCreatePixmap ( theDisp, rootW, w, h, DefaultDepth(theDisp, theScreen));
X
X if (pic == 0) {
X fprintf(stderr, "%s: Unable to create Pixmap", cmd);
X exit(1);
X }
X
X XPutImage(theDisp,pic,gc,expImage,x,y,x,y,w,h);
X XPutImage(theDisp,rootW,gc,expImage,x,y,x,y,w,h);
X XSetWindowBackgroundPixmap(theDisp, rootW, pic);
X XFreeGC(theDisp, gc);
X XFreePixmap(theDisp, pic);
X XClearWindow(theDisp, rootW);
X XFlush(theDisp);
X
X prop = XInternAtom ( theDisp, "_XSETROOT_ID", False );
X (void) XGetWindowProperty ( theDisp, rootW, prop, 0L, 1L, True,
X AnyPropertyType, &type, &format, &length, &after, &data );
X if ((type == XA_PIXMAP) && (format == 32) && (length == 1 ) &&
X (after == 0) )
X XKillClient ( theDisp, *((Pixmap *)data) );
X XFlush ( theDisp );
X
X}
X
X
X/***********************************/
X/* This makes sure the display's depth is the same as the
X * depth of the default 8 bit image. If not, we build a new image
X * that has the correct depth. This works on the fact that
X * the color mapper has already changed every pixel value in the
X * image into the proper number of bits (to fit into the pallet)
X * so we can just chop down the number of bits.
X * This changes the global variable 'expImage' if necessary.
X */
XCheckDepth()
X{
X register byte *sptr, *dptr;
X register unsigned int pixval;
X register int dwx, dwy;
X byte *ximag;
X
X if (expImage->depth != DefaultDepth(theDisp, theScreen) ) {
X dispImage = expImage;
X ximag = (byte *) malloc(eWIDE*eHIGH);
X expImage = XCreateImage(theDisp,theVisual,DefaultDepth(theDisp, theScreen),
X ZPixmap,0,ximag,eWIDE,eHIGH,8,0);
X if (dispImage->depth == 8 && expImage->depth == 4) {
X /* speedup for the most common format change */
X dptr = (byte *)expImage->data;
X sptr = (byte *)dispImage->data;
X for (dwy=1; dwy<=eHIGH; dwy++) {
X for (dwx=1; dwx<eWIDE; dwx+=2) {
X *dptr = (*sptr) | (*(sptr+1)<<4);
X dptr++;
X sptr+=2;
X }
X if (eWIDE & 1) {
X /* if extra pixal at end of line, just move it */
X *dptr = *sptr;
X sptr++; dptr++;
X }
X }
X }
X else {
X for (dwx=0; dwx<eWIDE; dwx++) {
X for (dwy=0; dwy<eHIGH; dwy++) {
X pixval = XGetPixel(dispImage, dwx, dwy);
X (void) XPutPixel(expImage, dwx, dwy, pixval);
X }
X }
X if (dispImage != theImage) {
X free(dispImage->data);
X dispImage->data = NULL;
X XDestroyImage(dispImage);
X }
X }
X }
X}
X
X/***********************************/
XResize(w,h)
Xint w,h;
X{
X int ix,iy,ex,ey;
X byte *ximag,*ilptr,*ipptr,*elptr,*epptr;
X static char *rstr = "Resizing Image. Please wait...";
X
X /* warning: this code'll only run machines where int=32-bits */
X
X if (w==iWIDE && h==iHIGH) { /* very special case */
X if (expImage != theImage) {
X if (expImage) XDestroyImage(expImage);
X expImage = theImage;
X eWIDE = iWIDE; eHIGH = iHIGH;
X }
X }
X
X else { /* have to do some work */
X /* if it's a big image, this'll take a while. mention it */
X if (w*h>(500*500)) {
X printf ( "%s\n", rstr );
X }
X
X /* first, kill the old expImage, if one exists */
X if (expImage && expImage != theImage) {
X free(expImage->data); expImage->data = NULL;
X XDestroyImage(expImage);
X }
X
X /* create expImage of the appropriate size */
X
X eWIDE = w; eHIGH = h;
X ximag = (byte *) malloc(w*h);
X expImage = XCreateImage(theDisp,theVisual,8,ZPixmap,0,ximag,
X eWIDE,eHIGH,8,eWIDE);
X
X if (!ximag || !expImage) {
X fprintf(stderr,"ERROR: unable to create a %dx%d image\n",w,h);
X exit(0);
X }
X
X elptr = epptr = (byte *) expImage->data;
X
X for (ey=0; ey<eHIGH; ey++, elptr+=eWIDE) {
X iy = (iHIGH * ey) / eHIGH;
X epptr = elptr;
X ilptr = (byte *) theImage->data + (iy * iWIDE);
X for (ex=0; ex<eWIDE; ex++,epptr++) {
X ix = (iWIDE * ex) / eWIDE;
X ipptr = ilptr + ix;
X *epptr = *ipptr;
X }
X }
X }
X}
X
SHAR_EOF
chmod 0644 xgifroot.c || echo "restore of xgifroot.c fails"
sed 's/^X//' << 'SHAR_EOF' > xgifroot.man &&
X.TH xgifroot 1X
X.SH NAME
Xxgif \- displays GIF (*) pictures on the X11 root window
X.SH SYNTAX
X\fBxgifroot\fP [\fIdisplay\fP] [\fIfilename\fP]
X.SH DESCRIPTION
X\fBxgifroot\fP is an X11 program that converts GIF pictures to the root
Xwindow background (a la xsetroot).
X.PP
XThe program will make it's best guess at the colors and adjust the number
Xof planes to match the display. It will also resize the image to fill the
XX11 root window.
X.SH OPTIONS
XThere are only two options. \fIdisplay\fP selects the display to use
Xand \fIfilename\fP to select the GIF file to display. If \fIfilename\fP
Xis not supplied, the program will read the picture from stdin.
X.SH LIMITATIONS
XYou'll require (at least) an 8-plane X11 display. This program
Xignores 'local colormaps' in GIF files (see the GIF spec for details).
XIt also only displays the first image in GIF files that have multiple
Ximages in them.
X.PP
XNote: This program points out a bug in the X11R2 server for the IBM RT
XMegapel display. This bug will occasionally cause the colors in a picture
Xto be wrong, but no 'unable to allocate' message will be printed by the
Xprogram. (Essentially, the problem is a discrepancy between what the
Xserver THINKS the colormap is, and what the colormap in the hardware
XACTUALLY is.)
X.PP
X.SH AUTHOR
XBob Paauwe - bpa...@mcdre3.intel.com
X.PP
XBased (heavily) on xgif.c, by John Bradley (bra...@cis.upenn.edu),
Xa program that displays GIF pictures on a X11 display. All of the routines
Xto read and convert GIF images are directly from xgif.c.
X.PP
XBased (heavily) on gif2ras.c, by Patrick J. Naughton (naug...@wind.sun.com),
Xa program that converts GIF pictures to Sun Rasterfiles.
X.PP
X(*) GIF is a no doubt a trademark of CompuServe, so watch it!
X.PP
X.SH SEE ALSO
Xxgif (1X), xsetroot
SHAR_EOF
chmod 0644 xgifroot.man || echo "restore of xgifroot.man fails"
exit 0
--
Bob Paauwe ________________________ Any resemblence to a
bpa...@mcdre3.intel.com | REAL opinion is unintentional.
/-----------------___________________/---\___________________-----------------\
!ames!pacbell!sactoh0!mcdre3!bpaauwe \___/ I'd rather be Gliding!!!!!

0 new messages