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

📄 svgalib.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 5 页
字号:
 */static void show_mouse(void){	get_mouse_background(background_buffer);	background_x=mouse_x;	background_y=mouse_y;	memcpy(mouse_buffer,background_buffer,bmpixelsize*arrow_area);	render_mouse_arrow();	place_mouse();}/* Doesn't draw anything into the screen */static void put_and_clip_background_buffer_over_mouse_buffer(void){	unsigned char *bbufptr=background_buffer, *mbufptr=mouse_buffer;	int left=background_x-mouse_x;	int top=background_y-mouse_y;	int right,bottom;	int bmpixelsizeL=bmpixelsize;	int number_of_bytes;	int byte_skip;	right=left+arrow_width;	bottom=top+arrow_height;	if (left<0){		bbufptr-=left*bmpixelsizeL;		left=0;	}	if (right>arrow_width) right=arrow_width;	if (top<0){		bbufptr-=top*bmpixelsizeL*arrow_width;		top=0;	}	if (bottom>arrow_height) bottom=arrow_height;	mbufptr+=bmpixelsizeL*(left+arrow_width*top);	byte_skip=arrow_width*bmpixelsizeL;	number_of_bytes=bmpixelsizeL*(right-left);	for (;top<bottom;top++){		memcpy(mbufptr,bbufptr,number_of_bytes);		mbufptr+=byte_skip;		bbufptr+=byte_skip;	}}/* This draws both the contents of background_buffer and mouse_buffer in a scan * way (left-right, top-bottom), so the flicker is reduced. */static inline void place_mouse_composite(void){	int mouse_left=mouse_x;	int mouse_top=mouse_y;	int background_left=background_x;	int background_top=background_y;	int mouse_right=mouse_left+arrow_width;	int mouse_bottom=mouse_top+arrow_height;	int background_right=background_left+arrow_width;	int background_bottom=background_top+arrow_height;	int skip=arrow_width*bmpixelsize;	int background_length,mouse_length;	unsigned char *mouse_ptr=mouse_buffer,*background_ptr=background_buffer;	int yend;	/* First let's sync to the beam - wait for the beginning of vertical retrace	 * (it would be better to wait for the beginning of the blank, however,	 * svgalib doesn't provide it as VGA and SVGA cards don't provide it	 */	/* This will probably not make any good anyway.	if (vga_colors>=256)		vga_waitretrace();	*/		if (mouse_bottom>ysize) mouse_bottom=ysize;	if (background_bottom>ysize) background_bottom=ysize;	SYNC	/* We have to sync because mouse_drawscansegment does not wait for	 * the accelerator to finish. But we never waste time here because	 * mouse_drawscansegment is never accelerated.	 */	/* Let's do the top part */	if (background_top<mouse_top){		/* Draw the background */		background_length=background_right>xsize?xsize-background_left			:arrow_width;		for (;background_top<mouse_top;background_top++){			mouse_drawscansegment(background_ptr,background_left				,background_top,background_length*bmpixelsize);			background_ptr+=skip;		}				}else if (background_top>mouse_top){		/* Draw the mouse */		mouse_length=mouse_right>xsize			?xsize-mouse_left:arrow_width;		for (;mouse_top<background_top;mouse_top++){			mouse_drawscansegment(mouse_ptr,mouse_left,mouse_top,mouse_length*bmpixelsize);			mouse_ptr+=skip;		}	}	/* Let's do the middle part */	yend=mouse_bottom<background_bottom?mouse_bottom:background_bottom;	if (background_left<mouse_left){		/* Draw background, mouse */		mouse_length=mouse_right>xsize?xsize-mouse_left:arrow_width;		for (;mouse_top<yend;mouse_top++){			mouse_drawscansegment(background_ptr,background_left,mouse_top				,(mouse_left-background_left)*bmpixelsize);			mouse_drawscansegment(mouse_ptr,mouse_left,mouse_top,mouse_length*bmpixelsize);			mouse_ptr+=skip;			background_ptr+=skip;		}				}else{		int l1, l2, l3;				/* Draw mouse, background */		mouse_length=mouse_right>xsize?xsize-mouse_left:arrow_width;		background_length=background_right-mouse_right;		if (background_length+mouse_right>xsize)			background_length=xsize-mouse_right;		l1=mouse_length*bmpixelsize;		l2=(mouse_right-background_left)*bmpixelsize;		l3=background_length*bmpixelsize;		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>xsize?xsize-mouse_left			:arrow_width;		for (;background_bottom<mouse_bottom;background_bottom++){			mouse_drawscansegment(mouse_ptr,mouse_left,background_bottom				,mouse_length*bmpixelsize);			mouse_ptr+=skip;		}	}else{		/* Draw background */		background_length=background_right>xsize?xsize-background_left			:arrow_width;		for (;mouse_bottom<background_bottom;mouse_bottom++){			mouse_drawscansegment(background_ptr,background_left,mouse_bottom				,background_length*bmpixelsize);			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,bmpixelsize*arrow_area);	new_background_x=mouse_x;	new_background_y=mouse_y;	render_mouse_arrow();	place_mouse_composite();	memcpy(background_buffer,new_background_buffer,bmpixelsize*arrow_area);	background_x=new_background_x;	background_y=new_background_y;}static void redraw_mouse(void){		if (flags) 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*bmpixelsize);			render_mouse_arrow();			hide_mouse();			place_mouse();			memcpy(background_buffer,new_background_buffer				,arrow_area*bmpixelsize);			background_x=mouse_x;			background_y=mouse_y;		}	}}static unsigned char *svga_get_driver_param(void){	return svga_driver_param;}static void generate_palette_outer(void){	if (vga_colors==16||vga_colors==256){		struct irgb *palette;		palette=mem_alloc(vga_colors*sizeof(*palette));		generate_palette(palette);		set_palette(palette);		mem_free(palette);		/* Palette in SVGAlib will be always color cube */	}}/* This is to be called after vga_setmode and sets up accelerator, * svgalib functions */static void setup_mode(int mode){	vga_modeinfo *i;	int sig;	accel_avail=vga_ext_set(VGA_EXT_AVAILABLE,VGA_AVAIL_ACCEL);	if (vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_SET)&VGA_CLUT8){		vga_ext_set(VGA_EXT_SET,VGA_CLUT8);		palette_depth=8;	}else palette_depth=6;	i=vga_getmodeinfo(mode);	vga_bytes=i->bytesperpixel;	bmpixelsize=vga_bytes?vga_bytes:1;	vga_misordered=!!(i->flags&RGB_MISORDERED);	mode_x=!!(i->flags&IS_MODEX);	vga_linear=!!(i->flags&IS_LINEAR);	/*	if (!vga_linear && i->flags&CAPABLE_LINEAR && 0<=vga_setlinearaddressing()) vga_linear=1; 	*/	my_graph_mem=vga_getgraphmem();	svga_driver.x = xsize=i->width;	svga_driver.y = ysize=i->height;	aspect_native=(196608*xsize+(ysize<<1))/(ysize<<2);	aspect=aspect_native*bfu_aspect+0.5;	vga_colors=i->colors;	if (xsize==320&&ysize==200&&vga_colors==256) vga_linear=1; /* The mode		does not need to page :-) */	vga_linewidth=i->linewidth;	if (!vga_linear){		vga_page=-1;	}	vga_misordered=!!i->flags&RGB_MISORDERED;	/*dump_mode_info_into_file(i);*/	svga_driver.depth=0;	svga_driver.depth|=vga_misordered<<8;	switch (vga_colors){		case 16:		sig=4;		break;		case 256:		sig=8;		break;		case 32768:		sig=15;		break;		case 65536:		sig=16;		break;		case 16777216:		sig=24;		break;		default:		sig=0; /* Only to suppress warning */		break;	}	svga_driver.depth|=sig<<3;	svga_driver.depth|=bmpixelsize;	/* setup_functions uses depth. */	setup_functions();	generate_palette_outer();}#ifndef __SPAD__static void vtswitch_handler(void * nothing){	int oktowrite;	nothing=nothing;	vga_unlockvc();	vga_lockvc();	oktowrite=vga_oktowrite();	if (!oktowrite&&!flags){		backup_virtual_device=current_virtual_device;		current_virtual_device=NULL;	}	if (flags==1&&oktowrite) current_virtual_device=backup_virtual_device;	flags=(flags&~1)|!oktowrite;	svgalib_timer_id=install_timer(100,vtswitch_handler, NULL);}#endifstatic void svga_ctrl_c(struct itrm *i){	kbd_ctrl_c();}/* Param: one string which is to be compared with one from modes. * Copies the svga_driver into gr_driver. * Returns: 	0 OK *		1 Passed mode unknown by svga_driver *		2 Passed mode unknown by svgalib * mikulas: Change: Returns:	NULL: OK *				non-null: poiner to string with error *					  description, string must be freed */static unsigned char *svga_init_driver(unsigned char *param, unsigned char *display){	int j;	kbd_set_raw = 0;	vga_init();	svga_driver.flags |= GD_NEED_CODEPAGE;	j = 0;	svga_driver_param=NULL;	if (!param || !*param) goto not_found;	svga_driver_param=stracpy(param);	for (j=0;(size_t)j<sizeof(modes)/sizeof(*modes);j++)		if (!strcasecmp(modes[j].name,param)) goto found;	j = 1;	not_found:	{		unsigned char *m = init_str();		int l = 0;		int f = 0;		if (j) {			add_to_str(&m, &l, "Video mode ");			add_to_str(&m, &l, param);			add_to_str(&m, &l, " not supported by ");			add_to_str(&m, &l, j == 2 ? "your video card" : "svgalib");			add_to_str(&m, &l, ".\n");		} else add_to_str(&m, &l, "There is no default video mode.\n");		for (j=0;(size_t)j<sizeof(modes)/sizeof(*modes);j++) if (vga_hasmode(modes[j].number)) {			if (f) add_to_str(&m, &l, ", ");			else f = 1, add_to_str(&m, &l, "The following modes are supported:\n");			add_to_str(&m, &l, modes[j].name);		}		if (f) add_to_str(&m, &l, "\nUse -mode switch to set video mode.\n");		else add_to_str(&m, &l, "There are no supported video modes. Links can't run on svgalib.\n");		if(svga_driver_param)mem_free(svga_driver_param),svga_driver_param=NULL;		return m;			}	found:	if (!vga_hasmode(modes[j].number)) {		j = 2;		goto not_found;	}	if (init_virtual_devices(&svga_driver, NUMBER_OF_DEVICES))	{		if(svga_driver_param)mem_free(svga_driver_param),svga_driver_param=NULL;		return stracpy("Allocation of virtual devices failed.\n");	}	if ((vga_getmousetype()&MOUSE_TYPE_MASK)==MOUSE_NONE)		{			vga_setmousesupport(0);			mouse_works=0;		}else{			vga_setmousesupport(1);			mouse_works=1;		}	vga_lockvc();#ifndef __SPAD__	svgalib_timer_id=install_timer(100,vtswitch_handler,NULL);	if (vga_runinbackground_version()>=1) vga_runinbackground(1);#endif	vga_setmode(vga_mode=modes[j].number);	setup_mode(modes[j].number);	handle_svgalib_keyboard((void (*)(void *, unsigned char *, int))svgalib_key_in);	if (mouse_works){		if ((unsigned)arrow_area > (unsigned)MAXINT / bmpixelsize) overalloc();		mouse_buffer=mem_alloc(bmpixelsize*arrow_area);		background_buffer=mem_alloc(bmpixelsize*arrow_area);		new_background_buffer=mem_alloc(bmpixelsize*arrow_area);		mouse_black=svga_driver.get_color(0);		mouse_white=svga_driver.get_color(0xffffff);		mouse_graphics_device=svga_driver.init_device();		virtual_devices[0] = NULL;		global_mouse_hidden=1;		background_x=mouse_x=xsize>>1;		background_y=mouse_y=ysize>>1;		show_mouse();		mouse_seteventhandler(mouse_event_handler);	}else{		global_mouse_hidden=1;		/* To ensure hide_mouse and show_mouse will do nothing */	}	signal(SIGPIPE, SIG_IGN);	signal(SIGTSTP, SIG_IGN);	install_signal_handler(SIGINT, (void (*)(void *))svga_ctrl_c, ditrm, 0);	return NULL;}/* Return value:	0 alloced on heap *			1 alloced in vidram *			2 alloced in X server shm *//*static int svga_get_filled_bitmap(struct bitmap *dest, long color){	int n;		if (dest->x && (unsigned)dest->x * (unsigned)dest->y / (unsigned)dest->x != (unsigned)dest->y) overalloc();	if ((unsigned)dest->x * (unsigned)dest->y > MAXINT / bmpixelsize) overalloc();	n=dest->x*dest->y*bmpixelsize;	dest->data=mem_alloc(n);	pixel_set(dest->data,n,&color);	dest->skip=dest->x*bmpixelsize;	dest->flags=0;	return 0;}*//* Return value:	0 alloced on heap *			1 alloced in vidram *			2 alloced in X server shm */static int svga_get_empty_bitmap(struct bitmap *dest){	if (dest->x && (unsigned)dest->x * (unsigned)dest->y / (unsigned)dest->x != (unsigned)dest->y) overalloc();	if ((unsigned)dest->x * (unsigned)dest->y > (unsigned)MAXINT / bmpixelsize) overalloc();	dest->data=mem_alloc(dest->x*dest->y*bmpixelsize);	dest->skip=dest->x*bmpixelsize;	dest->flags=0;	return 0;}static int vga_block(struct graphics_device *dev){	int overridden;	overridden=(flags>>1)&1;	if (!overridden){		if (!(flags&1)){			backup_virtual_device=current_virtual_device;			current_virtual_device=NULL;		}		svgalib_block_itrm(ditrm);		if (mouse_works){			hide_mouse();			/* mouse_close(); This is not necessary as it is				handled by vga_setmode(TEXT). */		}		vga_setmode(TEXT);	}	flags|=2;	return overridden;}static int vga_unblock(struct graphics_device *dev){#ifdef DEBUG	if (current_virtual_device) {		internal("vga_unblock called without vga_block");		return 0;	}#endif /* #ifdef DEBUG */	flags&=~2;	if (!flags) current_virtual_device=backup_virtual_device;	vga_setmousesupport(1);	vga_setmode(vga_mode);	setup_mode(vga_mode);	if (mouse_works){		show_mouse();		mouse_seteventhandler(mouse_event_handler);	}	svgalib_unblock_itrm(ditrm);	if (current_virtual_device) current_virtual_device->redraw_handler(current_virtual_device			,&current_virtual_device->size);	return 0;}static void *svga_prepare_strip(struct bitmap *bmp, int top, int lines){	return ((char *)bmp->data)+bmp->skip*top;}static void svga_commit_strip(struct bitmap *bmp, int top, int lines){	return;}/* This is a nasty hack */#undef selectint vga_select(int  n,  fd_set *readfds, fd_set *writefds, fd_set *exceptfds,			      struct timeval *timeout){	int retval,i;	if (drv != &svga_driver) return select(n, readfds, writefds, exceptfds, timeout);	/* The second flag here is to suppress mouse wait	 * in blocked state */	retval=vga_waitevent((mouse_works&&!(flags&2) ? VGA_MOUSEEVENT : 0)#i

⌨️ 快捷键说明

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