Doxygen Source Code Documentation
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_Viewer * | new_viewer (Display *display, Window use_window, Gif_Stream *gfs, char *name) |
void | delete_viewer (Gt_Viewer *viewer) |
Gt_Viewer * | next_viewer (Gif_Stream *gfs, char *name) |
Gt_Viewer * | get_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_Viewer * | find_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_Viewer * | viewers |
Gt_Viewer * | animations |
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
|
Definition at line 162 of file gifview.c. Referenced by main(). |
|
Definition at line 169 of file gifview.c. Referenced by main(). |
|
Definition at line 159 of file gifview.c. Referenced by main(). |
|
|
|
Definition at line 163 of file gifview.c. Referenced by main(). |
|
Definition at line 165 of file gifview.c. Referenced by main(). |
|
Definition at line 167 of file gifview.c. Referenced by main(). |
|
Definition at line 168 of file gifview.c. Referenced by main(). |
|
Definition at line 45 of file gifview.c. Referenced by schedule_next_frame(). |
|
Definition at line 164 of file gifview.c. Referenced by main(). |
|
Definition at line 39 of file gifview.c. Referenced by unoptimized_frame(). |
|
Definition at line 160 of file gifview.c. Referenced by main(). |
|
Definition at line 161 of file gifview.c. Referenced by main(). |
|
|
|
Definition at line 166 of file gifview.c. Referenced by main(). |
|
Definition at line 171 of file gifview.c. Referenced by main(). |
|
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(). |
|
Definition at line 86 of file gifview.c. Referenced by loop(), and schedule_next_frame(). |
|
Definition at line 83 of file gifview.c. Referenced by main(). |
|
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) |
|
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(). |
|
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(). |
|
Value: ((a).tv_sec > (b).tv_sec || \ ((a).tv_sec == (b).tv_sec && (a).tv_usec > (b).tv_usec)) |
|
|
Typedef Documentation
|
|
Function Documentation
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 743 of file gifview.c. References Gt_Viewer::display, display, Gt_Viewer::next, v, and Gt_Viewer::window. Referenced by loop().
|
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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
|
Definition at line 153 of file gifview.c. Referenced by input_stream_done(), main(), and switch_animating(). |
|
|
|
Definition at line 145 of file gifview.c. Referenced by main(), and new_viewer(). |
|
Definition at line 149 of file gifview.c. Referenced by main(), and new_viewer(). |
|
Definition at line 143 of file gifview.c. Referenced by get_input_stream(), main(), and next_viewer(). |
|
Definition at line 142 of file gifview.c. Referenced by get_input_stream(), and main(). |
|
Definition at line 144 of file gifview.c. Referenced by create_viewer_window(), and main(). |
|
Definition at line 147 of file gifview.c. Referenced by create_viewer_window(), and main(). |
|
Definition at line 148 of file gifview.c. Referenced by main(), and next_viewer(). |
|
Definition at line 146 of file gifview.c. Referenced by main(), and new_viewer(). |
|
Definition at line 87 of file gifview.c. Referenced by main(). |
|
Definition at line 155 of file gifview.c. Referenced by choose_visual(), and main(). |
|
Definition at line 156 of file gifview.c. Referenced by main(). |
|
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 140 of file gifview.c. Referenced by error(), fatal_error(), main(), short_usage(), usage(), and warning(). |
|
Definition at line 154 of file gifview.c. Referenced by main(), and new_viewer(). |
|
|
|
Definition at line 650 of file gifview.c. Referenced by create_viewer_window(), and loop(). |
|
Definition at line 651 of file gifview.c. Referenced by create_viewer_window(), and loop(). |