📄 view.c
字号:
/* view.c * (c) 2002 Mikulas Patocka * This file is a part of the Links program, released under GPL. */#include "links.h"void send_open_in_new_xterm_target(struct terminal *term, void (*open_window)(struct terminal *term, unsigned char *, unsigned char *), struct session *ses);void copy_vs(struct view_state *, struct view_state *);void add_event_desc(unsigned char **, int *, unsigned char *, unsigned char *);void set_link(struct f_data_c *);int find_tag(struct f_data *, unsigned char *);int comp_links(struct link *, struct link *);void draw_link(struct terminal *, struct f_data_c *, int);void free_link(struct f_data_c *);void clear_link(struct terminal *, struct f_data_c *);int get_range(struct f_data *, int, int, int, struct search **, struct search **);int is_in_range(struct f_data *, int, int, unsigned char *, int *, int *);void get_searched(struct f_data_c *, struct point **, int *);void draw_searched(struct terminal *, struct f_data_c *);void draw_current_link(struct terminal *, struct f_data_c *);struct link *get_first_link(struct f_data_c *);struct link *get_last_link(struct f_data_c *);void init_ctrl(struct form_control *, struct form_state *);void draw_form_entry(struct terminal *, struct f_data_c *, struct link *);void x_draw_form_entry(struct session *, struct f_data_c *, struct link *);void draw_forms(struct terminal *, struct f_data_c *);void set_xchar(struct terminal *, int, int, unsigned);void draw_frame_lines(struct terminal *, struct frameset_desc *, int, int);void set_brl_cursor(struct terminal *, struct f_data_c *);void clr_xl(struct f_data_c *);void draw_doc_c(struct terminal *, struct f_data_c *);void draw_fd_nrd(struct f_data_c *);int in_viewx(struct f_data_c *, struct link *);int in_viewy(struct f_data_c *, struct link *);int in_view(struct f_data_c *, struct link *);int next_in_view(struct f_data_c *, int, int, int (*)(struct f_data_c *, struct link *), void (*)(struct f_data_c *, struct link *));void page_down(struct session *, struct f_data_c *, int);void page_up(struct session *, struct f_data_c *, int);void down(struct session *, struct f_data_c *, int);void up(struct session *, struct f_data_c *, int);void hscroll(struct session *, struct f_data_c *, int);void right(struct session *, struct f_data_c *, int);void left(struct session *, struct f_data_c *, int);int get_at_pos(struct f_data *, int, int);void cursor_word(struct session *, struct f_data_c *, int);void cursor_word_back(struct session *, struct f_data_c *, int);void cursor_home(struct session *, struct f_data_c *, int);void cursor_end(struct session *, struct f_data_c *, int);void br_next_link(struct session *, struct f_data_c *, int);void br_prev_link(struct session *, struct f_data_c *, int);void home(struct session *, struct f_data_c *, int);void x_end(struct session *, struct f_data_c *, int);int has_form_submit(struct f_data *, struct form_control *);void free_succesful_controls(struct list_head *);unsigned char *encode_textarea(unsigned char *);void get_succesful_controls(struct f_data_c *, struct form_control *, struct list_head *);unsigned char *strip_file_name(unsigned char *);void encode_string(unsigned char *, unsigned char **, int *);void encode_controls(struct list_head *, unsigned char **, int *, int, int);void encode_multipart(struct session *, struct list_head *, unsigned char **, int *, unsigned char *, int, int);unsigned char *get_link_url(struct session *, struct f_data_c *, struct link *, int *);struct menu_item *clone_select_menu(struct menu_item *);void free_select_menu(struct menu_item *);void back(struct session *, struct f_data_c *, int);void set_form_position(struct f_data_c *, struct link *, struct event *);int textarea_adjust_viewport(struct f_data_c *fd, struct link *l);void set_br_pos(struct f_data_c *, struct link *);int point_intersect(struct point *, int, struct point *, int);int find_next_link_in_search(struct f_data_c *, int);void rep_ev(struct session *, struct f_data_c *, void (*)(struct session *, struct f_data_c *, int), int);struct link *choose_mouse_link(struct f_data_c *, struct event *);void goto_link_number(struct session *, unsigned char *);int frame_ev(struct session *, struct f_data_c *, struct event *);int event_catchable(struct event *ev);int call_keyboard_event(struct f_data_c *fd, unsigned char *code, struct event *ev);int send_to_frame(struct session *, struct event *);void do_mouse_event(struct session *, struct event *);void send_enter(struct terminal *, void *, struct session *);void send_download_image(struct terminal *, void *, struct session *);void send_download(struct terminal *, void *, struct session *);void send_submit(struct terminal *, void *, struct session *);void send_reset(struct terminal *, void *, struct session *);void copy_link_location(struct terminal *, void *, struct session *);void send_open_in_new_xterm(struct terminal *, void (*)(struct terminal *, unsigned char *, unsigned char *), struct session *);void send_image(struct terminal *, void *, struct session *);void save_formatted(struct session *, unsigned char *);unsigned char *print_current_titlex(struct f_data_c *, int);unsigned char *print_current_linkx(struct f_data_c *, struct terminal *);unsigned char *print_current_linkx_plus(struct f_data_c *, struct terminal *);void scroll(struct session *, struct f_data_c *, int);struct view_state *create_vs(void){ struct view_state *vs; vs = mem_calloc(sizeof(struct view_state)); vs->refcount = 1; vs->current_link = -1; vs->orig_link = -1; vs->frame_pos = -1; vs->plain = -1; vs->form_info = DUMMY; vs->form_info_len = 0; return vs;}void destroy_vs(struct view_state *vs){ int i; if (--vs->refcount) { if (vs->refcount < 0) internal("destroy_vs: view_state refcount underflow"); return; } for (i = 0; i < vs->form_info_len; i++) if (vs->form_info[i].value) mem_free(vs->form_info[i].value); mem_free(vs->form_info); mem_free(vs);}void copy_vs(struct view_state *dst, struct view_state *src){ int i; memcpy(dst, src, sizeof(struct view_state)); if ((unsigned)src->form_info_len > MAXINT / sizeof(struct form_state)) overalloc(); dst->form_info = mem_alloc(src->form_info_len * sizeof(struct form_state)); memcpy(dst->form_info, src->form_info, src->form_info_len * sizeof(struct form_state)); for (i = 0; i < src->form_info_len; i++) if (src->form_info[i].value) dst->form_info[i].value = stracpy(src->form_info[i].value);}#ifdef JSvoid create_js_event_spec(struct js_event_spec **j){ if (*j) return; *j = mem_calloc(sizeof(struct js_event_spec));}void free_js_event_spec(struct js_event_spec *j){ if (!j) return; if (j->move_code) mem_free(j->move_code); if (j->over_code) mem_free(j->over_code); if (j->out_code) mem_free(j->out_code); if (j->down_code) mem_free(j->down_code); if (j->up_code) mem_free(j->up_code); if (j->click_code) mem_free(j->click_code); if (j->dbl_code) mem_free(j->dbl_code); if (j->blur_code) mem_free(j->blur_code); if (j->focus_code) mem_free(j->focus_code); if (j->change_code) mem_free(j->change_code); if (j->keypress_code) mem_free(j->keypress_code); if (j->keyup_code) mem_free(j->keyup_code); if (j->keydown_code) mem_free(j->keydown_code); mem_free(j);}int compare_js_event_spec(struct js_event_spec *j1, struct js_event_spec *j2){ if (!j1 && !j2) return 0; if (!j1 || !j2) return 1; return xstrcmp(j1->move_code, j2->move_code) || xstrcmp(j1->over_code, j2->over_code) || xstrcmp(j1->out_code, j2->out_code) || xstrcmp(j1->down_code, j2->down_code) || xstrcmp(j1->up_code, j2->up_code) || xstrcmp(j1->click_code, j2->click_code) || xstrcmp(j1->dbl_code, j2->dbl_code) || xstrcmp(j1->blur_code, j2->blur_code) || xstrcmp(j1->focus_code, j2->focus_code) || xstrcmp(j1->change_code, j2->change_code) || xstrcmp(j1->keypress_code, j2->keypress_code) || xstrcmp(j1->keydown_code, j2->keydown_code) || xstrcmp(j1->keyup_code, j2->keyup_code); }void copy_js_event_spec(struct js_event_spec **target, struct js_event_spec *source){ struct js_event_spec *t; *target = NULL; if (!source) return; create_js_event_spec(target); t = *target; t->move_code = stracpy(source->move_code); t->over_code = stracpy(source->over_code); t->out_code = stracpy(source->out_code); t->down_code = stracpy(source->down_code); t->up_code = stracpy(source->up_code); t->click_code = stracpy(source->click_code); t->dbl_code = stracpy(source->dbl_code); t->blur_code = stracpy(source->blur_code); t->focus_code = stracpy(source->focus_code); t->change_code = stracpy(source->change_code); t->keypress_code = stracpy(source->keypress_code); t->keyup_code = stracpy(source->keyup_code); t->keydown_code = stracpy(source->keydown_code);}static inline int copy_string(unsigned char **dest, unsigned char *src){ if (!src) return 0; if (*dest) { if (!strcmp(src, *dest)) return 0; mem_free(*dest); } *dest = stracpy(src); return 1;}int join_js_event_spec(struct js_event_spec **target, struct js_event_spec *source){ if (!source) return 0; create_js_event_spec(target); return copy_string(&(*target)->move_code, source->move_code) | copy_string(&(*target)->over_code, source->over_code) | copy_string(&(*target)->out_code, source->out_code) | copy_string(&(*target)->down_code, source->down_code) | copy_string(&(*target)->up_code, source->up_code) | copy_string(&(*target)->click_code, source->click_code) | copy_string(&(*target)->dbl_code, source->dbl_code) | copy_string(&(*target)->blur_code, source->blur_code) | copy_string(&(*target)->focus_code, source->focus_code) | copy_string(&(*target)->change_code, source->change_code) | copy_string(&(*target)->keypress_code, source->keypress_code) | copy_string(&(*target)->keyup_code, source->keyup_code) | copy_string(&(*target)->keydown_code, source->keydown_code);}void add_event_desc(unsigned char **str, int *l, unsigned char *fn, unsigned char *desc){ if (!fn) return; if (*l) add_to_str(str, l, ", "); add_to_str(str, l, desc); add_to_str(str, l, ":"); add_to_str(str, l, fn);}unsigned char *print_js_event_spec(struct js_event_spec *j){ unsigned char *str = init_str(); int l = 0; if (!j) return str; add_event_desc(&str, &l, j->click_code, "onclick"); add_event_desc(&str, &l, j->dbl_code, "ondblclick"); add_event_desc(&str, &l, j->down_code, "onmousedown"); add_event_desc(&str, &l, j->up_code, "onmouseup"); add_event_desc(&str, &l, j->over_code, "onmouseover"); add_event_desc(&str, &l, j->out_code, "onmouseout"); add_event_desc(&str, &l, j->move_code, "onmousemove"); add_event_desc(&str, &l, j->focus_code, "onfocus"); add_event_desc(&str, &l, j->blur_code, "onblur"); add_event_desc(&str, &l, j->change_code, "onchange"); add_event_desc(&str, &l, j->keypress_code, "onkeypress"); add_event_desc(&str, &l, j->keyup_code, "onkeyup"); add_event_desc(&str, &l, j->keydown_code, "onkeydown"); return str;}#elsevoid create_js_event_spec(struct js_event_spec **j){}void free_js_event_spec(struct js_event_spec *j){}int compare_js_event_spec(struct js_event_spec *j1, struct js_event_spec *j2){ return 0;}void copy_js_event_spec(struct js_event_spec **target, struct js_event_spec *source){}int join_js_event_spec(struct js_event_spec **target, struct js_event_spec *source){ return 0;}unsigned char *print_js_event_spec(struct js_event_spec *j){ return stracpy("");}#endifstatic inline int c_in_view(struct f_data_c *);void set_pos_x(struct f_data_c *, struct link *);void set_pos_y(struct f_data_c *, struct link *);void find_link(struct f_data_c *, int, int);void update_braille_link(struct f_data_c *f);void check_vs(struct f_data_c *f){ struct view_state *vs = f->vs; int ovx, ovy, ol, obx, oby; if (f->f_data->frame_desc) { struct f_data_c *ff; int n = 0; foreach(ff, f->subframes) n++; if (vs->frame_pos < 0) vs->frame_pos = 0; if (vs->frame_pos >= n) vs->frame_pos = n - 1; return; } ovx = f->vs->orig_view_posx; ovy = f->vs->orig_view_pos; ol = f->vs->orig_link; obx = f->vs->orig_brl_x; oby = f->vs->orig_brl_y; if (vs->current_link >= f->f_data->nlinks) vs->current_link = f->f_data->nlinks - 1; if (!F) { if (vs->current_link != -1 && !c_in_view(f)) { set_pos_x(f, &f->f_data->links[f->vs->current_link]); set_pos_y(f, &f->f_data->links[f->vs->current_link]); } if (vs->current_link == -1) find_link(f, 1, 0); if (f->ses->term->spec->braille) { if (vs->brl_x >= f->f_data->x) vs->brl_x = f->f_data->x - 1; if (vs->brl_x >= vs->view_posx + f->xw) vs->brl_x = vs->view_posx + f->xw - 1; if (vs->brl_x < vs->view_posx) vs->brl_x = vs->view_posx; if (vs->brl_y >= f->f_data->y) vs->brl_y = f->f_data->y - 1; if (vs->brl_y >= vs->view_pos + f->yw) vs->brl_y = vs->view_pos + f->yw - 1; if (vs->brl_y < vs->view_pos) vs->brl_y = vs->view_pos; update_braille_link(f); }#ifdef G } else { /*if (vs->current_link >= 0 && !is_link_in_view(f, vs->current_link)) vs->current_link = -1;*/#endif } f->vs->orig_view_posx = ovx; f->vs->orig_view_pos = ovy; if (!f->ses->term->spec->braille) f->vs->orig_link = ol; f->vs->orig_brl_x = obx; f->vs->orig_brl_y = oby;}void set_link(struct f_data_c *f){ if (c_in_view(f)) return; find_link(f, 1, 0);}int find_tag(struct f_data *f, unsigned char *name){ struct tag *tag; unsigned char *tt; int ll; tt = init_str(); ll = 0; add_conv_str(&tt, &ll, name, strlen(name), -2); foreach(tag, f->tags) if (!strcasecmp(tag->name, tt) || (tag->name[0] == '#' && !strcasecmp(tag->name + 1, tt))) { mem_free(tt); return tag->y; } mem_free(tt); return -1;}int comp_links(struct link *l1, struct link *l2){ return l1->num - l2->num;}void sort_links(struct f_data *f){ int i; if (F) return; /*if (F) goto skip_sort;*/ if (f->nlinks) qsort(f->links, f->nlinks, sizeof(struct link), (void *)comp_links); /* skip_sort: mem_free(f->link_events); if ((unsigned)f->nlinks > MAXINT / sizeof(struct js_event_spec *)) overalloc(); f->link_events = mem_alloc(f->nlinks * sizeof(struct js_event_spec *)); f->nlink_events = f->nlinks; for (i = 0; i < f->nlinks; i++) copy_js_event_spec(&f->link_events[i], f->links[i].js_event); if (F) return; */ if ((unsigned)f->y > MAXINT / sizeof(struct link *)) overalloc(); f->lines1 = mem_calloc(f->y * sizeof(struct link *)); f->lines2 = mem_calloc(f->y * sizeof(struct link *)); for (i = 0; i < f->nlinks; i++) { int p, q, j; struct link *link = &f->links[i]; if (!link->n) { if (d_opt->num_links) continue; if (link->where) mem_free(link->where); if (link->target) mem_free(link->target); if (link->where_img) mem_free(link->where_img); if (link->img_alt) mem_free(link->img_alt); if (link->pos) mem_free(link->pos); free_js_event_spec(link->js_event); memmove(link, link + 1, (f->nlinks - i - 1) * sizeof(struct link)); f->nlinks --; i--; continue; } p = f->y - 1; q = 0; for (j = 0; j < link->n; j++) { if (link->pos[j].y < p) p = link->pos[j].y; if (link->pos[j].y > q) q = link->pos[j].y; } /* p = link->pos[0].y; q = link->pos[link->n - 1].y; */ if (p > q) j = p, p = q, q = j; for (j = p; j <= q; j++) { if (j >= f->y) { internal("link out of screen"); continue; } f->lines2[j] = &f->links[i]; if (!f->lines1[j]) f->lines1[j] = &f->links[i]; } }}unsigned char *utf8_add(unsigned char *t, int i){ if (!F) return t + i;#ifdef G while (i-- && *t) FWD_UTF_8(t);#endif return t;}int utf8_diff(unsigned char *t2, unsigned char *t1){ if (!F) return t2 - t1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -