diff options
| -rw-r--r-- | etc.c | 60 | ||||
| -rw-r--r-- | file.c | 6 | ||||
| -rw-r--r-- | fm.h | 5 | ||||
| -rw-r--r-- | image.c | 82 | ||||
| -rw-r--r-- | main.c | 8 | ||||
| -rw-r--r-- | mimehead.c | 48 | ||||
| -rw-r--r-- | proto.h | 2 | ||||
| -rw-r--r-- | rc.c | 15 | ||||
| -rw-r--r-- | terms.c | 33 | 
9 files changed, 169 insertions, 90 deletions
| @@ -2004,3 +2004,63 @@ void (*mySignal(int signal_number, void (*action) (int))) (int) {      return (signal(signal_number, action));  #endif  } + +static char Base64Table[] = +    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char * +base64_encode(const unsigned char *src, size_t len) +{ +    unsigned char *w, *at; +    const unsigned char *in, *endw; +    int j; +    size_t k; + +    k = len; +    if (k % 3) +      k += 3 - (k % 3); +    k = k / 3 * 4; + +    if (k + 1 < len) +	return NULL; + +    w = GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(k + 1); +    w[k] = 0; + +    at = w; +    in = src; + +    endw = src + len - 2; + +    while (in < endw) { +	j = *in++; +	j = j << 8 | *in++; +	j = j << 8 | *in++; + +	*at++ = Base64Table[(j >> 18) & 0x3f]; +	*at++ = Base64Table[(j >> 12) & 0x3f]; +	*at++ = Base64Table[(j >> 6) & 0x3f]; +	*at++ = Base64Table[j & 0x3f]; +    } + +    if (in - src - len) { +	if (in - src - len == 1) { +	    j = *in++; +	    j = j << 8; +	    j = j << 8; +	    *at++ = Base64Table[(j >> 18) & 0x3f]; +	    *at++ = Base64Table[(j >> 12) & 0x3f]; +	    *at++ = '='; +	    *at++ = '='; +	} else { +	    j = *in++; +	    j = j << 8 | *in++; +	    j = j << 8; +	    *at++ = Base64Table[(j >> 18) & 0x3f]; +	    *at++ = Base64Table[(j >> 12) & 0x3f]; +	    *at++ = Base64Table[(j >> 6) & 0x3f]; +	    *at++ = '='; +	} +    } +    return (char *)w; +} @@ -1175,7 +1175,11 @@ AuthBasicCred(struct http_auth *ha, Str uname, Str pw, ParsedURL *pu,      Str s = Strdup(uname);      Strcat_char(s, ':');      Strcat(s, pw); -    return Strnew_m_charp("Basic ", encodeB(s->ptr)->ptr, NULL); +    char *base64 = base64_encode(s->ptr, s->length); +    if (!base64) +	return Strnew_charp("Basic "); +    else +	return Strnew_m_charp("Basic ", base64, NULL);  }  #ifdef USE_DIGEST_AUTH @@ -312,6 +312,11 @@ extern int REV_LB[];  #define EOL(l) (&(l)->ptr[(l)->length])  #define IS_EOL(p,l) ((p)==&(l)->ptr[(l)->length]) +#define INLINE_IMG_NONE		0 +#define INLINE_IMG_OSC5379	1 +#define INLINE_IMG_SIXEL	2 +#define INLINE_IMG_ITERM2	3 +  /*    * Types.   */ @@ -195,8 +195,9 @@ syncImage(void)      n_terminal_image = 0;  } -void put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh, int n_terminal_image); +void put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh);  void put_image_sixel(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh, int n_terminal_image); +void put_image_iterm2(char *url, int x, int y, int w, int h);  void  drawImage() @@ -214,41 +215,48 @@ drawImage()  	i = &terminal_image[j];  	if (enable_inline_image) { -	#if 0 +	    /* +	     * So this shouldn't ever happen, but if it does then at least let's +	     * not have external programs fetch images from the Internet... +	     */ +	    if (!i->cache->touch || stat(i->cache->file,&st)) +	      return; + +	    char *url = i->cache->file; + +	    int x = i->x / pixel_per_char_i; +	    int y = i->y / pixel_per_line_i; + +	    int w = i->cache->a_width > 0 ? ( +		    (i->cache->width + i->x % pixel_per_char_i + pixel_per_char_i - 1) / +		    pixel_per_char_i) : 0; +	    int h = i->cache->a_height > 0 ? ( +		    (i->cache->height + i->y % pixel_per_line_i + pixel_per_line_i - 1) / +		    pixel_per_line_i) : 0; + +	    int sx = i->sx / pixel_per_char_i; +	    int sy = i->sy / pixel_per_line_i; + +	    int sw = (i->width + i->sx % pixel_per_char_i + pixel_per_char_i - 1) / +		      pixel_per_char_i; +	    int sh = (i->height + i->sy % pixel_per_line_i + pixel_per_line_i - 1) / +		      pixel_per_line_i; + +#if 0  	    fprintf(stderr,"file %s x %d y %d w %d h %d sx %d sy %d sw %d sh %d (ppc %d ppl %d)\n", -		((enable_inline_image == 2 || getenv("WINDOWID")) && -		 i->cache->touch) ? i->cache->file : i->cache->url, -		i->x, i->y, -		i->cache->width > 0 ? i->cache->width : 0, -		i->cache->height > 0 ? i->cache->height : 0, -		i->sx, i->sy, i->width, i->height, +		i->cache->file, +		x, y, w, h, sx, sy, sw, sh,  		pixel_per_char_i, pixel_per_line_i); -	#endif -	    (enable_inline_image == 2 ? put_image_sixel : put_image_osc5379)( -		((enable_inline_image == 2 /* sixel */ || getenv("WINDOWID")) && -		 /* XXX I don't know why but sometimes i->cache->file doesn't exist. */ -		 i->cache->touch && stat(i->cache->file,&st) == 0) ? -			/* local */ i->cache->file : /* remote */ i->cache->url, -		i->x / pixel_per_char_i, -		i->y / pixel_per_line_i, -	    #if 1 -		i->cache->a_width > 0 ? -			(i->cache->width + i->x % pixel_per_char_i + pixel_per_char_i - 1) / -				pixel_per_char_i : -	    #endif -			0, - -	    #if 1 -		i->cache->a_height > 0 ? -			(i->cache->height + i->y % pixel_per_line_i + pixel_per_line_i - 1) / -				pixel_per_line_i : -	    #endif -			0, -		i->sx / pixel_per_char_i, -		i->sy / pixel_per_line_i, -		(i->width + i->sx % pixel_per_char_i + pixel_per_char_i - 1) / pixel_per_char_i, -		(i->height + i->sy % pixel_per_line_i + pixel_per_line_i - 1) / pixel_per_line_i, -		n_terminal_image); +#endif + + +	    if (enable_inline_image == INLINE_IMG_SIXEL) { +		put_image_sixel(url, x, y, w, h, sx, sy, sw, sh, n_terminal_image); +	    } else if (enable_inline_image == INLINE_IMG_OSC5379) { +		put_image_osc5379(url, x, y, w, h, sx, sy, sw, sh); +	    } else if (enable_inline_image == INLINE_IMG_ITERM2) { +		put_image_iterm2(url, x, y, sw, sh); +	    }  	    continue ;  	} @@ -471,7 +479,9 @@ loadImage(Buffer *buf, int flag)  	     */  	    cache->pid = 0;  	} +	/*TODO make sure removing this didn't break anything  	unlink(cache->touch); +	*/  	image_cache[i] = NULL;      } @@ -544,8 +554,10 @@ loadImage(Buffer *buf, int flag)  	    setup_child(FALSE, 0, -1);  	    image_source = cache->file;  	    b = loadGeneralFile(cache->url, cache->current, NULL, 0, NULL); +	    /* TODO make sure removing this didn't break anything  	    if (!b || !b->real_type || strncasecmp(b->real_type, "image/", 6))  		unlink(cache->file); +	    */  #if defined(HAVE_SYMLINK) && defined(HAVE_LSTAT)  	    symlink(cache->file, cache->touch);  #else @@ -599,7 +611,7 @@ getImage(Image * image, ParsedURL *current, int flag)  	cache->pid = 0;  	cache->index = 0;  	cache->loaded = IMG_FLAG_UNLOADED; -	if (enable_inline_image == 1) { +	if (enable_inline_image == INLINE_IMG_OSC5379) {  	    if (image->width > 0 && image->width % pixel_per_char_i > 0)  		image->width += (pixel_per_char_i - image->width % pixel_per_char_i); @@ -123,7 +123,7 @@ static int searchKeyNum(void);  #define help() fusage(stdout, 0)  #define usage() fusage(stderr, 1) -int enable_inline_image;	/* 1 == mlterm OSC 5379, 2 == sixel */ +int enable_inline_image;  static void  fversion(FILE * f) @@ -692,10 +692,10 @@ main(int argc, char **argv, char **envp)  	    }  #endif  	    else if (!strcmp("-ri", argv[i])) { -	        enable_inline_image = 1; +	        enable_inline_image = INLINE_IMG_OSC5379;  	    }  	    else if (!strcmp("-sixel", argv[i])) { -		enable_inline_image = 2; +		enable_inline_image = INLINE_IMG_SIXEL;  	    }  	    else if (!strcmp("-num", argv[i]))  		showLineNum = TRUE; @@ -5961,7 +5961,7 @@ deleteFiles()      }      while ((f = popText(fileToDelete)) != NULL) {  	unlink(f); -	if (enable_inline_image == 2 && strcmp(f+strlen(f)-4, ".gif") == 0) { +	if (enable_inline_image == INLINE_IMG_SIXEL && strcmp(f+strlen(f)-4, ".gif") == 0) {  	    Str firstframe = Strnew_charp(f);  	    Strcat_charp(firstframe, "-1");  	    unlink(firstframe->ptr); @@ -350,51 +350,3 @@ decodeMIME0(Str orgstr)      return cnv;  } -/* encoding */ - -static char Base64Table[] = -    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - -Str -encodeB(char *a) -{ -    unsigned char d[3]; -    unsigned char c1, c2, c3, c4; -    int i, n_pad; -    Str w = Strnew(); - -    while (1) { -	if (*a == '\0') -	    break; -	n_pad = 0; -	d[1] = d[2] = 0; -	for (i = 0; i < 3; i++) { -	    d[i] = a[i]; -	    if (a[i] == '\0') { -		n_pad = 3 - i; -		break; -	    } -	} -	c1 = d[0] >> 2; -	c2 = (((d[0] << 4) | (d[1] >> 4)) & 0x3f); -	if (n_pad == 2) { -	    c3 = c4 = 64; -	} -	else if (n_pad == 1) { -	    c3 = ((d[1] << 2) & 0x3f); -	    c4 = 64; -	} -	else { -	    c3 = (((d[1] << 2) | (d[2] >> 6)) & 0x3f); -	    c4 = (d[2] & 0x3f); -	} -	Strcat_char(w, Base64Table[c1]); -	Strcat_char(w, Base64Table[c2]); -	Strcat_char(w, Base64Table[c3]); -	Strcat_char(w, Base64Table[c4]); -	if (n_pad) -	    break; -	a += 3; -    } -    return w; -} @@ -828,3 +828,5 @@ extern void dispVer(void);  void srand48(long);  long lrand48(void);  #endif + +extern char *base64_encode(const unsigned char *src, size_t len); @@ -86,6 +86,7 @@ static int OptionEncode = FALSE;  #define CMT_IMAGE_SCALE  N_("Scale of image (%)")  #define CMT_IMGDISPLAY   N_("External command to display image")  #define CMT_IMAGE_MAP_LIST N_("Use link list of image map") +#define CMT_INLINE_IMG_PROTOCOL N_("Inline image display method")  #endif  #define CMT_MULTICOL     N_("Display file names in multi-column format")  #define CMT_ALT_ENTITY   N_("Use ASCII equivalents to display entities") @@ -363,6 +364,16 @@ static struct sel_c graphic_char_str[] = {      {0, NULL, NULL}  }; +#ifdef USE_IMAGE +static struct sel_c inlineimgstr[] = { +    {N_S(INLINE_IMG_NONE), N_("external command")}, +    {N_S(INLINE_IMG_OSC5379), N_("mlterm")}, +    {N_S(INLINE_IMG_SIXEL), N_("sixel")}, +    {N_S(INLINE_IMG_ITERM2), N_("iterm2")}, +    {0, NULL, NULL} +}; +#endif				/* USE_IMAGE */ +  struct param_ptr params1[] = {      {"tabstop", P_NZINT, PI_TEXT, (void *)&Tabstop, CMT_TABSTOP, NULL},      {"indent_incr", P_NZINT, PI_TEXT, (void *)&IndentIncr, CMT_INDENT_INCR, @@ -424,6 +435,8 @@ struct param_ptr params1[] = {       CMT_EXT_IMAGE_VIEWER, NULL},      {"image_scale", P_SCALE, PI_TEXT, (void *)&image_scale, CMT_IMAGE_SCALE,       NULL}, +    {"inline_img_protocol", P_INT, PI_SEL_C, (void *)&enable_inline_image, +     CMT_INLINE_IMG_PROTOCOL, (void *)inlineimgstr},      {"imgdisplay", P_STRING, PI_TEXT, (void *)&Imgdisplay, CMT_IMGDISPLAY,       NULL},      {"image_map_list", P_INT, PI_ONOFF, (void *)&image_map_list, @@ -1223,7 +1236,7 @@ sync_with_option(void)      init_migemo();  #endif  #ifdef USE_IMAGE -    if (fmInitialized && displayImage) +    if (fmInitialized && (displayImage || enable_inline_image))  	initImage();  #else      displayImage = FALSE;	/* XXX */ @@ -469,7 +469,7 @@ writestr(char *s)  #ifdef USE_IMAGE  void -put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh, int n_terminal_image) +put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw, int sh)  {      Str buf;      char *size ; @@ -485,6 +485,37 @@ put_image_osc5379(char *url, int x, int y, int w, int h, int sx, int sy, int sw,      MOVE(Currentbuf->cursorY,Currentbuf->cursorX);  } + +void +put_image_iterm2(char *url, int x, int y, int w, int h) +{ +    Str buf, filecontent; +    const char *base64; +    FILE *fp; + +    fp = fopen(url, "r"); +    if (!fp) +	return; +    filecontent = Strfgetall(fp); + +    base64 = base64_encode(filecontent->ptr, filecontent->length); +    if (!base64) +	return; + +    MOVE(y,x); +    buf = Sprintf("\x1b]1337;" +      "File=" +      "name=%s;" +      "size=%d;" +      "width=%d;" +      "height=%d;" +      "preserveAspectRatio=0;" +      "inline=1" +      ":%s\a", url, filecontent->length, w, h, base64); +    writestr(buf->ptr); +    MOVE(Currentbuf->cursorY,Currentbuf->cursorX); +} +  static void  save_gif(const char *path, u_char *header, size_t  header_size, u_char *body, size_t body_size)  { | 
