📄 zgv.c
字号:
if(!no_dir_prompt) { snprintf(buf,sizeof(buf),"Directory to %s to (or Esc to abort)",msg_action); dest=cm_getline(zgv_ttyfd,buf,idx_light,idx_dark,idx_black,idx_medium); if(dest==NULL || *dest==0) return; if(stat(dest,&sbuf)==-1) { /* it would be nicer to say `dir doesn't exist' or something, * but this is the only reasonably safe bet :-) */ msgbox(zgv_ttyfd,"Error - directory cannot be accessed", MSGBOXTYPE_OK,idx_light,idx_dark,idx_black); return; } if(!S_ISDIR(sbuf.st_mode)) { msgbox(zgv_ttyfd,"Error - destination is not a directory", MSGBOXTYPE_OK,idx_light,idx_dark,idx_black); return; } /* the dir might yet not be writable, but we let the copy/movefile routine * find that out. */ }if(t==0) { t=1; gifdir[curent].marked=1; fakemark=1; }if(t>1) inithowfar(msg_howfar);/* save context for possible abort */if(setjmp(setjmpbuf)) { /* if we get here, someone aborted copying/moving/deleting a file. */ if(fakemark && !fakegone) gifdir[curent].marked=0; snprintf(buf,sizeof(buf),"File %s aborted",msg_action_sav); msgbox(zgv_ttyfd,buf,MSGBOXTYPE_OK,idx_light,idx_dark,idx_black); return; }for(done=0,f=1;f<=gifdirsiz;f++) { if(gifdir[f].marked==0) continue; if(!(*func_ptr)(gifdir[f].name,dest)) { snprintf(buf,sizeof(buf),"Error %s %s",msg_acting,gifdir[f].name); msgbox(zgv_ttyfd,buf,MSGBOXTYPE_OK,idx_light,idx_dark,idx_black); if(fakemark && !fakegone) gifdir[curent].marked=0; return; } if(remove_from_array) { delete_gifdir_element(f); if(fakemark) fakegone=1; f--; } done++; /* we do this such a bonehead way to defeat the %10 business in * showhowfar - optimal it ain't. :-/ */ if(t>1) showhowfar(done*10,t*10); }if(fakemark && !fakegone) gifdir[curent].marked=0;sprintf(buf,"File%s %s OK",(t>1)?"s":"",msg_acted);msgbox(zgv_ttyfd,buf,MSGBOXTYPE_OK,idx_light,idx_dark,idx_black);}int goto_named_dir(){char *dest;dest=cm_getline(zgv_ttyfd,"Go to which directory?", idx_light,idx_dark,idx_black,idx_medium);if(dest==NULL || *dest==0) return(0);if(chdir(dest)<0) { msgbox(zgv_ttyfd,"Error changing directory", MSGBOXTYPE_OK,idx_light,idx_dark,idx_black); return(0); }return(1);}/* this could also be file not found of course */int permissiondenied(char *fname){FILE *junk;if((junk=fopen(fname,"rb"))==NULL) return(1);fclose(junk);return(0);}void redrawall(int curent,int startfrom){screenon();showgifdir(startfrom,0,1,0);showbar(curent,1,startfrom);}static int howfar_wbar,howfar_hmid;void inithowfar(char *msg){static char *last=NULL;int scrn_hmid;int f;if(!msg) msg=last;else last=msg;scrn_hmid=fs_scrnhigh/2;vga_setcolor(idx_medium);for(f=scrn_hmid-16;f<=scrn_hmid+16;f++) vga_drawline(104,f,fs_scrnwide-104,f);drawbutton(104,scrn_hmid-16,fs_scrnwide-104,scrn_hmid+16, NULL,0,idx_light,idx_dark,idx_blacknz,0);howfar_upto=0;if(msg) { vga_setcolor(idx_black); vgadrawtext((fs_scrnwide-vgatextsize(2,msg))/2,scrn_hmid-5,2,msg); }howfar_wbar=fs_scrnwide-220;howfar_hmid=scrn_hmid;}/* call with sofar==-1 to re-init progress indicator; however, * if you do, the char * originally passed to inithowfar() *must* * have pointed to a statically allocated string. */void showhowfar(int sofar,int total){int f,d;if(sofar==-1) { inithowfar(NULL); return; }if(sofar>total) sofar=total;/* test for abort and keep mouse pos up-to-date */smallhowfar(sofar,total);if(((sofar%10)==0)||(sofar==total)) { d=(howfar_wbar*sofar)/total; if(d>howfar_upto) { vga_lockvc(); if(!vga_oktowrite()) { vga_unlockvc(); return; } vga_setcolor(idx_light); /* we set this always in case of a VC switch */ for(f=howfar_upto;f<=d;f++) vga_drawline(110+f,howfar_hmid-10,110+f,howfar_hmid+10); vga_unlockvc(); howfar_upto=f; } }}/* minimal 'how far' function that just tests for an abort and stops * mouse causing problems. */void smallhowfar(int sofar,int total){if(sofar==-1) return;if(has_mouse) mouse_update(),click_update();/* we jump back to an abort message if Esc was pressed */if(!cfg.repeat_timer) if(readnbkey(zgv_ttyfd)==RK_ESC) { /* these routines blast the malloc'ed stuff, which has *for sure* * been allocated by now, because we must already be reading the file * in for us to get here! */ aborted_file_cleanup(); longjmp(setjmpbuf,1); }}void showbar(int entnum,int selected,int startfrom){static char ctmp[256+2]; /* prettyfile() buffer */int xpos,ypos;int xt;xpos=fwinxpos(entnum-startfrom+1);if((xpos<1)||(xpos+BARWIDTH>XENDPOS)) return;ypos=fwinypos(entnum-startfrom+1);prettyfile(ctmp,&(gifdir[entnum]),sizeof(ctmp));set_max_text_width(BAR_RESTRICT_WIDTH);xt=cfg.xvpic_index?centreseltxt(xpos,gdfsiz,ctmp):xpos+3;if(cfg.blockcursor) { /* block-style cursor - hopefully easier to read/see. */ if(selected) draw3dbox(xpos-2,ypos-2,xpos+BARWIDTH+1,ypos+barheight+1,4,1, idx_dark,idx_dark); else undraw3dbox(xpos-2,ypos-2,xpos+BARWIDTH+1,ypos+barheight+1,4); /* in case the last file was just marked/unmarked */ vga_setcolor(gifdir[entnum].marked?idx_marked:idx_black); vgadrawtext(xt,ypos+3+gdfofs,gdfsiz,ctmp); }else { if(selected) { draw3dbox(xpos,ypos,xpos+BARWIDTH-1,ypos+barheight-1,1,1, idx_light,idx_dark); drawtext3d(xt,ypos+3+gdfofs,gdfsiz,ctmp,0, idx_light,idx_dark, gifdir[entnum].marked?idx_marked:idx_black); /* box if cfg.xvpic_index and is an xvpic being used */ if(cfg.xvpic_index && gifdir[entnum].xvw!=0) draw3dbox(xpos+(BARWIDTH-gifdir[entnum].xvw)/2-2, ypos+GDFYBIT+39-gifdir[entnum].xvh/2-2, xpos+(BARWIDTH-gifdir[entnum].xvw)/2+gifdir[entnum].xvw+1, ypos+GDFYBIT+39-gifdir[entnum].xvh/2+gifdir[entnum].xvh+1, 1,0, idx_light,idx_dark); } else { undraw3dbox(xpos,ypos,xpos+BARWIDTH-1,ypos+barheight-1,1); undrawtext3d(xt,ypos+3+gdfofs,gdfsiz,ctmp); vga_setcolor(gifdir[entnum].marked?idx_marked:idx_black); vgadrawtext(xt,ypos+3+gdfofs,gdfsiz,ctmp); /* undraw box if cfg.xvpic_index and is an xvpic being used */ if(cfg.xvpic_index && gifdir[entnum].xvw!=0) undraw3dbox(xpos+(BARWIDTH-gifdir[entnum].xvw)/2-2, ypos+GDFYBIT+39-gifdir[entnum].xvh/2-2, xpos+(BARWIDTH-gifdir[entnum].xvw)/2+gifdir[entnum].xvw+1, ypos+GDFYBIT+39-gifdir[entnum].xvh/2+gifdir[entnum].xvh+1, 1); } }set_max_text_width(NO_CLIP_FONT);}int centreseltxt(int x,int fsiz,char *str){int a;a=vgatextsize(fsiz,str);return(x+(BARWIDTH-a)/2);}/* a de-hassled getcwd(). You need to free the memory after use, though. * (I could have used GNU's one, but I already had this from xzgv.) */char *getcwd_allocated(void){int incr=1024;int size=incr;char *buf=malloc(size);while(buf!=NULL && getcwd(buf,size-1)==NULL) { free(buf); size+=incr; buf=malloc(size); }return(buf);}void showgifdir(int startfrom,int unshow,int drawdirmsg,int do_one_only){char cdir[MAXPATHLEN+1],*ptr;static char ctmp[1024],ctmp2[1024];int f,ypos,xpos,w,h,y,xt;unsigned char *image;int xvpics_dir_exists=0;int start,end;/* draw the bulk of the scrollbar. unshow code for this is * at bottom of routine so scrollbar isn't `empty' long when moving. */if(!unshow && cfg.scrollbar && !do_one_only) draw_scrollbar_main(startfrom,gifdirsiz,XSIZ*YSIZ);*cdir=0;getcwd(cdir,MAXPATHLEN);if(drawdirmsg) { if(updating_index) { char *cptr=getcwd_allocated(); snprintf(cdir,sizeof(cdir),"updating index%s%s", cptr?" of ":"",cptr?cptr:""); if(cptr) free(cptr); } vga_setcolor(unshow?idx_medium:idx_black); set_max_text_width(DIR_OF_XSIZ); vgadrawtext(DIR_OF_XPOS,DIR_OF_YPOS,3,cdir); }/* see if either xvpics dir exists. if not, we can speed things * up a little by not bothering to look for thumbnails at all (the * difference is usually small, but on a dos partition it's sometimes * *really* painful otherwise). * * There's a little bit of duplicated code though, so it's a bit * nasty and should be cleaned up sometime (XXX). */if(strstr(cdir,"/.xvpics")!=NULL) xvpics_dir_exists=1;else { struct stat sbuf; /* must be either a dir or symlink (symlink could be to a dir...) */ if(stat(".xvpics",&sbuf)!=-1 && (S_ISDIR(sbuf.st_mode) || S_ISLNK(sbuf.st_mode))) xvpics_dir_exists=1; else { snprintf(ctmp2,sizeof(ctmp2), "%s/.xvpics/",getenv("HOME")?getenv("HOME"):""); ptr=ctmp2+strlen(ctmp2); getcwd(ptr,sizeof(ctmp2)-strlen(ctmp2)-1); /* convert /foo/bar/baz to _foo_bar_baz */ while((ptr=strchr(ptr,'/'))!=NULL) *ptr++='_'; if(stat(ctmp2,&sbuf)!=-1 && (S_ISDIR(sbuf.st_mode) || S_ISLNK(sbuf.st_mode))) xvpics_dir_exists=1; } }if(do_one_only) start=end=do_one_only;else start=startfrom,end=gifdirsiz;for(f=start;f<=end;f++) { set_max_text_width(BAR_RESTRICT_WIDTH); xpos=fwinxpos(f-startfrom+1); if(xpos+BARWIDTH>XENDPOS) break; ypos=fwinypos(f-startfrom+1); prettyfile(ctmp,&(gifdir[f]),sizeof(ctmp)); xt=cfg.xvpic_index?centreseltxt(xpos,gdfsiz,ctmp):xpos+3; vga_setcolor(unshow?idx_medium:(gifdir[f].marked?idx_marked:idx_black)); vgadrawtext(xt,ypos+3+gdfofs,gdfsiz,ctmp); if(cfg.linetext && cfg.thicktext && cfg.blockcursor) vgadrawtext(xt+1,ypos+3+gdfofs,gdfsiz,ctmp); vga_setcolor(unshow?idx_medium:idx_black); if(cfg.xvpic_index) { /* load and draw thumbnail file (or undraw it) */ if(unshow) { image=malloc(96); if(image!=NULL) { memset(image,idx_medium,96); for(y=-2;y<62;y++) vga_drawscansegment(image, xpos+(BARWIDTH-80)/2-2,ypos+y+GDFYBIT+9,96); free(image); } } else { if(xvpics_dir_exists) { /* if '/.xvpics' is in the (absolute) path somewhere, we're * in a xvpics subdir. So look for the thumbnail here! :-) */ if(strstr(cdir,"/.xvpics")!=NULL) { strncpy(ctmp,gifdir[f].name,sizeof(ctmp)-1); ctmp[sizeof(ctmp)-1]=0; } else snprintf(ctmp,sizeof(ctmp),".xvpics/%s",gifdir[f].name); /* -1 here buys space for the "/" below */ snprintf(ctmp2,sizeof(ctmp2)-1, "%s/.xvpics/",getenv("HOME")?getenv("HOME"):""); ptr=ctmp2+strlen(ctmp2); getcwd(ptr,sizeof(ctmp2)-strlen(ctmp2)-1); /* convert /foo/bar/baz to _foo_bar_baz */ while((ptr=strchr(ptr,'/'))!=NULL) *ptr++='_'; strcat(ctmp2,"/"); strncat(ctmp2,gifdir[f].name,sizeof(ctmp2)-strlen(ctmp2)-1); } gifdir[f].xvw=gifdir[f].xvh=0; if(xvpics_dir_exists && (read_xv332(ctmp,&image,&w,&h)==_PIC_OK || read_xv332(ctmp2,&image,&w,&h)==_PIC_OK)) { int xwant=xpos+(BARWIDTH-w)/2,w8=0; gifdir[f].xvw=w; gifdir[f].xvh=h; if(fs_vgamode==G640x480x16) { w8=((w+7)&~7)+8; greyfix332(&image,w,h,xwant&7,w8); xwant&=~7; } if(image!=NULL) { for(y=0;y<h;y++) vga_drawscansegment(image+y*(fs_vgamode==G640x480x16?w8:w),xwant, ypos+y+GDFYBIT+39-h/2,fs_vgamode==G640x480x16?w8:w); free(image); } } else if(gifdir[f].isdir) { /* 'folder' icon, as usual for these types of things */ vga_setcolor(unshow?idx_medium:idx_black); xt=xpos+(BARWIDTH-80)/2; ypos+=GDFYBIT+9; /* main bit */ vga_drawline(xt+10,ypos+50,xt+70,ypos+50); vga_drawline(xt+70,ypos+50,xt+70,ypos+20); vga_drawline(xt+70,ypos+20,xt+65,ypos+15); vga_drawline(xt+65,ypos+15,xt+15,ypos+15); vga_drawline(xt+15,ypos+15,xt+10,ypos+20); vga_drawline
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -