📄 fbi.c
字号:
{ int fh; if (-1 == (fh = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666))) { show_error("writing comment failed"); return; } write(fh,dest,len); write(fh,"\n",1); close(fh);}static char *my_basename(char *filename){ char *h; h = strrchr(filename,'/'); if (h) return h+1; return filename;}static char *file_desc(char *filename){ static char desc[128]; char *h; strncpy(desc,filename,sizeof(desc)-1); if (NULL != (h = strrchr(filename,'/'))) { snprintf(desc,sizeof(desc),"%.*s/%s", (int)(h - filename), filename, "description.txt"); } else { strcpy(desc,"description.txt"); } return desc;}static char *make_desc(struct ida_image_info *img, char *filename){ static char linebuffer[128]; struct ida_extra *extra; char *desc; int len; memset(linebuffer,0,sizeof(linebuffer)); strncpy(linebuffer,filename,sizeof(linebuffer)-1); if (comments) { extra = load_find_extra(img, EXTRA_COMMENT); if (extra) snprintf(linebuffer,sizeof(linebuffer),"%.*s", extra->size,extra->data); } else { desc = file_desc(filename); len = read_comment(desc, linebuffer, sizeof(linebuffer)-1); if (-1 != len) snprintf(linebuffer+len,sizeof(linebuffer)-len, " (%s)", my_basename(filename)); } return linebuffer;}static char *make_info(struct ida_image *img, float scale){ static char linebuffer[128]; snprintf(linebuffer, sizeof(linebuffer), "%s%.0f%% %dx%d %d/%d", fcurrent->tag ? "* " : "", scale*100, img->i.width, img->i.height, fcurrent->nr, fcount); return linebuffer;}static char edit_line(char *line, int max){ int len = strlen(line); int pos = len; int rc; char key[11]; fd_set set; do { fb_edit_line(line,pos); FD_SET(0, &set); rc = select(1, &set, NULL, NULL, NULL); if (switch_last != fb_switch_state) { console_switch(0); continue; } rc = read(0, key, sizeof(key)-1); if (rc < 1) { /* EOF */ return KEY_EOF; } key[rc] = 0; if (0 == strcmp(key,"\x0a")) { /* Enter */ return 0; } else if (0 == strcmp(key,"\x1b")) { /* ESC */ return KEY_ESC; } else if (0 == strcmp(key,"\x1b[C")) { /* cursor right */ if (pos < len) pos++; } else if (0 == strcmp(key,"\x1b[D")) { /* cursor left */ if (pos > 0) pos--; } else if (0 == strcmp(key,"\x1b[1~")) { /* home */ pos = 0; } else if (0 == strcmp(key,"\x1b[4~")) { /* end */ pos = len; } else if (0 == strcmp(key,"\x7f")) { /* backspace */ if (pos > 0) { memmove(line+pos-1,line+pos,len-pos+1); pos--; len--; } } else if (0 == strcmp(key,"\x1b[3~")) { /* delete */ if (pos < len) { memmove(line+pos,line+pos+1,len-pos); len--; } } else if (1 == rc && isprint(key[0]) && len < max) { /* new key */ if (pos < len) memmove(line+pos+1,line+pos,len-pos+1); line[pos] = key[0]; pos++; len++; line[len] = 0; } else if (0 /* debug */) { debug_key(key); sleep(1); } } while (1);}static void edit_desc(char *filename){ static char linebuffer[128]; char *desc; int len, rc; desc = file_desc(filename); len = read_comment(desc, linebuffer, sizeof(linebuffer)-1); if (-1 == len) { linebuffer[0] = 0; len = 0; } rc = edit_line(linebuffer, sizeof(linebuffer)-1); if (0 != rc) return; write_comment(desc,linebuffer,strlen(linebuffer));}/* ---------------------------------------------------------------------- */static void cleanup_and_exit(int code){ fb_clear_mem(); tty_restore(); fb_cleanup(); flist_print_tagged(stdout); exit(code);}intmain(int argc, char *argv[]){ int timeout = -1; int randomize = -1; int opt_index = 0; int vt = 0; int backup = 0; int preserve = 0; struct ida_image *fimg = NULL; struct ida_image *simg = NULL; struct ida_image *img = NULL; float scale = 1; float newscale = 1; int c, editable = 0, once = 0; int need_read, need_refresh; int i, arg, key; char *line, *info, *desc; char linebuffer[128]; if (NULL != (line = getenv("FRAMEBUFFER"))) fbdev = line; if (NULL != (line = getenv("FBGAMMA"))) fbgamma = atof(line); if (NULL != (line = getenv("FBFONT"))) fontname = line;#ifdef HAVE_LIBLIRC lirc = lirc_fbi_init();#endif setlocale(LC_ALL,""); for (;;) { c = getopt_long(argc, argv, "u1evahPqVbpr:t:m:d:g:s:f:l:T:", fbi_options, &opt_index); if (c == -1) break; switch (c) { case 0: /* long option, nothing to do */ break; case '1': once = 1; break; case 'a': autoup = 1; autodown = 1; break; case 'q': statusline = 0; break; case 'v': statusline = 1; break; case 'P': textreading = 1; break; case 'g': fbgamma = atof(optarg); break; case 'r': pcd_res = atoi(optarg); break; case 's': steps = atoi(optarg); break; case 't': timeout = atoi(optarg); break; case 'u': randomize = 1; break; case 'd': fbdev = optarg; break; case 'm': fbmode = optarg; break; case 'f': fontname = optarg; break; case 'e': editable = 1; break; case 'b': backup = 1; break; case 'p': preserve = 1; break; case 'l': flist_add_list(optarg); break; case 'T': vt = atoi(optarg); break; case 'V': version(); exit(0); break; default: case 'h': usage(argv[0]); exit(1); } } for (i = optind; i < argc; i++) { flist_add(argv[i]); } flist_renumber(); if (0 == fcount) { usage(argv[0]); exit(1); } if (randomize != -1) flist_randomize(); fcurrent = flist_first(); need_read = 1; need_refresh = 1; fb_text_init1(fontname); fd = fb_init(fbdev, fbmode, vt); fb_catch_exit_signals(); fb_switch_init(); signal(SIGTSTP,SIG_IGN); fb_text_init2(); switch (fb_var.bits_per_pixel) { case 8: svga_dither_palette(8, 8, 4); dither = TRUE; init_dither(8, 8, 4, 2); break; case 15: case 16: if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) linear_palette(5); if (fb_var.green.length == 5) { lut_init(15); } else { lut_init(16); } break; case 24: if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) linear_palette(8); break; case 32: if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR) linear_palette(8); lut_init(24); break; default: fprintf(stderr, "Oops: %i bit/pixel ???\n", fb_var.bits_per_pixel); exit(1); } if (fb_fix.visual == FB_VISUAL_DIRECTCOLOR || fb_var.bits_per_pixel == 8) { if (-1 == ioctl(fd,FBIOPUTCMAP,&cmap)) { perror("ioctl FBIOPUTCMAP"); exit(1); } } /* svga main loop */ tty_raw(); desc = NULL; info = NULL; for (;;) { if (need_read) { need_read = 0; need_refresh = 1; sprintf(linebuffer,"loading %s ...",fcurrent->name); status(linebuffer, NULL); free_image(fimg); free_image(simg); fimg = read_image(fcurrent->name); simg = NULL; img = NULL; scale = 1; if (fimg) { if (autoup || autodown) { scale = auto_scale(fimg); if (scale < 1 && !autodown) scale = 1; if (scale > 1 && !autoup) scale = 1; } if (scale != 1) { sprintf(linebuffer,"scaling (%.0f%%) %s ...", scale*100, fcurrent->name); status(linebuffer, NULL); simg = scale_image(fimg,scale); img = simg; } else { img = fimg; } desc = make_desc(&fimg->i,fcurrent->name); } if (!img) { sprintf(linebuffer,"%s: FAILED",fcurrent->name); show_error(linebuffer); } } if (img) { if (need_refresh) { need_refresh = 0; if (img->i.width < fb_var.xres || img->i.height < fb_var.yres) fb_clear_screen(); } info = make_info(fimg,scale); } switch (key = svga_show(img, timeout, desc, info, &arg)) { case KEY_DELETE: if (editable) { struct flist *fdel = fcurrent; if (flist_islast(fcurrent)) fcurrent = flist_prev(fcurrent); else fcurrent = flist_next(fcurrent,0,0); unlink(fdel->name); flist_del(fdel); flist_renumber(); need_read = 1; if (list_empty(&flist)) { /* deleted last one */ fb_clear_mem(); tty_restore(); fb_cleanup(); exit(0); } } else { show_error("readonly mode, sorry [start with --edit?]"); } break; case KEY_ROT_CW: case KEY_ROT_CCW: { if (editable) { sprintf(linebuffer,"rotating %s ...",fcurrent->name); status(linebuffer, NULL); jpeg_transform_inplace (fcurrent->name, (key == KEY_ROT_CW) ? JXFORM_ROT_90 : JXFORM_ROT_270, NULL, (backup ? JFLAG_FILE_BACKUP : 0) | (preserve ? JFLAG_FILE_KEEP_TIME : 0) | JFLAG_TRANSFORM_IMAGE | JFLAG_TRANSFORM_THUMBNAIL | JFLAG_UPDATE_ORIENTATION); need_read = 1; } else { show_error("readonly mode, sorry [start with --edit?]"); } break; } case KEY_TAGFILE: fcurrent->tag = !fcurrent->tag; /* fall throuth */ case KEY_SPACE: need_read = 1; fcurrent = flist_next(fcurrent,1,0); if (NULL != fcurrent) break; /* else fall */ case KEY_ESC: case KEY_Q: case KEY_EOF: cleanup_and_exit(0); break; case KEY_PGDN: need_read = 1; fcurrent = flist_next(fcurrent,0,0); break; case KEY_PGUP: need_read = 1; fcurrent = flist_prev(fcurrent); break; case KEY_TIMEOUT: need_read = 1; fcurrent = flist_next(fcurrent,once,1); if (NULL == fcurrent) { fb_clear_mem(); tty_restore(); fb_cleanup(); } /* FIXME: wrap around */ break; case KEY_PLUS: case KEY_MINUS: case KEY_ASCALE: case KEY_SCALE: if (key == KEY_PLUS) { newscale = scale * 1.6; } else if (key == KEY_MINUS) { newscale = scale / 1.6; } else if (key == KEY_ASCALE) { newscale = auto_scale(fimg); } else { newscale = arg / 100; } if (newscale < 0.1) newscale = 0.1; if (newscale > 10) newscale = 10; scale_fix_top_left(scale, newscale, img); scale = newscale; sprintf(linebuffer,"scaling (%.0f%%) %s ...", scale*100, fcurrent->name); status(linebuffer, NULL); free_image(simg); simg = scale_image(fimg,scale); img = simg; need_refresh = 1; break; case KEY_GOTO: if (arg > 0 && arg <= fcount) { need_read = 1; fcurrent = flist_goto(arg); } break; case KEY_VERBOSE: statusline = !statusline; need_refresh = 1; break; case KEY_DESC: if (!comments) { edit_desc(fcurrent->name); desc = make_desc(&fimg->i,fcurrent->name); } break; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -