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

📄 svgalib.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 5 页
字号:
{	memcpy(&dev->clip, r, sizeof(struct rect));	if (dev->clip.x1>=dev->clip.x2||dev->clip.y2<=dev->clip.y1||dev->clip.y2<=0||dev->clip.x2<=0||dev->clip.x1>=xsize			||dev->clip.y1>=ysize){		/* Empty region */		dev->clip.x1=dev->clip.x2=dev->clip.y1=dev->clip.y2=0;	}else{		if (dev->clip.x1<0) dev->clip.x1=0;		if (dev->clip.x2>xsize) dev->clip.x2=xsize;		if (dev->clip.y1<0) dev->clip.y1=0;		if (dev->clip.y2>ysize) dev->clip.y2=ysize;	}}/* For modes where video memory is not directly accessible through svgalib */static inline void fill_area_drawscansegment(struct graphics_device *dev, int left, int top, int right, int bottom, long color){	int xs;	int col=*(unsigned char *)&color;		FILL_CLIP_PREFACE	SYNC	xs=right-left;	memset(scroll_buffer,col,xs);	for (;top<bottom;top++){		vga_drawscansegment(scroll_buffer,left,top,xs);	}	END_MOUSE}/* Emulates horizontal line by calling fill_area */static void draw_hline_fill_area(struct graphics_device *dev, int left, int y, int right, long color){	dev->drv->fill_area(dev,left,y,right,y+1,color);}/* Emulates vline by fill_area */static void draw_vline_fill_area(struct graphics_device *dev, int x, int top, int bottom, long color){	dev->drv->fill_area(dev,x,top,x+1,bottom, color);}/* This does no clipping and is used only by the mouse code * length is in bytes, not in pixels */static int drawscansegment_linear(unsigned char *colors, int x, int y, int length){	unsigned char *ptr=my_graph_mem+vga_linewidth*y+vga_bytes*x;	memcpy (ptr,colors,length);	return 0;}/* This does no clipping and is used only by the mouse code * length is in bytes, not in pixels */static int getscansegment_linear(unsigned char *colors, int x, int y, int length){	unsigned char *ptr=my_graph_mem+vga_linewidth*y+vga_bytes*x;	memcpy (colors, ptr, length);	return 0;}/* This does no clipping and is used only by the mouse code * length is in bytes, not in pixels */static int drawscansegment_paged(unsigned char *colors, int x, int y, int length){	int lina=vga_linewidth*y+vga_bytes*x;	paged_memcpy(lina, colors, length);	return 0;}/* This does no clipping and is used only by the mouse code * length is in the bytes, not in pixels */static int getscansegment_paged(unsigned char *colors, int x, int y, int length){	int lina=vga_linewidth*y+vga_bytes*x;	get_row(colors, lina, length);	return 0;}static void svga_draw_bitmaps(struct graphics_device *dev, struct bitmap **hndls, int n	,int x, int y){	void (*draw_b)(struct graphics_device *, struct bitmap *, int, int);	TEST_INACTIVITY	if (x>=xsize||y>ysize) return;	while(x+(*hndls)->x<=0&&n){		x+=(*hndls)->x;		n--;		hndls++;	}	draw_b = dev->drv->draw_bitmap;	while(n&&x<=xsize){		draw_b(dev, *hndls, x, y);		x+=(*hndls)->x;		n--;		hndls++;	}		}static void alloc_scroll_buffer(void){	if (!scroll_buffer) {		if ((unsigned)xsize > (unsigned)MAXINT / bmpixelsize) overalloc();		scroll_buffer=mem_alloc(xsize*bmpixelsize);	}}static void setup_functions(void){	if (accel_avail&ACCELFLAG_SETMODE){		do_sync=1;		vga_accel(ACCEL_SETMODE, BLITS_IN_BACKGROUND);	}else do_sync=0;	svga_driver.get_color=get_color_fn(svga_driver.depth);	if (!svga_driver.get_color) internal("Unknown bit depth %x", svga_driver.depth);	switch(vga_colors){		case 2: internal(				"2-color modes are not supported by\ links as they are buggy in svgalib and incapable of colors");		case 16:		alloc_scroll_buffer();		svga_driver.draw_bitmap=draw_bitmap_drawscansegment;		svga_driver.hscroll=hscroll_scansegment;		svga_driver.vscroll=vscroll_scansegment;		svga_driver.flags |= GD_DONT_USE_SCROLL;		svga_driver.fill_area=fill_area_drawscansegment;		svga_driver.draw_hline=draw_hline_fill_area;		svga_driver.draw_vline=draw_vline_fill_area;		mouse_getscansegment=vga_getscansegment;		mouse_drawscansegment=vga_drawscansegment;		break;		default:		mouse_getscansegment=vga_getscansegment;		mouse_drawscansegment=vga_drawscansegment;		if (accel_avail&ACCELFLAG_PUTIMAGE){			svga_driver.draw_bitmap=draw_bitmap_accel;		}else if (vga_linear){			svga_driver.draw_bitmap=draw_bitmap_linear;		}else if (mode_x){			svga_driver.draw_bitmap=draw_bitmap_drawscansegment;		}else{			svga_driver.draw_bitmap=draw_bitmap_paged;		}				if (accel_avail&ACCELFLAG_FILLBOX) svga_driver.fill_area=fill_area_accel_box;		else if (accel_avail&ACCELFLAG_DRAWLINE) svga_driver.fill_area=fill_area_accel_lines;		else if (vga_linear) svga_driver.fill_area=fill_area_linear;		else if (mode_x) svga_driver.fill_area=fill_area_drawscansegment;		else svga_driver.fill_area=fill_area_paged;				if (accel_avail&ACCELFLAG_DRAWLINE){			svga_driver.draw_hline=draw_hline_accel_line;			svga_driver.draw_vline=draw_vline_accel_line;		}else if (accel_avail&ACCELFLAG_FILLBOX){			svga_driver.draw_hline=draw_hline_accel_box;			svga_driver.draw_vline=draw_vline_accel_box;		}else if (vga_linear){			svga_driver.draw_hline=draw_hline_linear;			svga_driver.draw_vline=draw_vline_linear;		}else if (mode_x){			svga_driver.draw_hline=draw_hline_fill_area;			svga_driver.draw_vline=draw_vline_fill_area;		}else{			/* Paged memory access */			svga_driver.draw_hline=draw_hline_paged;			switch(vga_bytes)			{				case 1:				svga_driver.draw_vline=draw_vline_paged_1;				break;#ifdef t2c				case 2:				svga_driver.draw_vline=draw_vline_paged_2;				break;#endif /* #ifdef t2c */#ifdef t4c				case 4:				svga_driver.draw_vline=draw_vline_paged_4;				break;#endif /* #ifdef t4c */				default:				if (vga_bytes&(vga_bytes-1))					svga_driver.draw_vline=draw_vline_paged;				else					svga_driver.draw_vline=draw_vline_paged_aligned;				break;			}		}		if (vga_colors>=256){			if (vga_linear){				mouse_drawscansegment=drawscansegment_linear;				mouse_getscansegment=getscansegment_linear;			}else if (!mode_x){				mouse_drawscansegment=drawscansegment_paged;				mouse_getscansegment=getscansegment_paged;			}		}		if (accel_avail&ACCELFLAG_SCREENCOPY){			svga_driver.hscroll=hscroll_accel;			svga_driver.vscroll=vscroll_accel;		}else if (vga_linear){			svga_driver.hscroll=hscroll_linear;			svga_driver.vscroll=vscroll_linear;			svga_driver.flags |= GD_DONT_USE_SCROLL;		}else if (mode_x){			alloc_scroll_buffer();			svga_driver.hscroll=hscroll_scansegment;			svga_driver.vscroll=vscroll_scansegment;			svga_driver.flags |= GD_DONT_USE_SCROLL;		}else{			alloc_scroll_buffer();			svga_driver.hscroll=hscroll_paged;			svga_driver.vscroll=vscroll_paged;			svga_driver.flags |= GD_DONT_USE_SCROLL;		}	}}#if 0void dump_mode_info_into_file(vga_modeinfo* i){ FILE *f; f=fopen(".links_svga_modeinfo","w"); if (!f) return; fprintf(f,"Resolution %d*%d\n",i->width,i->height); fprintf(f,"%d bytes per screen pixel\n",i->bytesperpixel); fprintf(f,"%d colors\n",i->colors); fprintf(f,"Linewidth %d bytes\n",i->linewidth); fprintf(f,"Maximum logical width %d bytes\n",i->maxlogicalwidth); fprintf(f,"Start address rangemask 0x%x\n",i->startaddressrange); fprintf(f,"Max. pixels per logical screen %d\n",i->maxpixels); fprintf(f,"bitblt %s\n",i->haveblit&HAVE_BITBLIT?"yes":"no"); fprintf(f,"fillblt %s\n",i->haveblit&HAVE_FILLBLIT?"yes":"no"); fprintf(f,"imageblt %s\n",i->haveblit&HAVE_IMAGEBLIT?"yes":"no"); fprintf(f,"hlinelistblt %s\n",i->haveblit&HAVE_HLINELISTBLIT?"yes":"no"); fprintf(f,"read/write page %s\n",i->flags&HAVE_RWPAGE?"yes":"no"); fprintf(f,"Interlaced %s\n",i->flags&IS_INTERLACED?"yes":"no"); fprintf(f,"Mode X layout %s\n",i->flags&IS_MODEX?"yes":"no"); fprintf(f,"Dynamically loaded %s\n",i->flags&IS_DYNAMICMODE?"yes":"no"); fprintf(f,"Linear: %s\n",vga_linear?"yes":"no"); fprintf(f,"Misordered %s\n",i->flags&RGB_MISORDERED?"yes":"no"); if (!i->flags&EXT_INFO_AVAILABLE){	 fprintf(f,"Old svgalib, extended info is not available\n"); }else{	 fprintf(f,"Chiptype 0x%x\n",i->chiptype);	 fprintf(f,"Memory %dKB\n",i->memory);	 fprintf(f,"Linewidth Unit %d\n",i->linewidth_unit);	 fprintf(f,"Aperture size %d\n",i->aperture_size); } fprintf(f,"Accelerated putimage: %s\n",svga_driver.draw_bitmap==draw_bitmap_accel?"yes":"no"); fclose(f);}#endifstatic void svgalib_key_in(void *p, struct event *ev, int size){	if (size != sizeof(struct event) || ev->ev != EV_KBD) return;	if ((ev->y & KBD_ALT) && ev->x >= '0' && ev->x <= '9') {		switch_virtual_device((ev->x - '1' + 10) % 10);		return;	}	if (svga_driver.codepage!=utf8_table&&(ev->x)>=128&&(ev->x)<=255)		if ((ev->x=cp2u(ev->x,svga_driver.codepage)) == -1) return;	if (current_virtual_device && current_virtual_device->keyboard_handler) current_virtual_device->keyboard_handler(current_virtual_device, ev->x, ev->y);}#ifndef MOUSE_FOURTHBUTTON#define MOUSE_FOURTHBUTTON	0#endif#ifndef MOUSE_FIFTHBUTTON#define MOUSE_FIFTHBUTTON	0#endif#ifndef MOUSE_SIXTHBUTTON#define MOUSE_SIXTHBUTTON	0#endif#define BUTTON_MASK (MOUSE_RIGHTBUTTON | MOUSE_MIDDLEBUTTON | MOUSE_LEFTBUTTON | MOUSE_FOURTHBUTTON | MOUSE_FIFTHBUTTON /*| MOUSE_SIXTHBUTTON*/)static inline void mouse_aggregate_flush(void){	if (!mouse_aggregate_flag) return;	mouse_aggregate_flag=0;	if (!current_virtual_device) return;	if (!current_virtual_device->mouse_handler) return;	current_virtual_device->mouse_handler(current_virtual_device, mouse_x, mouse_y, mouse_aggregate_action);}/* Only calls appropriate callbacks, doesn't draw anything. */static void mouse_event_handler(int button, int dx, int dy, int dz, int drx, int dry, int drz){	int moved,old_mouse_x,old_mouse_y;	void (*mh)(struct graphics_device *, int, int, int);	struct graphics_device *cd=current_virtual_device;		mh=cd?cd->mouse_handler:NULL;	old_mouse_x=mouse_x;	old_mouse_y=mouse_y;	mouse_x+=dx;	if (mouse_x>=xsize) mouse_x=xsize-1;	else if (mouse_x<0) mouse_x=0;	mouse_y+=dy;	if (mouse_y>=ysize) mouse_y=ysize-1;	else if (mouse_y<0) mouse_y=0;	redraw_mouse();	moved=(old_mouse_x!=mouse_x||old_mouse_y!=mouse_y);		/* Test movement without buttons */	if (!(mouse_buttons & BUTTON_MASK) && moved) {		mouse_aggregate_flag=1;		mouse_aggregate_action=B_MOVE;	}				/* Test presses */	if ((button&MOUSE_LEFTBUTTON)&&!(mouse_buttons&MOUSE_LEFTBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_LEFT|B_DOWN);	}	if ((button&MOUSE_MIDDLEBUTTON)&&!(mouse_buttons&MOUSE_MIDDLEBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_MIDDLE|B_DOWN);	}	if ((button&MOUSE_RIGHTBUTTON)&&!(mouse_buttons&MOUSE_RIGHTBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_RIGHT|B_DOWN);	}	if ((button&MOUSE_FOURTHBUTTON)&&!(mouse_buttons&MOUSE_FOURTHBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_RIGHT|B_FOURTH);	}	if ((button&MOUSE_FIFTHBUTTON)&&!(mouse_buttons&MOUSE_FIFTHBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_RIGHT|B_FIFTH);	}	if ((button&MOUSE_SIXTHBUTTON)&&!(mouse_buttons&MOUSE_SIXTHBUTTON)){		mouse_aggregate_flush();		/*if (mh) mh(cd,mouse_x, mouse_y,B_RIGHT|B_SIXTH);*/		switch_virtual_device(VD_NEXT);	}	/* Test releases */	if (!(button&MOUSE_LEFTBUTTON)&&(mouse_buttons&MOUSE_LEFTBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_LEFT|B_UP);	}	if (!(button&MOUSE_MIDDLEBUTTON)&&(mouse_buttons&MOUSE_MIDDLEBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_MIDDLE|B_UP);	}	if (!(button&MOUSE_RIGHTBUTTON)&&(mouse_buttons&MOUSE_RIGHTBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_RIGHT|B_UP);	}	if (!(button&MOUSE_FOURTHBUTTON)&&(mouse_buttons&MOUSE_FOURTHBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_FOURTH|B_UP);	}	if (!(button&MOUSE_FIFTHBUTTON)&&(mouse_buttons&MOUSE_FIFTHBUTTON)){		mouse_aggregate_flush();		if (mh) mh(cd,mouse_x, mouse_y,B_FIFTH|B_UP);	}	if (!(button&MOUSE_SIXTHBUTTON)&&(mouse_buttons&MOUSE_SIXTHBUTTON)){		mouse_aggregate_flush();		/*if (mh) mh(cd,mouse_x, mouse_y,B_SIXTH|B_UP);*/	}		if (drx < 0 && mh) mh(cd, mouse_x, mouse_y, B_MOVE | B_WHEELUP);	if (drx > 0 && mh) mh(cd, mouse_x, mouse_y, B_MOVE | B_WHEELDOWN);	if (dry < 0 && mh) mh(cd, mouse_x, mouse_y, B_MOVE | B_WHEELLEFT);	if (dry > 0 && mh) mh(cd, mouse_x, mouse_y, B_MOVE | B_WHEELRIGHT);	/* Test drag */	if (! ((button^mouse_buttons) & BUTTON_MASK ) && moved && (button &		BUTTON_MASK)){		mouse_aggregate_flag=1;		mouse_aggregate_action=(				      button&MOUSE_LEFTBUTTON?B_LEFT:				      button&MOUSE_RIGHTBUTTON?B_RIGHT:				      button&MOUSE_MIDDLEBUTTON?B_MIDDLE:				      button&MOUSE_FOURTHBUTTON?B_FOURTH:				      button&MOUSE_FIFTHBUTTON?B_FIFTH:				      /*button&MOUSE_SIXTHBUTTON?B_SIXTH:*/				      0) | B_DRAG;	}	mouse_buttons=button;}#undef BUTTON_MASK/* Flushes the background_buffer onscreen where it was originally taken from. */static void place_mouse_background(void){	struct bitmap bmp;	bmp.x=arrow_width;	bmp.y=arrow_height;	bmp.skip=arrow_width*bmpixelsize;	bmp.data=background_buffer;	{		struct graphics_device * current_virtual_device_backup;		current_virtual_device_backup=current_virtual_device;		current_virtual_device=mouse_graphics_device;		svga_driver.draw_bitmap(mouse_graphics_device, &bmp, background_x,			background_y);		current_virtual_device=current_virtual_device_backup;	}}/* Only when the old and new mouse don't interfere. Using it on interfering mouses would * cause a flicker. */static void hide_mouse(void){	global_mouse_hidden=1;	place_mouse_background();}/* Gets background from the screen (clipping provided only right and bottom) to the * passed buffer. */static void get_mouse_background(unsigned char *buffer_ptr){	int width,height,skip,x,y;	skip=arrow_width*bmpixelsize;	x=mouse_x;	y=mouse_y;	width=bmpixelsize*(arrow_width+x>xsize?xsize-x:arrow_width);	height=arrow_height+y>ysize?ysize-y:arrow_height;	SYNC	for (;height;height--){		mouse_getscansegment(buffer_ptr,x,y,width);		buffer_ptr+=skip;		y++;	}}/* Overlays the arrow's image over the mouse_buffer * Doesn't draw anything into the screen */static void render_mouse_arrow(void){	int x,y, reg0, reg1;	unsigned char *mouse_ptr=mouse_buffer;	int *arrow_ptr=arrow;	for (y=arrow_height;y;y--){		reg0=*arrow_ptr;		reg1=arrow_ptr[1];		arrow_ptr+=2;		for (x=arrow_width;x;)		{			int mask=1<<(--x);			if (reg0&mask)				memcpy (mouse_ptr, &mouse_black, bmpixelsize);			else if (reg1&mask)				memcpy (mouse_ptr, &mouse_white, bmpixelsize);			mouse_ptr+=bmpixelsize;		}	}}static void place_mouse(void){	struct bitmap bmp;	bmp.x=arrow_width;	bmp.y=arrow_height;	bmp.skip=arrow_width*bmpixelsize;	bmp.data=mouse_buffer;		{		struct graphics_device * current_graphics_device_backup;		current_graphics_device_backup=current_virtual_device;		current_virtual_device=mouse_graphics_device;		/* We do need to worry about SYNC because draw_bitmap already		 * does it (if necessary)		 */		svga_driver.draw_bitmap(mouse_graphics_device, &bmp, mouse_x, mouse_y);		current_virtual_device=current_graphics_device_backup;	}	global_mouse_hidden=0;}/* Only when the old and the new mouse positions do not interfere. Using this routine * on interfering positions would cause a flicker.

⌨️ 快捷键说明

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