📄 view.c
字号:
for (i = 1; i < l; i++) if (s1[i].c != txt[i]) goto unable_to_handle_kernel_paging_request___oops; for (i = 0; i < l; i++) if (s1[i].y >= y && s1[i].y < y + yw && s1[i].n) goto in_view; continue; in_view: if (!min && !max) return 1; found = 1; for (i = 0; i < l; i++) if (s1[i].n) { if (s1[i].x < *min) *min = s1[i].x; if (s1[i].x + s1[i].n > *max) *max = s1[i].x + s1[i].n; } } return found;}void get_searched(struct f_data_c *scr, struct point **pt, int *pl){ int xp = scr->xp; int yp = scr->yp; int xw = scr->xw; int yw = scr->yw; int vx = scr->vs->view_posx; int vy = scr->vs->view_pos; struct search *s1, *s2; int l; unsigned char c; struct point *points = DUMMY; int len = 0; if (!scr->search_word || !*scr->search_word || !(*scr->search_word)[0]) return; get_search_data(scr->f_data); l = strlen(*scr->search_word); c = (*scr->search_word)[0]; if (get_range(scr->f_data, scr->vs->view_pos, scr->yw, l, &s1, &s2)) goto ret; for (; s1 <= s2; s1++) { int i, j; if (s1->c != c) { c:continue; } for (i = 1; i < l; i++) if (s1[i].c != (*scr->search_word)[i]) goto c; for (i = 0; i < l; i++) for (j = 0; j < s1[i].n; j++) { int x = s1[i].x + j + xp - vx; int y = s1[i].y + yp - vy; if (x >= xp && y >= yp && x < xp + xw && y < yp + yw) { /*unsigned co; co = get_char(t, x, y); co = ((co >> 3) & 0x0700) | ((co << 3) & 0x3800); set_color(t, x, y, co);*/ if (!(len & (ALLOC_GR - 1))) { if ((unsigned)len > MAXINT / sizeof(struct point) - ALLOC_GR) overalloc(); points = mem_realloc(points, sizeof(struct point) * (len + ALLOC_GR)); } points[len].x = s1[i].x + j; points[len++].y = s1[i].y; } } } ret: *pt = points; *pl = len;}void draw_searched(struct terminal *t, struct f_data_c *scr){ int xp = scr->xp; int yp = scr->yp; int vx = scr->vs->view_posx; int vy = scr->vs->view_pos; struct point *pt; int len, i; if (!scr->search_word || !*scr->search_word || !(*scr->search_word)[0]) return; get_searched(scr, &pt, &len); for (i = 0; i < len; i++) { int x = pt[i].x + xp - vx, y = pt[i].y + yp - vy; unsigned co; co = get_char(t, x, y); co = ((co >> 3) & 0x0700) | ((co << 3) & 0x3800); set_color(t, x, y, co); } mem_free(pt);}void draw_current_link(struct terminal *t, struct f_data_c *scr){ draw_link(t, scr, scr->vs->current_link); draw_searched(t, scr);}struct link *get_first_link(struct f_data_c *f){ int i; struct link *l = f->f_data->links + f->f_data->nlinks; for (i = f->vs->view_pos; i < f->vs->view_pos + f->yw; i++) if (i >= 0 && i < f->f_data->y && f->f_data->lines1[i] && f->f_data->lines1[i] < l) l = f->f_data->lines1[i]; if (l == f->f_data->links + f->f_data->nlinks) l = NULL; return l;}struct link *get_last_link(struct f_data_c *f){ int i; struct link *l = NULL; for (i = f->vs->view_pos; i < f->vs->view_pos + f->yw; i++) if (i >= 0 && i < f->f_data->y && f->f_data->lines2[i] > l) l = f->f_data->lines2[i]; return l;}void fixup_select_state(struct form_control *fc, struct form_state *fs){ int i; if (fs->state >= 0 && fs->state < fc->nvalues && !strcmp(fc->values[fs->state], fs->value)) return; for (i = 0; i < fc->nvalues; i++) { if (!strcmp(fc->values[i], fs->value)) { fs->state = i; return; } } fs->state = 0; if (fs->value) mem_free(fs->value); if (fc->nvalues) fs->value = stracpy(fc->values[0]); else fs->value = stracpy("");}void init_ctrl(struct form_control *form, struct form_state *fs){ if (fs->value) mem_free(fs->value), fs->value = NULL; switch (form->type) { case FC_TEXT: case FC_PASSWORD: case FC_TEXTAREA: fs->value = stracpy(form->default_value); fs->state = strlen(form->default_value); fs->vpos = 0; break; case FC_FILE: fs->value = stracpy(""); fs->state = 0; fs->vpos = 0; break; case FC_CHECKBOX: case FC_RADIO: fs->state = form->default_state; break; case FC_SELECT: fs->value = stracpy(form->default_value); fs->state = form->default_state; fixup_select_state(form, fs); break; }}struct form_state *find_form_state(struct f_data_c *f, struct form_control *form){ struct view_state *vs = f->vs; struct form_state *fs; int n = form->g_ctrl_num; if (n < vs->form_info_len) fs = &vs->form_info[n]; else { if ((unsigned)n > MAXINT / sizeof(struct form_state) - 1) overalloc(); fs = mem_realloc(vs->form_info, (n + 1) * sizeof(struct form_state)); vs->form_info = fs; memset(fs + vs->form_info_len, 0, (n + 1 - vs->form_info_len) * sizeof(struct form_state)); vs->form_info_len = n + 1; fs = &vs->form_info[n]; } if (fs->form_num == form->form_num && fs->ctrl_num == form->ctrl_num && fs->g_ctrl_num == form->g_ctrl_num && fs->position == form->position && fs->type == form->type) return fs; if (fs->value) mem_free(fs->value); memset(fs, 0, sizeof(struct form_state)); fs->form_num = form->form_num; fs->ctrl_num = form->ctrl_num; fs->g_ctrl_num = form->g_ctrl_num; fs->position = form->position; fs->type = form->type; init_ctrl(form, fs); return fs;}void draw_form_entry(struct terminal *t, struct f_data_c *f, struct link *l){ int xp = f->xp; int yp = f->yp; int xw = f->xw; int yw = f->yw; struct view_state *vs = f->vs; int vx = vs->view_posx; int vy = vs->view_pos; struct form_state *fs; struct form_control *form = l->form; int i, x, y; if (!form) { internal("link %d has no form", (int)(l - f->f_data->links)); return; } if (!(fs = find_form_state(f, form))) return; switch (form->type) { unsigned char *s; struct line_info *ln, *lnx; int sl; 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 (!l->n) break; x = l->pos[0].x + xp - vx; y = l->pos[0].y + yp - vy; for (i = 0; i < form->size; i++, x++) if (x >= xp && y >= yp && x < xp+xw && y < yp+yw) { if (fs->value && i >= -fs->vpos && i < (int)strlen(fs->value) - fs->vpos) set_only_char(t, x, y, form->type != FC_PASSWORD ? fs->value[i + fs->vpos] : '*'); else set_only_char(t, x, y, '_'); } break; case FC_TEXTAREA: if (!l->n) break; x = l->pos[0].x + xp - vx; y = l->pos[0].y + yp - vy; _area_cursor(form, fs); if (!(lnx = format_text(fs->value, form->cols, form->wrap))) break; ln = lnx; sl = fs->vypos; while (ln->st && sl) sl--, ln++; for (; ln->st && y < l->pos[0].y + yp - vy + form->rows; ln++, y++) { for (i = 0; i < form->cols; i++) { if (x+i >= xp && y >= yp && x+i < xp+xw && y < yp+yw) { if (fs->value && i >= -fs->vpos && i + fs->vpos < ln->en - ln->st) set_only_char(t, x+i, y, ln->st[i + fs->vpos]); else set_only_char(t, x+i, y, '_'); } } } for (; y < l->pos[0].y + yp - vy + form->rows; y++) { for (i = 0; i < form->cols; i++) { if (x+i >= xp && y >= yp && x+i < xp+xw && y < yp+yw) set_only_char(t, x+i, y, '_'); } } mem_free(lnx); break; case FC_CHECKBOX: case FC_RADIO: if (l->n < 2) break; x = l->pos[1].x + xp - vx; y = l->pos[1].y + yp - vy; if (x >= xp && y >= yp && x < xp+xw && y < yp+yw) set_only_char(t, x, y, fs->state ? 'X' : ' '); break; case FC_SELECT: fixup_select_state(form, fs); s = fs->state < form->nvalues ? form->labels[fs->state] : (unsigned char *)""; sl = s ? strlen(s) : 0; for (i = 0; i < l->n; i++) { x = l->pos[i].x + xp - vx; y = l->pos[i].y + yp - vy; if (x >= xp && y >= yp && x < xp+xw && y < yp+yw) set_only_char(t, x, y, i < sl ? s[i] : '_'); } break; case FC_SUBMIT: case FC_IMAGE: case FC_RESET: case FC_HIDDEN: break; }}void draw_forms(struct terminal *t, struct f_data_c *f){ struct link *l1 = get_first_link(f); struct link *l2 = get_last_link(f); if (!l1 || !l2) { if (l1 || l2) internal("get_first_link == %p, get_last_link == %p", l1, l2); return; } do { if (l1->type != L_LINK) draw_form_entry(t, f, l1); } while (l1++ < l2);}/* 0 -> 1 <- 2 v 3 ^ */unsigned char fr_trans[2][4] = {{0xb3, 0xc3, 0xb4, 0xc5}, {0xc4, 0xc2, 0xc1, 0xc5}};void set_xchar(struct terminal *t, int x, int y, unsigned dir){ unsigned c; if (x < 0 || x >= t->x || y < 0 || y >= t->y) return; c = get_char(t, x, y); if (!(c & ATTR_FRAME)) return; c &= 0xff; if (c == fr_trans[dir / 2][0]) set_only_char(t, x, y, fr_trans[dir / 2][1 + (dir & 1)] | ATTR_FRAME); else if (c == fr_trans[dir / 2][2 - (dir & 1)]) set_only_char(t, x, y, fr_trans[dir / 2][3] | ATTR_FRAME);}void draw_frame_lines(struct terminal *t, struct frameset_desc *fsd, int xp, int yp){ int i, j; int x, y; if (!fsd) return; y = yp - 1; for (j = 0; j < fsd->y; j++) { int wwy = fsd->f[j * fsd->x].yw; x = xp - 1; 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); 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); 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); x += wwx + 1; } y += wwy + 1; } y = yp - 1; for (j = 0; j < fsd->y; j++) { int wwy = fsd->f[j * fsd->x].yw; x = xp - 1; for (i = 0; i < fsd->x; i++) { int wwx = fsd->f[i].xw; if (fsd->f[j * fsd->x + i].subframe) { draw_frame_lines(t, fsd->f[j * fsd->x + i].subframe, x + 1, y + 1); } x += wwx + 1; } y += wwy + 1; }}void draw_doc(struct terminal *t, struct f_data_c *scr, int active){ int y; int xp = scr->xp; int yp = scr->yp; int xw = scr->xw; int yw = scr->yw; struct view_state *vs; int vx, vy; struct cache_entry *ce; if (active) { set_cursor(t, xp + xw - 1, yp + yw - 1, xp + xw - 1, yp + yw - 1); set_window_ptr(get_root_window(t), xp, yp); } if (!scr->vs) { fill_area(t, xp, yp, xw, yw, scr->f_data->y ? scr->f_data->bg : ' '); return; } if (scr->f_data->frame) { fill_area(t, xp, yp, xw, yw, scr->f_data->y ? scr->f_data->bg : ' '); draw_frame_lines(t, scr->f_data->frame_desc, xp, yp); if (scr->vs && scr->vs->current_link == -1) scr->vs->current_link = 0, scr->vs->orig_link = scr->vs->current_link; return; } check_vs(scr); vs = scr->vs; if (vs->goto_position && !get_cache_entry(vs->url, &ce) && (vy = find_tag(scr->f_data, vs->goto_position)) != -1) { if (vs->goto_position_end) mem_free(vs->goto_position_end); if (ce->incomplete) { vs->goto_position_end = vs->goto_position; } else { vs->goto_position_end = NULL; mem_free(vs->goto_position); } vs->goto_position = NULL; goto goto_vy; } if (vs->goto_position_end && !get_cache_entry(vs->url, &ce) && !ce->incomplete && (vy = find_tag(scr->f_data, vs->goto_position_end)) != -1) { mem_free(vs->goto_position_end); vs->goto_position_end = NULL; goto_vy: if (vy > scr->f_data->y) vy = scr->f_data->y - 1; if (vy < 0) vy = 0; vs->view_pos = vy; vs->view_posx = 0; vs->orig_view_pos = vs->view_pos; vs->orig_view_posx = vs->view_posx; set_link(scr); } if (vs->view_pos != vs->orig_view_pos || vs->view_posx != vs->orig_view_posx || vs->current_link != vs->orig_link) { int ol; vs->view_pos = vs->orig_view_pos; vs->view_posx = vs->orig_view_posx; ol = vs->orig_link; if (ol < scr->f_data->nlinks) vs->current_link = ol; set_link(scr); check_vs(scr); vs->orig_link = ol; } vx = vs->view_posx; vy = vs->view_pos; if (scr->xl == vx && scr->yl == vy && scr->xl != -1 && (!scr->search_word || !*scr->search_word || !(*scr->search_word)[0])) { clear_link(t, scr); draw_forms(t, scr); if (active) draw_current_link(t, scr); return; } free_link(scr); scr->xl = vx; scr->yl = vy; fill_area(t, xp, yp, xw, yw, scr->f_data->y ? scr->f_data->bg : ' '); 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; if (vy != vs->view_pos) vy = vs->view_pos, check_vs(scr); for (y = vy <= 0 ? 0 : vy; y < (-vy + scr->f_data->y <= yw ? scr->f_data->y : yw + vy); y++) { int st = vx <= 0 ? 0 : vx; int en = -vx + scr->f_data->data[y].l <= xw ? scr->f_data->data[y].l : xw + vx; set_line(t, xp + st - vx, yp + y - vy, en - st, &scr->f_data->data[y].d[st]); } draw_forms(t, scr); if (active) draw_current_link(t, scr); if (scr->search_word && *scr->search_word && (*scr->search_word)[0]) scr->xl = scr->yl = -1;}void draw_frames(struct session *ses){ int n; int i, d, more; int *l; struct f_data_c *f, *cf; if (!ses->screen->f_data->frame) return; n = 0; foreach(f, ses->scrn_frames) f->xl = f->yl = -1, n++; l = &cur_loc(ses)->vs.current_link; if (*l < 0) *l = 0; if (!n) n = 1; *l %= n; i = *l; cf = current_frame(ses); d = 0; do { more = 0; foreach(f, ses->scrn_frames) { if (f->depth == d) draw_doc(ses->term, f, f == cf); else if (f->depth > d) more = 1; } d++; } while (more);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -