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

📄 matroxfb_base.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int visual;	int cmap_len;	unsigned int ydstorg;	struct display* display;	int chgvar;	DBG("matroxfb_set_var")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	if (con >= 0)		display = fb_display + con;	else		display = ACCESS_FBINFO(fbcon.disp);	if ((err = matroxfb_decode_var(PMINFO display, var, &visual, &cmap_len, &ydstorg)) != 0)		return err;	switch (var->activate & FB_ACTIVATE_MASK) {		case FB_ACTIVATE_TEST:	return 0;		case FB_ACTIVATE_NXTOPEN:	/* ?? */		case FB_ACTIVATE_NOW:	break;	/* continue */		default:		return -EINVAL; /* unknown */	}	if (con >= 0) {		chgvar = ((display->var.xres != var->xres) ||		    (display->var.yres != var->yres) ||                    (display->var.xres_virtual != var->xres_virtual) ||		    (display->var.yres_virtual != var->yres_virtual) ||		    (display->var.bits_per_pixel != var->bits_per_pixel) ||		    memcmp(&display->var.red, &var->red, sizeof(var->red)) ||		    memcmp(&display->var.green, &var->green, sizeof(var->green)) ||		    memcmp(&display->var.blue, &var->blue, sizeof(var->blue)));	} else {		chgvar = 0;	}	display->var = *var;	/* cmap */	display->screen_base = ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg;	display->visual = visual;	display->ypanstep = 1;	display->ywrapstep = 0;	if (var->bits_per_pixel) {		display->type = FB_TYPE_PACKED_PIXELS;		display->type_aux = 0;		display->next_line = display->line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;	} else {		display->type = FB_TYPE_TEXT;		display->type_aux = ACCESS_FBINFO(devflags.text_type_aux);		display->next_line = display->line_length = (var->xres_virtual / (fontwidth(display)?fontwidth(display):8)) * ACCESS_FBINFO(devflags.textstep);	}	display->can_soft_blank = 1;	display->inverse = ACCESS_FBINFO(devflags.inverse);	/* conp, fb_info, vrows, cursor_x, cursor_y, fgcol, bgcol */	/* next_plane, fontdata, _font*, userfont */	initMatrox(PMINFO display);	/* dispsw */	/* dispsw, scrollmode, yscroll */	/* fgshift, bgshift, charmask */	if (chgvar && info && info->changevar)		info->changevar(con);	if (con == ACCESS_FBINFO(currcon)) {		unsigned int pos;		ACCESS_FBINFO(curr.cmap_len) = cmap_len;		if (display->type == FB_TYPE_TEXT) {			/* textmode must be in first megabyte, so no ydstorg allowed */			ACCESS_FBINFO(curr.ydstorg.bytes) = 0;			ACCESS_FBINFO(curr.ydstorg.chunks) = 0;			ACCESS_FBINFO(curr.ydstorg.pixels) = 0;		} else {			ydstorg += ACCESS_FBINFO(devflags.ydstorg);			ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg;			ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2);			if (var->bits_per_pixel == 4)				ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg;			else				ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel;		}		ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel);		if (visual == MX_VISUAL_PSEUDOCOLOR) {			int i;			for (i = 0; i < 16; i++) {				int j;				j = color_table[i];				ACCESS_FBINFO(palette[i].red)   = default_red[j];				ACCESS_FBINFO(palette[i].green) = default_grn[j];				ACCESS_FBINFO(palette[i].blue)  = default_blu[j];			}		}		{	struct my_timming mt;			struct matrox_hw_state* hw;			int out;			matroxfb_var2my(var, &mt);			mt.crtc = MATROXFB_SRC_CRTC1;			/* CRTC1 delays */			switch (var->bits_per_pixel) {				case  0:	mt.delay = 31 + 0; break;				case 16:	mt.delay = 21 + 8; break;				case 24:	mt.delay = 17 + 8; break;				case 32:	mt.delay = 16 + 8; break;				default:	mt.delay = 31 + 8; break;			}			hw = &ACCESS_FBINFO(hw);			del_timer_sync(&ACCESS_FBINFO(cursor.timer));			ACCESS_FBINFO(cursor.state) = CM_ERASE;			down_read(&ACCESS_FBINFO(altout).lock);			for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {				if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 &&				    ACCESS_FBINFO(outputs[out]).output->compute) {					ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt);				}			}			up_read(&ACCESS_FBINFO(altout).lock);			ACCESS_FBINFO(crtc1).pixclock = mt.pixclock;			ACCESS_FBINFO(crtc1).mnp = mt.mnp;			ACCESS_FBINFO(hw_switch->init(PMINFO &mt, display));			if (display->type == FB_TYPE_TEXT) {				if (fontheight(display))					pos = var->yoffset / fontheight(display) * display->next_line / ACCESS_FBINFO(devflags.textstep) + var->xoffset / (fontwidth(display)?fontwidth(display):8);				else					pos = 0;			} else {				pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;				pos += ACCESS_FBINFO(curr.ydstorg.chunks);			}			hw->CRTC[0x0D] = pos & 0xFF;			hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;			hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);			hw->CRTCEXT[8] = pos >> 21;					ACCESS_FBINFO(hw_switch->restore(PMINFO display));			down_read(&ACCESS_FBINFO(altout).lock);			for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {				if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 &&				    ACCESS_FBINFO(outputs[out]).output->program) {					ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data);				}			}			ACCESS_FBINFO(cursor.redraw) = 1;			for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {				if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 &&				    ACCESS_FBINFO(outputs[out]).output->start) {					ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data);				}			}			up_read(&ACCESS_FBINFO(altout).lock);			matrox_cfbX_init(PMINFO display);			my_install_cmap(PMINFO2);#if defined(CONFIG_FB_COMPAT_XPMAC)			if (console_fb_info == &ACCESS_FBINFO(fbcon)) {				int vmode, cmode;				display_info.width = var->xres;				display_info.height = var->yres;				display_info.depth = var->bits_per_pixel;				display_info.pitch = (var->xres_virtual)*(var->bits_per_pixel)/8;				if (mac_var_to_vmode(var, &vmode, &cmode))					display_info.mode = 0;				else					display_info.mode = vmode;				strcpy(display_info.name, ACCESS_FBINFO(matrox_name));				display_info.fb_address = ACCESS_FBINFO(video.base);				display_info.cmap_adr_address = 0;				display_info.cmap_data_address = 0;				display_info.disp_reg_address = ACCESS_FBINFO(mmio.base);			}#endif /* CONFIG_FB_COMPAT_XPMAC */		}	}	return 0;#undef minfo}static int matrox_getcolreg(unsigned regno, unsigned *red, unsigned *green,			    unsigned *blue, unsigned *transp,			    struct fb_info *info){	DBG("matrox_getcolreg")#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	/*	 *  Read a single color register and split it into colors/transparent.	 *  Return != 0 for invalid regno.	 */	if (regno >= ACCESS_FBINFO(curr.cmap_len))		return 1;	*red   = ACCESS_FBINFO(palette[regno].red);	*green = ACCESS_FBINFO(palette[regno].green);	*blue  = ACCESS_FBINFO(palette[regno].blue);	*transp = ACCESS_FBINFO(palette[regno].transp);	return 0;#undef minfo}static int matroxfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			     struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	struct display* dsp = (con < 0) ? ACCESS_FBINFO(fbcon.disp)					: fb_display + con;	DBG("matroxfb_get_cmap")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	if (con == ACCESS_FBINFO(currcon)) /* current console? */		return fb_get_cmap(cmap, kspc, matrox_getcolreg, info);	else if (dsp->cmap.len) /* non default colormap? */		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap(matroxfb_get_cmap_len(&dsp->var)),			     cmap, kspc ? 0 : 2);	return 0;#undef minfo}static int matroxfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			     struct fb_info *info){	unsigned int cmap_len;	struct display* dsp = (con < 0) ? info->disp : (fb_display + con);#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	DBG("matroxfb_set_cmap")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	cmap_len = matroxfb_get_cmap_len(&dsp->var);	if (dsp->cmap.len != cmap_len) {		int err;		err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);		if (err)			return err;	}	if (con == ACCESS_FBINFO(currcon)) {			/* current console? */		return fb_set_cmap(cmap, kspc, matroxfb_setcolreg, info);	} else		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);	return 0;#undef minfo}static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank){	unsigned int sts1;	matroxfb_enable_irq(PMINFO 0);	memset(vblank, 0, sizeof(*vblank));	vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC |			FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK;	sts1 = mga_inb(M_INSTS1);	vblank->vcount = mga_inl(M_VCOUNT);	/* BTW, on my PIII/450 with G400, reading M_INSTS1	   byte makes this call about 12% slower (1.70 vs. 2.05 us	   per ioctl()) */	if (sts1 & 1)		vblank->flags |= FB_VBLANK_HBLANKING;	if (sts1 & 8)		vblank->flags |= FB_VBLANK_VSYNCING;	if (vblank->vcount >= ACCESS_FBINFO(currcon_display)->var.yres)		vblank->flags |= FB_VBLANK_VBLANKING;	if (test_bit(0, &ACCESS_FBINFO(irq_flags))) {		vblank->flags |= FB_VBLANK_HAVE_COUNT;		/* Only one writer, aligned int value... 		   it should work without lock and without atomic_t */		vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt;	}	return 0;}static struct matrox_altout panellink_output = {	.owner   = THIS_MODULE,	.name	 = "Panellink output",};static int matroxfb_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, unsigned long arg, int con,			  struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	DBG("matroxfb_ioctl")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	switch (cmd) {		case FBIOGET_VBLANK:			{				struct fb_vblank vblank;				int err;				err = matroxfb_get_vblank(PMINFO &vblank);				if (err)					return err;				if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))					return -EFAULT;				return 0;			}		case FBIO_WAITFORVSYNC:			{				u_int32_t crt;				if (get_user(crt, (u_int32_t *)arg))					return -EFAULT;				return matroxfb_wait_for_sync(PMINFO crt);			}		case MATROXFB_SET_OUTPUT_MODE:			{				struct matroxioc_output_mode mom;				struct matrox_altout *oproc;				int val;				if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))					return -EFAULT;				if (mom.output >= MATROXFB_MAX_OUTPUTS)					return -ENXIO;				down_read(&ACCESS_FBINFO(altout.lock));				oproc = ACCESS_FBINFO(outputs[mom.output]).output;				if (!oproc) {					val = -ENXIO;				} else if (!oproc->verifymode) {					if (mom.mode == MATROXFB_OUTPUT_MODE_MONITOR) {						val = 0;					} else {						val = -EINVAL;					}				} else {					val = oproc->verifymode(ACCESS_FBINFO(outputs[mom.output]).data, mom.mode);				}				if (!val) {					if (ACCESS_FBINFO(outputs[mom.output]).mode != mom.mode) {						ACCESS_FBINFO(outputs[mom.output]).mode = mom.mode;						val = 1;					}				}				up_read(&ACCESS_FBINFO(altout.lock));				if (val != 1)					return val;				switch (ACCESS_FBINFO(outputs[mom.output]).src) {					case MATROXFB_SRC_CRTC1:						matroxfb_switch(ACCESS_FBINFO(currcon), info);						break;					case MATROXFB_SRC_CRTC2:						{							struct matroxfb_dh_fb_info* crtc2;							down_read(&ACCESS_FBINFO(crtc2.lock));							crtc2 = ACCESS_FBINFO(crtc2.info);							if (crtc2)								crtc2->fbcon.switch_con(crtc2->currcon, &crtc2->fbcon);							up_read(&ACCESS_FBINFO(crtc2.lock));						}						break;				}				return 0;			}		case MATROXFB_GET_OUTPUT_MODE:			{				struct matroxioc_output_mode mom;				struct matrox_altout *oproc;				int val;				if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))					return -EFAULT;				if (mom.output >= MATROXFB_MAX_OUTPUTS)					return -ENXIO;				down_read(&ACCESS_FBINFO(altout.lock));				oproc = ACCESS_FBINFO(outputs[mom.output]).output;				if (!oproc) {					val = -ENXIO;				} else {					mom.mode = ACCESS_FBINFO(outputs[mom.output]).mode;					val = 0;				}				up_read(&ACCESS_FBINFO(altout.lock));				if (val)					return val;				if (copy_to_user((struct matroxioc_output_mode*)arg, &mom, sizeof(mom)))					return -EFAULT;				return 0;			}		case MATROXFB_SET_OUTPUT_CONNECTION:			{				u_int32_t tmp;				int i;				int changes;				if (copy_from_user(&tmp, (u_int32_t*)arg, sizeof(tmp)))					return -EFAULT;				for (i = 0; i < 32; i++) {					if (tmp & (1 << i)) {						if (i >= MATROXFB_MAX_OUTPUTS)							return -ENXIO;						if (!ACCESS_FBINFO(outputs[i]).output)							return -ENXIO;						switch (ACCESS_FBINFO(outputs[i]).src) {							case MATROXFB_SRC_NONE:							case MATROXFB_SRC_CRTC1:								break;							default:								return -EBUSY;						}					}				}				if (ACCESS_FBINFO(devflags.panellink)) {					if (tmp & MATROXFB_OUTPUT_CONN_DFP) {						if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY)							return -EINVAL;						for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {							if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC2) {								return -EBUSY;							}						}					}				}				changes = 0;				for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) {					if (tmp & (1 << i)) {						if (ACCESS_FBINFO(outputs[i]).src != MATROXFB_SRC_CRTC1) {							changes = 1;							ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_CRTC1;						}					} else if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) {						changes = 1;						ACCESS_FBINFO(outputs[i]).src = MATROXFB_SRC_NONE;					}

⌨️ 快捷键说明

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