/* w1gif.c capture pixels and write w1gif.gif */ #include #include #include #include #include #ifdef XBITS long int background = 0xFFFF; /* user must use white background 16 bit */ /* 0xffff on PC, FFFFFF on Sun */ #else long int background = 0xFFFFFF; /* user must use white background 24 bit */ #endif static void doInitialize(void); /* function prototypes used below */ static void doCreateWindows(void); static void doCreateGraphicsContext(void); static void doExpose(XEvent *eventP); static void doHandleEvents(void); static void write_gif_file(char filename[]); static void write_gif_data(unsigned char datablk[], unsigned char *byte_count, int * nbit, FILE * FpGif); /* just w1.c pasted in here to put some bits on the screen */ Display *dpy; Window window1; GC gc; Screen *screen; int frame_xmax = 199; /* capture area, must be visible */ int frame_xmin = 1; int frame_ymax = 99; int frame_ymin = 1; /********************** The main program *******************************/ int main(int argc, char *argv[]) { doInitialize(); doHandleEvents(); /* this never returns */ return 0; } /***************** doInitialize **************************/ static void doInitialize(void) { dpy = XOpenDisplay(0); if (!dpy){ printf("Display not opened!\n"); exit(1); } screen = XDefaultScreenOfDisplay(dpy); doCreateWindows(); doCreateGraphicsContext(); XStoreName(dpy, window1, "W1 click to exit"); XMapWindow(dpy, window1); } /******* doCreateWindows *********/ static void doCreateWindows(void) { int window1X = 300; int window1Y = 200; int window1W = 200; int window1H = 100; XSetWindowAttributes xswa; /* Create the window1 window */ xswa.event_mask = ExposureMask | ButtonPressMask; xswa.background_pixel = XWhitePixelOfScreen(screen); window1 = XCreateWindow(dpy, XRootWindowOfScreen(screen), window1X, window1Y, window1W, window1H, 0, XDefaultDepthOfScreen(screen), InputOutput, XDefaultVisualOfScreen(screen), CWEventMask | CWBackPixel, &xswa); } /******** Create the graphics context *********/ static void doCreateGraphicsContext(void) { XGCValues xgcv; /* Create graphics context. */ xgcv.background = XWhitePixelOfScreen(screen); xgcv.foreground = XBlackPixelOfScreen(screen); gc = XCreateGC(dpy, window1, GCForeground | GCBackground, &xgcv); } /****************** doHandleEvents ***********************/ static void doHandleEvents(void) { XEvent event; for ( ; ; ) { XNextEvent(dpy, &event); switch (event.type) { case Expose: doExpose(&event); break; case ButtonPress: /* added write .gif file here */ write_gif_file("w1gif.gif"); exit(0); /* shut down */ } } } /***** draw and write the message in the window *****/ static void doExpose(XEvent *eventP) { static char message[] = {"Click here to exit"}; /* If this is an expose event on our window1 window, then write the text and rectangle. */ if (eventP->xexpose.window != window1) return; XClearWindow(dpy, window1); XDrawImageString(dpy, window1, gc, 50, 25, message, strlen(message)); XDrawRectangle(dpy, window1, gc, 50, 50, 100, 25); } /* end old w1.c */ static void write_gif_file(char filename[]) { /* frame_xmin, ... needed first */ FILE * FpGif; int i, j, this_bit; long int my_pixel; XImage * my_image; unsigned char byte_count; unsigned char datablk[1280]; /* [257] */ int nbit; int dbit, jbit; int dbyte; int ncode = 3; /* smallest for 1 bit */ int width, height; /* from frame */ int xoffs, yoffs; /* from frame */ unsigned char head[13]={ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00}; /* head[6]=low width, head[7]=high width, head[8]=low height, head[9]=high height */ unsigned char coltab[6]= {0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF}; unsigned char imgblk[11]= {0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}; /* imgblk[5]=low width, imgblk[6]=high width, imgblk[7]=low height, imgblk[8]=high height */ printf("gif_out stating to write %s \n", filename); FpGif=fopen(filename,"wb"); if(FpGif==NULL) { printf("could not open %s for write\n", filename); return; } width = frame_xmax-frame_xmin-1; /* omit frame line */ height = frame_ymax-frame_ymin-1; my_image = XGetImage(dpy, window1, frame_xmin+1, frame_ymin+1, frame_xmax-frame_xmin-1, frame_ymax-frame_ymin-1, 0xFFFFFF, XYPixmap); if(my_image == NULL) { printf("can't get my_image\n"); fclose(FpGif); return; } head[6]=width&0xFF; head[7]=width>>8; head[8]=height&0xFF; head[9]=height>>8; for(i=0; i<13; i++) putc(head[i], FpGif); /* header */ for(i=0; i<6; i++) putc(coltab[i], FpGif); /* color table */ imgblk[5]=width&0xFF; imgblk[6]=width>>8; imgblk[7]=height&0xFF; imgblk[8]=height>>8; for(i=0; i<11; i++) putc(imgblk[i], FpGif); /* image desc */ /* read pixels and do non LZW encode */ /* pack bits in datablk */ for(i=0; i<1280; i++)datablk[i]=0; /* zero image data */ nbit = 0; for(i=0; i7) datablk[dbyte+1] = dbit>>(8-jbit); nbit = nbit + ncode; dbit = this_bit; /* index into color table to write out */ dbyte = nbit/8; /* byte index */ jbit = nbit-dbyte*8; /* bit index in byte */ datablk[dbyte] = (datablk[dbyte]+(dbit<7) datablk[dbyte+1] = dbit>>(8-jbit); nbit = nbit + ncode; byte_count = nbit/8; if(byte_count >=253) write_gif_data(datablk, &byte_count, &nbit, FpGif); } /* end j loop */ } /* end i loop */ dbit = 0x05; /* end code */ dbyte = nbit/8; /* byte index */ jbit = nbit-dbyte*8; /* bit index in byte */ datablk[dbyte] = (datablk[dbyte]+(dbit<7) datablk[dbyte+1] = dbit>>(8-jbit); nbit = nbit + ncode; byte_count = (nbit+7)/8; write_gif_data(datablk, &byte_count, &nbit, FpGif); putc(0x00, FpGif); /* byte count of zero, indicating last data */ putc(0x3b, FpGif); /* file terminator */ fclose(FpGif); } /* end write_gif_file */ static void write_gif_data(unsigned char datablk[], unsigned char *byte_count, int * nbit, FILE * FpGif) { int j; /* write byte count of 254 or less, doing a data block */ putc(*byte_count, FpGif); /* image data byte count */ /* write packed bits as bytes */ for(j=0; j<(*byte_count); j++) { putc(datablk[j], FpGif); /* image data */ } datablk[0] = datablk[*byte_count]; for(j=1; j<1280; j++)datablk[j]=0; /* zero image data */ *nbit = (*nbit)-(*byte_count)*8; *byte_count = 0; } /* end write_gif_data */ /* end w1gif.c */