Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

gifview.c File Reference

#include "config.h"
#include "gifx.h"
#include "clp.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#include <sys/select.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>

Go to the source code of this file.


Data Structures

struct  Gt_Viewer

Defines

#define EXTERN   extern
#define SAVE_FRAMES   10
#define MICRO_PER_SEC   1000000
#define xwADDTIME(result, a, b)
#define xwSUBTIME(result, a, b)
#define xwSETMINTIME(a, b)
#define xwTIMEGEQ(a, b)
#define xwTIMEGT(a, b)
#define xwTIMELEQ0(a)   ((a).tv_sec < 0 || ((a).tv_sec == 0 && (a).tv_usec <= 0))
#define xwGETTIMEOFDAY(a)   gettimeofday((a), 0)
#define xwGETTIME(a)   do { xwGETTIMEOFDAY(&(a)); xwSUBTIME((a), (a), genesis_time); } while (0)
#define DISPLAY_OPT   300
#define UNOPTIMIZE_OPT   301
#define VERSION_OPT   302
#define ANIMATE_OPT   303
#define GEOMETRY_OPT   304
#define NAME_OPT   305
#define HELP_OPT   306
#define WINDOW_OPT   307
#define INSTALL_COLORMAP_OPT   308
#define INTERACTIVE_OPT   309
#define BACKGROUND_OPT   310
#define WINDOW_TYPE   (Clp_MaxDefaultType + 1)
#define VISUAL_CLASS   class

Typedefs

typedef Gt_Viewer Gt_Viewer

Functions

void fatal_error (char *message,...)
void error (char *message,...)
void warning (char *message,...)
void short_usage (void)
void usage (void)
void choose_visual (Gt_Viewer *viewer)
Gt_Viewernew_viewer (Display *display, Window use_window, Gif_Stream *gfs, char *name)
void delete_viewer (Gt_Viewer *viewer)
Gt_Viewernext_viewer (Gif_Stream *gfs, char *name)
Gt_Viewerget_input_stream (char *name)
void switch_animating (Gt_Viewer *viewer, int animating)
void unschedule (Gt_Viewer *viewer)
void schedule_next_frame (Gt_Viewer *viewer)
int parse_geometry (const char *const_g, XSizeHints *sh, int screen_width, int screen_height)
void create_viewer_window (Gt_Viewer *viewer, int w, int h)
void pre_delete_viewer (Gt_Viewer *viewer)
Gt_Viewerfind_viewer (Display *display, Window window)
void set_viewer_name (Gt_Viewer *viewer, int slow_number)
Pixmap unoptimized_frame (Gt_Viewer *viewer, int frame, int slow)
void kill_unoptimized_frames (Gt_Viewer *viewer, int new_frame)
void view_frame (Gt_Viewer *viewer, int frame)
int frame_argument (Gt_Viewer *viewer, char *arg)
void input_stream_done (Gt_Viewer *viewer, int first_frame)
void key_press (Gt_Viewer *viewer, XKeyEvent *e)
void loop (void)
int main (int argc, char **argv)

Variables

timeval genesis_time
const char * program_name = "gifview"
char * cur_display_name = 0
Display * cur_display = 0
char * cur_geometry_spec = 0
Cursor cur_arrow_cursor = 0
Cursor cur_wait_cursor = 0
const char * cur_resource_name
Window cur_use_window = None
const char * cur_background_color = "black"
Gt_Viewerviewers
Gt_Vieweranimations
int animating = 0
int unoptimizing = 0
int install_colormap = 0
int interactive = 1
Clp_Option options []
Atom wm_delete_window_atom
Atom wm_protocols_atom

Define Documentation

#define ANIMATE_OPT   303
 

Definition at line 162 of file gifview.c.

Referenced by main().

#define BACKGROUND_OPT   310
 

Definition at line 169 of file gifview.c.

Referenced by main().

#define DISPLAY_OPT   300
 

Definition at line 159 of file gifview.c.

Referenced by main().

#define EXTERN   extern
 

Definition at line 36 of file gifview.c.

#define GEOMETRY_OPT   304
 

Definition at line 163 of file gifview.c.

Referenced by main().

#define HELP_OPT   306
 

Definition at line 165 of file gifview.c.

Referenced by main().

#define INSTALL_COLORMAP_OPT   308
 

Definition at line 167 of file gifview.c.

Referenced by main().

#define INTERACTIVE_OPT   309
 

Definition at line 168 of file gifview.c.

Referenced by main().

#define MICRO_PER_SEC   1000000
 

Definition at line 45 of file gifview.c.

Referenced by schedule_next_frame().

#define NAME_OPT   305
 

Definition at line 164 of file gifview.c.

Referenced by main().

#define SAVE_FRAMES   10
 

Definition at line 39 of file gifview.c.

Referenced by unoptimized_frame().

#define UNOPTIMIZE_OPT   301
 

Definition at line 160 of file gifview.c.

Referenced by main().

#define VERSION_OPT   302
 

Definition at line 161 of file gifview.c.

Referenced by main().

#define VISUAL_CLASS   class
 

Definition at line 276 of file gifview.c.

#define WINDOW_OPT   307
 

Definition at line 166 of file gifview.c.

Referenced by main().

#define WINDOW_TYPE   (Clp_MaxDefaultType + 1)
 

Definition at line 171 of file gifview.c.

Referenced by main().

#define xwADDTIME result,
a,
b   
 

Value:

do { \
        (result).tv_sec = (a).tv_sec + (b).tv_sec; \
        if (((result).tv_usec = (a).tv_usec + (b).tv_usec) >= MICRO_PER_SEC) { \
                (result).tv_sec++; \
                (result).tv_usec -= MICRO_PER_SEC; \
        } } while (0)

Definition at line 47 of file gifview.c.

Referenced by schedule_next_frame().

#define xwGETTIME a       do { xwGETTIMEOFDAY(&(a)); xwSUBTIME((a), (a), genesis_time); } while (0)
 

Definition at line 86 of file gifview.c.

Referenced by loop(), and schedule_next_frame().

#define xwGETTIMEOFDAY a       gettimeofday((a), 0)
 

Definition at line 83 of file gifview.c.

Referenced by main().

#define xwSETMINTIME a,
b   
 

Value:

do { \
        if ((b).tv_sec < (a).tv_sec || \
            ((b).tv_sec == (a).tv_sec && (b).tv_usec < (a).tv_usec)) \
                (a) = (b); \
        } while (0)

Definition at line 61 of file gifview.c.

#define xwSUBTIME result,
a,
b   
 

Value:

do { \
        (result).tv_sec = (a).tv_sec - (b).tv_sec; \
        if (((result).tv_usec = (a).tv_usec - (b).tv_usec) < 0) { \
                (result).tv_sec--; \
                (result).tv_usec += MICRO_PER_SEC; \
        } } while (0)

Definition at line 54 of file gifview.c.

Referenced by loop().

#define xwTIMEGEQ a,
b   
 

Value:

((a).tv_sec > (b).tv_sec || \
        ((a).tv_sec == (b).tv_sec && (a).tv_usec >= (b).tv_usec))

Definition at line 67 of file gifview.c.

Referenced by loop(), and schedule_next_frame().

#define xwTIMEGT a,
b   
 

Value:

((a).tv_sec > (b).tv_sec || \
        ((a).tv_sec == (b).tv_sec && (a).tv_usec > (b).tv_usec))

Definition at line 70 of file gifview.c.

#define xwTIMELEQ0 a       ((a).tv_sec < 0 || ((a).tv_sec == 0 && (a).tv_usec <= 0))
 

Definition at line 73 of file gifview.c.


