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(). |