links

lynx-like text mode web browser
git clone anongit@rnpnr.xyz:links.git
Log | Files | Refs | Feed | README | LICENSE

Commit: 59862c0b6b58946d98818a774a4c288fbe328707
Parent: 34c4622d7f8a07d251913cc524bed3e455392fe1
Author: 0x766F6964
Date:   Tue, 15 Oct 2019 22:29:11 -0600

merge relevant changes from links-2.18

Diffstat:
MChangeLog | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbfu.c | 12++++++------
Mbookmark.c | 2+-
Mcache.c | 6------
Mcharsets.c | 2+-
Mcompress.c | 16+++++++++-------
Mconnect.c | 3++-
Mdefault.c | 32+++++++++++++++++++-------------
Mdip.c | 245++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mdither.c | 260+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mhtml.c | 80+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mhtml_gr.c | 14++++++++------
Mhtml_r.c | 3++-
Mhtml_tbl.c | 10+++++-----
Mhttp.c | 8++++----
Mimg.c | 83++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mkbd.c | 343+++++++------------------------------------------------------------------------
Mlanguage.h | 1134++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mlanguage.inc | 10+++++++++-
Mlinks.1 | 10+++++-----
Mlinks.h | 56+++++++++++++++++++++++++++++---------------------------
Mlistedit.c | 14+++++++-------
Mmain.c | 5+++--
Mmenu.c | 29++++++++++++++++++++++++-----
Mobjreq.c | 24+++++++++++++++++++++---
Mos_dep.c | 110++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msched.c | 14++++++++++----
Msession.c | 87++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mstring.c | 7++++---
Msuffix.inc | 165++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mview.c | 60+++++++++++++++++++++++++++++-------------------------------
Mview_gr.c | 20++++++++++----------
Mx.c | 684+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
33 files changed, 2115 insertions(+), 1532 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,102 @@ +=== RELEASE 2.18 === + +Sat Jan 12 20:39:51 CET 2019 mikulas: + + Compile links with graphics support on OpenVMS + +Sun Nov 25 17:27:29 CET 2018 mikulas: + + Automatically enable tor mode when the socks port is 9050 + +Sun Nov 25 17:01:20 CET 2018 mikulas: + + When we are in tor mode, invert the colors on the top line and bottom + line, so that the user can immediatelly see it + +Sat Nov 17 21:54:09 CET 2018 mikulas: + + Fix an incorrect shift in write_ev_queue that could cause spurious error + if the socket for interprocess communication fills up. + This bug was introduced in Links 2.15. + +Sat Nov 17 21:27:03 CET 2018 mikulas: + + Fix 'runtime error: member access within null pointer' sanitizer warning + +Sat Nov 17 21:16:29 CET 2018 mikulas: + + Add a menu entry to save and load a clipboard + +Sun Oct 28 19:58:49 CET 2018 mikulas: + + Don't synchronize with the Xserver on every pixmap load + It improves performance on remote connections + +Thu Oct 25 01:36:35 CEST 2018 mikulas: + + Fix a bug that in the "Network options" dialog box, the value in the + field "Timeout when trying multiple addresses" incorrectly set the value + "Timeout when unrestartable". + +Mon Oct 15 21:46:23 CEST 2018 mikulas: + + Fix a possible integer overflow in decoder_memory_expand + +Fri Oct 12 22:44:38 CEST 2018 mikulas: + + Work around a bug on OpenVMS where allocations larger than 0x77fffff0 + are treated as if they had 16 bytes + +Fri Oct 12 01:19:14 CEST 2018 mikulas: + + Fix possible pointer arithmetics bugs if the operating system allocated + memory few bytes below the limit 0xffffffff or 0xffffffffffffffff + +Tue Oct 9 22:30:01 CEST 2018 mikulas: + + Add a button to never accept invalid certificate for a given server + +Tue Oct 2 01:28:44 CEST 2018 mikulas: + + Fix incorrect strings -html-t-text-color, -html-t-link-color, + -html-t-background-color, -html-t-ignore-document-color in the manual + page and help (reported by Oliver Schode <oliver.schode@online.de>) + +Tue Oct 2 00:54:24 CEST 2018 mikulas: + + Windows 7 has a bug (or feature) that corrupts the screen when using the + unaccelerated video driver - when a thread draws into window's device context + and the user simultaneously drags the window, the device context coordinates + may not be updated. Subsequent draws are done with incorrect coordinates. + + In order to work around this bug, we detect that a drawing operation + possibly raced with window moving. If it did, we allocate a new DC (the + old one is corrupted) and start a timer that asks the main thread to + redraw the whole window using the new DC. + +Sun Sep 23 22:02:09 CEST 2018 mikulas: + + Add ascii replacement of Romanian S and T with comma + Fix replacement of c with cedilla and a/i with grave accent a/o/u with + diaeresis + +Sun Sep 23 16:31:17 cet 2018 mikulas: + + Use static linking in the released binaries on OS/2 because the DLL + names may clash with other programs + +Sun Sep 23 00:07:29 cet 2018 mikulas: + + On OS/2, use AF_OS2 for interprocess communication because the loopback + network device may not be properly configured. + Fall back to 127.0.0.1 only if AF_OS2 in not installed. + +Sat Sep 22 14:18:19 CEST 2018 mikulas: + + Fixed a bug when IPv6 control connection to a ftp server fails and IPv4 + control connection succeeds, links would incorrectly try to make the + data connection using IPv6 (this bug was introduced in Links 2.15). + === RELEASE 2.17 === Fri Sep 7 00:04:41 CEST 2018 mikulas: diff --git a/bfu.c b/bfu.c @@ -1660,8 +1660,8 @@ void dialog_func(struct window *win, struct links_event *ev, int fwd) /* gid and gnum are 100 times greater than boundaries (e.g. if gid==1 boundary is 0.01) */ int check_float(struct dialog_data *dlg, struct dialog_item_data *di) { - unsigned char *end; - double d = strtod(cast_const_char di->cdata, (char **)(void *)&end); + char *end; + double d = strtod(cast_const_char di->cdata, &end); if (!*di->cdata || *end || di->cdata[strspn(cast_const_char di->cdata, "0123456789.")] || *di->cdata == (unsigned char)'.') { @@ -1682,8 +1682,8 @@ int check_float(struct dialog_data *dlg, struct dialog_item_data *di) int check_number(struct dialog_data *dlg, struct dialog_item_data *di) { - unsigned char *end; - long l = strtol(cast_const_char di->cdata, (char **)(void *)&end, 10); + char *end; + long l = strtol(cast_const_char di->cdata, &end, 10); if (!*di->cdata || *end) { msg_box(dlg->win->term, NULL, TEXT_(T_BAD_NUMBER), AL_CENTER, TEXT_(T_NUMBER_EXPECTED), MSG_BOX_END, NULL, 1, @@ -1701,8 +1701,8 @@ int check_number(struct dialog_data *dlg, struct dialog_item_data *di) int check_hex_number(struct dialog_data *dlg, struct dialog_item_data *di) { - unsigned char *end; - long l = strtol(cast_const_char di->cdata, (char **)(void *)&end, 16); + char *end; + long l = strtol(cast_const_char di->cdata, &end, 16); if (!*di->cdata || *end) { msg_box(dlg->win->term, NULL, TEXT_(T_BAD_NUMBER), AL_CENTER, TEXT_(T_NUMBER_EXPECTED), MSG_BOX_END, NULL, 1, diff --git a/bookmark.c b/bookmark.c @@ -545,7 +545,7 @@ static void load_bookmarks(struct session *ses) if (p >= end) break; s = p; - if (p + 2 <= end && (p[1] == '!' || p[1]== '?')) { + if (end - p >= 2 && (p[1] == '!' || p[1]== '?')) { p = skip_comment(p,end); continue; } diff --git a/cache.c b/cache.c @@ -192,8 +192,6 @@ void detach_cache_entry(struct cache_entry *e) #define sf(x) e->data_size += (x), cache_size += (int)(x) -int page_size = 4096; - #define C_ALIGN(x) ((((x) + sizeof(struct fragment)) | (page_size - 1)) - sizeof(struct fragment)) int add_fragment(struct cache_entry *e, off_t offset, const unsigned char *data, off_t length) @@ -541,9 +539,5 @@ ret: void init_cache(void) { - int getpg; - EINTRLOOP(getpg, sysconf(_SC_PAGESIZE)); - if (getpg > 0 && getpg < 0x10000 && !(getpg & (getpg - 1))) - page_size = getpg; register_cache_upcall(shrink_file_cache, 0, cast_uchar "file"); } diff --git a/charsets.c b/charsets.c @@ -335,7 +335,7 @@ decode: } else { i = pp + 1; if (!dopt || dopt->plain) goto put_c; - while (i < l && c[i] != ';' && c[i] != '&' && c[i] > ' ') i++; + while (i < l && !is_entity_terminator(c[i])) i++; if (!(e = get_entity_string(&c[pp + 1], i - pp - 1))) goto put_c; pp = i + (i < l && c[i] == ';'); diff --git a/compress.c b/compress.c @@ -297,20 +297,21 @@ after_inflateend: return 0; } -int get_file_by_term(struct terminal *term, struct cache_entry *ce, unsigned char **start, unsigned char **end, int *errp) +int get_file_by_term(struct terminal *term, struct cache_entry *ce, unsigned char **start, size_t *len, int *errp) { unsigned char *enc; struct fragment *fr; int e; if (errp) *errp = 0; - *start = *end = NULL; + *start = NULL; + *len = 0; if (!ce) return 1; if (ce->decompressed) { return_decompressed: *start = ce->decompressed; - *end = ce->decompressed + ce->decompressed_len; + *len = ce->decompressed_len; return 0; } enc = get_content_encoding(ce->head, ce->url, 0); @@ -344,18 +345,19 @@ uncompressed: if (fr->offset || !fr->length) return 1; *start = fr->data; - *end = fr->data + fr->length; + *len = fr->length; return 0; } -int get_file(struct object_request *o, unsigned char **start, unsigned char **end) +int get_file(struct object_request *o, unsigned char **start, size_t *len) { struct terminal *term; - *start = *end = NULL; + *start = NULL; + *len = 0; if (!o) return 1; term = find_terminal(o->term); - return get_file_by_term(term, o->ce, start, end, NULL); + return get_file_by_term(term, o->ce, start, len, NULL); } void free_decompressed_data(struct cache_entry *e) diff --git a/connect.c b/connect.c @@ -139,8 +139,9 @@ void make_connection(struct connection *c, int port, int *sock, void (*func)(str b->l.target_port = port; strcpy(b->host, cast_const_char host); c->newconn = b; - if (c->last_lookup_state.addr.n) { + if (c->last_lookup_state.addr_index < c->last_lookup_state.addr.n) { b->l.addr = c->last_lookup_state.addr; + b->l.addr_index = c->last_lookup_state.addr_index; b->l.dont_try_more_servers = 1; dns_found(c, 0); as = 0; diff --git a/default.c b/default.c @@ -186,24 +186,22 @@ static unsigned char *create_config_string(struct option *options) return s; } -#define FILE_BUF 1024 - -static unsigned char cfg_buffer[FILE_BUF]; - unsigned char *read_config_file(unsigned char *name) { int h, r; int l = 0; - unsigned char *s; + unsigned char *cfg_buffer, *s; int rs; h = c_open(name, O_RDONLY | O_NOCTTY); if (h == -1) return NULL; s = init_str(); - while ((r = hard_read(h, cfg_buffer, FILE_BUF)) > 0) { + cfg_buffer = xmalloc(page_size); + while ((r = hard_read(h, cfg_buffer, page_size)) > 0) { int i; for (i = 0; i < r; i++) if (!cfg_buffer[i]) cfg_buffer[i] = ' '; add_bytes_to_str(&s, &l, cfg_buffer, r); } + free(cfg_buffer); if (r == -1) { free(s); s = NULL; @@ -472,7 +470,7 @@ static void num_wr(struct option *o, unsigned char **s, int *l) static unsigned char *dbl_rd(struct option *o, unsigned char *c) { unsigned char *tok = get_token(&c); - unsigned char *end; + char *end; double d; if (!tok) return cast_uchar "Missing argument"; @@ -482,7 +480,7 @@ static unsigned char *dbl_rd(struct option *o, unsigned char *c) return cast_uchar "Number is too long"; } - d = strtod(cast_const_char tok, (char **)(void *)&end); + d = strtod(cast_const_char tok, &end); if (*end) { free(tok); @@ -510,7 +508,7 @@ static unsigned char *str_rd(struct option *o, unsigned char *c) { unsigned char *tok = get_token(&c); unsigned char *e = NULL; - if (!tok) return NULL; + if (!tok) tok = stracpy(cast_uchar ""); if (strlen(cast_const_char tok) + 1 > (size_t)o->max) e = cast_uchar "String too long"; else strcpy(cast_char o->ptr, cast_const_char tok); free(tok); @@ -548,8 +546,8 @@ static void cp_wr(struct option *o, unsigned char **s, int *l) static int getnum(unsigned char *s, int *n, int r1, int r2) { - unsigned char *e; - long l = strtol(cast_const_char s, (char **)(void *)&e, 10); + char *e; + long l = strtol(cast_const_char s, &e, 10); if (*e || !*s) return -1; if (l < r1 || l >= r2) return -1; *n = (int)l; @@ -1170,9 +1168,17 @@ static struct option html_options[] = { static struct option *all_options[] = { links_options, html_options, NULL, }; -unsigned char *parse_options(int argc, unsigned char *argv[]) +unsigned char *parse_options(int argc, char *argv[]) { - return p_arse_options(argc, argv, all_options); + int i; + unsigned char **u_argv, *ret; + if ((argc * sizeof(unsigned char *)) > INT_MAX) overalloc(); + u_argv = xmalloc(argc * sizeof(unsigned char *)); + for (i = 0; i < argc; i++) + u_argv[i] = cast_uchar argv[i]; + ret = p_arse_options(argc, u_argv, all_options); + free(u_argv); + return ret; } static void load_config_file(unsigned char *prefix, unsigned char *name) diff --git a/dip.c b/dip.c @@ -403,7 +403,7 @@ static void enlarge_color_horizontal(unsigned short *in, int ix, int y, * Automatically mem_frees the "in" and allocates "out". */ /* We assume unsigned holds at least 32 bits */ static void scale_gray_horizontal(unsigned char *in, int ix, int y, - unsigned char ** out, int ox) + unsigned char **out, int ox) { unsigned *col_buf; int total=ix*ox; @@ -664,7 +664,7 @@ static void enlarge_color_vertical(unsigned short *in, int x, int iy, * Automatically allocates output and frees input. * We assume unsigned holds at least 32 bits */ static void scale_gray_vertical(unsigned char *in, int x, int iy, - unsigned char ** out ,int oy) + unsigned char **out ,int oy) { unsigned *row_buf; int total=iy*oy; @@ -1097,7 +1097,7 @@ void agx_48_to_48(unsigned short *restrict dest, for (;lenght;lenght--,src+=3,dest+=3) { - a=*src; + a = src[0]; a*=inv_65535; a=powf(a,red_gamma); dest[0]=(unsigned short)((a*65535)+(float)0.5); @@ -1386,8 +1386,7 @@ static void dip_set_gamma(png_structp png_ptr, png_infop info_ptr) * is 34/255ink+(255-34)paper. No gamma is involved in this formula, as you can see. * The multiplications and additions take place in photon space. */ -static void load_char(unsigned char **dest, int *x, int *y, -const unsigned char *png_data, int png_length) +static void load_char(unsigned char **dest, int *x, int *y, const unsigned char *png_data, int png_length) { png_structp png_ptr; png_infop info_ptr; @@ -1472,59 +1471,58 @@ const unsigned char *png_data, int png_length) /* Like load_char, but we dictate the y. */ -static void load_scaled_char(void **dest, int *x, int y, -const unsigned char *png_data, int png_length, struct style *style) +static void load_scaled_char(unsigned char **dest, int *x, int y, const unsigned char *png_data, int png_length, struct style *style) { unsigned char *interm; unsigned char *interm2; - unsigned char *i2ptr,*dptr; + unsigned char *i2ptr, *dptr; int ix, iy, y0, x0, c; - float conv0, conv1,sharpness,contrast; + float conv0, conv1, sharpness, contrast; - load_char(&interm, &ix,&iy,png_data, png_length); - if (style->mono_space>=0) - *x=compute_width(style->mono_space, style->mono_height, y); + load_char(&interm, &ix, &iy, png_data, png_length); + if (style->mono_space >= 0) + *x = compute_width(style->mono_space, style->mono_height, y); else - *x=compute_width(ix,iy,y); - scale_gray(interm, ix,iy, (unsigned char **)dest, *x, y); - if (y>32||y<=0) return ; /* No convolution */ - ix=*x+2; /* There is one-pixel border around */ - iy=y+2; + *x = compute_width(ix, iy, y); + scale_gray(interm, ix, iy, dest, *x, y); + if (y > 32 || y <= 0) return; /* No convolution */ + ix = *x + 2; /* There is one-pixel border around */ + iy = y + 2; if (ix && (unsigned)ix * (unsigned)iy / (unsigned)ix != (unsigned)iy) overalloc(); if ((unsigned)ix * (unsigned)iy > INT_MAX) overalloc(); interm2 = xmalloc(ix * iy); - i2ptr=interm2+ix+1; - dptr=*dest; - memset(interm2,0,ix); - memset(interm2+(iy-1)*ix,0,ix); - for (y0=y;y0;y0--){ - i2ptr[-1]=0; - memcpy(i2ptr,dptr,*x); - i2ptr[*x]=0; - i2ptr+=ix; - dptr+=*x; - } - i2ptr=interm2+ix+1; - dptr=*dest; + i2ptr = interm2 + ix + 1; + dptr = *dest; + memset(interm2, 0, ix); + memset(interm2 + (iy - 1) * ix, 0, ix); + for (y0 = y; y0; y0--) { + i2ptr[-1] = 0; + memcpy(i2ptr, dptr, *x); + i2ptr[*x] = 0; + i2ptr += ix; + dptr += *x; + } + i2ptr = interm2 + ix + 1; + dptr = *dest; /* Determine the sharpness and contrast */ - sharpness=fancy_constants[2*y-2]; - contrast=fancy_constants[2*y-1]; + sharpness = fancy_constants[2 * y - 2]; + contrast = fancy_constants[2 * y - 1]; /* Compute the matrix constants from contrast and sharpness */ - conv0=(1+sharpness)*contrast; - conv1=(float)(-sharpness*(float)0.25*contrast); + conv0 = (1 + sharpness) * contrast; + conv1 = (float)(-sharpness * (float)0.25 * contrast); - for (y0=y;y0;y0--){ - for (x0=*x;x0;x0--){ + for (y0 = y; y0; y0--) { + for (x0 = *x; x0; x0--) { /* Convolution */ - c=(int)(((*i2ptr)*conv0)+i2ptr[-ix]*conv1+i2ptr[-1]*conv1+i2ptr[1]*conv1+i2ptr[ix]*conv1+(float)0.5); - if (c & ~255) c=c<0?0:255; - *dptr=(unsigned char)c; + c = (int)((*i2ptr * conv0) + i2ptr[-ix] * conv1 + i2ptr[-1] * conv1 + i2ptr[1] * conv1 + i2ptr[ix] * conv1 + (float)0.5); + if (c & ~255) c = c < 0 ? 0 : 255; + *dptr = (unsigned char)c; dptr++; i2ptr++; } - i2ptr+=2; + i2ptr += 2; } free(interm2); } @@ -1535,63 +1533,60 @@ static struct font_cache_entry *locked_color_entry = NULL; */ static struct font_cache_entry *supply_color_cache_entry(struct style *style, struct letter *letter) { - struct font_cache_entry *found, *neww; + int found_x, found_y; + unsigned char *found_data; + struct font_cache_entry *neww; unsigned short *primary_data; unsigned short red, green, blue; unsigned bytes_consumed; - found = xmalloc(sizeof(*found)); - found->bitmap.y=style->height; - load_scaled_char(&(found->bitmap.data),&(found->bitmap.x), - found->bitmap.y, letter->begin, - letter->length, style); + found_y = style->height; + load_scaled_char(&found_data, &found_x, found_y, letter->begin, letter->length, style); neww = xmalloc(sizeof(*neww)); locked_color_entry = neww; - neww->bitmap=found->bitmap; - neww->r0=style->r0; - neww->g0=style->g0; - neww->b0=style->b0; - neww->r1=style->r1; - neww->g1=style->g1; - neww->b1=style->b1; - neww->mono_space=style->mono_space; - neww->mono_height=style->mono_height; + neww->bitmap.x = found_x; + neww->bitmap.y = found_y; + neww->r0 = style->r0; + neww->g0 = style->g0; + neww->b0 = style->b0; + neww->r1 = style->r1; + neww->g1 = style->g1; + neww->b1 = style->b1; + neww->mono_space = style->mono_space; + neww->mono_height = style->mono_height; if (neww->bitmap.x && (unsigned)neww->bitmap.x * (unsigned)neww->bitmap.y / (unsigned)neww->bitmap.x != (unsigned)neww->bitmap.y) overalloc(); if ((unsigned)neww->bitmap.x * (unsigned)neww->bitmap.y > INT_MAX / 3 / sizeof(*primary_data)) overalloc(); primary_data = xmalloc(3 * neww->bitmap.x * neww->bitmap.y * sizeof(*primary_data)); /* We assume the gamma of HTML styles is in sRGB space */ - round_color_sRGB_to_48(&red, &green, &blue, - ((style->r0)<<16)|((style->g0)<<8)|(style->b0)); - mix_two_colors(primary_data, found->bitmap.data, - found->bitmap.x*found->bitmap.y, - red,green,blue, + round_color_sRGB_to_48(&red, &green, &blue, (style->r0 << 16) | (style->g0 << 8) | style->b0); + mix_two_colors(primary_data, found_data, + found_x * found_y, + red, green, blue, ags_8_to_16(style->r1, (float)(user_gamma / sRGB_gamma)), ags_8_to_16(style->g1, (float)(user_gamma / sRGB_gamma)), ags_8_to_16(style->b1, (float)(user_gamma / sRGB_gamma)) ); /* We have a buffer with photons */ - if (drv->get_empty_bitmap(&(neww->bitmap))) + if (drv->get_empty_bitmap(&neww->bitmap)) goto skip_dither; if (dither_letters) - dither(primary_data, &(neww->bitmap)); + dither(primary_data, &neww->bitmap); else - (*round_fn)(primary_data,&(neww->bitmap)); + (*round_fn)(primary_data, &neww->bitmap); skip_dither: free(primary_data); - drv->register_bitmap(&(neww->bitmap)); + drv->register_bitmap(&neww->bitmap); - free(found->bitmap.data); - free(found); + free(found_data); - bytes_consumed=neww->bitmap.x*neww->bitmap.y*(drv->depth&7); + bytes_consumed = neww->bitmap.x * neww->bitmap.y * (drv->depth & 7); /* Number of bytes per pixel in passed bitmaps */ - bytes_consumed+=(int)sizeof(*neww); - bytes_consumed+=(int)sizeof(struct lru_entry); - lru_insert(&font_cache, neww, &(letter->color_list), - bytes_consumed); + bytes_consumed += (int)sizeof(*neww); + bytes_consumed += (int)sizeof(struct lru_entry); + lru_insert(&font_cache, neww, &letter->color_list, bytes_consumed); return neww; } @@ -1601,7 +1596,7 @@ static int destroy_font_cache_bottom(void) bottom=lru_get_bottom(&font_cache); if (!bottom) return 0; if (bottom == locked_color_entry) return 0; - drv->unregister_bitmap(&(bottom->bitmap)); + drv->unregister_bitmap(&bottom->bitmap); free(bottom); lru_destroy_bottom(&font_cache); return 1; @@ -1675,49 +1670,41 @@ static void get_underline_pos(int height, int *top, int *bottom) /* *width will be advanced by the width of the text */ void g_print_text(struct graphics_device *device, int x, int y, struct style *style, unsigned char *text, int *width) { - int original_flags, top_underline, bottom_underline, original_width, - my_width; + int original_flags, top_underline, bottom_underline, original_width, my_width; struct rect saved_clip; - if (y+style->height<=device->clip.y1||y>=device->clip.y2) goto o; - if (style->flags){ + if (y + style->height <= device->clip.y1 || y >= device->clip.y2) + goto o; + if (style->flags) { /* Underline */ - if (!width){ - width=&my_width; - *width=0; + if (!width) { + width = &my_width; + *width = 0; } - original_flags=style->flags; - original_width=*width; - style->flags=0; + original_flags = style->flags; + original_width = *width; + style->flags = 0; get_underline_pos(style->height, &top_underline, &bottom_underline); - restrict_clip_area(device, &saved_clip, 0, 0, device->size.x2, y+ - top_underline); + restrict_clip_area(device, &saved_clip, 0, 0, device->size.x2, y + top_underline); g_print_text(device, x, y, style, text, width); set_clip_area(device, &saved_clip); - if (bottom_underline-top_underline==1){ + if (bottom_underline - top_underline == 1) { /* Line */ - drv->draw_hline(device, x, y+top_underline, - safe_add(x,*width)-original_width, - style->underline_color); - }else{ + drv->draw_hline(device, x, y + top_underline, safe_add(x, *width) - original_width, style->underline_color); + } else { /* Area */ - drv->fill_area(device, x, y+top_underline, - safe_add(x,*width)-original_width, - y+bottom_underline, - style->underline_color); + drv->fill_area(device, x, y + top_underline, safe_add(x, *width) - original_width, y + bottom_underline, style->underline_color); } - if (bottom_underline<style->height){ + if (bottom_underline < style->height) { /* Do the bottom half only if the underline is above * the bottom of the letters. */ - *width=original_width; - restrict_clip_area(device, &saved_clip, 0, - y+bottom_underline, device->size.x2, - device->size.y2); + *width = original_width; + restrict_clip_area(device, &saved_clip, 0, y + bottom_underline, device->size.x2, device->size.y2); g_print_text(device, x, y, style, text, width); set_clip_area(device, &saved_clip); } - style->flags=original_flags; + style->flags = original_flags; return; } while (*text) { @@ -1743,18 +1730,20 @@ void g_print_text(struct graphics_device *device, int x, int y, struct style *st if (u==0x82)u=' '; #endif /* stare Mikulasovo patchovani, musim to opravit -- Brain */ - if (!u || u == 0xad) continue; + if (!u || u == 0xad) + continue; if (u == 0x01 || u == 0xa0) u = ' '; - p=print_letter(device,x,y,style, u); + p = print_letter(device, x, y, style, u); x += p; if (width) { *width = safe_add(*width, p); continue; } - if (x>=device->clip.x2) return; + if (x>=device->clip.x2) + return; } return; - o: + o: if (width) { int qw = g_text_width(style, text); *width = safe_add(*width, qw); @@ -1876,6 +1865,16 @@ void update_aspect(void) destroy_font_cache(); } +void flush_bitmaps(int flush_font, int flush_images, int redraw_all) +{ + if (flush_font) + destroy_font_cache(); + if (flush_images) + gamma_stamp++; + if (redraw_all) + cls_redraw_all_terminals(); +} + int fontcache_info(int type) { switch (type) { @@ -2082,7 +2081,7 @@ struct style *g_get_style(int fg, int bg, int size, unsigned char *font, int fla if ((unsigned)n_fonts > INT_MAX / sizeof(*st->table)) overalloc(); st->table = xmalloc(sizeof(*st->table)*(n_fonts-1)); if(fill_style_table(st->table, font)) - load_metric(&(st->mono_space), &(st->mono_height),' ',st->table); + load_metric(&st->mono_space, &st->mono_height, ' ', st->table); else st->mono_space=-1; return st; @@ -2103,8 +2102,10 @@ void g_free_style(struct style *st) tcount gamma_stamp = 1; /* stamp counter for gamma changes */ -long gamma_cache_color; -int gamma_cache_rgb = -2; +long gamma_cache_color_1; +int gamma_cache_rgb_1; +long gamma_cache_color_2; +int gamma_cache_rgb_2; /* IEC 61966-2-1 * Input gamma: sRGB space (directly from HTML, i. e. unrounded) @@ -2113,32 +2114,32 @@ int gamma_cache_rgb = -2; * We assume unsigned short holds at least 16 bits. */ long real_dip_get_color_sRGB(int rgb) { - unsigned short r,g,b; - int new_rgb; + unsigned short r, g, b; + int hacked_rgb, new_rgb; + + hacked_rgb = hack_rgb(rgb); - rgb = hack_rgb(rgb); + round_color_sRGB_to_48(&r, &g, &b, hacked_rgb); + r = ags_16_to_8(r, (float)(1 / (float)(display_red_gamma))); + g = ags_16_to_8(g, (float)(1 / (float)(display_green_gamma))); + b = ags_16_to_8(b, (float)(1 / (float)(display_blue_gamma))); + new_rgb = b | (g << 8) | (r << 16); - round_color_sRGB_to_48(&r,&g,&b,rgb); - r = ags_16_to_8(r, (float)(1 / display_red_gamma)); - g = ags_16_to_8(g, (float)(1 / display_green_gamma)); - b = ags_16_to_8(b, (float)(1 / display_blue_gamma)); - new_rgb=b|(g<<8)|(r<<16); - gamma_cache_rgb = rgb; /* The get_color takes values with gamma of display_*_gamma */ - return gamma_cache_color = drv->get_color(new_rgb); + return gamma_cache_color_1 = drv->get_color(new_rgb); } void get_links_icon(char **data, int *width, int *height, int *skip, int pad) { struct bitmap b; - b.x=48; - b.y=48; - *width=b.x; - *height=b.y; - b.skip=b.x*(drv->depth&7); + b.x = 48; + b.y = 48; + *width = b.x; + *height = b.y; + b.skip = b.x * (drv->depth & 7); while (b.skip % pad) b.skip++; - *skip=b.skip; + *skip = b.skip; b.data = *data = xmalloc(b.skip * b.y); } diff --git a/dither.c b/dither.c @@ -47,6 +47,7 @@ /* We assume here int holds at least 32 bits */ static int *red_table = NULL, *green_table = NULL, *blue_table = NULL; static int table_16 = 1; +static unsigned short *real_colors_table = NULL; /* If we want to represent some 16-bit from-screen-light, it would require certain display input * value (0-255 red, 0-255 green, 0-255 blue), possibly not a whole number. [red|green|blue]_table @@ -90,14 +91,15 @@ static void (*dither_fn_internal)(unsigned short *restrict in, struct bitmap *ou int slow_fpu = -1; -#define LIN \ - r+=(int)(in[0]);\ - g+=(int)(in[1]);\ - b+=(int)(in[2]);\ - in+=3; - /* EMPIRE IMAGINE FEAR */ #define LTABLES \ + ir = in[0];\ + ig = in[1];\ + ib = in[2];\ + r+=(int)ir;\ + g+=(int)ig;\ + b+=(int)ib;\ + in+=3;\ {\ int rc=r,gc=g,bc=b;\ if ((unsigned)rc>65535) rc=rc<0?0:65535;\ @@ -114,7 +116,6 @@ int slow_fpu = -1; #define BODY \ - LIN\ LTABLES\ r=bptr[3];\ g=bptr[4];\ @@ -136,7 +137,6 @@ int slow_fpu = -1; bptr[5]=bt; #define BODYR \ - LIN\ LTABLES\ rt+=8;\ gt+=8;\ @@ -147,12 +147,11 @@ int slow_fpu = -1; bptr[-3]+=3*rt;\ bptr[-2]+=3*gt;\ bptr[-1]+=3*bt;\ - *bptr+=5*rt;\ + bptr[0]+=5*rt;\ bptr[1]+=5*gt;\ bptr[2]+=5*bt; #define BODYC \ - LIN\ LTABLES\ r=rt;\ g=gt;\ @@ -179,10 +178,11 @@ int slow_fpu = -1; bptr[-1]+=3*bt;\ bptr+=3; -#define DITHER_TEMPLATE(template_name) \ +#define DITHER_TEMPLATE(template_name, sh) \ static void template_name(unsigned short *restrict in, struct bitmap *out, int *dregs)\ - {\ - int shift = 8 - table_16 * 8;\ + {\ + const int shift = sh;\ + unsigned short ir, ig, ib;\ int r,g,b,o,rt,gt,bt,y,x;\ unsigned char *restrict outp=out->data;\ int *restrict bptr;\ @@ -215,36 +215,28 @@ int slow_fpu = -1; }\ } -#define ROUND_TEMPLATE(template_name)\ +#define ROUND_TEMPLATE(template_name, sh)\ static void template_name(unsigned short *restrict in, struct bitmap *out)\ {\ + const int shift = sh;\ + unsigned short ir, ig, ib;\ int rt,gt,bt,o,x,y;\ unsigned char *restrict outp=out->data;\ int skip=out->skip-SKIP_CODE;\ \ o=0;o=o; /*warning go away */\ - if (table_16) {\ - for (y=out->y;y;y--){\ - for (x=out->x;x;x--){\ - rt = red_table[in[0]];\ - gt = green_table[in[1]];\ - bt = blue_table[in[2]];\ - in+=3;\ - SAVE_CODE\ - }\ - outp+=skip;\ - }\ - } else {\ - for (y=out->y;y;y--){\ - for (x=out->x;x;x--){\ - rt = red_table[in[0] >> 8];\ - gt = green_table[in[1] >> 8];\ - bt = blue_table[in[2] >> 8];\ - in+=3;\ - SAVE_CODE\ - }\ - outp+=skip;\ + for (y=out->y;y;y--){\ + for (x=out->x;x;x--){\ + ir = in[0];\ + ig = in[1];\ + ib = in[2];\ + rt=red_table[ir >> shift];\ + gt=green_table[ig >> shift];\ + bt=blue_table[ib >> shift];\ + in+=3;\ + SAVE_CODE\ }\ + outp+=skip;\ }\ } @@ -255,12 +247,40 @@ int slow_fpu = -1; * that saves appropriate code on *outp (unsigned char *outp). We can use int o; * as a scratchpad. */ -#define SAVE_CODE \ - o = (rt >> 16) + (gt >> 16) + (bt >> 16);\ +#define SAVE_CODE \ + o = (rt >> 16) + (gt >> 16) + (bt >> 16); \ *outp++ = (unsigned char)o; -DITHER_TEMPLATE(dither_1byte) -ROUND_TEMPLATE(round_1byte) +DITHER_TEMPLATE(dither_1byte, 0) +ROUND_TEMPLATE(round_1byte, 0) +DITHER_TEMPLATE(dither_1byte_8, 8) +ROUND_TEMPLATE(round_1byte_8, 8) + +#undef SKIP_CODE +#undef SAVE_CODE + +#define SKIP_CODE out->x +#define SAVE_CODE \ + { \ + int rr, gr, br, or; \ + o = (rt >> 16) + (gt >> 16) + (bt >> 16); \ + rr = red_table[ir >> shift]; \ + gr = green_table[ig >> shift]; \ + br = blue_table[ib >> shift]; \ + or = (rr >> 16) + (gr >> 16) + (br >> 16); \ + if (!((real_colors_table[or * 3 + 0] - ir) | \ + (real_colors_table[or * 3 + 1] - ig) | \ + (real_colors_table[or * 3 + 2] - ib))) { \ + o = or; \ + } \ + rt = real_colors_table[o * 3 + 0]; \ + gt = real_colors_table[o * 3 + 1]; \ + bt = real_colors_table[o * 3 + 2]; \ + *outp++ = (unsigned char)o; \ + } + +DITHER_TEMPLATE(dither_1byte_real_colors, 0) +DITHER_TEMPLATE(dither_1byte_real_colors_8, 8) #undef SKIP_CODE #undef SAVE_CODE @@ -271,8 +291,10 @@ ROUND_TEMPLATE(round_1byte) *(unsigned short *)outp=(o>>16);\ outp+=2; -DITHER_TEMPLATE(dither_2byte) -ROUND_TEMPLATE(round_2byte) +DITHER_TEMPLATE(dither_2byte, 0) +ROUND_TEMPLATE(round_2byte, 0) +DITHER_TEMPLATE(dither_2byte_8, 8) +ROUND_TEMPLATE(round_2byte_8, 8) #undef SAVE_CODE #undef SKIP_CODE @@ -283,8 +305,10 @@ ROUND_TEMPLATE(round_2byte) outp[1]=gt>>16;\ outp[2]=rt>>16;\ outp+=3; -DITHER_TEMPLATE(dither_195) -ROUND_TEMPLATE(round_195) +DITHER_TEMPLATE(dither_195, 0) +ROUND_TEMPLATE(round_195, 0) +DITHER_TEMPLATE(dither_195_8, 8) +ROUND_TEMPLATE(round_195_8, 8) #undef SAVE_CODE #undef SKIP_CODE @@ -295,8 +319,10 @@ ROUND_TEMPLATE(round_195) outp[1]=gt>>16;\ outp[2]=bt>>16;\ outp+=3; -DITHER_TEMPLATE(dither_451) -ROUND_TEMPLATE(round_451) +DITHER_TEMPLATE(dither_451, 0) +ROUND_TEMPLATE(round_451, 0) +DITHER_TEMPLATE(dither_451_8, 8) +ROUND_TEMPLATE(round_451_8, 8) #undef SAVE_CODE #undef SKIP_CODE @@ -308,8 +334,10 @@ ROUND_TEMPLATE(round_451) outp[2]=rt>>16;\ outp[3]=0;\ outp+=4; -DITHER_TEMPLATE(dither_196) -ROUND_TEMPLATE(round_196) +DITHER_TEMPLATE(dither_196, 0) +ROUND_TEMPLATE(round_196, 0) +DITHER_TEMPLATE(dither_196_8, 8) +ROUND_TEMPLATE(round_196_8, 8) #undef SAVE_CODE #undef SKIP_CODE @@ -321,8 +349,10 @@ ROUND_TEMPLATE(round_196) outp[2]=gt>>16;\ outp[3]=rt>>16;\ outp+=4; -DITHER_TEMPLATE(dither_452) -ROUND_TEMPLATE(round_452) +DITHER_TEMPLATE(dither_452, 0) +ROUND_TEMPLATE(round_452, 0) +DITHER_TEMPLATE(dither_452_8, 8) +ROUND_TEMPLATE(round_452_8, 8) #undef SAVE_CODE #undef SKIP_CODE @@ -334,8 +364,10 @@ ROUND_TEMPLATE(round_452) outp[2]=gt>>16;\ outp[3]=bt>>16;\ outp+=4; -DITHER_TEMPLATE(dither_708) -ROUND_TEMPLATE(round_708) +DITHER_TEMPLATE(dither_708, 0) +ROUND_TEMPLATE(round_708, 0) +DITHER_TEMPLATE(dither_708_8, 8) +ROUND_TEMPLATE(round_708_8, 8) #undef SAVE_CODE #undef SKIP_CODE @@ -852,6 +884,25 @@ static void compress_tables(void) blue_table = bt; } +static void make_real_colors_table(void) +{ + unsigned short *real_colors; + if (real_colors_table) { + free(real_colors_table); + real_colors_table = NULL; + } + if (round_fn != round_1byte && round_fn != round_1byte_8) + return; + if (!drv->get_real_colors) + return; + real_colors = drv->get_real_colors(); + if (!real_colors) + return; + real_colors_table = xmalloc(256 * 3 * sizeof(unsigned short)); + agx_48_to_48(real_colors_table, real_colors, 256, display_red_gamma, display_green_gamma, display_blue_gamma); + free(real_colors); +} + /* Also makes up the dithering tables. * You may call it twice - it doesn't leak any memory. */ @@ -864,8 +915,9 @@ void init_dither(int depth) make_red_table(1 << 1, 1 << 3, 0); make_green_table(1 << 2, 1 << 1, 0); make_blue_table(1 << 1, 1 << 0, 0); - dither_fn_internal = dither_1byte; - round_fn = round_1byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_1byte : dither_1byte_8; + round_fn = table_16 ? round_1byte : round_1byte_8; break; case 801: @@ -873,8 +925,9 @@ void init_dither(int depth) make_red_table(1 << 1, 1 << 2, 0); make_green_table(1 << 1, 1 << 1, 0); make_blue_table(1 << 1, 1 << 0, 0); - dither_fn_internal = dither_1byte; - round_fn = round_1byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_1byte : dither_1byte_8; + round_fn = table_16 ? round_1byte : round_1byte_8; break; case 65: @@ -882,8 +935,9 @@ void init_dither(int depth) make_red_table(1 << 3, 1 << 5, 0); make_green_table(1 << 3, 1 << 2, 0); make_blue_table(1 << 2, 1 << 0, 0); - dither_fn_internal = dither_1byte; - round_fn = round_1byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_1byte : dither_1byte_8; + round_fn = table_16 ? round_1byte : round_1byte_8; break; case 833: @@ -891,8 +945,9 @@ void init_dither(int depth) make_red_table(6, 36, 0); make_green_table(6, 6, 0); make_blue_table(6, 1, 0); - dither_fn_internal = dither_1byte; - round_fn = round_1byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_1byte : dither_1byte_8; + round_fn = table_16 ? round_1byte : round_1byte_8; break; case 122: @@ -900,8 +955,9 @@ void init_dither(int depth) make_red_table(1 << 5, 1 << 10, 0); make_green_table(1 << 5, 1 << 5, 0); make_blue_table(1 << 5, 1 << 0, 0); - dither_fn_internal = dither_2byte; - round_fn = round_2byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_2byte : dither_2byte_8; + round_fn = table_16 ? round_2byte : round_2byte_8; break; case 378: @@ -909,8 +965,9 @@ void init_dither(int depth) make_red_table(1 << 5, 1 << 10, 1); make_green_table(1 << 5, 1 << 5, 1); make_blue_table(1 << 5, 1 << 0, 1); - dither_fn_internal = dither_2byte; - round_fn = round_2byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_2byte : dither_2byte_8; + round_fn = table_16 ? round_2byte : round_2byte_8; break; case 130: @@ -918,8 +975,9 @@ void init_dither(int depth) make_red_table(1 << 5, 1 << 11, 0); make_green_table(1 << 6, 1 << 5, 0); make_blue_table(1 << 5, 1 << 0, 0); - dither_fn_internal = dither_2byte; - round_fn = round_2byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_2byte : dither_2byte_8; + round_fn = table_16 ? round_2byte : round_2byte_8; break; case 386: @@ -927,8 +985,9 @@ void init_dither(int depth) make_red_table(1 << 5, 1 << 11, 1); make_green_table(1 << 6, 1 << 5, 1); make_blue_table(1 << 5, 1 << 0, 1); - dither_fn_internal = dither_2byte; - round_fn = round_2byte; + compress_tables(); + dither_fn_internal = table_16 ? dither_2byte : dither_2byte_8; + round_fn = table_16 ? round_2byte : round_2byte_8; break; case 451: @@ -939,8 +998,9 @@ void init_dither(int depth) make_red_table(1 << 8, 1 << 0, 0); make_green_table(1 << 8, 1 << 0, 0); make_blue_table(1 << 8, 1 << 0, 0); - dither_fn_internal = dither_451; - round_fn = round_451; + compress_tables(); + dither_fn_internal = table_16 ? dither_451 : dither_451_8; + round_fn = table_16 ? round_451 : round_451_8; break; case 195: @@ -951,8 +1011,9 @@ void init_dither(int depth) make_red_table(1 << 8, 1 << 0, 0); make_green_table(1 << 8, 1 << 0, 0); make_blue_table(1 << 8, 1 << 0, 0); - dither_fn_internal = dither_195; - round_fn = round_195; + compress_tables(); + dither_fn_internal = table_16 ? dither_195 : dither_195_8; + round_fn = table_16 ? round_195 : round_195_8; break; case 452: @@ -963,8 +1024,9 @@ void init_dither(int depth) make_red_table(1 << 8, 1 << 0, 0); make_green_table(1 << 8, 1 << 0, 0); make_blue_table(1 << 8, 1 << 0, 0); - dither_fn_internal = dither_452; - round_fn = round_452; + compress_tables(); + dither_fn_internal = table_16 ? dither_452 : dither_452_8; + round_fn = table_16 ? round_452 : round_452_8; break; case 196: @@ -975,8 +1037,9 @@ void init_dither(int depth) make_red_table(1 << 8, 1 << 0, 0); make_green_table(1 << 8, 1 << 0, 0); make_blue_table(1 << 8, 1 << 0, 0); - dither_fn_internal = dither_196; - round_fn = round_196; + compress_tables(); + dither_fn_internal = table_16 ? dither_196 : dither_196_8; + round_fn = table_16 ? round_196 : round_196_8; break; case 708: @@ -987,8 +1050,9 @@ void init_dither(int depth) make_red_table(1 << 8, 1 << 0, 0); make_green_table(1 << 8, 1 << 0, 0); make_blue_table(1 << 8, 1 << 0, 0); - dither_fn_internal = dither_708; - round_fn = round_708; + compress_tables(); + dither_fn_internal = table_16 ? dither_708 : dither_708_8; + round_fn = table_16 ? round_708 : round_708_8; break; case 15555: @@ -998,8 +1062,9 @@ void init_dither(int depth) make_red_table(1 << 5, 1 << 3, 0); make_green_table(1 << 5, 1 << 3, 0); make_blue_table(1 << 5, 1 << 3, 0); - dither_fn_internal = dither_195; - round_fn = round_195; + compress_tables(); + dither_fn_internal = table_16 ? dither_195 : dither_195_8; + round_fn = table_16 ? round_195 : round_195_8; break; case 16579: @@ -1009,17 +1074,27 @@ void init_dither(int depth) make_red_table(1 << 5, 1 << 3, 0); make_green_table(1 << 6, 1 << 2, 0); make_blue_table(1 << 5, 1 << 3, 0); - dither_fn_internal = dither_195; - round_fn = round_195; + compress_tables(); + dither_fn_internal = table_16 ? dither_195 : dither_195_8; + round_fn = table_16 ? round_195 : round_195_8; break; default: internal("Graphics driver returned unsupported pixel memory organisation %d",depth); } - compress_tables(); + make_round_tables(); + make_real_colors_table(); - gamma_cache_rgb = -2; + if (real_colors_table) { + if (dither_fn_internal == dither_1byte) + dither_fn_internal = dither_1byte_real_colors; + if (dither_fn_internal == dither_1byte_8) + dither_fn_internal = dither_1byte_real_colors_8; + } + + gamma_cache_rgb_1 = -2; + gamma_cache_rgb_2 = -2; gamma_stamp++; } @@ -1030,9 +1105,20 @@ void init_dither(int depth) void round_color_sRGB_to_48(unsigned short *restrict red, unsigned short *restrict green, unsigned short *restrict blue, int rgb) { - *red=round_red_table[(rgb>>16)&255]; - *green=round_green_table[(rgb>>8)&255]; - *blue=round_blue_table[rgb&255]; + *red = round_red_table[(rgb >> 16) & 255]; + *green = round_green_table[(rgb >> 8) & 255]; + *blue = round_blue_table[rgb & 255]; + if (real_colors_table) { + int shift, rt, gt, bt, o; + shift = 8 - table_16 * 8; + rt = red_table[*red >> shift]; + gt = green_table[*green >> shift]; + bt = blue_table[*blue >> shift]; + o = (rt >> 16) + (gt >> 16) + (bt >> 16); + *red = real_colors_table[o * 3 + 0]; + *green = real_colors_table[o * 3 + 1]; + *blue = real_colors_table[o * 3 + 2]; + } } void free_dither(void) @@ -1043,6 +1129,8 @@ void free_dither(void) green_table = NULL; free(blue_table); blue_table = NULL; + free(real_colors_table); + real_colors_table = NULL; } #endif diff --git a/html.c b/html.c @@ -458,7 +458,7 @@ static const struct color_spec color_specs[] = { int decode_color(unsigned char *str, struct rgb *col) { unsigned long ch; - unsigned char *end; + char *end; if (*str != '#') { const struct color_spec *cs; for (cs = color_specs; cs < endof(color_specs); cs++) @@ -470,7 +470,7 @@ int decode_color(unsigned char *str, struct rgb *col) str++; } if (strlen(cast_const_char str) == 6) { - ch = strtoul(cast_const_char str, (char **)(void *)&end, 16); + ch = strtoul(cast_const_char str, &end, 16); if (!*end && ch < 0x1000000) { found: memset(col, 0, sizeof(struct rgb)); @@ -481,7 +481,7 @@ found: } } if (strlen(cast_const_char str) == 3) { - ch = strtoul(cast_const_char str, (char **)(void *)&end, 16); + ch = strtoul(cast_const_char str, &end, 16); if (!*end && ch < 0x1000) { memset(col, 0, sizeof(struct rgb)); col->r = ((unsigned)ch / 0x100) * 0x11; @@ -613,7 +613,7 @@ static int put_chars_conv(unsigned char *c, int l) if (c[pp] != '&') { struct conv_table *t; int i; - if (pp + 3 <= l && c[pp] == 0xef && c[pp + 1] == 0xbb && c[pp + 2] == 0xbf && !d_opt->real_cp) { + if (l - pp >= 3 && c[pp] == 0xef && c[pp + 1] == 0xbb && c[pp + 2] == 0xbf && !d_opt->real_cp) { pp += 3; continue; } @@ -633,7 +633,7 @@ static int put_chars_conv(unsigned char *c, int l) } else { int i = pp + 1; if (d_opt->plain & 1) goto put_c; - while (i < l && c[i] != ';' && c[i] != '&' && c[i] > ' ') i++; + while (i < l && !is_entity_terminator(c[i])) i++; if (!(e = get_entity_string(&c[pp + 1], i - pp - 1))) goto put_c; pp = i + (i < l && c[i] == ';'); } @@ -756,8 +756,8 @@ int get_num(unsigned char *a, unsigned char *n) { unsigned char *al; if ((al = get_attr_val(a, n))) { - unsigned char *end; - unsigned long s = strtoul(cast_const_char al, (char **)(void *)&end, 10); + char *end; + unsigned long s = strtoul(cast_const_char al, &end, 10); if (!*al || *end || s > 10000) s = -1; free(al); return (int)s; @@ -937,10 +937,16 @@ static void html_a(unsigned char *a) static void html_a_special(unsigned char *a, unsigned char *next, unsigned char *eof) { unsigned char *t; + if (!format_.link) return; while (next < eof && WHITECHAR(*next)) next++; - if (next > eof - 4) return; - if (!(next[0] == '<' && next[1] == '/' && upcase(next[2]) == 'A' && next[3] == '>')) return; - if (!has_attr(a, cast_uchar "href") || !format_.link) return; + if (eof - next >= 4 && next[0] == '<' && next[1] == '/' && upcase(next[2]) == 'A' && next[3] == '>') + goto ok; + if (strstr(cast_const_char format_.link, "/raw/")) /* gitlab hack */ + goto ok; + return; + + ok: + if (!has_attr(a, cast_uchar "href")) return; t = get_attr_val(a, cast_uchar "title"); if (!t) return; put_chrs(t, (int)strlen(cast_const_char t)); @@ -969,7 +975,7 @@ static void html_font(unsigned char *a) int p = 0; unsigned long s; unsigned char *nn = al; - unsigned char *end; + char *end; if (*al == '+') { p = 1; nn++; @@ -978,7 +984,7 @@ static void html_font(unsigned char *a) p = -1; nn++; } - s = strtoul(cast_const_char nn, (char **)(void *)&end, 10); + s = strtoul(cast_const_char nn, &end, 10); if (*nn && !*end) { if (s > 7) s = 7; if (!p) format_.fontsize = (int)s; @@ -1032,12 +1038,16 @@ static void html_img(unsigned char *a) || (s = get_url_val_img(a, cast_uchar "data-original")) || (s = get_url_val_img(a, cast_uchar "data-small")) || (s = get_url_val_img(a, cast_uchar "data-lazy")) + || (s = get_url_val_img(a, cast_uchar "data-lazy-src")) || (s = get_url_val_img(a, cast_uchar "src")) + || (s = get_url_val_img(a, cast_uchar "data-source")) || (s = get_url_val_img(a, cast_uchar "dynsrc")) || (s = get_url_val_img(a, cast_uchar "data")) || (s = get_url_val_img(a, cast_uchar "content")) || (s = get_url_val(a, cast_uchar "src"))) { + if (!s[0]) goto skip_img; format_.image = join_urls(format_.href_base, s); + skip_img: orig_link = s; } if (!F || !d_opt->display_images) { @@ -1673,7 +1683,7 @@ static void find_form_for_input(unsigned char *i) se: while (s < i && *s != '<') sp:s++; if (s >= i) goto end_parse; - if (s + 2 <= eofff && (s[1] == '!' || s[1] == '?')) { + if (eofff - s >= 2 && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, i); goto se; } @@ -1947,7 +1957,7 @@ static void html_option(unsigned char *a) r = p; while (r < eoff && WHITECHAR(*r)) r++; if (r >= eoff) goto x; - if (r - 2 <= eoff && (r[1] == '!' || r[1] == '?')) { + if (eoff - r >= 2 && (r[1] == '!' || r[1] == '?')) { p = skip_comment(r, eoff); goto rrrr; } @@ -2191,7 +2201,7 @@ static int do_html_select(unsigned char *attr, unsigned char *html, unsigned cha } add_bytes_to_str(&vlbl, &vlbl_l, s, l); } - if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { + if (eof - html >= 2 && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto se; } @@ -2481,6 +2491,7 @@ static void html_frame(unsigned char *a) static void parse_frame_widths(unsigned char *a, int ww, int www, int **op, int *olp) { unsigned char *aa; + char *end; int q, qq, i, d, nn; unsigned long n; int *oo, *o; @@ -2489,7 +2500,8 @@ static void parse_frame_widths(unsigned char *a, int ww, int www, int **op, int o = NULL; new_ch: while (WHITECHAR(*a)) a++; - n = strtoul(cast_const_char a, (char **)(void *)&a, 10); + n = strtoul(cast_const_char a, &end, 10); + a = cast_uchar end; if (n > 10000) n = 10000; q = (int)n; if (*a == '%') q = q * ww / 100; @@ -2661,7 +2673,11 @@ static void html_meta(unsigned char *a) if (!strcmp(cast_const_char prop, "og:image")) { unsigned char *host = get_host_name(format_.href_base); if (host) { - if (strstr(cast_const_char host, "instagram.")) + if (strstr(cast_const_char host, "flickr.") + || strstr(cast_const_char host, "instagram.") + || strstr(cast_const_char host, "mastadon.") + || strstr(cast_const_char host, "pinterest.") + || strstr(cast_const_char host, "twitter.")) html_img(a); free(host); } @@ -2838,11 +2854,11 @@ static struct element_info elements[] = { unsigned char *skip_comment(unsigned char *html, unsigned char *eof) { - int comm = html + 4 <= eof && html[2] == '-' && html[3] == '-'; + int comm = eof - html >= 4 && html[2] == '-' && html[3] == '-'; html += comm ? 4 : 2; while (html < eof) { if (!comm && html[0] == '>') return html + 1; - if (comm && html + 2 <= eof && html[0] == '-' && html[1] == '-') { + if (comm && eof - html >= 2 && html[0] == '-' && html[1] == '-') { html += 2; while (html < eof && (*html == '-' || *html == '!')) html++; while (html < eof && WHITECHAR(*html)) html++; @@ -2886,9 +2902,13 @@ static int qd(unsigned char *html, unsigned char *eof, int *len) return -1; } if (html[0] != '&' || d_opt->plain & 1) return html[0]; - if (html + 1 >= eof) return -1; + if (eof - html >= 5 && !memcmp(html + 1, "Tab;", 4)) { + *len = 5; + return 9; + } + if (eof - html <= 1) return -1; if (html[1] != '#') return -1; - for (l = 2; l < 10 && html + l < eof; l++) if (html[l] == ';') { + for (l = 2; l < 10 && eof - html > l; l++) if (html[l] == ';') { int n = get_entity_number(html + 2, l - 2); if (n >= 0) { *len = l + 1; @@ -2941,7 +2961,7 @@ do { \ } putsp = 0;*/ while (h < eof && WHITECHAR(*h)) h++; - if (h + 1 < eof && h[0] == '<' && h[1] == '/') { + if (eof - h > 1 && h[0] == '<' && h[1] == '/') { if (!parse_element(h, eof, &name, &namelen, &attr, &end)) { put_chrs(lt, (int)(html - lt)); lt = html = h; @@ -2981,7 +3001,7 @@ do { \ put_chrs(lt, (int)(html - lt)); next_break: html += l; - if (q == 13 && html < eof - 1 && qd(html, eof, &l) == 10) html += l; + if (q == 13 && eof - html > 1 && qd(html, eof, &l) == 10) html += l; ln_break(1); if (html >= eof) goto set_lt; q = qd(html, eof, &l); @@ -2996,12 +3016,12 @@ do { \ int xl; put_chrs(lt, (int)(html - lt)); xl = 1; - while (xl < 240 && html + xl + 1 < eof && html[xl + 1] < ' ' && html[xl + 1] != 9 && html[xl + 1] != 10 && html[xl + 1] != 13) xl++; + while (xl < 240 && eof - html > xl + 1 && html[xl + 1] < ' ' && html[xl + 1] != 9 && html[xl + 1] != 10 && html[xl + 1] != 13) xl++; put_chrs(cast_uchar "................................................................................................................................................................................................................................................", xl); html += xl; goto set_lt; } - if (html + 2 <= eof && html[0] == '<' && (html[1] == '!' || html[1] == '?') && !(d_opt->plain & 1) && html_top.invisible != INVISIBLE_STYLE) { + if (eof - html >= 2 && html[0] == '<' && (html[1] == '!' || html[1] == '?') && !(d_opt->plain & 1) && html_top.invisible != INVISIBLE_STYLE) { /*if (putsp == 1) goto put_sp; putsp = 0;*/ put_chrs(lt, (int)(html - lt)); @@ -3224,7 +3244,7 @@ int get_image_map(unsigned char *head, unsigned char *s, unsigned char *eof, uns free(*menu); return -1; } - if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { + if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se; } @@ -3249,7 +3269,7 @@ int get_image_map(unsigned char *head, unsigned char *s, unsigned char *eof, uns free(*menu); return -1; } - if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { + if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se2; } @@ -3270,7 +3290,7 @@ int get_image_map(unsigned char *head, unsigned char *s, unsigned char *eof, uns } add_bytes_to_str(&label, &lblen, s, ss - s); s = ss; - if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { + if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se3; } @@ -3417,7 +3437,7 @@ void scan_http_equiv(unsigned char *s, unsigned char *eof, unsigned char **head, se: while (s < eof && *s != '<') sp:s++; if (s >= eof) return; - if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { + if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se; } @@ -3447,7 +3467,7 @@ void scan_http_equiv(unsigned char *s, unsigned char *eof, unsigned char **head, while (s < eof && *s != '<') xsp:s++; add_bytes_to_str(title, &tlen, s1, s - s1); if (s >= eof) goto se; - if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { + if (eof - s >= 2 && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto xse; } diff --git a/html_gr.c b/html_gr.c @@ -487,13 +487,13 @@ int is_in_area(struct map_area *a, int x, int y) case SHAPE_POLY: over = 0; if (a->ncoords >= 4) - for (i = 0; i + 1 < a->ncoords; i += 2) { + for (i = 0; a->ncoords - i > 1; i += 2) { int x1, x2, y1, y2; x1 = a->coords[i]; y1 = a->coords[i + 1]; x2 = a->coords[0]; y2 = a->coords[1]; - if (i + 3 < a->ncoords) { + if (a->ncoords - i > 3) { x2 = a->coords[i + 2]; y2 = a->coords[i + 3]; } @@ -551,12 +551,14 @@ static void do_image(struct g_part *p, struct image_description *im) struct memory_list *ml; struct menu_item *menu; struct cache_entry *ce = af->rq->ce; - unsigned char *start, *end; + unsigned char *start; + size_t len; int i; struct image_map *map; - if (get_file(af->rq, &start, &end) - || (start == end) - || get_image_map(ce->head, start, end, tag, &menu, &ml, format_.href_base, format_.target_base, 0, 0, 0, 1)) + if (get_file(af->rq, &start, &len) || (!len)) + goto ft; + if (len > INT_MAX) len = INT_MAX; + if (get_image_map(ce->head, start, start + len, tag, &menu, &ml, format_.href_base, format_.target_base, 0, 0, 0, 1)) goto ft; map = xmalloc(sizeof(struct image_map)); map->n_areas = 0; diff --git a/html_r.c b/html_r.c @@ -599,7 +599,8 @@ static void put_chars(void *p_, unsigned char *c, int l) if (!l) return; if (p->cx < par_format.leftmargin) p->cx = par_format.leftmargin; if (c[0] != ' ' || (c[1] && c[1] != ' ')) { - last_tag_for_newline = &p->data->tags; + if (p->data) + last_tag_for_newline = &p->data->tags; } if (!d_opt->cp && !(format_.attr & AT_GRAPHICS)) { int pl; diff --git a/html_tbl.c b/html_tbl.c @@ -65,11 +65,11 @@ static void get_c_width(unsigned char *attr, int *w, int sh) unsigned char *al; if ((al = get_attr_val(attr, cast_uchar "width"))) { if (*al && al[strlen(cast_const_char al) - 1] == '*') { - unsigned char *en; + char *end; unsigned long n; al[strlen(cast_const_char al) - 1] = 0; - n = strtoul(cast_const_char al, (char **)(void *)&en, 10); - if (n < 10000 && !*en) *w = W_REL - (int)n; + n = strtoul(cast_const_char al, &end, 10); + if (n < 10000 && !*end) *w = W_REL - (int)n; } else { int p = get_width(attr, cast_uchar "width", sh); if (p >= 0) *w = p; @@ -374,7 +374,7 @@ unsigned char *skip_element(unsigned char *html, unsigned char *eof, unsigned ch int namelen; r: while (html < eof && (*html != '<')) rr:html++; - if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { + if (eof - html >= 2 && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto r; } @@ -438,7 +438,7 @@ static struct table *parse_table(unsigned char *html, unsigned char *eof, unsign if (lbhp) (*bad_html)[*bhp-1].e = html; goto scan_done; } - if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { + if (eof - html >= 2 && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto se; } diff --git a/http.c b/http.c @@ -400,7 +400,7 @@ static void add_user_agent(unsigned char **hdr, int *l) { add_to_str(hdr, l, cast_uchar "User-Agent: "); if (SCRUB_HEADERS) - add_to_str(hdr, l, cast_uchar "Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0\r\n"); + add_to_str(hdr, l, cast_uchar "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0\r\n"); else if (!(*http_options.header.fake_useragent)) { add_to_str(hdr, l, cast_uchar("Links (" VERSION "; ")); add_to_str(hdr, l, system_name); @@ -720,11 +720,11 @@ next_chunk: } else if (info->chunk_remaining == -1) { int l; if ((l = is_line_in_buffer(rb))) { - unsigned char *de = NULL; + char *end; long n = 0; if (l != -1) - n = strtol((char *)rb->data, (char **)(void *)&de, 16); - if (l == -1 || n < 0 || n >= INT_MAX || de == rb->data) { + n = strtol(cast_const_char rb->data, &end, 16); + if (l == -1 || n < 0 || n >= INT_MAX || cast_uchar end == rb->data) { setcstate(c, S_HTTP_ERROR); abort_connection(c); return; diff --git a/img.c b/img.c @@ -543,9 +543,9 @@ static void buffer_to_bitmap(struct cached_image *cimg) } else { if (tmp) { if (dither_images) - dither(tmp,&(cimg->bmp)); + dither(tmp, &cimg->bmp); else - (*round_fn)(tmp,&(cimg->bmp)); + (*round_fn)(tmp, &cimg->bmp); free(tmp); } else { int i; @@ -706,14 +706,15 @@ static void type(struct cached_image *cimg, unsigned char *content_type, unsigne */ static int img_process_download(struct g_object_image *goi, struct f_data_c *fdatac) { - unsigned char *data, *dataend, *ctype; - int length; + unsigned char *data, *ctype; + size_t total_len; struct cached_image *cimg = goi->cimg; int chopped=0; if (!goi->af->rq) return 0; - if (get_file(goi->af->rq, &data, &dataend)) goto end; - if (dataend - data < 4) goto end; + if (get_file(goi->af->rq, &data, &total_len)) goto end; + if (total_len < 4) goto end; + if (total_len > INT_MAX) total_len = INT_MAX; /*fprintf(stderr, "processing: %s\n", goi->af->rq->ce->url);*/ if (goi->af->rq->ce->count2!=cimg->last_count2|| (goi->af->rq->ce->count!=cimg->last_count && cimg->eof_hit) || @@ -737,7 +738,7 @@ static int img_process_download(struct g_object_image *goi, struct f_data_c *fda */ if (!((cimg->state^8)&9)){ - length = (int)(dataend - data); + int length = (int)total_len; if (length<=cimg->last_length) goto end; /* No new data */ data+=cimg->last_length; @@ -865,26 +866,41 @@ static void draw_frame_mark(struct graphics_device *dev, int x, int y, int xw, i } } +static long image_backgronud(struct cached_image *cimg) +{ + if (!cimg) return dip_get_color_sRGB(0x00c0c0c0); + return dip_get_color_sRGB(cimg->background_color); +} + +static long image_foregronud(struct cached_image *cimg) +{ + if (!cimg) return dip_get_color_sRGB(0x00000000); + return dip_get_color_sRGB(get_foreground(cimg->background_color)); +} + /* Entry is allowed only in states 12, 13, 14, 15 * Draws the picture from bitmap. * Before doing so, ensures that bitmap is present and if not, converts it from * the buffer. */ -static void draw_picture(struct f_data_c *fdatac, struct g_object_image *goi, - int x, int y, long bg) +static void draw_picture(struct f_data_c *fdatac, struct g_object_image *goi, int x, int y) { - struct graphics_device *dev=fdatac->ses->term->dev; - struct cached_image *cimg=goi->cimg; + struct graphics_device *dev = fdatac->ses->term->dev; + struct cached_image *cimg = goi->cimg; struct rect saved; - if (!(cimg->state&1)){ + if (!(cimg->state & 1)) { if (!cimg->bmp_used) buffer_to_bitmap(cimg); } - restrict_clip_area(dev, &saved, x, y, x+goi->goti.go.xw, y+goi->goti.go.yw); - drv->draw_bitmap(dev, &cimg->bmp,x,y); - drv->fill_area(dev, x + cimg->bmp.x, y, x + goi->goti.go.xw, y + cimg->bmp.y, bg); - drv->fill_area(dev, x, y + cimg->bmp.y, x + goi->goti.go.xw, y + goi->goti.go.yw,bg); + restrict_clip_area(dev, &saved, x, y, x + goi->goti.go.xw, y + goi->goti.go.yw); + drv->draw_bitmap(dev, &cimg->bmp, x, y); + if (cimg->bmp.x < goi->goti.go.xw + || cimg->bmp.y < goi->goti.go.yw) { + long bg = image_backgronud(cimg); + drv->fill_area(dev, x + cimg->bmp.x, y, x + goi->goti.go.xw, y + cimg->bmp.y, bg); + drv->fill_area(dev, x, y + cimg->bmp.y, x + goi->goti.go.xw, y + goi->goti.go.yw, bg); + } set_clip_area(dev, &saved); } @@ -893,16 +909,14 @@ static void draw_picture(struct f_data_c *fdatac, struct g_object_image *goi, */ static void update_bitmap(struct cached_image *cimg) { - if (!(cimg->state&1)&& - !cimg->strip_optimized - &&cimg->rows_added) buffer_to_bitmap(cimg); + if (!(cimg->state & 1) && !cimg->strip_optimized && cimg->rows_added) + buffer_to_bitmap(cimg); } /* Draws the image at x,y. Is called from other C sources. */ static void img_draw_image(struct f_data_c *fdatac, struct g_object *goi_, int x, int y) { struct g_object_image *goi = get_struct(goi_, struct g_object_image, goti.go); - long color_bg, color_fg; struct cached_image *cimg = goi->cimg; struct rect r; /* refresh_image(fdatac, goi, 1000); To sem asi napsal mikulas jako @@ -910,21 +924,14 @@ static void img_draw_image(struct f_data_c *fdatac, struct g_object *goi_, int x * usoudil, ze zadnejch 1000, ale 0. */ - if (cimg) { - color_bg = dip_get_color_sRGB(cimg->background_color); - color_fg = dip_get_color_sRGB(get_foreground(cimg->background_color)); - } else { - color_bg = dip_get_color_sRGB(0x00c0c0c0); - color_fg = dip_get_color_sRGB(0x00000000); - } - - if (!(goi->goti.go.xw && goi->goti.go.yw)) return; /* At least one dimension is zero */ - + if (!(goi->goti.go.xw && goi->goti.go.yw)) + return; /* At least one dimension is zero */ memcpy(&r, &fdatac->ses->term->dev->clip, sizeof(struct rect)); if (fdatac->vs->g_display_link && fdatac->active && fdatac->vs->current_link != -1 && fdatac->vs->current_link == goi->goti.link_num) { - draw_frame_mark(fdatac->ses->term->dev,x,y,goi->goti.go.xw, - goi->goti.go.yw,color_bg,color_fg,2); + long fg = image_foregronud(cimg); + draw_frame_mark(fdatac->ses->term->dev, x, y, goi->goti.go.xw, + goi->goti.go.yw, fg, fg, 2); restrict_clip_area(fdatac->ses->term->dev, &r, x + 2, y + 2, x + goi->goti.go.xw - 2, y + goi->goti.go.yw - 2); } @@ -933,14 +940,16 @@ static void img_draw_image(struct f_data_c *fdatac, struct g_object *goi_, int x if (img_process_download(goi, fdatac)) goto ret; /* Choked with data, will not * draw. */ /* Now we will only draw... */ - if (!cimg || cimg->state<12){ - draw_frame_mark(fdatac->ses->term->dev,x,y,goi->goti.go.xw, - goi->goti.go.yw,color_bg,color_fg,!cimg || cimg->state&1); + if (!cimg || cimg->state < 12) { + long fg = image_foregronud(cimg); + long bg = image_backgronud(cimg); + draw_frame_mark(fdatac->ses->term->dev, x, y, goi->goti.go.xw, + goi->goti.go.yw, bg, fg, !cimg || cimg->state & 1); } else { update_bitmap(cimg); - draw_picture(fdatac,goi,x,y,color_bg); + draw_picture(fdatac, goi, x, y); } - ret: + ret: set_clip_area(fdatac->ses->term->dev, &r); } diff --git a/kbd.c b/kbd.c @@ -77,7 +77,7 @@ retry: EINTRLOOP(l, (int)write(itrm->sock_out, itrm->ev_queue, to_write)); if (l <= 0) { if (to_write > 1) { - to_write >>= 2; + to_write >>= 1; goto retry; } itrm_error(itrm); @@ -144,11 +144,9 @@ static void send_term_sequence(int h, int flags) hard_write(h, term_seq_x_mouse, (int)strlen(cast_const_char term_seq_x_mouse)); } -static void resize_terminal(void) +static void resize_terminal(int x, int y) { struct links_event ev = { EV_RESIZE, 0, 0, 0 }; - int x, y; - if (get_terminal_size(ditrm->std_out, &x, &y)) return; ev.x = x; ev.y = y; queue_event(ditrm, (unsigned char *)&ev, sizeof(struct links_event)); @@ -281,15 +279,10 @@ static void setcooked(int ctl) void handle_trm(int sock_out, void *init_string, int init_len) { - int x, y; struct itrm *itrm; - struct links_event ev = { EV_INIT, 80, 24, 0 }; + struct links_event ev = { EV_INIT, 0, 0, 0 }; unsigned char *ts; int xwin, def_charset; - if (get_terminal_size(0, &x, &y)) { - error("ERROR: could not get terminal size"); - return; - } itrm = xmalloc(sizeof(struct itrm)); itrm->queue_event = queue_event; itrm->free_trm = free_trm; @@ -306,9 +299,7 @@ void handle_trm(int sock_out, void *init_string, int init_len) itrm->eqlen = 0; setraw(itrm->ctl_in, 1); set_handlers(0, in_kbd, NULL, itrm); - ev.x = x; - ev.y = y; - handle_terminal_resize(0, resize_terminal); + handle_terminal_resize(resize_terminal, &ev.x, &ev.y); queue_event(itrm, (unsigned char *)&ev, sizeof(struct links_event)); xwin = is_xterm() * ENV_XWIN + is_screen() * ENV_SCREEN; itrm->flags = 0; @@ -347,15 +338,16 @@ void handle_trm(int sock_out, void *init_string, int init_len) int unblock_itrm(int fd) { struct itrm *itrm = ditrm; + int x, y; if (!itrm) return -1; if (setraw(itrm->ctl_in, 0)) return -1; if (itrm->blocked != fd + 1) return -2; itrm->blocked = 0; send_init_sequence(itrm->std_out, itrm->flags); set_handlers(itrm->std_in, in_kbd, NULL, itrm); - handle_terminal_resize(itrm->ctl_in, resize_terminal); + handle_terminal_resize(resize_terminal, &x, &y); itrm->mouse_h = NULL; - resize_terminal(); + resize_terminal(x, y); return 0; } @@ -365,7 +357,7 @@ void block_itrm(int fd) if (!itrm) return; if (itrm->blocked) return; itrm->blocked = fd + 1; - unhandle_terminal_resize(itrm->ctl_in); + unhandle_terminal_resize(); itrm->mouse_h = NULL; send_term_sequence(itrm->std_out, itrm->flags); setcooked(itrm->ctl_in); @@ -378,7 +370,7 @@ static void free_trm(struct itrm *itrm) set_window_title(itrm->orig_title); free(itrm->orig_title); itrm->orig_title = NULL; - unhandle_terminal_resize(itrm->ctl_in); + unhandle_terminal_resize(); send_term_sequence(itrm->std_out, itrm->flags); setcooked(itrm->ctl_in); set_handlers(itrm->std_in, NULL, NULL, NULL); @@ -392,12 +384,22 @@ static void free_trm(struct itrm *itrm) if (itrm == ditrm) ditrm = NULL; } +static void refresh_terminal_size(void) +{ + int new_x, new_y; + if (!ditrm->blocked) { + unhandle_terminal_resize(); + handle_terminal_resize(resize_terminal, &new_x, &new_y); + resize_terminal(new_x, new_y); + } +} + static void resize_terminal_x(unsigned char *text) { unsigned char *p; if (!(p = cast_uchar strchr(cast_const_char text, ','))) return; *p++ = 0; - resize_terminal(); + refresh_terminal_size(); } void dispatch_special(unsigned char *text) @@ -443,8 +445,13 @@ static void kbd_timeout(void *itrm_) internal("timeout on empty queue"); return; } + if (itrm->kqueue[0] != 27) { + len = 1; + goto skip_esc; + } itrm->queue_event(itrm, (unsigned char *)&ev, sizeof(struct links_event)); if (get_esc_code(itrm->kqueue, itrm->qlen, &code, &num, &len)) len = 1; + skip_esc: itrm->qlen -= len; memmove(itrm->kqueue, itrm->kqueue + len, itrm->qlen); while (process_queue(itrm)) @@ -466,298 +473,6 @@ static int get_esc_code(unsigned char *str, int len, unsigned char *code, int *n return -1; } -/* -struct os2_key { - int x, y; -}; -*/ - -struct os2_key os2xtd[256] = { -/* 0 */ -{0,0}, -{0,0}, -{' ',KBD_CTRL}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{KBD_BS,KBD_ALT}, -{0,0}, -/* 16 */ -{'Q',KBD_ALT}, -{'W',KBD_ALT}, -{'E',KBD_ALT}, -{'R',KBD_ALT}, -{'T',KBD_ALT}, -{'Y',KBD_ALT}, -{'U',KBD_ALT}, -{'I',KBD_ALT}, -/* 24 */ -{'O',KBD_ALT}, -{'P',KBD_ALT}, -{'[',KBD_ALT}, -{']',KBD_ALT}, -{KBD_ENTER,KBD_ALT}, -{0,0}, -{'A',KBD_ALT}, -{'S',KBD_ALT}, -/* 32 */ -{'D',KBD_ALT}, -{'F',KBD_ALT}, -{'G',KBD_ALT}, -{'H',KBD_ALT}, -{'J',KBD_ALT}, -{'K',KBD_ALT}, -{'L',KBD_ALT}, -{';',KBD_ALT}, -/* 40 */ -{'\'',KBD_ALT}, -{'`',KBD_ALT}, -{0,0}, -{'\\',KBD_ALT}, -{'Z',KBD_ALT}, -{'X',KBD_ALT}, -{'C',KBD_ALT}, -{'V',KBD_ALT}, -/* 48 */ -{'B',KBD_ALT}, -{'N',KBD_ALT}, -{'M',KBD_ALT}, -{',',KBD_ALT}, -{'.',KBD_ALT}, -{'/',KBD_ALT}, -{0,0}, -{'*',KBD_ALT}, -/* 56 */ -{0,0}, -{' ',KBD_ALT}, -{0,0}, -{KBD_F1,0}, -{KBD_F2,0}, -{KBD_F3,0}, -{KBD_F4,0}, -{KBD_F5,0}, -/* 64 */ -{KBD_F6,0}, -{KBD_F7,0}, -{KBD_F8,0}, -{KBD_F9,0}, -{KBD_F10,0}, -{0,0}, -{0,0}, -{KBD_HOME,0}, -/* 72 */ -{KBD_UP,0}, -{KBD_PAGE_UP,0}, -{'-',KBD_ALT}, -{KBD_LEFT,0}, -{'5',0}, -{KBD_RIGHT,0}, -{'+',KBD_ALT}, -{KBD_END,0}, -/* 80 */ -{KBD_DOWN,0}, -{KBD_PAGE_DOWN,0}, -{KBD_INS,0}, -{KBD_DEL,0}, -{KBD_F1,KBD_SHIFT}, -{KBD_F2,KBD_SHIFT}, -{KBD_F3,KBD_SHIFT}, -{KBD_F4,KBD_SHIFT}, -/* 88 */ -{KBD_F5,KBD_SHIFT}, -{KBD_F6,KBD_SHIFT}, -{KBD_F7,KBD_SHIFT}, -{KBD_F8,KBD_SHIFT}, -{KBD_F9,KBD_SHIFT}, -{KBD_F10,KBD_SHIFT}, -{KBD_F1,KBD_CTRL}, -{KBD_F2,KBD_CTRL}, -/* 96 */ -{KBD_F3,KBD_CTRL}, -{KBD_F4,KBD_CTRL}, -{KBD_F5,KBD_CTRL}, -{KBD_F6,KBD_CTRL}, -{KBD_F7,KBD_CTRL}, -{KBD_F8,KBD_CTRL}, -{KBD_F9,KBD_CTRL}, -{KBD_F10,KBD_CTRL}, -/* 104 */ -{KBD_F1,KBD_ALT}, -{KBD_F2,KBD_ALT}, -{KBD_F3,KBD_ALT}, -{KBD_F4,KBD_ALT}, -{KBD_F5,KBD_ALT}, -{KBD_F6,KBD_ALT}, -{KBD_F7,KBD_ALT}, -{KBD_F8,KBD_ALT}, -/* 112 */ -{KBD_F9,KBD_ALT}, -{KBD_F10,KBD_ALT}, -{0,0}, -{KBD_LEFT,KBD_CTRL}, -{KBD_RIGHT,KBD_CTRL}, -{KBD_END,KBD_CTRL}, -{KBD_PAGE_DOWN,KBD_CTRL}, -{KBD_HOME,KBD_CTRL}, -/* 120 */ -{'1',KBD_ALT}, -{'2',KBD_ALT}, -{'3',KBD_ALT}, -{'4',KBD_ALT}, -{'5',KBD_ALT}, -{'6',KBD_ALT}, -{'7',KBD_ALT}, -{'8',KBD_ALT}, -/* 128 */ -{'9',KBD_ALT}, -{'0',KBD_ALT}, -{'-',KBD_ALT}, -{'=',KBD_ALT}, -{KBD_PAGE_UP,KBD_CTRL}, -{KBD_F11,0}, -{KBD_F12,0}, -{KBD_F11,KBD_SHIFT}, -/* 136 */ -{KBD_F12,KBD_SHIFT}, -{KBD_F11,KBD_CTRL}, -{KBD_F12,KBD_CTRL}, -{KBD_F11,KBD_ALT}, -{KBD_F12,KBD_ALT}, -{KBD_UP,KBD_CTRL}, -{'-',KBD_CTRL}, -{'5',KBD_CTRL}, -/* 144 */ -{'+',KBD_CTRL}, -{KBD_DOWN,KBD_CTRL}, -{KBD_INS,KBD_CTRL}, -{KBD_DEL,KBD_CTRL}, -{KBD_TAB,KBD_CTRL}, -{0,0}, -{0,0}, -{KBD_HOME,KBD_ALT}, -/* 152 */ -{KBD_UP,KBD_ALT}, -{KBD_PAGE_UP,KBD_ALT}, -{0,0}, -{KBD_LEFT,KBD_ALT}, -{0,0}, -{KBD_RIGHT,KBD_ALT}, -{0,0}, -{KBD_END,KBD_ALT}, -/* 160 */ -{KBD_DOWN,KBD_ALT}, -{KBD_PAGE_DOWN,KBD_ALT}, -{KBD_INS,KBD_ALT}, -{KBD_DEL,KBD_ALT}, -{0,0}, -{KBD_TAB,KBD_ALT}, -{KBD_ENTER,KBD_ALT}, -{0,0}, -/* 168 */ -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -/* 176 */ -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -/* 192 */ -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -/* 208 */ -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -/* 224 */ -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -/* 240 */ -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -{0,0}, -/* 256 */ -}; - static int xterm_button = -1; static int process_queue(struct itrm *itrm) @@ -858,7 +573,7 @@ static int process_queue(struct itrm *itrm) case 201: itrm->flags &= ~BRACKETED_PASTE; break; } break; case 'R': - resize_terminal(); + refresh_terminal_size(); break; case 'M': case '<': @@ -967,11 +682,7 @@ static int process_queue(struct itrm *itrm) } goto l1; } else if (itrm->kqueue[0] == 0) { - if (itrm->qlen < 2) goto ret; - if (!(ev.x = os2xtd[itrm->kqueue[1]].x)) ev.x = -1; - ev.y = os2xtd[itrm->kqueue[1]].y; - el = 2; - /*printf("%02x - %02x %02x\n", (int)itrm->kqueue[1], ev.x, ev.y);*/ + el = 1; goto l1; } el = 1; diff --git a/language.h b/language.h @@ -121,566 +121,574 @@ #define T_HTTPS_PROXY__HOST_PORT 118 #define T_SOCKS_4A_PROXY__USER_HOST_PORT 119 #define T_APPEND_TEXT_TO_SOCKS_LOOKUPS 120 -#define T_ONLY_PROXIES 121 -#define T_NOPROXY_LIST 122 -#define T_SSL_OPTIONS 123 -#define T_ACCEPT_INVALID_CERTIFICATES 124 -#define T_WARN_ON_INVALID_CERTIFICATES 125 -#define T_REJECT_INVALID_CERTIFICATES 126 -#define T_USE_BUILT_IN_CERTIFICATES 127 -#define T_CLIENT_CERTIFICATE_KEY_FILE 128 -#define T_CLIENT_CERTIFICATE_FILE 129 -#define T_CLIENT_CERTIFICATE_KEY_PASSWORD 130 -#define T_BAD_FILE 131 -#define T_THE_FILE_DOES_NOT_EXIST 132 -#define T_THE_FILE_HAS_INVALID_FORMAT 133 -#define T_ERROR_INITIALIZING_BUILT_IN_CERTIFICATES 134 -#define T_FAILED 135 -#define T_CONNECTIONS 136 -#define T_MAX_CONNECTIONS 137 -#define T_MAX_CONNECTIONS_TO_ONE_HOST 138 -#define T_RETRIES 139 -#define T_RECEIVE_TIMEOUT_SEC 140 -#define T_TIMEOUT_WHEN_UNRESTARTABLE 141 -#define T_TIMEOUT_WHEN_TRYING_MULTIPLE_ADDRESSES 142 -#define T_BIND_TO_LOCAL_IP_ADDRESS 143 -#define T_BIND_TO_LOCAL_IPV6_ADDRESS 144 -#define T_ASYNC_DNS_LOOKUP 145 -#define T_SET_TIME_OF_DOWNLOADED_FILES 146 -#define T_CACHE_OPTIONS 147 -#define T_MEMORY_CACHE_SIZE__KB 148 -#define T_IMAGE_CACHE_SIZE__KB 149 -#define T_FONT_CACHE_SIZE__KB 150 -#define T_NUMBER_OF_FORMATTED_DOCUMENTS 151 -#define T_AGGRESSIVE_CACHE 152 -#define T_HTML_OPTIONS 153 -#define T_DISPLAY_TABLES 154 -#define T_DISPLAY_FRAMES 155 -#define T_BREAK_LONG_LINES 156 -#define T_DISPLAY_IMAGES 157 -#define T_DISPLAY_IMAGE_FILENAMES 158 -#define T_DISPLAY_LINKS_TO_IMAGES 159 -#define T_LINK_ORDER_BY_COLUMNS 160 -#define T_NUMBERED_LINKS 161 -#define T_AUTO_REFRESH 162 -#define T_TARGET_IN_NEW_WINDOW 163 -#define T_TEXT_MARGIN 164 -#define T_DEFAULT_CODEPAGE 165 -#define T_IGNORE_CHARSET_INFO_SENT_BY_SERVER 166 -#define T_TEXT_COLOR 167 -#define T_LINK_COLOR 168 -#define T_BACKGROUND_COLOR 169 -#define T_IGNORE_DOCUMENT_COLOR 170 -#define T_COLOR_0 171 -#define T_COLOR_1 172 -#define T_COLOR_2 173 -#define T_COLOR_3 174 -#define T_COLOR_4 175 -#define T_COLOR_5 176 -#define T_COLOR_6 177 -#define T_COLOR_7 178 -#define T_COLOR_8 179 -#define T_COLOR_9 180 -#define T_COLOR_10 181 -#define T_COLOR_11 182 -#define T_COLOR_12 183 -#define T_COLOR_13 184 -#define T_COLOR_14 185 -#define T_COLOR_15 186 -#define T_GOTO_URL 187 -#define T_GO_BACK 188 -#define T_GO_FORWARD 189 -#define T_HISTORY 190 -#define T_RELOAD 191 -#define T_NEW_WINDOW 192 -#define T_SAVE_AS 193 -#define T_SAVE_URL_AS 194 -#define T_SAVE_FORMATTED_DOCUMENT 195 -#define T_COPY_URL_LOCATION 196 -#define T_KILL_BACKGROUND_CONNECTIONS 197 -#define T_KILL_ALL_CONNECTIONS 198 -#define T_FLUSH_ALL_CACHES 199 -#define T_RESOURCE_INFO 200 -#define T_OS_SHELL 201 -#define T_EXIT 202 -#define T_SEARCH 203 -#define T_SEARCH_BACK 204 -#define T_FIND_NEXT 205 -#define T_FIND_PREVIOUS 206 -#define T_TOGGLE_HTML_PLAIN 207 -#define T_DOCUMENT_INFO 208 -#define T_FRAME_AT_FULL_SCREEN 209 -#define T_SAVE_HTML_OPTIONS 210 -#define T_CHARACTER_SET 211 -#define T_DEFAULT_CHARSET 212 -#define T_CACHE 213 -#define T_MAIL_AND_TELNEL 214 -#define T_MAIL_TELNET_AND_SHELL 215 -#define T_ASSOCIATIONS 216 -#define T_FILE_EXTENSIONS 217 -#define T_SAVE_OPTIONS 218 -#define T_FILE 219 -#define T_VIEW 220 -#define T_LINK 221 -#define T_DOWNLOADS 222 -#define T_WINDOWS 223 -#define T_SETUP 224 -#define T_HELP 225 -#define T_ENTER_URL 226 -#define T_SAVE_URL 227 -#define T_DOWNLOAD 228 -#define T_SAVE_TO_FILE 229 -#define T_SEARCH_FOR_TEXT 230 -#define T_PAGE_P 231 -#define T_PAGE_OF 232 -#define T_PAGE_CL 233 -#define T_FORMATTING_DOCUMENT 234 -#define T_SEARCHING 235 -#define T_WAITING_IN_QUEUE 236 -#define T_LOOKING_UP_HOST 237 -#define T_MAKING_CONNECTION 238 -#define T_MAKING_CONNECTION_TO_ANOTHER_ADDRESS 239 -#define T_SOCKS_NEGOTIATION 240 -#define T_SSL_NEGOTIATION 241 -#define T_REQUEST_SENT 242 -#define T_LOGGING_IN 243 -#define T_GETTING_HEADERS 244 -#define T_SERVER_IS_PROCESSING_REQUEST 245 -#define T_TRANSFERRING 246 -#define T_INTERRUPTED 247 -#define T_SOCKET_EXCEPTION 248 -#define T_INTERNAL_ERROR 249 -#define T_OUT_OF_MEMORY 250 -#define T_HOST_NOT_FOUND 251 -#define T_PROXY_NOT_FOUND 252 -#define T_ERROR_WRITING_TO_SOCKET 253 -#define T_ERROR_READING_FROM_SOCKET 254 -#define T_DATA_MODIFIED 255 -#define T_BAD_URL_SYNTAX 256 -#define T_BAD_PROXY_SYNTAX 257 -#define T_RECEIVE_TIMEOUT 258 -#define T_REQUEST_MUST_BE_RESTARTED 259 -#define T_CANT_GET_SOCKET_STATE 260 -#define T_CYCLIC_REDIRECT 261 -#define T_TOO_LARGE_FILE 262 -#define T_BAD_HTTP_RESPONSE 263 -#define T_HTTP_100 264 -#define T_NO_CONTENT 265 -#define T_HTTPS_FWD_ERROR 266 -#define T_INVALID_CERTIFICATE 267 -#define T_DOWNGRADED_METHOD 268 -#define T_INSECURE_CIPHER 269 -#define T_UNKNOWN_FILE_TYPE 270 -#define T_ERROR_OPENING_FILE 271 -#define T_BAD_FTP_RESPONSE 272 -#define T_FTP_SERVICE_UNAVAILABLE 273 -#define T_BAD_FTP_LOGIN 274 -#define T_FTP_PORT_COMMAND_FAILED 275 -#define T_FILE_NOT_FOUND 276 -#define T_FTP_FILE_ERROR 277 -#define T_SSL_ERROR 278 -#define T_NO_SSL 279 -#define T_BAD_SOCKS_VERSION 280 -#define T_SOCKS_REJECTED_OR_FAILED 281 -#define T_SOCKS_NO_IDENTD 282 -#define T_SOCKS_BAD_USERID 283 -#define T_SOCKS_UNKNOWN_ERROR 284 -#define T_NO_SMB_CLIENT 285 -#define T_BLOCKED_URL 286 -#define T_SMB_NOT_ALLOWED 287 -#define T_FILE_NOT_ALLOWED 288 -#define T_NO_PROXY 289 -#define T_UNKNOWN_ERROR 290 -#define T_RECEIVED 291 -#define T_OF 292 -#define T_AVG 293 -#define T_CUR 294 -#define T_AVERAGE_SPEED 295 -#define T_SPEED 296 -#define T_CURRENT_SPEED 297 -#define T_ELAPSED_TIME 298 -#define T_ESTIMATED_TIME 299 -#define T_BACKGROUND 300 -#define T_ABORT 301 -#define T_ABORT_AND_DELETE_FILE 302 -#define T_YES 303 -#define T_NO 304 -#define T_DIRECTORY 305 -#define T_FILE_ALREADY_EXISTS 306 -#define T_ALREADY_EXISTS_AS_DOWNLOAD 307 -#define T_ALREADY_EXISTS 308 -#define T_DO_YOU_WISH_TO_CONTINUE 309 -#define T_DO_YOU_WISH_TO_OVERWRITE 310 -#define T_CONTINUE 311 -#define T_OVERWRITE 312 -#define T_RENAME 313 -#define T_DOWNLOAD_ERROR 314 -#define T_COULD_NOT_WRITE_TO_FILE 315 -#define T_ERROR_DOWNLOADING 316 -#define T_ERROR_LOADING 317 -#define T_COULD_NOT_CREATE_FILE 318 -#define T_COULD_NOT_CREATE_TEMPORARY_FILE 319 -#define T_ERROR_CALLING_LSEEK_ON_FILE 320 -#define T_TOO_LARGE_FILE_SEQUENCE 321 -#define T_UNKNOWN_TYPE 322 -#define T_CONTENT_TYPE_IS 323 -#define T_DO_YOU_WANT_TO_OPEN_SAVE_OR_DISPLAY_THIS_FILE 324 -#define T_DO_YOU_WANT_TO_OPEN_OR_DISPLAY_THIS_FILE 325 -#define T_DO_YOU_WANT_TO_SAVE_OR_DISLPAY_THIS_FILE 326 -#define T_SAVE 327 -#define T_DISPLAY 328 -#define T_WHAT_TO_DO 329 -#define T_DO_YOU_WANT_TO_OPEN_FILE_WITH 330 -#define T_SAVE_IT_OR_DISPLAY_IT 331 -#define T_OPEN 332 -#define T_OPEN_WITH 333 -#define T_DO_YOU_WANT_TO_FOLLOW_REDIRECT_AND_POST_FORM_DATA_TO_URL 334 -#define T_DO_YOU_WANT_TO_POST_FORM_DATA_TO_URL 335 -#define T_DO_YOU_WANT_TO_REPOST_FORM_DATA_TO_URL 336 -#define T_WARNING 337 -#define T_ERROR 338 -#define T_WELCOME 339 -#define T_WELCOME_TO_LINKS 340 -#define T_BASIC_HELP 341 -#define T_LABEL 342 -#define T_CONTENT_TYPES 343 -#define T_PROGRAM__IS_REPLACED_WITH_FILE_NAME 344 -#define T_BLOCK_TERMINAL_WHILE_PROGRAM_RUNNING 345 -#define T_RUN_ON_TERMINAL 346 -#define T_RUN_IN_XWINDOW 347 -#define T_ASK_BEFORE_OPENING 348 -#define T_ACCEPT_HTTP 349 -#define T_ACCEPT_FTP 350 -#define T_DELETE_ASSOCIATION 351 -#define T_ASSOCIATION 352 -#define T_EXTENSION_S 353 -#define T_CONTENT_TYPE 354 -#define T_DELETE_EXTENSION 355 -#define T_EXTENSION 356 -#define T_eXTENSION 357 -#define T_ERROR_WHILE_POSTING_FORM 358 -#define T_COULD_NOT_GET_FILE 359 -#define T_READING_FILES_IS_NOT_ALLOWED 360 -#define T_NO_PREVIOUS_SEARCH 361 -#define T_SEARCH_STRING_NOT_FOUND 362 -#define T_SAVE_ERROR 363 -#define T_ERROR_WRITING_TO_FILE 364 -#define T_DISPLAY_USEMAP 365 -#define T_FOLLOW_LINK 366 -#define T_OPEN_IN_NEW_WINDOW 367 -#define T_DOWNLOAD_LINK 368 -#define T_RESET_FORM 369 -#define T_SUBMIT_FORM 370 -#define T_SUBMIT_FORM_AND_OPEN_IN_NEW_WINDOW 371 -#define T_SUBMIT_FORM_AND_DOWNLOAD 372 -#define T_VIEW_IMAGE 373 -#define T_DOWNLOAD_IMAGE 374 -#define T_SCALE_IMAGE_TO_FULL_SCREEN 375 -#define T_NO_LINK_SELECTED 376 -#define T_IMAGE 377 -#define T_USEMAP 378 -#define T_XTERM 379 -#define T_TWTERM 380 -#define T_SCREEN 381 -#define T_WINDOW 382 -#define T_FULL_SCREEN 383 -#define T_BEOS_TERMINAL 384 -#define T_UNABLE_TO_OPEN_NEW_WINDOW 385 -#define T_JAVASCRIPT 386 -#define T_SUBMIT_FORM_TO 387 -#define T_POST_FORM_TO 388 -#define T_RADIO_BUTTON 389 -#define T_CHECKBOX 390 -#define T_SELECT_FIELD 391 -#define T_TEXT_FIELD 392 -#define T_TEXT_AREA 393 -#define T_FILE_UPLOAD 394 -#define T_PASSWORD_FIELD 395 -#define T_BUTTON 396 -#define T_NAME 397 -#define T_VALUE 398 -#define T_HIT_ENTER_TO 399 -#define T_SUBMIT_TO 400 -#define T_POST_TO 401 -#define T_INFO 402 -#define T_HEADER_INFO 403 -#define T_YOU_ARE_NOWHERE 404 -#define T_NO_HEADER 405 -#define T_URL 406 -#define T_IP_ADDRESS 407 -#define T_IP_ADDRESSES 408 -#define T_SIZE 409 -#define T_COMPRESSED_WITH 410 -#define T_INCOMPLETE 411 -#define T_CODEPAGE 412 -#define T_ASSUMED 413 -#define T_IGNORING_SERVER_SETTING 414 -#define T_SERVER 415 -#define T_DATE 416 -#define T_LAST_MODIFIED 417 -#define T_SSL_CIPHER 418 -#define T_LANGUAGE 419 -#define T_DEFAULT_LANG 420 -#define T_GO_TO_LINK 421 -#define T_ENTER_LINK_NUMBER 422 -#define T_RESIZE_TERMINAL 423 -#define T_COLUMNS 424 -#define T_ROWS 425 -#define T_GOTO 426 -#define T_CLOSE 427 -#define T_FOLDER 428 -#define T_fOLDER 429 -#define T_ADD 430 -#define T_DELETE 431 -#define T_EDIT 432 -#define T_MOVE 433 -#define T_NO_ITEMS_SELECTED 434 -#define T_UNSELECT_ALL 435 -#define T_BOOKMARKS 436 -#define T_BOOKMARK 437 -#define T_ADD_BOOKMARK 438 -#define T_ADD_ASSOCIATION 439 -#define T_ADD_EXTENSION 440 -#define T_ADD_FOLDER 441 -#define T_BOOKMARK_TITLE 442 -#define T_EDIT_BOOKMARK 443 -#define T_EDIT_ASSOCIATION 444 -#define T_EDIT_EXTENSION 445 -#define T_DELETE_BOOKMARK 446 -#define T_EDIT_FOLDER 447 -#define T_DELETE_FOLDER 448 -#define T_NOT_EMPTY_SURE_DELETE 449 -#define T_BOOKMARK_MANAGER 450 -#define T_ASSOCIATIONS_MANAGER 451 -#define T_EXTENSIONS_MANAGER 452 -#define T_url 453 -#define T_NNAME 454 -#define T_EXIT_LINKS 455 -#define T_DO_YOU_REALLY_WANT_TO_CLOSE_WINDOW 456 -#define T_DO_YOU_REALLY_WANT_TO_EXIT_LINKS 457 -#define T_DO_YOU_REALLY_WANT_TO_EXIT_LINKS_AND_TERMINATE_ALL_DOWNLOADS 458 -#define T_HTTP_OPTIONS 459 -#define T_FTP_OPTIONS 460 -#define T_SMB_OPTIONS 461 -#define T_HTTP_BUG_WORKAROUNDS 462 -#define T_USE_HTTP_10 463 -#define T_ALLOW_SERVER_BLACKLIST 464 -#define T_DO_NOT_SEND_ACCEPT_CHARSET 465 -#define T_DO_NOT_ADVERTISE_COMPRESSION_SUPPORT 466 -#define T_RETRY_ON_INTERNAL_ERRORS 467 -#define T_HEADER_OPTIONS 468 -#define T_HTTP_HEADER_OPTIONS 469 -#define T_FAKE_FIREFOX 470 -#define T_DO_NOT_TRACK 471 -#define T_REFERER_NONE 472 -#define T_REFERER_SAME_URL 473 -#define T_REFERER_FAKE 474 -#define T_REFERER_REAL_SAME_SERVER 475 -#define T_REFERER_REAL 476 -#define T_FAKE_REFERER 477 -#define T_FAKE_USERAGENT 478 -#define T_EXTRA_HEADER 479 -#define T_PASSWORD_FOR_ANONYMOUS_LOGIN 480 -#define T_USE_PASSIVE_FTP 481 -#define T_USE_EPRT_EPSV 482 -#define T_SET_TYPE_OF_SERVICE 483 -#define T_ALLOW_HYPERLINKS_TO_SMB 484 -#define T_MANUAL 485 -#define T_HOMEPAGE 486 -#define T_CALIBRATION 487 -#define T_MAILTO_PROG 488 -#define T_SHELL_PROG 489 -#define T_TELNET_PROG 490 -#define T_MAGNET_PROG 491 -#define T_TN3270_PROG 492 -#define T_MMS_PROG 493 -#define T_MAIL_AND_TELNET_PROGRAMS 494 -#define T_MAIL_TELNET_AND_SHELL_PROGRAMS 495 -#define T_NO_PROGRAM 496 -#define T_NO_PROGRAM_SPECIFIED_FOR 497 -#define T_MAIL 498 -#define T_TELNET 499 -#define T_MAGNET 500 -#define T_TN3270 501 -#define T_MMS 502 -#define T_BAD_MAILTO_URL 503 -#define T_BAD_TELNET_URL 504 -#define T_BAD_TN3270_URL 505 -#define T_MMS_URL_CONTAINS_INACCEPTABLE_CHARACTERS 506 -#define T_AUTHORIZATION_REQUIRED 507 -#define T_PROXY_AUTHORIZATION_REQUIRED 508 -#define T_USERID 509 -#define T_PASSWORD 510 -#define T_ENTER_USERNAME 511 -#define T_AT 512 -#define T_THE_SERVER_ 513 -#define T_DOESNT_HAVE_A_VALID_CERTIFICATE 514 -#define T_USES_DOWNGRADED_METHOD 515 -#define T_USES_INSECURE_CIPHER 516 -#define T_WAITING_FOR_REDIRECT_CONFIRMATION 517 -#define T_DECOMPRESSION_ERROR 518 -#define T_ERROR_DECOMPRESSING_ 519 -#define T__wITH_ 520 -#define T_COMPRESSED_ERROR 521 -#define T_UNKNOWN_COMPRESSION_METHOD 522 -#define T_SURE_DELETE 523 -#define T_BOOKMARKS_ALREADY_IN_USE 524 -#define T_ASSOCIATIONS_ALREADY_IN_USE 525 -#define T_EXTENSIONS_ALREADY_IN_USE 526 -#define T_VIDEO_OPTIONS 527 -#define T_VIDEO_OPTIONS_TEXT 528 -#define T_RED_DISPLAY_GAMMA 529 -#define T_GREEN_DISPLAY_GAMMA 530 -#define T_BLUE_DISPLAY_GAMMA 531 -#define T_USER_GAMMA 532 -#define T_ASPECT_RATIO 533 -#define T_DITHER_LETTERS 534 -#define T_DITHER_IMAGES 535 -#define T_8_BIT_GAMMA_CORRECTION 536 -#define T_16_BIT_GAMMA_CORRECTION 537 -#define T_AUTO_GAMMA_CORRECTION 538 -#define T_RGB_PALETTE_8x8x4 539 -#define T_RGB_PALETTE_6x6x6 540 -#define T_SWITCH_PALETTE 541 -#define T_OVERWRITE_SCREEN_INSTEAD_OF_SCROLLING_IT 542 -#define T_ALERT 543 -#define T_QUESTION 544 -#define T_KILL_SCRIPT 545 -#define T_KILL_ALL_SCRIPTS 546 -#define T_SCRIPT_KILLED_BY_USER 547 -#define T_SCRIPT_TRYING_TO_CLOSE_WINDOW 548 -#define T_ENTER_STRING 549 -#define T_JAVASCRIPT_OPTIONS 550 -#define T_ENABLE_JAVASCRIPT 551 -#define T_VERBOSE_JS_ERRORS 552 -#define T_VERBOSE_JS_WARNINGS 553 -#define T_MISCELANEOUS_OPTIONS 554 -#define T_JAVASCRIPT_ERROR 555 -#define T_JAVASCRIPT_WARNING 556 -#define T_DISMISS 557 -#define T_MENU_FONT_SIZE 558 -#define T_USER_FONT_SIZE 559 -#define T_TURN_OFF_WARNINGS 560 -#define T_BOOKMARKS_ENCODING 561 -#define T_JS_IS_ATTEMPTING_TO_GO_TO_URL 562 -#define T_JS_IS_ATTEMPTING_TO_OPEN_NEW_WINDOW_WITH_URL 563 -#define T_JS_IS_ATTEMPTING_TO_GO_INTO_HISTORY 564 -#define T_TO_URL 565 -#define T_GOTO_HISTORY 566 -#define T_ALLOW 567 -#define T_REJECT 568 -#define T_ENABLE_ALL_CONVERSIONS 569 -#define T_ENABLE_GLOBAL_NAME_RESOLUTION 570 -#define T_MANUAL_JS_CONTROL 571 -#define T_JS_RECURSION_DEPTH 572 -#define T_MENU_BACKGROUND_COLOR 573 -#define T_MENU_FOREGROUND_COLOR 574 -#define T_SCROLL_BAR_BAR_COLOR 575 -#define T_SCROLL_BAR_AREA_COLOR 576 -#define T_SCROLL_BAR_FRAME_COLOR 577 -#define T_BOOKMARKS_FILE 578 -#define T_SAVE_URL_HISTORY_ON_EXIT 579 -#define T_ENTER_COLORS_AS_RGB_TRIPLETS 580 -#define T_JS_MEMORY_LIMIT_KB 581 -#define T_SCALE_ALL_IMAGES_BY 582 -#define T_PORN_ENABLE 583 -#define T_DISPLAY_OPTIMIZATION_CRT 584 -#define T_DISPLAY_OPTIMIZATION_LCD_RGB 585 -#define T_DISPLAY_OPTIMIZATION_LCD_BGR 586 -#define T_KEYBOARD_CODEPAGE 587 -#define T_COPY_LINK_LOCATION 588 -#define T_BLOCK_URL 589 -#define T_BLOCK_LIST 590 -#define T_BLOCKED_IMAGE 591 -#define T_BLOCK_LIST_IN_USE 592 -#define T_BLOCK_LIST_MANAGER 593 -#define T_BLOCK_ADD 594 -#define T_BLOCK_EDIT 595 -#define T_BLOCK_DELETE 596 -#define T_HK_GOTO_URL 597 -#define T_HK_GO_BACK 598 -#define T_HK_GO_FORWARD 599 -#define T_HK_HISTORY 600 -#define T_HK_RELOAD 601 -#define T_HK_BOOKMARKS 602 -#define T_HK_NEW_WINDOW 603 -#define T_HK_SAVE_AS 604 -#define T_HK_SAVE_URL_AS 605 -#define T_HK_SAVE_FORMATTED_DOCUMENT 606 -#define T_HK_COPY_URL_LOCATION 607 -#define T_HK_KILL_BACKGROUND_CONNECTIONS 608 -#define T_HK_KILL_ALL_CONNECTIONS 609 -#define T_HK_FLUSH_ALL_CACHES 610 -#define T_HK_RESOURCE_INFO 611 -#define T_HK_MEMORY_INFO 612 -#define T_HK_OS_SHELL 613 -#define T_HK_RESIZE_TERMINAL 614 -#define T_HK_EXIT 615 -#define T_HK_SEARCH 616 -#define T_HK_SEARCH_BACK 617 -#define T_HK_FIND_NEXT 618 -#define T_HK_FIND_PREVIOUS 619 -#define T_HK_TOGGLE_HTML_PLAIN 620 -#define T_HK_DOCUMENT_INFO 621 -#define T_HK_HEADER_INFO 622 -#define T_HK_FRAME_AT_FULL_SCREEN 623 -#define T_HK_HTML_OPTIONS 624 -#define T_HK_COLOR 625 -#define T_HK_SAVE_HTML_OPTIONS 626 -#define T_HK_LANGUAGE 627 -#define T_HK_CHARACTER_SET 628 -#define T_HK_TERMINAL_OPTIONS 629 -#define T_HK_SCREEN_MARGINS 630 -#define T_HK_VIDEO_OPTIONS 631 -#define T_HK_NETWORK_OPTIONS 632 -#define T_HK_CONNECTIONS 633 -#define T_HK_IPV6_OPTIONS 634 -#define T_HK_PROXIES 635 -#define T_HK_SSL_OPTIONS 636 -#define T_HK_HTTP_OPTIONS 637 -#define T_HK_FTP_OPTIONS 638 -#define T_HK_SMB_OPTIONS 639 -#define T_HK_JAVASCRIPT_OPTIONS 640 -#define T_HK_MISCELANEOUS_OPTIONS 641 -#define T_HK_CACHE 642 -#define T_HK_MAIL_AND_TELNEL 643 -#define T_HK_ASSOCIATIONS 644 -#define T_HK_FILE_EXTENSIONS 645 -#define T_HK_BLOCK_LIST 646 -#define T_HK_SAVE_OPTIONS 647 -#define T_HK_ABOUT 648 -#define T_HK_KEYS 649 -#define T_HK_COPYING 650 -#define T_HK_MANUAL 651 -#define T_HK_HOMEPAGE 652 -#define T_HK_CALIBRATION 653 -#define T_HK_FILE 654 -#define T_HK_VIEW 655 -#define T_HK_LINK 656 -#define T_HK_DOWNLOADS 657 -#define T_HK_WINDOWS 658 -#define T_HK_SETUP 659 -#define T_HK_HELP 660 -#define T_HK_DISPLAY_USEMAP 661 -#define T_HK_FOLLOW_LINK 662 -#define T_HK_OPEN_IN_NEW_WINDOW 663 -#define T_HK_DOWNLOAD_LINK 664 -#define T_HK_RESET_FORM 665 -#define T_HK_SUBMIT_FORM 666 -#define T_HK_SUBMIT_FORM_AND_OPEN_IN_NEW_WINDOW 667 -#define T_HK_SUBMIT_FORM_AND_DOWNLOAD 668 -#define T_HK_VIEW_IMAGE 669 -#define T_HK_DOWNLOAD_IMAGE 670 -#define T_HK_SCALE_IMAGE_TO_FULL_SCREEN 671 -#define T_HK_COPY_LINK_LOCATION 672 -#define T_HK_BLOCK_URL 673 -#define T_HK_XTERM 674 -#define T_HK_TWTERM 675 -#define T_HK_SCREEN 676 -#define T_HK_WINDOW 677 -#define T_HK_FULL_SCREEN 678 -#define T_HK_BEOS_TERMINAL 679 -#define T_URL_MANUAL 680 -#define T_URL_HOMEPAGE 681 -#define T_URL_CALIBRATION 682 -#define T__N_TEXTS 683 +#define T_NOPROXY_LIST 121 +#define T_ONLY_PROXIES 122 +#define T_TOR_MODE_ENABLED 123 +#define T_SSL_OPTIONS 124 +#define T_ACCEPT_INVALID_CERTIFICATES 125 +#define T_WARN_ON_INVALID_CERTIFICATES 126 +#define T_REJECT_INVALID_CERTIFICATES 127 +#define T_USE_BUILT_IN_CERTIFICATES 128 +#define T_CLIENT_CERTIFICATE_KEY_FILE 129 +#define T_CLIENT_CERTIFICATE_FILE 130 +#define T_CLIENT_CERTIFICATE_KEY_PASSWORD 131 +#define T_BAD_FILE 132 +#define T_THE_FILE_DOES_NOT_EXIST 133 +#define T_THE_FILE_HAS_INVALID_FORMAT 134 +#define T_ERROR_INITIALIZING_BUILT_IN_CERTIFICATES 135 +#define T_FAILED 136 +#define T_CONNECTIONS 137 +#define T_MAX_CONNECTIONS 138 +#define T_MAX_CONNECTIONS_TO_ONE_HOST 139 +#define T_RETRIES 140 +#define T_RECEIVE_TIMEOUT_SEC 141 +#define T_TIMEOUT_WHEN_UNRESTARTABLE 142 +#define T_TIMEOUT_WHEN_TRYING_MULTIPLE_ADDRESSES 143 +#define T_BIND_TO_LOCAL_IP_ADDRESS 144 +#define T_BIND_TO_LOCAL_IPV6_ADDRESS 145 +#define T_ASYNC_DNS_LOOKUP 146 +#define T_SET_TIME_OF_DOWNLOADED_FILES 147 +#define T_CACHE_OPTIONS 148 +#define T_MEMORY_CACHE_SIZE__KB 149 +#define T_IMAGE_CACHE_SIZE__KB 150 +#define T_FONT_CACHE_SIZE__KB 151 +#define T_NUMBER_OF_FORMATTED_DOCUMENTS 152 +#define T_AGGRESSIVE_CACHE 153 +#define T_HTML_OPTIONS 154 +#define T_DISPLAY_TABLES 155 +#define T_DISPLAY_FRAMES 156 +#define T_BREAK_LONG_LINES 157 +#define T_DISPLAY_IMAGES 158 +#define T_DISPLAY_IMAGE_FILENAMES 159 +#define T_DISPLAY_LINKS_TO_IMAGES 160 +#define T_LINK_ORDER_BY_COLUMNS 161 +#define T_NUMBERED_LINKS 162 +#define T_AUTO_REFRESH 163 +#define T_TARGET_IN_NEW_WINDOW 164 +#define T_TEXT_MARGIN 165 +#define T_DEFAULT_CODEPAGE 166 +#define T_IGNORE_CHARSET_INFO_SENT_BY_SERVER 167 +#define T_TEXT_COLOR 168 +#define T_LINK_COLOR 169 +#define T_BACKGROUND_COLOR 170 +#define T_IGNORE_DOCUMENT_COLOR 171 +#define T_COLOR_0 172 +#define T_COLOR_1 173 +#define T_COLOR_2 174 +#define T_COLOR_3 175 +#define T_COLOR_4 176 +#define T_COLOR_5 177 +#define T_COLOR_6 178 +#define T_COLOR_7 179 +#define T_COLOR_8 180 +#define T_COLOR_9 181 +#define T_COLOR_10 182 +#define T_COLOR_11 183 +#define T_COLOR_12 184 +#define T_COLOR_13 185 +#define T_COLOR_14 186 +#define T_COLOR_15 187 +#define T_GOTO_URL 188 +#define T_GO_BACK 189 +#define T_GO_FORWARD 190 +#define T_HISTORY 191 +#define T_RELOAD 192 +#define T_NEW_WINDOW 193 +#define T_SAVE_AS 194 +#define T_SAVE_URL_AS 195 +#define T_SAVE_FORMATTED_DOCUMENT 196 +#define T_COPY_URL_LOCATION 197 +#define T_KILL_BACKGROUND_CONNECTIONS 198 +#define T_KILL_ALL_CONNECTIONS 199 +#define T_FLUSH_ALL_CACHES 200 +#define T_RESOURCE_INFO 201 +#define T_OS_SHELL 202 +#define T_EXIT 203 +#define T_SEARCH 204 +#define T_SEARCH_BACK 205 +#define T_FIND_NEXT 206 +#define T_FIND_PREVIOUS 207 +#define T_TOGGLE_HTML_PLAIN 208 +#define T_DOCUMENT_INFO 209 +#define T_FRAME_AT_FULL_SCREEN 210 +#define T_SAVE_CLIPBOARD_TO_A_FILE 211 +#define T_LOAD_CLIPBOARD_FROM_A_FILE 212 +#define T_THE_CLIPBOARD_IS_EMPTY 213 +#define T_SAVE_HTML_OPTIONS 214 +#define T_CHARACTER_SET 215 +#define T_DEFAULT_CHARSET 216 +#define T_CACHE 217 +#define T_MAIL_AND_TELNEL 218 +#define T_MAIL_TELNET_AND_SHELL 219 +#define T_ASSOCIATIONS 220 +#define T_FILE_EXTENSIONS 221 +#define T_SAVE_OPTIONS 222 +#define T_FILE 223 +#define T_VIEW 224 +#define T_LINK 225 +#define T_DOWNLOADS 226 +#define T_WINDOWS 227 +#define T_SETUP 228 +#define T_HELP 229 +#define T_ENTER_URL 230 +#define T_SAVE_URL 231 +#define T_DOWNLOAD 232 +#define T_SAVE_TO_FILE 233 +#define T_SEARCH_FOR_TEXT 234 +#define T_PAGE_P 235 +#define T_PAGE_OF 236 +#define T_PAGE_CL 237 +#define T_FORMATTING_DOCUMENT 238 +#define T_SEARCHING 239 +#define T_WAITING_IN_QUEUE 240 +#define T_LOOKING_UP_HOST 241 +#define T_MAKING_CONNECTION 242 +#define T_MAKING_CONNECTION_TO_ANOTHER_ADDRESS 243 +#define T_SOCKS_NEGOTIATION 244 +#define T_SSL_NEGOTIATION 245 +#define T_REQUEST_SENT 246 +#define T_LOGGING_IN 247 +#define T_GETTING_HEADERS 248 +#define T_SERVER_IS_PROCESSING_REQUEST 249 +#define T_TRANSFERRING 250 +#define T_INTERRUPTED 251 +#define T_SOCKET_EXCEPTION 252 +#define T_INTERNAL_ERROR 253 +#define T_OUT_OF_MEMORY 254 +#define T_HOST_NOT_FOUND 255 +#define T_PROXY_NOT_FOUND 256 +#define T_ERROR_WRITING_TO_SOCKET 257 +#define T_ERROR_READING_FROM_SOCKET 258 +#define T_DATA_MODIFIED 259 +#define T_BAD_URL_SYNTAX 260 +#define T_BAD_PROXY_SYNTAX 261 +#define T_RECEIVE_TIMEOUT 262 +#define T_REQUEST_MUST_BE_RESTARTED 263 +#define T_CANT_GET_SOCKET_STATE 264 +#define T_CYCLIC_REDIRECT 265 +#define T_TOO_LARGE_FILE 266 +#define T_BAD_HTTP_RESPONSE 267 +#define T_HTTP_100 268 +#define T_NO_CONTENT 269 +#define T_HTTPS_FWD_ERROR 270 +#define T_INVALID_CERTIFICATE 271 +#define T_DOWNGRADED_METHOD 272 +#define T_INSECURE_CIPHER 273 +#define T_UNKNOWN_FILE_TYPE 274 +#define T_ERROR_OPENING_FILE 275 +#define T_BAD_FTP_RESPONSE 276 +#define T_FTP_SERVICE_UNAVAILABLE 277 +#define T_BAD_FTP_LOGIN 278 +#define T_FTP_PORT_COMMAND_FAILED 279 +#define T_FILE_NOT_FOUND 280 +#define T_FTP_FILE_ERROR 281 +#define T_SSL_ERROR 282 +#define T_NO_SSL 283 +#define T_BAD_SOCKS_VERSION 284 +#define T_SOCKS_REJECTED_OR_FAILED 285 +#define T_SOCKS_NO_IDENTD 286 +#define T_SOCKS_BAD_USERID 287 +#define T_SOCKS_UNKNOWN_ERROR 288 +#define T_NO_SMB_CLIENT 289 +#define T_BLOCKED_URL 290 +#define T_SMB_NOT_ALLOWED 291 +#define T_FILE_NOT_ALLOWED 292 +#define T_NO_PROXY 293 +#define T_UNKNOWN_ERROR 294 +#define T_RECEIVED 295 +#define T_OF 296 +#define T_AVG 297 +#define T_CUR 298 +#define T_AVERAGE_SPEED 299 +#define T_SPEED 300 +#define T_CURRENT_SPEED 301 +#define T_ELAPSED_TIME 302 +#define T_ESTIMATED_TIME 303 +#define T_BACKGROUND 304 +#define T_ABORT 305 +#define T_ABORT_AND_DELETE_FILE 306 +#define T_YES 307 +#define T_NO 308 +#define T_NEVER 309 +#define T_DIRECTORY 310 +#define T_FILE_ALREADY_EXISTS 311 +#define T_ALREADY_EXISTS_AS_DOWNLOAD 312 +#define T_ALREADY_EXISTS 313 +#define T_DO_YOU_WISH_TO_CONTINUE 314 +#define T_DO_YOU_WISH_TO_OVERWRITE 315 +#define T_CONTINUE 316 +#define T_OVERWRITE 317 +#define T_RENAME 318 +#define T_DOWNLOAD_ERROR 319 +#define T_COULD_NOT_WRITE_TO_FILE 320 +#define T_ERROR_DOWNLOADING 321 +#define T_ERROR_LOADING 322 +#define T_COULD_NOT_CREATE_FILE 323 +#define T_COULD_NOT_CREATE_TEMPORARY_FILE 324 +#define T_ERROR_CALLING_LSEEK_ON_FILE 325 +#define T_TOO_LARGE_FILE_SEQUENCE 326 +#define T_UNKNOWN_TYPE 327 +#define T_CONTENT_TYPE_IS 328 +#define T_DO_YOU_WANT_TO_OPEN_SAVE_OR_DISPLAY_THIS_FILE 329 +#define T_DO_YOU_WANT_TO_OPEN_OR_DISPLAY_THIS_FILE 330 +#define T_DO_YOU_WANT_TO_SAVE_OR_DISLPAY_THIS_FILE 331 +#define T_SAVE 332 +#define T_DISPLAY 333 +#define T_WHAT_TO_DO 334 +#define T_DO_YOU_WANT_TO_OPEN_FILE_WITH 335 +#define T_SAVE_IT_OR_DISPLAY_IT 336 +#define T_OPEN 337 +#define T_OPEN_WITH 338 +#define T_DO_YOU_WANT_TO_FOLLOW_REDIRECT_AND_POST_FORM_DATA_TO_URL 339 +#define T_DO_YOU_WANT_TO_POST_FORM_DATA_TO_URL 340 +#define T_DO_YOU_WANT_TO_REPOST_FORM_DATA_TO_URL 341 +#define T_WARNING 342 +#define T_ERROR 343 +#define T_WELCOME 344 +#define T_WELCOME_TO_LINKS 345 +#define T_BASIC_HELP 346 +#define T_LABEL 347 +#define T_CONTENT_TYPES 348 +#define T_PROGRAM__IS_REPLACED_WITH_FILE_NAME 349 +#define T_BLOCK_TERMINAL_WHILE_PROGRAM_RUNNING 350 +#define T_RUN_ON_TERMINAL 351 +#define T_RUN_IN_XWINDOW 352 +#define T_ASK_BEFORE_OPENING 353 +#define T_ACCEPT_HTTP 354 +#define T_ACCEPT_FTP 355 +#define T_DELETE_ASSOCIATION 356 +#define T_ASSOCIATION 357 +#define T_EXTENSION_S 358 +#define T_CONTENT_TYPE 359 +#define T_DELETE_EXTENSION 360 +#define T_EXTENSION 361 +#define T_eXTENSION 362 +#define T_ERROR_WHILE_POSTING_FORM 363 +#define T_COULD_NOT_GET_FILE 364 +#define T_READING_FILES_IS_NOT_ALLOWED 365 +#define T_NO_PREVIOUS_SEARCH 366 +#define T_SEARCH_STRING_NOT_FOUND 367 +#define T_SAVE_ERROR 368 +#define T_ERROR_WRITING_TO_FILE 369 +#define T_ERROR_READING_THE_FILE 370 +#define T_DISPLAY_USEMAP 371 +#define T_FOLLOW_LINK 372 +#define T_OPEN_IN_NEW_WINDOW 373 +#define T_DOWNLOAD_LINK 374 +#define T_RESET_FORM 375 +#define T_SUBMIT_FORM 376 +#define T_SUBMIT_FORM_AND_OPEN_IN_NEW_WINDOW 377 +#define T_SUBMIT_FORM_AND_DOWNLOAD 378 +#define T_VIEW_IMAGE 379 +#define T_DOWNLOAD_IMAGE 380 +#define T_SCALE_IMAGE_TO_FULL_SCREEN 381 +#define T_NO_LINK_SELECTED 382 +#define T_IMAGE 383 +#define T_USEMAP 384 +#define T_XTERM 385 +#define T_TWTERM 386 +#define T_SCREEN 387 +#define T_WINDOW 388 +#define T_FULL_SCREEN 389 +#define T_BEOS_TERMINAL 390 +#define T_UNABLE_TO_OPEN_NEW_WINDOW 391 +#define T_JAVASCRIPT 392 +#define T_SUBMIT_FORM_TO 393 +#define T_POST_FORM_TO 394 +#define T_RADIO_BUTTON 395 +#define T_CHECKBOX 396 +#define T_SELECT_FIELD 397 +#define T_TEXT_FIELD 398 +#define T_TEXT_AREA 399 +#define T_FILE_UPLOAD 400 +#define T_PASSWORD_FIELD 401 +#define T_BUTTON 402 +#define T_NAME 403 +#define T_VALUE 404 +#define T_HIT_ENTER_TO 405 +#define T_SUBMIT_TO 406 +#define T_POST_TO 407 +#define T_INFO 408 +#define T_HEADER_INFO 409 +#define T_YOU_ARE_NOWHERE 410 +#define T_NO_HEADER 411 +#define T_URL 412 +#define T_IP_ADDRESS 413 +#define T_IP_ADDRESSES 414 +#define T_SIZE 415 +#define T_COMPRESSED_WITH 416 +#define T_INCOMPLETE 417 +#define T_CODEPAGE 418 +#define T_ASSUMED 419 +#define T_IGNORING_SERVER_SETTING 420 +#define T_SERVER 421 +#define T_DATE 422 +#define T_LAST_MODIFIED 423 +#define T_SSL_CIPHER 424 +#define T_LANGUAGE 425 +#define T_DEFAULT_LANG 426 +#define T_GO_TO_LINK 427 +#define T_ENTER_LINK_NUMBER 428 +#define T_RESIZE_TERMINAL 429 +#define T_COLUMNS 430 +#define T_ROWS 431 +#define T_GOTO 432 +#define T_CLOSE 433 +#define T_FOLDER 434 +#define T_fOLDER 435 +#define T_ADD 436 +#define T_DELETE 437 +#define T_EDIT 438 +#define T_MOVE 439 +#define T_NO_ITEMS_SELECTED 440 +#define T_UNSELECT_ALL 441 +#define T_BOOKMARKS 442 +#define T_BOOKMARK 443 +#define T_ADD_BOOKMARK 444 +#define T_ADD_ASSOCIATION 445 +#define T_ADD_EXTENSION 446 +#define T_ADD_FOLDER 447 +#define T_BOOKMARK_TITLE 448 +#define T_EDIT_BOOKMARK 449 +#define T_EDIT_ASSOCIATION 450 +#define T_EDIT_EXTENSION 451 +#define T_DELETE_BOOKMARK 452 +#define T_EDIT_FOLDER 453 +#define T_DELETE_FOLDER 454 +#define T_NOT_EMPTY_SURE_DELETE 455 +#define T_BOOKMARK_MANAGER 456 +#define T_ASSOCIATIONS_MANAGER 457 +#define T_EXTENSIONS_MANAGER 458 +#define T_url 459 +#define T_NNAME 460 +#define T_EXIT_LINKS 461 +#define T_DO_YOU_REALLY_WANT_TO_CLOSE_WINDOW 462 +#define T_DO_YOU_REALLY_WANT_TO_EXIT_LINKS 463 +#define T_DO_YOU_REALLY_WANT_TO_EXIT_LINKS_AND_TERMINATE_ALL_DOWNLOADS 464 +#define T_HTTP_OPTIONS 465 +#define T_FTP_OPTIONS 466 +#define T_SMB_OPTIONS 467 +#define T_HTTP_BUG_WORKAROUNDS 468 +#define T_USE_HTTP_10 469 +#define T_ALLOW_SERVER_BLACKLIST 470 +#define T_DO_NOT_SEND_ACCEPT_CHARSET 471 +#define T_DO_NOT_ADVERTISE_COMPRESSION_SUPPORT 472 +#define T_RETRY_ON_INTERNAL_ERRORS 473 +#define T_HEADER_OPTIONS 474 +#define T_HTTP_HEADER_OPTIONS 475 +#define T_FAKE_FIREFOX 476 +#define T_DO_NOT_TRACK 477 +#define T_REFERER_NONE 478 +#define T_REFERER_SAME_URL 479 +#define T_REFERER_FAKE 480 +#define T_REFERER_REAL_SAME_SERVER 481 +#define T_REFERER_REAL 482 +#define T_FAKE_REFERER 483 +#define T_FAKE_USERAGENT 484 +#define T_EXTRA_HEADER 485 +#define T_PASSWORD_FOR_ANONYMOUS_LOGIN 486 +#define T_USE_PASSIVE_FTP 487 +#define T_USE_EPRT_EPSV 488 +#define T_SET_TYPE_OF_SERVICE 489 +#define T_ALLOW_HYPERLINKS_TO_SMB 490 +#define T_MANUAL 491 +#define T_HOMEPAGE 492 +#define T_CALIBRATION 493 +#define T_MAILTO_PROG 494 +#define T_SHELL_PROG 495 +#define T_TELNET_PROG 496 +#define T_MAGNET_PROG 497 +#define T_TN3270_PROG 498 +#define T_MMS_PROG 499 +#define T_MAIL_AND_TELNET_PROGRAMS 500 +#define T_MAIL_TELNET_AND_SHELL_PROGRAMS 501 +#define T_NO_PROGRAM 502 +#define T_NO_PROGRAM_SPECIFIED_FOR 503 +#define T_MAIL 504 +#define T_TELNET 505 +#define T_MAGNET 506 +#define T_TN3270 507 +#define T_MMS 508 +#define T_BAD_MAILTO_URL 509 +#define T_BAD_TELNET_URL 510 +#define T_BAD_TN3270_URL 511 +#define T_MMS_URL_CONTAINS_INACCEPTABLE_CHARACTERS 512 +#define T_AUTHORIZATION_REQUIRED 513 +#define T_PROXY_AUTHORIZATION_REQUIRED 514 +#define T_USERID 515 +#define T_PASSWORD 516 +#define T_ENTER_USERNAME 517 +#define T_AT 518 +#define T_THE_SERVER_ 519 +#define T_DOESNT_HAVE_A_VALID_CERTIFICATE 520 +#define T_USES_DOWNGRADED_METHOD 521 +#define T_USES_INSECURE_CIPHER 522 +#define T_WAITING_FOR_REDIRECT_CONFIRMATION 523 +#define T_DECOMPRESSION_ERROR 524 +#define T_ERROR_DECOMPRESSING_ 525 +#define T__wITH_ 526 +#define T_COMPRESSED_ERROR 527 +#define T_UNKNOWN_COMPRESSION_METHOD 528 +#define T_SURE_DELETE 529 +#define T_BOOKMARKS_ALREADY_IN_USE 530 +#define T_ASSOCIATIONS_ALREADY_IN_USE 531 +#define T_EXTENSIONS_ALREADY_IN_USE 532 +#define T_VIDEO_OPTIONS 533 +#define T_VIDEO_OPTIONS_TEXT 534 +#define T_RED_DISPLAY_GAMMA 535 +#define T_GREEN_DISPLAY_GAMMA 536 +#define T_BLUE_DISPLAY_GAMMA 537 +#define T_USER_GAMMA 538 +#define T_ASPECT_RATIO 539 +#define T_DITHER_LETTERS 540 +#define T_DITHER_IMAGES 541 +#define T_8_BIT_GAMMA_CORRECTION 542 +#define T_16_BIT_GAMMA_CORRECTION 543 +#define T_AUTO_GAMMA_CORRECTION 544 +#define T_RGB_PALETTE_8x8x4 545 +#define T_RGB_PALETTE_6x6x6 546 +#define T_SWITCH_PALETTE 547 +#define T_OVERWRITE_SCREEN_INSTEAD_OF_SCROLLING_IT 548 +#define T_ALERT 549 +#define T_QUESTION 550 +#define T_KILL_SCRIPT 551 +#define T_KILL_ALL_SCRIPTS 552 +#define T_SCRIPT_KILLED_BY_USER 553 +#define T_SCRIPT_TRYING_TO_CLOSE_WINDOW 554 +#define T_ENTER_STRING 555 +#define T_JAVASCRIPT_OPTIONS 556 +#define T_ENABLE_JAVASCRIPT 557 +#define T_VERBOSE_JS_ERRORS 558 +#define T_VERBOSE_JS_WARNINGS 559 +#define T_MISCELANEOUS_OPTIONS 560 +#define T_JAVASCRIPT_ERROR 561 +#define T_JAVASCRIPT_WARNING 562 +#define T_DISMISS 563 +#define T_MENU_FONT_SIZE 564 +#define T_USER_FONT_SIZE 565 +#define T_TURN_OFF_WARNINGS 566 +#define T_BOOKMARKS_ENCODING 567 +#define T_JS_IS_ATTEMPTING_TO_GO_TO_URL 568 +#define T_JS_IS_ATTEMPTING_TO_OPEN_NEW_WINDOW_WITH_URL 569 +#define T_JS_IS_ATTEMPTING_TO_GO_INTO_HISTORY 570 +#define T_TO_URL 571 +#define T_GOTO_HISTORY 572 +#define T_ALLOW 573 +#define T_REJECT 574 +#define T_ENABLE_ALL_CONVERSIONS 575 +#define T_ENABLE_GLOBAL_NAME_RESOLUTION 576 +#define T_MANUAL_JS_CONTROL 577 +#define T_JS_RECURSION_DEPTH 578 +#define T_MENU_BACKGROUND_COLOR 579 +#define T_MENU_FOREGROUND_COLOR 580 +#define T_SCROLL_BAR_BAR_COLOR 581 +#define T_SCROLL_BAR_AREA_COLOR 582 +#define T_SCROLL_BAR_FRAME_COLOR 583 +#define T_BOOKMARKS_FILE 584 +#define T_SAVE_URL_HISTORY_ON_EXIT 585 +#define T_ENTER_COLORS_AS_RGB_TRIPLETS 586 +#define T_JS_MEMORY_LIMIT_KB 587 +#define T_SCALE_ALL_IMAGES_BY 588 +#define T_PORN_ENABLE 589 +#define T_DISPLAY_OPTIMIZATION_CRT 590 +#define T_DISPLAY_OPTIMIZATION_LCD_RGB 591 +#define T_DISPLAY_OPTIMIZATION_LCD_BGR 592 +#define T_KEYBOARD_CODEPAGE 593 +#define T_COPY_LINK_LOCATION 594 +#define T_BLOCK_URL 595 +#define T_BLOCK_LIST 596 +#define T_BLOCKED_IMAGE 597 +#define T_BLOCK_LIST_IN_USE 598 +#define T_BLOCK_LIST_MANAGER 599 +#define T_BLOCK_ADD 600 +#define T_BLOCK_EDIT 601 +#define T_BLOCK_DELETE 602 +#define T_HK_GOTO_URL 603 +#define T_HK_GO_BACK 604 +#define T_HK_GO_FORWARD 605 +#define T_HK_HISTORY 606 +#define T_HK_RELOAD 607 +#define T_HK_BOOKMARKS 608 +#define T_HK_NEW_WINDOW 609 +#define T_HK_SAVE_AS 610 +#define T_HK_SAVE_URL_AS 611 +#define T_HK_SAVE_FORMATTED_DOCUMENT 612 +#define T_HK_COPY_URL_LOCATION 613 +#define T_HK_KILL_BACKGROUND_CONNECTIONS 614 +#define T_HK_KILL_ALL_CONNECTIONS 615 +#define T_HK_FLUSH_ALL_CACHES 616 +#define T_HK_RESOURCE_INFO 617 +#define T_HK_MEMORY_INFO 618 +#define T_HK_OS_SHELL 619 +#define T_HK_RESIZE_TERMINAL 620 +#define T_HK_EXIT 621 +#define T_HK_SEARCH 622 +#define T_HK_SEARCH_BACK 623 +#define T_HK_FIND_NEXT 624 +#define T_HK_FIND_PREVIOUS 625 +#define T_HK_TOGGLE_HTML_PLAIN 626 +#define T_HK_DOCUMENT_INFO 627 +#define T_HK_HEADER_INFO 628 +#define T_HK_FRAME_AT_FULL_SCREEN 629 +#define T_HK_SAVE_CLIPBOARD_TO_A_FILE 630 +#define T_HK_LOAD_CLIPBOARD_FROM_A_FILE 631 +#define T_HK_HTML_OPTIONS 632 +#define T_HK_COLOR 633 +#define T_HK_SAVE_HTML_OPTIONS 634 +#define T_HK_LANGUAGE 635 +#define T_HK_CHARACTER_SET 636 +#define T_HK_TERMINAL_OPTIONS 637 +#define T_HK_SCREEN_MARGINS 638 +#define T_HK_VIDEO_OPTIONS 639 +#define T_HK_NETWORK_OPTIONS 640 +#define T_HK_CONNECTIONS 641 +#define T_HK_IPV6_OPTIONS 642 +#define T_HK_PROXIES 643 +#define T_HK_SSL_OPTIONS 644 +#define T_HK_HTTP_OPTIONS 645 +#define T_HK_FTP_OPTIONS 646 +#define T_HK_SMB_OPTIONS 647 +#define T_HK_JAVASCRIPT_OPTIONS 648 +#define T_HK_MISCELANEOUS_OPTIONS 649 +#define T_HK_CACHE 650 +#define T_HK_MAIL_AND_TELNEL 651 +#define T_HK_ASSOCIATIONS 652 +#define T_HK_FILE_EXTENSIONS 653 +#define T_HK_BLOCK_LIST 654 +#define T_HK_SAVE_OPTIONS 655 +#define T_HK_ABOUT 656 +#define T_HK_KEYS 657 +#define T_HK_COPYING 658 +#define T_HK_MANUAL 659 +#define T_HK_HOMEPAGE 660 +#define T_HK_CALIBRATION 661 +#define T_HK_FILE 662 +#define T_HK_VIEW 663 +#define T_HK_LINK 664 +#define T_HK_DOWNLOADS 665 +#define T_HK_WINDOWS 666 +#define T_HK_SETUP 667 +#define T_HK_HELP 668 +#define T_HK_DISPLAY_USEMAP 669 +#define T_HK_FOLLOW_LINK 670 +#define T_HK_OPEN_IN_NEW_WINDOW 671 +#define T_HK_DOWNLOAD_LINK 672 +#define T_HK_RESET_FORM 673 +#define T_HK_SUBMIT_FORM 674 +#define T_HK_SUBMIT_FORM_AND_OPEN_IN_NEW_WINDOW 675 +#define T_HK_SUBMIT_FORM_AND_DOWNLOAD 676 +#define T_HK_VIEW_IMAGE 677 +#define T_HK_DOWNLOAD_IMAGE 678 +#define T_HK_SCALE_IMAGE_TO_FULL_SCREEN 679 +#define T_HK_COPY_LINK_LOCATION 680 +#define T_HK_BLOCK_URL 681 +#define T_HK_XTERM 682 +#define T_HK_TWTERM 683 +#define T_HK_SCREEN 684 +#define T_HK_WINDOW 685 +#define T_HK_FULL_SCREEN 686 +#define T_HK_BEOS_TERMINAL 687 +#define T_URL_MANUAL 688 +#define T_URL_HOMEPAGE 689 +#define T_URL_CALIBRATION 690 +#define T__N_TEXTS 691 diff --git a/language.inc b/language.inc @@ -124,8 +124,9 @@ static const struct { { "HTTPS proxy (host:port)" }, { "Socks4A proxy (user@host:port)" }, { "Append text to hostname (for specifying tor exit node)" }, - { "Connect only via proxies or Socks (useful for tor)" }, { "Direct access (w/o proxy) domains (comma separated)" }, + { "Connect only via proxies or Socks (useful for tor)" }, + { "Tor mode enabled because the socks port is 9050." }, { "SSL options" }, { "Accept invalid certificates and weak ciphers" }, { "Warn on invalid certificate or weak cipher" }, @@ -213,6 +214,9 @@ static const struct { { "Toggle html/plain" }, { "Document info" }, { "Frame at full-screen" }, + { "Save clipboard to a file" }, + { "Load clipboard from a file" }, + { "The clipboard is empty" }, { "Save html options" }, { "Character set" }, { "Default" }, @@ -308,6 +312,7 @@ static const struct { { "Abort and delete file" }, { "Yes" }, { "No" }, + { "Never" }, { "Directory" }, { "File already exists" }, { "already exists as an active download." }, @@ -368,6 +373,7 @@ static const struct { { "Search string not found" }, { "Save error" }, { "Error writing to file" }, + { "Error reading the file" }, { "Display usemap" }, { "Follow link" }, { "Open in new window" }, @@ -627,6 +633,8 @@ static const struct { { "I" }, { "E" }, { "F" }, + { "V" }, + { "L" }, { "O" }, { "C" }, { "A" }, diff --git a/links.1 b/links.1 @@ -422,19 +422,19 @@ Margin in text mode. Size of font on pages in graphics mode. .TP -\f3-html-t-text-color \f2<0>-<15>\f1 +\f3-html-text-color \f2<0>-<15>\f1 Text color in text mode. .TP -\f3-html-t-link-color \f2<0>-<15>\f1 +\f3-html-link-color \f2<0>-<15>\f1 Link color in text mode. .TP -\f3-html-t-background-color \f2<0>-<7>\f1 +\f3-html-background-color \f2<0>-<7>\f1 Background color in text mode. .TP -\f3-html-t-ignore-document-color \f2<0>/<1>\f1 +\f3-html-ignore-document-color \f2<0>/<1>\f1 Ignore colors specified in html document in text mode. .TP @@ -652,7 +652,7 @@ See file for a list of people contributing to this project. .P The homepage of links can be found at -.BI http://atrey.karlin.mff.cuni.cz/~clock/twibright/links +.BI http://links.twibright.com/ .P This manual page was written by Peter Gervai <grin@tolna.net>, using excerpts from a (yet?) unknown diff --git a/links.h b/links.h @@ -290,6 +290,8 @@ static inline int cmpbeg(const unsigned char *str, const unsigned char *b) typedef unsigned long long uttime; typedef unsigned long long tcount; +extern int page_size; + struct terminal; struct open_in_new { @@ -301,11 +303,11 @@ struct open_in_new { void close_fork_tty(void); int is_screen(void); int is_xterm(void); -int get_terminal_size(int, int *, int *); -void handle_terminal_resize(int, void (*)(void)); -void unhandle_terminal_resize(int); +void get_terminal_size(int *, int *); +void handle_terminal_resize(void (*)(int, int), int *x, int *y); +void unhandle_terminal_resize(void); void set_nonblock(int); -int c_pipe(int *); +int c_pipe(int [2]); int c_dup(int oh); int c_socket(int, int, int); int c_accept(int, struct sockaddr *, socklen_t *); @@ -322,13 +324,14 @@ int clipboard_support(struct terminal *); void set_window_title(unsigned char *); unsigned char *get_window_title(void); int is_safe_in_shell(unsigned char); -unsigned char *escape_path(unsigned char *); +unsigned char *escape_path(char *); void check_shell_security(unsigned char **); void check_filename(unsigned char **); int check_shell_url(unsigned char *); void do_signal(int sig, void (*handler)(int)); uttime get_time(void); uttime get_absolute_time(void); +void init_page_size(void); void ignore_signals(void); int os_get_system_name(unsigned char *buffer); unsigned char *os_conv_to_external_path(unsigned char *, unsigned char *); @@ -494,8 +497,6 @@ struct fragment { unsigned char data[1]; }; -extern int page_size; - struct connection; void init_cache(void); @@ -715,7 +716,7 @@ void load_url(unsigned char *, unsigned char *, struct status *, int, int, int, void change_connection(struct status *, struct status *, int); void detach_connection(struct status *, off_t, int, int); void abort_all_connections(void); -void abort_background_connections(void); +int abort_background_connections(void); int is_entry_used(struct cache_entry *); void clear_connection_timeout(struct connection *); void set_connection_timeout(struct connection *); @@ -733,6 +734,7 @@ void free_blacklist(void); #define BL_IGNORE_CERTIFICATE 0x040 #define BL_IGNORE_DOWNGRADE 0x080 #define BL_IGNORE_CIPHER 0x100 +#define BL_AVOID_INSECURE 0x200 /* suffix.c */ @@ -939,6 +941,7 @@ void file_func(struct connection *); #define KBD_FORWARD -0x14b #define KBD_RELOAD -0x14c #define KBD_BOOKMARKS -0x14d +#define KBD_SELECT -0x14e #define KBD_ESCAPE_MENU(x) ((x) <= KBD_F1 && (x) > KBD_CTRL_C) @@ -956,12 +959,6 @@ void dispatch_special(unsigned char *); void kbd_ctrl_c(void); int is_blocked(void); -struct os2_key { - int x, y; -}; - -extern struct os2_key os2xtd[256]; - struct itrm; extern unsigned char init_seq[]; @@ -1091,6 +1088,7 @@ struct graphics_driver { void (*flush)(struct graphics_device *dev); void (*set_palette)(void); + unsigned short *(*get_real_colors)(void); void (*set_title)(struct graphics_device *dev, unsigned char *title); /* set window title. title is in utf-8 encoding -- you should recode it to device charset */ @@ -1285,7 +1283,7 @@ struct style { }; struct font_cache_entry { - unsigned char r0,g0,b0,r1,g1,b1; + unsigned char r0, g0, b0, r1, g1, b1; struct bitmap bitmap; int mono_space, mono_height; /* if the letter was rendered for a monospace font, then size of the space. Otherwise, mono_space @@ -1334,6 +1332,7 @@ void mix_one_color_24(unsigned char *restrict dest, int length, void scale_color(unsigned short *in, int ix, int iy, unsigned short **out, int ox, int oy); void update_aspect(void); +void flush_bitmaps(int flush_font, int flush_images, int redraw_all); struct g_object; @@ -1361,15 +1360,18 @@ struct style *g_clone_style(struct style *); extern tcount gamma_stamp; -extern long gamma_cache_color; -extern int gamma_cache_rgb; +extern long gamma_cache_color_1; +extern int gamma_cache_rgb_1; +extern long gamma_cache_color_2; +extern int gamma_cache_rgb_2; -extern long real_dip_get_color_sRGB(int rgb); +long real_dip_get_color_sRGB(int rgb); static inline long dip_get_color_sRGB(int rgb) { - if (rgb == gamma_cache_rgb) return gamma_cache_color; - else return real_dip_get_color_sRGB(rgb); + if (rgb == gamma_cache_rgb_1) return gamma_cache_color_1; + if (rgb == gamma_cache_rgb_2) return gamma_cache_color_2; + return real_dip_get_color_sRGB(rgb); } void init_dip(void); @@ -1385,7 +1387,7 @@ void my_png_free(png_structp png_ptr, void *ptr); extern int slow_fpu; /* -1 --- don't know, 0 --- no, 1 --- yes */ /* Dithering functions (for blocks of pixels being dithered into bitmaps) */ -void dither (unsigned short *in, struct bitmap *out); +void dither(unsigned short *in, struct bitmap *out); int *dither_start(unsigned short *in, struct bitmap *out); void dither_restart(unsigned short *in, struct bitmap *out, int *dregs); extern void (*round_fn)(unsigned short *restrict in, struct bitmap *out); @@ -1615,7 +1617,7 @@ extern int terminal_pipe[2]; extern int retval; extern const char *argv0; -extern unsigned char **g_argv; +extern char **g_argv; extern int g_argc; void sig_tstp(void *t); @@ -1676,8 +1678,8 @@ void detach_object_connection(struct object_request *, off_t); extern int decompressed_cache_size; -int get_file_by_term(struct terminal *term, struct cache_entry *ce, unsigned char **start, unsigned char **end, int *errp); -int get_file(struct object_request *o, unsigned char **start, unsigned char **end); +int get_file_by_term(struct terminal *term, struct cache_entry *ce, unsigned char **start, size_t *len, int *errp); +int get_file(struct object_request *o, unsigned char **start, size_t *len); void free_decompressed_data(struct cache_entry *e); void add_compress_methods(unsigned char **s, int *l); @@ -2470,8 +2472,6 @@ struct session { struct dialog_data; -int get_file(struct object_request *o, unsigned char **start, unsigned char **end); - int f_is_finished(struct f_data *f); unsigned long formatted_info(int); void init_fcache(void); @@ -2486,6 +2486,7 @@ unsigned char *decode_url(unsigned char *); struct session *get_download_ses(struct download *); unsigned char *subst_file(unsigned char *, unsigned char *, int); int are_there_downloads(void); +unsigned char get_session_attribute(struct session *, int); unsigned char *translate_download_file(unsigned char *); void free_strerror_buf(void); int get_error_from_errno(int errn); @@ -2802,6 +2803,7 @@ struct conv_table { }; struct conv_table *get_translation_table(const int, const int); +static inline int is_entity_terminator(unsigned char c) { return c <= ' ' || c == ';' || c == '&' || c == '/' || c == '?'; } int get_entity_number(unsigned char *st, int l); unsigned char *get_entity_string(unsigned char *, int); unsigned char *convert_string(struct conv_table *, unsigned char *, int, struct document_options *); @@ -3421,7 +3423,7 @@ extern unsigned char ggr_display[MAX_STR_LEN]; extern unsigned char default_target[MAX_STR_LEN]; -unsigned char *parse_options(int, unsigned char *[]); +unsigned char *parse_options(int, char *[]); void init_home(void); unsigned char *read_config_file(unsigned char *); int write_to_config_file(unsigned char *, unsigned char *, int); diff --git a/listedit.c b/listedit.c @@ -1370,7 +1370,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) list_find_next(&rd, - ld->search_direction); return EVENT_PROCESSED; } - if (ev->x==KBD_UP) + if (ev->x == KBD_UP) { if (ld->current_pos==ld->list) goto kbd_up_redraw_exit; /* already on the top */ ld->current_pos=prev_in_tree(ld,ld->current_pos); @@ -1386,7 +1386,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) draw_to_window(dlg->win,redraw_list_line,&rd); return EVENT_PROCESSED; } - if (ev->x=='i'||ev->x=='*'||ev->x=='8'||ev->x==KBD_INS) + if (ev->x == 'i' || ev->x == '*' || ev->x == '8' || ev->x == KBD_INS || ev->x == KBD_SELECT) { if (ld->current_pos!=ld->list)ld->current_pos->type^=4; rd.n=-1; @@ -1406,7 +1406,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) draw_to_window(dlg->win,redraw_list_line,&rd); return EVENT_PROCESSED; } - if (ev->x==KBD_DOWN) + if (ev->x == KBD_DOWN) { if (next_in_tree(ld,ld->current_pos)==ld->list) goto kbd_down_redraw_exit; /* already at the bottom */ ld->current_pos=next_in_tree(ld,ld->current_pos); @@ -1422,7 +1422,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) draw_to_window(dlg->win,redraw_list_line,&rd); return EVENT_PROCESSED; } - if (ev->x==KBD_HOME || (upcase(ev->x) == 'A' && ev->y & KBD_CTRL)) + if (ev->x == KBD_HOME || (upcase(ev->x) == 'A' && ev->y & KBD_CTRL)) { if (ld->current_pos==ld->list) goto kbd_home_redraw_exit; /* already on the top */ ld->win_offset=ld->list; @@ -1434,7 +1434,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) draw_to_window(dlg->win,redraw_list_line,&rd); /* set cursor */ return EVENT_PROCESSED; } - if (ev->x==KBD_END || (upcase(ev->x) == 'E' && ev->y & KBD_CTRL)) + if (ev->x == KBD_END || (upcase(ev->x) == 'E' && ev->y & KBD_CTRL)) { int a; @@ -1450,7 +1450,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) draw_to_window(dlg->win,redraw_list_line,&rd); /* set cursor */ return EVENT_PROCESSED; } - if (ev->x==KBD_PAGE_UP || (upcase(ev->x) == 'B' && ev->y & KBD_CTRL)) + if (ev->x == KBD_PAGE_UP || (upcase(ev->x) == 'B' && ev->y & KBD_CTRL)) { int a; @@ -1467,7 +1467,7 @@ static int list_event_handler(struct dialog_data *dlg, struct links_event *ev) draw_to_window(dlg->win,redraw_list_line,&rd); /* set cursor */ return EVENT_PROCESSED; } - if (ev->x==KBD_PAGE_DOWN || (upcase(ev->x) == 'F' && ev->y & KBD_CTRL)) + if (ev->x == KBD_PAGE_DOWN || (upcase(ev->x) == 'F' && ev->y & KBD_CTRL)) { int a; struct list*p=ld->win_offset; diff --git a/main.c b/main.c @@ -28,7 +28,7 @@ static void unhandle_basic_signals(struct terminal *); static int init_b = 0; int g_argc; const char *argv0; -unsigned char **g_argv; +char **g_argv; void die(const char *errstr, ...) @@ -491,12 +491,13 @@ int main(int argc, char *argv[]) { g_argc = argc; - g_argv = (unsigned char **)argv; + g_argv = argv; argv0 = argv[0]; if (pledge("stdio rpath wpath cpath inet dns tty unix", NULL) < 0) die("pledge: %s\n", strerror(errno)); + init_page_size(); select_loop(init); terminate_all_subsystems(); diff --git a/menu.c b/menu.c @@ -6,6 +6,8 @@ #include "links.h" +static struct history file_history = { 0, { &file_history.items, &file_history.items } }; + static unsigned char * const version_texts[] = { TEXT_(T_LINKS_VERSION), TEXT_(T_OPERATING_SYSTEM_VERSION), @@ -913,7 +915,7 @@ static void refresh_connections(void *xxx) max_tries = atoi(cast_const_char max_t_str); receive_timeout = atoi(cast_const_char time_str); unrestartable_receive_timeout = atoi(cast_const_char unrtime_str); - unrestartable_receive_timeout = atoi(cast_const_char addrtime_str); + timeout_multiple_addresses = atoi(cast_const_char addrtime_str); refresh_network(xxx); } @@ -1291,7 +1293,8 @@ static int check_noproxy_list(struct dialog_data *dlg, struct dialog_item_data * static int proxy_ok_dialog(struct dialog_data *dlg, struct dialog_item_data *di) { - int charset = term_charset(dlg->win->term); + struct terminal *term = dlg->win->term; + int charset = term_charset(term); int op = proxies.only_proxies; int r = ok_dialog(dlg, di); if (r) return r; @@ -1299,6 +1302,25 @@ static int proxy_ok_dialog(struct dialog_data *dlg, struct dialog_item_data *di) save_proxy(charset, proxies.https_proxy, https_proxy); save_proxy(charset, proxies.socks_proxy, socks_proxy); save_noproxy_list(charset, proxies.no_proxy, no_proxy); + + if (!proxies.only_proxies) { + /* parsing duplicated in make_connection */ + long lp; + char *end; + unsigned char *p = cast_uchar strchr(cast_const_char proxies.socks_proxy, '@'); + if (!p) p = proxies.socks_proxy; + else p++; + p = cast_uchar strchr(cast_const_char p, ':'); + if (p) { + p++; + lp = strtol(cast_const_char p, &end, 10); + if (!*end && lp == 9050) { + proxies.only_proxies = 1; + msg_box(term, NULL, TEXT_(T_PROXIES), AL_LEFT, TEXT_(T_TOR_MODE_ENABLED), MSG_BOX_END, NULL, 1, TEXT_(T_OK), msg_box_null, B_ENTER | B_ESC); + } + } + } + if (op != proxies.only_proxies) { data_cleanup(); } @@ -2919,9 +2941,6 @@ free_h_ret: } -static struct history file_history = { 0, { &file_history.items, &file_history.items } }; - - static void query_file_cancel(void *d_, unsigned char *s_) { struct does_file_exist_s *d = (struct does_file_exist_s *)d_; diff --git a/objreq.c b/objreq.c @@ -195,7 +195,7 @@ struct cert_dialog { static void cert_action(struct object_request *rq, int yes) { - if (yes) { + if (yes > 0) { rq->hold = 0; change_connection(&rq->stat, NULL, PRI_CANCEL); load_url(rq->url, rq->prev_url, &rq->stat, rq->pri, NC_CACHE, 0, 0, 0); @@ -212,7 +212,16 @@ static void cert_forall(struct cert_dialog *cs, int yes) { struct object_request *rq = NULL; struct list_head *lrq; - if (yes) add_blacklist_entry(cs->host, cs->bl); + if (yes > 0) { + add_blacklist_entry(cs->host, cs->bl); + del_blacklist_entry(cs->host, BL_AVOID_INSECURE); + } + if (yes < 0) { + add_blacklist_entry(cs->host, BL_AVOID_INSECURE); + del_blacklist_entry(cs->host, BL_IGNORE_CERTIFICATE); + del_blacklist_entry(cs->host, BL_IGNORE_DOWNGRADE); + del_blacklist_entry(cs->host, BL_IGNORE_CIPHER); + } foreach(struct object_request, rq, lrq, requests) if (rq->term == cs->term && rq->hold == HOLD_CERT && rq->stat.state == cs->state) { unsigned char *host = get_host_name(rq->url); if (!strcmp(cast_const_char host, cast_const_char cs->host)) cert_action(rq, yes); @@ -230,6 +239,11 @@ static void cert_no(void *data) cert_forall((struct cert_dialog *)data, 0); } +static void cert_never(void *data) +{ + cert_forall((struct cert_dialog *)data, -1); +} + static int cert_compare(void *data1, void *data2) { struct cert_dialog *cs1 = (struct cert_dialog *)data1; @@ -245,6 +259,10 @@ static int cert_window(struct object_request *rq) struct memory_list *ml; if (!(term = find_terminal(rq->term))) return -1; h = get_host_name(rq->url); + if (get_blacklist_flags(h) & BL_AVOID_INSECURE) { + free(h); + return -1; + } cs = xmalloc(sizeof(struct cert_dialog)); cs->term = rq->term; cs->host = h; @@ -271,7 +289,7 @@ static int cert_window(struct object_request *rq) msg_box(term, ml, title, AL_CENTER, TEXT_(T_THE_SERVER_), host, text, MSG_BOX_END, - (void *)cs, 2, TEXT_(T_NO), cert_no, B_ESC, TEXT_(T_YES), cert_yes, B_ENTER); + (void *)cs, 3, TEXT_(T_NO), cert_no, B_ESC, TEXT_(T_YES), cert_yes, B_ENTER, TEXT_(T_NEVER), cert_never, 0); return 0; } diff --git a/os_dep.c b/os_dep.c @@ -7,6 +7,8 @@ #include <sys/ioctl.h> +int page_size = 4096; + int is_safe_in_shell(unsigned char c) { return c == '@' || c == '+' || c == '-' || c == '.' || c == ',' || c == '=' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z'); @@ -49,16 +51,16 @@ int check_shell_url(unsigned char *url) return 0; } -unsigned char *escape_path(unsigned char *path) +unsigned char *escape_path(char *path) { unsigned char *result; size_t i; - if (strchr(cast_const_char path, '"')) return stracpy(path); + if (strchr(path, '"')) return stracpy(cast_uchar path); for (i = 0; path[i]; i++) if (!is_safe_in_url(path[i])) goto do_esc; - return stracpy(path); + return stracpy(cast_uchar path); do_esc: result = stracpy(cast_uchar "\""); - add_to_strn(&result, path); + add_to_strn(&result, cast_uchar path); add_to_strn(&result, cast_uchar "\""); return result; } @@ -71,6 +73,13 @@ static int get_e(const char *env) return 0; } +void init_page_size(void) { + long getpg = -1; + if (getpg < 0) + getpg = getpagesize(); + if (getpg > 0 && !(getpg & (getpg - 1))) page_size = (int)getpg; +} + void do_signal(int sig, void (*handler)(int)) { errno = 0; @@ -121,28 +130,34 @@ void os_free_clipboard(void) /* Terminal size */ +static void (*terminal_resize_callback)(int, int); + #ifdef SIGWINCH static void sigwinch(void *s) { - ((void (*)(void))s)(); + int cur_xsize, cur_ysize; + get_terminal_size(&cur_xsize, &cur_ysize); + terminal_resize_callback(cur_xsize, cur_ysize); } #endif -void handle_terminal_resize(int fd, void (*fn)(void)) +void handle_terminal_resize(void (*fn)(int, int), int *x, int *y) { -#ifdef SIGWINCH - install_signal_handler(SIGWINCH, sigwinch, (void *)fn, 0); + terminal_resize_callback = fn; + get_terminal_size(x, y); +#if defined(SIGWINCH) + install_signal_handler(SIGWINCH, sigwinch, NULL, 0); #endif } -void unhandle_terminal_resize(int fd) +void unhandle_terminal_resize(void) { -#ifdef SIGWINCH +#if defined(SIGWINCH) install_signal_handler(SIGWINCH, NULL, NULL, 0); #endif } -int get_terminal_size(int fd, int *x, int *y) +void get_terminal_size(int *x, int *y) { int rs = -1; #ifdef TIOCGWINSZ @@ -163,7 +178,6 @@ int get_terminal_size(int fd, int *x, int *y) ) && !(*y = get_e("LINES"))) { *y = 24; } - return 0; } static void new_fd_cloexec(int fd) @@ -191,66 +205,88 @@ void set_nonblock(int fd) #endif } -int c_pipe(int *fd) +static int cleanup_fds(void) +{ +#ifdef ENFILE + if (errno == ENFILE) return abort_background_connections(); +#endif +#ifdef EMFILE + if (errno == EMFILE) return abort_background_connections(); +#endif + return 0; +} + +int c_pipe(int fd[2]) { int r; - EINTRLOOP(r, pipe(fd)); - if (!r) { - new_fd_bin(fd[0]); - new_fd_bin(fd[1]); - } + do { + EINTRLOOP(r, pipe(fd)); + if (!r) new_fd_bin(fd[0]), new_fd_bin(fd[1]); + } while (r == -1 && cleanup_fds()); return r; } int c_dup(int oh) { int h; - EINTRLOOP(h, dup(oh)); - if (h != -1) new_fd_cloexec(h); + do { + EINTRLOOP(h, dup(oh)); + if (h != -1) new_fd_cloexec(h); + } while (h == -1 && cleanup_fds()); return h; } int c_socket(int d, int t, int p) { int h; - EINTRLOOP(h, socket(d, t, p)); - if (h != -1) new_fd_cloexec(h); + do { + EINTRLOOP(h, socket(d, t, p)); + if (h != -1) new_fd_cloexec(h); + } while (h == -1 && cleanup_fds()); return h; } -int c_accept(int h, struct sockaddr *addr, socklen_t *addrlen) +int c_accept(int sh, struct sockaddr *addr, socklen_t *addrlen) { - int rh; - EINTRLOOP(rh, accept(h, addr, addrlen)); - if (rh != -1) new_fd_cloexec(rh); - return rh; + int h; + do { + EINTRLOOP(h, accept(sh, addr, addrlen)); + if (h != -1) new_fd_cloexec(h); + } while (h == -1 && cleanup_fds()); + return h; } int c_open(unsigned char *path, int flags) { int h; - EINTRLOOP(h, open(cast_const_char path, flags)); - if (h != -1) new_fd_bin(h); + do { + EINTRLOOP(h, open(cast_const_char path, flags)); + if (h != -1) new_fd_bin(h); + } while (h == -1 && cleanup_fds()); return h; } int c_open3(unsigned char *path, int flags, int mode) { int h; - EINTRLOOP(h, open(cast_const_char path, flags, mode)); - if (h != -1) new_fd_bin(h); + do { + EINTRLOOP(h, open(cast_const_char path, flags, mode)); + if (h != -1) new_fd_bin(h); + } while (h == -1 && cleanup_fds()); return h; } DIR *c_opendir(unsigned char *path) { DIR *d; - ENULLLOOP(d, opendir(cast_const_char path)); - if (d) { - int h; - EINTRLOOP(h, dirfd(d)); - if (h != -1) new_fd_cloexec(h); - } + do { + ENULLLOOP(d, opendir(cast_const_char path)); + if (d) { + int h; + EINTRLOOP(h, dirfd(d)); + if (h != -1) new_fd_cloexec(h); + } + } while (!d && cleanup_fds()); return d; } diff --git a/sched.c b/sched.c @@ -205,12 +205,16 @@ int get_keepalive_socket(struct connection *c, int *protocol_data) return 0; } -static void abort_all_keepalive_connections(void) +static int abort_all_keepalive_connections(void) { - while (!list_empty(keepalive_connections)) + int did_something = 0; + while (!list_empty(keepalive_connections)) { del_keepalive_socket(list_struct(keepalive_connections.next, struct k_conn)); + did_something = 1; + } check_keepalive_connections(); + return did_something; } static void free_connection_data(struct connection *c) @@ -1021,8 +1025,9 @@ void abort_all_connections(void) abort_all_keepalive_connections(); } -void abort_background_connections(void) +int abort_background_connections(void) { + int did_something = 0; struct connection *c = NULL; struct list_head *lc; again: @@ -1030,10 +1035,11 @@ again: if (getpri(c) >= PRI_CANCEL) { setcstate(c, S_INTERRUPTED); abort_connection(c); + did_something = 1; goto again; } } - abort_all_keepalive_connections(); + return did_something | abort_all_keepalive_connections(); } int is_entry_used(struct cache_entry *e) diff --git a/session.c b/session.c @@ -25,6 +25,20 @@ int are_there_downloads(void) } struct list_head sessions = {&sessions, &sessions}; +unsigned char get_session_attribute(struct session *ses, int reverse) +{ + if (!ses->term->spec->col) { + if (!reverse) + return COLOR_TITLE; + else + return COLOR_STATUS; + } else { + if (!reverse) + return get_attribute(ses->ds.t_text_color, ses->ds.t_background_color); + else + return get_attribute(ses->ds.t_background_color, ses->ds.t_text_color); + } +} struct s_msg_dsc { int n; @@ -273,15 +287,14 @@ static void x_print_screen_status(struct terminal *term, void *ses_) { struct session *ses = (struct session *)ses_; if (!F) { - unsigned char color = get_attribute(ses->ds.t_text_color, ses->ds.t_background_color); - if (!term->spec->col) color = COLOR_TITLE; + unsigned char color = get_session_attribute(ses, proxies.only_proxies); fill_area(term, 0, term->y - 1, term->x, 1, ' ', color); if (ses->st) print_text(term, 0, term->y - 1, (int)strlen(cast_const_char ses->st), ses->st, COLOR_STATUS); #ifdef G } else { int l = 0; if (ses->st) g_print_text(term->dev, 0, term->y - G_BFU_FONT_SIZE, bfu_style_wb_mono, ses->st, &l); - drv->fill_area(term->dev, l, term->y - G_BFU_FONT_SIZE, term->x, term->y, bfu_bg_color); + drv->fill_area(term->dev, l, term->y - G_BFU_FONT_SIZE, term->x, term->y, !proxies.only_proxies ? bfu_bg_color : bfu_fg_color); #endif } } @@ -290,7 +303,8 @@ static void x_print_screen_title(struct terminal *term, void *ses_) { struct session *ses = (struct session *)ses_; unsigned char *m; - unsigned char color = get_attribute(ses->ds.t_text_color, ses->ds.t_background_color); + unsigned char color = get_session_attribute(ses, proxies.only_proxies); + if (!term->spec->col) color = COLOR_TITLE; fill_area(term, 0, 0, term->x, 1, ' ', color); if ((m = print_current_title(ses))) { int p = term->x - 1 - strlen((char *)m); @@ -304,9 +318,6 @@ static void print_only_screen_status(struct session *ses) { #ifdef G if (F) { - /*debug("%s - %s", ses->st_old, ses->st); - debug("clip: %d.%d , %d.%d", ses->term->dev->clip.x1, ses->term->dev->clip.y1, ses->term->dev->clip.x2, ses->term->dev->clip.y2); - debug("size: %d.%d , %d.%d", ses->term->dev->size.x1, ses->term->dev->size.y1, ses->term->dev->size.x2, ses->term->dev->size.y2);*/ if (ses->st_old) { if (ses->st && !strcmp(cast_const_char ses->st, cast_const_char ses->st_old)) return; free(ses->st_old); @@ -961,12 +972,13 @@ have_frag: if (stat->state < 0) { if (down->decompress) { struct session *ses = get_download_ses(down); - unsigned char *start, *end; + unsigned char *start; + size_t len; int err; - get_file_by_term(ses ? ses->term : NULL, ce, &start, &end, &err); + get_file_by_term(ses ? ses->term : NULL, ce, &start, &len, &err); if (err) goto det_abt; - while (down->last_pos < end - start) { - if (download_write(down, start + down->last_pos, end - start - down->last_pos)) goto det_abt; + while (down->last_pos < len) { + if (download_write(down, start + down->last_pos, len - down->last_pos)) goto det_abt; } } if (stat->state != S__OK) { @@ -1274,14 +1286,16 @@ static struct f_data *format_html(struct f_data_c *fd, struct object_request *rq f->time_to_get = -get_time(); clone_object(rq, &f->rq); if (f->rq->ce) { - unsigned char *start; unsigned char *end; + unsigned char *start; + size_t len; int stl = -1; struct additional_file *af = NULL; struct list_head *laf; if (fd->af) foreach(struct additional_file, af, laf, fd->af->af) if (af->need_reparse > 0) af->need_reparse = 0; - get_file(rq, &start, &end); + get_file(rq, &start, &len); + if (len > INT_MAX) len = INT_MAX; f->uncacheable = 1; if (opt->plain == 2) { start = init_str(); @@ -1289,9 +1303,9 @@ static struct f_data *format_html(struct f_data_c *fd, struct object_request *rq add_to_str(&start, &stl, cast_uchar "<img src=\""); add_to_str(&start, &stl, f->rq->ce->url); add_to_str(&start, &stl, cast_uchar "\">"); - end = start + stl; + len = stl; } - really_format_html(f->rq->ce, start, end, f, fd->ses ? fd != fd->ses->screen : 0); + really_format_html(f->rq->ce, start, start + len, f, fd->ses ? fd != fd->ses->screen : 0); if (stl != -1) free(start); f->use_tag = f->rq->ce->count; @@ -1884,7 +1898,23 @@ int f_data_c_allow_flags(struct f_data_c *fd) return 0; } -static int plain_type(struct session *ses, struct object_request *rq, unsigned char **p) +static int is_forced_download(struct object_request *rq) +{ + struct cache_entry *ce; + unsigned char *cd; + char *s; + + if (!rq || !(ce = rq->ce)) + return 0; + if ((cd = parse_http_header(ce->head, cast_uchar "Content-Disposition", NULL))) { + if ((s = strchr(cast_const_char cd, ';'))) *s = 0; + free(cd); + return !casestrcmp(cd, cast_uchar "attachment"); + } + return 0; +} + +static int plain_type(struct object_request *rq, unsigned char **p) { struct cache_entry *ce; unsigned char *ct; @@ -1938,7 +1968,7 @@ void fd_loaded(struct object_request *rq, void *fd_) } if (fd->parsed_done && f_need_reparse(fd->f_data)) fd->parsed_done = 0; if (fd->vs->plain == -1 && rq->state != O_WAITING) { - fd->vs->plain = plain_type(fd->ses, fd->rq, NULL); + fd->vs->plain = plain_type(fd->rq, NULL); } if (fd->rq->state < 0 && (f_is_finished(fd->f_data) || !fd->f_data)) { if (!fd->parsed_done) { @@ -2162,7 +2192,8 @@ static void ses_go_forward(struct session *ses, int plain, int refresh) fd->rq->upcall = fd_loaded; fd->rq->data = fd; fd->rq->upcall(fd->rq, fd); - draw_formatted(ses); + if (!list_empty(ses->screen->subframes)) + draw_formatted(ses); } static void ses_go_backward(struct session *ses) @@ -2321,11 +2352,14 @@ static int ses_abort_1st_state_loading(struct session *ses) static void tp_display(void *ses_) { + int plain = 1; struct session *ses = (struct session *)ses_; + if (plain_type(ses->tq, NULL) == 2) + plain = 2; ses_abort_1st_state_loading(ses); ses->rq = ses->tq; ses->tq = NULL; - ses_go_forward(ses, 1, 0); + ses_go_forward(ses, plain, 0); } static int direct_download_possible(struct object_request *rq, struct assoc *a) @@ -2486,9 +2520,10 @@ static void ses_go_to_2nd_state(struct session *ses) struct assoc *a; int n; unsigned char *ct = NULL; - int r = plain_type(ses, ses->rq, &ct); - if (r == 0 || r == 1 || r == 2 || r == 3) goto go; - if (!(a = get_type_assoc(ses->term, ct, &n)) && strlen(cast_const_char ct) >= 4 && !casecmp(ct, cast_uchar "text", 4)) { + int r = plain_type(ses->rq, &ct); + int force_download = is_forced_download(ses->rq); + if (!force_download && (r == 0 || r == 1 || r == 2)) goto go; + if (!(a = get_type_assoc(ses->term, ct, &n)) && strlen(cast_const_char ct) >= 4 && !casecmp(ct, cast_uchar "text", 4) && !force_download) { r = 1; goto go; } @@ -2644,15 +2679,17 @@ static void freeml_void(void *ml_) static void ses_imgmap(struct session *ses) { - unsigned char *start, *end; + unsigned char *start; + size_t len; struct memory_list *ml; struct menu_item *menu; struct f_data_c *fd; if (ses->rq->state != O_OK && ses->rq->state != O_INCOMPLETE) return; if (!(fd = current_frame(ses)) || !fd->f_data) return; - if (get_file(ses->rq, &start, &end)) return; + if (get_file(ses->rq, &start, &len)) return; + if (len > INT_MAX) len = INT_MAX; d_opt = &fd->f_data->opt; - if (get_image_map(ses->rq->ce->head, start, end, ses->goto_position, &menu, &ml, ses->imgmap_href_base, ses->imgmap_target_base, term_charset(ses->term), ses->ds.assume_cp, ses->ds.hard_assume, 0)) { + if (get_image_map(ses->rq->ce->head, start, start + len, ses->goto_position, &menu, &ml, ses->imgmap_href_base, ses->imgmap_target_base, term_charset(ses->term), ses->ds.assume_cp, ses->ds.hard_assume, 0)) { ses_abort_1st_state_loading(ses); return; } diff --git a/string.c b/string.c @@ -147,10 +147,11 @@ void add_knum_to_str(unsigned char **s, int *l, off_t n) long strtolx(unsigned char *c, unsigned char **end) { + char *end_c; long l; - if (c[0] == '0' && upcase(c[1]) == 'X' && c[2]) l = strtol(cast_const_char(c + 2), (char **)(void *)end, 16); - else l = strtol(cast_const_char c, (char **)(void *)end, 10); - if (!*end) return l; + if (c[0] == '0' && upcase(c[1]) == 'X' && c[2]) l = strtol(cast_const_char(c + 2), &end_c, 16); + else l = strtol(cast_const_char c, &end_c, 10); + *end = cast_uchar end_c; if (upcase(**end) == 'K') { (*end)++; if (l < -INT_MAX / 1024) return -INT_MAX; diff --git a/suffix.inc b/suffix.inc @@ -6,7 +6,6 @@ static const char *domain_suffix[] = { "*.alces.network", "*.awdev.ca", "*.bd", - "*.bn", "*.ck", "*.cns.joyent.com", "*.compute-1.amazonaws.com", @@ -17,25 +16,26 @@ static const char *domain_suffix[] = { "*.elb.amazonaws.com", "*.elb.amazonaws.com.cn", "*.er", + "*.ex.futurecms.at", "*.ex.ortsinfo.at", "*.fj", "*.fk", "*.futurecms.at", - "*.gu", "*.hosting.myjino.ru", + "*.in.futurecms.at", "*.jm", "*.kawasaki.jp", "*.kh", "*.kitakyushu.jp", "*.kobe.jp", "*.kunden.ortsinfo.at", - "*.kw", "*.landing.myjino.ru", "*.magentosite.cloud", "*.mm", "*.nagoya.jp", "*.nom.br", "*.np", + "*.otap.co", "*.pg", "*.platform.sh", "*.platformsh.site", @@ -52,15 +52,18 @@ static const char *domain_suffix[] = { "*.transurl.eu", "*.transurl.nl", "*.triton.zone", + "*.uberspace.de", "*.vps.myjino.ru", "*.ye", "*.yokohama.jp", "0.bg", + "001www.com", "1.bg", "12hp.at", "12hp.ch", "12hp.de", "1337.pictures", + "16-b.it", "1kapp.com", "2.bg", "2000.hu", @@ -69,6 +72,7 @@ static const char *domain_suffix[] = { "2ix.ch", "2ix.de", "3.bg", + "32-b.it", "3utilities.com", "4.bg", "4lima.at", @@ -77,6 +81,7 @@ static const char *domain_suffix[] = { "4u.com", "5.bg", "6.bg", + "64-b.it", "7.bg", "8.bg", "9.bg", @@ -373,7 +378,9 @@ static const char *domain_suffix[] = { "ap.leg.br", "aparecida.br", "apartments", + "apigee.io", "app", + "app.lmpm.com", "app.os.fedoraproject.org", "app.os.stg.fedoraproject.org", "appchizi.com", @@ -583,6 +590,8 @@ static const char *domain_suffix[] = { "balestrand.no", "ballangen.no", "ballooning.aero", + "balsan-sudtirol.it", + "balsan-suedtirol.it", "balsan.it", "balsfjord.no", "baltimore.museum", @@ -609,12 +618,27 @@ static const char *domain_suffix[] = { "barrel-of-knowledge.info", "barrell-of-knowledge.info", "barsy.bg", + "barsy.club", + "barsy.co.uk", "barsy.de", "barsy.eu", "barsy.in", + "barsy.info", + "barsy.io", + "barsy.me", + "barsy.menu", + "barsy.mobi", "barsy.net", "barsy.online", + "barsy.org", + "barsy.pro", + "barsy.pub", + "barsy.shop", + "barsy.site", "barsy.support", + "barsy.uk", + "barsycenter.com", + "barsyonline.co.uk", "barsyonline.com", "barueri.br", "barum.no", @@ -639,6 +663,7 @@ static const char *domain_suffix[] = { "bbva", "bc.ca", "bcg", + "bci.dnstrace.pro", "bcn", "bd.se", "be", @@ -743,6 +768,7 @@ static const char *domain_suffix[] = { "bjugn.no", "bl.it", "black", + "blackbaudcdn.net", "blackfriday", "blanco", "blockbuster", @@ -837,6 +863,7 @@ static const char *domain_suffix[] = { "bmoattachments.org", "bms", "bmw", + "bn", "bn.it", "bnl", "bnpparibas", @@ -856,6 +883,7 @@ static const char *domain_suffix[] = { "bolivia.bo", "bologna.it", "bolt.hu", + "bolzano-altoadige.it", "bolzano.it", "bom", "bomlo.no", @@ -879,6 +907,8 @@ static const char *domain_suffix[] = { "boutique", "box", "boxfuse.io", + "bozen-sudtirol.it", + "bozen-suedtirol.it", "bozen.it", "bplaced.com", "bplaced.de", @@ -928,6 +958,9 @@ static const char *domain_suffix[] = { "builders", "building.museum", "bukhara.su", + "bulsan-sudtirol.it", + "bulsan-suedtirol.it", + "bulsan.it", "bungoono.oita.jp", "bungotakada.oita.jp", "bunkyo.tokyo.jp", @@ -1248,6 +1281,7 @@ static const char *domain_suffix[] = { "cloudns.pro", "cloudns.pw", "cloudns.us", + "cloudycluster.net", "club", "club.aero", "club.tw", @@ -1255,11 +1289,13 @@ static const char *domain_suffix[] = { "cm", "cn", "cn-north-1.eb.amazonaws.com.cn", + "cn-northwest-1.eb.amazonaws.com.cn", "cn.com", "cn.eu.org", "cn.it", "cn.ua", "cng.br", + "cnpy.gdn", "cnt.br", "co", "co.ae", @@ -1360,6 +1396,7 @@ static const char *domain_suffix[] = { "com.bh", "com.bi", "com.bm", + "com.bn", "com.bo", "com.br", "com.bs", @@ -1391,6 +1428,7 @@ static const char *domain_suffix[] = { "com.gp", "com.gr", "com.gt", + "com.gu", "com.gy", "com.hk", "com.hn", @@ -1405,6 +1443,7 @@ static const char *domain_suffix[] = { "com.ki", "com.km", "com.kp", + "com.kw", "com.ky", "com.kz", "com.la", @@ -1537,6 +1576,7 @@ static const char *domain_suffix[] = { "cr", "cr.it", "cr.ua", + "crafting.xyz", "crafts.museum", "cranbrook.museum", "creation.museum", @@ -1616,6 +1656,10 @@ static const char *domain_suffix[] = { "date.hokkaido.jp", "dating", "datsun", + "dattolocal.com", + "dattolocal.net", + "dattorelay.com", + "dattoweb.com", "davvenjarga.no", "davvesiida.no", "day", @@ -1628,6 +1672,7 @@ static const char *domain_suffix[] = { "ddnsfree.com", "ddnsgeek.com", "ddnsking.com", + "ddnslive.com", "ddnss.de", "ddnss.org", "ddr.museum", @@ -1718,6 +1763,8 @@ static const char *domain_suffix[] = { "dnsfor.me", "dnshome.de", "dnsiskinky.com", + "dnsking.ch", + "dnsup.net", "dnsupdater.de", "do", "docs", @@ -1811,6 +1858,7 @@ static const char *domain_suffix[] = { "dyndns.ws", "dyndns1.de", "dynns.com", + "dynserv.org", "dynu.net", "dynv6.net", "dynvpn.de", @@ -1858,6 +1906,7 @@ static const char *domain_suffix[] = { "edu.bh", "edu.bi", "edu.bm", + "edu.bn", "edu.bo", "edu.br", "edu.bs", @@ -1885,6 +1934,7 @@ static const char *domain_suffix[] = { "edu.gp", "edu.gr", "edu.gt", + "edu.gu", "edu.gy", "edu.hk", "edu.hn", @@ -1900,6 +1950,7 @@ static const char *domain_suffix[] = { "edu.kn", "edu.kp", "edu.krd", + "edu.kw", "edu.ky", "edu.kz", "edu.la", @@ -1993,6 +2044,7 @@ static const char *domain_suffix[] = { "elvendrell.museum", "elverum.no", "email", + "emb.kw", "embaixada.st", "embetsu.hokkaido.jp", "embroidery.museum", @@ -2122,6 +2174,8 @@ static const char *domain_suffix[] = { "fashion", "fast", "fastlylb.net", + "fastpanel.direct", + "fastvps-server.com", "fauske.no", "fbx-os.fr", "fbxos.fr", @@ -2251,6 +2305,7 @@ static const char *domain_suffix[] = { "fortworth.museum", "forum", "forum.hu", + "forumz.info", "fosnes.no", "fot.br", "foundation", @@ -2271,6 +2326,8 @@ static const char *domain_suffix[] = { "freeboxos.com", "freeboxos.fr", "freeddns.org", + "freeddns.us", + "freedesktop.org", "freemasonry.museum", "freesite.host", "freetls.fastly.net", @@ -2587,7 +2644,6 @@ static const char *domain_suffix[] = { "gon.pk", "gonohe.aomori.jp", "goo", - "goodhands", "goodyear", "goog", "google", @@ -2632,6 +2688,7 @@ static const char *domain_suffix[] = { "gov.bf", "gov.bh", "gov.bm", + "gov.bn", "gov.br", "gov.bs", "gov.bt", @@ -2657,6 +2714,7 @@ static const char *domain_suffix[] = { "gov.gi", "gov.gn", "gov.gr", + "gov.gu", "gov.gy", "gov.hk", "gov.ie", @@ -2672,6 +2730,7 @@ static const char *domain_suffix[] = { "gov.km", "gov.kn", "gov.kp", + "gov.kw", "gov.ky", "gov.kz", "gov.la", @@ -2802,7 +2861,9 @@ static const char *domain_suffix[] = { "gs.vf.no", "gsm.pl", "gt", + "gu", "gu.us", + "guam.gu", "guardian", "gub.uy", "gucci", @@ -2854,6 +2915,7 @@ static const char *domain_suffix[] = { "hakui.ishikawa.jp", "hakusan.ishikawa.jp", "halden.no", + "half.host", "halloffame.museum", "halsa.no", "ham-radio-op.net", @@ -2894,6 +2956,7 @@ static const char *domain_suffix[] = { "hashimoto.wakayama.jp", "hasuda.saitama.jp", "hasura-app.io", + "hasura.app", "hasvik.no", "hatogaya.saitama.jp", "hatoyama.saitama.jp", @@ -2941,6 +3004,7 @@ static const char *domain_suffix[] = { "hgtv", "hi.cn", "hi.us", + "hicam.net", "hichiso.gifu.jp", "hida.gifu.jp", "hidaka.hokkaido.jp", @@ -3242,6 +3306,7 @@ static const char *domain_suffix[] = { "ind.br", "ind.gt", "ind.in", + "ind.kw", "ind.tn", "inderoy.no", "indian.museum", @@ -3267,6 +3332,7 @@ static const char *domain_suffix[] = { "info.cx", "info.ec", "info.et", + "info.gu", "info.ht", "info.hu", "info.ke", @@ -3481,7 +3547,6 @@ static const char *domain_suffix[] = { "iwate.iwate.jp", "iwate.jp", "iwatsuki.saitama.jp", - "iwc", "iwi.nz", "iyo.ehime.jp", "iz.hr", @@ -3528,7 +3593,6 @@ static const char *domain_suffix[] = { "jinsekikogen.hiroshima.jp", "jio", "jl.cn", - "jlc", "jll", "jmp", "jnj", @@ -4020,6 +4084,7 @@ static const char *domain_suffix[] = { "kvinnherad.no", "kviteseid.no", "kvitsoy.no", + "kw", "kwp.gov.pl", "kwpsp.gov.pl", "ky", @@ -4207,6 +4272,7 @@ static const char *domain_suffix[] = { "linde", "lindesnes.no", "link", + "linkitools.space", "linkyard-cloud.ch", "linkyard.cloud", "linz.museum", @@ -4398,6 +4464,8 @@ static const char *domain_suffix[] = { "matsuzaki.shizuoka.jp", "matta-varjjat.no", "mattel", + "mayfirst.info", + "mayfirst.org", "mazowsze.pl", "mazury.pl", "mb.ca", @@ -4444,6 +4512,7 @@ static const char *domain_suffix[] = { "meeres.museum", "meet", "meguro.tokyo.jp", + "mein-iserv.de", "mein-vigor.de", "meiwa.gunma.jp", "meiwa.mie.jp", @@ -4455,9 +4524,9 @@ static const char *domain_suffix[] = { "meme", "memorial", "memorial.museum", + "memset.net", "men", "menu", - "meo", "meraker.no", "merckmsd", "merseine.nu", @@ -4596,6 +4665,7 @@ static const char *domain_suffix[] = { "miners.museum", "mini", "mining.museum", + "miniserver.com", "minnesota.museum", "mino.gifu.jp", "minobu.yamanashi.jp", @@ -4821,6 +4891,8 @@ static const char *domain_suffix[] = { "myactivedirectory.com", "myasustor.com", "mycd.eu", + "mydatto.com", + "mydatto.net", "myddns.rocks", "mydissent.net", "mydrobo.com", @@ -4831,6 +4903,7 @@ static const char *domain_suffix[] = { "myftp.biz", "myftp.org", "myhome-server.de", + "myiphost.com", "myjino.ru", "mykolaiv.ua", "mymailer.com.tw", @@ -4839,6 +4912,7 @@ static const char *domain_suffix[] = { "mypep.link", "mypets.ws", "myphotos.cc", + "mypi.co", "mypsx.net", "myqnapcloud.com", "myravendb.com", @@ -4853,6 +4927,7 @@ static const char *domain_suffix[] = { "mz", "n.bg", "n.se", + "n4t.co", "na", "na.it", "naamesjevuemie.no", @@ -5030,6 +5105,7 @@ static const char *domain_suffix[] = { "net.bb", "net.bh", "net.bm", + "net.bn", "net.bo", "net.br", "net.bs", @@ -5056,6 +5132,7 @@ static const char *domain_suffix[] = { "net.gp", "net.gr", "net.gt", + "net.gu", "net.gy", "net.hk", "net.hn", @@ -5072,6 +5149,7 @@ static const char *domain_suffix[] = { "net.kg", "net.ki", "net.kn", + "net.kw", "net.ky", "net.kz", "net.la", @@ -5267,6 +5345,7 @@ static const char *domain_suffix[] = { "nokia", "nom.ad", "nom.ae", + "nom.af", "nom.ag", "nom.ai", "nom.al", @@ -5275,10 +5354,12 @@ static const char *domain_suffix[] = { "nom.es", "nom.fr", "nom.gd", + "nom.ge", "nom.gl", "nom.gt", "nom.hn", "nom.im", + "nom.ke", "nom.km", "nom.li", "nom.mg", @@ -5295,6 +5376,8 @@ static const char *domain_suffix[] = { "nom.ro", "nom.rs", "nom.si", + "nom.st", + "nom.tj", "nom.tm", "nom.ug", "nom.uy", @@ -5333,6 +5416,9 @@ static const char *domain_suffix[] = { "nov.su", "novara.it", "now", + "now-dns.net", + "now-dns.org", + "now-dns.top", "now.sh", "nowaruda.pl", "nowruz", @@ -5352,6 +5438,7 @@ static const char *domain_suffix[] = { "nt.edu.au", "nt.no", "nt.ro", + "ntdll.top", "ntr.br", "ntt", "nu", @@ -5372,16 +5459,21 @@ static const char *domain_suffix[] = { "nym.by", "nym.bz", "nym.gr", + "nym.gy", + "nym.ie", "nym.kz", "nym.la", + "nym.lc", "nym.li", "nym.lt", "nym.lu", "nym.me", + "nym.mn", "nym.mx", "nym.nz", "nym.pe", "nym.pt", + "nym.ro", "nym.sk", "nym.su", "nym.sx", @@ -5516,6 +5608,7 @@ static const char *domain_suffix[] = { "onagawa.miyagi.jp", "one", "ong", + "ong.br", "onga.fukuoka.jp", "onion", "onjuku.chiba.jp", @@ -5579,6 +5672,7 @@ static const char *domain_suffix[] = { "org.bh", "org.bi", "org.bm", + "org.bn", "org.bo", "org.br", "org.bs", @@ -5608,6 +5702,7 @@ static const char *domain_suffix[] = { "org.gp", "org.gr", "org.gt", + "org.gu", "org.gy", "org.hk", "org.hn", @@ -5626,6 +5721,7 @@ static const char *domain_suffix[] = { "org.km", "org.kn", "org.kp", + "org.kw", "org.ky", "org.kz", "org.la", @@ -5771,6 +5867,7 @@ static const char *domain_suffix[] = { "owani.aomori.jp", "owariasahi.aichi.jp", "own.pm", + "ownip.net", "ownprovider.com", "ox.rs", "oxford.museum", @@ -5808,7 +5905,6 @@ static const char *domain_suffix[] = { "palmsprings.museum", "panama.museum", "panasonic", - "panerai", "pantheonsite.io", "parachuting.aero", "paragliding.aero", @@ -5952,6 +6048,7 @@ static const char *domain_suffix[] = { "poltava.ua", "pomorskie.pl", "pomorze.pl", + "ponpes.id", "pordenone.it", "porn", "porsanger.no", @@ -6429,7 +6526,6 @@ static const char *domain_suffix[] = { "saogonca.br", "saotome.st", "sap", - "sapo", "sar.it", "sardegna.it", "sardinia.it", @@ -6840,6 +6936,7 @@ static const char *domain_suffix[] = { "sosa.chiba.jp", "sosnowiec.pl", "soundandvision.museum", + "soundcast.me", "southcarolina.museum", "southwest.museum", "sowa.ibaraki.jp", @@ -6878,7 +6975,6 @@ static const char *domain_suffix[] = { "ssl.origin.cdn77-secure.org", "st", "st.no", - "stackspace.space", "stada", "stadt.museum", "stage.nodeart.io", @@ -7127,6 +7223,7 @@ static const char *domain_suffix[] = { "tc", "tci", "tcm.museum", + "tcp4.me", "td", "tdk", "te.it", @@ -7142,7 +7239,6 @@ static const char *domain_suffix[] = { "tel", "tel.tr", "tele.amune.org", - "telecity", "telefonica", "telekommunikation.museum", "television.museum", @@ -7161,6 +7257,7 @@ static const char *domain_suffix[] = { "terni.it", "ternopil.ua", "teshikaga.hokkaido.jp", + "test-iserv.de", "test.ru", "test.tj", "teva", @@ -7354,6 +7451,10 @@ static const char *domain_suffix[] = { "travelersinsurance", "trd.br", "tree.museum", + "trentin-sud-tirol.it", + "trentin-sudtirol.it", + "trentin-sued-tirol.it", + "trentin-suedtirol.it", "trentino-a-adige.it", "trentino-aadige.it", "trentino-alto-adige.it", @@ -7375,6 +7476,10 @@ static const char *domain_suffix[] = { "trentinosudtirol.it", "trentinosued-tirol.it", "trentinosuedtirol.it", + "trentinsud-tirol.it", + "trentinsudtirol.it", + "trentinsued-tirol.it", + "trentinsuedtirol.it", "trento.it", "treviso.it", "trieste.it", @@ -7581,6 +7686,7 @@ static const char *domain_suffix[] = { "uto.kumamoto.jp", "utsira.no", "utsunomiya.tochigi.jp", + "utwente.io", "uvic.museum", "uw.gov.pl", "uwajima.ehime.jp", @@ -7617,7 +7723,9 @@ static const char *domain_suffix[] = { "valled-aosta.it", "valledaosta.it", "vallee-aoste.it", + "vallee-d-aoste.it", "valleeaoste.it", + "valleedaoste.it", "valley.museum", "vana", "vang.no", @@ -7695,12 +7803,13 @@ static const char *domain_suffix[] = { "vipsinaapp.com", "virgin", "virginia.museum", + "virtual-user.de", "virtual.museum", + "virtualuser.de", "virtueeldomein.nl", "virtuel.museum", "visa", "vision", - "vista", "vistaprint", "viterbo.it", "viva", @@ -7729,6 +7838,7 @@ static const char *domain_suffix[] = { "voting", "voto", "voyage", + "vpndns.net", "vpnplus.to", "vr.it", "vs.it", @@ -7784,6 +7894,7 @@ static const char *domain_suffix[] = { "web.bo", "web.co", "web.do", + "web.gu", "web.id", "web.lk", "web.nf", @@ -7875,6 +7986,7 @@ static const char *domain_suffix[] = { "wzmiuw.gov.pl", "x.bg", "x.se", + "x443.pw", "xbox", "xen.prgmr.com", "xenapponazure.com", @@ -7916,6 +8028,7 @@ static const char *domain_suffix[] = { "xn--55qx5d", "xn--55qx5d.cn", "xn--55qx5d.hk", + "xn--55qx5d.xn--j6w193g", "xn--5js045d.jp", "xn--5rtp49c.jp", "xn--5rtq34k.jp", @@ -7951,6 +8064,7 @@ static const char *domain_suffix[] = { "xn--b-5ga.nordland.no", "xn--b-5ga.telemark.no", "xn--b4w605ferd", + "xn--balsan-sdtirol-nsb.it", "xn--bck1b9a5dre4c", "xn--bdddj-mrabd.no", "xn--bearalvhki-y4a.no", @@ -7964,15 +8078,19 @@ static const char *domain_suffix[] = { "xn--blt-elab.no", "xn--bmlo-gra.no", "xn--bod-2na.no", + "xn--bozen-sdtirol-2ob.it", "xn--brnny-wuac.no", "xn--brnnysund-m8ac.no", "xn--brum-voa.no", "xn--btsfjord-9za.no", + "xn--bulsan-sdtirol-nsb.it", "xn--c1avg", "xn--c1avg.xn--90a3ac", "xn--c2br7g", "xn--c3s14m.jp", "xn--cck2b3b", + "xn--cesena-forl-mcb.it", + "xn--cesenaforl-i8a.it", "xn--cg4bki", "xn--ciqpn.hk", "xn--clchc0ea0b2g2a9gcd", @@ -8013,6 +8131,8 @@ static const char *domain_suffix[] = { "xn--fl-zia.no", "xn--flor-jra.no", "xn--flw351e", + "xn--forl-cesena-fcb.it", + "xn--forlcesena-c8a.it", "xn--fpcrj9c3d", "xn--frde-gra.no", "xn--frna-woa.no", @@ -8030,6 +8150,7 @@ static const char *domain_suffix[] = { "xn--gls-elac.no", "xn--gmq050i.hk", "xn--gmqw5a.hk", + "xn--gmqw5a.xn--j6w193g", "xn--h-2fa.no", "xn--h1aegh.museum", "xn--h2breg3eve", @@ -8156,6 +8277,7 @@ static const char *domain_suffix[] = { "xn--muost-0qa.no", "xn--mxtq1m", "xn--mxtq1m.hk", + "xn--mxtq1m.xn--j6w193g", "xn--ngbc5azd", "xn--ngbe9e0a", "xn--ngbrx", @@ -8177,6 +8299,7 @@ static const char *domain_suffix[] = { "xn--o3cyx2a.xn--o3cw4h", "xn--od0alg.cn", "xn--od0alg.hk", + "xn--od0alg.xn--j6w193g", "xn--od0aq3b.hk", "xn--ogbpf8fl", "xn--oppegrd-ixa.no", @@ -8223,6 +8346,7 @@ static const char *domain_suffix[] = { "xn--s9brj9c", "xn--sandnessjen-ogb.no", "xn--sandy-yua.no", + "xn--sdtirol-n2a.it", "xn--seral-lra.no", "xn--ses554g", "xn--sgne-gra.no", @@ -8257,12 +8381,21 @@ static const char *domain_suffix[] = { "xn--tnsberg-q1a.no", "xn--tor131o.jp", "xn--trany-yua.no", + "xn--trentin-sd-tirol-rzb.it", + "xn--trentin-sdtirol-7vb.it", + "xn--trentino-sd-tirol-c3b.it", + "xn--trentino-sdtirol-szb.it", + "xn--trentinosd-tirol-rzb.it", + "xn--trentinosdtirol-7vb.it", + "xn--trentinsd-tirol-6vb.it", + "xn--trentinsdtirol-nsb.it", "xn--trgstad-r1a.no", "xn--trna-woa.no", "xn--troms-zua.no", "xn--tysvr-vra.no", "xn--uc0atv.hk", "xn--uc0atv.tw", + "xn--uc0atv.xn--j6w193g", "xn--uc0ay4a.hk", "xn--uist22h.jp", "xn--uisz3g.jp", @@ -8270,6 +8403,10 @@ static const char *domain_suffix[] = { "xn--unup4y", "xn--uuwu58a.jp", "xn--vads-jra.no", + "xn--valle-aoste-ebb.it", + "xn--valle-d-aoste-ehb.it", + "xn--valleaoste-e7a.it", + "xn--valledaoste-ebb.it", "xn--vard-jra.no", "xn--vegrshei-c0a.no", "xn--vermgensberater-ctb", @@ -8289,6 +8426,7 @@ static const char *domain_suffix[] = { "xn--w4r85el8fhu5dnra", "xn--w4rs40l", "xn--wcvs22d.hk", + "xn--wcvs22d.xn--j6w193g", "xn--wgbh1c", "xn--wgbl6a", "xn--xhq521b", @@ -8305,7 +8443,6 @@ static const char *domain_suffix[] = { "xn--zf0avx.hk", "xn--zfr164b", "xnbay.com", - "xperia", "xs4all.space", "xxx", "xyz", @@ -8449,6 +8586,7 @@ static const char *domain_suffix[] = { "zaporizhzhia.ua", "zappos", "zapto.org", + "zapto.xyz", "zara", "zarow.pl", "zentsuji.kagawa.jp", @@ -8463,6 +8601,7 @@ static const char *domain_suffix[] = { "zlg.br", "zm", "zone", + "zone.id", "zoological.museum", "zoology.museum", "zp.gov.pl", diff --git a/view.c b/view.c @@ -18,6 +18,16 @@ static int is_active_frame(struct session *ses, struct f_data_c *f); static void send_open_in_new_xterm(struct terminal *term, void *open_window_, void *ses_); static void (* const send_open_in_new_xterm_ptr)(struct terminal *, void *fn_, void *ses_) = send_open_in_new_xterm; +/* FIXME: remove */ +static void free_format_text_cache_entry(struct form_state *fs) +{ + struct format_text_cache_entry *ftce = fs->ftce; + if (!ftce) + return; + fs->ftce = NULL; + free(ftce); +} + struct view_state *create_vs(void) { struct view_state *vs; @@ -33,16 +43,6 @@ struct view_state *create_vs(void) } /* FIXME: remove */ -static void free_format_text_cache_entry(struct form_state *fs) -{ - struct format_text_cache_entry *ftce = fs->ftce; - if (!ftce) - return; - fs->ftce = NULL; - free(ftce); -} - -/* FIXME: remove */ static void free_form_state(struct form_state *fs) { free_format_text_cache_entry(fs); @@ -720,7 +720,9 @@ static void draw_form_entry(struct terminal *t, struct f_data_c *f, struct link int vy = vs->view_pos; struct form_state *fs; struct form_control *form = l->form; - int i, x, y; + int i, x, y, td; + size_t sl; + if (!form) { internal("link %d has no form", (int)(l - f->f_data->links)); return; @@ -734,15 +736,15 @@ static void draw_form_entry(struct terminal *t, struct f_data_c *f, struct link case FC_TEXT: case FC_PASSWORD: case FC_FILE: - /* - if (fs->state >= fs->vpos + form->size) fs->vpos = fs->state - form->size + 1; - if (fs->state < fs->vpos) fs->vpos = fs->state; - */ if ((size_t)fs->vpos > strlen(cast_const_char fs->string)) fs->vpos = (int)strlen(cast_const_char fs->string); - while ((size_t)fs->vpos < strlen(cast_const_char fs->string) && textptr_diff(fs->string + fs->state, fs->string + fs->vpos, f->f_data->opt.cp) >= form->size) { + sl = strlen((char *)fs->string); + td = textptr_diff(fs->string + fs->state, fs->string + fs->vpos, f->f_data->opt.cp); + + while (fs->vpos < sl && td >= form->size) { unsigned char *p = fs->string + fs->vpos; FWD_UTF_8(p); fs->vpos = (int)(p - fs->string); + td--; } while (fs->vpos > fs->state) { unsigned char *p = fs->string + fs->vpos; @@ -905,14 +907,14 @@ static void draw_frame_lines(struct session *ses, struct frameset_desc *fsd, int for (i = 0; i < fsd->x; i++) { int wwx = fsd->f[i].xw; if (i) { - fill_area(t, x, y + 1, 1, wwy, 179, ATTR_FRAME | get_attribute(ses->ds.t_text_color, ses->ds.t_background_color)); + fill_area(t, x, y + 1, 1, wwy, 179, ATTR_FRAME | get_session_attribute(ses, 0)); if (j == fsd->y - 1) set_xchar(t, x, y + wwy + 1, 3); } else if (j) set_xchar(t, x, y, 0); if (j) { - fill_area(t, x + 1, y, wwx, 1, 196, ATTR_FRAME | get_attribute(ses->ds.t_text_color, ses->ds.t_background_color)); + fill_area(t, x + 1, y, wwx, 1, 196, ATTR_FRAME | get_session_attribute(ses, 0)); if (i == fsd->x - 1) set_xchar(t, x + wwx + 1, y, 1); } else if (i) set_xchar(t, x, y, 2); - if (i && j) set_char(t, x, y, 197, ATTR_FRAME | get_attribute(ses->ds.t_text_color, ses->ds.t_background_color)); + if (i && j) set_char(t, x, y, 197, ATTR_FRAME | get_session_attribute(ses, 0)); /*if (fsd->f[j * fsd->x + i].subframe) { draw_frame_lines(ses, fsd->f[j * fsd->x + i].subframe, x + 1, y + 1); }*/ @@ -940,7 +942,7 @@ void draw_doc(struct terminal *t, void *scr_) if (!scr->parent) set_cursor(t, 0, 0, 0, 0); else set_cursor(t, xp, yp, xp, yp); } - fill_area(t, xp, yp, xw, yw, ' ', get_attribute(ses->ds.t_text_color, ses->ds.t_background_color)); + fill_area(t, xp, yp, xw, yw, ' ', get_session_attribute(ses, 0)); #ifdef G } else { long color = dip_get_color_sRGB(ses->ds.g_background_color /* 0x808080 */); @@ -1016,7 +1018,7 @@ void draw_doc(struct terminal *t, void *scr_) free_link(scr); scr->xl = vx; scr->yl = vy; - fill_area(t, xp, yp, xw, yw, ' ', scr->f_data->y ? scr->f_data->bg : get_attribute(ses->ds.t_text_color, ses->ds.t_background_color)); + fill_area(t, xp, yp, xw, yw, ' ', scr->f_data->y ? scr->f_data->bg : get_session_attribute(ses, 0)); if (!scr->f_data->y) return; while (vs->view_pos >= scr->f_data->y) vs->view_pos -= yw ? yw : 1; if (vs->view_pos < 0) vs->view_pos = 0; @@ -3719,11 +3721,6 @@ unsigned char *print_current_title(struct session *ses) return print_current_titlex(current_frame(ses), ses->term->x); } -static inline int find_in_cache_idn(unsigned char *xurl, struct cache_entry **ce) -{ - return find_in_cache(xurl, ce); -} - void loc_msg(struct terminal *term, struct location *lo, struct f_data_c *frame) { struct cache_entry *ce; @@ -3740,8 +3737,9 @@ void loc_msg(struct terminal *term, struct location *lo, struct f_data_c *frame) a = display_url(term, lo->url, 1); add_to_str(&s, &l, a); free(a); - if (!find_in_cache_idn(lo->url, &ce)) { - unsigned char *start, *end; + if (!find_in_cache(lo->url, &ce)) { + unsigned char *start; + size_t len; if (ce->ip_address) { add_to_str(&s, &l, cast_uchar "\n"); if (!strchr(cast_const_char ce->ip_address, ' ')) @@ -3754,10 +3752,10 @@ void loc_msg(struct terminal *term, struct location *lo, struct f_data_c *frame) add_to_str(&s, &l, cast_uchar "\n"); add_to_str(&s, &l, get_text_translation(TEXT_(T_SIZE), term)); add_to_str(&s, &l, cast_uchar ": "); - get_file_by_term(NULL, ce, &start, &end, NULL); + get_file_by_term(NULL, ce, &start, &len, NULL); if (ce->decompressed) { unsigned char *enc; - add_num_to_str(&s, &l, end - start); + add_unsigned_long_num_to_str(&s, &l, len); enc = get_content_encoding(ce->head, ce->url, 0); if (enc) { add_to_str(&s, &l, cast_uchar " ("); @@ -3857,7 +3855,7 @@ void head_msg(struct session *ses) msg_box(ses->term, NULL, TEXT_(T_HEADER_INFO), AL_LEFT, TEXT_(T_YOU_ARE_NOWHERE), MSG_BOX_END, NULL, 1, TEXT_(T_OK), msg_box_null, B_ENTER | B_ESC); return; } - if (!find_in_cache_idn(cur_loc(ses)->url, &ce)) { + if (!find_in_cache(cur_loc(ses)->url, &ce)) { if (ce->head) s = stracpy(ce->head); else s = stracpy(cast_uchar ""); len = (int)strlen(cast_const_char s) - 1; diff --git a/view_gr.c b/view_gr.c @@ -120,7 +120,8 @@ void g_text_draw(struct f_data_c *fd, struct g_object *t_, int x, int y) fs = find_form_state(fd, form); switch (form->type) { struct style *inv; - int in, lid; + int in, lid, td; + size_t sl; case FC_RADIO: if (link && fd->active @@ -169,15 +170,14 @@ void g_text_draw(struct f_data_c *fd, struct g_object *t_, int x, int y) case FC_TEXT: case FC_PASSWORD: case FC_FILE: - /* - if (fs->state >= fs->vpos + form->size) fs->vpos = fs->state - form->size + 1; - if (fs->state < fs->vpos) fs->vpos = fs->state; - */ if ((size_t)fs->vpos > strlen(cast_const_char fs->string)) fs->vpos = (int)strlen(cast_const_char fs->string); - while ((size_t)fs->vpos < strlen(cast_const_char fs->string) && textptr_diff(fs->string + fs->state, fs->string + fs->vpos, fd->f_data->opt.cp) >= form->size) { + sl = strlen(cast_const_char fs->string); + td = textptr_diff(fs->string + fs->state, fs->string + fs->vpos, fd->f_data->opt.cp); + while (fs->vpos < sl && td >= form->size) { unsigned char *p = fs->string + fs->vpos; FWD_UTF_8(p); fs->vpos = (int)(p - fs->string); + td--; } while (fs->vpos > fs->state) { unsigned char *p = fs->string + fs->vpos; @@ -1376,13 +1376,13 @@ void draw_title(struct f_data_c *f) } w = g_text_width(bfu_style_bw, title); z = 0; - g_print_text(dev, 0, 0, bfu_style_bw, cast_uchar G_LEFT_ARROW, &z); + g_print_text(dev, 0, 0, !proxies.only_proxies ? bfu_style_bw : bfu_style_wb, cast_uchar G_LEFT_ARROW, &z); f->ses->back_size = z; b = (dev->size.x2 - w) - 16; if (b < z) b = z; - drv->fill_area(dev, z, 0, b, G_BFU_FONT_SIZE, bfu_bg_color); - g_print_text(dev, b, 0, bfu_style_bw, title, &b); - drv->fill_area(dev, b, 0, dev->size.x2, G_BFU_FONT_SIZE, bfu_bg_color); + drv->fill_area(dev, z, 0, b, G_BFU_FONT_SIZE, !proxies.only_proxies ? bfu_bg_color : bfu_fg_color); + g_print_text(dev, b, 0, !proxies.only_proxies ? bfu_style_bw : bfu_style_wb, title, &b); + drv->fill_area(dev, b, 0, dev->size.x2, G_BFU_FONT_SIZE, !proxies.only_proxies ? bfu_bg_color : bfu_fg_color); free(title); } diff --git a/x.c b/x.c @@ -66,6 +66,7 @@ #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xlocale.h> +#include <X11/Xproto.h> #include <X11/Xutil.h> #define X_BORDER_WIDTH 4 @@ -73,8 +74,6 @@ #define X_MAX_CLIPBOARD_SIZE (15*1024*1024) -#define XPIXMAPP(a) ((struct x_pixmapa*)(a)) - static int x_default_window_width; static int x_default_window_height; @@ -84,8 +83,11 @@ static void x_convert_to_216(char *data, int x, int y, int skip); static void selection_request(XEvent *event); -static int x_fd; /* x socket */ static Display *x_display = NULL; /* display */ +static Visual *x_default_visual; +static XVisualInfo vinfo; + +static int x_fd; /* x socket */ static unsigned char *x_display_string = NULL; static int x_screen; /* screen */ static int x_display_height, x_display_width; /* screen dimensions */ @@ -94,10 +96,15 @@ static int x_depth, x_bitmap_bpp; /* bits per pixel and bytes per pixel */ static int x_bitmap_scanline_pad; /* bitmap scanline_padding in bytes */ static int x_bitmap_bit_order; +static XColor *static_color_map = NULL; static unsigned char x_have_palette; static unsigned char x_use_static_color_table; static unsigned char *static_color_table = NULL; -static XColor *static_color_map = NULL; +struct { + unsigned char failure; + unsigned char extra_allocated; + unsigned short alloc_count; +} *static_color_struct = NULL; #define X_STATIC_COLORS (x_depth < 8 ? 8 : 216) #define X_STATIC_CODE (x_depth < 8 ? 801 : 833) @@ -107,30 +114,34 @@ static int fake_window_initialized = 0; static GC x_normal_gc = 0, x_copy_gc = 0, x_drawbitmap_gc = 0, x_scroll_gc = 0; static long x_normal_gc_color; static struct rect x_scroll_gc_rect; -static Colormap x_colormap; +static Colormap x_default_colormap, x_colormap; static Atom x_delete_window_atom, x_wm_protocols_atom, x_sel_atom, x_targets_atom, x_utf8_string_atom; -static Visual *x_default_visual; static Pixmap x_icon = 0; static XIM xim = NULL; extern struct graphics_driver x_driver; -static unsigned char *x_driver_param=NULL; -static int n_wins; /* number of windows */ +static unsigned char *x_driver_param = NULL; +static int n_wins = 0; /* number of windows */ +static struct list_head bitmaps = { &bitmaps, &bitmaps }; -#define X_TYPE_PIXMAP 1 -#define X_TYPE_IMAGE 2 +#define XPIXMAPP(a) ((struct x_pixmapa *)(a)) -struct x_pixmapa -{ +#define X_TYPE_NOTHING 0 +#define X_TYPE_PIXMAP 1 +#define X_TYPE_IMAGE 2 + +struct x_pixmapa { unsigned char type; union { XImage *image; - Pixmap *pixmap; - }data; + Pixmap pixmap; + } data; + list_entry_1st + list_entry_last }; @@ -166,8 +177,8 @@ static void x_wait_for_event(void) static void x_process_events(void *data); -static unsigned char flush_in_progress=0; -static unsigned char process_events_in_progress=0; +static unsigned char flush_in_progress = 0; +static unsigned char process_events_in_progress = 0; static inline void X_SCHEDULE_PROCESS_EVENTS(void) { @@ -183,7 +194,7 @@ static void x_do_flush(void *ignore) * tipne Xy, tak se nic nedeje, maximalne se zavola XFlush na blbej * display, ale Xy se nepodelaj */ - flush_in_progress=0; + flush_in_progress = 0; XFlush(x_display); X_SCHEDULE_PROCESS_EVENTS(); } @@ -196,20 +207,91 @@ static inline void X_FLUSH(void) } } +static void x_pixmap_failed(void *ignore); + +static int (*original_error_handler)(Display *, XErrorEvent *) = NULL; +static unsigned char pixmap_mode = 0; + +static int pixmap_handler(Display *d, XErrorEvent *e) +{ + if (pixmap_mode == 2) { + if (e->request_code == X_CreatePixmap) { + pixmap_mode = 1; + register_bottom_half(x_pixmap_failed, NULL); + return 0; + } + } + if (pixmap_mode == 1) { + if (e->request_code == X_CreatePixmap + || e->request_code == X_PutImage + || e->request_code == X_CopyArea + || e->request_code == X_FreePixmap) { + return 0; + } + } + return original_error_handler(d, e); +} + +static void x_pixmap_failed(void *no_reinit) +{ + struct x_pixmapa *p; + struct list_head *lp; + + foreach(struct x_pixmapa, p, lp, bitmaps) { + if (p->type == X_TYPE_PIXMAP) { + XFreePixmap(x_display, p->data.pixmap); + p->type = X_TYPE_NOTHING; + } + } + + XSync(x_display, False); + X_SCHEDULE_PROCESS_EVENTS(); + + XSetErrorHandler(original_error_handler); + original_error_handler = NULL; + pixmap_mode = 0; + + if (!no_reinit) + flush_bitmaps(1, 1, 1); +} + +static void setup_pixmap_handler(void) +{ + original_error_handler = XSetErrorHandler(pixmap_handler); + pixmap_mode = 2; +} + +static void undo_pixmap_handler(void) +{ + if (pixmap_mode == 2) { + XSetErrorHandler(original_error_handler); + original_error_handler = NULL; + pixmap_mode = 0; + } + if (pixmap_mode == 1) { + x_pixmap_failed(NULL); + } + unregister_bottom_half(x_pixmap_failed, NULL); +} + static int (*old_error_handler)(Display *, XErrorEvent *) = NULL; -static int failure_happened; +static unsigned char failure_happened; +static unsigned char test_request_code; static int failure_handler(Display *d, XErrorEvent *e) { + if (e->request_code != test_request_code) + return old_error_handler(d, e); failure_happened = 1; return 0; } -static void x_prepare_for_failure(void) +static void x_prepare_for_failure(unsigned char code) { if (old_error_handler) internal("x_prepare_for_failure: double call"); failure_happened = 0; + test_request_code = code; old_error_handler = XSetErrorHandler(failure_handler); } @@ -231,76 +313,270 @@ static void x_clip_number(int *n,int l,int h) *n = h; } -static void x_set_palette(void) +static const unsigned char alloc_sequence_216[216] = { 0, 215, 30, 185, 5, 35, 180, 210, 86, 203, 23, 98, 192, 119, 126, 43, 173, 12, 74, 140, 188, 161, 27, 54, 95, 204, 17, 114, 198, 11, 107, 113, 60, 65, 68, 81, 102, 108, 120, 132, 146, 164, 20, 89, 92, 158, 170, 191, 6, 37, 40, 46, 49, 52, 57, 123, 129, 135, 151, 154, 175, 178, 195, 207, 24, 71, 77, 78, 101, 143, 149, 167, 2, 8, 14, 18, 29, 32, 59, 62, 66, 72, 83, 84, 90, 96, 104, 110, 116, 125, 131, 137, 138, 144, 156, 162, 168, 182, 186, 197, 200, 209, 212, 1, 3, 4, 7, 9, 10, 13, 15, 16, 19, 21, 22, 25, 26, 28, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 53, 55, 56, 58, 61, 63, 64, 67, 69, 70, 73, 75, 76, 79, 80, 82, 85, 87, 88, 91, 93, 94, 97, 99, 100, 103, 105, 106, 109, 111, 112, 115, 117, 118, 121, 122, 124, 127, 128, 130, 133, 134, 136, 139, 141, 142, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 163, 165, 166, 169, 171, 172, 174, 176, 177, 179, 181, 183, 184, 187, 189, 190, 193, 194, 196, 199, 201, 202, 205, 206, 208, 211, 213, 214 }; + +static void x_fill_color_table(XColor colors[256], unsigned q) { unsigned int a; + unsigned rgb[3]; unsigned int limit = 1U << x_depth; - if (x_use_static_color_table) - XStoreColors(x_display, x_colormap, static_color_map, (int)limit); - else { - XColor colors[256]; - for (a = 0; a < limit; a++) { - unsigned rgb[3]; - q_palette(limit, a, 65535, rgb); - colors[a].red = rgb[0]; - colors[a].green = rgb[1]; - colors[a].blue = rgb[2]; - colors[a].pixel = a; - colors[a].flags = DoRed | DoGreen | DoBlue; - } - XStoreColors(x_display, x_colormap, colors, (int)limit); + for (a = 0; a < limit; a++) { + q_palette(q, a, 65535, rgb); + colors[a].red = rgb[0]; + colors[a].green = rgb[1]; + colors[a].blue = rgb[2]; + colors[a].pixel = a; + colors[a].flags = DoRed | DoGreen | DoBlue; } +} - X_FLUSH(); +static double rgb_distance_with_border(int r1, int g1, int b1, int r2, int g2, int b2) +{ + double distance = rgb_distance(r1, g1, b1, r2, g2, b2); + if (!r1) + distance += r2 * 4294967296.; + if (!g1) + distance += g2 * 4294967296.; + if (!b1) + distance += b2 * 4294967296.; + if (r1 == 0xffff) + distance += (0xffff - r2) * 4294967296.; + if (g1 == 0xffff) + distance += (0xffff - g2) * 4294967296.; + if (b1 == 0xffff) + distance += (0xffff - b2) * 4294967296.; + return distance; } -static unsigned char get_nearest_color(unsigned rgb[3]) +static int get_nearest_color(unsigned rgb[3]) { int j; - double best_distance = 0; + double distance, best_distance = 0; int best = -1; for (j = 0; j < 1 << x_depth; j++) { - double distance; - if ((static_color_map[j].flags & (DoRed | DoGreen | DoBlue)) != (DoRed | DoGreen | DoBlue)) + if (static_color_struct[j].failure) continue; - distance = rgb_distance(rgb[0], rgb[1], rgb[2], static_color_map[j].red, static_color_map[j].green, static_color_map[j].blue); + distance = rgb_distance_with_border(rgb[0], rgb[1], rgb[2], static_color_map[j].red, static_color_map[j].green, static_color_map[j].blue); if (best < 0 || distance < best_distance) { best = j; best_distance = distance; } } - return (unsigned char)best; + return best; +} + +static int swap_color(int c, XColor *xc, int test_count, double *distance, unsigned rgb[3]) +{ + unsigned long old_px, new_px; + double new_distance; + + /* + * The manual page on XAllocColor says that it returns the closest + * color. + * In reality, it fails if it can't allocate the color. + * + * In case there were some other implementations that return the + * closest color, we check the distance after allocation and we fail if + * the distance would be increased. + */ + if (!XAllocColor(x_display, x_default_colormap, xc)) + return -1; + new_px = xc->pixel; + new_distance = rgb_distance(xc->red, xc->green, xc->blue, rgb[0], rgb[1], rgb[2]); + if (new_px >= 256 + || (test_count && (static_color_struct[new_px].alloc_count || static_color_struct[new_px].extra_allocated)) + || new_distance > *distance) { + XFreeColors(x_display, x_default_colormap, &xc->pixel, 1, 0); + return -1; + } + + old_px = static_color_table[c]; + static_color_struct[old_px].alloc_count--; + XFreeColors(x_display, x_default_colormap, &old_px, 1, 0); + + static_color_map[new_px] = *xc; + static_color_struct[new_px].alloc_count++; + static_color_struct[new_px].failure = 0; + static_color_struct[new_px].extra_allocated = 1; + static_color_table[c] = new_px; + *distance = new_distance; + + return 0; } static unsigned char *x_query_palette(void) { + unsigned rgb[3]; int i; int some_valid = 0; - if (x_depth > 8) - return stracpy(cast_uchar "Static color supported for up to 8-bit depth\n"); - if ((int)sizeof(XColor) > INT_MAX >> x_depth) overalloc(); - static_color_map = mem_calloc(sizeof(XColor) << x_depth); - for (i = 0; i < 1 << x_depth; i++) { + int do_alloc = vinfo.class == PseudoColor; + retry: + if (sizeof(XColor) > INT_MAX >> x_depth) overalloc(); + if (sizeof(*static_color_struct) > INT_MAX >> x_depth) overalloc(); + if (!static_color_map) + static_color_map = xmalloc(sizeof(XColor) << x_depth); + if (!static_color_struct) + static_color_struct = xmalloc(sizeof(*static_color_struct) << x_depth); + + memset(static_color_map, 0, sizeof(XColor) << x_depth); + memset(static_color_struct, 0, sizeof(*static_color_struct) << x_depth); + for (i = 0; i < 1 << x_depth; i++) static_color_map[i].pixel = i; - x_prepare_for_failure(); - XQueryColor(x_display, XDefaultColormap(x_display, x_screen), &static_color_map[i]); - if (!x_test_for_failure() && (static_color_map[i].flags & (DoRed | DoGreen | DoBlue)) == (DoRed | DoGreen | DoBlue)) - some_valid = 1; - else - memset(&static_color_map[i], 0, sizeof(XColor)); + x_prepare_for_failure(X_QueryColors); + XQueryColors(x_display, x_default_colormap, static_color_map, 1 << x_depth); + if (!x_test_for_failure()) { + for (i = 0; i < 1 << x_depth; i++) { + if ((static_color_map[i].flags & (DoRed | DoGreen | DoBlue)) == (DoRed | DoGreen | DoBlue)) + some_valid = 1; + else + static_color_struct[i].failure = 1; + } + } + + if (!some_valid) { + memset(static_color_map, 0, sizeof(XColor) << x_depth); + memset(static_color_struct, 0, sizeof(*static_color_struct) << x_depth); + for (i = 0; i < 1 << x_depth; i++) { + static_color_map[i].pixel = i; + x_prepare_for_failure(X_QueryColors); + XQueryColor(x_display, x_default_colormap, &static_color_map[i]); + if (!x_test_for_failure() && (static_color_map[i].flags & (DoRed | DoGreen | DoBlue)) == (DoRed | DoGreen | DoBlue)) + some_valid = 1; + else + static_color_struct[i].failure = 1; + } + } + + if (!some_valid) { + if (vinfo.class == StaticColor) { + return stracpy(cast_uchar "Could not query static colormap.\n"); + } else { + x_fill_color_table(static_color_map, X_STATIC_COLORS); + do_alloc = 0; + } } - if (!some_valid) - return stracpy(cast_uchar "Could not query static colormap\n"); - static_color_table = mem_calloc(256); + if (!static_color_table) + static_color_table = xmalloc(256); + memset(static_color_table, 0, 256); for (i = 0; i < X_STATIC_COLORS; i++) { - unsigned int rgb[3]; - q_palette(X_STATIC_COLORS, i, 65535, rgb); - static_color_table[i] = get_nearest_color(rgb); + int idx = X_STATIC_COLORS == 216 ? alloc_sequence_216[i] : i; + int c; + q_palette(X_STATIC_COLORS, idx, 65535, rgb); + another_nearest: + c = get_nearest_color(rgb); + if (c < 0) { + do_alloc = 0; + goto retry; + } + if (do_alloc) { + XColor xc; + memset(&xc, 0, sizeof xc); + xc.red = static_color_map[c].red; + xc.green = static_color_map[c].green; + xc.blue = static_color_map[c].blue; + xc.flags = DoRed | DoGreen | DoBlue; + if (!XAllocColor(x_display, x_default_colormap, &xc)) { + if (0) { + allocated_invalid: + XFreeColors(x_display, x_default_colormap, &xc.pixel, 1, 0); + } + static_color_struct[c].failure = 1; + goto another_nearest; + } else { + if (xc.pixel >= 256) + goto allocated_invalid; + c = xc.pixel; + static_color_map[c] = xc; + static_color_struct[c].alloc_count++; + } + } + static_color_table[idx] = c; } + if (do_alloc) { + double distances[256]; + double max_dist; + int c; + for (i = 0; i < X_STATIC_COLORS; i++) { + unsigned char q = static_color_table[i]; + q_palette(X_STATIC_COLORS, i, 65535, rgb); + distances[i] = rgb_distance(static_color_map[q].red, static_color_map[q].green, static_color_map[q].blue, rgb[0], rgb[1], rgb[2]); + } + try_alloc_another: + max_dist = 0; + c = -1; + for (i = 0; i < X_STATIC_COLORS; i++) { + int idx = X_STATIC_COLORS == 216 ? alloc_sequence_216[i] : i; + if (distances[idx] > max_dist) { + max_dist = distances[idx]; + c = idx; + } + } + if (c >= 0) { + XColor xc; + memset(&xc, 0, sizeof xc); + q_palette(X_STATIC_COLORS, c, 65535, rgb); + xc.red = rgb[0]; + xc.green = rgb[1]; + xc.blue = rgb[2]; + xc.flags = DoRed | DoGreen | DoBlue; + if (swap_color(c, &xc, 1, &distances[c], rgb)) + goto no_more_alloc; + + for (i = 0; i < X_STATIC_COLORS; i++) { + double d1, d2; + unsigned char cidx = static_color_table[i]; + q_palette(X_STATIC_COLORS, i, 65535, rgb); + d1 = rgb_distance_with_border(rgb[0], rgb[1], rgb[2], static_color_map[cidx].red, static_color_map[cidx].green, static_color_map[cidx].blue); + d2 = rgb_distance_with_border(rgb[0], rgb[1], rgb[2], xc.red, xc.green, xc.blue); + if (d2 < d1) { + if (distances[i] < rgb_distance(xc.red, xc.green, xc.blue, rgb[0], rgb[1], rgb[2])) + continue; + if (swap_color(i, &xc, 0, &distances[i], rgb)) + goto no_more_alloc; + } + } + + goto try_alloc_another; + } + } + no_more_alloc: return NULL; } +static void x_free_colors(void) { + unsigned long pixels[256]; + int n_pixels = 0; + int i; + if (!static_color_struct) + return; + for (i = 0; i < 1 << x_depth; i++) { + while (static_color_struct[i].alloc_count) { + static_color_struct[i].alloc_count--; + pixels[n_pixels++] = i; + } + } + if (n_pixels) + XFreeColors(x_display, x_default_colormap, pixels, n_pixels, 0); +} + +static void x_set_palette(void) +{ + unsigned limit = 1U << x_depth; + + x_free_colors(); + + if (x_use_static_color_table) { + x_query_palette(); + XStoreColors(x_display, x_colormap, static_color_map, (int)limit); + } else { + XColor colors[256]; + x_fill_color_table(colors, limit); + XStoreColors(x_display, x_colormap, colors, (int)limit); + } + + X_FLUSH(); +} static inline int trans_key(unsigned char *str, int table) { @@ -317,41 +593,41 @@ static inline int trans_key(unsigned char *str, int table) /* translates X keys to links representation */ /* return value: 1=valid key, 0=nothing */ -static int x_translate_key(struct graphics_device *dev, XKeyEvent *e,int *key,int *flag) +static int x_translate_key(struct graphics_device *dev, XKeyEvent *e, int *key, int *flag) { KeySym ks = 0; static XComposeStatus comp = { NULL, 0 }; - static unsigned char str[16]; + static char str[16]; #define str_size ((int)(sizeof(str) - 1)) int table = 0; int len; if (get_window_info(dev)->xic) { Status status; - len = Xutf8LookupString(get_window_info(dev)->xic, e, cast_char str, str_size, &ks, &status); + len = Xutf8LookupString(get_window_info(dev)->xic, e, str, str_size, &ks, &status); table = 0; /*fprintf(stderr, "len: %d, ks %ld, status %d\n", len, ks, status);*/ } else - len = XLookupString(e,cast_char str,str_size,&ks,&comp); + len = XLookupString(e, str, str_size, &ks, &comp); - str[len>str_size?str_size:len]=0; + str[len > str_size ? str_size : len] = 0; if (!len) { - str[0] = (unsigned char)ks; + str[0] = (char)ks; str[1] = 0; } - *flag=0; - *key=0; + *flag = 0; + *key = 0; /* alt, control, shift ... */ - if (e->state&ShiftMask)*flag|=KBD_SHIFT; - if (e->state&ControlMask)*flag|=KBD_CTRL; - if (e->state&Mod1Mask)*flag|=KBD_ALT; + if (e->state & ShiftMask) *flag |= KBD_SHIFT; + if (e->state & ControlMask) *flag |= KBD_CTRL; + if (e->state & Mod1Mask) *flag |= KBD_ALT; /* alt-f4 */ - if (((*flag)&KBD_ALT)&&(ks==XK_F4)){*key=KBD_CTRL_C;*flag=0;return 1;} + if (*flag & KBD_ALT && ks == XK_F4) { *key = KBD_CTRL_C; *flag = 0; return 1; } /* ctrl-c */ - if (((*flag)&KBD_CTRL)&&(ks==XK_c||ks==XK_C)){*key=KBD_CTRL_C;*flag=0;return 1;} + if (*flag & KBD_CTRL && (ks == XK_c || ks == XK_C)) {*key = KBD_CTRL_C; *flag = 0; return 1; } if (ks == NoSymbol) { return 0; } else if (ks == XK_Return) { *key = KBD_ENTER; @@ -465,6 +741,9 @@ static int x_translate_key(struct graphics_device *dev, XKeyEvent *e,int *key,in } else if (ks == XK_KP_7) { *key = '7'; } else if (ks == XK_KP_8) { *key = '8'; } else if (ks == XK_KP_9) { *key = '9'; +#ifdef XK_Select + } else if (ks == XK_Select) { *key = KBD_SELECT; +#endif #ifdef XK_Undo } else if (ks == XK_Undo) { *key = KBD_UNDO; #endif @@ -500,9 +779,11 @@ static int x_translate_key(struct graphics_device *dev, XKeyEvent *e,int *key,in if (!casestrcmp(str, cast_uchar "XF86Back")) { *key = KBD_BACK; return 1; } if (!casestrcmp(str, cast_uchar "XF86Open")) { *key = KBD_OPEN; return 1; } if (!casestrcmp(str, cast_uchar "XF86OpenURL")) { *key = KBD_OPEN; return 1; } + if (!casestrcmp(str, cast_uchar "apLineDel")) { *key = KBD_DEL; return 1; } } return 0; - } else { *key = ((*flag)&KBD_CTRL)?(int)ks&255:trans_key(str,table); + } else { + *key = *flag & KBD_CTRL ? (int)ks & 255 : trans_key(cast_uchar str, table); } return 1; } @@ -536,11 +817,14 @@ static void x_free_hash_table(void) x_clear_clipboard(); + x_free_colors(); + free(static_color_table); free(static_color_map); + free(static_color_struct); static_color_table = NULL; static_color_map = NULL; - + static_color_struct = NULL; if (x_display) { if (x_icon) { @@ -579,6 +863,13 @@ static void x_free_hash_table(void) free(x_display_string); x_driver_param = NULL; x_display_string = NULL; + + undo_pixmap_handler(); + + process_events_in_progress = 0; + flush_in_progress = 0; + unregister_bottom_half(x_process_events, NULL); + unregister_bottom_half(x_do_flush, NULL); } /* returns graphics device structure which belonging to the window */ @@ -684,7 +975,7 @@ static void x_process_events(void *data) while (XPending(x_display) || replay_event) { if (replay_event) replay_event = 0; - else XNextEvent(x_display,&event); + else XNextEvent(x_display, &event); if (last_was_mouse&&(event.type==ButtonPress||event.type==ButtonRelease)) /* this is end of mouse move block --- call mouse handler */ { int a,b; @@ -781,7 +1072,7 @@ static void x_process_events(void *data) dev = x_find_gd(event.xkey.window); if (!dev) break; - if (x_translate_key(dev, (XKeyEvent*)(&event), &k, &f)) + if (x_translate_key(dev, (XKeyEvent *)&event, &k, &f)) dev->keyboard_handler(dev, k, f); } break; @@ -910,13 +1201,10 @@ static unsigned char *x_init_driver(unsigned char *param, unsigned char *display XGCValues gcv; XSetWindowAttributes win_attr; - XVisualInfo vinfo; int misordered = -1; x_init_hash_table(); - n_wins = 0; - #if defined(LC_CTYPE) setlocale(LC_CTYPE, ""); #endif @@ -936,7 +1224,13 @@ static unsigned char *x_init_driver(unsigned char *param, unsigned char *display */ x_display_string = stracpy(display ? display : cast_uchar ""); - x_display = XOpenDisplay((char *)display); + if (display) { + char *xx_display = strndup((char *)display, strlen(cast_const_char display) + 1); + x_display = XOpenDisplay(xx_display); + free(xx_display); + } else { + x_display = XOpenDisplay(NULL); + } if (!x_display) { err = init_str(); l = 0; @@ -953,6 +1247,7 @@ static unsigned char *x_init_driver(unsigned char *param, unsigned char *display x_display_height = DisplayHeight(x_display, x_screen); x_display_width = DisplayWidth(x_display, x_screen); x_root_window = RootWindow(x_display, x_screen); + x_default_colormap = XDefaultColormap(x_display, x_screen); x_default_window_width = x_display_width; if (x_default_window_width >= 100) @@ -965,22 +1260,25 @@ static unsigned char *x_init_driver(unsigned char *param, unsigned char *display if (param && *param) { unsigned char *e; + char *end_c; unsigned long w, h; x_driver_param = stracpy(param); if (*x_driver_param < '0' || *x_driver_param > '9') { invalid_param: - err = stracpy(cast_uchar "Invalid parameter\n"); + err = stracpy(cast_uchar "Invalid parameter.\n"); goto ret_err; } - w = strtoul((char *)x_driver_param, (char **)&e, 10); + w = strtoul(cast_const_char x_driver_param, &end_c, 10); + e = cast_uchar end_c; if (upcase(*e) != 'X') goto invalid_param; e++; if (*e < '0' || *e > '9') goto invalid_param; - h = strtoul((char *)e, (char **)&e, 10); + h = strtoul(cast_const_char e, &end_c, 10); + e = cast_uchar end_c; if (*e) goto invalid_param; if (w && h && w <= 30000 && h <= 30000) { @@ -1088,14 +1386,17 @@ invalid_param: x_driver.flags &= ~GD_SWITCH_PALETTE; x_have_palette = 0; x_use_static_color_table = 0; - if (vinfo.class == StaticColor || vinfo.class == PseudoColor) { + if (vinfo.class == StaticColor) { + if (x_depth > 8) + return stracpy(cast_uchar "Static color supported for up to 8-bit depth.\n"); if ((err = x_query_palette())) goto ret_err; x_use_static_color_table = 1; } if (vinfo.class == PseudoColor) { - if (x_driver.param->palette_mode) - x_use_static_color_table = 0; + if (x_depth > 8) + return stracpy(cast_uchar "Static color supported for up to 8-bit depth.\n"); + x_use_static_color_table = !x_driver.param->palette_mode; x_have_palette = 1; x_colormap = XCreateColormap(x_display, x_root_window, x_default_visual, AllocAll); x_set_palette(); @@ -1137,7 +1438,7 @@ invalid_param: if (x_have_palette) win_attr.colormap = x_colormap; else - win_attr.colormap = XDefaultColormap(x_display, x_screen); + win_attr.colormap = x_default_colormap; fake_window = XCreateWindow(x_display, x_root_window, 0, 0, 10, 10, 0, x_depth, CopyFromParent, x_default_visual, @@ -1200,7 +1501,7 @@ invalid_param: xim = XOpenIM(x_display, NULL, NULL, NULL); #if defined(LC_CTYPE) if (!xim) { - l = cast_uchar setlocale(LC_CTYPE, "en_US.UTF-8"); + if (!l) l = cast_uchar setlocale(LC_CTYPE, "en_US.UTF-8"); xim = XOpenIM(x_display, NULL, NULL, NULL); } #endif @@ -1220,6 +1521,9 @@ invalid_param: x_fd = XConnectionNumber(x_display); set_handlers(x_fd, x_process_events, NULL, NULL); + + setup_pixmap_handler(); + XSync(x_display, False); X_SCHEDULE_PROCESS_EVENTS(); return NULL; @@ -1251,7 +1555,7 @@ static struct graphics_device *x_init_device(void) XWMHints wm_hints; XClassHint class_hints; XTextProperty windowName; - unsigned char *links_name = cast_uchar "Links"; + char *links_name = "Links"; XSetWindowAttributes win_attr; struct window_info *wi; @@ -1267,30 +1571,53 @@ static struct graphics_device *x_init_device(void) if (x_have_palette) win_attr.colormap = x_colormap; else - win_attr.colormap = XDefaultColormap(x_display, x_screen); + win_attr.colormap = x_default_colormap; win_attr.border_pixel = x_black_pixel; + x_prepare_for_failure(X_CreateWindow); wi->window = XCreateWindow(x_display, x_root_window, dev->size.x1, dev->size.y1, dev->size.x2, dev->size.y2, X_BORDER_WIDTH, x_depth, InputOutput, x_default_visual, CWColormap | CWBorderPixel, &win_attr); + if (x_test_for_failure()) { + x_prepare_for_failure(X_DestroyWindow); + XDestroyWindow(x_display, wi->window); + x_test_for_failure(); + free(dev); + free(wi); + return NULL; + } if (!x_icon) { XImage *img; char *data; + char *xx_data; int w, h, skip; get_links_icon(&data, &w, &h, &skip, x_bitmap_scanline_pad); x_convert_to_216(data, w, h, skip); + xx_data = strndup(data, h * skip); + free(data); + img = XCreateImage(x_display, x_default_visual, x_depth, ZPixmap, 0, - data, w, h, x_bitmap_scanline_pad << 3, skip); + xx_data, w, h, x_bitmap_scanline_pad << 3, skip); if (!img) { x_icon = 0; + free(xx_data); goto nic_nebude_bobankove; } - img->data = data; + XSync(x_display, False); + X_SCHEDULE_PROCESS_EVENTS(); + x_prepare_for_failure(X_CreatePixmap); + img->data = xx_data; x_icon = XCreatePixmap(x_display, wi->window, w, h, x_depth); + if (x_test_for_failure()) { + x_prepare_for_failure(X_FreePixmap); + XFreePixmap(x_display, x_icon); + x_test_for_failure(); + x_icon = 0; + } if (!x_icon) { XDestroyImage(img); x_icon = 0; @@ -1310,12 +1637,12 @@ nic_nebude_bobankove:; } XSetWMHints(x_display, wi->window, &wm_hints); - class_hints.res_name = (char *)links_name; - class_hints.res_class = (char *)links_name; + class_hints.res_name = links_name; + class_hints.res_class = links_name; XSetClassHint(x_display, wi->window, &class_hints); - XStringListToTextProperty((char **)(void *)&links_name, 1, &windowName); + XStringListToTextProperty(&links_name, 1, &windowName); XSetWMName(x_display, wi->window, &windowName); - XStoreName(x_display, wi->window, (char *)links_name); + XStoreName(x_display, wi->window, links_name); XSetWMIconName(x_display, wi->window, &windowName); XFree(windowName.value); @@ -1387,6 +1714,36 @@ static void x_update_palette(void) x_set_palette(); } +static unsigned short *x_get_real_colors(void) +{ + int perfect = 1; + int i; + unsigned short *v; + if (!x_use_static_color_table) + return NULL; + v = mem_calloc(256 * 3 * sizeof(unsigned short)); + for (i = 0; i < X_STATIC_COLORS; i++) { + unsigned idx = static_color_table[i]; + v[i * 3 + 0] = static_color_map[idx].red; + v[i * 3 + 1] = static_color_map[idx].green; + v[i * 3 + 2] = static_color_map[idx].blue; + if (perfect) { + unsigned rgb[256]; + q_palette(X_STATIC_COLORS, i, 65535, rgb); + if (static_color_map[idx].red != rgb[0] + || static_color_map[idx].green != rgb[1] + || static_color_map[idx].blue != rgb[2]) { + perfect = 0; + } + } + } + if (perfect) { + free(v); + return NULL; + } + return v; +} + static void x_translate_colors(unsigned char *data, int x, int y, int skip) { int i, j; @@ -1422,7 +1779,7 @@ static void x_convert_to_216(char *data, int x, int y, int skip) } else { unsigned rgb[3]; q_palette(256, a, 65535, rgb); - result = get_nearest_color(rgb); + result = (unsigned char)get_nearest_color(rgb); color_table[a] = result; } data[i] = result; @@ -1433,12 +1790,21 @@ static void x_convert_to_216(char *data, int x, int y, int skip) static int x_get_empty_bitmap(struct bitmap *bmp) { + struct x_pixmapa *p; int pad; + p = xmalloc(sizeof(struct x_pixmapa)); + p->type = X_TYPE_NOTHING; + add_to_list(bitmaps, p); + bmp->data = NULL; + bmp->flags = p; + if (bmp->x > (INT_MAX - x_bitmap_scanline_pad) / x_bitmap_bpp) + return -1; pad = x_bitmap_scanline_pad - ((bmp->x * x_bitmap_bpp) % x_bitmap_scanline_pad); if (pad == x_bitmap_scanline_pad) pad = 0; bmp->skip = bmp->x * x_bitmap_bpp + pad; - bmp->flags = NULL; + if (bmp->skip * bmp->y > INT_MAX) + return -1; bmp->data = xmalloc(bmp->skip * bmp->y); return 0; } @@ -1447,27 +1813,22 @@ static void x_register_bitmap(struct bitmap *bmp) { struct x_pixmapa *p; XImage *image; - Pixmap *pixmap = NULL; + Pixmap pixmap = 0; int can_create_pixmap; - X_FLUSH(); if (!bmp->data || !bmp->x || !bmp->y) goto cant_create; x_translate_colors(bmp->data, bmp->x, bmp->y, bmp->skip); - /* alloc struct x_bitmapa */ - p = xmalloc(sizeof(struct x_pixmapa)); - /* alloc XImage in client's memory */ retry: image = XCreateImage(x_display, x_default_visual, x_depth, ZPixmap, 0, - bmp->data, bmp->x, bmp->y, x_bitmap_scanline_pad << 3, + (char *)bmp->data, bmp->x, bmp->y, x_bitmap_scanline_pad << 3, bmp->skip); if (!image) { if (out_of_memory()) goto retry; - free(p); goto cant_create; } @@ -1479,26 +1840,26 @@ static void x_register_bitmap(struct bitmap *bmp) goto no_pixmap; } - x_prepare_for_failure(); - pixmap = xmalloc(sizeof(Pixmap)); - *pixmap = XCreatePixmap(x_display, fake_window, bmp->x, bmp->y, x_depth); - if (x_test_for_failure()) { - if (*pixmap) { - x_prepare_for_failure(); - XFreePixmap(x_display, *pixmap); + if (!pixmap_mode) x_prepare_for_failure(X_CreatePixmap); + pixmap = XCreatePixmap(x_display, fake_window, bmp->x, bmp->y, x_depth); + if (!pixmap_mode && x_test_for_failure()) { + if (pixmap) { + x_prepare_for_failure(X_FreePixmap); + XFreePixmap(x_display, pixmap); x_test_for_failure(); - *pixmap = 0; + pixmap = 0; } } - if (!*pixmap) { - free(pixmap); + if (!pixmap) { can_create_pixmap = 0; } no_pixmap: + p = XPIXMAPP(bmp->flags); + if (can_create_pixmap) { - XPutImage(x_display, *pixmap, x_copy_gc, image, 0, 0, 0, 0, + XPutImage(x_display, pixmap, x_copy_gc, image, 0, 0, 0, 0, bmp->x, bmp->y); XDestroyImage(image); p->type = X_TYPE_PIXMAP; @@ -1507,34 +1868,36 @@ static void x_register_bitmap(struct bitmap *bmp) p->type = X_TYPE_IMAGE; p->data.image = image; } - bmp->flags = p; bmp->data = NULL; return; cant_create: free(bmp->data); bmp->data = NULL; - bmp->flags=NULL; return; } static void x_unregister_bitmap(struct bitmap *bmp) { - if (!bmp->flags) - return; + struct x_pixmapa *p = XPIXMAPP(bmp->flags); + + switch (p->type) { + case X_TYPE_NOTHING: + break; - switch(XPIXMAPP(bmp->flags)->type) { case X_TYPE_PIXMAP: - XFreePixmap(x_display, *(XPIXMAPP(bmp->flags)->data.pixmap)); - free(XPIXMAPP(bmp->flags)->data.pixmap); + XFreePixmap(x_display, p->data.pixmap); /* free XPixmap from server's memory */ break; case X_TYPE_IMAGE: - XDestroyImage(XPIXMAPP(bmp->flags)->data.image); + XDestroyImage(p->data.image); /* free XImage from client's memory */ break; + default: + internal("invalid pixmap type %d", (int)p->type); } - free(bmp->flags); /* struct x_pixmap */ + del_from_list(p); + free(p); } static long x_get_color(int rgb) @@ -1603,9 +1966,8 @@ static void x_draw_vline(struct graphics_device *dev, int x, int y1, int y2, lon static void x_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x, int y) { + struct x_pixmapa *p; int bmp_off_x, bmp_off_y, bmp_size_x, bmp_size_y; - if (!bmp->flags) - return; CLIP_DRAW_BITMAP @@ -1628,18 +1990,25 @@ static void x_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x if (y + bmp_size_y > dev->clip.y2) bmp_size_y = dev->clip.y2 - y; - switch(XPIXMAPP(bmp->flags)->type) { + p = XPIXMAPP(bmp->flags); + + switch (p->type) { + case X_TYPE_NOTHING: + break; + case X_TYPE_PIXMAP: - XCopyArea(x_display, *(XPIXMAPP(bmp->flags)->data.pixmap), - get_window_info(dev)->window, x_drawbitmap_gc, bmp_off_x, - bmp_off_y, bmp_size_x, bmp_size_y, x, y); + XCopyArea(x_display, p->data.pixmap, + get_window_info(dev)->window, x_drawbitmap_gc, + bmp_off_x, bmp_off_y, bmp_size_x, bmp_size_y, x, y); break; case X_TYPE_IMAGE: XPutImage(x_display, get_window_info(dev)->window, - x_drawbitmap_gc, XPIXMAPP(bmp->flags)->data.image, + x_drawbitmap_gc, p->data.image, bmp_off_x, bmp_off_y, x, y, bmp_size_x, bmp_size_y); break; + default: + internal("invalid pixmap type %d", (int)p->type); } X_FLUSH(); } @@ -1647,16 +2016,16 @@ static void x_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x static void *x_prepare_strip(struct bitmap *bmp, int top, int lines) { - struct x_pixmapa *p = (struct x_pixmapa *)bmp->flags; + struct x_pixmapa *p = XPIXMAPP(bmp->flags); XImage *image; void *x_data; - if (!p) - return NULL; - bmp->data = NULL; switch (p->type) { + case X_TYPE_NOTHING: + return NULL; + case X_TYPE_PIXMAP: x_data = xmalloc(bmp->skip * lines); image = XCreateImage(x_display, x_default_visual, x_depth, @@ -1672,37 +2041,34 @@ static void *x_prepare_strip(struct bitmap *bmp, int top, int lines) case X_TYPE_IMAGE: return p->data.image->data + (bmp->skip * top); } - internal("Unknown pixmap type found in x_prepare_strip. SOMETHING IS REALLY STRANGE!!!!\n"); + internal("invalid pixmap type %d", (int)p->type); return NULL; } static void x_commit_strip(struct bitmap *bmp, int top, int lines) { - struct x_pixmapa *p = (struct x_pixmapa *)bmp->flags; - - if (!p) - return; + struct x_pixmapa *p = XPIXMAPP(bmp->flags); bmp->data = NULL; switch (p->type) { - /* send image to pixmap in xserver */ + case X_TYPE_NOTHING: + return; case X_TYPE_PIXMAP: if (!bmp->data) return; x_translate_colors((unsigned char *)((XImage*)bmp->data)->data, bmp->x, lines, bmp->skip); - XPutImage(x_display, *(XPIXMAPP(bmp->flags)->data.pixmap), - x_copy_gc, (XImage*)bmp->data, 0, 0, 0, top, bmp->x, - lines); + XPutImage(x_display, p->data.pixmap, + x_copy_gc, (XImage *)bmp->data, 0, 0, 0, top, bmp->x, lines); XDestroyImage((XImage *)bmp->data); return; case X_TYPE_IMAGE: - x_translate_colors((unsigned char *)p->data.image->data - + (bmp->skip * top), bmp->x, lines, bmp->skip); + x_translate_colors((unsigned char *)p->data.image->data + (bmp->skip * top), bmp->x, lines, bmp->skip); /* everything has been done by user */ return; } + internal("invalid pixmap type %d", (int)p->type); } static int x_scroll(struct graphics_device *dev, struct rect_set **set, int scx, int scy) @@ -1790,6 +2156,7 @@ static void x_flush(struct graphics_device *dev) static void x_set_window_title(struct graphics_device *dev, unsigned char *title) { unsigned char *t; + char *xx_str; XTextProperty windowName; Status ret; @@ -1798,18 +2165,21 @@ static void x_set_window_title(struct graphics_device *dev, unsigned char *title t = convert(0, 0, title, NULL); clr_white(t); + xx_str = strndup((char *)t, strlen(cast_const_char t) + 1); + free(t); + if (XSupportsLocale()) { - ret = XmbTextListToTextProperty(x_display, (char**)(&t), + ret = XmbTextListToTextProperty(x_display, &xx_str, 1, XStdICCTextStyle, &windowName); #ifdef X_HAVE_UTF8_STRING if (ret > 0) { XFree(windowName.value); ret = XmbTextListToTextProperty(x_display, - (char**)(&t), 1, + &xx_str, 1, XUTF8StringStyle, &windowName); if (ret < 0) ret = XmbTextListToTextProperty(x_display, - (char**)(&t), + &xx_str, 1, XStdICCTextStyle, &windowName); } @@ -1818,13 +2188,13 @@ static void x_set_window_title(struct graphics_device *dev, unsigned char *title goto retry_print_ascii; } else { retry_print_ascii: - ret = XStringListToTextProperty((char**)(&t), 1, &windowName); + ret = XStringListToTextProperty(&xx_str, 1, &windowName); if (!ret) { - free(t); + free(xx_str); return; } } - free(t); + free(xx_str); XSetWMName(x_display, get_window_info(dev)->window, &windowName); XSetWMIconName(x_display, get_window_info(dev)->window, &windowName); XFree(windowName.value); @@ -1850,6 +2220,7 @@ static void selection_request(XEvent *event) XSelectionRequestEvent *req; XSelectionEvent sel; size_t l; + unsigned char *xx_str; req = &(event->xselectionrequest); sel.type = SelectionNotify; @@ -1872,16 +2243,20 @@ static void selection_request(XEvent *event) l = strlen(cast_const_char str); if (l > X_MAX_CLIPBOARD_SIZE) l = X_MAX_CLIPBOARD_SIZE; + xx_str = (unsigned char *)strndup((char *)str, l); XChangeProperty(x_display, sel.requestor, sel.property, - XA_STRING, 8, PropModeReplace, str, l); + XA_STRING, 8, PropModeReplace, xx_str, l); free(str); + free(xx_str); } else if (req->target == x_utf8_string_atom) { l = x_my_clipboard ? strlen((char *)x_my_clipboard) : 0; if (l > X_MAX_CLIPBOARD_SIZE) l = X_MAX_CLIPBOARD_SIZE; + xx_str = (unsigned char *)strndup((char *)x_my_clipboard, l); XChangeProperty(x_display, sel.requestor, sel.property, - x_utf8_string_atom, 8, PropModeReplace, x_my_clipboard, + x_utf8_string_atom, 8, PropModeReplace, xx_str, l); + free(xx_str); } else if (req->target == x_targets_atom) { unsigned tgt_atoms[3]; tgt_atoms[0] = (unsigned)x_targets_atom; @@ -2049,6 +2424,7 @@ struct graphics_driver x_driver = { NULL, x_flush, x_update_palette, + x_get_real_colors, x_set_window_title, x_exec, x_set_clipboard_text,