Typedef Documentation

typedef struct Gt_Viewer Gt_Viewer
 


Function Documentation

void choose_visual Gt_Viewer   viewer [static]
 

Definition at line 280 of file gifview.c.

References Gt_Viewer::colormap, Gt_Viewer::depth, Gt_Viewer::display, display, Gt_Viewer::gfx, i, install_colormap, Gt_Viewer::next, Gif_XContext::refcount, Gt_Viewer::screen_number, v, and Gt_Viewer::visual.

Referenced by new_viewer().

00281 {
00282   Display *display = viewer->display;
00283   int screen_number = viewer->screen_number;
00284   VisualID default_visualid = DefaultVisual(display, screen_number)->visualid;
00285   
00286   XVisualInfo visi_template;
00287   int nv, i;
00288   XVisualInfo *v, *best_v = 0;
00289   Gt_Viewer *trav;
00290   
00291   /* Look for an existing Gt_Viewer with the same display and screen number */
00292   if (!install_colormap)
00293     for (trav = viewers; trav; trav = trav->next)
00294       if (trav != viewer && trav->display == display
00295           && trav->screen_number == screen_number) {
00296         viewer->visual = trav->visual;
00297         viewer->depth = trav->depth;
00298         viewer->colormap = trav->colormap;
00299         viewer->gfx = trav->gfx;
00300         viewer->gfx->refcount++;
00301         return;
00302       }
00303   
00304   /* Find the default visual's XVisualInfo & put it in best_v */
00305   visi_template.screen = screen_number;
00306   v = XGetVisualInfo(display, VisualScreenMask, &visi_template, &nv);
00307   for (i = 0; i < nv && !best_v; i++)
00308     if (v[i].visualid == default_visualid)
00309       best_v = &v[i];
00310   
00311   if (!best_v) {
00312     
00313     /* This should never happen. If we can't find the default visual's
00314        XVisualInfo, we just use the default visual */
00315     viewer->visual = DefaultVisual(display, screen_number);
00316     viewer->depth = DefaultDepth(display, screen_number);
00317     viewer->colormap = DefaultColormap(display, screen_number);
00318     
00319   } else {
00320     
00321     /* Which visual to choose? This isn't exactly a simple decision, since
00322        we want to avoid colormap flashing while choosing a nice visual. So
00323        here's the algorithm: Prefer the default visual, or take a TrueColor
00324        visual with strictly greater depth. */
00325     for (i = 0; i < nv; i++)
00326       if (v[i].depth > best_v->depth && v[i].VISUAL_CLASS == TrueColor)
00327         best_v = &v[i];
00328     
00329     viewer->visual = best_v->visual;
00330     viewer->depth = best_v->depth;
00331     if (best_v->visualid != default_visualid
00332         || (best_v->VISUAL_CLASS == PseudoColor && install_colormap))
00333       viewer->colormap =
00334         XCreateColormap(display, RootWindow(display, screen_number),
00335                         viewer->visual, AllocNone);
00336     else
00337       viewer->colormap = DefaultColormap(display, screen_number);
00338     
00339   }
00340   
00341   viewer->gfx = Gif_NewXContextFromVisual
00342     (display, screen_number, viewer->visual, viewer->depth, viewer->colormap);
00343   viewer->gfx->refcount++;
00344   
00345   if (v) XFree(v);
00346 }

void create_viewer_window Gt_Viewer   viewer,
int    w,
int    h
 

Definition at line 654 of file gifview.c.

References Gt_Viewer::arrow_cursor, Gt_Viewer::colormap, cur_geometry_spec, cur_resource_name, Gt_Viewer::depth, Gt_Viewer::display, display, Gt_Viewer::height, Gt_Viewer::parent, parse_geometry(), Gt_Viewer::resizable, Gt_Viewer::screen_number, Gt_Viewer::top_level, Gt_Viewer::visual, Gt_Viewer::width, Gt_Viewer::window, wm_delete_window_atom, and wm_protocols_atom.

Referenced by view_frame().

00655 {
00656   Display *display = viewer->display;
00657   char *stringlist[2];
00658   XTextProperty window_name, icon_name;
00659   XClassHint classh;
00660   XSizeHints *sizeh = XAllocSizeHints(); /* sets all fields to 0 */
00661 
00662   /* Set the window's geometry */
00663   sizeh->width = w;
00664   sizeh->height = h;
00665   if (cur_geometry_spec) {
00666     int scr_width = DisplayWidth(viewer->display, viewer->screen_number);
00667     int scr_height = DisplayHeight(viewer->display, viewer->screen_number);
00668     parse_geometry(cur_geometry_spec, sizeh, scr_width, scr_height);
00669   }
00670   
00671   /* Open the display and create the window */
00672   if (!viewer->window) {
00673     XSetWindowAttributes x_set_attr;
00674     unsigned long x_set_attr_mask;
00675     x_set_attr.colormap = viewer->colormap;
00676     x_set_attr.backing_store = NotUseful;
00677     x_set_attr.save_under = False;
00678     x_set_attr.border_pixel = 0;
00679     x_set_attr.background_pixel = 0;
00680     x_set_attr_mask = CWColormap | CWBorderPixel | CWBackPixel
00681       | CWBackingStore | CWSaveUnder;
00682     
00683     viewer->window = XCreateWindow
00684       (display, viewer->parent,
00685        sizeh->x, sizeh->y, sizeh->width, sizeh->height, 0,
00686        viewer->depth, InputOutput, viewer->visual,
00687        x_set_attr_mask, &x_set_attr);
00688     XDefineCursor(display, viewer->window, viewer->arrow_cursor);
00689   }
00690 
00691   /* If user gave us geometry, don't change the size later */
00692   if (sizeh->flags & USSize)
00693     viewer->resizable = 0;
00694   viewer->width = w;
00695   viewer->height = h;
00696   
00697   /* Set the window's title and class (for window manager resources) */
00698   if (viewer->top_level) {
00699     stringlist[0] = "gifview";
00700     stringlist[1] = 0;
00701     XStringListToTextProperty(stringlist, 1, &window_name);
00702     XStringListToTextProperty(stringlist, 1, &icon_name);
00703     classh.res_name = (char *)cur_resource_name;
00704     classh.res_class = "Gifview";
00705     XSetWMProperties(display, viewer->window, &window_name, &icon_name,
00706                      NULL, 0, sizeh, NULL, &classh);
00707     XFree(window_name.value);
00708     XFree(icon_name.value);
00709   
00710     if (!wm_delete_window_atom) {
00711       wm_delete_window_atom = XInternAtom(display, "WM_DELETE_WINDOW", False);
00712       wm_protocols_atom = XInternAtom(display, "WM_PROTOCOLS", False);
00713     }
00714     XSetWMProtocols(display, viewer->window, &wm_delete_window_atom, 1);
00715   }
00716 
00717   if (interactive)
00718     XSelectInput(display, viewer->window, ButtonPressMask | KeyPressMask
00719                  | StructureNotifyMask);
00720   else
00721     XSelectInput(display, viewer->window, StructureNotifyMask);
00722   
00723   XFree(sizeh);
00724 }

void delete_viewer Gt_Viewer   viewer
 

Definition at line 462 of file gifview.c.

References Gt_Viewer::display, Gt_Viewer::gfs, Gt_Viewer::gfx, Gif_Delete, Gif_DeleteArray, Gif_DeleteStream(), Gif_DeleteXContext(), i, Gt_Viewer::im, Gt_Viewer::next, Gt_Viewer::nim, Gt_Viewer::pixmap, Gt_Viewer::unoptimized_pixmaps, and Gt_Viewer::was_unoptimized.

