📄 view.c
字号:
void draw_formatted(struct session *ses){ if (!ses->screen || !ses->screen->f_data) { /*internal("document not formatted");*/ fill_area(ses->term, 0, 1, ses->term->x, ses->term->y - 2, ' '); return; } if (!ses->screen->vs && !list_empty(ses->history)) ses->screen->vs = &cur_loc(ses)->vs; ses->screen->xl = ses->screen->yl = -1; draw_doc(ses->term, ses->screen, 1); draw_frames(ses); print_screen_status(ses); redraw_from_window(ses->win);}#define D_BUF 65536extern unsigned char frame_dumb[];int dump_to_file(struct f_data *fd, int h){ int x, y; unsigned char *buf; int bptr = 0; buf = mem_alloc(D_BUF); for (y = 0; y < fd->y; y++) for (x = 0; x <= fd->data[y].l; x++) { int c; if (x == fd->data[y].l) c = '\n'; else { if (((c = fd->data[y].d[x]) & 0xff) == 1) c += ' ' - 1; if ((c >> 15) && (c & 0xff) >= 176 && (c & 0xff) < 224) c = frame_dumb[(c & 0xff) - 176]; } buf[bptr++] = c; if (bptr >= D_BUF) { if (hard_write(h, buf, bptr) != bptr) goto fail; bptr = 0; } } if (hard_write(h, buf, bptr) != bptr) { fail: mem_free(buf); return -1; } mem_free(buf); if (fd->opt.num_links && fd->nlinks) { static char head[] = "\nLinks:\n"; int i; if ((int)hard_write(h, head, strlen(head)) != (int)strlen(head)) return -1; for (i = 0; i < fd->nlinks; i++) { struct link *lnk = &fd->links[i]; unsigned char *s = init_str(); int l = 0; add_num_to_str(&s, &l, i + 1); add_to_str(&s, &l, ". "); if (lnk->where) { add_to_str(&s, &l, lnk->where); } else if (lnk->where_img) { add_to_str(&s, &l, "Image: "); add_to_str(&s, &l, lnk->where_img); } else if (lnk->type == L_BUTTON) { struct form_control *fc = lnk->form; if (fc->type == FC_RESET) add_to_str(&s, &l, "Reset form"); else if (!fc->action) add_to_str(&s, &l, "Button"); else { if (!fc->method == FM_GET) add_to_str(&s, &l, "Submit form: "); else add_to_str(&s, &l, "Post form: "); add_to_str(&s, &l, fc->action); } } else if (lnk->type == L_CHECKBOX || lnk->type == L_SELECT || lnk->type == L_FIELD || lnk->type == L_AREA) { struct form_control *fc = lnk->form; if (fc->type == FC_RADIO) add_to_str(&s, &l, "Radio button"); else if (fc->type == FC_CHECKBOX) add_to_str(&s, &l, "Checkbox"); else if (fc->type == FC_SELECT) add_to_str(&s, &l, "Select field"); else if (fc->type == FC_TEXT) add_to_str(&s, &l, "Text field"); else if (fc->type == FC_TEXTAREA) add_to_str(&s, &l, "Text area"); else if (fc->type == FC_FILE) add_to_str(&s, &l, "File upload"); else if (fc->type == FC_PASSWORD) add_to_str(&s, &l, "Password field"); else goto unknown; if (fc->name && fc->name[0]) add_to_str(&s, &l, ", Name "), add_to_str(&s, &l, fc->name); if ((fc->type == FC_CHECKBOX || fc->type == FC_RADIO) && fc->default_value && fc->default_value[0]) add_to_str(&s, &l, ", Value "), add_to_str(&s, &l, fc->default_value); } unknown: add_to_str(&s, &l, "\n"); if (hard_write(h, s, l) != l) { mem_free(s); return -1; } mem_free(s); } } return 0;}int in_viewx(struct f_data_c *f, struct link *l){ int i; for (i = 0; i < l->n; i++) { if (l->pos[i].x >= f->vs->view_posx && l->pos[i].x < f->vs->view_posx + f->xw) return 1; } return 0;}int in_viewy(struct f_data_c *f, struct link *l){ int i; for (i = 0; i < l->n; i++) { if (l->pos[i].y >= f->vs->view_pos && l->pos[i].y < f->vs->view_pos + f->yw) return 1; } return 0;}int in_view(struct f_data_c *f, struct link *l){ return in_viewy(f, l) && in_viewx(f, l);}static inline int c_in_view(struct f_data_c *f){ return f->vs->current_link != -1 && in_view(f, &f->f_data->links[f->vs->current_link]);}int next_in_view(struct f_data_c *f, int p, int d, int (*fn)(struct f_data_c *, struct link *), void (*cntr)(struct f_data_c *, struct link *)){ int p1 = f->f_data->nlinks - 1; int p2 = 0; int y; int yl = f->vs->view_pos + f->yw; if (yl > f->f_data->y) yl = f->f_data->y; for (y = f->vs->view_pos < 0 ? 0 : f->vs->view_pos; y < yl; y++) { if (f->f_data->lines1[y] && f->f_data->lines1[y] - f->f_data->links < p1) p1 = f->f_data->lines1[y] - f->f_data->links; if (f->f_data->lines2[y] && f->f_data->lines2[y] - f->f_data->links > p2) p2 = f->f_data->lines2[y] - f->f_data->links; } /*while (p >= 0 && p < f->f_data->nlinks) {*/ while (p >= p1 && p <= p2) { if (fn(f, &f->f_data->links[p])) { f->vs->current_link = p; f->vs->orig_link = f->vs->current_link; if (cntr) cntr(f, &f->f_data->links[p]); return 1; } p += d; } f->vs->current_link = -1; f->vs->orig_link = f->vs->current_link; return 0;}void set_pos_x(struct f_data_c *f, struct link *l){ int i; int xm = 0; int xl = MAXINT; for (i = 0; i < l->n; i++) { if (l->pos[i].y >= f->vs->view_pos && l->pos[i].y < f->vs->view_pos + f->yw) { if (l->pos[i].x >= xm) xm = l->pos[i].x + 1; if (l->pos[i].x < xl) xl = l->pos[i].x; } } if (xl == MAXINT) return; /*if ((f->vs->view_posx = xm - f->xw) > xl) f->vs->view_posx = xl;*/ if (f->vs->view_posx + f->xw < xm) f->vs->view_posx = xm - f->xw; if (f->vs->view_posx > xl) f->vs->view_posx = xl; f->vs->orig_view_posx = f->vs->view_posx;}void set_pos_y(struct f_data_c *f, struct link *l){ int i; int ym = 0; int yl = f->f_data->y; for (i = 0; i < l->n; i++) { if (l->pos[i].y >= ym) ym = l->pos[i].y + 1; if (l->pos[i].y < yl) yl = l->pos[i].y; } if ((f->vs->view_pos = (ym + yl) / 2 - f->f_data->opt.yw / 2) > f->f_data->y - f->f_data->opt.yw) f->vs->view_pos = f->f_data->y - f->f_data->opt.yw; if (f->vs->view_pos < 0) f->vs->view_pos = 0; f->vs->orig_view_pos = f->vs->view_pos;}void find_link(struct f_data_c *f, int p, int s){ /* p=1 - top, p=-1 - bottom, s=0 - pgdn, s=1 - down */ int y; int l; struct link *link; struct link **line = p == -1 ? f->f_data->lines2 : f->f_data->lines1; if (p == -1) { y = f->vs->view_pos + f->yw - 1; if (y >= f->f_data->y) y = f->f_data->y - 1; } else { y = f->vs->view_pos; if (y < 0) y = 0; } if (y < 0 || y >= f->f_data->y) goto nolink; link = NULL; do { if (line[y] && (!link || (p > 0 ? line[y] < link : line[y] > link))) link = line[y]; y += p; } while (!(y < 0 || y < f->vs->view_pos || y >= f->vs->view_pos + f->f_data->opt.yw || y >= f->f_data->y)); if (!link) goto nolink; l = link - f->f_data->links; if (s == 0) { next_in_view(f, l, p, in_view, NULL); return; } f->vs->current_link = l; f->vs->orig_link = f->vs->current_link; set_pos_x(f, link); return; nolink: f->vs->current_link = -1; f->vs->orig_link = f->vs->current_link;}void page_down(struct session *ses, struct f_data_c *f, int a){ if (f->vs->view_pos + f->f_data->opt.yw < f->f_data->y) f->vs->view_pos += f->f_data->opt.yw, f->vs->orig_view_pos = f->vs->view_pos, find_link(f, 1, a); else find_link(f, -1, a);}void page_up(struct session *ses, struct f_data_c *f, int a){ f->vs->view_pos -= f->yw; find_link(f, -1, a); if (f->vs->view_pos < 0) f->vs->view_pos = 0/*, find_link(f, 1, a)*/; f->vs->orig_view_pos = f->vs->view_pos;}void set_textarea(struct session *, struct f_data_c *, int);void down(struct session *ses, struct f_data_c *f, int a){ int l = f->vs->current_link; /*if (f->vs->current_link >= f->nlinks - 1) return;*/ if (f->vs->current_link == -1 || !next_in_view(f, f->vs->current_link+1, 1, in_viewy, set_pos_x)) page_down(ses, f, 1); if (l != f->vs->current_link) set_textarea(ses, f, KBD_UP);}void up(struct session *ses, struct f_data_c *f, int a){ int l = f->vs->current_link; /*if (f->vs->current_link == 0) return;*/ if (f->vs->current_link == -1 || !next_in_view(f, f->vs->current_link-1, -1, in_viewy, set_pos_x)) page_up(ses, f, 1); if (l != f->vs->current_link) set_textarea(ses, f, KBD_DOWN);}void scroll(struct session *ses, struct f_data_c *f, int a){ if (f->vs->view_pos + f->f_data->opt.yw >= f->f_data->y && a > 0) return; f->vs->view_pos += a; if (f->vs->view_pos > f->f_data->y - f->f_data->opt.yw && a > 0) f->vs->view_pos = f->f_data->y - f->f_data->opt.yw; if (f->vs->view_pos < 0) f->vs->view_pos = 0; f->vs->orig_view_pos = f->vs->view_pos; if (c_in_view(f)) return; find_link(f, a < 0 ? -1 : 1, 0);}void hscroll(struct session *ses, struct f_data_c *f, int a){ f->vs->view_posx += a; if (f->vs->view_posx >= f->f_data->x) f->vs->view_posx = f->f_data->x - 1; if (f->vs->view_posx < 0) f->vs->view_posx = 0; f->vs->orig_view_posx = f->vs->view_posx; if (c_in_view(f)) return; find_link(f, 1, 0); /* !!! FIXME: check right margin */}void home(struct session *ses, struct f_data_c *f, int a){ f->vs->view_pos = f->vs->view_posx = 0; f->vs->orig_view_posx = f->vs->view_posx; f->vs->orig_view_pos = f->vs->view_pos; find_link(f, 1, 0);}void x_end(struct session *ses, struct f_data_c *f, int a){ f->vs->view_posx = 0; if (f->vs->view_pos < f->f_data->y - f->f_data->opt.yw) f->vs->view_pos = f->f_data->y - f->f_data->opt.yw; if (f->vs->view_pos < 0) f->vs->view_pos = 0; f->vs->orig_view_pos = f->vs->view_pos; f->vs->orig_view_posx = f->vs->view_posx; find_link(f, -1, 0);}int has_form_submit(struct f_data *f, struct form_control *form){ struct form_control *i; int q = 0; foreach (i, f->forms) if (i->form_num == form->form_num) { if ((i->type == FC_SUBMIT || i->type == FC_IMAGE)) return 1; q = 1; } if (!q) internal("form is not on list"); return 0;}void decrement_fc_refcount(struct f_data *f){ if (!--f->refcount) format_cache_entries++;}struct submitted_value { struct submitted_value *next; struct submitted_value *prev; int type; unsigned char *name; unsigned char *value; void *file_content; int fc_len; int position;};void free_succesful_controls(struct list_head *submit){ struct submitted_value *v; foreach(v, *submit) { if (v->name) mem_free(v->name); if (v->value) mem_free(v->value); if (v->file_content) mem_free(v->file_content); } free_list(*submit);}unsigned char *encode_textarea(unsigned char *t){ int len = 0; unsigned char *o = init_str(); for (; *t; t++) { if (*t != '\n') add_chr_to_str(&o, &len, *t); else add_to_str(&o, &len, "\r\n"); } return o;}int compare_submitted(struct submitted_value *sub1, struct submitted_value *sub2);int compare_submitted(struct submitted_value *sub1, struct submitted_value *sub2){ /*int c = (sub1->type == FC_IMAGE) - (sub2->type == FC_IMAGE); if (c) return c;*/ return sub1->position - sub2->position;}void get_succesful_controls(struct f_data_c *f, struct form_control *fc, struct list_head *subm){ int ch; struct form_control *form; init_list(*subm); foreach(form, f->f_data->forms) { if (form->form_num == fc->form_num && ((form->type != FC_SUBMIT && form->type != FC_IMAGE && form->type != FC_RESET) || form == fc) && form->name && form->name[0]) { struct submitted_value *sub; struct form_state *fs; int fi = form->type == FC_IMAGE && form->default_value && *form->default_value ? -1 : 0;; if (!(fs = find_form_state(f, form))) continue; if ((form->type == FC_CHECKBOX || form->type == FC_RADIO) && !fs->state) continue; if (form->type == FC_SELECT && !form->nvalues) continue; fi_rep: sub = mem_alloc(sizeof(struct submitted_value)); memset(sub, 0, sizeof(struct submitted_value)); sub->type = form->type; sub->name = stracpy(form->name); switch (form->type) { case FC_TEXT: case FC_PASSWORD: case FC_FILE: sub->value = stracpy(fs->value); break; case FC_TEXTAREA: sub->value = encode_textarea(fs->value); break; case FC_CHECKBOX: case FC_RADIO: case FC_SUBMIT: case FC_HIDDEN: sub->value = stracpy(form->default_value); break; case FC_SELECT: fixup_select_state(form, fs); sub->value = stracpy(fs->value); break; case FC_IMAGE: if (fi == -1) { sub->value = stracpy(form->default_value); break; } add_to_strn(&sub->name, fi ? ".x" : ".y"); sub->value = stracpy("1"); break; default: internal("bad form control type"); mem_free(sub); continue; } sub->position = form->form_num + form->ctrl_num; add_to_list(*subm, sub); if (form->type == FC_IMAGE && fi < 1) { fi++; goto fi_rep; } } } do { struct submitted_value *sub, *nx; ch = 0; foreach(sub, *subm) if (sub->next != (void *)subm) if (sub->next->position < sub->position) { nx = sub->next; del_from_list(sub); add_at_pos(nx, sub); sub = nx; ch = 1; } foreachback(sub, *subm) if (sub->next != (void *)subm) if (sub->next->position < sub->position) { nx = sub->next; del_from_list(sub); add_at_pos(nx, sub); sub = nx; ch = 1; } } while (ch); }unsigned char *strip_file_name(unsigned char *f){ unsigned char *n; unsigned char *l = f - 1; for (n = f; *n; n++) if (dir_sep(*n)) l = n; return l + 1;}static inline int safe_char(unsigned char c){ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c== '.' || c == '-' || c == '_';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -