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

📄 zgv.c

📁 zgv-5.6,一个Linux系统下的图片浏览器(VGA/SVGA)
💻 C
📖 第 1 页 / 共 5 页
字号:
    FD_ZERO(&fds);    FD_SET(mouse_fd,&fds);    select(mouse_fd+1,&fds,NULL,NULL,&tv);    if(FD_ISSET(mouse_fd,&fds))      read(mouse_fd,&c,1);    }    /* set scaling of mouse x/y. Default is 16, which gives a fast-ish   * mouse on my trackball, and a slower but acceptable result with   * another mouse I tried.   */  mouse_setscale(cfg.mousescale);    /* set mouse pos to centre of screen - we only do this once */  found=0;  for(md_ptr=modedesc;md_ptr->mode;md_ptr++)    if(fs_vgamode==md_ptr->mode)      {      mouse_setposition(md_ptr->width/2,md_ptr->height/2);      found=1;      break;      }    if(!found)    {    fprintf(stderr, "zgv: "      "unknown file-sel video mode, can't correctly init mouse position\n");    mouse_setposition(320,240);		/* should at least be onscreen :-) */    /* not desperately nasty though, so carry on. */    }    /* not too nice not having scrollbar if using mouse, so force it on. */  cfg.scrollbar=1;  }}void openstdin_nonblocking(){zgv_ttyfd=fileno(stdin);fcntl(zgv_ttyfd,F_SETFL,O_NONBLOCK);}/* write PPM of image to stdout (for `-w') */void writeppm(){int c,x,y;printf("P6\n%d %d\n255\n",width,height);for(y=0;y<height;y++)  for(x=0;x<width;x++)    if(pixelsize==1)      {      /* lookup index in palette */      c=theimage[y*width+x];      putchar(image_palette[  0+c]);      putchar(image_palette[256+c]);      putchar(image_palette[512+c]);      }    else      {      /* just copy */      putchar(theimage[(y*width+x)*3+2]);      putchar(theimage[(y*width+x)*3+1]);      putchar(theimage[(y*width+x)*3  ]);      }}void load_one_file(char *filename){static hffunc hf;struct stat sbuf;/* before we load it, see if it's a directory. If so, we run zgv with * much the same result as typing '( cd whatever;zgv )'. */if(stat(filename,&sbuf)!=-1 && S_ISDIR(sbuf.st_mode))  {  chdir(filename);  return;  }if(cfg.writefile) cfg.onefile_progress=0;  openstdin_nonblocking();	/* we hadn't done this yet */one_file_only=1;if(cfg.onefile_progress)  {  screenon();  inithowfar(HOWFAR_LOADING_MSG);  hf=showhowfar;  }else   {  hf=NULL;  if(!cfg.writefile) fprintf(stderr,"Loading...");  }if(cfg.onefile_progress && hf!=NULL) vga_runinbackground(1);  if(cfg.writefile) pixelsize=3;	/* 24-bit output preferred *//* save context for possible abort (if using showhowfar) */if(setjmp(setjmpbuf))  {  /* if we get here, someone aborted loading a file. */  wait_for_foreground();  screenoff();  exit(0);  }if(readpicture(filename,hf,!cfg.writefile,0,NULL,NULL)!=_PIC_OK)  {  if(cfg.onefile_progress) screenoff();  fprintf(stderr,"\rzgv: error loading file.\n");  exit(1);  }else  {  if(hf==NULL && !cfg.writefile)    fprintf(stderr,"\r          \r");  }/* restore_mouse_pos is unimportant for a one-file situation, so we skip it. */if(cfg.writefile)  {  writeppm();  /* pointless really, but might as well... */  free(theimage);  free(image_palette);  }else  {  wait_for_foreground();  screenoff();  }exit(0);}void copyfromconfig(){curvgamode=cfg.videomode;zoom=cfg.zoom;vkludge=cfg.vkludge;brightness=cfg.brightness;contrast=cfg.contrast;picgamma=cfg.initial_picgamma;virtual=(curvgamode==G320x400x256 || curvgamode==G360x480x256);fs_vgamode=cfg.fs_startmode;/* if we don't have or don't allow the mode, use 640x480x8. */if(!vga_hasmode(fs_vgamode) || !cfg.mode_allowed[fs_vgamode])  fs_vgamode=G640x480x256;/* now make it 640x480x4 (which also locks it in that mode) * if force16fs, or if 640x480x8 and we don't have it (or don't allow it). */if(cfg.force16fs || (fs_vgamode==G640x480x256 &&   (!vga_hasmode(fs_vgamode) || !cfg.mode_allowed[fs_vgamode])))  fs_vgamode=G640x480x16;}/* make `rw-r--r--'-style permission string from mode. */char *make_perms_string(int mode){static char buf[10];int f,shift,submode;char *execptr;strcpy(buf,"---------");for(f=0,shift=6;f<3;f++,shift-=3)  {  /* first do basic `rwx' bit. */  submode=((mode>>shift)&7);  if(submode&4) buf[f*3+0]='r';  if(submode&2) buf[f*3+1]='w';  if(submode&1) buf[f*3+2]='x';    execptr=buf+f*3+2;    /* apply any setuid/setgid/sticky bits */  switch(f)    {    case 0: if(mode&04000) *execptr=((*execptr=='x')?'s':'S'); break;    case 1: if(mode&02000) *execptr=((*execptr=='x')?'s':'S'); break;    case 2: if(mode&01000) *execptr=((*execptr=='x')?'t':'T'); break;    }  }return(buf);}/* this does the stat() itself, as it may be called from vgadisp.c. * width/height are zero if we should read the thumbnail to get them. * if need_redraw_ptr is non-NULL, it gets set to 1 when a screen redraw * is needed on return (only possible when called from the viewer). */void file_details(char *filename,int w,int h,int *need_redraw_ptr){static char buf[2048];struct tm *ctime;struct stat sbuf;struct passwd *pwptr=NULL;struct group *grptr=NULL;int gotdim=1,dim_from_pic=1;if(need_redraw_ptr) *need_redraw_ptr=0;if(stat(filename,&sbuf)==-1)  return;/* this should be a can't happen, I think... */if((ctime=localtime(&sbuf.st_mtime))==NULL)  return;/* try reading dimensions from thumbnail if needed */if(!w || !h)  {  FILE *tn;  char *ptr;  dim_from_pic=0;  if((ptr=strrchr(filename,'/'))==NULL)    snprintf(buf,sizeof(buf),".xvpics/%s",filename);  else    {    buf[sizeof(buf)-1]=0;    strncpy(buf,filename,sizeof(buf)-1);    snprintf(buf+strlen(buf),sizeof(buf)-1-strlen(buf),             ".xvpics/%s",ptr+1);    }  gotdim=0;  if((tn=fopen(buf,"rb"))!=NULL)    {    fgets(buf,sizeof(buf),tn);	/* lose first line */    fgets(buf,sizeof(buf),tn);	/* this may be "#IMGINFO:123x456 <type>" */    while(buf[0]=='#')      {      if(sscanf(buf,"#IMGINFO:%dx%d",&w,&h)==2)        {        gotdim=1;        break;        }      /* otherwise try another comment line */      fgets(buf,sizeof(buf),tn);      }    fclose(tn);    }  }if(!gotdim)  w=h=0;pwptr=getpwuid(sbuf.st_uid);grptr=getgrgid(sbuf.st_gid);/* given the 7 field values, msgbox() does most of the work. */snprintf(buf,sizeof(buf),         "%s\n"         "%dk\n"         "%d-%02d-%02d  %02d:%02d\n"         "%s  (%o)\n"         "%s\n"         "%s\n"         "%c%d x %d\n",         filename,         (int)(sbuf.st_size+1023)/1024,         1900+ctime->tm_year,ctime->tm_mon+1,ctime->tm_mday,         ctime->tm_hour,ctime->tm_min,         make_perms_string(sbuf.st_mode&07777),sbuf.st_mode&07777,         pwptr?pwptr->pw_name:"unknown",         grptr?grptr->gr_name:"unknown",         dim_from_pic?'p':'t',	/* bit of a kludge :-/ */         w,h);msgbox(zgv_ttyfd,buf,MSGBOXTYPE_FILEDETAILS, idx_light,idx_dark,idx_black);if(need_redraw_ptr) *need_redraw_ptr=!msgbox_did_restore();}void file_count(void){char buf[128];int f,tagged=0,files=0;for(f=1;f<=gifdirsiz;f++)  {  if(!gifdir[f].isdir) files++;  if(gifdir[f].marked) tagged++;  }if(!files)  {  msgbox(zgv_ttyfd,"No files",MSGBOXTYPE_OK,idx_light,idx_dark,idx_black);  return;  }if(tagged)  snprintf(buf,sizeof(buf),           "%d file%s (%d tagged)",           files,files>1?"s":"",tagged);else  snprintf(buf,sizeof(buf),           "%d file%s (none tagged)",           files,files>1?"s":"");msgbox(zgv_ttyfd,buf,MSGBOXTYPE_OK,idx_light,idx_dark,idx_black);}int tagged_count(void){int f,tagged=0;for(f=1;f<=gifdirsiz;f++)  if(gifdir[f].marked) tagged++;return(tagged);}void mainloop(){int quit,key,curent; /* quit, key pressed, current entry */int oldent,startfrom,oldstart,f,markchange;int rb_menu_mode=0;int pending_mouse_viewsel=0;int tmpkey;/* blank out past-positions array */for(f=0;f<MPPOSSIZ;f++)  pastpos[f].dev=-1,pastpos[f].inode=-1;quit=0; curent=1; oldent=1;startfrom=1;readgifdir(1);showgifdir(startfrom,0,1,0);showbar(curent,1,startfrom);while(!quit)  {  oldent=curent;  markchange=0;  key=mousecur_wait_for_keys_or_mouse(zgv_ttyfd);    /* convert xzgv-ish keypresses */  if(cfg.xzgvkeys)    {    switch(key)      {      case ' ':		key=RK_ENTER; break;      case '-':		key='n'; break;      case '=':		key='t'; break;      case '-'+128:	key='N'; break;      case '='+128:	key='T'; break;      case 'N'-0x40:	key='R'; break;      case 'D'-0x40:	key=RK_DELETE; break;      case 'Q'-0x40:	key=RK_ESC; break;      case 'q':		key=RK_ESC; break;      }    }    if(rb_menu_mode)    {    /* we deal with keys ourselves... */    if(key==RK_ESC || key=='x')      {      rb_menu_mode=0;      undraw_rb_menu();      continue;      }        /* but mouse dealt with by this. if not clicked an entry, skip     * rest of loop.     */    if(rb_menu_event(&key))	/* returns non-zero if should stay in menu */      continue;        /* otherwise restore saved area of screen, and do action in (faked) key */    rb_menu_mode=0;    undraw_rb_menu();    goto parsekey;	/* skip normal mouse stuff just in case */    }    /* grok mouse movements and buttons */  if(has_mouse)    {    int mx=mouse_getx(),my=mouse_gety();    int mbuttons=mouse_getbutton();    int mleft_start=is_start_click_left();    int mleft=is_end_click_left(),mright=is_end_click_right();        if(slider_drag)      {      /* the usual way of dragging a slider is (I think) that the (in this       * case) horiz. pos. of the slider and the mouse pointer should (where       * `physically' possible) stay constant relative to each other.       * But the way zgv does it is to treat the mouse pointer's position       * on the scrollbar as a place to move the file cursor to, despite       * the relative position. This is a little odd, but I quite like it. :-)       *       * Anyway, the calculations are similar to those used by scrollbar.c       * to draw the slider, so we let that take care of it...       */      curent=scrollbar_conv_drag_to_curent(mx,gifdirsiz);      }    else	/* not dragging slider */      {      /* we're only interested in the mouse if:       * - have released right button       * - pending_mouse_viewsel is set and have released left       * - we're on the scrollbar and have pressed the left button       * - we're on the file area and have pressed left       *		(sets pending_mouse_viewsel)       * - we're on the current-directory bit and have released left       */            /* if right button released, get the right-button menu. */      if(mright)        {        rb_menu_mode=1;        pending_mouse_viewsel=0;	/* cancel any pending view */        draw_rb_menu();        /* if left mouse button is depressed now (poor thing :-))         * we should set flag to ignore first end-left-click.         */        rb_ignore_first_left_click=((mbuttons&MOUSE_LEFTBUTTON)?1:0);        continue;	/* skip rest of main loop */        }            /* this comes early (before other mleft-testing stuff)       * so we can be sure that the end click doesn't do something       * else as well.       */      if(mleft && pending_mouse_viewsel)        {        pending_mouse_viewsel=0;        key=RK_ENTER;	/* fake a key to view current */        mleft=0;	/* make sure it doesn't match stuff below :-) */        }            if(cfg.scrollbar)        {        /* check for scrollbar. This is actually a bit complicated         * button-wise due to dragging etc., so we check for mouse being         * in it first.          * my is tested first as that's more likely to fail quickly if not         * in scrollbar area.         */        if(my>=SCRLBAR_YPOS && my<SCRLBAR_YPOS+SCRLBAR_HEIGHT &&           mx>=SCRLBAR_XPOS && mx<SCRLBAR_XPOS+SCRLBAR_WIDTH)          {          int slid_xpos= scrollbar_slider_xpos();          int slid_width=scrollbar_slider_width();                    /* so we're here then. where we are determines which button           * states we care about. here's the list:           * - for arrows, end of left click (XXX this isn't ideal!)           * - for scrollbar but not slider, end of left click (ditto)           * - for scrollbar slider, start of left click puts us           *   in slider_drag mode, end of left click leaves it.           *   (end of click isn't tested here though; it's tested above by

⌨️ 快捷键说明

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