Referenced by loop(), and pre_delete_viewer().

00463 {
00464   Gt_Viewer *prev = 0, *trav;
00465   int i;
00466   if (viewer->pixmap && !viewer->was_unoptimized)
00467     XFreePixmap(viewer->display, viewer->pixmap);
00468   for (i = 0; i < viewer->nim; i++)
00469     if (viewer->unoptimized_pixmaps[i])
00470       XFreePixmap(viewer->display, viewer->unoptimized_pixmaps[i]);
00471   
00472   for (trav = viewers; trav != viewer; prev = trav, trav = trav->next)
00473     ;
00474   if (prev) prev->next = viewer->next;
00475   else viewers = viewer->next;
00476   
00477   Gif_DeleteStream(viewer->gfs);
00478   Gif_DeleteArray(viewer->unoptimized_pixmaps);
00479   Gif_DeleteArray(viewer->im);
00480   Gif_DeleteXContext(viewer->gfx);
00481   Gif_Delete(viewer);
00482 }

void error char *    message,
...   
 

Definition at line 205 of file gifview.c.

References program_name.

00206 {
00207   va_list val;
00208   va_start(val, message);
00209   fprintf(stderr, "%s: ", program_name);
00210   vfprintf(stderr, message, val);
00211   fputc('\n', stderr);
00212 }

void fatal_error char *    message,
...   
 

Definition at line 194 of file gifview.c.

References program_name.

00195 {
00196   va_list val;
00197   va_start(val, message);
00198   fprintf(stderr, "%s: ", program_name);
00199   vfprintf(stderr, message, val);
00200   fputc('\n', stderr);
00201   exit(1);
00202 }

Gt_Viewer* find_viewer Display *    display,
Window    window
 

Definition at line 743 of file gifview.c.

References Gt_Viewer::display, display, Gt_Viewer::next, v, and Gt_Viewer::window.

Referenced by loop().

00744 {
00745   Gt_Viewer *v;
00746   for (v = viewers; v; v = v->next)
00747     if (v->display == display && v->window == window)
00748       return v;
00749   return 0;
00750 }

int frame_argument Gt_Viewer   viewer,
char *    arg
 

Definition at line 953 of file gifview.c.

References arg, c, error(), Gt_Viewer::gfs, Gif_GetNamedImage(), Gif_ImageNumber(), n1, and Gt_Viewer::nim.

Referenced by main().

00954 {
00955   char *c = arg;
00956   int n1 = 0;
00957   
00958   /* Get a number range (#x, #x-y, #x-, or #-y). First, read x. */
00959   if (isdigit(c[0]))
00960     n1 = strtol(arg, &c, 10);
00961   
00962   /* It really was a number range only if c is now at the end of the
00963      argument. */
00964   if (c[0] != 0) {
00965     Gif_Image *gfi = Gif_GetNamedImage(viewer->gfs, c);
00966     if (!gfi)
00967       error("no frame named `%s'", c);
00968     else
00969       n1 = Gif_ImageNumber(viewer->gfs, gfi);
00970   } else {
00971     if (n1 < 0 || n1 >= viewer->nim) {
00972       error("no frame number %d", n1);
00973       n1 = 0;
00974     }
00975   }
00976   
00977   return n1;
00978 }

Gt_Viewer* get_input_stream char *    name [static]
 

Definition at line 495 of file gifview.c.

References cur_display, cur_display_name, error(), Gif_DeleteStream(), Gif_FullReadFile(), Gif_ImageCount, GIF_READ_COMPRESSED, name, next_viewer(), and strerror().

Referenced by main().

00496 {
00497   FILE *f;
00498   Gif_Stream *gfs = 0;
00499   
00500   if (name == 0 || strcmp(name, "-") == 0) {
00501     f = stdin;
00502     name = "<stdin>";
00503   } else
00504     f = fopen(name, "rb");
00505   if (!f) {
00506     error("%s: %s", name, strerror(errno));
00507     return 0;
00508   }
00509   
00510   gfs = Gif_FullReadFile(f, GIF_READ_COMPRESSED, 0, 0);
00511   fclose(f);
00512   
00513   if (!gfs || Gif_ImageCount(gfs) == 0) {
00514     error("`%s' doesn't seem to contain a GIF", name);
00515     Gif_DeleteStream(gfs);
00516     return 0;
00517   }
00518   
00519   if (!cur_display) {
00520     cur_display = XOpenDisplay(cur_display_name);
00521     if (!cur_display) {
00522       error("can't open display");
00523       return 0;
00524     }
00525   }
00526 
00527   return next_viewer(gfs, name);
00528 }

void input_stream_done Gt_Viewer   viewer,
int    first_frame
 

Definition at line 982 of file gifview.c.

References animating, Gt_Viewer::can_animate, Gt_Viewer::gfs, Gif_ImageCount, switch_animating(), and view_frame().

Referenced by main().

00983 {
00984   viewer->can_animate = Gif_ImageCount(viewer->gfs) > 1;
00985   switch_animating(viewer, animating && viewer->can_animate);
00986   if (first_frame < 0)
00987     first_frame = 0;
00988   view_frame(viewer, first_frame);
00989 }

void key_press Gt_Viewer   viewer,
XKeyEvent *    e
 

Definition at line 993 of file gifview.c.

References Gt_Viewer::anim_loop, Gt_Viewer::animating, Gt_Viewer::im_pos, key, Gt_Viewer::nim, pre_delete_viewer(), Gt_Viewer::resizable, set_viewer_name(), switch_animating(), Gt_Viewer::unoptimizing, unschedule(), and view_frame().

Referenced by loop().

00994 {
00995   char buf[32];
00996   KeySym key;
00997   int nbuf = XLookupString(e, buf, 32, &key, 0);
00998   if (nbuf > 1) buf[0] = 0;     /* ignore multikey sequences */
00999   
01000   if (key == XK_space || key == XK_F || key == XK_f)
01001     /* space or F: one frame ahead */
01002     view_frame(viewer, viewer->im_pos + 1);
01003   
01004   else if (key == XK_B || key == XK_b)
01005     /* B: one frame back */
01006     view_frame(viewer, viewer->im_pos - 1);
01007   
01008   else if (key == XK_W || key == XK_w || key == XK_BackSpace)
01009     /* backspace: delete viewer */
01010     pre_delete_viewer(viewer);
01011   
01012   else if (key == XK_Q || key == XK_q)
01013     /* Q: quit applicaton */
01014     exit(0);
01015   
01016   else if (key == XK_S || key == XK_s || key == XK_a || key == XK_A) {
01017     /* S or A: toggle animation */
01018     switch_animating(viewer, !viewer->animating);
01019     
01020     if (viewer->animating) {
01021       int pos = viewer->im_pos;
01022       if (viewer->im_pos >= viewer->nim - 1) {
01023         pos = 0;
01024         viewer->anim_loop = 0;
01025       }
01026       view_frame(viewer, pos);
01027       
01028     } else
01029       unschedule(viewer);
01030     
01031     set_viewer_name(viewer, -1);
01032     
01033   } else if (key == XK_U || key == XK_u) {
01034     /* U: toggle unoptimizing */
01035     int pos = viewer->im_pos;
01036     viewer->unoptimizing = !viewer->unoptimizing;
01037     if (!viewer->animating) {
01038       viewer->im_pos = -1;
01039       view_frame(viewer, pos);
01040       set_viewer_name(viewer, -1);
01041     }
01042     
01043   } else if (key == XK_R || key == XK_r
01044              || (nbuf == 1 && buf[0] == '<')) {
01045     /* R or <: reset to first frame */
01046     unschedule(viewer);
01047     viewer->anim_loop = 0;
01048     view_frame(viewer, 0);
01049     
01050   } else if (nbuf == 1 && buf[0] == '>') {
01051     /* >: reset to last frame */
01052     unschedule(viewer);
01053     viewer->anim_loop = 0;
01054     view_frame(viewer, viewer->nim - 1);
01055     
01056   } else if (key == XK_Escape && viewer->animating) {
01057     /* Escape: stop animation */
01058     switch_animating(viewer, 0);
01059     unschedule(viewer);
01060     set_viewer_name(viewer, -1);
01061     
01062   } else if (key == XK_Z || key == XK_z) {
01063     /* Z: trigger resizability */
01064     viewer->resizable = !viewer->resizable;
01065   }
01066 }

void kill_unoptimized_frames Gt_Viewer   viewer,
int    new_frame
[static]
 

Definition at line 828 of file gifview.c.

References Gt_Viewer::display, Gt_Viewer::free_pixmaps, Gt_Viewer::im_pos, Gt_Viewer::nim, and Gt_Viewer::unoptimized_pixmaps.

Referenced by view_frame().

00829 {
00830   int nimages = viewer->nim;
00831   int kill = nimages;
00832   if (!viewer->free_pixmaps)
00833     return;
00834   
00835   if (new_frame == 0)
00836     kill = 3;
00837   else if (new_frame < viewer->im_pos)
00838     kill = new_frame + 1;
00839   
00840   for (; kill < nimages; kill++)
00841     if (viewer->unoptimized_pixmaps[kill] && kill % 50 != 0) {
00842       XFreePixmap(viewer->display, viewer->unoptimized_pixmaps[kill]);
00843       viewer->unoptimized_pixmaps[kill] = None;
00844     }
00845 }

void loop void   
 

Definition at line 1070 of file gifview.c.

References Gt_Viewer::anim_next, Gt_Viewer::animating, delete_viewer(), Gt_Viewer::display, display, find_viewer(), Gt_Viewer::im_pos, key_press(), pre_delete_viewer(), retval(), schedule_next_frame(), Gt_Viewer::scheduled, Gt_Viewer::timer, v, view_frame(), wm_delete_window_atom, wm_protocols_atom, xwGETTIME, xwSUBTIME, and xwTIMEGEQ.

Referenced by main().

01071 {
01072   struct timeval now;
01073   fd_set xfds;
01074   XEvent e;
01075   int pending;
01076   Gt_Viewer *v;
01077   Display *display = viewers->display;
01078   int x_socket = ConnectionNumber(display);
01079   
01080   xwGETTIME(now);
01081   FD_ZERO(&xfds);
01082   
01083   while (viewers) {
01084     
01085     /* Check for any animations */
01086     /* 13.Feb.2001 - Use the 'pending' counter to avoid a tight loop
01087        if all the frames in an animation have delay 0. Reported by
01088        Franc,ois Petitjean. */
01089     pending = 0;
01090     while (animations && xwTIMEGEQ(now, animations->timer) && pending < 25) {
01091       v = animations;
01092       animations = v->anim_next;
01093       v->scheduled = 0;
01094       view_frame(v, v->im_pos + 1);
01095       xwGETTIME(now);
01096       pending++;
01097     }
01098     
01099     pending = XPending(display);
01100     if (!pending) {
01101       /* select() until event arrives */
01102       struct timeval timeout, *timeout_ptr;
01103       int retval;
01104 
01105       if (animations) {
01106         xwSUBTIME(timeout, animations->timer, now);
01107         timeout_ptr = &timeout;
01108       } else
01109         timeout_ptr = 0;
01110     
01111       FD_SET(x_socket, &xfds);
01112       retval = select(x_socket + 1, &xfds, 0, 0, timeout_ptr);
01113       pending = (retval <= 0 ? 0 : FD_ISSET(x_socket, &xfds));
01114     }
01115     
01116     if (pending)
01117       while (XPending(display)) {
01118         XNextEvent(display, &e);
01119         v = find_viewer(e.xany.display, e.xany.window);
01120         if (v) {
01121           if (interactive) {
01122             if (e.type == ButtonPress && e.xbutton.button == 1)
01123               /* Left mouse button: go to next frame */
01124               view_frame(v, v->im_pos + 1);
01125             
01126             else if (e.type == ButtonPress && e.xbutton.button == 3)
01127               /* Right mouse button: delete window */
01128               pre_delete_viewer(v);
01129             
01130             else if (e.type == KeyPress)
01131               /* Key press: call function */
01132               key_press(v, &e.xkey);
01133           }
01134           
01135           if (e.type == ClientMessage
01136               && e.xclient.message_type == wm_protocols_atom
01137               && (Atom)(e.xclient.data.l[0]) == wm_delete_window_atom)
01138             /* WM_DELETE_WINDOW message: delete window */
01139             pre_delete_viewer(v);
01140           
01141           else if (e.type == MapNotify && v->animating
01142                    && v->scheduled == 0)
01143             /* Window was just mapped; now, start animating it */
01144             schedule_next_frame(v);
01145           
01146           else if (e.type == DestroyNotify)
01147             /* Once the window has been destroyed, delete related state */
01148             delete_viewer(v);
01149         }
01150       }
01151     
01152     xwGETTIME(now);
01153   }
01154 }

int main int    argc,
char **    argv
 

Definition at line 1158 of file gifview.c.

References ANIMATE_OPT, animating, Clp_Parser::arg, argc, BACKGROUND_OPT, Clp_AllowNumbers, Clp_BadOption, Clp_Done, Clp_NewParser(), Clp_Next(), Clp_NotOption, Clp_ProgramName(), Clp_SetOptionChar(), Clp_ShortNegated, cur_arrow_cursor, cur_background_color, cur_display, cur_display_name, cur_geometry_spec, cur_resource_name, cur_use_window, cur_wait_cursor, DISPLAY_OPT, dmalloc_report(), fatal_error(), frame_argument(), genesis_time, GEOMETRY_OPT, get_input_stream(), Gt_Viewer::gfs, HELP_OPT, input_stream_done(), install_colormap, INSTALL_COLORMAP_OPT, interactive, INTERACTIVE_OPT, loop(), Gt_Viewer::name, NAME_OPT, Clp_Parser::negated, next_viewer(), program_name, short_usage(), UNOPTIMIZE_OPT, unoptimizing, usage(), Clp_Parser::val, VERSION_OPT, WINDOW_OPT, WINDOW_TYPE, and xwGETTIMEOFDAY.

01159 {
01160   Gt_Viewer *viewer = 0;
01161   int viewer_given = 0;
01162   int any_errors = 0;
01163   int first_frame = -1;
01164   
01165   Clp_Parser *clp =
01166     Clp_NewParser(argc, argv,
01167                   sizeof(options) / sizeof(options[0]), options);
01168   Clp_SetOptionChar(clp, '+', Clp_ShortNegated);
01169   Clp_AddStringListType
01170     (clp, WINDOW_TYPE, Clp_AllowNumbers,
01171      "root", -1,
01172      0);
01173   program_name = cur_resource_name = Clp_ProgramName(clp);
01174   
01175   xwGETTIMEOFDAY(&genesis_time);
01176   
01177   while (1) {
01178     int opt = Clp_Next(clp);
01179     switch (opt) {
01180       
01181      case DISPLAY_OPT:
01182       if (cur_display)
01183         fatal_error("`--display' must come before all other options");
01184       cur_display_name = clp->arg;
01185       cur_display = 0;
01186       cur_arrow_cursor = cur_wait_cursor = None;
01187       break;
01188       
01189      case GEOMETRY_OPT:
01190       cur_geometry_spec = clp->arg;
01191       break;
01192       
01193      case NAME_OPT:
01194       cur_resource_name = clp->arg;
01195       break;
01196       
01197      case UNOPTIMIZE_OPT:
01198       unoptimizing = clp->negated ? 0 : 1;
01199       break;
01200       
01201      case BACKGROUND_OPT:
01202       cur_background_color = clp->arg;
01203       break;
01204       
01205      case ANIMATE_OPT:
01206       animating = clp->negated ? 0 : 1;
01207       break;
01208       
01209      case INSTALL_COLORMAP_OPT:
01210       install_colormap = clp->negated ? 0 : 1;
01211       break;
01212       
01213      case WINDOW_OPT:
01214       cur_use_window = clp->val.u;
01215       break;
01216       
01217      case INTERACTIVE_OPT:
01218       interactive = clp->negated ? 0 : 1;
01219       break;
01220       
01221      case VERSION_OPT:
01222       printf("gifview (LCDF Gifsicle) %s\n", VERSION);
01223       printf("Copyright (C) 1997-2001 Eddie Kohler\n\
01224 This is free software; see the source for copying conditions.\n\
01225 There is NO warranty, not even for merchantability or fitness for a\n\
01226 particular purpose.\n");
01227       exit(0);
01228       break;
01229       
01230      case HELP_OPT:
01231       usage();
01232       exit(0);
01233       break;
01234       
01235      case Clp_NotOption:
01236       if (clp->arg[0] == '#') {
01237         if (!viewer_given) {
01238           viewer = get_input_stream(0);
01239           viewer_given = 1;
01240         }
01241         if (viewer && first_frame >= 0) {
01242           /* copy viewer if 2 frame specs given */
01243           input_stream_done(viewer, first_frame);
01244           viewer = next_viewer(viewer->gfs, viewer->name);
01245         }
01246         if (viewer)
01247           first_frame = frame_argument(viewer, clp->arg + 1);
01248       } else {
01249         if (viewer) input_stream_done(viewer, first_frame);
01250         first_frame = -1;
01251         viewer = get_input_stream(clp->arg);
01252         viewer_given = 1;
01253       }
01254       break;
01255       
01256      case Clp_Done:
01257       goto done;
01258       
01259      case Clp_BadOption:
01260       any_errors = 1;
01261       break;
01262       
01263      default:
01264       break;
01265       
01266     }
01267   }
01268   
01269  done:
01270   
01271   if (!viewer_given) {
01272     if (any_errors) {
01273       short_usage();
01274       exit(1);
01275     }
01276     viewer = get_input_stream(0);
01277   }
01278   if (viewer) input_stream_done(viewer, first_frame);
01279   
01280   if (viewers) loop();
01281   
01282 #ifdef DMALLOC
01283   dmalloc_report();
01284 #endif
01285   return 0;
01286 }

Gt_Viewer* new_viewer Display *    display,
Window    use_window,
Gif_Stream   gfs,
char *    name
 

Definition at line 350 of file gifview.c.

References Gt_Viewer::anim_loop, Gt_Viewer::anim_next, Gt_Viewer::animating, Gt_Viewer::arrow_cursor, Gt_Viewer::being_deleted, choose_visual(), color, Gif_XContext::colormap, Gt_Viewer::colormap, cur_arrow_cursor, cur_background_color, cur_wait_cursor, Gif_XContext::depth, Gt_Viewer::depth, Gif_XContext::display, Gt_Viewer::display, display, error(), Gt_Viewer::free_pixmaps, Gt_Viewer::gfs, Gt_Viewer::gfx, Gif_ImageCount, Gif_New, Gif_NewArray, i, Gt_Viewer::im, Gt_Viewer::im_pos, Gif_Stream::images, Gt_Viewer::name, name, Gt_Viewer::next, Gt_Viewer::nim, Gt_Viewer::parent, Gt_Viewer::pixmap, Gif_Stream::refcount, Gif_XContext::refcount, Gt_Viewer::resizable, Gt_Viewer::scheduled, Gif_XContext::screen_number, Gt_Viewer::screen_number, Gt_Viewer::timer, Gt_Viewer::top_level, Gif_XContext::transparent_pixel, Gt_Viewer::unoptimized_pixmaps, unoptimizing, Gt_Viewer::unoptimizing, Gt_Viewer::use_window, Gif_XContext::visual, Gt_Viewer::visual, Gt_Viewer::wait_cursor, warning(), Gt_Viewer::was_unoptimized, and Gt_Viewer::window.

Referenced by next_viewer().

00351 {
00352   Gt_Viewer *viewer;
00353   int i;
00354   
00355   /* Make the Gt_Viewer structure */
00356   viewer = Gif_New(Gt_Viewer);
00357   viewer->display = display;
00358   
00359   if (use_window) {
00360     XWindowAttributes attr;
00361 
00362     if (use_window == -1) {     /* means use root window */
00363       viewer->screen_number = DefaultScreen(display);
00364       use_window = RootWindow(display, viewer->screen_number);
00365     }
00366     
00367     XGetWindowAttributes(display, use_window, &attr);
00368     
00369     viewer->screen_number = -1;
00370     for (i = 0; i < ScreenCount(display); i++)
00371       if (ScreenOfDisplay(display, i) == attr.screen)
00372         viewer->screen_number = i;
00373     assert(viewer->screen_number >= 0);
00374     
00375     viewer->visual = attr.visual;
00376     viewer->depth = attr.depth;
00377     viewer->colormap = attr.colormap;
00378     
00379     viewer->gfx = Gif_NewXContextFromVisual
00380       (display, viewer->screen_number, viewer->visual, viewer->depth,
00381        viewer->colormap);
00382     viewer->gfx->refcount++;
00383 
00384     /* use root window, if that's what we were given; otherwise, create a
00385        child of the window we were given */
00386     viewer->window = (use_window == attr.root ? use_window : None);
00387     viewer->parent = use_window;
00388     viewer->use_window = (use_window == attr.root ? 1 : 0);
00389     viewer->top_level = 0;
00390     viewer->resizable = 0;
00391     
00392   } else {
00393     viewer->screen_number = DefaultScreen(display);
00394     choose_visual(viewer);
00395     viewer->window = None;
00396     viewer->parent = RootWindow(display, viewer->screen_number);
00397     viewer->use_window = 0;
00398     viewer->top_level = 1;
00399     viewer->resizable = 1;
00400   }
00401   
00402   /* assign background color */
00403   if (cur_background_color) {
00404     XColor color;
00405     if (!XParseColor(viewer->display, viewer->colormap, cur_background_color,
00406                      &color)) {
00407       error("invalid background color `%s'", cur_background_color);
00408       cur_background_color = 0;
00409     } else if (!XAllocColor(viewer->display, viewer->colormap, &color))
00410       warning("can't allocate background color");
00411     else {
00412       unsigned long pixel = color.pixel;
00413       Gif_XContext *gfx = viewer->gfx;
00414       if (pixel != gfx->transparent_pixel && gfx->refcount > 1) {
00415         /* copy X context */
00416         viewer->gfx = Gif_NewXContextFromVisual
00417           (gfx->display, gfx->screen_number, gfx->visual, gfx->depth,
00418            gfx->colormap);
00419         viewer->gfx->refcount++;
00420         gfx->refcount--;
00421       }
00422       viewer->gfx->transparent_pixel = pixel;
00423     }
00424   }
00425 
00426   if (!cur_arrow_cursor) {
00427     cur_arrow_cursor = XCreateFontCursor(display, XC_left_ptr);
00428     cur_wait_cursor = XCreateFontCursor(display, XC_watch);
00429   }
00430   viewer->arrow_cursor = cur_arrow_cursor;
00431   viewer->wait_cursor = cur_wait_cursor;
00432   
00433   viewer->being_deleted = 0;
00434   viewer->gfs = gfs;
00435   gfs->refcount++;
00436   viewer->name = name;
00437   viewer->nim = Gif_ImageCount(gfs);
00438   viewer->im = Gif_NewArray(Gif_Image *, viewer->nim);
00439   for (i = 0; i < viewer->nim; i++)
00440     viewer->im[i] = gfs->images[i];
00441   viewer->pixmap = None;
00442   viewer->im_pos = -1;
00443   viewer->was_unoptimized = 0;
00444   viewer->free_pixmaps = 1;
00445   viewer->unoptimized_pixmaps = Gif_NewArray(Pixmap, viewer->nim);
00446   for (i = 0; i < viewer->nim; i++)
00447     viewer->unoptimized_pixmaps[i] = None;
00448   viewer->next = viewers;
00449   viewers = viewer;
00450   viewer->animating = 0;
00451   viewer->unoptimizing = unoptimizing;
00452   viewer->scheduled = 0;
00453   viewer->anim_next = 0;
00454   viewer->anim_loop = 0;
00455   viewer->timer.tv_sec = viewer->timer.tv_usec = 0;
00456   
00457   return viewer;
00458 }

Gt_Viewer* next_viewer Gif_Stream   gfs,
char *    name
[static]
 

Definition at line 486 of file gifview.c.

References cur_display, cur_use_window, name, and new_viewer().

Referenced by get_input_stream(), and main().

00487 {
00488   Gt_Viewer *viewer = new_viewer(cur_display, cur_use_window, gfs, name);
00489   if (cur_use_window)
00490     cur_use_window = None;
00491   return viewer;
00492 }

int parse_geometry const char *    const_g,
XSizeHints *    sh,
int    screen_width,
int    screen_height
 

Definition at line 603 of file gifview.c.

References error(), and warning().

Referenced by create_viewer_window().

00605 {
00606   char *g = (char *)const_g;
00607   sh->flags = 0;
00608   
00609   if (isdigit(*g)) {
00610     sh->flags |= USSize;
00611     sh->width = strtol(g, &g, 10);
00612     if (g[0] == 'x' && isdigit(g[1]))
00613       sh->height = strtol(g + 1, &g, 10);
00614     else
00615       goto error;
00616   } else if (!*g)
00617     goto error;
00618   
00619   if (*g == '+' || *g == '-') {
00620     int x_minus, y_minus;
00621     sh->flags |= USPosition | PWinGravity;
00622     x_minus = *g == '-';
00623     sh->x = strtol(g + 1, &g, 10);
00624     if (x_minus) sh->x = screen_width - sh->x - sh->width;
00625     
00626     y_minus = *g == '-';
00627     if (*g == '-' || *g == '+')
00628       sh->y = strtol(g + 1, &g, 10);
00629     else
00630       goto error;
00631     if (y_minus) sh->y = screen_height - sh->y - sh->height;
00632     
00633     if (x_minus)
00634       sh->win_gravity = y_minus ? SouthEastGravity : NorthEastGravity;
00635     else
00636       sh->win_gravity = y_minus ? SouthWestGravity : NorthWestGravity;
00637     
00638   } else if (*g)
00639     goto error;
00640   
00641   return 1;
00642   
00643  error:
00644   warning("bad geometry specification");
00645   sh->flags = 0;
00646   return 0;
00647 }

void pre_delete_viewer Gt_Viewer   viewer
 

Definition at line 728 of file gifview.c.

References Gt_Viewer::being_deleted, delete_viewer(), Gt_Viewer::display, Gt_Viewer::scheduled, unschedule(), Gt_Viewer::use_window, and Gt_Viewer::window.

Referenced by key_press(), and loop().

00729 {
00730   if (viewer->being_deleted) return;
00731   viewer->being_deleted = 1;
00732   
00733   if (viewer->scheduled) unschedule(viewer);
00734   
00735   if (viewer->window && !viewer->use_window)
00736     XDestroyWindow(viewer->display, viewer->window);
00737   else
00738     delete_viewer(viewer);
00739 }

void schedule_next_frame Gt_Viewer   viewer
 

Definition at line 568 of file gifview.c.

References Gt_Viewer::anim_next, Gt_Viewer::im, Gt_Viewer::im_pos, MICRO_PER_SEC, Gt_Viewer::scheduled, Gt_Viewer::timer, unschedule(), xwADDTIME, xwGETTIME, and xwTIMEGEQ.

Referenced by loop(), and view_frame().

00569 {
00570   struct timeval interval;
00571   Gt_Viewer *prev, *trav;
00572   int delay = viewer->im[viewer->im_pos]->delay;
00573 
00574   if (viewer->timer.tv_sec == 0 && viewer->timer.tv_usec == 0)
00575     xwGETTIME(viewer->timer);
00576   interval.tv_sec = delay / 100;
00577   interval.tv_usec = (delay % 100) * (MICRO_PER_SEC / 100);
00578   xwADDTIME(viewer->timer, viewer->timer, interval);
00579 
00580   if (viewer->scheduled)
00581     unschedule(viewer);
00582   
00583   prev = 0;
00584   for (trav = animations; trav; prev = trav, trav = trav->anim_next)
00585     if (xwTIMEGEQ(trav->timer, viewer->timer))
00586       break;
00587   if (prev) {
00588     viewer->anim_next = trav;
00589     prev->anim_next = viewer;
00590   } else {
00591     viewer->anim_next = animations;
00592     animations = viewer;
00593   }
00594   viewer->scheduled = 1;
00595 }

void set_viewer_name Gt_Viewer   viewer,
int    slow_number
 

Definition at line 754 of file gifview.c.

References Gt_Viewer::animating, Gt_Viewer::being_deleted, Gt_Viewer::display, Gif_DeleteArray, Gif_NewArray, Gif_Image::identifier, Gt_Viewer::im, Gt_Viewer::im_pos, Gt_Viewer::name, Gt_Viewer::nim, Gt_Viewer::top_level, and Gt_Viewer::window.

Referenced by key_press(), unoptimized_frame(), and view_frame().

00755 {
00756   Gif_Image *gfi;
00757   char *strs[2];
00758   char *identifier;
00759   XTextProperty name_prop;
00760   int im_pos = (slow_number >= 0 ? slow_number : viewer->im_pos);
00761   int len;
00762   
00763   if (!viewer->top_level || im_pos >= viewer->nim || viewer->being_deleted)
00764     return;
00765 
00766   gfi = viewer->im[im_pos];
00767   len = strlen(viewer->name) + 21;
00768   identifier = (slow_number >= 0 ? (char *)0 : gfi->identifier);
00769   if (identifier)
00770     len += 2 + strlen(identifier);
00771   
00772   strs[0] = Gif_NewArray(char, len);
00773   if (slow_number >= 0)
00774     sprintf(strs[0], "gifview: %s [#%d]", viewer->name, im_pos);
00775   else if (viewer->nim == 1 && identifier)
00776     sprintf(strs[0], "gifview: %s #%s", viewer->name, identifier);
00777   else if (viewer->animating || viewer->nim == 1)
00778     sprintf(strs[0], "gifview: %s", viewer->name);
00779   else if (!identifier)
00780     sprintf(strs[0], "gifview: %s #%d", viewer->name, im_pos);
00781   else
00782     sprintf(strs[0], "gifview: %s #%d #%s", viewer->name, im_pos, identifier);
00783   strs[1] = 0;
00784   
00785   XStringListToTextProperty(strs, 1, &name_prop);
00786   XSetWMName(viewer->display, viewer->window, &name_prop);
00787   XSetWMIconName(viewer->display, viewer->window, &name_prop);
00788   
00789   XFree(name_prop.value);
00790   Gif_DeleteArray(strs[0]);
00791 }

