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

📄 framebuffer.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 3 页
字号:
		int l1, l2, l3;				/* Draw mouse, background */		mouse_length=mouse_right>fb_xsize?fb_xsize-mouse_left:arrow_width;		background_length=background_right-mouse_right;		if (background_length+mouse_right>fb_xsize)			background_length=fb_xsize-mouse_right;		l1=mouse_length*fb_pixelsize;		l2=(mouse_right-background_left)*fb_pixelsize;		l3=background_length*fb_pixelsize;		for (;mouse_top<yend;mouse_top++){			mouse_drawscansegment(mouse_ptr,mouse_left,mouse_top,l1);			if (background_length>0)				mouse_drawscansegment(					background_ptr +l2,				       	mouse_right,mouse_top ,l3);			mouse_ptr+=skip;			background_ptr+=skip;		}	}	if (background_bottom<mouse_bottom){		/* Count over bottoms! tops will be invalid! */		/* Draw mouse */		mouse_length=mouse_right>fb_xsize?fb_xsize-mouse_left			:arrow_width;		for (;background_bottom<mouse_bottom;background_bottom++){			mouse_drawscansegment(mouse_ptr,mouse_left,background_bottom				,mouse_length*fb_pixelsize);			mouse_ptr+=skip;		}	}else{		/* Draw background */		background_length=background_right>fb_xsize?fb_xsize-background_left			:arrow_width;		for (;mouse_bottom<background_bottom;mouse_bottom++){			mouse_drawscansegment(background_ptr,background_left,mouse_bottom				,background_length*fb_pixelsize);			background_ptr+=skip;		}	}}/* This moves the mouse a sophisticated way when the old and new position of the * cursor overlap. */static inline void redraw_mouse_sophisticated(void){	int new_background_x, new_background_y;	get_mouse_background(mouse_buffer);	put_and_clip_background_buffer_over_mouse_buffer();	memcpy(new_background_buffer,mouse_buffer,fb_pixelsize*arrow_area);	new_background_x=mouse_x;	new_background_y=mouse_y;	render_mouse_arrow();	place_mouse_composite();	memcpy(background_buffer,new_background_buffer,fb_pixelsize*arrow_area);	background_x=new_background_x;	background_y=new_background_y;}static void redraw_mouse(void){		if (!fb_active) return; /* We are not drawing */	if (mouse_x!=background_x||mouse_y!=background_y){		if (RECTANGLES_INTERSECT(			background_x, background_x+arrow_width,			mouse_x, mouse_x+arrow_width,			background_y, background_y+arrow_height,			mouse_y, mouse_y+arrow_height)){			redraw_mouse_sophisticated();		}else{			/* Do a normal hide/show */			get_mouse_background(mouse_buffer);			memcpy(new_background_buffer,				mouse_buffer,arrow_area*fb_pixelsize);			render_mouse_arrow();			hide_mouse();			place_mouse();			memcpy(background_buffer,new_background_buffer				,arrow_area*fb_pixelsize);			background_x=mouse_x;			background_y=mouse_y;		}	}}/* This is an empiric magic that ensures * Good white purity * Correct rounding and dithering prediction * And this is the cabbala: * 063 021 063  * 009 009 021 * 255 085 255 * 036 036 084 */static void generate_palette(struct palette *palette){        int a;	switch (fb_colors)	{		case 16:               	for (a=0;a<fb_palette_colors;a++)                {       	                palette->red[a]=(a&8)?65535:0;               	        palette->green[a]=((a>>1)&3)*(65535/3);                       	palette->blue[a]=(a&1)?65535:0;		}		break;		case 256:                for (a=0;a<fb_palette_colors;a++){                       	palette->red[a]=((a>>5)&7)*(65535/7);                        palette->green[a]=((a>>2)&7)*(65535/7);       	                palette->blue[a]=(a&3)*(65535/3);                }		break;		case 32768:                for (a=0;a<fb_palette_colors;a++){			/*                       	palette->red[a]=((a>>10)&31)*(65535/31);                        palette->green[a]=((a>>5)&31)*(65535/31);       	                palette->blue[a]=(a&31)*(65535/31);			*/                        palette->red[a]=                        palette->green[a]=                        palette->blue[a]=(((a&31)*255)/31)*257;                }		break;		case 65536:                for (a=0;a<fb_palette_colors;a++){			/*                       	palette->red[a]=((a>>11)&31)*(65535/31);                        palette->green[a]=((a>>5)&63)*(65535/63);       	                palette->blue[a]=(a&31)*(65535/31);			*/                        palette->green[a]=(((a&63)*255)/64)*257;                        palette->red[a]=                        palette->blue[a]=(((a&31)*255)/32)*257;                }		break;                default:                for (a=0;a<fb_palette_colors;a++){                        palette->red[a]=                        palette->green[a]=                        palette->blue[a]=a*257;                        /* stuff it in both high and low byte */                }	}}static void alloc_palette(struct palette *pal){	pal->red=mem_calloc(sizeof(unsigned short)*fb_palette_colors);	pal->green=mem_calloc(sizeof(unsigned short)*fb_palette_colors);	pal->blue=mem_calloc(sizeof(unsigned short)*fb_palette_colors);	if (!pal->red||!pal->green||!pal->blue) {		/*internal("Cannot create palette.\n")*/;	}}static void free_palette(struct palette *pal){	mem_free(pal->red);	mem_free(pal->green);	mem_free(pal->blue);}static void set_palette(struct palette *pal){	struct fb_cmap cmap;	int i;	unsigned short *red=pal->red;	unsigned short *green=pal->green;	unsigned short *blue=pal->blue;	__u16 *r, *g, *b, *t;	r=mem_alloc(fb_palette_colors*sizeof(__u16));	g=mem_alloc(fb_palette_colors*sizeof(__u16));	b=mem_alloc(fb_palette_colors*sizeof(__u16));	t=mem_calloc(fb_palette_colors*sizeof(__u16));	if (!r||!g||!b||!t) {		/*internal("Cannot allocate memory.\n")*/;	}	for (i = 0; i < fb_palette_colors; i++)	{	        r[i] = red[i];	        g[i] = green[i];	        b[i] = blue[i];		/*fprintf(stderr, "%d %d %d\n", r[i], g[i], b[i]);*/                /*fprintf(stderr, "%5x: %5x\t%5x\t%5x\t%5x\n",i,r[i],g[i],b[i],t[i]);*/	}	cmap.start = 0;	cmap.len = fb_palette_colors;	cmap.red = r;	cmap.green = g;	cmap.blue = b;	cmap.transp = t;	if ((ioctl(fb_handler, FBIOPUTCMAP, &cmap))==-1) {		/*internal("Cannot set palette\n")*/;	}	mem_free(r);mem_free(g);mem_free(b);mem_free(t);}static void get_palette(struct palette *pal){	struct fb_cmap cmap;	int i;	__u16 *r, *g, *b, *t;	r=mem_alloc(fb_palette_colors*sizeof(__u16));	g=mem_alloc(fb_palette_colors*sizeof(__u16));	b=mem_alloc(fb_palette_colors*sizeof(__u16));	t=mem_alloc(fb_palette_colors*sizeof(__u16));	if (!r||!g||!b||!t) {		/*internal("Cannot allocate memory.\n")*/;	}	cmap.start = 0;	cmap.len = fb_palette_colors;	cmap.red = r;	cmap.green = g;	cmap.blue = b;	cmap.transp = t;	if (ioctl(fb_handler, FBIOGETCMAP, &cmap)) {		/*internal("Cannot get palette\n")*/;	}	for (i = 0; i < fb_palette_colors; i++)	{		/*printf("%d %d %d\n",r[i],g[i],b[i]);*/	        pal->red[i] = r[i];	        pal->green[i] = g[i];	        pal->blue[i] = b[i];	}	mem_free(r);mem_free(g);mem_free(b);mem_free(t);}static void fb_switch_signal(void *data){	struct vt_stat st;	struct rect r;	int signal=(int)(unsigned long)data;	switch(signal)	{		case SIG_REL: /* release */		fb_active=0;		if (!in_gr_operation)ioctl(TTY,VT_RELDISP,1);		break;		case SIG_ACQ: /* acq */		if (ioctl(TTY,VT_GETSTATE,&st)) return;		if (st.v_active != fb_console) return;		fb_active=1;		ioctl(TTY,VT_RELDISP,VT_ACKACQ);		if (have_cmap && current_virtual_device)			set_palette(&global_pal);		r.x1=0;		r.y1=0;		r.x2=fb_xsize;		r.y2=fb_ysize;		if (border_left | border_top | border_right | border_bottom) memset(fb_mem,0,fb_mem_size);		if (current_virtual_device) current_virtual_device->redraw_handler(current_virtual_device,&r);		break;	}}static unsigned char *fb_switch_init(void){	ioctl(TTY, VT_WAITACTIVE, fb_console);	install_signal_handler(SIG_REL, fb_switch_signal, (void*)SIG_REL, 1);	install_signal_handler(SIG_ACQ, fb_switch_signal, (void*)SIG_ACQ, 0);	if (-1 == ioctl(TTY,VT_GETMODE, &vt_omode)) {		return stracpy("Could not get VT mode.\n");	}	memcpy(&vt_mode, &vt_omode, sizeof(vt_mode));	vt_mode.mode   = VT_PROCESS;	vt_mode.waitv  = 0;	vt_mode.relsig = SIG_REL;	vt_mode.acqsig = SIG_ACQ;	if (-1 == ioctl(TTY,VT_SETMODE, &vt_mode)) {		return stracpy("Could not set VT mode.\n");	}	return NULL;}static void fb_switch_shutdown(void){	ioctl(TTY,VT_SETMODE, &vt_omode);}static void fb_shutdown_palette(void){	if (have_cmap)	{		set_palette(&old_palette);		free_palette(&old_palette);		free_palette(&global_pal);	}}static void fb_ctrl_c(struct itrm *i){	kbd_ctrl_c();}#ifndef USE_GPM_DXvoid fb_mouse_setsize(){	struct vt_stat vs;	if (!ioctl(0, VT_GETSTATE, &vs)) {		fd_set zero;		struct timeval tv;		FD_ZERO(&zero);		memset(&tv, 0, sizeof tv);		ioctl(0, VT_ACTIVATE, vs.v_active > 1 ? 1 : 2);		tv.tv_sec = 0;		tv.tv_usec = 100000;		select(0, &zero, &zero, &zero, &tv);		tv.tv_sec = 0;		tv.tv_usec = 100000;		select(0, &zero, &zero, &zero, &tv);		tv.tv_sec = 0;		tv.tv_usec = 100000;		select(0, &zero, &zero, &zero, &tv);		ioctl(0, VT_ACTIVATE, vs.v_active);	}}#endifvoid unhandle_fb_mouse(void);static void fb_gpm_in(void *nic){#ifndef USE_GPM_DX	static int lx = -1, ly = -1;#endif	struct event ev;	Gpm_Event gev;	again:	if (Gpm_GetEvent(&gev) <= 0) {		unhandle_fb_mouse();		return;	}	/*fprintf(stderr, "%d %d\n", gev.x, gev.y);*/#ifndef USE_GPM_DX	if (gev.x != lx || gev.y != ly) {		mouse_x = (gev.x - 1) * fb_xsize / fb_txt_xsize + fb_xsize / fb_txt_xsize / 2 - 1;		mouse_y = (gev.y - 1) * fb_ysize / fb_txt_ysize + fb_ysize / fb_txt_ysize / 2 - 1;		lx = gev.x, ly = gev.y;	}#else	if (gev.dx || gev.dy) {		if (!(gev.type & gpm_smooth)) {			mouse_x += gev.dx * 8;			mouse_y += gev.dy * 8;		} else {			mouse_x += gev.dx;			mouse_y += gev.dy;		}	}#endif	ev.ev = EV_MOUSE;	if (mouse_x >= fb_xsize) mouse_x = fb_xsize - 1;	if (mouse_y >= fb_ysize) mouse_y = fb_ysize - 1;	if (mouse_x < 0) mouse_x = 0;	if (mouse_y < 0) mouse_y = 0;	if (!(gev.type & gpm_smooth) && (gev.dx || gev.dy)) {		mouse_x = (mouse_x + 8) / 8 * 8 - 4;		mouse_y = (mouse_y + 8) / 8 * 8 - 4;		if (mouse_x >= fb_xsize) mouse_x = fb_xsize - 1;		if (mouse_y >= fb_ysize) mouse_y = fb_ysize - 1;		if (mouse_x < 0) mouse_x = 0;		if (mouse_y < 0) mouse_y = 0;	}	ev.x = mouse_x;	ev.y = mouse_y;	if (gev.buttons & GPM_B_LEFT) ev.b = B_LEFT;	else if (gev.buttons & GPM_B_MIDDLE) ev.b = B_MIDDLE;	else if (gev.buttons & GPM_B_RIGHT) ev.b = B_RIGHT;	else ev.b = 0;	if (gev.type & GPM_DOWN) ev.b |= B_DOWN;	else if (gev.type & GPM_UP) ev.b |= B_UP;	else if (gev.type & GPM_DRAG) ev.b |= B_DRAG;	else ev.b |= B_MOVE;#ifndef USE_GPM_DX	if (fb_msetsize < 0) {	} else if (fb_msetsize < 10) {		fb_msetsize++;	} else if ((ev.b & BM_ACT) == B_MOVE && !(ev.b & BM_BUTT)) {		fb_mouse_setsize();		fb_msetsize = -1;	}#endif	if (((ev.b & BM_ACT) == B_MOVE && !(ev.b & BM_BUTT)) || (ev.b & BM_ACT) == B_DRAG) {		if (can_read(fb_hgpm)) goto again;	}	if (!current_virtual_device) return;	if (current_virtual_device->mouse_handler) current_virtual_device->mouse_handler(current_virtual_device, ev.x, ev.y, ev.b);	redraw_mouse();}static int handle_fb_mouse(void){	Gpm_Connect conn;#ifndef USE_GPM_DX	int gpm_ver = 0;	struct winsize ws;	fb_old_ws_v = 0;#endif	fb_hgpm = -1;#ifndef USE_GPM_DX	Gpm_GetLibVersion(&gpm_ver);	if (gpm_ver >= 11900 && ioctl(1, TIOCGWINSZ, &ws) != -1) {		memcpy(&fb_old_ws, &ws, sizeof(struct winsize));		fb_old_ws_v = 1;		ws.ws_row *= 2;		ioctl(1, TIOCSWINSZ, &ws);		fb_msetsize = 0;		memcpy(&fb_new_ws, &ws, sizeof ws);	} else fb_msetsize = -1;	get_terminal_size(1, &fb_txt_xsize, &fb_txt_ysize);#endif	conn.eventMask = ~0;	conn.defaultMask = gpm_smooth;	conn.minMod = 0;	conn.maxMod = -1;	if ((fb_hgpm = Gpm_Open(&conn, 0)) < 0) {		unhandle_fb_mouse();		return -1;	}	set_handlers(fb_hgpm, fb_gpm_in, NULL, NULL, NULL);#ifdef SIGTSTP	install_signal_handler(SIGTSTP, (void (*)(void *))sig_tstp, NULL, 0);#endif#ifdef SIGCONT	install_signal_handler(SIGCONT, (void (*)(void *))sig_cont, NULL, 0);#endif#ifdef SIGTTIN	install_signal_handler(SIGTTIN, (void (*)(void *))sig_tstp, NULL, 0);#endif	return 0;}void unhandle_fb_mouse(void){	if (fb_hgpm >= 0) set_handlers(fb_hgpm, NULL, NULL, NULL, NULL);#ifndef USE_GPM_DX	fb_hgpm = -1;	if (fb_old_ws_v) {		ioctl(1, TIOCSWINSZ, &fb_old_ws);		fb_old_ws_v = 0;	}#endif	Gpm_Close();#ifdef SIGTSTP	install_signal_handler(SIGTSTP, (void (*)(void *))sig_tstp, NULL, 0);#endif#ifdef SIGCONT	install_signal_handler(SIGCONT, (void (*)(void *))sig_cont, NULL, 0);#endif#ifdef SIGTTIN	install_signal_handler(SIGTTIN, (void (*)(void *))sig_tstp, NULL, 0);#endif}#ifndef USE_GPM_DXstatic void block_fb_mouse(void){	if (fb_hgpm >= 0) set_handlers(fb_hgpm, NULL, NULL, NULL, NULL);#ifndef USE_GPM_DX	if (fb_old_ws_v) {		ioctl(1, TIOCSWINSZ, &fb_old_ws);	}#endif}static void unblock_fb_mouse(void){	if (fb_hgpm >= 0) set_handlers(fb_hgpm, fb_gpm_in, NULL, NULL, NULL);#ifndef USE_GPM_DX	if (fb_old_ws_v) {		ioctl(1, TIOCSWINSZ, &fb_new_ws);		fb_msetsize = 0;	}#endif}#endifstatic void fb_hide_cursor(void){	printf("\033[10000B\033[10000C\033[?25l");	fflush(stdout);}static void fb_show_cursor(void){	printf("\033[10000D\033[?25h");	fflush(stdout);}static unsigned char *fb_init_driver(unsigned char *param, unsigned char *ignore){	unsigned char *e;	struct stat st;	kbd_set_raw = 1;	fb_old_vd = NULL;	ignore=ignore;	fb_driver_param=NULL;	if(param != NULL)		fb_driver_param=stracpy(param);	border_left = border_right = border_top = border_bottom = 0;	if (!param) param="";	if (*param) {		if (*param < '0' || *param > '9')			{ bad_p:				if(fb_driver_param) { mem_free(fb_driver_param); fb_driver_param=NULL; }				return stracpy("-mode syntax is left_border[,top_border[,right_border[,bottom_border]]]\n"); }		border_left = strtoul(param, (char **)(void *)&param, 10);		if (*param == ',') param++;	} else {		border_left = 0;	}	if (*param) {		if (*param < '0' || *param > '9') goto bad_p;		border_top = strtoul(param, (char **)(void *)&param, 10);		if (*param == ',') param++;	} else {		border_top = border_left;	}	if (*param) {		if (*param < '0' || *param > '9') goto bad_p;		border_right = strtoul(param, (char **)(void *)&param, 10);		if (*param == ',') param++;	} else {		border_right = border_left;	}	if (*param) {		if (*param < '0' || *param > '9') goto bad_p;		border_bottom = strtoul(param, (char **)(void *)&param, 10);		if (*param == ',') param++;

⌨️ 快捷键说明

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