qiv-2.2.4.orig/0000755000175000017500000000000011566230264012256 5ustar bartmbartmqiv-2.2.4.orig/qiv.h0000644000175000017500000001635111563226774013244 0ustar bartmbartm/* Up to release 1.3 of imlib2 there is a problem with the includes. Imlib2.h does not load Xlib.h. Workaround: add the following line: #include */ #include #include #include #include #ifdef GTD_XINERAMA # include # include #endif /* // [as] thinks that this is not portable enough // [lc] // I use a virtual screen of 1600x1200, and the resolution is 1024x768, // so I changed how screen_[x,y] is obtained; it seems that gtk 1.2 // cannot give the geometry of viewport, so I borrowed from the source of // xvidtune the code for calling XF86VidModeGetModeLine, this requires // the linking option -lXxf86vm. #include #include // for XF86VidModeGetModeLine */ #define VERSION "2.2.4" #define VERSION_FULL "QIV - Quick Image Viewer v2.2.4 - http://qiv.spiegl.de/" #define TRASH_DIR ".qiv-trash" #define SELECT_DIR ".qiv-select" #define SLIDE_DELAY 3000 /* milliseconds */ #define IMAGE_BG "black" #define STATUSBAR_BG "#FFB900" #define STATUSBAR_FS 8 /* default fontsize if none is given */ #define ERROR_BG "#0000FF" #define DEFAULT_BRIGHTNESS 256 #define DEFAULT_CONTRAST 256 #define DEFAULT_GAMMA 256 #define BUF_LEN 1024 /* FILENAME_LEN is the maximum length of any path/filename that can be * handled. MAX_DELETE determines how many items can be placed into * the kill-ring for undelete handling. */ #define FILENAME_LEN 1024 #define MAX_DELETE 1024 /* [pw] Warning: qiv uses the imlib 1.x units. Not what imlib 2 wants. */ typedef struct _qiv_color_modifier { int gamma, brightness, contrast; } qiv_color_modifier; typedef struct _qiv_image { qiv_color_modifier mod; /* Image modifier (for brightness..) */ GdkPixmap *p; /* Pixmap of the image to display */ GdkWindow *win; /* Main window for windowed and fullscreen mode */ int error; /* 1 if Imlib couldn't load image */ gint win_x, win_y, win_w, win_h; /* window co-ordinates */ gint orig_w, orig_h; /* Size of original image in pixels */ GdkGC *bg_gc; /* image window background */ GdkGC *text_gc; /* statusbar text color */ GdkGC *status_gc; /* statusbar background */ /* These are used to work out how to redraw in fullscreen mode */ gint win_ox, win_oy, win_ow, win_oh; /* coordinates currently drawn at */ gint text_ow, text_oh; /* old size of the statusbar */ int statusbar_was_on; /* true if statusbar was visible last frame */ int exposed; /* window became visible */ int drag; /* user is currently dragging the image */ double drag_start_x, drag_start_y; /* position of cursor at drag start */ int drag_win_x, drag_win_y; /* position of win at drag start */ // char infotext[BUF_LEN]; gchar win_title[BUF_LEN]; gint text_len, text_w, text_h; } qiv_image; typedef struct _qiv_mgl { /* [pw] needs a seperate context? */ qiv_color_modifier mod; /* Image modifier (for brightness..) */ GdkPixmap *p; /* Pixmap of the image to display */ GdkWindow *win; /* window for magnify */ gint win_x, win_y, win_w, win_h; /* window coordinates */ gint frame_x, frame_y; /* UpLeft Corner of frame (titlebar included) of */ /* main qiv_image */ // GdkGC *bg_gc; /* image window background */ // int exposed; /* window became visible */ } qiv_mgl; /* the magnifying glass [lc] */ typedef struct _qiv_deletedfile { char *filename, *trashfile; int pos; } qiv_deletedfile; extern int first; extern char infotext[BUF_LEN]; extern GMainLoop *qiv_main_loop; extern gint screen_x, screen_y; extern GdkFont *text_font; extern GdkColormap *cmap; extern char *image_bg_spec; extern GdkColor image_bg; extern GdkColor text_bg; extern GdkColor error_bg; extern int images; extern char **image_names; extern int image_idx; extern int max_image_cnt; extern time_t current_mtime; extern qiv_deletedfile *deleted_files; extern int delete_idx; extern char select_dir[FILENAME_LEN]; extern PangoLayout *layout; extern PangoFontDescription *fontdesc; extern PangoFontMetrics *metrics; extern int filter; extern gint center; extern gint cycle; extern gint default_brightness; extern gint default_contrast; extern gint default_gamma; extern gint delay; extern int readonly; extern int random_order; extern int random_replace; extern int fullscreen; extern int maxpect; extern int statusbar_fullscreen; extern int statusbar_window; extern int slide; extern int scale_down; extern int recursive; extern int to_root; extern int to_root_t; extern int to_root_s; extern int transparency; extern int do_grab; extern int disable_grab; extern int max_rand_num; extern int fixed_window_size; extern int fixed_zoom_factor; extern int zoom_factor; extern int watch_file; extern int browse; extern int magnify; // [lc] extern qiv_mgl magnify_img; // [lc] extern int autorotate; extern int rotation; extern const char *helpstrs[], **helpkeys, *image_extensions[]; #ifdef GTD_XINERAMA extern XineramaScreenInfo preferred_screen[1]; extern XineramaScreenInfo statusbar_screen[1]; extern int user_screen; extern int number_xinerama_screens; extern void get_preferred_xinerama_screens(void); #endif /* main.c */ extern void qiv_exit(int); extern void qiv_load_image(); /* image.c */ /* Modes for update_image */ #define REDRAW 0 #define MOVED 1 #define ZOOMED 2 #define FULL_REDRAW 3 extern void qiv_load_image(qiv_image *); extern void set_desktop_image(qiv_image *); extern void zoom_in(qiv_image *); extern void zoom_out(qiv_image *); extern void zoom_maxpect(qiv_image *); extern void reload_image(qiv_image *q); extern void reset_coords(qiv_image *); extern void check_size(qiv_image *, gint); extern void render_to_pixmap(qiv_image *, double *); extern void update_image(qiv_image *, int); extern void reset_mod(qiv_image *); extern void destroy_image(qiv_image *q); extern void center_image(qiv_image *q); extern void correct_image_position(qiv_image *q); extern void hide_cursor(qiv_image *q); extern void show_cursor(qiv_image *q); extern void setup_magnify(qiv_image *, qiv_mgl *); // [lc] extern void update_magnify(qiv_image *, qiv_mgl *,int, gint, gint); // [lc] /* event.c */ extern void qiv_handle_event(GdkEvent *, gpointer); /* options.c */ extern void options_read(int, char **, qiv_image *); /* utils.c */ extern int move2trash(void); extern int copy2select(void); extern int undelete_image(void); extern void jump2image(char *); extern void run_command(qiv_image *, char *, char *, int *, const char ***); extern void finish(int); extern void next_image(int); extern int checked_atoi(const char *); extern void usage(char *, int); extern void show_help(char *, int); extern int get_random(int, int, int); extern gboolean color_alloc(const char *, GdkColor *); extern void swap(int *, int *); #define myround qiv_round extern int myround(double); extern gboolean qiv_watch_file (gpointer); extern int rreaddir(const char *, int); extern int rreadfile(const char *); extern int find_image(int images, char **image_names, char *name); qiv-2.2.4.orig/README.INSTALL0000644000175000017500000000077711563226774014266 0ustar bartmbartmPlease read the "README" file first! If you are using Debian/GNU Linux (or a derivative thereof) just type: dpkg-buildpackage -uc -B -m"your@email.address" -rfakeroot Otherwise type: "make install" (or "gmake install", if your standard make doesn't like the Makefile) to compile and install qiv. If you are compiling on FreeBSD, Solaris, or any other system without GNU getopt_long, comment out the GETOPT_LONG line in the Makefile. There are also a few other options there that can be set at compile time. qiv-2.2.4.orig/upstreamdebian/0000755000175000017500000000000011563226774015271 5ustar bartmbartmqiv-2.2.4.orig/upstreamdebian/examples0000644000175000017500000000001411563226774017025 0ustar bartmbartmqiv-command qiv-2.2.4.orig/upstreamdebian/qiv.mime0000644000175000017500000000344411563226774016746 0ustar bartmbartmimage/gif; qiv -tfi %s; description="GIF Image"; test=test "$DISPLAY"; nametemplate=%s.gif; priority=4 image/jpeg; qiv -tfi %s; description="JPEG Image"; test=test "$DISPLAY"; nametemplate=%s.jpeg; priority=4 image/pjpeg; qiv -tfi %s; description="JPEG Image"; test=test "$DISPLAY"; nametemplate=%s.jpeg; priority=4 image/tiff; qiv -tfi %s; description="TIFF Image"; test=test "$DISPLAY"; nametemplate=%s.tiff; priority=4 image/x-portable-bitmap; qiv -tfi %s; description="PBM Image"; test=test "$DISPLAY"; nametemplate=%s.pbm; priority=4 image/x-portable-graymap; qiv -tfi %s; description="PGM Image"; test=test "$DISPLAY";nametemplate=%s.pgm; priority=4 image/x-portable-pixmap; qiv -tfi %s; description="PPM Image"; test=test "$DISPLAY"; nametemplate=%s.ppm; priority=4 image/x-xbitmap; qiv -tfi %s; description="XBM Image"; test=test "$DISPLAY"; nametemplate=%s.xbm; priority=4 image/x-xpixmap; qiv -tfi %s; description="XPM Image"; test=test "$DISPLAY"; nametemplate=%s.xpm; priority=4 image/bmp; qiv -tfi %s; description="BMP Image"; test=test "$DISPLAY"; nametemplate=%s.bmp; priority=4 image/x-bmp; qiv -tfi %s; description="BMP Image"; test=test "$DISPLAY"; nametemplate=%s.bmp; priority=4 image/x-ms-bmp; qiv -tfi %s; description="BMP Image"; test=test "$DISPLAY"; nametemplate=%s.bmp; priority=4 image/x-rgb; qiv -tfi %s; description="RGB Image"; test=test "$DISPLAY"; nametemplate=%s.rgb; priority=4 image/targa; qiv -tfi %s; description="TARGA Image"; test=test "$DISPLAY"; nametemplate=%s.tga; priority=4 image/fits; qiv -tfi %s; description="FITS Image"; test=test "$DISPLAY"; nametemplate=%s.fits; priority=4 image/png; qiv -tfi %s; description="PNG Image"; test=test "$DISPLAY"; nametemplate=%s.png; priority=4 image/pm; qiv -tfi %s; description="PM Image"; test=test "$DISPLAY"; nametemplate=%s.pm; priority=4 qiv-2.2.4.orig/upstreamdebian/manpages0000644000175000017500000000000611563226774017003 0ustar bartmbartmqiv.1 qiv-2.2.4.orig/upstreamdebian/rules0000755000175000017500000000072411563226774016354 0ustar bartmbartm#!/usr/bin/make -f DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) DEB_PATCHDIRS := debian/patches debian/patches_$(DEB_HOST_ARCH) include /usr/share/cdbs/1/class/makefile.mk include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk update-config:: [ -f qiv-command ] || mv qiv-command.example qiv-command reverse-config:: [ ! -f qiv-command ] || mv qiv-command qiv-command.example clean:: rm -f qiv xmalloc.o qiv-2.2.4.orig/upstreamdebian/watch0000644000175000017500000000007111563226774016320 0ustar bartmbartmversion=3 http://qiv.spiegl.de/download/qiv-(.*)-src.tgz qiv-2.2.4.orig/upstreamdebian/compat0000644000175000017500000000000211563226774016467 0ustar bartmbartm5 qiv-2.2.4.orig/upstreamdebian/docs0000644000175000017500000000003511563226774016142 0ustar bartmbartmintro.jpg README.TODO README qiv-2.2.4.orig/upstreamdebian/install0000644000175000017500000000001411563226774016655 0ustar bartmbartmqiv usr/bin qiv-2.2.4.orig/upstreamdebian/changelog0000644000175000017500000002611411563226774017147 0ustar bartmbartmqiv (2.2.4) unstable; urgency=low * new upstream version; see Changelog for details -- Andy Spiegl Mon, 02 May 2011 16:26:51 +0200 qiv (2.2.4pre) unstable; urgency=low * new upstream version; see Changelog for details -- Andy Spiegl Wed, 14 Apr 2010 18:00:00 +0200 qiv (2.2.3) unstable; urgency=low * new upstream version; see Changelog for details -- Andy Spiegl Wed, 10 Jan 2010 22:34:00 +0100 qiv (2.2.3pre) unstable; urgency=low * new upstream version; see Changelog for details -- Andy Spiegl Wed, 02 Aug 2009 23:59:00 +0200 qiv (2.2.2) unstable; urgency=low * new upstream version; see Changelog for details -- Andy Spiegl Wed, 30 May 2009 23:59:00 +0200 qiv (2.2.1) unstable; urgency=low * new upstream version; see Changelog for details -- Andy Spiegl Wed, 26 May 2009 18:30:00 +0200 qiv (2.2) unstable; urgency=low * migration from imlib1 to imlib2 * new upstream version; see Changelog for details -- Andy Spiegl Thu, 30 Apr 2009 12:00:00 +0200 qiv (2.1) unstable; urgency=low * Adam Kopacz delegated to Andy Spiegl as new upstream maintainer * new homepage: http://qiv.spiegl.de/ * new upstream version; see Changelog for details -- Andy Spiegl Thu, 05 Mar 2009 23:19:00 +0100 qiv (2.1-pre13) unstable; urgency=low * small patch to prevent segfault on amd64 * removed debian/lintian/qiv -- Andy Spiegl Thu, 24 May 2007 11:19:43 +0200 qiv (2.1-pre12) unstable; urgency=low * new upstream developer version; see Changelog for details -- Andy Spiegl Wed, 02 May 2007 23:00:00 +0200 qiv (2.1-pre11) unstable; urgency=low * new upstream developer version; see Changelog for details -- Andy Spiegl Wed, 25 Apr 2007 04:00:00 +0200 qiv (2.0-8) unstable; urgency=low * debian/README.Debian, debian/docs: Removed README.Debian, and install debian/NEWS.Debian. Closes: #403936. * debian/qiv.mime: Updated. Closes: #404220. Thanks to Roman Galeyev . -- Bart Martens Sat, 27 Jan 2007 17:02:56 +0100 qiv (2.0-7) unstable; urgency=low * debian/NEWS.Debian: Added. * debian/patches/10_qiv-nosort_2.diff: Added. Closes: #383110. * debian/patches/11_no_background_opts_2.diff: Added. Closes: #351816. -- Bart Martens Wed, 6 Dec 2006 19:58:52 +0100 qiv (2.0-6) unstable; urgency=low * debian/patches/07_no_background_opts.diff: Added. Closes: #351816. * debian/patches/08_hide_therealqiv.diff: Added, to hide "therealqiv". * debian/patches/09_man_xscreensaver.diff: Added. Closes: #360514. * debian/bin/qiv: Use "exec". Closes: #399596. -- Bart Martens Wed, 22 Nov 2006 14:52:29 +0100 qiv (2.0-5) unstable; urgency=low * New maintainer. Closes: #398124. * Acknowledge NMU's. Closes: #320115, #347042. * debian/*: Repackaged with cdbs. * debian/control: Updated build-depends to gdk-imlib11-dev. * debian/patches/*: Converted dpatches to diff files. * debian/patches/02.typo_envoked.diff: Added. Closes: #311232. Patch by A Costa , thanks. * debian/patches/04.qiv-nosort.diff: Added. Closes: #383110. Patch by Kevin Locke , thanks. * debian/patches/05.qiv-manpage-options.diff: Added. Closes: #383108. Patch by Kevin Locke , thanks. * debian/patches/06.xmalloc.diff: Added. Closes: #383113. Patch by Kevin Locke , thanks. * debian/watch: Added. * debian/bin/qiv, debian/lintian/qiv, debian/rules: Add wrapper using XLIB_SKIP_ARGB_VISUALS=1 as workaround for problem in qiv with X composite extension. Closes: #326849. Thanks to Joerg Platte . -- Bart Martens Sun, 12 Nov 2006 09:21:38 +0100 qiv (2.0-4.2) unstable; urgency=low * NMU. * debian/patches/02.improves_bgimage_setting.dpatch, debian/patches/00list: Removed patch with regression. Closes: #320115. * debian/copyright: Fixed old-fsf-address-in-copyright-file. * debian/control: Standards version. * debian/control: Adjusted homepage. -- Bart Martens Sat, 13 May 2006 21:00:04 +0200 qiv (2.0-4.1) unstable; urgency=low * Non-maintainer upload. * Update build-deps for xlibs-dev removal; closes: #347042. -- Justin Pryzby Sat, 14 Jan 2006 15:23:43 -0500 qiv (2.0-4) unstable; urgency=low * New maintainer (Closes: #304096) * added Homepage to long description * use dpatch now * Closes: #294293: qiv should support the new background setting mechanism; used provided patch * Closes: #262986: more customizable keys for qiv-command; used provided patch -- Christoph Wegscheider Sun, 22 May 2005 09:03:12 +0200 qiv (2.0-3) unstable; urgency=low * eliminated warning about missing Xinerama extension on non-Xinerama displays * correctly center image on Xinerama displays * Thanks to Geoffrey T. Dairiki for these patches! -- Martin Pitt Wed, 16 Jun 2004 21:04:31 +0200 qiv (2.0-2) unstable; urgency=low * enabled Xinerama support in Makefile (closes: #253880) -- Martin Pitt Sun, 13 Jun 2004 11:34:10 +0200 qiv (2.0-1) unstable; urgency=low * new upstream version; key "PageUp" now does not crash any more when there are less than five pictures. closes: #246732 * updated description -- Martin Pitt Sun, 23 May 2004 23:53:16 +0200 qiv (1.9-4) unstable; urgency=low * short option for --ignore_path_sort is now correctly documented as -P (manpage and --help). (closes: #234174) -- Martin Pitt Mon, 23 Feb 2004 19:46:04 +0100 qiv (1.9-3) unstable; urgency=low * Added option -B / --noblank to disable screensaver and DPMS during execution (closes: #178668) -- Martin Pitt Wed, 4 Feb 2004 23:42:46 +0100 qiv (1.9-2) unstable; urgency=low * shortened NAME section in manpage (closes: #230752) * stated copyright holders in debian/copyright -- Martin Pitt Tue, 3 Feb 2004 20:07:11 +0100 qiv (1.9-1) unstable; urgency=low * new upstream release (some new features, upstream took over my patches) * correctly install README.CHANGES as upstream changelog * updated long description -- Martin Pitt Sun, 14 Dec 2003 23:38:53 +0100 qiv (1.8-6) unstable; urgency=low * qiv.mime: now gives option '-n' to ignore file extension (better for mail attachments etc.) (closes: #217226) * changed my Maintainer address -- Martin Pitt Tue, 28 Oct 2003 17:49:31 +0100 qiv (1.8-5) unstable; urgency=low * undeleting a file now also works on FAT file systems (closes: #210550) (this really was the last spot using link(), I checked!) -- Martin Pitt Fri, 12 Sep 2003 12:16:29 +0200 qiv (1.8-4) unstable; urgency=low * deleting a file now also works on FAT file systems (closes: #209079) * updated Standards-Version to 3.6.1 (no changes required) -- Martin Pitt Tue, 9 Sep 2003 11:26:37 +0200 qiv (1.8-3) unstable; urgency=low * new maintainer (closes: #193604) * debian/control: updated maintainer and wrong upstream URL * debian/copyright: replaced copyright with standard GPL clause * fixed build-deps: removed unnecessary libglib1.2-dev, added gdk-imlib-dev as alternative to make it Woody-compatible * debian/qiv.mime: added image/pjpeg type (closes: #193643) * image.c, reload_image(): now checked image loading for errors, thanks to Niels Andersen; patch sent to upstream who included it (closes: #194575) * updated to standards version 3.5.10: DH_COMPAT -> debian/compat, respect DEB_BUILD_OPTIONS * cleaned up debian/ directory: removed dirs, docs (debian/rules does that now) * removed debian/patches/: Makefile patch not needed any more, patch to options.c incorporated into package.diff.gz (also sent to upstream who included it in next version) * complete rewrite of debian/rules * included intro.jpg and qiv-command.example in package * removed Emacs' local variables stuff from Debian changelog -- Martin Pitt Mon, 26 May 2003 20:34:28 +0200 qiv (1.8-2) unstable; urgency=low * Builded against gdk-imlib1. -- Luis Bustamante Thu, 6 Feb 2003 07:25:08 -0500 qiv (1.8-1) unstable; urgency=low * The I-will-take-care-of-qiv release. * Package builded from the scratch. Updated to standards version 3.5.8. * New maintainer (closes: #176329). * New upstream release (closes: #156155). * It seems qiv handles bmp files correctly now (closes: #120681). * Builded against gdk-imlib2 (closes: #158926). * Better delay handling for slideshow. Thanks to Samuele Giovanni Tonon (closes: #159019). * Stop clearing when panning in full screen mode (closes: #150951). * Show images with unknown extensions using -n option (closes: #99811). -- Luis Bustamante Thu, 16 Jan 2003 12:00:55 -0500 qiv (1.7-0.2) unstable; urgency=medium * Non-maintainer upload. * Move man page from /usr/man to /usr/share/man (closes: #141105). -- Colin Watson Thu, 18 Apr 2002 00:08:22 +0100 qiv (1.7-0.1) unstable; urgency=low * NMU * New Upstream release (Closes: #110115) * Upstream fixed: (Closes: #97090) * moved binary and manpage to /usr, not /usr/X11R6 * This isnt a Debian native package, lets give it an orig.tar.gz, not a tar.gz.. Tsk. -- Michael Beattie Fri, 22 Feb 2002 23:57:20 +1200 qiv (1.6-1) unstable; urgency=low * Upstream release (closes: #82827) -- Mitch Blevins Sun, 11 Feb 2001 16:07:31 -0600 qiv (1.5-2) unstable; urgency=low * Added Build-Depends (closes: Bug#82405) -- Mitch Blevins Mon, 15 Jan 2001 23:53:58 -0600 qiv (1.5-1) unstable; urgency=low * Upstream release (closes: Bug#77504) * Fixed typo in description (closes: Bug#56126) * Added mime types to /etc/mailcap (closes: Bug#61598) -- Mitch Blevins Thu, 4 Jan 2001 19:08:35 -0600 qiv (1.1-1) unstable; urgency=low * Upstream release -- Mitch Blevins Mon, 31 May 1999 23:09:11 -0400 qiv (1.0-5) unstable; urgency=low * Recompiled for gtk/glib 1.2 -- Mitch Blevins Sat, 6 Mar 1999 01:28:09 -0500 qiv (1.0-4) unstable; urgency=low * Recomplied to fix multiple libglib dependencies -- Mitch Blevins Tue, 2 Feb 1999 10:30:10 -0500 qiv (1.0-3) unstable; urgency=low * Removed install from default target in Makefile -- Mitch Blevins Mon, 11 Jan 1999 07:48:26 -0500 qiv (1.0-2) unstable; urgency=low * Updated libjpeg dependancies -- Mitch Blevins Sat, 14 Nov 1998 02:27:23 -0500 qiv (1.0-1) unstable; urgency=low * Initial Release. -- Mitch Blevins Sun, 8 Nov 1998 23:37:24 -0500 qiv-2.2.4.orig/upstreamdebian/copyright0000644000175000017500000000664411563226774017236 0ustar bartmbartmThis package was debianized by Mitch Blevins on Sun, 8 Nov 1998 23:37:24 -0500 It was downloaded from http://qiv.spiegl.de/download/ The homepage of the original author Adam Kopacz is http://www.klografx.net/qiv/ Upstream Authors: (see below) Adam Kopacz Andy Spiegl Darren Smith Pavel Andreev Decklin Foster Holger Mueller Scott Sams Serge Winitzki Frederic Crozat Rutger Nijlunsing John Knottenbelt Danny Tomas Ogren Erik Jacobsen Alfred Weyers Daniel Henning Kulander Ask Bjoern Hansen Adrian Lopez Y Furuhashi Wayne Davison Johannes Stezenbach OEyvind Kolaas Matthieu Castet Geoffrey T. Dairik Leopoldo Cerbaro Heikki Lehvaslaiho Larry Doolittle S. Dobrev Thomas Wiegner Barry deFreese Peter deWachter Akos Pasztory Copyright: Copyright (C) 1989-2009 the above-mentioned authors See "Changelog" for details who did what when. Copyright (C) 1987-1997 Free Software Foundation, Inc. For lib/getopt*. License: This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991. This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this package; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. On Debian GNU/Linux systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. The file debian/patches/06.xmalloc.diff is: * Created by Kevin Locke (from numerous canonical examples) * * I hereby place this file in the public domain. It may be freely reproduced, * distributed, used, modified, built upon, or otherwise employed by anyone * for any purpose without restriction. Kevin Locke wrote on bug 383113: I have attached my stock do-or-die memory handling functions (public domain, but easily relicensable to GPL if desired), and a patch to incorporate those functions into qiv. qiv-2.2.4.orig/upstreamdebian/control0000644000175000017500000000171011563226774016673 0ustar bartmbartmSource: qiv Section: graphics Priority: extra Maintainer: Bart Martens Recommends: libwmf0.2-7, librsvg2-common Build-Depends: cdbs, debhelper (>= 5), libimlib2-dev, libgtk2.0-dev, libx11-dev, libxinerama-dev, libmagic-dev Standards-Version: 3.7.3 Homepage: http://qiv.spiegl.de/ Package: qiv Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: A quick image viewer for X Quick Image Viewer (qiv) is a very small and pretty fast GDK/Imlib image viewer. Features include zoom, maxpect, scale down, fullscreen, brightness/contrast/gamma correction, slideshow, pan with keyboard and mouse, rotate left/right, flip, delete (move to .qiv-trash/), jump to image x, jump forward/backward x images, filename filter, and you can use qiv to set your X11-Desktop background. With support for Xinerama. . qiv also supports the assignment of external commands (like metacam) to unused keys. . Homepage: http://qiv.spiegl.de/ qiv-2.2.4.orig/main.h0000644000175000017500000001540411563226774013367 0ustar bartmbartm#ifndef MAIN_H #define MAIN_H int first = 1; /* TRUE if this is first image or after fullscreen or iconifying */ char infotext[BUF_LEN]; GMainLoop *qiv_main_loop; gint screen_x, screen_y; /* Size of the screen in pixels */ GdkColormap *cmap; /* global colormap */ char *image_bg_spec = IMAGE_BG; GdkColor image_bg; /* default background */ GdkColor text_bg; /* statusbar and help backgrounf */ GdkColor error_bg; /* for the error window/screen */ int images; /* Number of images in current collection */ char **image_names = NULL; /* Filenames of the images */ int image_idx = 0; /* Index of current image displayed. 0 = 1st image */ int max_image_cnt = 0; /* # images currently allocated into arrays */ time_t current_mtime; /* modification time of file currently loaded */ qiv_deletedfile *deleted_files; int delete_idx; char select_dir[FILENAME_LEN]; /* stuff for rendering statusbar, infotext, etc ... */ PangoLayout *layout; PangoFontMetrics *metrics; PangoFontDescription *fontdesc; /* Options and such */ int filter = FILTER; gint center = CENTER; gint cycle = 0; /* TRUE if cycle between images */ gint default_brightness = DEFAULT_BRIGHTNESS; gint default_contrast = DEFAULT_CONTRAST; gint default_gamma = DEFAULT_GAMMA; gint delay = SLIDE_DELAY; /* delay in slideshow mode in seconds */ int readonly = 0; /* TRUE if (un)deletion of images should be impossible */ int random_order; /* TRUE if random delay in slideshow */ int random_replace = 1; /* random with replacement by default */ int fullscreen; /* TRUE if fullscreen mode */ int maxpect; /* TRUE if autozoom (fit-to-screen) mode */ int statusbar_fullscreen = 1; /* TRUE if statusbar in fullscreen is turned on (default) */ int statusbar_window = 0; /* FALSE if statusbar in window is turned off (default) */ int slide; /* 1=slide show running */ int scale_down; /* resize down if image x/y > screen */ int recursive; /* descend recursively */ int to_root; /* display on root (centered) */ int to_root_t; /* display on root (tiled) */ int to_root_s; /* display on root (stretched) */ int transparency; /* transparency on/off */ int do_grab; /* grab keboard/pointer (default off) */ int disable_grab; /* disable keyboard/mouse grabbing in fullscreen mode */ int max_rand_num; /* the largest random number range we will ask for */ int fixed_window_size = 0; /* window width fixed size/off */ int fixed_zoom_factor = 0; /* window fixed zoom factor (percentage)/off */ int zoom_factor = 0; /* zoom factor/off */ int watch_file = 0; /* watch current files Timestamp, reload if changed */ int magnify = 0; /* [lc] */ int user_screen = -1; /* preferred (by user) Xinerama screen */ int browse = 0; /* scan directory of file for browsing */ int autorotate = 0; /* autorotate JPEGs according to EXIF tag */ int rotation = 0; /* rotation x degrees clockwise, 1=90degrees 2=180degrees 3=270degrees */ #ifdef GTD_XINERAMA int number_xinerama_screens = 0; XineramaScreenInfo preferred_screen[1]; XineramaScreenInfo statusbar_screen[1]; #endif /* Used for the ? key */ const char *helpstrs[] = { VERSION_FULL, "", "space/left mouse/wheel down next picture", "backspace/right mouse/wheel up previous picture", "PgDn 5 pictures forward", "PgUp 5 pictures backward", "q/ESC/middle mouse exit", "", "0-9 Run 'qiv-command '", "^ Run 'qiv-command ^ '", "?/F1 show keys (in fullscreen mode)", "F11/F12 in/decrease slideshow delay (1 second)", "a/A copy current image to .qiv-select", "d/D/del move picture to .qiv-trash", "u undelete the previously trashed image", "+/=/wheel r/btn fwd zoom in (10%)", "-/wheel l/btn back zoom out (10%)", "e center mode on/off", "f fullscreen mode on/off", "m scale to screen size on/off", "t scale down on/off", "X cycle through xinerama screens", "s slide show on/off", "p transparency on/off", "r random order on/off", "b - brightness", "B + brightness", "c - contrast", "C + contrast", "g - gamma", "G + gamma", "o reset brightness, contrast, gamma", "h flip horizontal", "v flip vertical", "k rotate right", "l rotate left", "jtx jump to image number x", "jfx jump forward x images", "jbx jump backward x images", "enter/return reset zoom, rotation and color settings", "i statusbar on/off", "I iconify window", "w watch file on/off", "x center image on background", "y tile image on background", "z stretch image on background", "< turn on/off magnifying window", "arrow keys move image (in fullscreen mode)", "arrow keys+Shift move image faster (in fullscreen mode)", "NumPad-arrow keys+NumLock move image faster (in fullscreen mode)", NULL }; /* For --help output, we'll skip the first two lines. */ const char **helpkeys = helpstrs+2; /* Used for filtering */ const char *image_extensions[] = { #ifdef EXTN_JPEG ".jpg",".jpeg", ".jpe", #endif #ifdef EXTN_GIF ".gif", #endif #ifdef EXTN_TIFF ".tif",".tiff", #endif #ifdef EXTN_XPM ".xpm", #endif #ifdef EXTN_PNG ".png",".pjpeg", #endif #ifdef EXTN_PPM ".ppm", #endif #ifdef EXTN_PNM ".pnm", #endif #ifdef EXTN_PGM ".pgm", ".pbm", #endif #ifdef EXTN_PCX ".pcx", #endif #ifdef EXTN_BMP ".bmp", #endif #ifdef EXTN_EIM ".eim", #endif #ifdef EXTN_TGA ".tga", #endif #ifdef EXTN_ICO ".ico", #endif #ifdef EXTN_WMF ".wmf", #endif #ifdef EXTN_SVG ".svg", #endif NULL }; #ifdef HAVE_MAGIC const char *image_magic[] = { #ifdef EXTN_JPEG "JPEG image data", #endif #ifdef EXTN_GIF "GIF image data", #endif #ifdef EXTN_TIFF "TIFF image data", #endif #ifdef EXTN_XPM "X pixmap image", #endif #ifdef EXTN_PNG "PNG image data", #endif #ifdef EXTN_PGM "Netpbm PBM", "Netpbm PPM", #endif #ifdef EXTN_BMP "PC bitmap data", #endif #ifdef EXTN_TGA "Targa image data", #endif #ifdef EXTN_PCX "PCX ver. 3.0 image", #endif #ifdef EXTN_SVG "SVG Scalable Vector", #endif #ifdef EXTN_ICO "MS Windows icon resource", #endif NULL }; #endif #endif /* MAIN_H */ qiv-2.2.4.orig/README.COPYING0000644000175000017500000004312711563226774014264 0ustar bartmbartm GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. qiv-2.2.4.orig/qiv_icon.h0000644000175000017500000000712511563226774014253 0ustar bartmbartm/* GdkPixbuf RGBA C-Source image dump 1-byte-run-length-encoded */ #ifdef __SUNPRO_C #pragma align 4 (qiv_icon) #endif #ifdef __GNUC__ static const guint8 qiv_icon[] __attribute__ ((__aligned__ (4))) = #else static const guint8 qiv_icon[] = #endif { "" /* Pixbuf magic (0x47646b50) */ "GdkP" /* length: header (24) + pixel_data (882) */ "\0\0\3\212" /* pixdata_type (0x2010002) */ "\2\1\0\2" /* rowstride (64) */ "\0\0\0@" /* width (16) */ "\0\0\0\20" /* height (16) */ "\0\0\0\20" /* pixel_data: */ "\224\0\0\0\0\11\354\321\\\377\366\3151\377\372\3151\377\374\311/\377" "\376\303.\377\372\302/\377\361\3003\377\352\272K\377\342\300\204\377" "\206\0\0\0\0\13\373\316\77\377\374\311#\377\373\3040\377\374\3044\377" "\374\3078\377\374\3108\377\374\304.\377\372\277.\377\374\270\37\377\366" "\260)\377\344\264e\377\204\0\0\0\0\15\367\306(\377\375\303*\377\375\307" "6\377\374\330C\377\375\340L\377\374\344Q\377\374\345S\377\374\337O\377" "\373\333I\377\375\314<\377\375\267,\377\363\264\40\377\341\2427\377\202" "\0\0\0\0\16\355\313C\377\375\3021\377\375\3126\377\376\326E\377\377\353" "U\377\366\350_\377\361\347j\377\361\354u\377\372\363m\377\376\364d\377" "\375\344U\377\375\315@\377\373\2734\377\370\254+\377\202\0\0\0\0&\373" "\302)\377\376\307/\377\374\316<\377\374\341E\377\371\354g\377\342\335" "u\377\324\316\207\377\327\322\215\377\360\353\216\377\373\370v\377\374" "\364`\377\374\326E\377\375\3035\377\376\262$\377\262\235y\377\0\0\0\0" "\376\300#\377\376\3113\377\376\322=\377\376\347V\377\323\302\201\377" "\275\274\257\377\320\325\326\377\340\341\341\377\306\304\270\377\337" "\341\233\377\374\377q\377\374\344Q\377\373\320=\377\374\276,\377\261" "\226]\377\0\0\0\0\377\272\33\377\376\3062\377\374\320<\377\376\345O\377" "\302\265\222\377\336\343\344\377\203\0\0\0\0\15\325\326\262\377\377\377" "w\377\376\350U\377\377\322B\377\377\3010\377\262\222^\377\0\0\0\0\374" "\266'\377\376\303,\377\375\3149\377\376\337J\377\311\272\211\377\341" "\342\332\377\203\0\0\0\0\15\332\334\255\377\377\376o\377\375\344R\377" "\375\317A\377\377\275/\377\256\223b\377\0\0\0\0\361\2625\377\375\277" "%\377\376\3062\377\377\327A\377\327\301r\377\334\331\304\377\202\0\0" "\0\0'\347\350\342\377\342\341\240\377\377\367b\377\375\333I\377\374\310" ":\377\377\266+\377\251\225j\377\0\0\0\0\355\264g\377\376\256!\377\373" "\270\"\377\376\300/\377\366\307H\377\323\276z\377\323\322\277\377\346" "\344\347\377\331\334\241\377\363\353m\377\373\327E\377\374\3033\377\366" "\265'\377\357\242%\377\240\230v\377\0\0\0\0\336\302\207\377\372\252\30" "\377\375\256\31\377\376\263%\377\376\277/\377\357\277J\377\351\311f\377" "\353\336~\377\361\334Q\377\372\325@\377\376\3011\377\375\263!\377\375" "\252\35\377\371\237\30\377\317\2303\377\202\0\0\0\0\16\367\246\35\377" "\373\247\26\377\376\254\33\377\376\264\"\377\376\272&\377\372\301,\377" "\366\3166\377\372\313/\377\375\276)\377\375\264#\377\374\251\31\377\375" "\243\22\377\377\233\15\377\335\216\30\377\202\0\0\0\0\16\346\240G\377" "\361\236'\377\376\237\15\377\375\243\17\377\374\246\17\377\375\247\26" "\377\376\247\21\377\376\244\27\377\375\244\24\377\375\237\20\377\376" "\231\14\377\373\230\11\377\373\225\5\377\274y-\377\203\0\0\0\0\15\331" "\265\204\377\341\217)\377\373\230\11\377\375\235\13\377\376\234\12\377" "\375\231\12\377\376\232\10\377\372\233\10\377\371\231\6\377\370\224\3" "\377\366\223\3\377\365\220\0\377\254\202O\377\204\0\0\0\0\11\321\260" "\203\377\327\217-\377\331\215#\377\334\214\26\377\334\213\27\377\332" "\215\35\377\327\213%\377\322\213*\377\317\213.\377\202\314\2121\377\1" "\0\0\0\0"}; qiv-2.2.4.orig/Makefile0000644000175000017500000001101311563226774013722 0ustar bartmbartm####################################################################### # Makefile for qiv - Quick Image Viewer - http://qiv.spiegl.de/ # User Options ####################################################################### # Directory where qiv will be installed under. PREFIX = /usr/local # Font to use for statusbar in fullscreen mode STATUSBAR_FONT = "fixed" # Cursor to use on qiv windows - see # /usr/X11R6/include/X11/cursorfont.h for more choices. CURSOR = 84 # Should image be centered on screen by default? 1=yes, 0=no. CENTER = 1 # Should images be filtered by extension? 1=yes, 0=no. FILTER = 1 # This sets the file extentions to filter on (other file types will be # skipped.) It should reflect whatever is compiled into imlib. # The latest version of imlib has removed imagemagick fallback support, # so some extensions (XBM TGA) have been removed. EXTNS = GIF TIFF XPM PNG PPM PNM PGM PCX BMP EIM JPEG SVG WMF ICO # Comment this line out if your system doesn't have getopt_long(). GETOPT_LONG = -DHAVE_GETOPT_LONG # This program will be run on the manual page after it is installed. # If you don't want to compress the manpage, change it to 'true'. COMPRESS_PROG = gzip -9f # Comment this line out if your system doesn't have libXinerama # installed (for centering on dual-screen) GTD_XINERAMA = -DGTD_XINERAMA # Comment this line out if you do not want to use libmagic to # identify if a file is an image MAGIC = -DHAVE_MAGIC ###################################################################### # Variables and Rules # Do not edit below here! ###################################################################### CC = gcc #CFLAGS = -O -g -Wall CFLAGS = -O2 -Wall \ -fcaller-saves -ffast-math -fno-strength-reduce \ -fthread-jumps #-march=pentium #-DSTAT_MACROS_BROKEN #CFLAGS = -O2 -Wall -fomit-frame-pointer -finline-functions \ # -fcaller-saves -ffast-math -fno-strength-reduce \ # -fthread-jumps #-march=pentium #-DSTAT_MACROS_BROKEN INCLUDES := $(shell pkg-config --cflags gdk-2.0 imlib2) LIBS := $(shell pkg-config --libs gdk-2.0 imlib2) -lX11 # [as] thinks that this is not portable enough: # [lc] I use a virtual screen of 1600x1200, and the resolution is 1024x768, # so I changed (in main.c) how screen_[x,y] is obtained; it seems that gtk # 1.2 cannot give the geometry of viewport, so I borrowed from the source # of xvidtune the code for calling XF86VidModeGetModeLine, this requires # the linking option -lXxf86vm. #LIBS += -lXxf86vm PROGRAM = qiv OBJS = main.o image.o event.o options.o utils.o xmalloc.o HEADERS = qiv.h DEFINES = $(patsubst %,-DEXTN_%, $(EXTNS)) \ $(GETOPT_LONG) \ -DSTATUSBAR_FONT='$(STATUSBAR_FONT)' \ -DCENTER=$(CENTER) \ -DFILTER=$(FILTER) \ -DCURSOR=$(CURSOR) \ $(MAGIC) \ $(GTD_XINERAMA) ifndef GETOPT_LONG OBJS += lib/getopt.o lib/getopt1.o OBJS_G += lib/getopt.g lib/getopt1.g endif ifdef GTD_XINERAMA LIBS += -L/usr/X11R6/lib -lXinerama endif ifdef MAGIC LIBS += -lmagic endif PROGRAM_G = qiv-g OBJS_G = $(OBJS:.o=.g) DEFINES_G = $(DEFINES) -DDEBUG ###################################################################### all: $(PROGRAM) $(PROGRAM): $(OBJS) $(CC) $(CFLAGS) $(DEFINES) $(OBJS) $(LIBS) -o $(PROGRAM) $(OBJS): %.o: %.c $(HEADERS) $(CC) -c $(CFLAGS) $(DEFINES) $(INCLUDES) $< -o $@ main.o: main.h ###################################################################### debug: $(PROGRAM_G) $(PROGRAM_G): $(OBJS_G) $(CC) -g $(CFLAGS) $(DEFINES_G) $(LIBS) $(OBJS_G) -o $(PROGRAM_G) $(OBJS_G): %.g: %.c $(HEADERS) $(CC) -c -g $(CFLAGS) $(DEFINES_G) $(INCLUDES) $< -o $@ ###################################################################### clean : @echo "Cleaning up..." rm -f $(OBJS) $(OBJS_G) distclean : clean rm -f $(PROGRAM) $(PROGRAM_G) install: $(PROGRAM) @echo "Installing QIV..." @if [ ! -e $(PREFIX)/bin ]; then \ install -d -m 0755 $(PREFIX)/bin; \ echo install -d -m 0755 $(PREFIX)/bin; \ fi install -s -m 0755 $(PROGRAM) $(PREFIX)/bin @if [ ! -e $(PREFIX)/man/man1 ]; then \ echo install -d -m 0755 $(PREFIX)/man/man1; \ install -d -m 0755 $(PREFIX)/man/man1; \ fi install -m 0644 $(PROGRAM).1 $(PREFIX)/man/man1 $(COMPRESS_PROG) $(PREFIX)/man/man1/$(PROGRAM).1 @if ./qiv -f ./intro.jpg ; \ then echo "-- Test Passed --" ; \ else echo "-- Test Failed --" ; \ fi @echo "\nDont forget to look into the \"qiv-command\" file and install it!\n-> cp qiv-command.example /usr/local/bin/qiv-command\n\n" # the end... ;-) qiv-2.2.4.orig/qiv.10000644000175000017500000002624611563226774013161 0ustar bartmbartm.\" @(#)qiv.1 -*- nroff -*- .de EX .ne 5 .if n .sp .5 .if t .sp .5 .nf .. .de EE .fi .if n .sp .5 .if t .sp .5 .. .TH qiv 1 "qiv" "fast image viewer for X" "X Tools" .SH NAME qiv \- a fast gdk/imlib image viewer for X. .br .br Version: 2.2.4, released on 2011-05-02 .br by Andy Spiegl - http://qiv.spiegl.de/ - qiv.andy@spiegl.de .br originally by Adam Kopacz / KLOGRAFX.DE Network .br http://www.klografx.net/qiv/ - adam.k@klografx.de .SH SYNOPSIS .B qiv [options] file ... .SH DESCRIPTION .I qiv is an image viewer developed with gdk/imlib. As a result, .I qiv is faster than traditional image viewers such as \fIxv\fR or \fIxli\fR. .SH OPTIONS .TP .B \-h, \-\-help Print out a brief help message. .TP .B \-\-display \fIdisp\fB Open qiv window on display \fIdisp\fR. .TP .B \-F, \-\-file \fIfile | stdin\fB Read file names from \fIfile\fR or \fIstdin\fR, one name per line. This option can be specified multiple times to read from several files, and will not affect other file names passed on the command-line. .TP .B \-u, \-\-recursivedir Change the behavior of qiv to recursively descend into the directories given on the command line. .TP .B \-e, \-\-center Disable window centering. .TP .B \-w, \-\-fixed_width \fIx\fB Window with fixed width \fIx\fR. .TP .B \-W, \-\-fixed_zoom \fIx\fB. Window with fixed zoom factor (percentage \fIx\fR). .TP .B \-x, \-\-root \fIfile\fB Set \fIfile\fR as the current desktop background (centered) and exit. .TP .B \-y, \-\-root_t \fIfile\fB Set \fIfile\fR as the current desktop background (tiled) and exit. .TP .B \-z, \-\-root_s \fIfile\fB Set \fIfile\fR as the current desktop background (stretched) and exit. .TP .B \-m, \-\-maxpect Expand image(s) to fit screen size while preserving aspect ratio. .TP .B \-t, \-\-scale_down Shrink image(s) which are larger than screen size to fit. .TP .B \-b, \-\-brightness \fIx\fB Set brightness to \fIx\fR (-32..32). .TP .B \-c, \-\-contrast \fIx\fB Set contrast to \fIx\fR (-32..32). .TP .B \-g, \-\-gamma \fIx\fB Set gamma to \fIx\fR (-32..32). .TP .B \-n, \-\-no_filter Disable filtering of images by extension. Normally, qiv will only load images with an image extension such as .jpg, .png, .gif ... This option lets you load any file as an image. .TP .B \-i, \-\-no_statusbar Disable statusbar. .TP .B \-I, \-\-statusbar Enable statusbar. .TP .B \-p, \-\-transparency Enable transparency for transparent images. .TP .B \-a, \-\-do_grab Grab the pointer in windowed mode. .TP .B \-G, \-\-disable_grab Disable grabbing the pointer/kbd in fullscreen mode. Useful e.g. if qiv displays images on a display other than where it was invoked from. Use with caution! .TP .B \-v, \-\-version Print version information. .TP .B \-o, \-\-bg_color \fIx\fB Set root background color to named color \fIx\fR or 24 bit hex RGB triple in the format \fI#RRGGBB\fR. .TP .B \-C, \-\-cycle Change cycle behaviour. qiv will exit after last picture has been shown. .TP .B \-s, \-\-slide Start slideshow immediately. This can also be used for the desktop background (x/y/z). .TP .B \-r, \-\-random Randomize slideshow. .TP .B \-R, \-\-readonly Disable the deletion feature. .TP .B \-S, \-\-shuffle Shuffle images (random order with next/previous functionality). .TP .B \-d, \-\-delay \fIx\fB Set slideshow delay to \fIx\fR seconds. .TP .B \-f, \-\-fullscreen Use fullscreen window on start-up. .TP .B \-P, \-\-ignore_path_sort Sort all the image files by just their filename, ignoring the path. .TP .B \-M, \-\-merged_case_sort Sort all the image files in merged-case order (AaBbCc...). .TP .B \-N, \-\-numeric_sort A "smart" numeric sort that attempts to sort filenames with numbers in a logical manner. For instance: 2.jpg sorts before 10.jpg; 1foo.jpg through 10foo.jpg sorts after 1bar.jpg through 15bar.jpg (because "foo" comes after "bar"); and baz0001.jpg through baz0010.jpg sorts after baz01.jpg through baz99.jpg (because the longer group of zero-padded digits indicates that they shouldn't be intermingled). .TP .B \-D, \-\-no_sort Do not apply any sorting to the list of files. .TP .B \-T, \-\-watch Reload the image if it has changed on disk. .TP .B \-A, \-\-select_dir \fIdir\fB Store the selected files in \fIdir\fR (default is .qiv-select). .TP .B \-q, \-\-rotate \fIx\fB Rotate 90(x=1),180(x=2),270(x=3) degrees clockwise .TP .B \-l, \-\-autorotate Autorotate JPEGs according to EXIF rotation tag. .TP .B \-X, \-\-xineramascreen \fIx\fB Use screen \fIx\fR as preferred Xinerama screen .TP .B \-B, \-\-browse This option is useful when configuring qiv to be used with a file manager. qiv will scan the directory of the clicked image and allow you to scroll through those images. .SH EXAMPLES qiv \-atsd2 *.jpg .br qiv \-\-maxpect \-\-root image.png .br qiv \-\-maxpect \-\-slide \-\-random \-\-delay=2 * .br qiv \-\-maxpect \-\-scale_down \-\-slide \-\-delay=2 `find / *` .br qiv \-\-bg_color 0000FF \-\-root image.png .br qiv \-\-bg_color blue \-\-root image.png .SH KEYS .EX space/left mouse/wheel down next picture backspace/right mouse/wheel up previous picture PgDn 5 pictures forward PgUp 5 pictures backward q/ESC/middle mouse exit 0-9 run 'qiv-command ' ^\fI...\fR run 'qiv-command ^\fI...\fR ' where \fI...\fR can be any string ?/F1 show keys F11/F12 in/decrease slideshow delay (1 second) a/A copy picture to .qiv-select d/D/del move picture to .qiv-trash (-R disables this feature) u undelete the previously trashed image +/=/wheel r/btn fwd zoom in (10%) -/wheel l/btn back zoom out (10%) e center mode on/off f fullscreen mode on/off m scale to screen size on/off t scale down on/off X cycle through xinerama screens s slide show on/off p transparency on/off r random order on/off b - brightness B + brightness c - contrast C + contrast g - gamma G + gamma o reset brightness, contrast, gamma h flip horizontally v flip vertically k rotate right l rotate left jt\fIx\fR jump to image number \fIx\fR jf\fIx\fR jump forward \fIx\fR images jb\fIx\fR jump backward \fIx\fR images enter/return reset zoom, rotation and color settings i statusbar on/off I iconify window w watch file on/off x center image on background y tile image on background z stretch image on background < turn on/off magnifying window arrow keys move image (in fullscreen mode) arrow keys+Shift move image faster (in fullscreen mode) NumPad-arrow keys+NumLock move image faster (in fullscreen mode) .EE .SH MOUSE CONTROLS .EX Button 1 next picture Button 1 (hold down) & Mouse-Move moving picture Button 2 quit Button 3 previous picture Wheel Up next picture Wheel Dn previous picture Wheel Lt/Button back zoom out (10%) Wheel Rt/Button forward zoom in (10%) .EE .SH DELETING qiv doesn't actually delete files. It creates a directory named ".qiv-trash" and moves the images to that directory. qiv maintains the directory structure of your "deleted" images. You can also undelete the most recently trashed images in reverse order, which moves each file back into its original directory. There is a limit to how many deletions can be undone, but it should be pretty large (currently 1024 items). Sometimes this feature might be unwanted. To prevent accidents you can specify the "-R" option to disable this feature. .SH IMWHEEL SUPPORT With XFree86 3.3.2+ server, using the wheel is seen as button 4 and 5 pressed. You only have to use "IMPS/2" or "Intellimouse" for protocol and add "ZAxisMapping 4 5 " in the "Pointer" section of XF86Config. If imwheel (a program used to emulate key pressed when wheel is used for program not supporting wheel), the following two lines must be add to imwheel config file : .P "qiv" .br @Exclude .SH USER-DEFINED KEYBOARD ACTIONS Keys 0-9 will invoke .B qiv-command with the key pressed as the first argument and the current image filename as the second argument. .B qiv-command is not distributed with qiv; it is to be supplied by the user. Thus, this feature could be enabled by placing a simple shell script such as the following in the command search path (for example, in the user's ~/bin directory): .P .EX #!/bin/sh # Argument sanity checking eliminated for brevity case $1 in 0|1|2|3|4|5|6|7|8|9) mkdir -f dir$1; mv "$fname" dir$1 ;; *) echo "unrecognized command"; exit ;; esac .EE .P If the first line of the output is like "NEWNAME=xxxxxxx" then qiv thinks that the filename of the currently displayed image has changed to this new name and updates its internal filelist. This is very useful when using qiv-command to rename files. .P Please also see the example that came together with qiv. .EE .SH AUTHORS .EX Adam Kopacz Andy Spiegl Darren Smith Pavel Andreev Decklin Foster Holger Mueller Scott Sams Serge Winitzki Frederic Crozat Rutger Nijlunsing John Knottenbelt Danny Tomas Ogren Erik Jacobsen Alfred Weyers Daniel Henning Kulander Ask Bjoern Hansen Adrian Lopez Y Furuhashi Wayne Davison Johannes Stezenbach OEyvind Kolaas Matthieu Castet Geoffrey T. Dairik Leopoldo Cerbaro Heikki Lehvaslaiho Larry Doolittle S. Dobrev Thomas Wiegner Barry deFreese Peter deWachter Akos Pasztory .EE .SH MISC .P qiv homepage: http://qiv.spiegl.de/ .P homepage of original author Adam Kopacz http://www.klografx.net/qiv/ .P Mail bug, reports and comments to Andy Spiegl .P Sending a SIGUSR1 to qiv will cause the program to flip to next picture. SIGUSR2 will move to previous. .P This program is covered by the GNU GPL; see the file COPYING for details. qiv-2.2.4.orig/lib/0000755000175000017500000000000011563226774013034 5ustar bartmbartmqiv-2.2.4.orig/lib/getopt.h0000644000175000017500000001112311563226774014505 0ustar bartmbartm/* Declarations for getopt. Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if defined (__STDC__) && __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if defined (__STDC__) && __STDC__ #ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ qiv-2.2.4.orig/lib/getopt.c0000644000175000017500000007007411563226774014512 0ustar bartmbartm/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #include #ifdef HAVE_CONFIG_H #include #endif #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #include #endif /* GNU C library. */ #ifdef VMS #include #if HAVE_STRING_H - 0 #include #endif #endif #if defined (WIN32) && !defined (__CYGWIN32__) /* It's not Unix, really. See? Capital letters. */ #include #define getpid() GetCurrentProcessId() #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ #ifdef HAVE_LIBINTL_H # include # define _(msgid) gettext (msgid) #else # define _(msgid) (msgid) #endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #if !defined (__STDC__) || !__STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ static const char *nonoption_flags; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void store_args (int argc, char *const *argv) __attribute__ ((unused)); static void store_args (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } text_set_element (__libc_subinit, store_args); #endif /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined (__STDC__) && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined (__STDC__) && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { /* Bash 2.0 puts a special variable in the environment for each command it runs, specifying which ARGV elements are the results of file name wildcard expansion and therefore should not be considered as options. */ char var[100]; sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ()); nonoption_flags = getenv (var); if (nonoption_flags == NULL) nonoption_flags_len = 0; else nonoption_flags_len = strlen (nonoption_flags); } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (!__getopt_initialized || optind == 0) { optstring = _getopt_initialize (argc, argv, optstring); optind = 1; /* Don't scan ARGV[0], the program name. */ __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && nonoption_flags[optind] == '1')) #else #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ qiv-2.2.4.orig/lib/getopt1.c0000644000175000017500000001105311563226774014563 0ustar bartmbartm/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include "getopt.h" #if !defined (__STDC__) || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ qiv-2.2.4.orig/event.c0000644000175000017500000010447011563226774013561 0ustar bartmbartm/* Module : event.c Purpose : Handle GDK events More : see qiv README Policy : GNU GPL Homepage : http://qiv.spiegl.de/ Original : http://www.klografx.net/qiv/ */ #include #include #include #include #include "qiv.h" #define STEP 3 //When using KP arrow, number of step for seeing all the image. static int jumping; static int extcommand; // [lc] static char jcmd[100]; static int jidx; static int cursor_timeout; static gboolean displaying_textwindow = FALSE; static void qiv_enable_mouse_events(qiv_image *q) { gdk_window_set_events(q->win, gdk_window_get_events(q->win) & ~GDK_POINTER_MOTION_HINT_MASK); } static void qiv_disable_mouse_events(qiv_image *q) { gdk_window_set_events(q->win, gdk_window_get_events(q->win) | GDK_POINTER_MOTION_HINT_MASK); } static gboolean qiv_cursor_timeout(gpointer data) { qiv_image *q = data; cursor_timeout = 0; hide_cursor(q); qiv_enable_mouse_events(q); return FALSE; } static void qiv_set_cursor_timeout(qiv_image *q) { if (!cursor_timeout) cursor_timeout = g_timeout_add(1000, qiv_cursor_timeout, q); qiv_disable_mouse_events(q); } static void qiv_cancel_cursor_timeout(qiv_image *q) { hide_cursor(q); if (cursor_timeout) { g_source_remove(cursor_timeout); cursor_timeout = 0; } } static void qiv_drag_image(qiv_image *q, int move_to_x, int move_to_y) { q->win_x = move_to_x; if (q->win_w > screen_x) { if (q->win_x > 0) q->win_x = 0; else if (q->win_x + q->win_w < screen_x) q->win_x = screen_x - q->win_w; } else { if (q->win_x < 0) q->win_x = 0; else if (q->win_x + q->win_w > screen_x) q->win_x = screen_x - q->win_w; } q->win_y = move_to_y; if (q->win_h > screen_y) { if (q->win_y > 0) q->win_y = 0; else if (q->win_y + q->win_h < screen_y) q->win_y = screen_y - q->win_h; } else { if (q->win_y < 0) q->win_y = 0; else if (q->win_y + q->win_h > screen_y) q->win_y = screen_y - q->win_h; } update_image(q, MOVED); } void qiv_display_text_window(qiv_image *q, const char *infotextdisplay, const char *strs[], const char *continue_msg) { int temp, text_w = 0, text_h, i, maxlines; int width, height, text_left; int ascent; int descent; ascent = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics)); descent = PANGO_PIXELS(pango_font_metrics_get_descent(metrics)); if (fullscreen) { width = screen_x; height = screen_y; } else { width = q->win_w; height = q->win_h; } /* Calculate maximum number of lines to display */ if (ascent + descent > 0) maxlines = height / (ascent + descent) - 3; else maxlines = 60; pango_layout_set_text(layout, continue_msg, -1); pango_layout_get_pixel_size (layout, &text_w, NULL); for (i = 0; strs[i] && i < maxlines; i++) { pango_layout_set_text(layout, strs[i], -1); pango_layout_get_pixel_size (layout, &temp, NULL); if (text_w < temp) text_w = temp; } text_h = (i + 2) * ( ascent + descent ); snprintf(infotext, sizeof infotext, "%s", infotextdisplay); update_image(q, REDRAW); text_left = width/2 - text_w/2 - 4; if (text_left < 2) text_left = 2; /* if window/screen is smaller than text */ gdk_draw_rectangle(q->win, q->bg_gc, 0, text_left, height/2 - text_h/2 - 4, text_w + 7, text_h + 7); gdk_draw_rectangle(q->win, q->status_gc, 1, text_left + 1, height/2 - text_h/2 - 3, text_w + 6, text_h + 6); for (i = 0; strs[i] && i < maxlines; i++) { pango_layout_set_text(layout, strs[i], -1); gdk_draw_layout (q->win, q->text_gc, text_left + 4, height/2 - text_h/2 + i * (ascent + descent), layout); } /* Display Push Any Key... message */ pango_layout_set_text(layout, continue_msg, -1); pango_layout_get_pixel_size (layout, &temp, NULL); gdk_draw_layout (q->win, q->text_gc, width/2 - temp/2, height/2 - text_h/2 - descent + (i+1) * (ascent + descent), layout); displaying_textwindow = TRUE; /* print also on console */ if (0) { int i; for (i = 0; strs[i] != NULL; i++) { printf("%s\n", strs[i]); } } } void qiv_handle_event(GdkEvent *ev, gpointer data) { gboolean exit_slideshow = FALSE; qiv_image *q = data; Window xwindow; int move_step; const char *mess[2]={ jcmd, NULL}; // get windows position if not in fullscreen mode // (because the user might have moved the window our since last redraw) if (!fullscreen) { gdk_window_get_position(q->win, &q->win_x, &q->win_y); // g_print("position : q->win_x = %d, q->win_y = %d, q->win_w = %d\n", q->win_x, q->win_y, q->win_w); // gdk_window_get_origin(q->win, &q->win_x, &q->win_y); // gdk_window_get_root_origin(q->win, &q->win_x, &q->win_y); } switch(ev->type) { case GDK_DELETE: qiv_exit(0); break; case GDK_EXPOSE: if (!q->exposed) { q->exposed = 1; qiv_set_cursor_timeout(q); } break; case GDK_LEAVE_NOTIFY: if (magnify && !fullscreen) { gdk_window_hide(magnify_img.win); } break; case GDK_CONFIGURE: if (magnify && !fullscreen) { gdk_window_get_root_origin(q->win, &magnify_img.frame_x, &magnify_img.frame_y); // printf("GDK_CONFIGURE get_root_origin %d %d\n", // magnify_img.frame_x, magnify_img.frame_y); } // gdk_draw_rectangle(q->win, q->status_gc, 1, 10, 10, 50, 50); if (statusbar_window) { #ifdef DEBUG g_print("*** print statusbar at (%d, %d)\n", MAX(2,q->win_w-q->text_w-10), MAX(2,q->win_h-q->text_h-10)); #endif // printf(">>> statusbar_w %d %d %d %d\n", // MAX(2,q->win_w-text_w-10), MAX(2,q->win_h-text_h-10), text_w+5, text_h+5); gdk_draw_rectangle(q->win, q->bg_gc, 0, MAX(2,q->win_w-q->text_w-10), MAX(2,q->win_h-q->text_h-10), q->text_w+5, q->text_h+5); gdk_draw_rectangle(q->win, q->status_gc, 1, MAX(3,q->win_w-q->text_w-9), MAX(3,q->win_h-q->text_h-9), q->text_w+4, q->text_h+4); pango_layout_set_text(layout, q->win_title, -1); pango_layout_get_pixel_size (layout, &(q->text_w), &(q->text_h)); gdk_draw_layout (q->win, q->text_gc, MAX(5,q->win_w-q->text_w-7), MAX(5,q->win_h-7-q->text_h), layout); } break; case GDK_BUTTON_PRESS: jumping=0; /* abort jump mode if a button is pressed */ qiv_cancel_cursor_timeout(q); if (fullscreen && ev->button.button == 1) { q->drag = 1; q->drag_start_x = ev->button.x; q->drag_start_y = ev->button.y; q->drag_win_x = q->win_x; q->drag_win_y = q->win_y; qiv_enable_mouse_events(q); } break; case GDK_MOTION_NOTIFY: if (q->drag) { int move_x, move_y; move_x = (int)(ev->button.x - q->drag_start_x); move_y = (int)(ev->button.y - q->drag_start_y); if (q->drag == 1 && (ABS(move_x) > 3 || ABS(move_y) > 3)) { /* distinguish from simple mouse click... */ q->drag = 2; show_cursor(q); } if (q->drag > 1 && (q->win_x != q->drag_win_x + move_x || q->win_y != q->drag_win_y + move_y)) { GdkEvent *e; qiv_disable_mouse_events(q); qiv_drag_image(q, q->drag_win_x + move_x, q->drag_win_y + move_y); snprintf(infotext, sizeof infotext, "(Drag)"); /* el cheapo mouse motion compression */ while (gdk_events_pending()) { e = gdk_event_get(); if (e->type == GDK_BUTTON_RELEASE) { gdk_event_put(e); gdk_event_free(e); break; } gdk_event_free(e); } qiv_enable_mouse_events(q); } } else { show_cursor(q); // printf(" motion_notify magnify %d is_hint %d\n", magnify, ev->motion.is_hint); if (magnify && !fullscreen) { gint xcur, ycur; if (ev->motion.is_hint) { gdk_window_get_pointer(q->win, &xcur, &ycur, NULL); update_magnify(q, &magnify_img,REDRAW, xcur, ycur); // [lc] } // update_magnify(q, &magnify_img,REDRAW, ev->motion.x, ev->motion.y); } else { qiv_set_cursor_timeout(q); } } break; /* Use release instead of press (Fixes bug with junk being sent * to underlying xterm window on exit) */ case GDK_BUTTON_RELEASE: exit_slideshow = TRUE; switch (ev->button.button) { /* [tw]: I think buttons 4-7 don't work in GDK-2.0 as button events, * they are now GDK_SCROLL events */ case 1: /* left button pressed */ if (q->drag) { int move_x, move_y; move_x = (int)(ev->button.x - q->drag_start_x); move_y = (int)(ev->button.y - q->drag_start_y); qiv_disable_mouse_events(q); qiv_set_cursor_timeout(q); if (q->drag > 1) { qiv_drag_image(q, q->drag_win_x + move_x, q->drag_win_y + move_y); snprintf(infotext, sizeof infotext, "(Drag)"); q->drag = 0; break; } q->drag = 0; } case 5: /* scroll wheel down emulated by button 5 */ goto next_image; case 8: goto zoom_out; case 9: goto zoom_in; default: g_print("unmapped button event %d, exiting\n",ev->button.button); case 2: /* middle button pressed */ qiv_exit(0); break; case 3: /* right button pressed */ case 4: /* scroll wheel up emulated by button 4 */ goto previous_image; break; } break; case GDK_SCROLL: switch (ev->scroll.direction) { case GDK_SCROLL_UP: goto next_image; case GDK_SCROLL_DOWN: goto previous_image; case GDK_SCROLL_LEFT: goto zoom_out; case GDK_SCROLL_RIGHT: goto zoom_in; default: break; } break; case GDK_KEY_PRESS: exit_slideshow = TRUE; /* Abort slideshow on any key by default */ qiv_cancel_cursor_timeout(q); #ifdef DEBUG g_print("*** key:\n"); /* display key-codes */ g_print("\tstring: %s\n",ev->key.string); g_print("\tkeyval: %d\n",ev->key.keyval); #endif if (displaying_textwindow && !extcommand ) { // [lc] /* Hide the text window if it is showing */ displaying_textwindow = FALSE; update_image(q, FULL_REDRAW); break; } if (jumping || extcommand) { // [lc] todo: Backspace, if(ev->key.keyval == GDK_Escape) { extcommand = 0; jidx = 0; displaying_textwindow = FALSE; update_image(q, FULL_REDRAW); break; } if(ev->key.keyval == GDK_BackSpace) { jidx--; jcmd[jidx]='\0'; qiv_display_text_window(q, "(Sending Command)", mess, "Press to send, to abort"); // [lc] break; } if((ev->key.keyval == GDK_Return) || (ev->key.keyval == GDK_KP_Enter) || (jidx == 99)) { /* 99 digits already typed */ jcmd[jidx] = '\0'; if (jumping) { jump2image(jcmd); qiv_load_image(q); jumping=0; } else { // extcommand=1 int numlines = 0; const char **lines; extcommand=0; /* Hide the text window if it is showing */ displaying_textwindow = FALSE; update_image(q, FULL_REDRAW); run_command(q, jcmd, image_names[image_idx], &numlines, &lines); if (lines && numlines) qiv_display_text_window(q, "(Command output)", lines, "Push any key..."); } } /* else record keystroke if not null */ else if(ev->key.string && *(ev->key.string) != '\0') { jcmd[jidx++]=*(ev->key.string); jcmd[jidx] = '\0'; if (extcommand) qiv_display_text_window(q, "(Sending Command)", mess, "Press to send, to abort"); // [lc] } } else { switch (ev->key.keyval) { /* Help */ case '?': case GDK_F1: qiv_display_text_window(q, "(Showing Help)", helpstrs,"Press any key..."); break; /* Exit */ case GDK_Escape: case 'q': qiv_exit(0); break; /* Fullscreen mode (on/off) */ case 'f': exit_slideshow = FALSE; gdk_window_withdraw(q->win); show_cursor(q); fullscreen ^= 1; first=1; qiv_load_image(q); break; /* Center mode (on/off) */ case 'e': exit_slideshow = FALSE; center ^= 1; snprintf(infotext, sizeof infotext, center ? "(Centering: on)" : "(Centering: off)"); if (center) center_image(q); update_image(q, MOVED); break; /* Transparency on/off */ case 'p': exit_slideshow = FALSE; transparency ^= 1; snprintf(infotext, sizeof infotext, transparency ? "(Transparency: on)" : "(Transparency: off)"); update_image(q, FULL_REDRAW); break; /* Maxpect on/off */ case 'm': scale_down = 0; maxpect ^= 1; snprintf(infotext, sizeof infotext, maxpect ? "(Maxpect: on)" : "(Maxpect: off)"); zoom_factor = maxpect ? 0 : fixed_zoom_factor; /* reset zoom */ check_size(q, TRUE); update_image(q, REDRAW); break; /* Random on/off */ case 'r': random_order ^= 1; snprintf(infotext, sizeof infotext, random_order ? "(Random order: on)" : "(Random order: off)"); update_image(q, REDRAW); break; /* iconify */ case 'I': exit_slideshow = TRUE; if (fullscreen) { gdk_window_withdraw(q->win); show_cursor(q); qiv_set_cursor_timeout(q); fullscreen=0; first=1; qiv_load_image(q); } xwindow = GDK_WINDOW_XWINDOW(q->win); XIconifyWindow(GDK_DISPLAY(), xwindow, DefaultScreen(GDK_DISPLAY())); break; /* Statusbar on/off */ case 'i': exit_slideshow = FALSE; if (fullscreen) { statusbar_fullscreen ^= 1; snprintf(infotext, sizeof infotext, statusbar_fullscreen ? "(Statusbar: on)" : "(Statusbar: off)"); } else { statusbar_window ^= 1; snprintf(infotext, sizeof infotext, statusbar_window ? "(Statusbar: on)" : "(Statusbar: off)"); } update_image(q, REDRAW); break; /* Slide show on/off */ case 's': exit_slideshow = FALSE; slide ^= 1; snprintf(infotext, sizeof infotext, slide ? "(Slideshow: on)" : "(Slideshow: off)"); update_image(q, REDRAW); break; /* move image right */ case GDK_Left: case GDK_KP_4: case GDK_KP_Left: if (fullscreen) { if (ev->key.state & GDK_SHIFT_MASK || ev->key.keyval == GDK_KP_4) { move_step = (MIN(screen_x, q->win_w) / STEP); } else { move_step = (q->win_w / 100); } if (move_step < 10) move_step = 10; /* is image greater than screen? */ if (q->win_w > screen_x) { /* left border visible yet? */ if (q->win_x < 0) { q->win_x += move_step; /* sanity check */ if (q->win_x > 0) q->win_x = 0; snprintf(infotext, sizeof infotext, "(Moving right)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further to the right)"); } } else { /* user is just playing around */ /* right border reached? */ if (q->win_x + q->win_w < screen_x) { q->win_x += move_step; /* sanity check */ if (q->win_x + q->win_w > screen_x) q->win_x = screen_x - q->win_w; snprintf(infotext, sizeof infotext, "(Moving right)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further to the right)"); } } } else { snprintf(infotext, sizeof infotext, "(Moving works only in fullscreen mode)"); fprintf(stdout, "qiv: Moving works only in fullscreen mode\n"); } update_image(q, MOVED); break; /* move image left */ case GDK_Right: case GDK_KP_6: case GDK_KP_Right: if (fullscreen) { if (ev->key.state & GDK_SHIFT_MASK || ev->key.keyval == GDK_KP_6) { move_step = (MIN(screen_x, q->win_w) / STEP); } else { move_step = (q->win_w / 100); } if (move_step < 10) move_step = 10; /* is image greater than screen? */ if (q->win_w > screen_x) { /* right border visible yet? */ if (q->win_x + q->win_w > screen_x) { q->win_x -= move_step; /* sanity check */ if (q->win_x + q->win_w < screen_x) q->win_x = screen_x - q->win_w; snprintf(infotext, sizeof infotext, "(Moving left)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further to the left)"); } } else { /* user is just playing around */ /* left border reached? */ if (q->win_x > 0) { q->win_x -= move_step; /* sanity check */ if (q->win_x < 0) q->win_x = 0; snprintf(infotext, sizeof infotext, "(Moving left)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further to the left)"); } } } else { snprintf(infotext, sizeof infotext, "(Moving works only in fullscreen mode)"); fprintf(stdout, "qiv: Moving works only in fullscreen mode\n"); } update_image(q, MOVED); break; /* move image up */ case GDK_Down: case GDK_KP_2: case GDK_KP_Down: if (fullscreen) { if (ev->key.state & GDK_SHIFT_MASK || ev->key.keyval == GDK_KP_2) { move_step = (MIN(screen_y, q->win_h) / STEP); } else { move_step = (q->win_h / 100); } if (move_step < 10) move_step = 10; /* is image greater than screen? */ if (q->win_h > screen_y) { /* bottom visible yet? */ if (q->win_y + q->win_h > screen_y) { q->win_y -= move_step; /* sanity check */ if (q->win_y + q->win_h < screen_y) q->win_y = screen_y - q->win_h; snprintf(infotext, sizeof infotext, "(Moving up)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further up)"); } } else { /* user is just playing around */ /* top reached? */ if (q->win_y > 0) { q->win_y -= move_step; /* sanity check */ if (q->win_y < 0) q->win_y = 0; snprintf(infotext, sizeof infotext, "(Moving up)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further up)"); } } } else { snprintf(infotext, sizeof infotext, "(Moving works only in fullscreen mode)"); fprintf(stdout, "qiv: Moving works only in fullscreen mode\n"); } update_image(q, MOVED); break; /* move image down */ case GDK_Up: case GDK_KP_8: case GDK_KP_Up: if (fullscreen) { if (ev->key.state & GDK_SHIFT_MASK || ev->key.keyval == GDK_KP_8) { move_step = (MIN(screen_y, q->win_h) / STEP); } else { move_step = (q->win_h / 100); } if (move_step < 10) move_step = 10; /* is image greater than screen? */ if (q->win_h > screen_y) { /* top visible yet? */ if (q->win_y < 0) { q->win_y += move_step; /* sanity check */ if (q->win_y > 0) q->win_y = 0; snprintf(infotext, sizeof infotext, "(Moving down)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further down)"); } } else { /* user is just playing around */ /* bottom reached? */ if (q->win_y + q->win_h < screen_y) { q->win_y += move_step; /* sanity check */ if (q->win_y + q->win_h > screen_y) q->win_y = screen_y - q->win_h; snprintf(infotext, sizeof infotext, "(Moving down)"); } else { snprintf(infotext, sizeof infotext, "(Cannot move further down)"); } } } else { snprintf(infotext, sizeof infotext, "(Moving works only in fullscreen mode)"); fprintf(stdout, "qiv: Moving works only in fullscreen mode\n"); } update_image(q, MOVED); break; /* Scale_down */ case 't': maxpect = 0; scale_down ^= 1; snprintf(infotext, sizeof infotext, scale_down ? "(Scale down: on)" : "(Scale down: off)"); zoom_factor = maxpect ? 0 : fixed_zoom_factor; /* reset zoom */ check_size(q, TRUE); update_image(q, REDRAW); break; /* Resize + */ case GDK_KP_Add: case '+': case '=': zoom_in: snprintf(infotext, sizeof infotext, "(Zoomed in)"); zoom_in(q); update_image(q, ZOOMED); break; /* Resize - */ case GDK_KP_Subtract: case '-': zoom_out: snprintf(infotext, sizeof infotext, "(Zoomed out)"); zoom_out(q); update_image(q, ZOOMED); break; /* Reset Image / Original (best fit) size */ case GDK_Return: case GDK_KP_Enter: snprintf(infotext, sizeof infotext, "(Reset size)"); reload_image(q); zoom_factor = fixed_zoom_factor; /* reset zoom */ check_size(q, TRUE); update_image(q, REDRAW); break; /* Next picture - or loop to the first */ case ' ': next_image: snprintf(infotext, sizeof infotext, "(Next picture)"); next_image(1); qiv_load_image(q); if(magnify && !fullscreen) { gdk_window_hide(magnify_img.win); // [lc] // gdk_flush(); // gdk_window_get_root_origin(q->win, // &magnify_img.frame_x, &magnify_img.frame_y); // printf(">>> frame %d %d\n", magnify_img.frame_x, magnify_img.frame_y); // setup_magnify(q, &magnify_img); } break; /* 5 pictures forward - or loop to the beginning */ case GDK_Page_Down: case GDK_KP_Page_Down: snprintf(infotext, sizeof infotext, "(5 pictures forward)"); next_image(5); if(magnify && !fullscreen) gdk_window_hide(magnify_img.win); // [lc] qiv_load_image(q); break; /* Previous picture - or loop back to the last */ case GDK_BackSpace: previous_image: snprintf(infotext, sizeof infotext, "(Previous picture)"); next_image(-1); if(magnify && !fullscreen) gdk_window_hide(magnify_img.win); // [lc] qiv_load_image(q); break; /* 5 pictures backward - or loop back to the last */ case GDK_Page_Up: case GDK_KP_Page_Up: snprintf(infotext, sizeof infotext, "(5 pictures backward)"); next_image(-5); if(magnify && !fullscreen) gdk_window_hide(magnify_img.win); // [lc] qiv_load_image(q); break; /* + brightness */ case 'B': snprintf(infotext, sizeof infotext, "(More brightness)"); q->mod.brightness += 8; update_image(q, REDRAW); break; /* - brightness */ case 'b': snprintf(infotext, sizeof infotext, "(Less brightness)"); q->mod.brightness -= 8; update_image(q, REDRAW); break; /* + contrast */ case 'C': snprintf(infotext, sizeof infotext, "(More contrast)"); q->mod.contrast += 8; update_image(q, REDRAW); break; /* - contrast */ case 'c': snprintf(infotext, sizeof infotext, "(Less contrast)"); q->mod.contrast -= 8; update_image(q, REDRAW); break; /* + gamma */ case 'G': snprintf(infotext, sizeof infotext, "(More gamma)"); q->mod.gamma += 8; update_image(q, REDRAW); break; /* - gamma */ case 'g': snprintf(infotext, sizeof infotext, "(Less gamma)"); q->mod.gamma -= 8; update_image(q, REDRAW); break; /* - reset brightness, contrast and gamma */ case 'o': snprintf(infotext, sizeof infotext, "(Reset bri/con/gam)"); reset_mod(q); update_image(q, REDRAW); break; /* Delete image */ case GDK_Delete: case 'd': if (!readonly) { if (move2trash() == 0) snprintf(infotext, sizeof infotext, "(Deleted last image)"); else snprintf(infotext, sizeof infotext, "(Delete FAILED)"); qiv_load_image(q); } break; /* Undelete image */ case 'u': if (!readonly) { if (undelete_image() == 0) snprintf(infotext, sizeof infotext, "(Undeleted)"); else snprintf(infotext, sizeof infotext, "(Undelete FAILED)"); qiv_load_image(q); } break; /* Copy image to selected directory */ case 'a': if (copy2select() == 0) snprintf(infotext, sizeof infotext, "(Last image copied)"); else snprintf(infotext, sizeof infotext, "(Selection FAILED)"); next_image(1); qiv_load_image(q); break; /* Jump to image */ case 'j': jumping=1; jidx=0; break; /* Flip horizontal */ case 'h': imlib_image_flip_horizontal(); snprintf(infotext, sizeof infotext, "(Flipped horizontally)"); update_image(q, REDRAW); break; /* Flip vertical */ case 'v': imlib_image_flip_vertical(); snprintf(infotext, sizeof infotext, "(Flipped vertically)"); update_image(q, REDRAW); break; /* Watch File (on/off) */ case 'w': watch_file ^= 1; snprintf(infotext, sizeof infotext, watch_file ? "(File watching: on)" : "(File watching: off)"); update_image(q, REDRAW); if(watch_file){ g_idle_add (qiv_watch_file, q); } break; /* Rotate right */ case 'k': imlib_image_orientate(1); snprintf(infotext, sizeof infotext, "(Rotated right)"); swap(&q->orig_w, &q->orig_h); swap(&q->win_w, &q->win_h); check_size(q, FALSE); correct_image_position(q); update_image(q, REDRAW); break; /* Rotate left */ case 'l': imlib_image_orientate(3); snprintf(infotext, sizeof infotext, "(Rotated left)"); swap(&q->orig_w, &q->orig_h); swap(&q->win_w, &q->win_h); check_size(q, FALSE); correct_image_position(q); update_image(q, REDRAW); break; /* Center image on background */ case 'x': to_root=1; set_desktop_image(q); snprintf(infotext, sizeof infotext, "(Centered image on background)"); update_image(q, REDRAW); to_root=0; break; /* Tile image on background */ case 'y': to_root_t=1; set_desktop_image(q); snprintf(infotext, sizeof infotext, "(Tiled image on background)"); update_image(q, REDRAW); to_root_t=0; break; case 'z': to_root_s=1; set_desktop_image(q); snprintf(infotext, sizeof infotext, "(Stretched image on background)"); update_image(q, REDRAW); to_root_s=0; break; /* Decrease slideshow delay */ case GDK_F11: exit_slideshow = FALSE; if (delay > 1000) { delay-=1000; snprintf(infotext, sizeof infotext, "(Slideshow-Delay: %d seconds (-1)", delay/1000); update_image(q,MOVED); }else{ snprintf(infotext, sizeof infotext, "(Slideshow-Delay: can not be less than 1 second!)"); update_image(q,MOVED); } break; /* Show magnifying window */ case '<': // [lc] if (!fullscreen) { magnify ^= 1; int xcur, ycur; if (!magnify) { gdk_window_hide(magnify_img.win); } else { setup_magnify(q, &magnify_img); gdk_window_get_pointer(q->win, &xcur, &ycur, NULL); update_magnify(q, &magnify_img, REDRAW, xcur, ycur); // [lc] qiv_disable_mouse_events(q); } } break; /* Increase slideshow delay */ case GDK_F12: exit_slideshow = FALSE; delay+=1000; snprintf(infotext, sizeof infotext, "(Slideshow-Delay: %d seconds (+1)", delay/1000); update_image(q,MOVED); break; #ifdef GTD_XINERAMA /* go to next xinerama screen */ case 'X': if (number_xinerama_screens) { user_screen++; user_screen %= number_xinerama_screens; // g_print("user_screen = %d, number_xinerama_screens = %d\n", user_screen, number_xinerama_screens); } get_preferred_xinerama_screens(); // reselect appropriate screen snprintf(infotext, sizeof infotext, "(xinerama screen: %i)", user_screen); if (center) center_image(q); update_image(q, FULL_REDRAW); break; #else case 'X': { int numlines = 0; const char **lines; run_command(q, ev->key.string, image_names[image_idx], &numlines, &lines); if (lines && numlines) qiv_display_text_window(q, "(Command output)", lines, "Push any key..."); } break; #endif /* run qiv-command */ case '^': // special command with options { extcommand =1; jidx = 0; jcmd[jidx++]=*(ev->key.string); jcmd[jidx] = '\0'; qiv_display_text_window(q, "(Sending Command)", mess, "Press to send, to abort"); // [lc] } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'D': case 'E': case 'F': case 'H': case 'J': case 'K': case 'L': case 'M': case 'n': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'Y': case 'Z': { int numlines = 0; const char **lines; run_command(q, ev->key.string, image_names[image_idx], &numlines, &lines); if (lines && numlines) qiv_display_text_window(q, "(Command output)", lines, "Push any key..."); } break; default: exit_slideshow = FALSE; break; } } default: break; } if (exit_slideshow) { slide=0; } } qiv-2.2.4.orig/utils.c0000644000175000017500000005333011563226774013576 0ustar bartmbartm/* Module : utils.c Purpose : Various utilities for qiv More : see qiv README Policy : GNU GPL Homepage : http://qiv.spiegl.de/ Original : http://www.klografx.net/qiv/ */ #include #include #include #include #include #include #include #include #include #include #include "qiv.h" #include "xmalloc.h" #ifdef STAT_MACROS_BROKEN #undef S_ISDIR #endif #if !defined(S_ISDIR) && defined(S_IFDIR) #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif /* move current image to .qiv-trash */ int move2trash() { char *ptr, *ptr2, *filename = image_names[image_idx]; char trashfile[FILENAME_LEN], path_result[PATH_MAX]; int i; if (readonly) return 0; if(!(ptr = strrchr(filename, '/'))) { /* search rightmost slash */ /* no slash in filename */ strncpy(path_result, filename, PATH_MAX); /* move file to TRASH_DIR/filename */ snprintf(trashfile, sizeof trashfile, "%s/%s", TRASH_DIR, path_result); } else { /* find full path to file */ *ptr = 0; if(!realpath(filename,path_result)) { g_print("Error: realpath failure while moving file to trash\a\n"); *ptr = '/'; return 1; } /* move file to fullpath/TRASH_DIR/filename */ snprintf(trashfile, sizeof trashfile, "%s/%s/%s", path_result, TRASH_DIR, ptr+1); strncat(path_result, "/", PATH_MAX - strlen(path_result) ); strncat(path_result, ptr + 1, PATH_MAX - strlen(path_result) ); *ptr = '/'; } #ifdef DEBUG g_print("*** trashfile: '%s'\n",trashfile); #endif ptr = ptr2 = trashfile; if(trashfile[0] == '/') { /* filename starts with a slash? */ ptr += 1; } while((ptr = strchr(ptr,'/'))) { *ptr = '\0'; if(access(ptr2,F_OK)) { if(mkdir(ptr2,0700)) { g_print("Error: Could not make directory '%s'\a\n",ptr2); return 1; } } *ptr = '/'; ptr += 1; } unlink(trashfile); /* Just in case it already exists... */ if(rename(filename,trashfile)) { g_print("Error: Could not rename '%s' to '%s'\a\n",filename,trashfile); return 1; } else { qiv_deletedfile *del; if (!deleted_files) deleted_files = (qiv_deletedfile*)xcalloc(MAX_DELETE,sizeof *deleted_files); del = &deleted_files[delete_idx++]; if (delete_idx == MAX_DELETE) delete_idx = 0; if (del->filename) free(del->trashfile); del->filename = filename; del->trashfile = strdup(trashfile); del->pos = image_idx; --images; for(i=image_idx;i 0) write(fdo, buf, n); close(fdi); close(fdo); return 0; } /* move the last deleted image out of the delete list */ int undelete_image() { int i; qiv_deletedfile *del; char *ptr; if (readonly) return 0; if (!deleted_files) { g_print("Error: nothing to undelete\a\n"); return 1; } if (--delete_idx < 0) delete_idx = MAX_DELETE - 1; del = &deleted_files[delete_idx]; if (!del->filename) { g_print("Error: nothing to undelete\a\n"); return 1; } if (rename(del->trashfile,del->filename) < 0) { g_print("Error: undelete_image '%s' failed\a\n", del->filename); del->filename = NULL; free(del->trashfile); return 1; } /* unlink TRASH_DIR if empty */ ptr = del->trashfile; /* the path without the filename is the TRASH_DIR */ ptr = strrchr(ptr,'/'); *ptr = '\0'; if(rmdir(del->trashfile)) { /* we can't delete the TRASH_DIR because there are still files */ } *ptr = '/'; image_idx = del->pos; for(i=images;--i>=image_idx;) { image_names[i+1] = image_names[i]; } images++; image_names[image_idx] = del->filename; del->filename = NULL; free(del->trashfile); return 0; } #define MAXOUTPUTBUFFER 16384 #define MAXLINES 100 /* run a command ... */ void run_command(qiv_image *q, char *n, char *filename, int *numlines, const char ***output) { static char nr[100]; static char *buffer = 0; static const char *lines[MAXLINES + 1]; int pipe_stdout[2]; int pid; char *newfilename; int i; struct stat before, after; stat(filename, &before); if (!buffer) buffer = xmalloc(MAXOUTPUTBUFFER + 1); *numlines = 0; *output = lines; snprintf(infotext, sizeof infotext, "Running: 'qiv-command %s %s'", n, filename); snprintf(nr, sizeof nr, "%s", n); /* Use some pipes for stdout and stderr */ if (pipe(pipe_stdout) < 0) { perror("pipe"); return; } pid = fork(); if (pid == 0) { /* Child */ dup2(pipe_stdout[1], 1); dup2(pipe_stdout[1], 2); close(pipe_stdout[1]); execlp("qiv-command", "qiv-command", nr, filename, NULL); perror("Error calling qiv-command"); abort(); } else if (pid > 0) { /* parent */ int len = 0; char *p = buffer; gboolean finished = FALSE; close(pipe_stdout[1]); do { char *s = p, *q; finished = waitpid(pid, 0, WNOHANG) > 0; len = read(pipe_stdout[0], s, MAXOUTPUTBUFFER - (s - buffer)); if (len < 0 || (finished && len == 0)) break; s[len] = '\0'; /* Process the buffer into lines */ for (; *numlines < MAXLINES && p < s + len; ) { lines[(*numlines)++] = p; /* Find the end of the line */ q = strchr(p, '\n'); if (!q) break; *q = '\0'; p = q + 1; } } while (len > 0); lines[(*numlines)] = 0; if (!finished) waitpid(pid, 0, 0); close(pipe_stdout[0]); } else { perror("fork"); return; } /* Check for special keyword "NEWNAME=" in first line * indicating that the filename has changed */ if ( lines[0] && strncmp(lines[0], "NEWNAME=", 8) == 0 ) { newfilename = strdup(lines[0]); newfilename += 8; #ifdef DEBUG g_print("*** filename has changed from: '%s' to '%s'\n", image_names[image_idx], newfilename); #endif image_names[image_idx] = strdup(newfilename); filename = strdup(newfilename); /* delete this line from the output */ (*numlines)--; lines[0] = 0; for (i = 0; i < *numlines; i++) { lines[i] = lines[i+1]; } update_image(q, FULL_REDRAW); return; } stat(filename, &after); /* If image modified reload, otherwise redraw */ if (before.st_size == after.st_size && before.st_ctime == after.st_ctime && before.st_mtime == after.st_mtime) update_image(q, FULL_REDRAW); else qiv_load_image(q); } /* This routine jumps x images forward or backward or directly to image x Enter jf10\n ... jumps 10 images forward Enter jb5\n ... jumps 5 images backward Enter jt15\n ... jumps to image 15 */ void jump2image(char *cmd) { int direction = 0; int x; #ifdef DEBUG g_print("*** starting jump2image function: '%s'\n", cmd); #endif if(cmd[0] == 'f' || cmd[0] == 'F') direction = 1; else if(cmd[0] == 'b' || cmd[0] == 'B') direction = -1; else if(!(cmd[0] == 't' || cmd[0] == 'T')) return; /* get number of images to jump or image to jump to */ x = atoi(cmd+1); if (direction == 1) { if ((image_idx + x) > (images-1)) image_idx = images-1; else image_idx += x; } else if (direction == -1) { if ((image_idx - x) < 0) image_idx = 0; else image_idx -= x; } else { if (x > images || x < 1) return; else image_idx = x-1; } #ifdef DEBUG g_print("*** end of jump2image function\n"); #endif } void finish(int sig) { gdk_pointer_ungrab(CurrentTime); gdk_keyboard_ungrab(CurrentTime); exit(0); } /* Update selected image index image_idx Direction determines if the next or the previous image is selected. */ void next_image(int direction) { static int last_modif = 1; /* Delta of last change of index of image */ if (!direction) direction = last_modif; else last_modif = direction; if (random_order) image_idx = get_random(random_replace, images, direction); else { image_idx = (image_idx + direction) % images; if (image_idx < 0) image_idx += images; else if (cycle && image_idx == 0) qiv_exit(0); } } int checked_atoi (const char *s) { char *endptr; int num = strtol(s, &endptr, 0); if (endptr == s || *endptr != '\0') { g_print("Error: %s is not a valid number.\n", s); gdk_exit(1); } return num; } void usage(char *name, int exit_status) { g_print("qiv (Quick Image Viewer) v%s\n" "Usage: qiv [options] files ...\n" "See 'man qiv' or type 'qiv --help' for options.\n", VERSION); gdk_exit(exit_status); } void show_help(char *name, int exit_status) { int i; g_print("qiv (Quick Image Viewer) v%s\n" "Usage: qiv [options] files ...\n\n", VERSION); g_print( "General options:\n" " --file, -F x Read file names from text file x or stdin\n" " --bg_color, -o x Set root background color to x\n" " --brightness, -b x Set brightness to x (-32..32)\n" " --browse, -B Scan directory of file for browsing\n" " --center, -e Disable window centering\n" " --contrast, -c x Set contrast to x (-32..32)\n" " --cycle, -C do not cycle after last image\n" " --display x Open qiv window on display x\n" " --do_grab, -a Grab the pointer in windowed mode\n" " --disable_grab, -G Disable pointer/kbd grab in fullscreen mode\n" " --fixed_width, -w x Window with fixed width x\n" " --fixed_zoom, -W x Window with fixed zoom factor (percentage x)\n" " --fullscreen, -f Use fullscreen window on start-up\n" " --gamma, -g x Set gamma to x (-32..32)\n" " --help, -h This help screen\n" " --ignore_path_sort, -P Sort filenames by the name only\n" " --readonly, -R Disable the deletion feature\n" " --maxpect, -m Zoom to screen size and preserve aspect ratio\n" " --merged_case_sort, -M Sort filenames with AaBbCc... alpha order\n" " --no_filter, -n Do not filter images by extension\n" " --no_statusbar, -i Disable statusbar\n" " --statusbar, -I Enable statusbar\n" " --no_sort, -D Do not apply any sorting to the list of files\n" " --numeric_sort, -N Sort filenames with numbers intuitively\n" " --root, -x Set centered desktop background and exit\n" " --root_t, -y Set tiled desktop background and exit\n" " --root_s, -z Set stretched desktop background and exit\n" " --scale_down, -t Shrink image(s) larger than the screen to fit\n" " --transparency, -p Enable transparency for transparent images\n" " --watch, -T Reload the image if it has changed on disk\n" " --recursivedir, -u Recursively include all files\n" " --select_dir, -A x Store the selected files in dir x (default is .qiv-select)\n" #if GDK_PIXBUF_MINOR >= 12 " --autorotate, -l Autorotate JPEGs according to EXIF rotation tag\n" #endif " --rotate, -q x Rotate 90(x=1),180(x=2),270(x=3) degrees clockwise\n" #ifdef GTD_XINERAMA " --xineramascreen, -X x Use screen x as preferred Xinerama screen\n" #endif " --version, -v Print version information and exit\n" "\n" "Slideshow options:\n" "This can also be used for the desktop background (x/y/z)\n" " --slide, -s Start slideshow immediately\n" " --random, -r Random order\n" " --shuffle, -S Shuffled order\n" " --delay, -d x Wait x seconds between images [default=%d]\n" "\n" "Keys:\n", SLIDE_DELAY/1000); /* skip header and blank line */ for (i=0; helpkeys[i]; i++) g_print(" %s\n", helpkeys[i]); g_print("\nValid image extensions:\nUse --no_filter/-n to disable"); for (i=0; image_extensions[i]; i++) g_print("%s%s", (i%8) ? " " : "\n ", image_extensions[i]); g_print("\n\n"); g_print("Homepage: http://qiv.spiegl.de/\n" "Please mail bug reports and comments to Andy Spiegl \n"); gdk_exit(exit_status); } /* returns a random number from the integers 0..num-1, either with replacement (replace=1) or without replacement (replace=0) */ int get_random(int replace, int num, int direction) { static int index = -1; static int *rindices = NULL; /* the array of random intgers */ static int rsize; int n,m,p,q; if (!rindices) rindices = (int *) xmalloc((unsigned) max_rand_num*sizeof(int)); if (rsize != num) { rsize = num; index = -1; } if (index < 0) /* no more indices left in this cycle. Build a new */ { /* array of random numbers, by not sorting on random keys */ index = num-1; for (m=0;m is true, * else just reads directory */ int rreaddir(const char *dirname, int recursive) { DIR *d; struct dirent *entry; char cdirname[FILENAME_LEN], name[FILENAME_LEN]; struct stat sb; int before_count = images; strncpy(cdirname, dirname, sizeof cdirname); cdirname[FILENAME_LEN-1] = '\0'; if (!(d = opendir(cdirname))) return -1; while ((entry = readdir(d)) != NULL) { if (strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0 || strcmp(entry->d_name,TRASH_DIR) == 0) continue; snprintf(name, sizeof name, "%s/%s", cdirname, entry->d_name); if (lstat(name, &sb) >= 0) { if (S_ISDIR(sb.st_mode)) { if (!recursive) continue; rreaddir(name,1); } else { if (images >= max_image_cnt) { max_image_cnt += 8192; if (!image_names) image_names = (char**)xmalloc(max_image_cnt * sizeof(char*)); else image_names = (char**)xrealloc(image_names,max_image_cnt*sizeof(char*)); } image_names[images++] = strdup(name); } } } closedir(d); return images - before_count; } /* Read image filenames from a file */ int rreadfile(const char *filename) { FILE *fp; struct stat sb; int before_count = images; if (strcmp(filename,"-")) { fp = fopen(filename, "r"); if(!fp) return -1; } else fp = stdin; if (!images) { max_image_cnt = 8192; image_names = (char**)xmalloc(max_image_cnt * sizeof(char*)); } while (1) { char line[ BUFSIZ ]; size_t linelen; if (fgets(line, sizeof(line), fp) == NULL ) { if (ferror(fp)) g_print("Error while reading %s: %s\n", filename, strerror(errno)); fclose(fp); break; } linelen = strlen(line) -1; if (line[linelen] == '\n') line[linelen--] = '\0'; if (line[linelen] == '\r') line[linelen--] = '\0'; if (stat(line, &sb) >= 0 && S_ISDIR(sb.st_mode)) rreaddir(line,1); else { if (images >= max_image_cnt) { max_image_cnt += 8192; image_names = (char**)xrealloc(image_names,max_image_cnt*sizeof(char*)); } image_names[images++] = strdup(line); } } return images - before_count; } gboolean color_alloc(const char *name, GdkColor *color) { gboolean result; result = gdk_color_parse(name, color); if (!result) { fprintf(stderr, "qiv: can't parse color '%s'\n", name); name = "black"; } result = gdk_colormap_alloc_color(cmap, color, FALSE, TRUE); if (!result) { fprintf(stderr, "qiv: can't alloc color '%s'\n", name); color->pixel = 0; } return result; } void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } /* rounding a float to an int */ int myround( double a ) { return( (a-(int)a > 0.5) ? (int)a+1 : (int)a); } /* File watcher, an idle thread checking whether the loaded file has changed */ gboolean qiv_watch_file (gpointer data) { struct stat statbuf; qiv_image *q=data; if(!watch_file) return FALSE; stat(image_names[image_idx], &statbuf); if(current_mtime!=statbuf.st_mtime && statbuf.st_size){ reload_image(q); update_image(q, REDRAW); } usleep(200); /* avoid eating 100% cpu */ return TRUE; } int find_image(int images, char **image_names, char *name) { int i; for (i=0; iscreen_number); value = f(screen); if (value > maxvalue) { maxvalue = value; maximal_screen = screen; } } return maximal_screen; } static long xinerama_screen_number_pixels (XineramaScreenInfo * screen) { // g_print("npixels: screen->width = %d, screen->height = %d\n", screen->width, screen->height); return screen->width * screen->height; } /** * We will want to find the lower-rightmost screen (on which we * would like to display the statusbar in full-screen mode). * * In the general case (screens of differing sizes and arbitrarily placed) * the "lower-rightmost" screen is not particularly well defined. We * take the definition as follows: * * Let (l_i, r_i) be the absolute pixel coordinates of the lower right corner * corner of screen i. The lower-rightmost screen is the one for which * l_i + r_i is a maximum. */ static long xinerama_screen_lower_rightness (XineramaScreenInfo * screen) { return screen->x_org + screen->y_org + screen->width + screen->height; } void get_preferred_xinerama_screens(void) { Display * dpy; XineramaScreenInfo *screens = 0; dpy = XOpenDisplay(gdk_get_display()); if (dpy && XineramaIsActive(dpy)) screens = XineramaQueryScreens(dpy, &number_xinerama_screens); // g_print("number_xinerama_screens: %i\n", number_xinerama_screens); if (screens) { // g_print("xinerama screen: %i\n", user_screen); if (user_screen > -1 && user_screen < number_xinerama_screens) { // set user selected screen *preferred_screen = screens[user_screen]; // g_print("preferred screen (user): %i\n", preferred_screen->screen_number); } else { // auto select largest screen *preferred_screen = *xinerama_maximize_screen_function(screens, number_xinerama_screens, xinerama_screen_number_pixels); // g_print("preferred screen (auto): %i\n", preferred_screen->screen_number); } // find lower rightmost screens for the statusbar *statusbar_screen = *xinerama_maximize_screen_function(screens, number_xinerama_screens, xinerama_screen_lower_rightness); XFree(screens); } else { /* If we don't have Xinerama, fake it: */ preferred_screen->screen_number = 0; preferred_screen->x_org = 0; preferred_screen->y_org = 0; preferred_screen->width = gdk_screen_width(); preferred_screen->height = gdk_screen_height(); *statusbar_screen = *preferred_screen; } if (dpy) XCloseDisplay(dpy); } #endif qiv-2.2.4.orig/xmalloc.c0000644000175000017500000000326311563226774014075 0ustar bartmbartm/* xmalloc.c - Do-or-die Memory management functions. * * Created by Kevin Locke (from numerous canonical examples) * * I hereby place this file in the public domain. It may be freely reproduced, * distributed, used, modified, built upon, or otherwise employed by anyone * for any purpose without restriction. */ #include #include #include #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #define EXIT_FAILURE 1 #endif void *xmalloc(size_t size) { void *allocated = malloc(size); if (allocated == NULL) { fprintf(stderr, "Error: Insufficient memory " # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) "(attempt to malloc %zu bytes)\n", #else "(attempt to malloc %u bytes)\n", #endif (unsigned int) size); exit(EXIT_FAILURE); } return allocated; } void *xcalloc(size_t num, size_t size) { void *allocated = calloc(num, size); if (allocated == NULL) { fprintf(stderr, "Error: Insufficient memory " # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) "(attempt to calloc %zu bytes)\n", #else "(attempt to calloc %u bytes)\n", #endif (unsigned int) size); exit(EXIT_FAILURE); } return allocated; } void *xrealloc(void *ptr, size_t size) { void *allocated; /* Protect against non-standard behavior */ if (ptr == NULL) { allocated = malloc(size); } else { allocated = realloc(ptr, size); } if (allocated == NULL) { fprintf(stderr, "Error: Insufficient memory " # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) "(attempt to realloc %zu bytes)\n", #else "(attempt to realloc %u bytes)\n", #endif (unsigned int) size); exit(EXIT_FAILURE); } return allocated; } qiv-2.2.4.orig/Changelog0000644000175000017500000010656011563226774014110 0ustar bartmbartmAuthors: ak: Adam Kopacz as: Andy Spiegl de: Darren Smith pa: Pavel Andreev df: Decklin Foster hm: Holger Mueller ss: Scott Sams sw: Serge Winitzki fc: Frederic Crozat rn: Rutger Nijlunsing jk: John Knottenbelt da: Danny to: Tomas Ogren ej: Erik Jacobsen aw: Alfred Weyers da: Daniel hk: Henning Kulander ab: Ask Bjoern Hansen al: Adrian Lopez yf: Y Furuhashi wd: Wayne Davison js: Johannes Stezenbach ok: OEyvind Kolaas mc: Matthieu Castet jd: Geoffrey T. Dairik lc: Leopoldo Cerbaro hl: Heikki Lehvaslaiho ld: Larry Doolittle sd: S. Dobrev tw: Thomas Wiegner bd: Barry deFreese pw: Peter deWachter ap: Akos Pasztory 2.2.4 ===== 02.05.2011 [as] README: added note about obsoleted GTK v1 28.12.2010 [as] qiv-command: more examples from Clint Pachl 02.11.2010 [tw] only center image upon reload when center option is active [tw] Do not break install if using a non existing target location (clemens fischer) [tw] make gdk options work again (e.g. --display) [tw] Do not follow symlinked directories, when using recursivedir option (Goswin v. Brederlow) [tw] Add option to change cycle behavior after last picture. (patch by Nicolas Pouillard) [tw] Images were displayed twice when using --browse option. (patch by Adam Lee) [tw] Fix inconsistent behavior when using -x/-y/-z option. 2.2.3 ===== 10.01.2010 [tw] add 'Q' icon in qiv-window [tw] bring back scrollwheel functionality (Based upon a patch sent by "Johnny") Zoom in/out with left/right scroll and forward/back buttons [tw] change loading of images from imlib2_loader to pixbuf_loader. Adds support for additional file types, e.g. pcx, ico, svg, wmf and better handling of transparency. [tw] use gdk_pixbuf to autorotate with EXIF tags instead of libexif. Note: needs at least GDK 2.12 [tw] Resetting the image (pressing return) no longer destroys "transparency checkboard" [tw] Fix compilation issues with unusual linker defaults. Update solaris Makefile. [tw] new option to start with default rotation (patch submitted by Atsushi Kamoshida) 2.2.2 ===== 30.05.2009 [tw] fix -x (root window needs colormap) [tw] patch pango code to avoid garbled output of F1 [as] fix wrong image size after autorotating 2.2.1 ===== 28.05.2009 [tw] recognize changed files, using --slideshow and --watch [tw] sanitize infotextdisplay [tw] check EXIF tags only after successful file loading [tw] shuffle now implies not to sort filenames [tw] fix autorotate with EXIF-tag [tw] avoid crash calling qiv -x without argument [ap] fix behaviour of "recursivedir" switch [as] added note in README and qiv.h explaining a problem of includes with imlib2 up to v1.2 [as] migrated notes in README from imlib1 to imlib2 [tw] migrated gdk_draw_text() to gdk_draw_layout() fixing wrong display of utf-8 filenames 2.2 === 30.04.2009 [pw] migration from imlib1 to imlib2 2.1 === 05.03.2009 [as] Adam Kopacz delegated to new maintainer: Andy Spiegl [as] new homepage: http://qiv.spiegl.de/ [as] removed obsoleted GDK_WA_WMCLASS see http://library.gnome.org/devel/gdk/2.11/gdk-Windows.html#GdkWindowAttr and http://developer.gimp.org/api/2.0/gtk/GtkWindow.html#gtk-window-set-wmclass Thanks to Bernhard Kaindl . [as] added patch from Debian gtk_includes.diff, closes: #456854 [as] added patch from Debian cmdbuflen.diff, closes: #441401 Thanks to Norman Ramsey . [as] added patch from Debian man_xscreensaver.diff [as] remove xscreensaver left overs from Makefiles [sd] added autorotate patch (using libexif) by sdobrev@sistechnology.com [as] display initial autorotation in status bar, option "autorotate" [tw] patch to detect image types using libmagic [de] added GDK_ENTER_NOTIFY_MASK|GDK_LEAVE_NOTIFY_MASK in image.c [de] removed TGA and XBM because not supported by imlib anymore [de] exit on unmapped mouse events [de] browse option -B, useful when launching qiv from a file manager 21.05.2007 [pre13] [ld] patch to prevent segfault on amd64 02.05.2007 [pre12] [as] avoid wrapper, include "XLIB_SKIP_ARGB_VISUALS=1" in main.c 25.04.2007 [as] include README and README.TODO in debian package README.TODO: fvwm style setting has to be for "therealqiv" 25.04.2007 [pre11] [as] include Debian changes and package files: renamed README.CHANGES to Changelog added patch hide_therealqiv (for Debian Bug #326849) added patch xmalloc (Debian Bug #383113) added patch qiv-manpage-options (Debian Bug #383108) don't recurse directories given on command line (better: use -u) NOT added: no_background_opts (can't reproduce Debian Bug #351816) added patch qiv-nosort [hl] patch to reset bright/contrast/gamma hitting "o" (2006-06-29) 24.04.2007 [as] more comments and examples in qiv-command option -X to set preferred xinerama screen key "X" cycles through available xinerama screens after 'X' window moves to the new screen right away prefix "^" instead "0" for extended call of qiv-command workaround-patch by Bart Martens for problem with X composite extension try keep image on the screen after zooming/rotating fixed centering=off behaviour in fullscreen mode fixed "magnifying glass" windowsize bug fixed compiler warnings "differ in signedness" fixed compiler warning "missing sentinel in function call" 07.10.2005 [lc] bugfix: statusbar is redrawn after size changes and moves 30.09.2005 [lc] "magnifying glass" patch (not perfect yet) call of qiv-command with "0"-prefixed option 10.05.2005 [pre10] [AK] Added Patch by Christoph Wegscheider (new QIV Debian maintainer). Now all free Keys can be used by qiv-command 27.03.2005 [pre9] [jd] Another Xinerama bugfix (statusbar: now displayed on the smaller screen if two are used) 23.02.2005 [pre8] [as] new qiv-command feature: if first output line is like "NEWNAME=xxxxxxx" then qiv understands that the filename of the currently displayed image has changed to this new name (very useful when using qiv-command to rename files) fix image position when zooming to avoid wild jumps delete files from list if they cannot be loaded display text popup after qiv-command not only in fullscreen mode qiv_display_text_window: adjust minimum width of box after qiv-command also check file size and ctime avoid file overwrites in .qiv-select (NEEDS IMPROVING) updated and added more examples to qiv-command 01.01.2005 [pre7] [ak] added small patch by Nick Clifton : setting WM_CLASS name to "qiv" (attr.wmclass_name). 05.12.2004 [pre6] [ak] changed a-key/copy to real copy (no links anymore) 11.09.2004 [pre5] [ak] patch-bugfix by Christian Lademann 01.09.2004 [pre4] [ak] adden patch by Christian Lademann now slideshow (-s) can also be combine with -x/y/z 07.07.2004 [pre3] [ak] added -F Patch by Martin Fiedler now stdin can also be used.. 16.06.2004 [pre2] [jd] Xinerama bugfix 26.05.2004 [pre1] [wd] small changes in delete-command 2.0 === 22.05.04 [ak] released v2.0! 08.05.04 [pre12] [ak] some Makefile.Solaris changes again Work-Tests: Soalis=ok, FreeBSD (5.2-CURRENT): ok 07.05.04 [pre11] [ak] changed round(); to myround(); and fixed Makefile.Solaris 24.04.04 [pre10] [jk] fixed qiv_display_text_window 24.04.04 [pre9] [ak] added patch by Joachim Kuebart (kuebart@mathematik.uni-ulm.de) if images is < 5 and PgUp is pressed, image_index might become negative.. [mc] small patch that remove a warning with gcc 3.4 19.04.04 [pre8] [jk] qiv_display_text_window update (Push any key..) - its really cool! :-) [ak] cleaned up README, qiv-command.example, manpage.. 19.04.04 [pre7] [jk] Fixed Help-Screen remove. Added qiv-command-stdout support, now "metacam" (EXIF-Header) or other tools can be used within qiv and the output is shown in a box in the pixture like the helpscreen. 18.04.04 [pre6] [ak] All arrow-keys = normal moving. All arrow-keys+Shift = faster moving. NumPad-arrow-keys+NumLock = faster moving. 18.04.04 [pre6] [ak] All arrow-keys = normal moving. All arrow-keys+Shift = faster moving. NumPad-arrow-keys+NumLock = faster moving. 18.04.04 [pre5] [mc/ak] Added patch: Faster moving of pictures with pushed Shift+Arrow-Keys. 14.04.04 [pre3/4] [jd] Xinerama patch (MultiHead XFree86 V. 4.0+) 23.02.04 [pre2] [ak] fixed manpage (ignore_path_sort was wrong) 08.01.04 [pre1] [ak] Added patch by HaJo Schatz (hajo@hajo.net): "--disable_grab, -G" Disable pointer/kbd grab in fullscreen mode for Remote-Display stuff. 1.9 === 13.12.03 [-----] [ak] Cleaned up version-stuff and released 1.9 :-) 10.11.03 [pre19] [ok] added patch: capability to watch a file for changes, --watch/-T options 27.09.03 [pre18] [ak] removed qiv_set_cursor_timeout from fullscreen-key-event. It hangs with FVWM2. 27.09.03 [pre18] [js] added patch: capability to drag the image with the mouse in fullscreen mode and fixed bugs related to background repainting with --bg_color 23.09.03 [pre17] [ak] added patch by Johannes Stezenbach which hides the mouse cursor after one second and redisplays it when the mouse is moved. I also cleaned up bugs with the delay adjustments (F11/F12), and made sure the 'q' key comes through even when starting with delay 0. 13.09.03 [pre16] [ak] added patch / undelete (link) replaced by rename. Now also works on FAT. 09.09.03 [pre15] [ak] added patch / delete (link) replaced by rename. Now also works on FAT. http://bugs.debian.org/209079 16.06.03 [pre14] [ak] added patch by Robert R. Pavlis fixed event queues (KeyComands). Now a key can be hold down for a while ;) 25.05.03 [pre13] [ak] added patch by Martin Pitt / DEBIAN Fixed handling of non existing images (no crash anymore) 24.05.03 [pre12] [ak] added patch by Martin Pitt / DEBIAN Now -d can contain 0.5 seconds or so.. 16.02.03 [pre11] [ak] added patch by Drew Cohan Key F11/F12 now in-/decrease the Slideshow-Delay (+/- 1 sec). Think its maybe time for QIV v2.0 ?! :-) 13.01.03 [pre10] [ak] added patch by J'raxis 270145 --file= (-F) option to qiv to allow it to read image/directory names from a text file 24.12.02 [pre9] [ak] added PBM support (just the extension) 20.10.02 [pre8] [ak] added patch by Wayne Davison scale-down rotation quirk. 20.10.02 [pre7] [ak] added patch by Kim Rasmussen fixed WM "wmx v6" centering problem. 04.10.02 [pre6] [ak] added patch by Lin Zhemin A-key to copy images to "./.qiv-select". 26.09.02 [pre5] [ak] added patch by Wayne Davison (some small changes) 11.09.02 [pre4] [ak] added patch by Geoff Richards great patch to reduce flicker while moving in fullscreen :-) 26.08.02 [pre3] [ak] added patch by Simon Budig removed "-u". qiv is now detecting directorys. added "-R" (readonly option). 10.08.02 [ak] added jpeg ".jpe" support (just the extension). 05.08.02 [pre2] [ak] added patch by Qef Richards : changed the option handling slightly so that invalid arguments to options which want numbers will be detected and a suitable error message printed. 20.07.02 [pre1] [ak] now using qiv_load_image after qiv-command (no segfaults anymore) 1.8 === 16.07.02 [----] [ak] Released 1.8 :-) 07.07.02 [pre8] [ak] added zoom in/out bugfix from Qef Richards 29.06.02 [pre7] [as] fixed load_time. now the real render/load/display-time is displayed. 09.06.02 [pre6] [as] fixed image moving merged update_m_image and update_z_image into update_image 05.06.02 [pre5] [as] fixed trashdir and delete path, fixed rounding error of zoom factor in statusbar added support for transparency in fullscreen mode (leaves a problem with the disappearing window border) added a Transparency toggle added possibility for the statusbar in non-fullscreen mode added command line switch "I" to force display of the statusbar changed command line switch ignore_path_sort from "I" to "P" added command line switch "W" for a fixed zoom factor added a Center mode toggle changed meaning of page down/up keys 16.05.02 [pre4] [ak] Added reload-after-qiv-command-patch from "Andy Spiegl " 12.05.02 [pre3] [ak] Added Iconify-Patch (Key: I) from "Goetz Waschk " 29.12.01 [pre2] [ak] Added manpage-patch (qiv-command changes) from James M Corey 31.07.01 [pre1] [ak] added patch from Matthias Kilian (adds random order when starting qiv in shuffle mode & fixed deleting and undeleting a picture which is a symlink) 1.7 === 05.07.01 [----] [ak] added a qiv-command.example & released 1.7 :-) 10.06.01 [pre9] [ak] added qiv_command_patch from post@volker-wysk.de 03.06.01 [pre8] [ak] image_moving now uses func update_m_image. no screen clean first anymore -> faster moving :) zoom now uses update_z_image -> a little bit faster zoom (+0.1s?) added README.TODO 11.05.01 [pre7] [wd] Fixed window-resizing in non-fullscreen mode. Fixed combining -x with -m or -t. 02.05.01 [pre6] [wd] Fixed mouse-hiding on button-push when fullscreen. Added some missing names to the doc file. 30.04.01 [pre5] [wd] Hide the mouse on keypress and button push when it is in the qiv window (the mouse is re-shown on mouse movement). Improved the sort algorithms (particularly the numeric sort). 02.04.01 [pre4] [wd] rreaddir() patch. 28.03.01 [pre3] [wd] Added undelete image command (bound to u & U). Allow the user to specify multiple -u options and also to specify files on the commandline in addition to -uDIRs. Added new commandline sorting options (-I, -M, & -N). Optimized rreaddir(), next_image(), and get_random(). Improved the implementation of shuffle. Other misc. (and minor) bug fixes and tweaks. 20.02.01 [pre2] [yf] removed slideshow_exit from default event. 17.02.01 [pre1] [yf] added the option -w x or --width x for displaying with a fixed window-width. 1.6 === 18.01.01 [1.6] [ak] killed "pre8" string, -v (gzip) - we dont neet verbose mode *g* release qiv 1.6 06.01.01 [1.6] [df] Put 'm' back in help text (oops!) 06.01.01 [pre8] [df] Rewrote part of the extension filtering code. 06.01.01 [pre8] [df] Move the program used to compress man pages (gzip -9vf) up to the top so that it can be disabled easily. 06.01.01 [pre8] [df] Some HP-UX compilation fixes. 05.01.01 [pre7] [df] Change zoom_in/zoom_out so that they will break out of maxpect/scale_down mode, and make maxpect/scale_down override each other. 05.01.01 [pre7] [df] A whole bunch of other cleanups. 05.01.01 [pre7] [df] Updated keys help text for rotation/moving. 05.01.01 [pre7] [df] Fixed bug that caused the image not to update when brightness/contrast/gamma was re-adjusted to 0/0/0 (with either the Enter key or B/C/G.) 05.01.01 [pre7] [df] Merged README.SPEED_UP into README. 05.01.01 [pre7] [df] Don't reset image size when rotating, and scale properly according to maxpect/scale_down. 05.01.01 [pre7] [df] Fold filter.c into main.c. 05.01.01 [pre7] [df] Big cleanup: move everything pertaining to the image into a qiv_image struct and pass that as an argument to most functions. Got rid of a lot of global variables. 04.01.01 [pre6] [df] gzip manpage with -9 (This is required for Debian packages, and is a good idea anywhere). 04.01.01 [pre6] [df] Replace strcpy/strcat with strncpy/snprintf in rreaddir and move2trash to prevent a few more possible overflows. 04.01.01 [pre6] [df] Clean up initialization code. 04.01.01 [pre6] [df] Redo color handling: remove GDK deprecated functions and internal color list. Now you can use any color from X's rgb.txt or equivalent (however, you may have to change '123456' to '#123456'). 03.01.01 [pre5] [df] Fix Makefile to handle fonts with spaces in their names. 03.01.01 [pre5] [df] Use actual font height when drawing the help screen and statusbar instead of hardcoding it. 03.01.01 [pre5] [df] Plug text_font and statusbar_background_gc memory leaks. 03.01.01 [pre5] [df] Use helpstrs in show_help to avoid duplicating the help text. 03.01.01 [pre5] [df] Change raw keysyms to symbolic names in event.c. 02.01.01 [pre4] [df] Use NULL for the sentinel value in image_extentions. 02.01.01 [pre4] [df] Updated man page. 02.01.01 [pre4] [df] Replace random() with rand(), since the HAVE_RANDOM check didn't really work properly, rand is guaranteed to be there, and it's acceptible for the amount of randomness we need. This facilitated some more Makefile improvements. 02.01.01 [pre4] [df] Reorganized the source layout a bit. Optional code now lives in the lib/ dir. 02.01.01 [pre4] [df] Resync Makefile.Solaris to Makefile, and make some minor fixes to each. 01.01.01 [pre3] [df] Updated -e to work properly with the new centering stuff. This is now considered a feature, not a workaround ;-) 01.01.01 [pre3] [df] Put x and y hints into the window when we create it (should eliminate the "window pops up and then centers itself" problem.) 01.01.01 [pre3] [df] Removed last traces of wm_handle kludge, and set StaticGravity instead. 31.12.00 [pre3] [df] Only call gdk_show_window on load, not every single time we update. 31.12.00 [pre3] [df] Replaced strsort with qsort. (should be faster, doesn't have an illegal name ;-) 31.12.00 [pre3] [df] Replaced sprintf with snprintf and g_snprintf to prevent any possible overflows. 31.12.00 [pre3] [df] Cleaned up some extraneous blank lines in output. 05.12.00 [pre2] [ak] another PPC fix. 27.11.00 [pre1] [ak] changed "char c" to "int c" in options.c not worked with char on Linux/ppc (mailed by Jiri Masik ) 1.5 === 23.09.00 [pre3] [ak] Released v1.5 - new homepage: www.klografx.net/qiv/ 05.08.00 [pre3] [ak] cleaned up readmes.. 05.08.00 [pre2] [ak] changed up/down and left/right moving of the image. now the stuff works like in ACDSee (Win). 30.07.00 [pre1] [ak] added limits for moving. 1.4 === 28.07.00 [1.4] [ak] added solaris 2.5 patch from francois.petitjean@bureauveritas.com 25.07.00 [1.4] [ak] added image moving with left/right/up/down-keys! :) tried to fix reset_display_settings (b/g/c) but it dont work.. hm added zoom_out limits (64x64). changed keys: now K and L rotate the image. 1.4 === 25.06.00 [pre4] [da] Sending a SIGUSR1 to qiv will cause the program to flip to next picture. SIGUSR2 will move to previous. 15.06.00 [pre3] [ak] re-added b/c/g to titlebar/infoline. painted new intro.jpg *g* 29.04.00 [pre2] [al] image shuffling option (--shuffle) provides random image order while preserving next and previous functionality. 13.04.00 [pre1] [ak] cleaned up infoscreen/added more info and kicked "show_info". 03.04.00 [pre1] [da] The delay time in slideshow mode used to include the time it took for a picture to load. Pressing '?' in non-fullscreen mode results in the help being printed to stdout. 1.3 === 03.04.00 [pre4] [ak] updated man-page and info-screens. also added "qiv: " to title and info-bar. RELEASED v1.3-finale. 03.04.00 [pre4] [ab] patch to run a script called "qiv-command" with the key number and the filename as parameters. keys: 0-9. 13.02.00 [pre3] [de] utils.c patch. added recursive file retrieval (-u option) 30.10.99 [pre2] [ak] removed b/c/g limits to enable nice effects like b0/c-100/g0 :-) 05.10.99 [pre2] [ak] added SPEED_UP readme. 28.09.99 [pre2] [ak] added nice "infotext" stuff that shows a short info about the called function in the statusbar (maxspect: on/off and so..) 24.09.99 [pre1] [hk] started using a better random-slideshow generator. 1.2 === 23.09.99 [da] "?" patch :) 23.09.99 [aw] transparency bugfix. 17.06.99 [ak] no_replace is now default fpr random-slideshow. the parameter has been removed. 14.06.99 [ak] added TO-DO list 14.06.99 [ej] added slideshow_without_replacement_patch 1.1 === 27.04.99 [ak] added #include to image.c 21.04.99 [df] changed Makefile to use the system's getopt if it's availible, took the getopt section back out of README, updated install-xscreensaver to use -fitsd style options, fixed -h typo. 21.04.99 [pa] Included GNU getopt_long sources and deleted the non-getopt code from options.c. 20.04.99 [ak] kicked make test ;) now its in make install again. 20.04.99 [df] added HAVE_GETOPT_LONG conditional compilation stuff for Solaris/FreeBSD, rescued xscreensaver stuff from install.sh into Makefile, shuffled INSTALL into README and reformatted a bit. 20.04.99 [ak] kicked user_settings from qiv.h (nw in Makefile) added --help. small changes in manpage. 19.04.99 [df] rewrote Makefile (replacing install.sh), fixed syntax of -e, rewrote option-parsing code to use getopt, axed really long usage message, header file reorg. 17.04.99 [ak] removed prefix from install.sh. don't ask me why, but this don't works here with my bash 2.01 :( 15.04.99 [de] Makefile changes/additions (test/debug targets) Added prefix to install script 13.04.99 [ak] man page update, many tests, new image . 08.04.99 [pa] fixed the "-d 0" problem :-) 07.04.99 [pa] fixed the slideshow/key problems from pre4 with some glib versions. 06.04.99 [pa] slideshow fixes. [ak] removed old language.h/stuff. 02.04.99 [pa] Reorganized everything to use events and not to eat up 100% CPU time. Got rid of sleep() in slideshow, thus making qiv react faster. Random now works not only in slideshow. In random non-slideshow mode, terms "next image" and "previous image" are essentially the same, as they both are random. Image jumping uses main event handler now. 01.04.99 [pa] added utils.c patch for FreeBSD. 22.02.99 [to/ak] added 8bpp patch for better to_root drawing. 1.0.1 ===== 27.01.99 [ak] kicked the language stuff. updated manpage. tested with newest libraries (gtk/glib 1.1.13, Imlib 1.9.2). 19.11.98 [ak] addec --center, -e for disabling window_centering 13.11.98 [de] speed_ups 10.11.98 [ak] configure script, directiries for language files. added language-information to qiv -v 09.11.98 [de] incorporated Roland Trique's french documentation minor bug-fix to pointer/keyboard grabbing/ungrabbing 1.0 === 05.11.98 [ak] fixed --do_grab for wm=0 added --display and --wm to man-page made qiv ready for releasing 1.0 :-) added error_handler for set_background_image... painted a new and also wonderful intro.png (with the GIMP). 03.11.98 [ak] added gdk_beep(); for bad images (error handler). 03.11.98 [de] better WM_HANDLE= support. better command_line support for Solaris. 03.11.98 [ak] added window_manager_handling.. the damm center_stuff seems to be a general GDK problem :-( no way to fix it (at the moment).. so YOU must tell qiv which WM you are using.. see README selection "Center Problem".. 02.11.98 [de] removed getopt stuff (now qiv manually checks commandline options) 30.10.98 [ak] small changes in main.c: now --display :1 or so works. 27.10.98 [ak] added tga support to main.h/Makefile played with the "first window centered" problem.. it's not fixed 100%, but better then bevore :) 25.10.98 [de] changed bg_color option to use 24 bits (6 numbers - like HTML) cleaned up move2trash function 24.10.98 [de] added more color names 22.10.98 [de] --no_filter option works again added --bg_color (-o) option to change root background color when setting root background image with --root (-x) 20.10.98 [de] modification to bcg variable names to remove warning on Solaris mouse grabbing is no longer the default (use --do_grab (-a) to grab the pointer in windowed mode). 18.10.98 [ak] removed error_xpm. now we set only the background_color to blue. painted a wonderfull intro.jpg and added to make install. 17.10.98 [de] grouped functions into separate files 16.10.98 [de] added imlib dithering for 8 bit displays 15.10.98 [de] fixed another solaris issue with stdlib.h and random/srandom (see the Makefile if you're having problems compiling) 15.10.98 [ak] more comments, small changes in man-page... 14.10.98 [de] added --version, -v switch for version information 13.10.98 [ak] added --no_grab, -a for disabling keyboard/mouse grabbing in windowed mode. added -y/-x also for "no getopt.h"-users ;) 11.10.98 [de] cleaned up code for 1.0 release added x/y/z keys for setting bg (center/tile/stretched) while qiv is running removed x key from exit sequence added keyboard/mouse grabs to qiv (now fullscreen works right) changed mouse events to work off release instead of press --root_s, -z shows the image stretched on root. 11.10.98 [ak] --root. -x now center the image on root (can be used with -m or so..). --root_t, -y shows the image tiled on root. 08.10.98 [ak] added pnm support 0.9.1 (Solaris NOW!) ==================== 08.10.98 [ak] small changes in manpage.. 08.10.98 [de] made 0.9 ready for Soliaris/SunOS. (fixed getopt.h stuff). 0.9 === 04.10.98 [ak] added render_time (x.xs) to title- and statusbar. changed statusbar_color from white to orange. small code-cleanup. 04.10.98 [de] added more stuff to manpage. 03.10.98 [ak] removed doc/ and added qiv.1 to install.sh 03.10.98 [de] created manpage :) 03.10.98 [da] fixed problem with not taking into account the null terminator of some strings (char xyz[x+1]). 01.10.98 [ak] added --no_statusbar (-i) and i/I keys for on/off. added doc/ + install of README file. small changes in usage (its now smaller). fixed statusbar => works! :-) statusbar is now white - added black (1 pixel) border. Changes is now installed to. 30.09.98 [ak] fixed error_xpm.. now w=500 and h=400 in windowed and w=screen_x, h=screen_y (fullscreen) in fullscreen mode. collor is now BLUE :-) like "bluewin95" :)) statusbar added for fullscreen mode.. but its alpha, black text without a background color or so at the moment.. 30.09.98 [ak] happy birthday to me.. happy.. yes, i'm 20 now :) 29.09.98 [de] extension filter can be disabled now: --no_filter (-n) 28.09.98 [jk] fullscreen_mode: instead of blanking the whole window, blanks only the areas which aren't going to be covered by the picture. (?) 0.8.1 ===== 25.09.98 [de] bugfix: move2trash: the problem was that the subdirectories were NOT being created in the .qiv-trash directory. 25.09.98 [ak] removed the error.h (error_xpm[]) not you will get a black screen (500*400)... 0.8 === 22.09.98 [de] filter stuff: now non case-sensitive 23.09.98 [fc] fixed: transparency in fullscreen, jump2image 22.09.98 [ak] imlib_load error handler. 22.09.98 [de] changes on the filter stuff (+Makefile). adds rotate right/left, flip horizontal/vertical and some minor bug fixes to qiv. 18.09.98 [de] added image_filter, pre-increment and removed dir_check. 16.09.98 [de] jxx -> usage 16.09.98 [fc] bugfix (floating point exception). 16.09.98 [de] "jt15[enter]" - qiv should go to image 15, "jb5[enter]" - qiv should go back 5 images to image 10, "jf7[enter]" - qiv should go forward 7 images to image 17 15.09.98 [de] usage + b/c/g again. 15.09.98 [ak] small "--help" changes. sys/time.h :) 15.09.98 [de] b/c/g fix + delete (move to .qiv-trash) funktion :-) 15.09.98 [fc] fixes + comments. 15.09.98 [rn] fixed -r and order. 14.09.98 [ak] maxpect on/off keys: m/M and scale_down (t/T) -x (set X11 background) 14.09.98 [rn] code_rewrite (clean up) and maxpect 0.7 === 12.09.98: [de] random slideshow (-r), brightness, contrast and gamma. 09.09.98: [fc] code cleanup 0.6 === 09.09.98: [fc] full_screen mode and imwheel support. 08.09.98: [fc] slideshow and mouse-bindings :-) 0.5.2 ===== 07.09.98: [ak] fixed transparency again.. now it seems to work fine, but now all windows don't get a border (FVWM2).. 07.09.98: [ak] fixed 'first_window_was_not_centered'-bug.. 07.09.98: [sw] changes in auto_resize funktion. now only to large images will be scalled down. (a/A removed) 0.5.1 ===== 05.09.98: [ak] fixed transparency bug. 0.5 === 04.09.98: [ak] removed 200% zoom limit. 04.09.98: [ak] added s/S key for en- disabling autoresize + -DAUTORESIZE for enabling on startup. 04.09.98: [sw] auto_resize funktion. 04.09.98: [sw] auto_loop on next/prev image. 0.4 === 31.08.98: [ak] using gdk_imlib_kill_image for disabling Imlib-Caching. the caching is a verry good feature, but when you view 100 pictures or so then your system begins to swap.. 30.08.98: [hm/ak] loading of more than one pictures (*.jpg or so) 0.3 === 30.08.98: [ak] center_placement.. but this looks ugly because gdk (1.1.2(cvs)/FVWM2 with OpaqueMove) make a refresh beetwen resize and move :( any ideas ? on KWM this works fine... 29.08.98: [ak] fixed 100% 'bug' 0.2 === 29.08.89: [ss] min_zoom_size=5%, max=200%, auto-resize (window) qiv-2.2.4.orig/xmalloc.h0000644000175000017500000000070511563226774014100 0ustar bartmbartm/* xmalloc.h - Header for do-or-die memory management functions. * * Created by Kevin Locke (to accompany xmalloc.c) * * I hereby place this file in the public domain. It may be freely reproduced, * distributed, used, modified, built upon, or otherwise employed by anyone * for any purpose without restriction. */ extern void *xmalloc(size_t size); extern void *xcalloc(size_t num, size_t size); extern void *xrealloc(void *ptr, size_t size); qiv-2.2.4.orig/main.c0000644000175000017500000001521611563226774013363 0ustar bartmbartm/* Module : main.c Purpose : GDK/Imlib Quick Image Viewer (qiv) More : see qiv README Homepage : http://qiv.spiegl.de/ Original : http://www.klografx.net/qiv/ Policy : GNU GPL */ #include #include #include #include #include #include #ifdef HAVE_MAGIC #include #endif #include "qiv.h" #include "main.h" qiv_image main_img; qiv_mgl magnify_img; /* [lc] */ static void filter_images(int *, char **); static int check_extension(const char *); static void qiv_signal_usr1(); static void qiv_signal_usr2(); static gboolean qiv_handle_timer(gpointer); static void qiv_timer_restart(gpointer); #ifdef HAVE_MAGIC static int check_magic(const char *name); #endif int main(int argc, char **argv) { struct timeval tv; // [as] workaround for problem with X composite extension // is this still needed with imlib2 ?? putenv("XLIB_SKIP_ARGB_VISUALS=1"); /* // [as] thinks that this is not portable enough // [lc] // I use a virtual screen of 1600x1200, and the resolution is 1024x768, // so I changed how screen_[x,y] is obtained; it seems that gtk 1.2 // cannot give the geometry of viewport, so I borrowed from the source of // xvidtune the code for calling XF86VidModeGetModeLine, this requires // the linking option -lXxf86vm. XF86VidModeModeLine modeline; int dot_clock; */ /* Randomize seed for 'true' random */ gettimeofday(&tv,NULL); srand(tv.tv_usec*1000000+tv.tv_sec); /* Initialize GDK */ gdk_init(&argc,&argv); /* Set up our options, image list, etc */ strncpy(select_dir, SELECT_DIR, sizeof select_dir); reset_mod(&main_img); options_read(argc, argv, &main_img); /* Load things from GDK/Imlib */ qiv_main_loop = g_main_new(TRUE); cmap = gdk_colormap_get_system(); screen_x = gdk_screen_width(); screen_y = gdk_screen_height(); /* statusbar with pango */ layout = pango_layout_new(gdk_pango_context_get()); fontdesc = pango_font_description_from_string (STATUSBAR_FONT); /* set fontsize to 8 if no fontsize is given */ if(!pango_font_description_get_size(fontdesc)) { pango_font_description_set_size(fontdesc, PANGO_SCALE * STATUSBAR_FS); } metrics = pango_context_get_metrics (gdk_pango_context_get(), fontdesc, NULL); pango_layout_set_font_description (layout, fontdesc); /* // [as] thinks that this is not portable enough // [lc] // I use a virtual screen of 1600x1200, and the resolution is 1024x768, // so I changed how screen_[x,y] is obtained; it seems that gtk 1.2 // cannot give the geometry of viewport, so I borrowed from the source of // xvidtune the code for calling XF86VidModeGetModeLine, this requires // the linking option -lXxf86vm. XF86VidModeGetModeLine(GDK_DISPLAY(), DefaultScreen(GDK_DISPLAY()), &dot_clock, &modeline); //printf("> hdisplay %d vdisplay %d\n", modeline.hdisplay, modeline.vdisplay); screen_x=MIN(screen_x, modeline.hdisplay); screen_y=MIN(screen_y, modeline.vdisplay); */ #ifdef GTD_XINERAMA get_preferred_xinerama_screens(); // screen_x=MIN(screen_x, preferred_screen->width); // screen_y=MIN(screen_y, preferred_screen->height); #endif max_rand_num = images; if (filter) /* Filter graphic images */ filter_images(&images,image_names); if (!images) { /* No images to display */ g_print("qiv: cannot load any images.\n"); usage(argv[0],1); } /* get colors */ color_alloc(STATUSBAR_BG, &text_bg); color_alloc(ERROR_BG, &error_bg); color_alloc(image_bg_spec, &image_bg); /* Display first image first, except in random mode */ if (random_order) next_image(0); //disabled because 'params' is never used, see above //if (to_root || to_root_t || to_root_s) { // params.flags |= PARAMS_VISUALID; // (GdkVisual*)params.visualid = gdk_window_get_visual(GDK_ROOT_PARENT()); //} /* Setup callbacks */ gdk_event_handler_set(qiv_handle_event, &main_img, NULL); qiv_timer_restart(NULL); /* And signal catchers */ signal(SIGTERM, finish); signal(SIGINT, finish); signal(SIGUSR1, qiv_signal_usr1); signal(SIGUSR2, qiv_signal_usr2); /* Load & display the first image */ qiv_load_image(&main_img); if(watch_file){ g_idle_add (qiv_watch_file, &main_img); } g_main_run(qiv_main_loop); /* will never return */ return 0; } void qiv_exit(int code) { if (cmap) gdk_colormap_unref(cmap); destroy_image(&main_img); pango_font_description_free (fontdesc); g_object_unref (layout); pango_font_metrics_unref(metrics); g_main_destroy(qiv_main_loop); finish(SIGTERM); /* deprecated, subject to change */ } /* * functions for handling signals */ static void qiv_signal_usr1() { next_image(1); qiv_load_image(&main_img); } static void qiv_signal_usr2() { next_image(-1); qiv_load_image(&main_img); } /* * Slideshow timer function * * If this function returns false, the timer is destroyed * and qiv_timer_restart() is automatically called, which * then starts the timer again. Thus images which takes some * time to load will still be displayed for "delay" seconds. */ static gboolean qiv_handle_timer(gpointer data) { if (*(int *)data || slide) { next_image(0); qiv_load_image(&main_img); } return FALSE; } /* * Slideshow timer (re)start function */ static void qiv_timer_restart(gpointer dummy) { g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, delay, qiv_handle_timer, &slide, qiv_timer_restart); } /* Filter images by extension */ static void filter_images(int *images, char **image_names) { int i = 0; while(i < *images) { if (check_extension(image_names[i]) #ifdef HAVE_MAGIC || check_magic(image_names[i]) #endif ) { i++; } else { int j = i; if (j < *images-1) image_idx--; while(j < *images-1) { image_names[j] = image_names[j+1]; ++j; } --(*images); } } if (image_idx < 0) image_idx = 0; } static int check_extension(const char *name) { char *extn = strrchr(name, '.'); int i; if (extn) for (i=0; image_extensions[i]; i++) if (strcasecmp(extn, image_extensions[i]) == 0) return 1; return 0; } #ifdef HAVE_MAGIC static int check_magic(const char *name) { magic_t cookie; const char *description=NULL; int i; int ret=0; cookie = magic_open(MAGIC_NONE); magic_load(cookie,NULL); description = magic_file(cookie, name); if(description) { for(i=0; image_magic[i]; i++ ) if (strncasecmp(description, image_magic[i], strlen(image_magic[i])) == 0) { ret = 1; break; } } magic_close(cookie); return ret; } #endif qiv-2.2.4.orig/README0000644000175000017500000000760211563226774013153 0ustar bartmbartmQuick Image Viewer (qiv) by Andy Spiegl http://qiv.spiegl.de/ - qiv.andy@spiegl.de --------------------------------------------------------------------------- Original author: Adam Kopacz / KLOGRAFX.DE Network http://www.klografx.net/qiv/ - adam.k@klografx.de =========================================================================== Installation (Linux/Solaris/FreeBSD): ------------------------------------- If you are using Debian/GNU Linux (or a derivative thereof) just type: dpkg-buildpackage -uc -B -m"your@email.address" -rfakeroot Various compile-time options are in the Makefile; be sure to at least read over them before typing "make install"... :) Remove the "#" if you want to use the libXinerama for centering on dual-screen: #GTD_XINERAMA = -DGTD_XINERAMA qiv-command ----------- Rename "qiv-command.example" to "qiv-command" and copy it in your path if you want to launch other programs within qiv. This is very nice for stuff like "metacam", "jhead", "exiftool" etc. to show the EXIF-infos of digital photos. If you get errors like this: "/bin/sh: pkg-config: command not found" then your Imlib is too old.. this means you don't have the program pkg-config. You should install pkg-config or replace the `pkg-config` calls in the Makefile: `pkg-config --cflags gdk-2.0 imlib2` --> -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/pango-1.0 \ -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/cairo \ -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 `pkg-config --libs gdk-2.0 imlib2` --> -lgdk-x11-2.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lgio-2.0 -lpango-1.0 \ -lcairo -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lImlib2 Solaris Users: please try "Makefile.Solaris" instead of "Makefile" if the default Makefile doesn't work for you. Other OSes: ---------- Try the Linux/Solaris/FreeBSD stuff... it would be nice if you could drop me some lines if qiv works also on other systems (HP-UX?) ... Authors: -------- Adam Kopacz Andy Spiegl ...and many more (see Changelog and/or Homepage) Homepage: --------- http://qiv.spiegl.de/ Homepage of original author: ---------------------------- http://www.klografx.net/qiv/ Misc: ----- Thanx to all programers, Owen Taylor and Rasterman (@REDHAT) for helping with patches and their knowledge :-) type "man qiv" for more information. See the Makefile if you have problems compiling. qiv is designed to work with ANY gtk/gdk, it also should work with ANY version of Imlib of Linux (Intel/Mac), Solaris (SunOS) and FreeBSD. As of version 2.2 imlib2 and gdk-2.0 are required, as imlib1 and gtk-1.2 are basically obsolete. To use autorotation based on exif information gdk >= 2.12 is required. Up to release 1.3 of imlib2 there is a problem with the includes. Imlib2.h does not load Xlib.h. Workaround: to add the following (as very first line) to qiv.h: #include Centering: ---------- As of version 1.7, qiv centers images by applying the correct window position and setting the window gravity to Static, so that window managers don't move the window when adding borders. If you come across a window manager that does mess up our centering, or has other problems with qiv, email Decklin (decklin@red-bean.com) and he'll quickly send off a patch to whoever maintains that WM. ;-) Thumbnails: ----------- we don't plan on adding a thumbnail function. sorry, but qiv is a QUICK image VIEWER and nothing more. if you want more features (with Imlib) then try Electric Eyes or gqview or feh ... Links: ------ ImLib2 : http://freshmeat.net/projects/imlib2/ gtk/gdk : http://www.gtk.org/ qiv-orig : http://www.klografx.net/qiv/ qiv : http://qiv.spiegl.de/ Contact: -------- Mail bug, reports and comments to Andy Spiegl qiv-2.2.4.orig/README.TODO0000644000175000017500000000427711563226774013724 0ustar bartmbartm- wishlist for the XINERAMA support: (like feh does it) + fullscreen mode: unused screens shouldn't go black see patch by Tim Connors (mercurial branch "fullscreen-window") + ungrab mouse and keyboard in unused screens - magnifying glass: [lc] + if the image is smaller than the magnifying window then it is stretched - would (black) borders be better? + doesn't work in fullscreen mode + the key sequence ' cp qiv-command.example /usr/local/bin/qiv-command\n\n" # the end... ;-) qiv-2.2.4.orig/intro.jpg0000644000175000017500000005065311563226774014134 0ustar bartmbartmJFIFCreated with The GIMPC   (1#%(:3=<9387@H\N@DWE78PmQW_bghg>Mqypdx\egcC//cB8Bcccccccccccccccccccccccccccccccccccccccccccccccccc<"S !1AQSa"2eq45Us#3BR$brCcDt%&6d0Q!12aq3AR"#B ?:9e3{qo(y]iusRMӋq\ *MM)pE3뻭8"֯"ٓOڈfOVQgwZpE3뻭^DɧC2zP>ӂ(y]j&M?jՔx"֜CW2iP̞<ϮgwZOچde}wuP> Oچde.}wuP>L~3'K(y]i<Ϯu& RgwZpE3뻭]DɧC2z"֜CWQ2iP̞.}wuP>L~3'K(y]i<Ϯu& RgwZpE3뻭]DɧC2zP>ӂ(y]j&M?jԥ<ϮgwZOچd)pE3뻭8"֮d=YK(y]i<Ϯu& RgwZpE3뻭]DɧC2zP>ӂ(y]j&M?jՔ"֜CWQ2iP̞<ϮgwZOچde.}wuP>L~3'K(y]i<Ϯu& RgwZpE3뻭]DɧC2zʪ.JEK6@P;e1RC ,kDf1`lԹ2iP̞pE3뻭a t-{is<=6 Zyo krj%t쳶mYa첈;$@Y@A.4fOV\f@5Yr<ϮM cq9ȱlH< npuTG-mML%縉18k3e;Й4fOVdA` 9k {?;ފIm2- \?{UG.*DZWSD[HD@DDD@DDBQAӕ)qG *(D(@J(O:QG< Et%y΀QD((O:QG< Et@J" """ """{Z/p. [^] ҕB蕟=Ex~{ʼE^Wt|*si" """ cvlֲ1\Ǝyv#ޫ#{@*l7"Ԧ]sJƎE q::W{U{Ϳf<ekkOܞQusnL >R0^\6Wl܇T'3U['he`kI`TL<9t6SM7I?(ICz۾նB).Sw8\k]5ݞ].=LV*+DDD@DDBB蕟=Ex~{ʼE^Wt|*si" ""*8*]m!hVdZX\p\؊v߯N nxA^I$e%PJogryԯB-l6VQͼFcةt,7iW*V5^_ Do?$N)g-,Umѻ&d=cznN2FDoi:*Xr7a$e8qR0jwdĤ8xj푠2*Zs:Zo\{u9DEDDD@DDyT2xJ|>H3V%5#QU8TN:g+C+<*Cĺ×cNl !&fֽnw.Ty36қ+ks |{6ɿNH3CMLjttEohSNХsóҏ mWɮ`ȲPZ\0wJ}R=;g*=_unUt\ AڷAUͶϽh r~kvڡd2^]5D.Up T.cyL?Al_:ceڒVuzv ӿTa7Kl#}}?uwAy? Kľ&F35xnٗ1 nV-Gw>m[6-}3W?N ^UIb;qSX)7[zݽks`9VHA*0 /@]Z@]{a_EY2wd"" """ @r=Dhz/?>f[Ǖ \?{UG.*DZWSD[HD@DDD@B'Wa@k&?*Ӱn"O+_*A=va3(= UŚ'nMA=-24!fm)HM/,V]Q3qh aȱYUS6aۜ ,˸QY+5n /ƮGr6˟[2:猗UsR3ޅ| TgŸ}NC?^5y<Ӽb߱!B z^C+XSC*KWpFAW>U Gx6apH߿Rnծ>v޹1ْoJ!x^7y#r.'K<œ0E<$nUy|d0à]jnG,D\QmYO"0I @xrݤD?ֱq7 /ɈVEu`;TH[{ή QDDD@DD T 9 ϞV|w3-ʎ.*y]ث"-" """ ˼(;cZ x[_Ue&/ѽpc!g:(J$fáVYnR%7\q,> 1w|8nR]ĺ(pkpGڃof-1d~PMiWC~WI-XVC~m oeXnNjȼ$*[=7hf4 qhŹ|V ;Jl r=VkmQ5S6^ڇS{qU˷K c$ Ej!jهGs_"l0x}'y=x,~] 5=νJ؞%I`/K7c`OJ0(;U%PNKq8_^Rw-WМgKkuHN%|Mi9˱9\lT@=ӱm\a!hE+q7 HsYwD@DDD@PBhz%ggG{y2<_*8/pyW.=""@""" ""J <: }뭦4ڎ Qne;{o^~UFPۗR}BMђgmB *zoƵ\ˉkYF.b*vRfN ,K ڹȫA{V.f4e%w]u y6s {[*I7U+I% R$'7,<ɶ!4.P\g;T˰!B tHE?=G޵ԟHE?;Gޮp|v'7&_̕:m뢰֤Ճ0 򮪱ڷNV;/G^W{pE#/ků1'[qT7%7- ڌ4T;2FgH1h8ji5eJ+i""" """ @r=Dhz/?>f[Ǖ \?{UG.*DZWSD[HD@DDD@ ]E J9{@䴎E~7\I n5mWZ&ݺ;*[O7Wviu:m|9YY+JU%y&:ǓRz R_PT-e[BlJÚ3jO GSݵqF?ʓXc<1:F[QӺ4ըc*V5:fH:l*Lֽ$2F, JkwgDY0DDD@DD T 9 ϞV|w3-ʎ.*y]ث"-" """ "(@9C{ Sld'we"M#XæbtQZ0U ;65I؋ENNdڊoпTksJZزklb:cw[b4o{ڈ0MƼf6+KC^c9_gst+49 ɷdn#FiQcb}^ۊmGS6gi:_Ul9mR4M3(xbH6q'@ś = ܩTL!p{}auTwܱLB9+ps LDDD@DDD@)P+>{?;މY^~|̷*:,~ʎ \?{UwGˏb;""" ""U/&3g4K]]X㫦|2MŤf-&q죧f+*++ZnYg1L&w-/G}kEvpف~UvT܏:\MD[we73Z(ޮ}}TV9R*#[BNjK^EU㪐XӐ5=\:p\eC; =f;+ $kȶx {J9bmm$l䎔$aTj):]@ƜG$撒i\.|#{WMS>`0 0<'iE؋2iʲK{l}v"݌2#NoV䣨avEkCSԺѼ:mcublU$S5PɨOЖdmdQC&gF;t s[5G i]{?;ދϙGEyQ~{ʼqUaD@DDBQB %"QB %"QB %"QB %"QB %"QB %"QB %B"Q u(ԢJ """ ""J!YJϞeyQ`E^\ 4/ݔ=|Q? DZWS@E(;~_?iSo=@}~iP@E(;~|o=N( iSo=@w(;~~iSo=@w(;~~iSo=@w(;~~iSo=@w(;~~iSo=@w(;~~iSo=@w(;~~iSo=@w(;~~iSo=@}~iP@E(;~|o=N(_?iSo=@}~iP@E(;~|o=N(_?iSo=@}~iP@E(;~.o=N(hz* 6i}m:/?>f[ǕWdM}B-7UXSSD|p=T8 ԯ(q슺עp1Uw8 Զ5}U]N>w 5}U]N>w 5}U]N>w 5}U]N>w 5}U]N>w 5Z5`XUގ,cGRWVS) :zs\m]p6 DnGG\tcyidzPj./vIK $MwvOMMfRrΊGQn @!$`<&ýeë_M؍2pFMiJ<[ 4N a{e;Zcoz5;.s}YA\ j%JE F; e驢.,|m.:ցNY&Jx0Ka,vFPHD +YWЀ͆?G}DiNf İq*`\4z2cA 67 jy%&pD^(D]mj) 2BG,ns.Zit*| _6qdl,)'_FI!͑'Yysx>jK6+\w vmV잪HʘoQsa@X|8Q6 %MA~Uh0K4[ ^@G^ijK kԕ gc%N]bU?%+浈dlcTPGvD.ZG%eb))DO(k <}OAZ19! erj&&Rڦ*0m '2R<b[Yj"!Sf1{jAЋATC;$l2ZR\gh%}$Ҳ9$eDp7 jO*'axtoeCR#LK ħ{@qcЪaX,SU;53ztGa5/qq xeH z-cUWz;H z-cUWz;H z-cUWz;H z-cUWz;H z-cUWz;H z-cUWz;H z-cUWz;H z-cUWz;H6YPP#\Dz&p Ao_*8/pyW.=""@""" """ UEe~Fl*[C3X$-Ѥ oaY+iJ=ťۮVD@DDg^'e}F2΀"""tԺv6 9Z,m,,1Ǻ7exkZy"2*T>NcnS]o gc.1,ommcD@DDD@E969XF uO!YD@Bafط>7}/ƀ̡J!YJϞeyQ`E^Tp_+>\{u9DEDDD@DDD@i&Y o¦'ƗM z x㶙v\ᵭaD!X!Zicp[w8؝ z5JqIOI[ONichٜH{[k䤩GKET븗:{;4G1Ҍ_tTu2H/p`ONlBcL$7H#Ę ln nsvHo`iP 㕵G+d G83ZCr9W[faͩ{0x| ""fj[nsmِ]qm8aTTs؊A#@cIٍtAn[;f%=de\׳y7vRt,2cMEG]C)H>PHc] vAm6.˻/p@Ǚ9l&G- K SO,6I<5.g\[UZZ죬{ʨaZq2'KDCY5lˈTY;f {mq-fYQME'GDŽG {7vZڞէ/kv;+hɻ~.NOճ'=U;T32GH`#] ĩ&Sls4JGH[mso{@r=Dhz/?>f[Ǖ1 =jBh;+_w/]6sX$nkpEUC, !~̴M[+>\{u9] Qel82Ӗa9UJx祖dZ m]4r$rR@HwzTOJttLhۀt[H#ts>60$y[yH;A&6-cNSM%em6/Slq:f=.?ü:V ݒcQV"ۛv޶KDv`9|ۥz6 6gH3J:" 1%ƽs\.TE Է8t?]w ] "[°#_һN?ݓq6uJ:Zi}Sv0e\\ZlDqG{ `?3'-8C$n֦)d:1:F]b)bE@ʗg}< ٌaVJH:Gz76Au.-ffգЀ$Q2Ag hCZm9tAs"iYOES,MZ Ii`( [mK^d/Fd~fݖbIVqBw n97y9b1lEVSGD^-i. $F gM+9^cKccvAN0̧eI©ƲK5pޗ_Rl|zZ%'m0nSyBĩ)btSE2Qvh iaEPIHa[K\kmk0tSFؚHH(q^:ƶH əٯsk\i] DL'Z{Cu=+jܝW2mI<=ټ*[ ss|C=BkXFhԐ$ ֞ 6tb_+!x4[Lۭb*édIK l;Yy^caMS#1gdw.:9ajha--vnUk*J\̥"/ӿT8BeI4|yl" !+6!WE_=\Uf6KjՁğ17eaBX;r&\>lZ:wf͹_'BikvywVjH ۅ7 k7Tv̎hm ˛Qc-;X;um L*cMF&k 9E4FH̏GEwݦC{^KsSP7E l{.-}tUp 9hi/3-gy7=ӓDTtEJꗖ ffo\|̣ˑl8]tUG9:呡*-+i /2hbcd80:FۓCC>?Lɪ1AES|y&N'8;,5[Mngm}{zIM!O;y(^fWI5$= s$n6p1c cNe ۻ\ ZZn3\q훝Fe`sI}um=<\r\"UvФQ@j;a5SUe<.4K%]EN ثMKZ>5~趱SF%1&@_H9iddsԘ!M |Oh(d@^.t h+Xh9îۃ`m!nxj;\cf]444qo*t4`K0 I$r4@s~1֦X'WcfZ@o|*FjUJC(b#`u,{yukZMkc1,mvݠ;FBXcŲ jt@s;YO3aO$,s }I7rT}tO:&i_0V䑑F${X 6 tl}DP1tpE#.;+M_j{)~Fm~ T 9 ϞV|w3-ʎ.*y]ث"-$l7#{?;މY^~|̷*:,~ʎ \?{UwGˏb;(R^*wOP@$4ܐBIJvGIx?XuI ll/6ߧqq.I+JmO-WSUs~Rb6L:JnaX`X%K#,eX [rU\c,u_(0ZC ?+ cɌlF޶L͐gh#P O8sG$E^7T&tϧN죙rxmhpMZg Ibl ͶmN؇Sm@%ݛ]mm۸ʼn$cʊO3]f)di.gyMwUs~b5fsi ?^Gz4#ia][=6Fd8ۚnUb*m1NUs~Aߥi(]QSSO,B9isevf`2q$E|j}oҟ(0ZC:xcce}C=E`]NĸXNJwc?+ϸ1z|U'e삧 Nz$>Pa^7Z{47#-1rU$ݸt7XY g`9eױb8d4)OfsCy5aelUI qwlt:ieg{)Y+g#02 ]YזUs~AzߥrcRF6HECGQUWS5>TvQ15׸7:@4!Sj;FNUs~AzߥqXUC*naq \+)ͷ9Mkb'Z;O-WU.™Pg}m3e [,ΗutU,3:XLmS}l}&7U-=D64 .^$j ?)9Jq2Idz.qs܋$EPdnYط_%Z:-WSUs~c5' Jv.˂@6[ZZHNW:\h^I방ft>悖Pq i 1a ED>^72f<]+@]s4F۸¡KVT2{[5s'{V/刓"DPa>7O-WWTڇ=E0meHdθhB`I,r:j͛ nHYt#I7c}Q9K`A!Lj(0ZCs{&GIV;#IiƋ.f~w>ڎ2up7c!sQˢIJpU~bRIm}wc}OJN7b2:Ca:w͘cTo](Aߥ>PPrߥs%^),s#p9MvrߏEXto1Ӂ&Y]0^7ⰱ%?ʎW9JpUs~s:\FڗNru ܮbaˋqtFxFn&U{ϔ-WPAAS~OYfsmw5;N k'!mmCLd|wO)L1u?(0ZC ?+kY4ӹ@ȟ!/i㰷^[]rv3vߋ]+ˆJc hxsKMߩ+/ ?+Ƕv˜G ^]D dXnl㒈J؛!pU7(FT_u?(0ZC ?+MH -N#cFH!-.Ymk4M޵9j12>'I9JESWFSB. rqXi1:c#$mͬvRΟ.Z!UyM٭mggG{+>{?;ފ|̱*:,~!R`2,-]VisIɻJ.[UIޥ?  =QԢZ[Ԝ-]O Jw?귩8Z[Ԟ:1g6Tae~D *n , 3ǘt$r-]8ZGReɌTς 09cgyIV[ k&h=u煫Tu)joRBJ?ߓ*U?mvmfnZ[ACPHx{ |-]Sޥ=~u:[9-8%KkYg֛&[Vh(jaAFFw4ԓaʲpw?귩8Z[ԲQ:CU U[ٰ<=6IU gkO,#q]~V)joR©B6!Ө1CUKW4=h9EEݲ׽yk_rޤjoRfQ~F]N(U:EY-.t/{k&ɹ{t=KvbⓡzjoRpw?귩aʃi~g. 0dn TLFn9r ç S - -]Sޥ/_]N 2z.X\٣i- #include #include #include #include #include #include #include "qiv.h" #include "xmalloc.h" #include "qiv_icon.h" static void setup_win(qiv_image *); //static void setup_magnify(qiv_image *, qiv_mgl *); // [lc] static int used_masks_before=0; static struct timeval load_before, load_after; static double load_elapsed; static GdkCursor *cursor, *visible_cursor, *invisible_cursor; Imlib_Image im_from_pixbuf_loader(char * image_name, int * has_alpha) { GError *error=NULL; GdkPixbuf *pixbuf_ori; GdkPixbuf *pixbuf; char * argbdata; guchar * pixels; guchar * pixels_ori; int i,j,k,rs; int pb_w, pb_h; Imlib_Image * im=NULL; const gchar *gdk_orientation = NULL; pixbuf_ori = gdk_pixbuf_new_from_file(image_name, &error); if (error != NULL) { /* Report error to user, and free error */ fprintf(stderr, "Unable to read file: %s\n", error->message); g_error_free (error); } else { #if GDK_PIXBUF_MINOR >= 12 if(autorotate) { gdk_orientation = gdk_pixbuf_get_option(pixbuf_ori, "orientation"); if(gdk_orientation) { #ifdef DEBUG printf("orientation %s\n", gdk_orientation); #endif pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf_ori); g_object_unref(pixbuf_ori); pixbuf_ori = pixbuf; } } #else #warning autoration needs at least gdk version 2.12 #endif *has_alpha = ( gdk_pixbuf_get_n_channels(pixbuf_ori) == 4) ? 1 : 0; pixels_ori = gdk_pixbuf_get_pixels(pixbuf_ori); /* create checkboard if image has transparency */ if(*has_alpha) { pixbuf = gdk_pixbuf_composite_color_simple(pixbuf_ori, gdk_pixbuf_get_width(pixbuf_ori), gdk_pixbuf_get_height(pixbuf_ori), GDK_INTERP_NEAREST, 255, 0x08, 0x00666666, 0x00aaaaaa); pixels = gdk_pixbuf_get_pixels(pixbuf); } else { pixbuf = pixbuf_ori; pixels = pixels_ori; } #ifdef DEBUG printf("channels %i\n", gdk_pixbuf_get_n_channels(pixbuf)); printf("rowstride %i\n", gdk_pixbuf_get_rowstride(pixbuf)); #endif pb_w = gdk_pixbuf_get_width(pixbuf); pb_h = gdk_pixbuf_get_height(pixbuf); argbdata=malloc(4 * pb_w * pb_h); /* create imlib2 compatible data */ if(*has_alpha) { for(i=0; i< pb_w*pb_h*4; i=i+4) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN argbdata[i+0]=pixels[i+2]; // B argbdata[i+1]=pixels[i+1]; // G argbdata[i+2]=pixels[i]; // R // keep old alpha values argbdata[i+3]=pixels_ori[i+3]; // Alpha #else // BIG_ENDIAN argbdata[i+3]=pixels[i+2]; // B argbdata[i+2]=pixels[i+1]; // G argbdata[i+1]=pixels[i]; // R // keep old alpha values argbdata[i+0]=pixels_ori[i+3]; // Alpha #endif } } else { rs = gdk_pixbuf_get_rowstride (pixbuf); k=0; for(i=0; i < pb_h; i++) { for(j=0; j< pb_w*3; j+=3) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN argbdata[k++]=pixels[i*rs+j+2]; // B argbdata[k++]=pixels[i*rs+j+1]; // G argbdata[k++]=pixels[i*rs+j]; // R argbdata[k++]=0; #else argbdata[k++]=0; argbdata[k++]=pixels[i*rs+j]; // R argbdata[k++]=pixels[i*rs+j+1]; // G argbdata[k++]=pixels[i*rs+j+2]; // B #endif } } } im = imlib_create_image_using_copied_data(pb_w, pb_h, (DATA32*)argbdata); free(argbdata); if(*has_alpha) { g_object_unref(pixbuf); } g_object_unref(pixbuf_ori); } return im; } /* * Load & display image */ void qiv_load_image(qiv_image *q) { struct stat statbuf; const char * image_name = image_names[ image_idx]; Imlib_Image * im=NULL; int has_alpha=0; gettimeofday(&load_before, 0); if (imlib_context_get_image()) imlib_free_image(); stat(image_name, &statbuf); current_mtime = statbuf.st_mtime; #ifdef DEBUG g_print("loading %s\n",image_name); #endif /* use gdk_pixbuf for loading im = imlib_load_image( (char*)image_name ); */ im = im_from_pixbuf_loader( (char*)image_name, &has_alpha); if (!im) { /* error */ q->error = 1; q->orig_w = 400; q->orig_h = 300; } else { /* Retrieve image properties */ imlib_context_set_image(im); if(has_alpha) { imlib_image_set_has_alpha(has_alpha); } q->error = 0; q->orig_w = imlib_image_get_width(); q->orig_h = imlib_image_get_height(); } if (rotation>0) { imlib_image_orientate(rotation); if (rotation!=2) { swap(&q->orig_w, &q->orig_h); swap(&q->win_w, &q->win_h); } } check_size(q, TRUE); if (rotation>0) { correct_image_position(q); } if (first) { setup_win(q); first = 0; } /* desktop-background -> exit */ if (to_root || to_root_t || to_root_s) { if (!im) { fprintf(stderr, "qiv: cannot load background_image\n"); qiv_exit(1); } set_desktop_image(q); qiv_exit(0); } gdk_window_set_background(q->win, im ? &image_bg : &error_bg); if (do_grab || (fullscreen && !disable_grab) ) { gdk_keyboard_grab(q->win, FALSE, CurrentTime); gdk_pointer_grab(q->win, FALSE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, CurrentTime); } gettimeofday(&load_after, 0); load_elapsed = ((load_after.tv_sec + load_after.tv_usec / 1.0e6) - (load_before.tv_sec + load_before.tv_usec / 1.0e6)); update_image(q, FULL_REDRAW); // if (magnify && !fullscreen) { // [lc] // setup_magnify(q, &magnify_img); // update_magnify(q, &magnify_img, FULL_REDRAW, 0, 0); // } } static gchar blank_cursor[1]; static void setup_imlib_for_drawable(GdkDrawable * d) { imlib_context_set_dither(1); /* dither for depths < 24bpp */ imlib_context_set_display( gdk_x11_drawable_get_xdisplay(d)); imlib_context_set_visual( gdk_x11_visual_get_xvisual(gdk_drawable_get_visual(d))); imlib_context_set_colormap( gdk_x11_colormap_get_xcolormap(gdk_drawable_get_colormap(d))); imlib_context_set_drawable( gdk_x11_drawable_get_xid(d)); } static void setup_imlib_color_modifier(qiv_color_modifier q) { if (q.gamma == DEFAULT_GAMMA && q.brightness == DEFAULT_BRIGHTNESS && q.contrast == DEFAULT_CONTRAST) { if (imlib_context_get_color_modifier()) imlib_free_color_modifier(); return; } if (imlib_context_get_color_modifier()) imlib_reset_color_modifier(); else imlib_context_set_color_modifier(imlib_create_color_modifier()); imlib_modify_color_modifier_gamma(q.gamma / 256.0); imlib_modify_color_modifier_brightness((q.brightness - 256) / 256.0); imlib_modify_color_modifier_contrast(q.contrast / 256.0); } static void setup_win(qiv_image *q) { GdkWindowAttr attr; GdkPixmap *cursor_pixmap; static GdkPixbuf *icon=NULL;; static GdkPixmap *icon_pixmap; static GdkBitmap *icon_bitmap; if (!fullscreen) { attr.window_type=GDK_WINDOW_TOPLEVEL; attr.wclass=GDK_INPUT_OUTPUT; attr.event_mask=GDK_ALL_EVENTS_MASK; attr.x = center ? q->win_x : 0; attr.y = center ? q->win_y : 0; attr.width = q->win_w; attr.height = q->win_h; q->win = gdk_window_new(NULL, &attr, GDK_WA_X|GDK_WA_Y); /* create the icon only once */ if(icon==NULL) { icon = gdk_pixbuf_new_from_inline (-1, qiv_icon, FALSE, NULL); gdk_pixbuf_render_pixmap_and_mask(icon, &icon_pixmap, &icon_bitmap, 10); } gdk_window_set_icon(q->win, NULL, icon_pixmap, icon_bitmap); if (center) { GdkGeometry geometry = { .min_width = q->win_w, .min_height = q->win_h, .max_width = q->win_w, .max_height = q->win_h, .win_gravity = GDK_GRAVITY_STATIC }; gdk_window_set_geometry_hints(q->win, &geometry, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_WIN_GRAVITY); gdk_window_move_resize(q->win, q->win_x, q->win_y, q->win_w, q->win_h); } else { GdkGeometry geometry = { .min_width = q->win_w, .min_height = q->win_h, .max_width = q->win_w, .max_height = q->win_h, }; gdk_window_set_geometry_hints(q->win, &geometry, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE); gdk_window_resize(q->win, q->win_w, q->win_h); } if (!(to_root || to_root_t || to_root_s)) gdk_window_show(q->win); } else { /* fullscreen */ attr.window_type=GDK_WINDOW_TEMP; attr.wclass=GDK_INPUT_OUTPUT; attr.event_mask=GDK_ALL_EVENTS_MASK; attr.x = attr.y = 0; attr.width=screen_x; attr.height=screen_y; q->win = gdk_window_new(NULL, &attr, GDK_WA_X|GDK_WA_Y); gdk_window_set_cursor(q->win, cursor); if (!(to_root || to_root_t || to_root_s)) gdk_window_show(q->win); } q->bg_gc = gdk_gc_new(q->win); q->text_gc = gdk_gc_new(q->win); /* black is default */ q->status_gc = gdk_gc_new(q->win); gdk_gc_set_foreground(q->bg_gc, &image_bg); gdk_gc_set_foreground(q->status_gc, &text_bg); cursor_pixmap = gdk_bitmap_create_from_data(q->win, blank_cursor, 1, 1); invisible_cursor = gdk_cursor_new_from_pixmap(cursor_pixmap, cursor_pixmap, &text_bg, &text_bg, 0, 0); cursor = visible_cursor = gdk_cursor_new(CURSOR); gdk_window_set_cursor(q->win, cursor); setup_imlib_for_drawable(GDK_DRAWABLE(q->win)); } void hide_cursor(qiv_image *q) { if (cursor != invisible_cursor) gdk_window_set_cursor(q->win, cursor = invisible_cursor); } void show_cursor(qiv_image *q) { if (cursor != visible_cursor) gdk_window_set_cursor(q->win, cursor = visible_cursor); } /* set image as background */ void set_desktop_image(qiv_image *q) { GdkWindow *root_win = gdk_get_default_root_window(); GdkVisual *gvis = gdk_drawable_get_visual(root_win); GdkPixmap *temp; gchar *buffer; gint root_w = screen_x, root_h = screen_y; gint root_x = 0, root_y = 0; Pixmap x_pixmap, x_mask; if (to_root || to_root_t) { root_w = q->win_w; root_h = q->win_h; } if (to_root) { root_x = (screen_x - root_w) / 2; root_y = (screen_y - root_h) / 2; } setup_imlib_for_drawable(GDK_DRAWABLE(root_win)); imlib_render_pixmaps_for_whole_image_at_size(&x_pixmap, &x_mask, root_w, root_h); #ifdef DEBUG if (x_mask) g_print("*** image has transparency\n"); #endif if(x_pixmap) { GdkPixmap * p = gdk_pixmap_foreign_new(x_pixmap); gdk_drawable_set_colormap(GDK_DRAWABLE(p), gdk_drawable_get_colormap(GDK_DRAWABLE(root_win))); if (to_root_t) { gdk_window_set_back_pixmap(root_win, p, FALSE); } else { GdkGC *rootGC; buffer = xcalloc(1, screen_x * screen_y * gvis->depth / 8); rootGC = gdk_gc_new(root_win); temp = gdk_pixmap_create_from_data(root_win, buffer, screen_x, screen_y, gvis->depth, &image_bg, &image_bg); gdk_drawable_set_colormap(GDK_DRAWABLE(temp), gdk_drawable_get_colormap(GDK_DRAWABLE(root_win))); gdk_draw_drawable(temp, rootGC, p, 0, 0, root_x, root_y, root_w, root_h); gdk_window_set_back_pixmap(root_win, temp, FALSE); g_object_unref(temp); g_object_unref(rootGC); free(buffer); } g_object_unref(p); imlib_free_pixmap_and_mask(x_pixmap); } gdk_window_clear(root_win); gdk_flush(); setup_imlib_for_drawable(q->win); } void zoom_in(qiv_image *q) { int zoom_percentage; int w_old, h_old; /* first compute current zoom_factor */ if (maxpect || scale_down || fixed_window_size) { zoom_percentage=myround((1.0-(q->orig_w - q->win_w)/(double)q->orig_w)*100); zoom_factor=(zoom_percentage - 100) / 10; } maxpect = scale_down = 0; zoom_factor++; w_old = q->win_w; h_old = q->win_h; q->win_w = (gint)(q->orig_w * (1 + zoom_factor * 0.1)); q->win_h = (gint)(q->orig_h * (1 + zoom_factor * 0.1)); /* adapt image position */ q->win_x -= (q->win_w - w_old) / 2; q->win_y -= (q->win_h - h_old) / 2; if (fullscreen) { if (center) center_image(q); else correct_image_position(q); } else { correct_image_position(q); } } void zoom_out(qiv_image *q) { int zoom_percentage; int w_old, h_old; /* first compute current zoom_factor */ if (maxpect || scale_down || fixed_window_size) { zoom_percentage=myround((1.0-(q->orig_w - q->win_w)/(double)q->orig_w)*100); zoom_factor=(zoom_percentage - 100) / 10; } maxpect = scale_down = 0; w_old = q->win_w; h_old = q->win_h; if(zoom_factor > -9 && q->win_w > MIN(64, q->orig_w) && q->win_h > MIN(64, q->orig_h)) { zoom_factor--; q->win_w = (gint)(q->orig_w * (1 + zoom_factor * 0.1)); q->win_h = (gint)(q->orig_h * (1 + zoom_factor * 0.1)); /* adapt image position */ q->win_x -= (q->win_w - w_old) / 2; q->win_y -= (q->win_h - h_old) / 2; if (fullscreen) { if (center) center_image(q); else correct_image_position(q); } else { correct_image_position(q); } } else { snprintf(infotext, sizeof infotext, "(Cannot zoom out anymore)"); fprintf(stderr, "qiv: cannot zoom out anymore\n"); } } void zoom_maxpect(qiv_image *q) { #ifdef GTD_XINERAMA double zx = (double)preferred_screen->width / (double)q->orig_w; double zy = (double)preferred_screen->height / (double)q->orig_h; #else double zx = (double)screen_x / (double)q->orig_w; double zy = (double)screen_y / (double)q->orig_h; #endif /* titlebar and frames ignored on purpose to use full height/width of screen */ q->win_w = (gint)(q->orig_w * MIN(zx, zy)); q->win_h = (gint)(q->orig_h * MIN(zx, zy)); center_image(q); } /* Set display settings to startup values which are used whenever a new image is loaded. */ void reload_image(qiv_image *q) { Imlib_Image *im; int has_alpha = 0; imlib_image_set_changes_on_disk(); im = im_from_pixbuf_loader(image_names[image_idx], &has_alpha); if (!im && watch_file) return; struct stat statbuf; stat(image_names[image_idx], &statbuf); current_mtime = statbuf.st_mtime; if (imlib_context_get_image()) imlib_free_image(); if (!im) { q->error = 1; q->orig_w = 400; q->orig_h = 300; } else { /* Retrieve image properties */ q->error = 0; imlib_context_set_image(im); if(has_alpha) { imlib_image_set_has_alpha(has_alpha); } q->orig_w = imlib_image_get_width(); q->orig_h = imlib_image_get_height(); } q->win_w = (gint)(q->orig_w * (1 + zoom_factor * 0.1)); q->win_h = (gint)(q->orig_h * (1 + zoom_factor * 0.1)); reset_mod(q); if (center) center_image(q); } void check_size(qiv_image *q, gint reset) { if (maxpect || (scale_down && (q->orig_w>screen_x || q->orig_h>screen_y))) { zoom_maxpect(q); } else if (reset || (scale_down && (q->win_worig_w || q->win_horig_h))) { reset_coords(q); } if (center) center_image(q); } void reset_coords(qiv_image *q) { if (fixed_window_size) { double w_o_ratio = (double)(fixed_window_size) / q->orig_w; q->win_w = fixed_window_size; q->win_h = q->orig_h * w_o_ratio; } else { if (fixed_zoom_factor) { zoom_factor = fixed_zoom_factor; /* reset zoom */ } q->win_w = (gint)(q->orig_w * (1 + zoom_factor * 0.1)); q->win_h = (gint)(q->orig_h * (1 + zoom_factor * 0.1)); } } /* Something changed the image. Redraw it. */ void update_image(qiv_image *q, int mode) { GdkPixmap * m = NULL; Pixmap x_pixmap, x_mask; double elapsed; struct timeval before, after; int i; if (q->error) { g_snprintf(q->win_title, sizeof q->win_title, "qiv: ERROR! cannot load image: %s", image_names[image_idx]); gdk_beep(); /* take this image out of the file list */ --images; for(i=image_idx;imod); if (mode == MOVED) { if (transparency && used_masks_before) { /* there should be a faster way to update the mask, but how? */ if (q->p) { imlib_free_pixmap_and_mask(GDK_PIXMAP_XID(q->p)); g_object_unref(q->p); } imlib_render_pixmaps_for_whole_image_at_size(&x_pixmap, &x_mask, q->win_w, q->win_h); q->p = gdk_pixmap_foreign_new(x_pixmap); gdk_drawable_set_colormap(GDK_DRAWABLE(q->p), gdk_drawable_get_colormap(GDK_DRAWABLE(q->win))); m = gdk_pixmap_foreign_new(x_mask); } g_snprintf(q->win_title, sizeof q->win_title, "qiv: %s (%dx%d) %d%% [%d/%d] b%d/c%d/g%d %s", image_names[image_idx], q->orig_w, q->orig_h, myround((1.0-(q->orig_w - q->win_w)/(double)q->orig_w)*100), image_idx+1, images, q->mod.brightness/8-32, q->mod.contrast/8-32, q->mod.gamma/8-32, infotext); snprintf(infotext, sizeof infotext, "(-)"); } // mode == MOVED else { if (q->p) { imlib_free_pixmap_and_mask(GDK_PIXMAP_XID(q->p)); g_object_unref(q->p); } /* calculate elapsed time while we render image */ gettimeofday(&before, 0); imlib_render_pixmaps_for_whole_image_at_size(&x_pixmap, &x_mask, q->win_w, q->win_h); gettimeofday(&after, 0); elapsed = ((after.tv_sec + after.tv_usec / 1.0e6) - (before.tv_sec + before.tv_usec / 1.0e6)); q->p = gdk_pixmap_foreign_new(x_pixmap); gdk_drawable_set_colormap(GDK_DRAWABLE(q->p), gdk_drawable_get_colormap(GDK_DRAWABLE(q->win))); m = x_mask == None ? NULL : gdk_pixmap_foreign_new(x_mask); #ifdef DEBUG if (m) g_print("*** image has transparency\n"); #endif g_snprintf(q->win_title, sizeof q->win_title, "qiv: %s (%dx%d) %1.01fs %d%% [%d/%d] b%d/c%d/g%d %s", image_names[image_idx], q->orig_w, q->orig_h, load_elapsed+elapsed, myround((1.0-(q->orig_w - q->win_w)/(double)q->orig_w)*100), image_idx+1, images, q->mod.brightness/8-32, q->mod.contrast/8-32, q->mod.gamma/8-32, infotext); snprintf(infotext, sizeof infotext, "(-)"); } } gdk_window_set_title(q->win, q->win_title); q->text_len = strlen(q->win_title); pango_layout_set_text(layout, q->win_title, -1); pango_layout_get_pixel_size (layout, &(q->text_w), &(q->text_h)); if (!fullscreen) { GdkGeometry geometry = { .min_width = q->win_w, .min_height = q->win_h, .max_width = q->win_w, .max_height = q->win_h, .win_gravity = GDK_GRAVITY_STATIC }; gdk_window_set_geometry_hints(q->win, &geometry, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE | GDK_HINT_WIN_GRAVITY); gdk_window_move_resize(q->win, q->win_x, q->win_y, q->win_w, q->win_h); if (!q->error) { gdk_window_set_back_pixmap(q->win, q->p, FALSE); /* remove or set transparency mask */ if (used_masks_before) { if (transparency) gdk_window_shape_combine_mask(q->win, m, 0, 0); else gdk_window_shape_combine_mask(q->win, 0, 0, 0); } else { if (transparency && m) { gdk_window_shape_combine_mask(q->win, m, 0, 0); used_masks_before=1; } } } gdk_window_clear(q->win); } // if (!fullscreen) else { #ifdef GTD_XINERAMA # define statusbar_x (statusbar_screen->x_org + statusbar_screen->width) # define statusbar_y (statusbar_screen->y_org + statusbar_screen->height) #else # define statusbar_x screen_x # define statusbar_y screen_y #endif if (mode == FULL_REDRAW) { gdk_window_clear(q->win); } else { if (q->win_x > q->win_ox) gdk_draw_rectangle(q->win, q->bg_gc, 1, q->win_ox, q->win_oy, q->win_x - q->win_ox, q->win_oh); if (q->win_y > q->win_oy) gdk_draw_rectangle(q->win, q->bg_gc, 1, q->win_ox, q->win_oy, q->win_ow, q->win_y - q->win_oy); if (q->win_x + q->win_w < q->win_ox + q->win_ow) gdk_draw_rectangle(q->win, q->bg_gc, 1, q->win_x + q->win_w, q->win_oy, q->win_ox + q->win_ow, q->win_oh); if (q->win_y + q->win_h < q->win_oy + q->win_oh) gdk_draw_rectangle(q->win, q->bg_gc, 1, q->win_ox, q->win_y + q->win_h, q->win_ow, q->win_oy + q->win_oh); if (q->statusbar_was_on && (!statusbar_fullscreen || q->text_ow > q->text_w || q->text_oh > q->text_h)) gdk_draw_rectangle(q->win, q->bg_gc, 1, statusbar_x-q->text_ow-9, statusbar_y-q->text_oh-9, q->text_ow+4, q->text_oh+4); } /* remove or set transparency mask */ if (used_masks_before) { if (transparency) gdk_window_shape_combine_mask(q->win, m, q->win_x, q->win_y); else gdk_window_shape_combine_mask(q->win, 0, q->win_x, q->win_y); } else { if (transparency && m) { gdk_window_shape_combine_mask(q->win, m, q->win_x, q->win_y); used_masks_before=1; } } if (!q->error) gdk_draw_drawable(q->win, q->bg_gc, q->p, 0, 0, q->win_x, q->win_y, q->win_w, q->win_h); if (statusbar_fullscreen) { { gdk_draw_rectangle(q->win, q->bg_gc, 0, statusbar_x-q->text_w-10, statusbar_y-q->text_h-10, q->text_w+5, q->text_h+5); gdk_draw_rectangle(q->win, q->status_gc, 1, statusbar_x-q->text_w-9, statusbar_y-q->text_h-9, q->text_w+4, q->text_h+4); gdk_draw_layout (q->win, q->text_gc, statusbar_x-q->text_w-7, statusbar_y-7-q->text_h, layout); } } q->win_ox = q->win_x; q->win_oy = q->win_y; q->win_ow = q->win_w; q->win_oh = q->win_h; q->text_ow = q->text_w; q->text_oh = q->text_h; q->statusbar_was_on = statusbar_fullscreen; } gdk_flush(); } void reset_mod(qiv_image *q) { q->mod.brightness = default_brightness; q->mod.contrast = default_contrast; q->mod.gamma = default_gamma; } void destroy_image(qiv_image *q) { if (q->p) { imlib_free_pixmap_and_mask(GDK_PIXMAP_XID(q->p)); g_object_unref(q->p); } if (q->bg_gc) g_object_unref(q->bg_gc); if (q->text_gc) g_object_unref(q->text_gc); if (q->status_gc) g_object_unref(q->status_gc); } void setup_magnify(qiv_image *q, qiv_mgl *m) { GdkWindowAttr mgl_attr; GdkGeometry mgl_hints; m->win_w=300; m->win_h=200; // gdk_flush(); gdk_window_get_root_origin(q->win, &m->frame_x, &m->frame_y); // printf("frame %d %d\n", m->frame_x, m->frame_y); mgl_attr.window_type=GDK_WINDOW_TOPLEVEL; // Set up attributes for GDK to create a Window mgl_attr.wclass=GDK_INPUT_OUTPUT; mgl_attr.event_mask=GDK_STRUCTURE_MASK; mgl_attr.width=m->win_w; mgl_attr.height=m->win_h; mgl_attr.override_redirect=TRUE; // m->win=gdk_window_new(NULL,&mgl_attr,GDK_WA_X|GDK_WA_Y|GDK_WA_WMCLASS); m->win=gdk_window_new(NULL,&mgl_attr,GDK_WA_X|GDK_WA_Y); mgl_hints.min_width=m->win_w; mgl_hints.max_width=m->win_w; mgl_hints.min_height=m->win_h; mgl_hints.max_height=m->win_h; gdk_window_set_geometry_hints(m->win, &mgl_hints, GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE); gdk_window_set_decorations(m->win, GDK_DECOR_BORDER); gdk_flush(); } void update_magnify(qiv_image *q, qiv_mgl *m, int mode, gint xcur, gint ycur) { // GdkWindowAttr mgl_attr; // GdkGeometry mgl_hints; register gint xx, yy; // win_pos_x, win_pos_y; /*********** if (mode == FULL_REDRAW) { // printf("> update_magnify: FULL_REDRAW \n"); m->im=gdk_imlib_crop_and_clone_image( q->im, 0, 0, m->win_w, m->win_h); gdk_imlib_apply_image(m->im,m->win); mgl_hints.min_width=m->win_w; mgl_hints.max_width=m->win_w; mgl_hints.min_height=m->win_h; mgl_hints.max_height=m->win_h; // gdk_window_set_hints(m->win, mgl_attr.x, mgl_attr.y,mglw, // mglw,mglh, mglh, GDK_HINT_POS | GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE); gdk_window_set_hints(m->win, xcur+50, ycur-50-m->win_h,m->win_w, m->win_w,m->win_h, m->win_h, GDK_HINT_POS | GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE); // gdk_window_move_resize(m->win,mgl_attr.x, mgl_attr.y, mglw, mglh); // gdk_window_set_geometry_hints(magnify_img.win, &mgl_hints, GDK_HINT_POS ); } ************/ if (mode == REDRAW ) { xx=xcur * q->orig_w / q->win_w; /* xx, yy are the coords of cursor */ if (xx <= m->win_w/2) /* xcur, ycur scaled to the original */ xx=0; /* image; they are changed so that */ else /* the magnified part is always */ if (xx >= q->orig_w - m->win_w/2) /* inside the image. */ xx=q->orig_w - m->win_w; else xx=xx - m->win_w/2; yy=ycur * q->orig_h / q->win_h; if (yy <= m->win_h/2) yy=0; else if (yy >= q->orig_h - m->win_h/2) yy=q->orig_h - m->win_h; else yy=yy - m->win_h/2; // printf("MGL: xcur: %d, ycur: %d, xx: %d, yy: %d\n", xcur, ycur, xx, yy); setup_imlib_for_drawable(m->win); imlib_render_image_part_on_drawable_at_size(xx, yy, m->win_w, m->win_h, 0, 0, m->win_w, m->win_h); setup_imlib_for_drawable(q->win); gdk_window_show(m->win); // xcur= m->frame_x + xcur + // (xcur < m->win_w/2? 50 : - 50 - m->win_w); // gdk_window_get_root_origin(q->win, // todo [lc] // &magnify_img.frame_x, &magnify_img.frame_y); // call not necessary xx= m->frame_x + xcur - 50 - m->win_w; yy= m->frame_y + ycur - 50 - m->win_h; if (xx < 0) { if (xcur < m->win_w - magnify_img.frame_x) xx=m->frame_x + xcur + 50; else xx=0; } if (yy < 0) { if (ycur < m->win_h - magnify_img.frame_y) yy=m->frame_y + ycur + 50; else yy=0; } // printf("MGL: m->frame_x: %d, m->frame_y: %d, xx: %d, yy: %d\n", m->frame_x, m->frame_y, xx, yy); // gdk_window_move_resize(m->win, xx, yy, m->win_w, m->win_h); gdk_window_move(m->win, xx, yy); } // gdk_window_show(m->win); gdk_flush(); } #ifdef GTD_XINERAMA void center_image(qiv_image *q) { // g_print("before: q->win_x = %d, q->win_y = %d, q->win_w = %d\n", q->win_x, q->win_y, q->win_w); XineramaScreenInfo * pscr = preferred_screen; // g_print("screen_x = %d, pscr->x_org = %d, pscr->width = %d\n", screen_x, pscr->x_org, pscr->width); /* Figure out x position */ if (q->win_w <= pscr->width) { /* If image fits on screen try to center image * within preferred (sub)screen */ q->win_x = (pscr->width - q->win_w) / 2 + pscr->x_org; /* Ensure image actually lies within screen boundaries */ if (q->win_x < 0) { q->win_x = 0; } else if (q->win_x + q->win_w > screen_x) { q->win_x = screen_x - q->win_w; } } else { /* If image wider than screen, just center it over all screens */ q->win_x = (screen_x - q->win_w) / 2; // g_print("q->win_x = %d, screen_x = %d, q->win_w = %d, pscr->width = %d\n", q->win_x, screen_x, q->win_w, pscr->width); } /* Same thing for y position */ if (q->win_h <= screen_y) { q->win_y = (pscr->height - q->win_h) / 2 + pscr->y_org; if (q->win_y < 0) { q->win_y = 0; } else if (q->win_y + q->win_h > screen_y) { q->win_y = screen_y - q->win_h; } } else { q->win_y = (screen_y - q->win_h) / 2; } // g_print("after: q->win_x = %d, q->win_y = %d, q->win_w = %d\n", q->win_x, q->win_y, q->win_w); } #else void center_image(qiv_image *q) { q->win_x = (screen_x - q->win_w) / 2; q->win_y = (screen_y - q->win_h) / 2; } #endif void correct_image_position(qiv_image *q) { // g_print("before: q->win_x = %d, q->win_y = %d, q->win_w = %d\n", q->win_x, q->win_y, q->win_w); /* try to keep inside the screen */ if (q->win_w < screen_x) { if (q->win_x < 0) q->win_x = 0; if (q->win_x + q->win_w > screen_x) q->win_x = screen_x - q->win_w; } else { if (q->win_x > 0) q->win_x = 0; if (q->win_x + q->win_w < screen_x) q->win_x = screen_x - q->win_w; } /* don't leave ugly borders */ if (q->win_h < screen_y) { if (q->win_y < 0) q->win_y = 0; if (q->win_y + q->win_h > screen_y) q->win_y = screen_y - q->win_h; } else { if (q->win_y > 0) q->win_y = 0; if (q->win_y + q->win_h < screen_y) q->win_y = screen_y - q->win_h; } // g_print("after: q->win_x = %d, q->win_y = %d, q->win_w = %d\n", q->win_x, q->win_y, q->win_w); } qiv-2.2.4.orig/options.c0000644000175000017500000003050611563226774014131 0ustar bartmbartm/* Module : options.c Purpose : Read and evaluate commandline options More : see qiv README Homepage : http://qiv.spiegl.de/ Original : http://www.klografx.net/qiv/ */ #include "qiv.h" #include #include #include #include #include #include #ifdef HAVE_GETOPT_LONG #include #else #include "lib/getopt.h" #endif #include "xmalloc.h" extern char *optarg; extern int optind, opterr, optopt; static char *short_options = "ab:c:Cd:efg:hilmno:pq:rstuvw:xyzA:BDF:GIMNPRSTW:X:"; static struct option long_options[] = { {"do_grab", 0, NULL, 'a'}, {"brightness", 1, NULL, 'b'}, {"contrast", 1, NULL, 'c'}, {"delay", 1, NULL, 'd'}, {"center", 0, NULL, 'e'}, {"fullscreen", 0, NULL, 'f'}, {"gamma", 1, NULL, 'g'}, {"help", 0, NULL, 'h'}, {"no_statusbar", 0, NULL, 'i'}, #if GDK_PIXBUF_MINOR >= 12 {"autorotate", 0, NULL, 'l'}, #endif {"maxpect", 0, NULL, 'm'}, {"no_filter", 0, NULL, 'n'}, {"bg_color", 1, NULL, 'o'}, {"transparency", 0, NULL, 'p'}, {"rotation", 1, NULL, 'q'}, {"random", 0, NULL, 'r'}, {"slide", 0, NULL, 's'}, {"scale_down", 0, NULL, 't'}, {"recursivedir", 0, NULL, 'u'}, {"version", 0, NULL, 'v'}, {"fixed_width", 1, NULL, 'w'}, {"root", 0, NULL, 'x'}, {"root_t", 0, NULL, 'y'}, {"root_s", 0, NULL, 'z'}, {"select_dir", 1, NULL, 'A'}, {"browse", 0, NULL, 'B'}, {"cycle", 0, NULL, 'C'}, {"no_sort", 0, NULL, 'D'}, {"file", 1, NULL, 'F'}, {"disable_grab", 0, NULL, 'G'}, {"statusbar", 0, NULL, 'I'}, {"merged_case_sort", 0, NULL, 'M'}, {"numeric_sort", 0, NULL, 'N'}, {"ignore_path_sort", 0, NULL, 'P'}, {"readonly", 0, NULL, 'R'}, {"shuffle", 0, NULL, 'S'}, {"watch", 0, NULL, 'T'}, {"fixed_zoom", 1, NULL, 'W'}, {"xineramascreen", 1, NULL, 'X'}, {0, 0, NULL, 0} }; static int numeric_sort = 0, merged_case_sort = 0, ignore_path_sort = 0; /* This array makes it easy to sort filenames into merged-case order * (e.g. AaBbCcDdEeFf...). */ static unsigned char casemap[256] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F, 0x40,0x41,0x43,0x45,0x47,0x49,0x4B,0x4D, /* @ABCDEFG */ 0x4F,0x51,0x53,0x55,0x57,0x59,0x5B,0x5D, /* HIJKLMNO */ 0x5F,0x61,0x63,0x65,0x67,0x69,0x6B,0x6D, /* PQRSTUVW */ 0x6F,0x71,0x73,0x75,0x76,0x77,0x78,0x79, /* XYZ[\]^_ */ 0x7A,0x42,0x44,0x46,0x48,0x4A,0x4C,0x4E, /* `abcdefg */ 0x50,0x52,0x54,0x56,0x58,0x5A,0x5C,0x5E, /* hijklmno */ 0x60,0x62,0x64,0x66,0x68,0x6A,0x6C,0x6E, /* pqrstuvw */ 0x70,0x72,0x74,0x7B,0x7C,0x7D,0x7E,0x7F, /* xyz{|}~ */ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97, 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7, 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF, 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7, 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF, 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7, 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF, 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7, 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF, 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7, 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7, 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF }; static int my_strcmp(const void *v1, const void *v2) { unsigned char *cp1 = *(unsigned char **)v1; unsigned char *cp2 = *(unsigned char **)v2; unsigned char *sufptr1, *sufptr2; int tmp; sufptr1 = cp1 + strlen((char *)cp1); while (--sufptr1 > cp1 && *sufptr1 != '.') {} sufptr2 = cp2 + strlen((char *)cp2); while (--sufptr2 > cp2 && *sufptr2 != '.') {} if (ignore_path_sort) { unsigned char *slash; if ((slash = (unsigned char *)strrchr((char *)cp1, '/')) != NULL) cp1 = slash + 1; if ((slash = (unsigned char *)strrchr((char *)cp2, '/')) != NULL) cp2 = slash + 1; } if (numeric_sort) { int namelen = 0, diff = 0; do { if (sufptr1 && (isdigit(*cp1) || isdigit(*cp2))) { unsigned char *ep1, *ep2; if (diff) return diff; for (ep1 = cp1; isdigit(*ep1); ep1++) {} if (ep1 == cp1) return 1; for (ep2 = cp2; isdigit(*ep2); ep2++) {} if (cp2 == ep2) return -1; if ((diff = (ep1 - cp1) - (ep2 - cp2)) == 0) { long val = atol((char *)cp1) - atol((char *)cp2); diff = val < 0? -1 : val > 0? 1 : 0; } if (diff && sufptr1 - cp1 <= namelen && sufptr2 - cp2 <= namelen) return diff; namelen += ep1 - cp1; cp1 = ep1; cp2 = ep2 - 1; } else { if (cp1 == sufptr1) { if (cp2 != sufptr2) return -1; sufptr1 = sufptr2 = NULL; } else if (cp2 == sufptr2) return 1; if (merged_case_sort) tmp = casemap[*cp1++] - casemap[*cp2]; else tmp = *cp1++ - *cp2; if (tmp != 0) return tmp; if (*cp2 == '/') namelen = 0; else namelen++; } } while (*cp2++ != '\0'); return diff; } do { if (cp1 == sufptr1) { if (cp2 != sufptr2) return -1; } else if (cp2 == sufptr2) return 1; if (merged_case_sort) tmp = casemap[*cp1++] - casemap[*cp2]; else tmp = *cp1++ - *cp2; if (tmp != 0) return tmp; } while (*cp2++ != '\0'); return 0; } void options_read(int argc, char **argv, qiv_image *q) { int long_index, shuffle = 0, need_sort = 1; int c, cnt; int force_statusbar=-1; /* default is don't force */ struct stat sb; while ((c = getopt_long(argc, argv, short_options, long_options, &long_index)) != -1) { switch(c) { case 'a': do_grab=1; break; case 'b': q->mod.brightness = (checked_atoi(optarg)+32)*8; if ((q->mod.brightness<0) || (q->mod.brightness>512)) usage(argv[0],1); break; case 'c': q->mod.contrast = (checked_atoi(optarg)+32)*8; if ((q->mod.contrast<0) || (q->mod.contrast>512)) usage(argv[0],1); break; case 'd': delay=(int) (atof (optarg) * 1000); if (delay < 0) { g_print("Error: %s is an invalid slide show delay.\n",optarg); exit(1); } else if (delay == 0) /* make sure we get the "quit key" */ do_grab = 1; break; case 'e': center=0; break; case 'f': fullscreen=1; break; case 'g': q->mod.gamma = (checked_atoi(optarg)+32)*8; if ((q->mod.gamma<0) || (q->mod.gamma>512)) usage(argv[0],1); break; case 'h': show_help(argv[0], 0); break; case 'i': force_statusbar=0; break; #if GDK_PIXBUF_MINOR >= 12 case 'l': autorotate=1; break; #endif case 'm': maxpect=1; break; case 'n': filter=0; break; case 'o': image_bg_spec = optarg; break; case 'p': transparency=1; break; case 'q': rotation=checked_atoi(optarg); if ((rotation<0) || (rotation>3)) usage(argv[0],1); break; case 'r': random_order=1; break; case 's': slide=1; break; case 't': scale_down=1; break; case 'u': recursive = 1; break; case 'v': g_print("qiv (Quick Image Viewer) v%s\n", VERSION); gdk_exit(0); break; case 'w': q->win_w = fixed_window_size = checked_atoi(optarg); break; case 'x': to_root=1; break; case 'y': to_root_t=1; break; case 'z': to_root_s=1; break; case 'A': snprintf(select_dir, sizeof select_dir, "%s", optarg); break; case 'B': browse=1; break; case 'C': cycle=1; break; case 'D': need_sort = 0; break; case 'F': if(rreadfile(optarg) < 0) { g_print("Error: %s could not be opened: %s.\n",optarg, strerror(errno)); gdk_exit(1); } break; case 'G': disable_grab=1; break; case 'I': force_statusbar=1; break; case 'M': merged_case_sort = 1; break; case 'N': numeric_sort = 1; break; case 'P': ignore_path_sort = 1; break; case 'R': readonly=1; break; case 'S': shuffle=1;need_sort=0; break; case 'T': watch_file=1; break; case 'W': fixed_zoom_factor = (checked_atoi(optarg) - 100) / 10; break; #ifdef GTD_XINERAMA case 'X': user_screen = checked_atoi(optarg); // g_print("set xinerama screen: %i\n", user_screen); break; #endif case 0: case '?': usage(argv[0], 1); gdk_exit(0); } } /* In case user specified -D and -P, -M, or -N */ need_sort = need_sort | ignore_path_sort | merged_case_sort | numeric_sort; /* default: show statusbar only in fullscreen mode */ /* user wants to override? */ if (force_statusbar != -1) { statusbar_window=statusbar_fullscreen = force_statusbar; } if((cnt = argc - optind) > 0) { if (!images) { max_image_cnt = 8192; image_names = (char**)xmalloc(max_image_cnt * sizeof(char*)); } while (cnt-- > 0) { if (stat(argv[optind], &sb) >= 0 && S_ISDIR(sb.st_mode)) { rreaddir(argv[optind++],recursive); } else { if (images >= max_image_cnt) { max_image_cnt += 8192; image_names = (char**)xrealloc(image_names, max_image_cnt*sizeof(char*)); } image_names[images++] = argv[optind++]; } } } if(shuffle) { char *fn; int i, p; for (i=0;i # Created: 2002-05-12 # Last change: 2010-12-28 # # more examples (renaming, jpg comments) by Clint Pachl # # needs jhead to rotate JPEG without loss of Exif Jpeg headers # jhead is: # Program for extracting Digicam setting information from Exif Jpeg headers # used by most Digital Cameras. v2.6 by Matthias Wandel, Dec 26 2006 # http://www.sentex.net/~mwandel/jhead mwandel@sentex.net # Syntax: qiv-command [pressed_key] [image_filename_with_full_path] pressed_key=$1 # key(s) pressed in qiv filename=$2 # image filename with full path echo "You pressed the $pressed_key key while watching $filename" case "$pressed_key" in 0) # do something with the image ($2) -> # # example: copy # cp "$2" "/home/myfiles/download/"; # # example: move # mv "$2" "/home/myfiles/download/"; # echo "NEWNAME=/home/myfiles/download/$2"; # # example: show EXIF Header using "exiftool" or "jhead" # exiftool "$filename" # jhead "$filename" echo -ne "0 was pushed.\nStart your own programs by editing the\n\"$0\" file!"; ;; 1|2|3|4|5) echo -ne "$pressed_key was pushed.\nStart your own programs by editing the\n\"$0\" file!"; ;; 6) # Modify comment header. Fire up an xterm running EDITOR to edit comment. #xterm -e jhead -ce $filename jhead -ce $filename ;; 7) echo -ne "$pressed_key was pushed.\nStart your own programs by editing the\n\"$0\" file!"; ;; 8) # lossless rotation of JPG, without losing EXIF tags echo 2>&1 "Rotating to the left." jhead -cmd "jpegtran -perfect -rotate 270 -outfile &o &i" $filename >/dev/null jhead -ft $filename >/dev/null # reset timestamp ;; 9) # lossless rotation of JPG, without losing EXIF tags echo 2>&1 "Rotating to the right." jhead -cmd "jpegtran -perfect -rotate 90 -outfile &o &i" $filename >/dev/null jhead -ft $filename >/dev/null # reset timestamp ;; # with "^"-prefix: forced (i.e. possibly NOT lossless) rotation ^8) # rotate JPG, but possibly losing quality echo 2>&1 "Forcing rotation to the left." jhead -cmd "jpegtran -rotate 270 -outfile &o &i" $filename >/dev/null jhead -ft $filename >/dev/null # reset timestamp ;; ^9) # rotate JPG, but possibly losing quality echo 2>&1 "Forcing rotation to the right." jhead -cmd "jpegtran -rotate 90 -outfile &o &i" $filename >/dev/null jhead -ft $filename >/dev/null # reset timestamp ;; ^*) # Rename image directly from qiv. The timestamp of the current image will be # automatically embedded in the new filename. This action is invoked by typing: # # ^ # # Echoing the `NEWNAME=new_img_name` line signals qiv to update it's file list # with the new filename. img_timestamp=$(date -r `stat -f '%m' $filename` +'%y%m%d%H%M%S') new_img_name=${pressed_key#^} new_img_name=`echo "$new_img_name" | tr ' ' '_'` new_img_name=${new_img_name%.[Jj][Pp][Gg]}-${img_timestamp}.jpg [[ -f $new_img_name ]] && exit 1 mv $filename $new_img_name echo "NEWNAME=$new_img_name" ;; V) qiv -h ;; *) cat <<-EOF Commands: 0 show EXIF header 6 edit JPEG comment 8 lossless rotate left 9 lossless rotate right ^8 non-perfect rotate left (use if '8' fails) ^9 non-perfect rotate right (use if '9' fails) ^STRING rename current file to STRING Within qiv you simply press a key from 0-9 or any other unused key! "$pressed_key" not defined yet. Quitting. EOF exit 1 esac exit 0