void short_usage void   
 

Definition at line 225 of file gifview.c.

References program_name.

00226 {
00227   fprintf(stderr, "Usage: %s [--display DISPLAY] [OPTION]... [FILE | FRAME]...\n\
00228 Try `%s --help' for more information.\n",
00229           program_name, program_name);
00230 }

void switch_animating Gt_Viewer   viewer,
int    animating
 

Definition at line 536 of file gifview.c.

References Gt_Viewer::animating, animating, Gt_Viewer::can_animate, Gt_Viewer::gfs, i, Gt_Viewer::im, Gif_Stream::images, Gif_Stream::nimages, and Gt_Viewer::timer.

Referenced by input_stream_done(), key_press(), and view_frame().

00537 {
00538   int i;
00539   Gif_Stream *gfs = viewer->gfs;
00540   if (animating == viewer->animating || !viewer->can_animate)
00541     return;
00542   for (i = 0; i < gfs->nimages; i++)
00543     viewer->im[i] = gfs->images[i];
00544   viewer->animating = animating;
00545   if (!animating)
00546     viewer->timer.tv_sec = viewer->timer.tv_usec = 0;
00547 }

Pixmap unoptimized_frame Gt_Viewer   viewer,
int    frame,
int    slow
[static]
 

Definition at line 794 of file gifview.c.

References Gt_Viewer::display, Gif_Image::disposal, Gt_Viewer::free_pixmaps, Gt_Viewer::gfs, Gt_Viewer::gfx, GIF_DISPOSAL_PREVIOUS, Gif_XNextImage(), Gif_Stream::images, SAVE_FRAMES, set_viewer_name(), and Gt_Viewer::unoptimized_pixmaps.

Referenced by view_frame().

00795 {
00796   /* create a new unoptimized frame; maybe kill some of the old ones */
00797   if (!viewer->unoptimized_pixmaps[frame]) {
00798     Gif_Stream *gfs = viewer->gfs;
00799     Pixmap last = None, last_last = None;
00800     if (frame >= 2 && gfs->images[frame-1]->disposal == GIF_DISPOSAL_PREVIOUS)
00801       last_last = unoptimized_frame(viewer, frame - 2, slow);
00802     if (frame >= 1)
00803       last = unoptimized_frame(viewer, frame - 1, slow);
00804     
00805     viewer->unoptimized_pixmaps[frame] =
00806       Gif_XNextImage(viewer->gfx, last_last, last, gfs, frame);
00807 
00808     if (viewer->free_pixmaps && frame > 1 && frame % SAVE_FRAMES == 1) {
00809       int kill = frame - 1 - SAVE_FRAMES;
00810       assert(kill >= 0);
00811       for (; kill < frame - 1; kill++)
00812         if (viewer->unoptimized_pixmaps[kill] && kill % 50 != 0) {
00813           XFreePixmap(viewer->display, viewer->unoptimized_pixmaps[kill]);
00814           viewer->unoptimized_pixmaps[kill] = None;
00815         }
00816     }
00817 
00818     if (slow) {
00819       set_viewer_name(viewer, frame);
00820       XFlush(viewer->display);
00821     }
00822   }
00823   
00824   return viewer->unoptimized_pixmaps[frame];
00825 }

void unschedule Gt_Viewer   viewer
 

Definition at line 551 of file gifview.c.

References Gt_Viewer::anim_next, Gt_Viewer::scheduled, and Gt_Viewer::timer.

Referenced by key_press(), pre_delete_viewer(), and schedule_next_frame().

00552 {
00553   Gt_Viewer *prev, *trav;
00554   if (!viewer->scheduled) return;
00555   for (prev = 0, trav = animations; trav; prev = trav, trav = trav->anim_next)
00556     if (trav == viewer)
00557       break;
00558   if (trav) {
00559     if (prev) prev->anim_next = viewer->anim_next;
00560     else animations = viewer->anim_next;
00561   }
00562   viewer->scheduled = 0;
00563   viewer->timer.tv_sec = viewer->timer.tv_usec = 0;
00564 }

void usage void   
 

Definition at line 233 of file gifview.c.

References program_name.

00234 {
00235   printf("\
00236 `Gifview' is a lightweight GIF viewer for X. It can display animated GIFs as\n\
00237 slideshows, one frame at a time, or as animations.\n\
00238 \n\
00239 Usage: %s [--display DISPLAY] [OPTION]... [FILE | FRAME]...\n\
00240 \n\
00241 Options are:\n\
00242   -a, --animate                 Animate multiframe GIFs.\n\
00243   -U, --unoptimize              Unoptimize displayed GIFs.\n\
00244   -d, --display DISPLAY         Set display to DISPLAY.\n\
00245       --name NAME               Set application resource name to NAME.\n\
00246   -g, --geometry GEOMETRY       Set window geometry.\n\
00247   -w, --window WINDOW           Show GIF in existing WINDOW.\n\
00248   -i, --install-colormap        Use a private colormap.\n\
00249   --bg, --background COLOR      Use COLOR for transparent pixels.\n\
00250   +e, --no-interactive          Ignore buttons and keystrokes.\n\
00251       --help                    Print this message and exit.\n\
00252       --version                 Print version number and exit.\n\
00253 \n\
00254 Frame selections:               #num, #num1-num2, #num1-, #name\n\
00255 \n\
00256 Keystrokes:\n\
00257   [Space] Go to next frame.             [B] Go to previous frame.\n\
00258   [R]/[<] Go to first frame.            [>] Go to last frame.\n\
00259   [ESC] Stop animation.                 [S]/[A] Toggle animation.\n\
00260   [U] Toggle unoptimization.            [Backspace]/[W] Delete window.\n\
00261   [Q] Quit.\n\
00262 \n\
00263 Left mouse button goes to next frame, right mouse button deletes window.\n\
00264 \n\
00265 Report bugs to <eddietwo@lcs.mit.edu>.\n", program_name);
00266 }

void view_frame Gt_Viewer   viewer,
int    frame
 

Definition at line 848 of file gifview.c.

References Gt_Viewer::anim_loop, Gt_Viewer::animating, Gt_Viewer::arrow_cursor, Gt_Viewer::being_deleted, create_viewer_window(), Gt_Viewer::display, display, Gt_Viewer::gfs, Gt_Viewer::gfx, Gif_ImageCount, Gif_ImageHeight, Gif_ImageWidth, Gif_XImage(), Gt_Viewer::height, Gt_Viewer::im, Gt_Viewer::im_pos, kill_unoptimized_frames(), Gif_Stream::loopcount, loopcount, Gt_Viewer::nim, Gt_Viewer::pixmap, Gt_Viewer::resizable, schedule_next_frame(), Gif_Stream::screen_height, Gt_Viewer::screen_number, Gif_Stream::screen_width, set_viewer_name(), switch_animating(), unoptimized_frame(), Gt_Viewer::unoptimized_pixmaps, Gt_Viewer::unoptimizing, Gt_Viewer::use_window, Gt_Viewer::wait_cursor, Gt_Viewer::was_unoptimized, Gt_Viewer::width, and Gt_Viewer::window.

Referenced by input_stream_done(), key_press(), and loop().

00849 {
00850   Display *display = viewer->display;
00851   Window window = viewer->window;
00852   Pixmap old_pixmap = viewer->pixmap;
00853   int need_set_name = 0;
00854   
00855   if (viewer->being_deleted)
00856     return;
00857   
00858   if (frame < 0)
00859     frame = 0;
00860   if (frame > viewer->nim - 1 && viewer->animating) {
00861     int loopcount = viewer->gfs->loopcount;
00862     if (loopcount == 0 || loopcount > viewer->anim_loop) {
00863       viewer->anim_loop++;
00864       frame = 0;
00865     } else {
00866       switch_animating(viewer, 0);
00867       need_set_name = 1;
00868     }
00869   }
00870   if (frame > viewer->nim - 1)
00871     frame = viewer->nim - 1;
00872   
00873   if (frame != viewer->im_pos) {
00874     Gif_Image *gfi = viewer->im[frame];
00875     int width, height, changed_cursor = 0;
00876 
00877     /* Change cursor if we need to wait. */
00878     if ((viewer->animating || viewer->unoptimizing)
00879         && !viewer->unoptimized_pixmaps[frame]) {
00880       if (frame > viewer->im_pos + 10 || frame < viewer->im_pos) {
00881         changed_cursor = 1;
00882         XDefineCursor(display, window, viewer->wait_cursor);
00883         XFlush(display);
00884       }
00885     }
00886     
00887     /* 5/26/98 Do some noodling around to try and use memory most effectively.
00888        If animating, keep the uncompressed frame; otherwise, throw it away. */
00889     if (viewer->animating || viewer->unoptimizing)
00890       viewer->pixmap = unoptimized_frame(viewer, frame, changed_cursor);
00891     else
00892       viewer->pixmap = Gif_XImage(viewer->gfx, viewer->gfs, gfi);
00893     
00894     /* put the image on the window */
00895     if (viewer->animating || viewer->unoptimizing)
00896       width = viewer->gfs->screen_width, height = viewer->gfs->screen_height;
00897     else
00898       width = Gif_ImageWidth(gfi), height = Gif_ImageHeight(gfi);
00899     if (!window) {
00900       create_viewer_window(viewer, width, height);
00901       window = viewer->window;
00902     }
00903     XSetWindowBackgroundPixmap(display, window, viewer->pixmap);
00904     if (old_pixmap || viewer->use_window) /* clear if using existing window */
00905       XClearWindow(display, window);
00906     /* Only change size after changing pixmap. */
00907     if ((viewer->width != width || viewer->height != height)
00908         && viewer->resizable) {
00909       XWindowChanges winch;
00910       winch.width = viewer->width = width;
00911       winch.height = viewer->height = height;
00912       XReconfigureWMWindow
00913         (display, window, viewer->screen_number,
00914          CWWidth | CWHeight, &winch);
00915     }
00916 
00917     /* Restore cursor */
00918     if (changed_cursor)
00919       XDefineCursor(display, window, viewer->arrow_cursor);
00920     
00921     /* Get rid of old pixmaps */
00922     if (viewer->was_unoptimized)
00923       kill_unoptimized_frames(viewer, frame);
00924     else if (old_pixmap)
00925       XFreePixmap(display, old_pixmap);
00926     viewer->was_unoptimized = viewer->animating || viewer->unoptimizing;
00927     
00928     /* Do we need a new name? */
00929     if ((!viewer->animating && Gif_ImageCount(viewer->gfs) > 1)
00930         || old_pixmap == None)
00931       need_set_name = 1;
00932     
00933     viewer->im_pos = frame;
00934   }
00935   
00936   if (need_set_name)
00937     set_viewer_name(viewer, -1);
00938   
00939   if (!old_pixmap && !viewer->use_window)
00940     /* first image; map the window */
00941     XMapRaised(display, window);
00942   else if (viewer->animating)
00943     /* only schedule next frame if image is already mapped */
00944     schedule_next_frame(viewer);
00945 }

void warning char *    message,
...   
 

Definition at line 215 of file gifview.c.

References program_name.

00216 {
00217   va_list val;
00218   va_start(val, message);
00219   fprintf(stderr, "%s: warning: ", program_name);
00220   vfprintf(stderr, message, val);
00221   fputc('\n', stderr);
00222 }

Variable Documentation

int animating = 0 [static]
 

Definition at line 153 of file gifview.c.

Referenced by input_stream_done(), main(), and switch_animating().

Gt_Viewer* animations [static]
 

Definition at line 152 of file gifview.c.

Cursor cur_arrow_cursor = 0 [static]
 

Definition at line 145 of file gifview.c.

Referenced by main(), and new_viewer().

const char* cur_background_color = "black" [static]
 

Definition at line 149 of file gifview.c.

Referenced by main(), and new_viewer().

Display* cur_display = 0 [static]
 

Definition at line 143 of file gifview.c.

Referenced by get_input_stream(), main(), and next_viewer().

char* cur_display_name = 0 [static]
 

Definition at line 142 of file gifview.c.

Referenced by get_input_stream(), and main().

char* cur_geometry_spec = 0 [static]
 

Definition at line 144 of file gifview.c.

Referenced by create_viewer_window(), and main().

const char* cur_resource_name [static]
 

Definition at line 147 of file gifview.c.

Referenced by create_viewer_window(), and main().

Window cur_use_window = None [static]
 

Definition at line 148 of file gifview.c.

Referenced by main(), and next_viewer().

Cursor cur_wait_cursor = 0 [static]
 

Definition at line 146 of file gifview.c.

Referenced by main(), and new_viewer().

struct timeval genesis_time
 

Definition at line 87 of file gifview.c.

Referenced by main().

int install_colormap = 0 [static]
 

Definition at line 155 of file gifview.c.

Referenced by choose_visual(), and main().

int interactive = 1 [static]
 

Definition at line 156 of file gifview.c.

Referenced by main().

Clp_Option options[]
 

Initial value:

 {
  { "animate", 'a', ANIMATE_OPT, 0, Clp_Negate },
  { "background", 'b', BACKGROUND_OPT, Clp_ArgString, 0 },
  { "bg", 0, BACKGROUND_OPT, Clp_ArgString, 0 },
  { "display", 'd', DISPLAY_OPT, Clp_ArgStringNotOption, 0 },
  { "geometry", 'g', GEOMETRY_OPT, Clp_ArgString, 0 },
  { "install-colormap", 'i', INSTALL_COLORMAP_OPT, 0, Clp_Negate },
  { "interactive", 'e', INTERACTIVE_OPT, 0, Clp_Negate },
  { "help", 0, HELP_OPT, 0, 0 },
  { "name", 0, NAME_OPT, Clp_ArgString, 0 },
  { "unoptimize", 'U', UNOPTIMIZE_OPT, 0, Clp_Negate },
  { "version", 0, VERSION_OPT, 0, 0 },
  { "window", 'w', WINDOW_OPT, WINDOW_TYPE, 0 },
}

Definition at line 173 of file gifview.c.

const char* program_name = "gifview"
 

Definition at line 140 of file gifview.c.

Referenced by error(), fatal_error(), main(), short_usage(), usage(), and warning().

int unoptimizing = 0 [static]
 

Definition at line 154 of file gifview.c.

Referenced by main(), and new_viewer().

Gt_Viewer* viewers [static]
 

Definition at line 151 of file gifview.c.

Atom wm_delete_window_atom [static]
 

Definition at line 650 of file gifview.c.

Referenced by create_viewer_window(), and loop().

Atom wm_protocols_atom [static]
 

Definition at line 651 of file gifview.c.

Referenced by create_viewer_window(), and loop().

 

Powered by Plone

This site conforms to the following standards: