⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 view.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef G	{		int i = 0;		while (t2 > t1) {			FWD_UTF_8(t1);			i++;		}		return i;	}#endif}struct line_info *format_text(unsigned char *text, int width, int wrap){	struct line_info *ln = DUMMY;	int lnn = 0;	unsigned char *b = text;	int sk, ps = 0;	while (*text) {		unsigned char *s;		if (*text == '\n') {			sk = 1;			put:			if (!(lnn & (ALLOC_GR-1))) {				if ((unsigned)lnn > MAXINT / sizeof(struct line_info) - ALLOC_GR) overalloc();				ln = mem_realloc(ln, (lnn + ALLOC_GR) * sizeof(struct line_info));			}			ln[lnn].st = b;			ln[lnn++].en = text;			b = text += sk;			continue;		}		if (!wrap || utf8_diff(text, b) < width) {			if (!F) text++;#ifdef G			else FWD_UTF_8(text);#endif			continue;		}		for (s = text; s >= b; s--) if (*s == ' ') {			text = s;			if (wrap == 2) {				*s = '\n';				for (s++; *s; s++) if (*s == '\n') {					if (s[1] != '\n') *s = ' ';					break;				}			}			sk = 1;			goto put;		}		sk = 0;		goto put;	}	if (ps < 2) {		ps++;		sk = 0;		goto put;	}	ln[lnn - 1].st = ln[lnn - 1].en = NULL;	return ln;}int _area_cursor(struct form_control *form, struct form_state *fs){	struct line_info *ln;	int q = 0;	if ((ln = format_text(fs->value, form->cols, form->wrap))) {		int x, y;		for (y = 0; ln[y].st; y++) if (fs->value + fs->state >= ln[y].st && fs->value + fs->state < ln[y].en + (ln[y+1].st != ln[y].en)) {			x = utf8_diff(fs->value + fs->state, ln[y].st);			if (form->wrap && x == form->cols) x--;			if (x >= form->cols + fs->vpos) fs->vpos = x - form->cols + 1;			if (x < fs->vpos) fs->vpos = x;			if (y >= form->rows + fs->vypos) fs->vypos = y - form->rows + 1;			if (y < fs->vypos) fs->vypos = y;			x -= fs->vpos;			y -= fs->vypos;			q = y * form->cols + x;			break;		}		mem_free(ln);	}	return q;}void draw_link(struct terminal *t, struct f_data_c *scr, int l){	struct link *link = &scr->f_data->links[l];	int xp = scr->xp;	int yp = scr->yp;	int xw = scr->xw;	int yw = scr->yw;	int vx, vy;	struct view_state *vs = scr->vs;	int f = 0;	vx = vs->view_posx;	vy = vs->view_pos;	if (scr->link_bg) {		internal("link background not empty");		mem_free(scr->link_bg);	}	if (l == -1) return;	switch (link->type) {		int i;		int q;		case L_LINK:		case L_CHECKBOX:		case L_BUTTON:		case L_SELECT:		case L_FIELD:		case L_AREA:			q = 0;			if (link->type == L_FIELD) {				struct form_state *fs = find_form_state(scr, link->form);				if (fs) q = fs->state - fs->vpos;				/*else internal("link has no form control");*/			} else if (link->type == L_AREA) {				struct form_state *fs = find_form_state(scr, link->form);				if (fs) q = _area_cursor(link->form, fs);				/*else internal("link has no form control");*/			}			if ((unsigned)link->n > MAXINT / sizeof(struct link_bg)) overalloc();			scr->link_bg = mem_alloc(link->n * sizeof(struct link_bg));			scr->link_bg_n = link->n;			for (i = 0; i < link->n; i++) {				int x = link->pos[i].x + xp - vx;				int y = link->pos[i].y + yp - vy;				if (x >= xp && y >= yp && x < xp+xw && y < yp+yw) {					unsigned co;					co = get_char(t, x, y);					if (scr->link_bg) scr->link_bg[i].x = x,							  scr->link_bg[i].y = y,							  scr->link_bg[i].c = co;					if (t->spec->braille && !vs->brl_in_field) goto skip_link;					if (!f || (link->type == L_CHECKBOX && i == 1) || (link->type == L_BUTTON && i == 2) || ((link->type == L_FIELD || link->type == L_AREA) && i == q)) {						int xx = x, yy = y;						if (link->type != L_FIELD && link->type != L_AREA) {							if (((co >> 8) & 0x38) != (link->sel_color & 0x38)) xx = xp + xw - 1, yy = yp + yw - 1;						}						set_cursor(t, x, y, xx, yy);						set_window_ptr(scr->ses->win, x, y);						f = 1;					}					skip_link:;					set_color(t, x, y, /*((link->sel_color << 3) | (co >> 11 & 7)) << 8*/ link->sel_color << 8);				} else scr->link_bg[i].x = scr->link_bg[i].y = scr->link_bg[i].c = -1;			}			break;		default: internal("bad link type");	}}void free_link(struct f_data_c *scr){	if (scr->link_bg) {		mem_free(scr->link_bg);		scr->link_bg = NULL;	}	scr->link_bg_n = 0;}void clear_link(struct terminal *t, struct f_data_c *scr){	if (scr->link_bg) {		int i;		for (i = scr->link_bg_n - 1; i >= 0; i--)			set_char(t, scr->link_bg[i].x, scr->link_bg[i].y, scr->link_bg[i].c);		free_link(scr);	}}int get_range(struct f_data *f, int y, int yw, int l, struct search **s1, struct search **s2){	int i;	*s1 = *s2 = NULL;	for (i = y < 0 ? 0 : y; i < y + yw && i < f->y; i++) {		if (f->slines1[i] && (!*s1 || f->slines1[i] < *s1)) *s1 = f->slines1[i];		if (f->slines2[i] && (!*s2 || f->slines2[i] > *s2)) *s2 = f->slines2[i];	}	if (!*s1 || !*s2) return -1;	*s1 -= l;	if (*s1 < f->search) *s1 = f->search;	if (*s2 + l > f->search + f->nsearch) *s2 = f->search + f->nsearch - l;	if (*s1 > *s2) *s1 = *s2 = NULL;	if (!*s1 || !*s2) return -1;	return 0;}int is_in_range(struct f_data *f, int y, int yw, unsigned char *txt, int *min, int *max){	int found = 0;	int l = strlen(txt);	struct search *s1, *s2;	if (min || max) *min = MAXINT, *max = 0;	if (get_range(f, y, yw, l, &s1, &s2)) return 0;	for (; s1 <= s2; s1++) {		int i;		if (s1->c != txt[0]) {			unable_to_handle_kernel_paging_request___oops:			continue;		}		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;	unsigned char *w = scr->ses->search_word;	if (!w || !*w) return;	get_search_data(scr->f_data);	l = strlen(w);	c = w[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 != w[i]) goto c;		for (i = 0; i < l && (!scr->ses->term->spec->braille || i < 1); 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->ses->search_word || !scr->ses->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 inited = 0;	int i;	retry:	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;		}	}	if (!inited) {		init_ctrl(fc, fs);		inited = 1;		goto retry;	}	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 && (size_t)i < 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, '_');					}				}			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -