⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zgv.c

📁 zgv-5.6,一个Linux系统下的图片浏览器(VGA/SVGA)
💻 C
📖 第 1 页 / 共 5 页
字号:
/* zgv 5.5 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-2001 Russell Marks. * * zgv.c - This provides the zgv file selector, and interfaces to the *         vga display routines (vgadisp.c) * * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <stdio.h>#include <dirent.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <signal.h>#include <time.h>#include <setjmp.h>#include <pwd.h>#include <grp.h>#include <sys/param.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/vt.h>#include <errno.h>#include <vga.h>#include <vgagl.h>#include <vgamouse.h>#include "zgv.h"#include "readgif.h"#include "vgadisp.h"#include "readnbkey.h"#include "font.h"#include "3deffects.h"#include "helppage.h"#include "rc_config.h"#include "rcfile.h"#include "readpnm.h"	/* for the dithering - should be moved! */#include "resizepic.h"#include "copymove.h"#include "mousecur.h"#include "scrollbar.h"#include "rbmenu.h"#include "gnuhelp.h"#include "modesel.h"#include "magic.h"#define HOWFAR_LOADING_MSG	"Reading - please wait"/* text used when copying >=2 files */#define HOWFAR_COPYING_MSG	"Copying files - please wait"/* text used when moving >=2 files */#define HOWFAR_MOVING_MSG	"Moving files - please wait"/* and deleting >=2 */#define HOWFAR_DELETING_MSG	"Deleting files - please wait"char *zgvhelp[]=  {  " ",  "? (question mark)\\this help page",  " ",  "up (also k or q)\\move file selection cursor up",  "down (also j or a)\\move file selection cursor down",  "left (also h or o)\\move file selection cursor left",  "right (also l or p)\\move file selection cursor right",  " ",  "Enter\\display file or change directory",  " ",  "v\\visual selection mode on/off",  "u\\create/update thumbnails in visual mode",  "Ctrl-R\\update directory listing / redraw screen",  "D or Delete\\delete file",  " ",  "Esc or x\\exit zgv",  ""  };struct rbm_data_tag filesel_menu_data[]=  {  /* 31 chars max for label text */  {1, "Quit zgv",		RK_ESC		},    /* stuff in draw_rb_menu which sets the active field of these   * mode buttons assumes they are in *exactly* this order/position.   * So don't change anything before the "Tag all" button without   * thinking twice... or more. :-)   */  {0,"-",0},  {1, "640x480x8",		RK_F1		},  {1, "800x600x8",		RK_F2		},  {1, "1024x768x8",		RK_F3		},  {1, "1280x1024x8",		RK_F4		},  {0,"-",0},  {1, "Tag all",		'T'		},  {1, "Untag all",		'N'		},  {0,"-",0},  {1, "Tag",			't'		},  {1, "Untag",			'n'		},  {1, "Toggle tag",		' '		},  {0,"-",0},  {1, "Copy files",		'C'		},  {1, "Move files",		'M'		},  {1, "Delete file",		'D'		},    {1, "Slideshow",		RK_TAB		},  {1, " ...looping on/off",	'L'		},  {1, " ...shuffle on/off",	'S'		},  {0,"-",0},  {1, "Rescan dir",		'R'-0x40	},  {0,"-",0},  {1, "Show file info",		':'		},  {1, "Thumbnails on/off",	'v'		},  {1, " ...grey/colour",	'c'		},  {0,"-",0},  {1, "Thumbnail update",	'u'		},  {1, " ...for directories",	'd'		},  {0,"-",0},  {1, "Sort by name",		128+'n'		},  {1, " ...extension",		128+'e'		},  {1, " ...file size",		128+'s'		},  {1, " ...date/time",		128+'d'		},    {0,"",0}  };/* from 18-bit RGB (as used by VGA palette) to 3:3:2 palette index */#define MAKE332COL(r,g,b) (((r)>>3)*32+((g)>>3)*4+((b)>>4))/* colour indicies used for filenames-only selector */#define LIGHT		2#define DARK		1#define BLACK		15#define MIDGREY		3#define MARKEDCOL	14/* these relate to the size of each file's entry ("bar") onscreen */#define GDFYBIT			18#define BARWIDTH		126#define BAR_RESTRICT_WIDTH	BARWIDTH-4#define DIR_OF_XPOS	(100)#define DIR_OF_YPOS	(12)#define DIR_OF_XSIZ	(fs_scrnwide-DIR_OF_XPOS-10)#define COLS		(fs_scrnwide-5)#define ROWS		(fs_scrnhigh-10-yofs)#define XSIZ		(COLS/BARWIDTH)#define YSIZ		(ROWS/barheight)#define XSTARTPOS	(4+(COLS%BARWIDTH)/2)#define XENDPOS		(XSTARTPOS+COLS)#define fwinxpos(f) (XSTARTPOS+(((f)-1)/YSIZ)*BARWIDTH)#define fwinypos(f) (yofs+(ROWS%barheight)/2-cfg.scrollbar*9+ \			barheight*(((f)-1)%YSIZ))/* maximum no. of `past positions' in dirs to save. * if it runs out of space the oldest entries are lost. */#define MPPOSSIZ	256/* number of greyscales *less one* used in selector when in 640x480x16 mode */#define GREY_MAXVAL	10struct gifdir_tag  {  char name[256];  char isdir;            /* 0=file, 1=dir. */  char xvw,xvh;		/* xvpic width and height, zero if none */  char marked;  off_t size;  time_t mtime;  int extofs;  };int gifdirsiz;struct gifdir_tag *gifdir=NULL;int gifdir_byte_size=64*sizeof(struct gifdir_tag);int gifdir_byte_incr=32*sizeof(struct gifdir_tag);enum sorttypes  {  sort_name,sort_ext,sort_size,sort_mtime  };/* this has to be global so we can use it in gcompare() */enum sorttypes filesel_sorttype=sort_name;int *slideshow_idx=NULL,slideshow_idx_size;int zgv_ttyfd,howfar_upto;jmp_buf setjmpbuf;   /* in case someone aborts decompressing a file */static int xv332_how_far_xpos,xv332_how_far_ypos;static int one_file_only=0;int original_vt,separate_vt=0;int zgv_vt;int tagview_mode=0;int slider_drag=0;				/* for scrollbar/mouse *//* for right-buttom menu */static int rb_ignore_first_left_click=0;static unsigned char *rb_save=NULL;static int rb_save_width,rb_save_height;int idx_light,idx_medium,idx_dark,idx_black,idx_marked;int idx_blacknz; 	/* idx_blacknz is always black, and always non-zero */			/* (it's needed for mouse cursor and buttons) */int updating_index=0;int gdfsiz=3;		/* size of filename text in selector */int gdfofs=0;int barheight,yofs;	/* height of cursor, and offset of selection bit *//* XXX this sgres stuff is bogus in the extreme */extern int sgres;int has_mouse=0;int current_colour=0;	/* see zgv.h */struct pastpos_tag  {  int dev,inode,curent,startfrom;  } pastpos[MPPOSSIZ];/* jpeg/png error messages are written into this */char jpeg_png_errmsg[JPEG_PNG_ERRMSG_SIZE];int fs_vgamode=G640x480x256;	/* current video mode for selector */int fs_scrnwide,fs_scrnhigh;	/* width/height of selector mode *//* stuff for checking old directories (to avoid symlink loops in * recursive update). */struct olddir_tag  {  dev_t device;  ino_t inode;  };static struct olddir_tag *olddirs=NULL;static int olddir_byte_size=64*sizeof(struct olddir_tag);static int olddir_byte_incr=32*sizeof(struct olddir_tag);static int num_olddirs=0;/* prototypes */int main(int argc,char *argv[]);void write_gifdir_name(int entry,char *str);void my_mouse_init(void);void openstdin_nonblocking(void);void writeppm(void);void load_one_file(char *filename);void copyfromconfig(void);void mainloop(void);void fix_startfrom(int curent,int *startfromp);int rename_file(int curent,int startfrom);static void draw_rb_menu(void);static void undraw_rb_menu(void);static int rb_menu_event(int *keyp);void new_pastpos(int curent, int startfrom);void get_pastpos(int *curentp,int *startfromp);int load_single_file(int curent, int do_howfar);int load_tagged_files(void);void delete_gifdir_element(int n);void copymovedel_file_or_tagged_files(int curent,int remove_from_array,                                      int no_dir_prompt,                                      int (*func_ptr)(char *,char *),                                      char *msg_action,char *msg_acting,                                      char *msg_acted,char *msg_howfar);int goto_named_dir(void);int permissiondenied(char *fname);void redrawall(int curent, int startfrom);void inithowfar(char *msg);void showhowfar(int sofar, int total);void smallhowfar(int sofar, int total);void showbar(int entnum, int selected, int startfrom);int centreseltxt(int x, int fsiz, char *str);void showgifdir(int startfrom,int unshow,int drawdirmsg,int do_one_only);int ispicture(char *filename);void readgifdir(int graphics_ok);void sort_files(void);int gcompare(void *gn1, void *gn2);void prettyfile(char *buf, struct gifdir_tag *gifdptr, int bufsize);void screenon(void);void screenoff(void);void cleartext(void);void showerrmessage(int errnumber);int delete_file(char *filename,int doprompt,int report_error);int delete_file_simple(char *filename,char *junk);void xv332_how_far(int sofar, int total);void clear_xvpic(int xpos, int ypos);int makexv332(char *filename, char *xvpicfn, unsigned int howfar);int makedirxv332(char *filename, char *xvpicfn, unsigned int howfar);void update_xvpics(int do_dirs_instead);void recursive_update(void);int fixvt(void);void switchback(void);void greyfix332(unsigned char **image, int w, int h, int xw7, int w8);void wait_for_foreground(void);void ctrlc(int foo);int make_slideshow_idx_array(void);void shuffle_slideshow_idx(void);void gifdir_init(void);int gifdir_resize_if_needed(int newent);int main(int argc,char *argv[]){int argsleft;if(fixvt()==0)  {  fprintf(stderr,"zgv: not running on console and no free VTs found.\n");  exit(1);  }atexit(switchback);		/* this gets called after svgalib stuff *//* this gets called after svgalib's ^C handler, on ^C */signal(SIGINT,ctrlc);vga_disabledriverreport();    /* quieten svgalib */vga_init();/* root permissions should now have been ditched *//* check modesel.c's mode array is valid & consistent (and quit if not) */check_modedesc_array();/*  Temporary workaround for svgalib security problem  --kvajk  */{int fd=3; while(!fcntl(fd,F_SETFD,1)) fd++;}gifdir_init();		/* allocate initial memory for gifdir[] */srand(time(NULL));	/* in case we use shuffleslideshow */pixelsize=1;getconfig();				/* see rcfile.c...   */argsleft=parsecommandline(argc,argv);	/* ...for these two. */fixconfig();		/* deal with any bogus config settings */copyfromconfig();my_mouse_init();cleartext();/* do one-file-only if have one arg. *//* (does a chdir and carries on if it's a dir.) */if(argsleft==1)  load_one_file(argv[argc-1]);/* do slideshow if more than one arg *//* XXX this should be shoved into a separate routine sometime */if(argsleft>1)  {  int i, entnum;  struct stat buf;  for(i=argc-argsleft,entnum=0;i<=argc-1;i++)    if(stat(argv[i],&buf) != -1 && !S_ISDIR(buf.st_mode))      {      entnum++;      if(!gifdir_resize_if_needed(entnum))        fprintf(stderr,"zgv: out of memory\n"),exit(1);      write_gifdir_name(entnum,argv[i]);      gifdir[entnum].marked=1;      gifdir[entnum].isdir=0;      }  gifdirsiz = entnum;  one_file_only=1;  openstdin_nonblocking();  screenon();  load_tagged_files();  screenoff();  exit(0);  }/* normal zgv startup */cfg.errignore=0;	/* don't ignore errs if using this way */openstdin_nonblocking();screenon();mainloop();screenoff();if(cfg.echotagged)  {  int f;    for(f=1;f<=gifdirsiz;f++)    if(gifdir[f].marked)      printf("%s\n",gifdir[f].name);  }exit(0);}/* write str to gifdir[entry].name checking buffer size */void write_gifdir_name(int entry,char *str){strncpy(gifdir[entry].name,str,sizeof(gifdir[entry].name)-1);gifdir[entry].name[sizeof(gifdir[entry].name)-1]=0;}void my_mouse_init(){int mouse_fd=-1;if(cfg.svgalib_mouse)  {  int svgalib_type=vga_getmousetype();    has_mouse=1;  if(svgalib_type==MOUSE_NONE)    {    has_mouse=0;    fprintf(stderr,"zgv: svgalib reports no mouse configured!\n"    		   "     (possibly an error in the config file?)\n"    		   "     carrying on anyway...\n");    sleep(3);		/* bit annoying but it's an important problem! */    }  else    {    mouse_fd=mouse_init_return_fd("/dev/mouse",    				svgalib_type,MOUSE_DEFAULTSAMPLERATE);    if(mouse_fd==-1)      has_mouse=0;    }  }if(has_mouse)  {  unsigned char c;  struct timeval tv={0,50000};  fd_set fds;  struct modedesc_tag *md_ptr;  int found;    /* ditch any byte which appears in next 1/20th-sec.   * this is to workaround a problem with my `mouse' (a logitech trackball)   * which sends a bogus `N' byte on initialisation for no obvious reason.   * (This screws everything up because input is *meant* to be in packets   * of 3 bytes!)   *   * 1/20-th sec is roughly five times as long as it should take,   * so this should work unless the machine is impossibly overloaded.   */  if(cfg.mousekludge)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -