Beispiel #1
0
void _GGI_terminfo_freedbs(ggi_visual *vis)
{
	int i;

	for (i=LIBGGI_APPLIST(vis)->num-1; i >= 0; i--) {
		free(LIBGGI_APPBUFS(vis)[i]->write);
		_ggi_db_free(LIBGGI_APPBUFS(vis)[i]);
		_ggi_db_del_buffer(LIBGGI_APPLIST(vis), i);
	}
}
Beispiel #2
0
static int do_cleanup(ggi_visual *vis)
{
	ggi_fbdev_priv *fbdevpriv = FBDEV_PRIV(vis);
	struct m2164w_priv *priv = NULL;
	int i;

	DPRINT_MISC("mga-2164w: Starting cleanup\n");

	if (fbdevpriv != NULL) {
		priv = M2164W_PRIV(vis);
	}

	/* We may be called more than once due to the LibGG cleanup stuff */
	if (priv == NULL) return 0;

	/* Restore OPMODE and terminate any pending DMA operations
	   Manual says we should write to byte 0 to terminate DMA sequence,
	   but it doesn't say whether a 8 bit access is required, or if any
	   access will do. We play it safe here... */
	mga_out8(fbdevpriv->mmioaddr, priv->origopmode & 0xff, OPMODE);
	mga_out16(fbdevpriv->mmioaddr, priv->origopmode, OPMODE);
	mga_waitidle(fbdevpriv->mmioaddr);

	munmap((void*)fbdevpriv->mmioaddr, fbdevpriv->orig_fix.mmio_len);
	DPRINT_MISC("mga-2164w: Unmapped MMIO\n");

	/* Free DB resource structures */
	for (i = LIBGGI_APPLIST(vis)->num-1; i >= 0; i--) {
		if (LIBGGI_APPBUFS(vis)[i]->resource) {
			free(LIBGGI_APPBUFS(vis)[i]->resource);
			LIBGGI_APPBUFS(vis)[i]->resource = NULL;
		}
	}

	free(priv);
	FBDEV_PRIV(vis)->accelpriv = NULL;

	ggUnregisterCleanup((ggcleanup_func *)do_cleanup, vis);

	return 0;
}
Beispiel #3
0
ggi_directbuffer *_ggi_db_find_frame(struct ggi_visual *vis, int frameno)
{
	int i;

	for (i=0; i < LIBGGI_APPLIST(vis)->num; i++) {
		ggi_directbuffer *cur = LIBGGI_APPBUFS(vis)[i];

		if ((cur->type & GGI_DB_NORMAL) && (cur->frame == frameno)) {
			return cur;
		}
	}

	for (i=0; i < LIBGGI_PRIVLIST(vis)->num; i++) {
		ggi_directbuffer *cur = LIBGGI_PRIVBUFS(vis)[i];

		if ((cur->type & GGI_DB_NORMAL) && (cur->frame == frameno)) {
			return cur;
		}
	}

	return NULL;  /* not found */
}
Beispiel #4
0
static int do_mmap(struct ggi_visual *vis)
{
	ggi_lcd823_priv *priv = LCD823_PRIV(vis);
	ggi_graphtype gt = LIBGGI_GT(vis);
	int xres_in_bytes = XRES;
	int i;

	/* Clear framebuffer */
	memset(priv->fb_ptr, 0, priv->fb_size);

	/* Set up pixel format */
	memset(LIBGGI_PIXFMT(vis), 0, sizeof(ggi_pixelformat));
	LIBGGI_PIXFMT(vis)->size  = GT_SIZE(gt);
	LIBGGI_PIXFMT(vis)->depth = GT_DEPTH(gt);
	LIBGGI_PIXFMT(vis)->clut_mask = (1 << GT_DEPTH(gt)) - 1;
	_ggi_build_pixfmt(LIBGGI_PIXFMT(vis));

	/* Set up DirectBuffers */
	for (i=0; i < LIBGGI_MODE(vis)->frames; i++) {
		ggi_directbuffer *buf;

		_ggi_db_add_buffer(LIBGGI_APPLIST(vis), _ggi_db_get_new());

		buf = LIBGGI_APPBUFS(vis)[i];

		buf->frame = i;
		buf->type  = GGI_DB_NORMAL;
		buf->read  = (uint8_t *) priv->fb_ptr + i * priv->frame_size;
		buf->write = buf->read;

		buf->type  |= GGI_DB_SIMPLE_PLB;
		buf->layout = blPixelLinearBuffer;
		buf->buffer.plb.stride = xres_in_bytes;
		buf->buffer.plb.pixelformat = LIBGGI_PIXFMT(vis);
	}

	return 0;
}
Beispiel #5
0
int GGI_vgl_setmode(ggi_visual *vis, ggi_mode *tm)
{ 
	struct vgl_priv *priv = VGL_PRIV(vis);
	ggi_graphtype gt = tm->graphtype;
	video_info_t modeinfo;
	unsigned long modenum = 0;
	char sugname[GGI_MAX_APILEN];
	char args[GGI_MAX_APILEN];
	int err = 0;
	int id, i;
	int pixelBytes;

	err = GGI_vgl_checkmode(vis, tm);
	if (err) return err;

	/* reset the modeinfo structure as expected by query_mode */
	memset(&modeinfo, 0, sizeof(modeinfo));
	
	switch(gt) {
	case GT_1BIT : modeinfo.vi_depth = 1; pixelBytes = 1; break;
	case GT_4BIT : modeinfo.vi_depth = 4; pixelBytes = 1; break;
	case GT_8BIT : modeinfo.vi_depth = 8; pixelBytes = 1; break;
	case GT_16BIT: modeinfo.vi_depth = 16; pixelBytes = 2; break;
	case GT_32BIT: modeinfo.vi_depth = 32; pixelBytes = 4; break;

	/* Unsupported mode depths */
	case GT_15BIT:
	case GT_24BIT:
	default:
		return GGI_ENOMATCH;
	}

	modeinfo.vi_width = tm->visible.x;
	modeinfo.vi_height = tm->visible.y;

	/* XXX should be added to libvgl */
	if (ioctl(0, FBIO_FINDMODE, &modeinfo))
		return -1;

	DPRINT("Setting VGLlib mode %d (0x%x)\n",
			modeinfo.vi_mode, modeinfo.vi_mode);

	/* Terminate any current mode before initialising another */
	if (priv->vgl_init_done) {
		priv->vgl_init_done = 0;
		VGLEnd();
	}

	/* XXX should be in VGL */
	if ((modeinfo.vi_mode >= M_B40x25) && (modeinfo.vi_mode <= M_VGA_M90x60))
		modenum = _IO('S', modeinfo.vi_mode);
	if ((modeinfo.vi_mode >= M_TEXT_80x25) && (modeinfo.vi_mode <= M_TEXT_132x60))
		modenum = _IO('S', modeinfo.vi_mode);
	if ((modeinfo.vi_mode >= M_VESA_CG640x400) &&
		(modeinfo.vi_mode <= M_VESA_FULL_1280))
		modenum = _IO('V', modeinfo.vi_mode - M_VESA_BASE);

	if ((err = VGLInit(modenum)) != 0) {
		DPRINT("display-vgl: setting mode 0x%x failed with error %d\n",
			modeinfo.vi_mode, err);
		return GGI_EFATAL;
	}

	priv->vgl_init_done = 1;

	if (priv->vgl_use_db) {
		_GGI_vgl_freedbs(vis);

		/* Set up DirectBuffer(s) */
		for (i = 0; i<tm->frames; i++) {
			if (LIBGGI_FB_SIZE(tm) >
				(unsigned)(VGLDisplay->Xsize*VGLDisplay->Ysize*
					pixelBytes)) {
				fprintf(stderr, "display-vgl: framebuffer too large! (%d > %d*%d*%d)\n",
					LIBGGI_FB_SIZE(tm),
					VGLDisplay->Xsize, VGLDisplay->Ysize, 
					pixelBytes);
				return GGI_ENOMEM;
			}

			_ggi_db_add_buffer(LIBGGI_APPLIST(vis), _ggi_db_get_new());

			LIBGGI_APPBUFS(vis)[i]->frame = i;
			LIBGGI_APPBUFS(vis)[i]->type = GGI_DB_NORMAL | GGI_DB_SIMPLE_PLB;
			LIBGGI_APPBUFS(vis)[i]->read = VGLDisplay->Bitmap;
			LIBGGI_APPBUFS(vis)[i]->write = VGLDisplay->Bitmap;
			LIBGGI_APPBUFS(vis)[i]->layout = blPixelLinearBuffer;
			LIBGGI_APPBUFS(vis)[i]->buffer.plb.stride
				= GT_ByPPP(tm->virt.x, tm->graphtype);
		}
	}

	/* Save mode info returned by the VESA driver */
	bcopy(&modeinfo, &priv->modeinfo, sizeof(priv->modeinfo));

	/* Palette */
	if (vis->palette) {
		free(vis->palette);
		vis->palette = NULL;
	}
	if (priv->savepalette) {
		free(priv->savepalette);
		priv->savepalette = NULL;
	}
	if (GT_SCHEME(tm->graphtype) == GT_PALETTE) {
		int len = 1 << GT_DEPTH(tm->graphtype);

		vis->palette = malloc(len * sizeof(ggi_color));
		if (vis->palette == NULL) return GGI_EFATAL;
		priv->savepalette = malloc(sizeof(int) * (len*3));
		if (priv->savepalette == NULL) return GGI_EFATAL;

		/* Set an initial palette */
		ggiSetColorfulPalette(vis);
	}

	/* Set up pixel format */
	memset(LIBGGI_PIXFMT(vis), 0, sizeof(ggi_pixelformat));
	LIBGGI_PIXFMT(vis)->size  = GT_SIZE(gt);
	LIBGGI_PIXFMT(vis)->depth = GT_DEPTH(gt);

	switch (GT_SCHEME(gt)) {

	case GT_PALETTE:
	case GT_GREYSCALE:
		LIBGGI_PIXFMT(vis)->clut_mask = (1 << GT_DEPTH(gt)) - 1;
		break;

	case GT_TRUECOLOR:
		DPRINT_MODE("display-vgl: RGB %d:%d:%d offsets %d:%d:%d\n",
			priv->modeinfo.vi_pixel_fsizes[VGL_RED_INDEX],
			priv->modeinfo.vi_pixel_fsizes[VGL_GREEN_INDEX],
			priv->modeinfo.vi_pixel_fsizes[VGL_BLUE_INDEX],
			priv->modeinfo.vi_pixel_fields[VGL_RED_INDEX],
			priv->modeinfo.vi_pixel_fields[VGL_GREEN_INDEX],
			priv->modeinfo.vi_pixel_fields[VGL_BLUE_INDEX]);

		LIBGGI_PIXFMT(vis)->red_mask =
		((1 << priv->modeinfo.vi_pixel_fsizes[VGL_RED_INDEX]) - 1) <<
			priv->modeinfo.vi_pixel_fields[VGL_RED_INDEX];

		LIBGGI_PIXFMT(vis)->green_mask =
		((1 << priv->modeinfo.vi_pixel_fsizes[VGL_GREEN_INDEX]) - 1) <<
			priv->modeinfo.vi_pixel_fields[VGL_GREEN_INDEX];
			
		LIBGGI_PIXFMT(vis)->blue_mask =
		((1 << priv->modeinfo.vi_pixel_fsizes[VGL_BLUE_INDEX]) - 1) <<
			priv->modeinfo.vi_pixel_fields[VGL_BLUE_INDEX];
		break;

	case GT_TEXT:
		/* Assumes VGA text */
		LIBGGI_PIXFMT(vis)->texture_mask = 0x00ff;
		LIBGGI_PIXFMT(vis)->fg_mask = 0x0f00;
		LIBGGI_PIXFMT(vis)->bg_mask = 0xf000;
		break;
	}
	_ggi_build_pixfmt(LIBGGI_PIXFMT(vis));

	memcpy(LIBGGI_MODE(vis),tm,sizeof(ggi_mode));

	_ggiZapMode(vis, 0);

	for(id = 1; 0 == GGI_vgl_getapi(vis, id, sugname, args); id++) {
		if (_ggiOpenDL(vis, _ggiGetConfigHandle(), sugname, args, NULL)) {
			fprintf(stderr,"display-vgl: Can't open the %s (%s) library.\n",
				sugname, args);
			return GGI_EFATAL;
		} else {
			DPRINT("Success in loading %s (%s)\n", sugname, args);
		}
	}

	if (!priv->vgl_use_db) {
		vis->opdraw->putpixel		= GGI_vgl_putpixel;
		vis->opdraw->putpixel_nc	= GGI_vgl_putpixel_nc;
		vis->opdraw->getpixel		= GGI_vgl_getpixel;
		vis->opdraw->drawpixel		= GGI_vgl_drawpixel;
		vis->opdraw->drawpixel_nc	= GGI_vgl_drawpixel_nc;
		vis->opdraw->drawhline		= GGI_vgl_drawhline;
		vis->opdraw->drawhline_nc	= GGI_vgl_drawhline_nc;
		vis->opdraw->drawvline		= GGI_vgl_drawvline;
		vis->opdraw->drawvline_nc	= GGI_vgl_drawvline_nc;
		vis->opdraw->drawbox		= GGI_vgl_drawbox;
		vis->opdraw->drawline		= GGI_vgl_drawline;
		vis->opdraw->puthline		= GGI_vgl_puthline;
		vis->opdraw->putbox		= GGI_vgl_putbox;
	} else {
		vis->opdraw->setorigin		= GGI_vgl_setorigin;
	}

	if (GT_SCHEME(tm->graphtype) == GT_PALETTE) {
		vis->opcolor->setpalvec = GGI_vgl_setpalvec;
	}

	if(priv->vgl_use_db) {
		for(i = 0; i<tm->frames; i++)
			LIBGGI_APPBUFS(vis)[i]->buffer.plb.pixelformat =
								LIBGGI_PIXFMT(vis);
	}

	ggiIndicateChange(vis, GGI_CHG_APILIST);

	return 0;
}
Beispiel #6
0
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh,
		   const char *args, void *argptr, uint32_t *dlret)
{
	ggi_fbdev_priv *fbdevpriv = FBDEV_PRIV(vis);
	struct m2164w_priv *priv;
	unsigned long usedmemend;
	size_t fontlen;
	int pixbytes;
	int fd = LIBGGI_FD(vis);
	int i;

	if (GT_SIZE(LIBGGI_GT(vis)) % 8 != 0 ||
	    GT_SIZE(LIBGGI_GT(vis)) > 32 ||
	    GT_SIZE(LIBGGI_GT(vis)) < 8) {
		/* Unsupported mode */
		return GGI_ENOFUNC;
	}
	pixbytes = GT_ByPP(LIBGGI_GT(vis));

	priv = malloc(sizeof(struct m2164w_priv));
	if (priv == NULL) {
		return GGI_ENOMEM;
	}

	fbdevpriv->mmioaddr = mmap(NULL, fbdevpriv->orig_fix.mmio_len,
				   PROT_READ | PROT_WRITE, MAP_SHARED,
				   fd, (signed)fbdevpriv->orig_fix.smem_len);
	if (fbdevpriv->mmioaddr == MAP_FAILED) {
		/* Can't mmap() MMIO region - bail out */
		DPRINT_LIBS("mga-2164w: Unable to map MMIO region: %s\n"
			       "          fd: %d, len: %ld, offset: %ld\n",
			       strerror(errno), fd,
			       fbdevpriv->orig_fix.mmio_len,
			       fbdevpriv->orig_fix.smem_len);
		fbdevpriv->mmioaddr = NULL;
		free(priv);
		return GGI_ENODEVICE;
	}

	DPRINT_MISC("mga-2164w: Mapped MMIO region at %p\n",
		       fbdevpriv->mmioaddr);

	/* Set up DirectBuffers */
	for (i=0; i < LIBGGI_MODE(vis)->frames; i++) {
		ggi_directbuffer *buf = LIBGGI_APPBUFS(vis)[i];
		ggi_resource *res;
		
		res = malloc(sizeof(ggi_resource));
		if (res == NULL) {
			do_cleanup(vis);
			return GGI_ENOMEM;
		}
		buf->resource = res;
		buf->resource->acquire = m2164w_acquire;
		buf->resource->release = m2164w_release;
		buf->resource->self = buf;
		buf->resource->priv = vis;
		buf->resource->count = 0;
		buf->resource->curactype = 0;
	}

	priv->drawboxcmd
		= BOP_COPY | SHFTZERO | SGNZERO | ARZERO | SOLID | OP_TRAP;
	if (pixbytes != 3) {
		switch (fbdevpriv->orig_fix.accel) {	
		case FB_ACCEL_MATROX_MGA2064W:
		case FB_ACCEL_MATROX_MGA1064SG:
		case FB_ACCEL_MATROX_MGA2164W:
		case FB_ACCEL_MATROX_MGA2164W_AGP:
			/* Use block mode */
			priv->drawboxcmd |= ATYPE_BLK;
			break;
		default:
			/* For now - assume SDRAM for other cards */
			break;
		}
	}
	priv->dwgctl = 0;
	priv->oldfgcol = LIBGGI_GC(vis)->fg_color - 1;
	priv->oldbgcol = LIBGGI_GC(vis)->bg_color - 1;
	priv->oldtl.x = -1;
	priv->oldtl.y = -1;
	priv->oldbr.x = -1;
	priv->oldbr.y = -1;
	priv->oldyadd = -1;
	priv->curopmode = priv->origopmode = mga_in16(fbdevpriv->mmioaddr, OPMODE);
	/* Use the 7k Pseudo-DMA window */
	priv->dmaaddr = (void*)fbdevpriv->mmioaddr;
	priv->dma_len = 0x1c00;

	vis->needidleaccel = 1;
	fbdevpriv->idleaccel = m2164w_idleaccel;

	/* Accelerate fonts if possible */
	priv->font = (uint8_t *)(font);
	usedmemend = LIBGGI_MODE(vis)->frames *
		fbdevpriv->fix.line_length * LIBGGI_VIRTY(vis);
	fontlen = 256*8;
	priv->fontoffset = fbdevpriv->orig_fix.smem_len - fontlen;
	priv->fontoffset &= ~127; /* Align */
	DPRINT_MISC("mga-2164w: usedmemend: %ld, fontoffset: %ld\n",
		       usedmemend, priv->fontoffset);
	if (usedmemend <= priv->fontoffset) {
		memcpy((uint8_t*)fbdevpriv->fb_ptr + priv->fontoffset,
		       font, fontlen);
		priv->fontoffset *= 8; /* In bits */
		priv->charadd = FWIDTH*FHEIGHT;
		vis->opdraw->putc = GGI_m2164w_fastputc;
		vis->opdraw->puts = GGI_m2164w_fastputs;
		DPRINT_MISC("mga-2164w: Using fast chars\n");
	} else {
		priv->fontoffset = 0;
		vis->opdraw->putc = GGI_m2164w_putc;
		vis->opdraw->puts = GGI_m2164w_puts;
		DPRINT_MISC("mga-2164w: Using slow chars\n");
	}

	/* Save previous function pointers */
	priv->crossblit = vis->opdraw->crossblit;

	/* Initialize function pointers */
	vis->opdraw->getcharsize= GGI_m2164w_getcharsize;
	vis->opdraw->drawhline = GGI_m2164w_drawhline;
	vis->opdraw->drawvline = GGI_m2164w_drawvline;
	vis->opdraw->drawline = GGI_m2164w_drawline;
	vis->opdraw->drawbox = GGI_m2164w_drawbox;
	vis->opdraw->copybox = GGI_m2164w_copybox;
	vis->opdraw->fillscreen = GGI_m2164w_fillscreen;
	/* The crossblit in linear-* is faster on truecolor modes! */
	if (GT_SCHEME(LIBGGI_GT(vis)) == GT_PALETTE ||
	    GT_SCHEME(LIBGGI_GT(vis)) == GT_STATIC_PALETTE) {
		vis->opdraw->crossblit = GGI_m2164w_crossblit;
	}

	FBDEV_PRIV(vis)->accelpriv = priv;

	/* Register cleanup handler */
	ggRegisterCleanup((ggcleanup_func *)do_cleanup, vis);

	*dlret = GGI_DL_OPDRAW;
	return 0;
}