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

📄 fbdev.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	case 8:		rc = 256;	/* pseudocolor... 256 entries HW palette */		break;#endif#ifdef FBCON_HAS_CFB16	case 15:		rc = 15;	/* fix for 15 bpp depths on Riva 128 based cards */		break;	case 16:		rc = 16;	/* directcolor... 16 entries SW palette */		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB32	case 32:		rc = 16;	/* directcolor... 16 entries SW palette */		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif	default:		/* should not occur */		break;	}	return rc;}/** * riva_getcolreg * @regno: register index * @red: red component * @green: green component * @blue: blue component * @transp: transparency * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Read a single color register and split it into colors/transparent. * The return values must have a 16 bit magnitude. * * RETURNS: * Return != 0 for invalid regno. * * CALLED FROM: * rivafb_get_cmap() * rivafb_switch() * fbcmap.c:fb_get_cmap() *	fbgen.c:fbgen_get_cmap() *	fbgen.c:fbgen_switch() */static int riva_getcolreg(unsigned regno, unsigned *red, unsigned *green,			  unsigned *blue, unsigned *transp,			  struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var))		return 1;	*red = rivainfo->palette[regno].red;	*green = rivainfo->palette[regno].green;	*blue = rivainfo->palette[regno].blue;	*transp = 0;	return 0;}/** * riva_setcolreg * @regno: register index * @red: red component * @green: green component * @blue: blue component * @transp: transparency * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Set a single color register. The values supplied have a 16 bit * magnitude. * * RETURNS: * Return != 0 for invalid regno. * * CALLED FROM: * rivafb_set_cmap() * fbcmap.c:fb_set_cmap() *	fbgen.c:fbgen_get_cmap() *	fbgen.c:fbgen_install_cmap() *		fbgen.c:fbgen_set_var() *		fbgen.c:fbgen_switch() *		fbgen.c:fbgen_blank() *	fbgen.c:fbgen_blank() */static int riva_setcolreg(unsigned regno, unsigned red, unsigned green,			  unsigned blue, unsigned transp,			  struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	RIVA_HW_INST *chip = &rivainfo->riva;	struct display *p;	DPRINTK("ENTER\n");	assert(rivainfo != NULL);	assert(rivainfo->currcon_display != NULL);	p = rivainfo->currcon_display;	if (regno >= riva_get_cmap_len(&p->var))		return -EINVAL;	rivainfo->palette[regno].red = red;	rivainfo->palette[regno].green = green;	rivainfo->palette[regno].blue = blue;	if (p->var.grayscale) {		/* gray = 0.30*R + 0.59*G + 0.11*B */		red = green = blue =		    (red * 77 + green * 151 + blue * 28) >> 8;	}	switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 8:		/* "transparent" stuff is completely ignored. */		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);		break;#endif /* FBCON_HAS_CFB8 */#ifdef FBCON_HAS_CFB16	case 16:		assert(regno < 16);		if (p->var.green.length == 5) {			/* 0rrrrrgg gggbbbbb */			rivainfo->con_cmap.cfb16[regno] =			    ((red & 0xf800) >> 1) |			    ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);		} else {			/* rrrrrggg gggbbbbb */			rivainfo->con_cmap.cfb16[regno] =			    ((red & 0xf800) >> 0) |			    ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);		}		break;#endif /* FBCON_HAS_CFB16 */#ifdef FBCON_HAS_CFB32	case 32:		assert(regno < 16);		rivainfo->con_cmap.cfb32[regno] =		    ((red & 0xff00) << 8) |		    ((green & 0xff00)) | ((blue & 0xff00) >> 8);		break;#endif /* FBCON_HAS_CFB32 */	default:		/* do nothing */		break;	}	return 0;}/* ------------------------------------------------------------------------- * * * framebuffer operations * * ------------------------------------------------------------------------- */static int rivafb_get_fix(struct fb_fix_screeninfo *fix, int con,			  struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	struct display *p;	DPRINTK("ENTER\n");	assert(fix != NULL);	assert(info != NULL);	assert(rivainfo->drvr_name && rivainfo->drvr_name[0]);	assert(rivainfo->fb_base_phys > 0);	assert(rivainfo->ram_amount > 0);	p = (con < 0) ? rivainfo->info.disp : &fb_display[con];	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	sprintf(fix->id, "nVidia %s", rivainfo->drvr_name);	fix->type = p->type;	fix->type_aux = p->type_aux;	fix->visual = p->visual;	fix->xpanstep = 1;	fix->ypanstep = 1;	fix->ywrapstep = 0;	/* FIXME: no ywrap for now */	fix->line_length = p->line_length;	fix->mmio_start = rivainfo->ctrl_base_phys;	fix->mmio_len = rivainfo->base0_region_size;	fix->smem_start = rivainfo->fb_base_phys;	fix->smem_len = rivainfo->ram_amount;	switch (rivainfo->riva.Architecture) {	case NV_ARCH_03:		fix->accel = FB_ACCEL_NV3;		break;	case NV_ARCH_04:	/* riva_hw.c now doesn't distinguish between TNT & TNT2 */		fix->accel = FB_ACCEL_NV4;		break;	case NV_ARCH_10:	/* FIXME: ID for GeForce */	case NV_ARCH_20:		fix->accel = FB_ACCEL_NV4;		break;	}	DPRINTK("EXIT, returning 0\n");	return 0;}static int rivafb_get_var(struct fb_var_screeninfo *var, int con,			  struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	DPRINTK("ENTER\n");	assert(info != NULL);	assert(var != NULL);	*var = (con < 0) ? rivainfo->disp.var : fb_display[con].var;	DPRINTK("EXIT, returning 0\n");	return 0;}static int rivafb_set_var(struct fb_var_screeninfo *var, int con,			  struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	struct display *dsp;	struct fb_var_screeninfo v;	int nom, den;		/* translating from pixels->bytes */	int accel;	unsigned chgvar = 0;	DPRINTK("ENTER\n");	assert(info != NULL);	assert(var != NULL);	DPRINTK("Requested: %dx%dx%d\n", var->xres, var->yres,		var->bits_per_pixel);	DPRINTK("  virtual: %dx%d\n", var->xres_virtual,		var->yres_virtual);	DPRINTK("   offset: (%d,%d)\n", var->xoffset, var->yoffset);	DPRINTK("grayscale: %d\n", var->grayscale);	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];	assert(dsp != NULL);	/* if var has changed, we should call changevar() later */	if (con >= 0) {		chgvar = ((dsp->var.xres != var->xres) ||			  (dsp->var.yres != var->yres) ||			  (dsp->var.xres_virtual != var->xres_virtual) ||			  (dsp->var.yres_virtual != var->yres_virtual) ||			  (dsp->var.accel_flags != var->accel_flags) ||			  (dsp->var.bits_per_pixel != var->bits_per_pixel)			  || memcmp(&dsp->var.red, &var->red,				    sizeof(var->red))			  || memcmp(&dsp->var.green, &var->green,				    sizeof(var->green))			  || memcmp(&dsp->var.blue, &var->blue,				    sizeof(var->blue)));	}	memcpy(&v, var, sizeof(v));	accel = v.accel_flags & FB_ACCELF_TEXT;	switch (v.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 1 ... 8:		v.bits_per_pixel = 8;		nom = 1;		den = 1;		v.red.offset = 0;		v.red.length = 8;		v.green.offset = 0;		v.green.length = 8;		v.blue.offset = 0;		v.blue.length = 8;		break;#endif#ifdef FBCON_HAS_CFB16	case 9 ... 15:		v.green.length = 5;		/* fall through */	case 16:		v.bits_per_pixel = 16;		nom = 2;		den = 1;		if (v.green.length == 5) {			/* 0rrrrrgg gggbbbbb */			v.red.offset = 10;			v.green.offset = 5;			v.blue.offset = 0;			v.red.length = 5;			v.green.length = 5;			v.blue.length = 5;		} else {			/* rrrrrggg gggbbbbb */			v.red.offset = 11;			v.green.offset = 5;			v.blue.offset = 0;			v.red.length = 5;			v.green.length = 6;			v.blue.length = 5;		}		break;#endif#ifdef FBCON_HAS_CFB32	case 17 ... 32:		v.bits_per_pixel = 32;		nom = 4;		den = 1;		v.red.offset = 16;		v.green.offset = 8;		v.blue.offset = 0;		v.red.length = 8;		v.green.length = 8;		v.blue.length = 8;		break;#endif	default:		printk(KERN_ERR PFX		       "mode %dx%dx%d rejected...color depth not supported.\n",		       var->xres, var->yres, var->bits_per_pixel);		DPRINTK("EXIT, returning -EINVAL\n");		return -EINVAL;	}	if (rivafb_do_maximize(rivainfo, var, &v, nom, den) < 0)		return -EINVAL;	if (v.xoffset < 0)		v.xoffset = 0;	if (v.yoffset < 0)		v.yoffset = 0;	/* truncate xoffset and yoffset to maximum if too high */	if (v.xoffset > v.xres_virtual - v.xres)		v.xoffset = v.xres_virtual - v.xres - 1;	if (v.yoffset > v.yres_virtual - v.yres)		v.yoffset = v.yres_virtual - v.yres - 1;	v.red.msb_right =	    v.green.msb_right =	    v.blue.msb_right =	    v.transp.offset = v.transp.length = v.transp.msb_right = 0;	switch (v.activate & FB_ACTIVATE_MASK) {	case FB_ACTIVATE_TEST:		DPRINTK("EXIT - FB_ACTIVATE_TEST\n");		return 0;	case FB_ACTIVATE_NXTOPEN:	/* ?? */	case FB_ACTIVATE_NOW:		break;		/* continue */	default:		DPRINTK("EXIT - unknown activation type\n");		return -EINVAL;	/* unknown */	}	memcpy(&dsp->var, &v, sizeof(v));	if (chgvar) {		riva_set_dispsw(rivainfo, dsp);		if (accel) {			if (nomove)				dsp->scrollmode = SCROLL_YNOMOVE;			else				dsp->scrollmode = 0;		} else			dsp->scrollmode = SCROLL_YREDRAW;		if (info && info->changevar)			info->changevar(con);	}	rivafb_create_cursor(rivainfo, fontwidth(dsp), fontheight(dsp));	riva_load_video_mode(rivainfo, &v);	if (accel) riva_setup_accel(rivainfo);	DPRINTK("EXIT, returning 0\n");	return 0;}static int rivafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			   struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	struct display *dsp;	DPRINTK("ENTER\n");	assert(rivainfo != NULL);	assert(cmap != NULL);	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];	if (con == rivainfo->currcon) {	/* current console? */		int rc = fb_get_cmap(cmap, kspc, riva_getcolreg, info);		DPRINTK("EXIT - returning %d\n", rc);		return rc;	} else if (dsp->cmap.len)	/* non default colormap? */		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap			     (riva_get_cmap_len(&dsp->var)), cmap,			     kspc ? 0 : 2);	DPRINTK("EXIT, returning 0\n");	return 0;}static int rivafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			   struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	struct display *dsp;	unsigned int cmap_len;	DPRINTK("ENTER\n");		assert(rivainfo != NULL);	assert(cmap != NULL);	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];	cmap_len = riva_get_cmap_len(&dsp->var);	if (dsp->cmap.len != cmap_len) {		int err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);		if (err) {			DPRINTK("EXIT - returning %d\n", err);			return err;		}	}	if (con == rivainfo->currcon) {	/* current console? */		int rc = fb_set_cmap(cmap, kspc, riva_setcolreg, info);		DPRINTK("EXIT - returning %d\n", rc);		return rc;	} else		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);	DPRINTK("EXIT, returning 0\n");	return 0;}/** * rivafb_pan_display * @var: standard kernel fb changeable data * @con: TODO * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Pan (or wrap, depending on the `vmode' field) the display using the * `xoffset' and `yoffset' fields of the `var' structure. * If the values don't fit, return -EINVAL. * * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag */static int rivafb_pan_display(struct fb_var_screeninfo *var, int con,			      struct fb_info *info){	unsigned int base;	struct display *dsp;	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	DPRINTK("ENTER\n");	assert(rivainfo != NULL);	if (var->xoffset > (var->xres_virtual - var->xres))		return -EINVAL;	if (var->yoffset > (var->yres_virtual - var->yres))		return -EINVAL;	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];	if (var->vmode & FB_VMODE_YWRAP) {		if (var->yoffset < 0		    || var->yoffset >= dsp->var.yres_virtual		    || var->xoffset) return -EINVAL;	} else {		if (var->xoffset + dsp->var.xres > dsp->var.xres_virtual ||		    var->yoffset + dsp->var.yres > dsp->var.yres_virtual)			return -EINVAL;	}	base = var->yoffset * dsp->line_length + var->xoffset;	if (con == rivainfo->currcon) {		rivainfo->riva.SetStartAddress(&rivainfo->riva, base);	}	dsp->var.xoffset = var->xoffset;	dsp->var.yoffset = var->yoffset;	if (var->vmode & FB_VMODE_YWRAP)		dsp->var.vmode |= FB_VMODE_YWRAP;	else		dsp->var.vmode &= ~FB_VMODE_YWRAP;	DPRINTK("EXIT, returning 0\n");	return 0;}static int rivafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,			unsigned long arg, int con, struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	DPRINTK("ENTER\n");	assert(rivainfo != NULL);	/* no rivafb-specific ioctls */	DPRINTK("EXIT, returning -EINVAL\n");	return -EINVAL;}static int rivafb_rasterimg(struct fb_info *info, int start){	struct rivafb_info *rinfo = (struct rivafb_info *)info;	wait_for_idle(rinfo);	return 0;}static int rivafb_switch(int con, struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *)info;	struct fb_cmap *cmap;	struct display *dsp;		DPRINTK("ENTER\n");		assert(rivainfo != NULL);	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];	if (rivainfo->currcon >= 0) {		/* Do we have to save the colormap? */		cmap = &(rivainfo->currcon_display->cmap);		DPRINTK("switch1: con = %d, cmap.len = %d\n",			 rivainfo->currcon, cmap->len);		if (cmap->len) {			DPRINTK("switch1a: %p %p %p %p\n", cmap->red,				 cmap->green, cmap->blue, cmap->transp);			fb_get_cmap(cmap, 1, riva_getcolreg, info);		}	}	rivainfo->currcon = con;	rivainfo->currcon_display = dsp;	rivafb_set_var(&dsp->var, con, info);	riva_set_dispsw(rivainfo, dsp);	DPRINTK("EXIT, returning 0\n");	return 0;}static int rivafb_updatevar(int con, struct fb_info *info){	int rc;	DPRINTK("ENTER\n");	rc = (con < 0) ? -EINVAL : rivafb_pan_display(&fb_display[con].var,						      con, info);	DPRINTK("EXIT, returning %d\n", rc);	return rc;}

⌨️ 快捷键说明

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