Exemple #1
0
int GGI_palemu_setmode(struct ggi_visual *vis, ggi_mode *mode)
{ 
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	int err;

	DPRINT_MODE("display-palemu: setmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	MANSYNC_ignore(vis);

	if ((err = ggiCheckMode(vis->instance.stem, mode)) != 0) {
		return err;
	}

	_ggiZapMode(vis, 0);

	*LIBGGI_MODE(vis) = *mode;
	
	priv->parent_mode.visible = mode->visible;
	priv->parent_mode.virt    = mode->virt;
	priv->parent_mode.dpp     = mode->dpp;
	priv->parent_mode.size    = mode->size;
	priv->parent_mode.frames  = 1;

	if ((err = do_setmode(vis)) != 0) {
		DPRINT_MODE("display-palemu: setmode failed (%d).\n", err);
		return err;
	}

	priv->squish.x = mode->visible.x / target_width;
	priv->squish.y = mode->visible.y / target_height;

	DPRINT_MODE("display-palemu: Attempting to setmode on parent "
		"visual...\n");

	if (priv->target == PALEMU_TARGET) {
		err = _ggi_palemu_Open(vis);
	} else {
		err = _ggi_monotext_Open(vis);
	}
	if (err != 0) {
		return err;
	}

	/* Initialize palette */
	ggiSetColorfulPalette(vis->instance.stem);

	MANSYNC_SETFLAGS(vis, LIBGGI_FLAGS(vis));
	MANSYNC_cont(vis);

	DPRINT_MODE("display-palemu: setmode succeeded.\n");

	return 0;
}
Exemple #2
0
int GGI_palemu_getmode(struct ggi_visual *vis, ggi_mode *mode)
{
	if ((vis == NULL) || (mode == NULL) || (LIBGGI_MODE(vis) == NULL)) {
		DPRINT_MODE("display-palemu: vis/mode == NULL\n");
		return GGI_EARGINVAL;
	}
	
	DPRINT_MODE("display-palemu: getmode.\n");

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

	return 0;
}
Exemple #3
0
int GGI_lcd823_checkmode(struct ggi_visual *vis, ggi_mode *mode)
{
	int err = 0;

	DPRINT_MODE("display-lcd823: checkmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	_GGIhandle_ggiauto(mode, XRES, YRES);

	if (mode->graphtype == GT_AUTO) {
		mode->graphtype = GT_8BIT;
	}

	if (mode->graphtype != GT_8BIT) {
		mode->graphtype = GT_8BIT;
		err = -1;
	}
	if (mode->virt.x != mode->visible.x || mode->visible.x != XRES) {
		mode->virt.x = mode->visible.x = XRES;
		err = -1;
	}
	if (mode->virt.y != mode->visible.y || mode->visible.y != YRES) {
		mode->virt.y = mode->visible.y = YRES;
		err = -1;
	}

	if (mode->frames != 1 && mode->frames != GGI_AUTO) {
		err = -1;
	}
	mode->frames = 1;

	if ((mode->dpp.x != 1 && mode->dpp.x != GGI_AUTO) ||
	    (mode->dpp.y != 1 && mode->dpp.y != GGI_AUTO)) {
		err = -1;
	}
	mode->dpp.x = mode->dpp.y = 1;

	if (mode->size.x != GGI_AUTO || mode->size.y != GGI_AUTO) {
		err = -1;
	}
	mode->size.x = mode->size.y = GGI_AUTO;

	DPRINT_MODE("display-lcd823: result %d %dx%d#%dx%dF%d[0x%02x]\n",
		       err, mode->visible.x, mode->visible.y,
		       mode->virt.x, mode->virt.y, 
		       mode->frames, mode->graphtype);

	return err;
}
Exemple #4
0
int GGI_vcsa_setmode(struct ggi_visual *vis, ggi_mode *mode)
{ 
	char libname[GGI_MAX_APILEN], libargs[GGI_MAX_APILEN];
	int err, id;

        if ((err = ggiCheckMode(vis->instance.stem, mode)) != 0) {
		return err;
	}

	DPRINT_MODE("display-vcsa: setmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

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

	_ggiZapMode(vis, 0);

	/* load API libraries */
	for (id=1; GGI_vcsa_getapi(vis, id, libname, libargs) == 0; id++) {
		err = _ggiOpenDL(vis, libggi->config, libname, libargs, NULL);
		if (err) {
			fprintf(stderr,"display-vcsa: Error opening the "
				"%s (%s) library.\n", libname, libargs);
			return GGI_EFATAL;
		}

		DPRINT_LIBS("Success in loading %s (%s)\n", libname, libargs);
	}

	/* setup drawing primitives */
	vis->opdraw->putpixel_nc  = GGI_vcsa_putpixel_nc;
	vis->opdraw->getpixel_nc  = GGI_vcsa_getpixel_nc;
	vis->opdraw->putc         = GGI_vcsa_putc;
	vis->opdraw->puts         = GGI_vcsa_puts;
	vis->opdraw->getcharsize  = GGI_vcsa_getcharsize;
	vis->opdraw->drawhline_nc = GGI_vcsa_drawhline_nc;
	vis->opdraw->puthline     = GGI_vcsa_puthline;
	vis->opdraw->gethline     = GGI_vcsa_gethline;

	vis->opcolor->mapcolor    = GGI_vcsa_mapcolor;
	vis->opcolor->unmappixel  = GGI_vcsa_unmappixel;

	/* indicate API change */
	ggiIndicateChange(vis->instance.stem, GGI_CHG_APILIST);

	DPRINT_MODE("display-vcsa: setmode Success.\n");

	return 0;
}
Exemple #5
0
int GGI_vcsa_getmode(struct ggi_visual *vis, ggi_mode *mode)
{
	DPRINT_MODE("display-vcsa: getmode\n");
	
	memcpy(mode, LIBGGI_MODE(vis), sizeof(ggi_mode));

	return 0;
}
Exemple #6
0
static int do_dbstuff(struct ggi_visual *vis)
{
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	int i;

	/* allocate memory */
	priv->frame_size = LIBGGI_FB_SIZE(LIBGGI_MODE(vis));
	priv->fb_size = priv->frame_size * LIBGGI_MODE(vis)->frames;
	priv->fb_ptr  = malloc((size_t)priv->fb_size);
	
	DPRINT_MODE("display-palemu: fb=%p size=%d frame=%d\n", 
		priv->fb_ptr, priv->fb_size, priv->frame_size);

	if (priv->fb_ptr == NULL) {
		fprintf(stderr, "display-palemu: Out of memory.\n");
		return GGI_ENOMEM;
	}

        /* clear all frames */
	memset(priv->fb_ptr, 0, (size_t)priv->fb_size);

	/* set up pixel format */
	memset(LIBGGI_PIXFMT(vis), 0, sizeof(ggi_pixelformat));
	setup_pixfmt(LIBGGI_PIXFMT(vis), LIBGGI_GT(vis));
	_ggi_build_pixfmt(LIBGGI_PIXFMT(vis));

	/* set up direct buffers */
	for (i=0; i < LIBGGI_MODE(vis)->frames; i++) {
		ggi_directbuffer *buf;
		
		_ggi_db_add_buffer(LIBGGI_PRIVLIST(vis), _ggi_db_get_new());

		buf = LIBGGI_PRIVBUFS(vis)[i];

		buf->frame = i;
		buf->type  = GGI_DB_NORMAL | GGI_DB_SIMPLE_PLB;
		buf->read  = (char *) priv->fb_ptr + i * priv->frame_size;
		buf->write = buf->read;
		buf->layout = blPixelLinearBuffer;

		buf->buffer.plb.stride = 
			GT_ByPPP(LIBGGI_VIRTX(vis), LIBGGI_GT(vis));
		buf->buffer.plb.pixelformat = LIBGGI_PIXFMT(vis);
	}

	/* Set up palette */
	if (LIBGGI_PAL(vis)->clut.data) {
		free(LIBGGI_PAL(vis)->clut.data);
 		LIBGGI_PAL(vis)->clut.data = NULL;
	}
	if (GT_SCHEME(LIBGGI_GT(vis)) == GT_PALETTE) {
		LIBGGI_PAL(vis)->clut.data = _ggi_malloc((1 << GT_DEPTH(LIBGGI_GT(vis))) *
						sizeof(ggi_color));
		LIBGGI_PAL(vis)->clut.size = 1 << GT_DEPTH(LIBGGI_GT(vis));
	}

	return 0;
}
Exemple #7
0
int GGI_trueemu_setmode(struct ggi_visual *vis, ggi_mode *mode)
{ 
	ggi_trueemu_priv *priv = TRUEEMU_PRIV(vis);
	int err;

	DPRINT_MODE("display-trueemu: setmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	MANSYNC_ignore(vis);

	if ((err = ggiCheckMode(vis->instance.stem, mode)) != 0) {
		return err;
	}

	_ggiZapMode(vis, 0);

	*LIBGGI_MODE(vis) = *mode;

	priv->mode.visible = mode->visible;
	priv->mode.virt    = mode->virt;
	priv->mode.dpp     = mode->dpp;
	priv->mode.size    = mode->size;
	priv->mode.frames  = 1;

	if ((err = do_setmode(vis)) != 0) {
		DPRINT_MODE("display-trueemu: setmode failed (%d).\n", err);
		return err;
	}

	DPRINT_MODE("display-trueemu: Attempting to setmode on parent "
		"visual...\n");

	if ((err = _ggi_trueemu_Open(vis)) != 0) {
		return err;
	}

	MANSYNC_SETFLAGS(vis, LIBGGI_FLAGS(vis));
	MANSYNC_cont(vis);

	DPRINT_MODE("display-trueemu: setmode succeeded.\n");

	return 0;
}
Exemple #8
0
static int calc_squish(ggi_palemu_priv *priv, ggi_mode *mode,
			int _target_width, int _target_height)
{
	int sq_x, sq_y;
	int totw = _target_width * priv->accuracy.x;
	int toth = _target_height * priv->accuracy.y;

#if 0	/* Preliminary mode-improvement code */
	while ((mode->visible.x % totw) != 0) mode.visible.x++;
	while ((mode->visible.y % toth) != 0) mode.visible.y++;
	mode->virt.x = mode->visible.x;
	mode->virt.y = mode->visible.y;
#endif

	if (((mode->visible.x % totw) != 0) ||
	    ((mode->visible.y % toth) != 0)) {
		DPRINT_MODE("display-monotext: visible size is not a "
			"multiple of the target size.\n");
		return GGI_ENOMATCH;
	}

	sq_x = mode->visible.x / totw;
	sq_y = mode->visible.y / toth;

	if (sq_x <= 0 || sq_y <= 0) {
		DPRINT_MODE("display-monotext: visible size is not a "
			"multiple of the target size.\n");
		return GGI_ENOMATCH;
	}

	if (mode->visible.x / priv->accuracy.x / sq_x != totw ||
	    mode->visible.y / priv->accuracy.y / sq_y != toth) {
		return GGI_ENOMATCH;
	}

	return 0;
}
Exemple #9
0
static int do_setmode(struct ggi_visual *vis)
{
	char libname[GGI_MAX_APILEN], libargs[GGI_MAX_APILEN];
	ggi_graphtype gt;
	int err, id;

	err = do_mmap(vis); 
	if (err) return err;

	_ggiZapMode(vis, 0);
	for (id=1; GGI_lcd823_getapi(vis, id, libname, libargs) == 0; id++) {
		if (_ggiOpenDL(vis, libggi->config, libname, libargs, NULL) != 0) {
			fprintf(stderr,"display-lcd823: Error opening the "
				"%s (%s) library.\n", libname, libargs);
			return GGI_EFATAL;
		}

		DPRINT_LIBS("Success in loading %s (%s)\n",
			       libname, libargs);
	}

	/* Set up palette */
	gt = LIBGGI_GT(vis);
	if ((GT_SCHEME(gt) == GT_PALETTE) || (GT_SCHEME(gt) == GT_TEXT)) {
	    	int nocols = 1 << GT_DEPTH(gt);

		LIBGGI_PAL(vis)->clut.size = nocols;
		LIBGGI_PAL(vis)->clut.data = _ggi_malloc(nocols * sizeof(ggi_color));
		LIBGGI_PAL(vis)->priv = _ggi_malloc(256 * sizeof(uint16_t));
		LIBGGI_PAL(vis)->setPalette  = GGI_lcd823_setPalette;
		LIBGGI_PAL(vis)->getPrivSize = GGI_lcd823_getPrivSize;
		/* Initialize palette */
		ggiSetColorfulPalette(vis);
	}

	ggiIndicateChange(vis, GGI_CHG_APILIST);

	DPRINT_MODE("display-lcd823: do_setmode SUCCESS\n");

	return 0;
}
Exemple #10
0
static int _ggi_xshm_create_ximage(struct ggi_visual *vis)
{
	char target[GGI_MAX_APILEN];
	ggi_mode tm;
	ggi_x_priv *priv;
	int err, i;
	XShmSegmentInfo *myshminfo;
	size_t shmsize;


	err = GGI_OK;
	priv = GGIX_PRIV(vis);

	DPRINT_MODE("X: MIT-SHM: Creating shared MIT-SHM buffer\n");

	_ggi_xshm_free_ximage(vis);

	priv->priv = calloc(1, sizeof(XShmSegmentInfo));
	if (!priv->priv) return GGI_ENOMEM;
	myshminfo = priv->priv;

	priv->ximage = XShmCreateImage(priv->disp,
				priv->vilist[priv->viidx].vi->visual, 
				(unsigned)priv->vilist[priv->viidx].vi->depth,
				ZPixmap,		/* format */
				NULL,		/* data */
				myshminfo,	/* shm object */
				(unsigned)LIBGGI_VIRTX(vis), 
				(unsigned)(LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames));
	if (priv->ximage == NULL) {
		DPRINT("XShmCreateImage() failed.");
		err = GGI_ENOMEM;
		goto err0;
	}

	shmsize = priv->ximage->bytes_per_line
			* LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames;

	DPRINT_MODE("X: MIT-SHM: Try to shmget() a buffer of %lu (0x%lx) size bytes\n",
		shmsize, shmsize);

	myshminfo->shmid = shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0777);
	if (myshminfo->shmid == -1) {
		DPRINT("shmget() failed.\n");
		priv->fb = NULL;
		err = GGI_ENOMEM;
		goto err1;
	}

	priv->fb = shmat(myshminfo->shmid,0,0);
	if (priv->fb == (void *)-1) {
		DPRINT("shmat() failed.\n");
		priv->fb = NULL;
		err = GGI_ENOMEM;
		goto err1;
	}
	myshminfo->shmaddr = priv->ximage->data = (char *)priv->fb;
	DPRINT_MODE("X: MIT-SHM: shmat success at %p.\n", priv->fb);

	myshminfo->readOnly = False;

	ggLock(_ggi_global_lock); /* Entering protected section */
	shmerror = 0;
	DPRINT_MODE("X: MIT-SHM: install error handler\n");
	oldshmerrorhandler = XSetErrorHandler(shmerrorhandler);
	DPRINT_MODE("X: MIT-SHM: Attach shm to display\n");
	XShmAttach(priv->disp, myshminfo);

	XSync(priv->disp, 0);
	DPRINT_MODE("X: MIT-SHM: restore error handler\n");
	XSetErrorHandler(oldshmerrorhandler);
	if (shmerror) {
		ggUnlock(_ggi_global_lock); /* Exiting protected section */
		DPRINT("can not access XSHM.\n");
		err = GGI_ENOMEM;
		goto err2;
	} else {
		/* Take the shmid away so noone else can get it. */
		shmctl(myshminfo->shmid, IPC_RMID, 0);
		DPRINT_MODE("X: MIT-SHM: ShmImage allocated\n");
	}
	ggUnlock(_ggi_global_lock); /* Exiting protected section */


	err = _ggi_create_dbs(vis);
	if (err)
		goto err3;

	/* We assume LIBGGI_MODE(vis) structure has already been filled out */
	memcpy(&tm, LIBGGI_MODE(vis), sizeof(ggi_mode));

	/* Make sure we do not fail due to physical size constraints,
	 * which are meaningless on a memory visual.
	 */
	tm.size.x = tm.size.y = GGI_AUTO;

	i = 0;
	memset(target, '\0', sizeof(target));
	i += snprintf(target, sizeof(target), "display-memory:-pixfmt=");

	_ggi_build_pixfmtstr(vis, target + i, sizeof(target) - i, 1);
	i = strlen(target);

	snprintf(target + i, sizeof(target) - i,
		":-layout=%iplb%i:-physz=%i,%i:pointer",
		priv->ximage->bytes_per_line * LIBGGI_VIRTY(vis),
		priv->ximage->bytes_per_line,
		LIBGGI_MODE(vis)->size.x, LIBGGI_MODE(vis)->size.y);

	err = _ggi_openslave(vis, target, &tm);
	if (err)
		goto err3;

	priv->ximage->byte_order = ImageByteOrder(priv->disp);
	priv->ximage->bitmap_bit_order = BitmapBitOrder(priv->disp);

	vis->opdisplay->flush		= GGI_XSHM_flush_ximage_child;

	DPRINT_MODE("X: MIT-SHM: XSHMImage and slave visual %p share buffer at %p\n",
		       priv->slave, priv->fb);

	return GGI_OK;

err3:
	fprintf(stderr,
		"XSHM extension failed to initialize. Retry with -noshm\n");
	_ggi_xshm_free_ximage(vis);
	return err;

err2:
	XShmDetach(priv->disp, myshminfo);
	shmdt(priv->fb);
	priv->fb = NULL;
err1:
	XDestroyImage(priv->ximage);
	priv->ximage = NULL;
err0:
	fprintf(stderr,
		"XSHM extension failed to initialize. Retry with -noshm\n");
	return err;
}
Exemple #11
0
int GGI_vcsa_checkmode(struct ggi_visual *vis, ggi_mode *mode)
{
	ggi_vcsa_priv *priv = VCSA_PRIV(vis);
	int err;

	DPRINT_MODE("display-vcsa: checkmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	/* handle GT_AUTO in graphtype */
	if (GT_SCHEME(mode->graphtype) == GT_AUTO) {
		GT_SETSCHEME(mode->graphtype, GT_TEXT);
	}
	if (GT_DEPTH(mode->graphtype) == GT_AUTO) {
		GT_SETDEPTH(mode->graphtype, 4);
	}
	if (GT_SIZE(mode->graphtype) == GT_AUTO) {
		GT_SETSIZE(mode->graphtype, 16);
	}

	/* handle GGI_AUTO in ggi_mode */
	if ((mode->dpp.x != 1 && mode->dpp.x != GGI_AUTO) ||
	    (mode->dpp.y != 1 && mode->dpp.y != GGI_AUTO)) {
		err = -1;
	}
	mode->dpp.x = mode->dpp.y = 1;

	_GGIhandle_ggiauto(mode, priv->width, priv->height);

	/* now check stuff */
	err = 0;

	if (GT_SCHEME(mode->graphtype) != GT_TEXT) {
		GT_SETSCHEME(mode->graphtype, GT_TEXT);
		err = -1;
	}
	if (GT_DEPTH(mode->graphtype) != 4) {
		GT_SETDEPTH(mode->graphtype, 4);
		err = -1;
	}
	if (GT_SIZE(mode->graphtype) != 16) {
		GT_SETSIZE(mode->graphtype, 16);
		err = -1;
	}

	if (mode->visible.x != priv->width) {
		mode->visible.x = priv->width;
		err = -1;
	}
	if (mode->visible.y != priv->height) {
		mode->visible.y = priv->height;
		err = -1;
	}
	if (mode->virt.x != priv->width) {
		mode->virt.x = priv->width;
		err = -1;
	}
	if (mode->virt.y != priv->height) {
		mode->virt.y = priv->height;
		err = -1;
	}

	if (mode->frames != 1) {
		mode->frames = 1;
		err = -1;
	}

	err = _ggi_physz_figure_size(mode, priv->physzflags, &(priv->physz),
				0, 0, mode->visible.x, mode->visible.y);
		
	DPRINT_MODE("display-vcsa: result %d %dx%d#%dx%dF%d[0x%02x]\n",
			err, mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);
	return err;
}
Exemple #12
0
int GGI_libkgi_setmode(struct ggi_visual *vis, ggi_mode *mode)
{
        int err;
	ggiGA_resource_list reqlist;
	struct ggiGA_resource_props rend;
	ggiGA_resource_handle motor_h, carb_h;

        DPRINT_MODE("display-libkgi: setmode\n");

	/* Make sure LibGAlloc is attached. */
	if (!(LIBKGI_PRIV(vis)->galloc_loaded)) {
		DPRINT("Attaching LibGAlloc\n");
		err = ggiGAAttach(vis);
		if (err) {
			fprintf(stderr, "Eek, couldn't attach LibGAlloc.\n");
			return err;
		}
		LIBKGI_PRIV(vis)->galloc_loaded = 1;
	}

	/* Since we cannot guarantee otherwise on other targets,
	 * calling ggiSetMode wipes out all ancilary resources.
	 */
	reqlist = NULL;
	err = ggiGAAddMode(vis, &reqlist, mode, NULL, NULL);
	if (err) {
		fprintf(stderr, "ggiGAAddMode failed.");
		return (err);
	}
	ggiGAClearMotorProperties(&rend);
	rend.sub.motor.div_max.x = 1;
	rend.sub.motor.div_max.y = 1;
	rend.sub.motor.mul_max.x = 1;
	rend.sub.motor.mul_max.y = 1;
	rend.sub.motor.div_min.x = 1;
	rend.sub.motor.div_min.y = 1;
	rend.sub.motor.mul_min.x = 1;
	rend.sub.motor.mul_min.y = 1;

	err = ggiGAAdd(&reqlist, &rend,
		       GA_RT_RENDERER_DRAWOPS | GA_RT_MOTOR, 
		       &motor_h);
	if (err) {
		fprintf(stderr, "ggiGAAdd failed.");
		ggiGAEmptyList(&reqlist);
		return (err);
	}
	ggiGAClearCarbProperties(&rend);
	/* TODO: fill out carb for solid drawops (no Z/Alpha) */

	err = ggiGAAdd(&reqlist, &rend,
		       GA_RT_RENDERER_DRAWOPS | GA_RT_CARB, 
		       &carb_h);
	if (err) {
		fprintf(stderr, "ggiGAAdd failed.");
		ggiGAEmptyList(&reqlist);
		return (err);
	}

	ggiGATagOnto(reqlist, motor_h, carb_h);

	/* 
	 * This will load the batchop to serve the rendering functions.
         * (The batchop sublib will, in turn, load generic renderers 
	 *  if needed.)
	 */
	err = ggiGASet(vis, reqlist, &reqlist);
	memcpy(mode, ggiGAGetGGIMode(reqlist /* mode is first resource */),
	       sizeof(ggi_mode));
        if (err != 0) return err;

        DPRINT_MODE("display-libkgi: setmode success.\n");

        return 0;
}
Exemple #13
0
int _ggi_x_createfb(struct ggi_visual *vis)
{
	char target[GGI_MAX_APILEN];
	ggi_mode tm;
	ggi_x_priv *priv;
	int err, i;

	err = GGI_OK;
	priv = GGIX_PRIV(vis);

	DPRINT_MODE("_ggi_x_createfb(%p) called\n", vis);
	DPRINT("viidx = %i\n", priv->viidx);

	_ggi_x_freefb(vis);

	DPRINT_MODE("Creating vanilla XImage client-side buffer\n");

	priv->fb = calloc(1, GT_ByPPP(LIBGGI_VIRTX(vis),LIBGGI_GT(vis))
			* LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames);
	if (priv->fb == NULL) {
		DPRINT("_ggi_x_createfb: XImage buffer allocation failed.\n");
		err = GGI_ENOMEM;
		goto err0;
	}

	/* We assume LIBGGI_MODE(vis) structure has already been filled out */
	memcpy(&tm, LIBGGI_MODE(vis), sizeof(ggi_mode));


	/* Make sure we do not fail due to physical size constraints,
	 * which are meaningless on a memory visual.
	 */
	tm.size.x = tm.size.y = GGI_AUTO;

	i = 0;
	memset(target, '\0', sizeof(target));
	i += snprintf(target, sizeof(target),
			"display-memory:-noblank:-pixfmt=");

	_ggi_build_pixfmtstr(vis, target + i, sizeof(target) - i, 1);
	i = strlen(target);

	snprintf(target + i, sizeof(target) - i, ":-physz=%i,%i:pointer", 
		LIBGGI_MODE(vis)->size.x, LIBGGI_MODE(vis)->size.y);

	err = _ggi_openslave(vis, target, &tm);
	if (err)
		goto err1;

	priv->ximage = _ggi_x_create_ximage( vis, (char*)priv->fb,
					     LIBGGI_VIRTX(vis), 
					     LIBGGI_VIRTY(vis) );
	if (priv->ximage == NULL) {
		DPRINT("_ggi_x_createfb: _ggi_x_create_ximage() failed\n");
		err = GGI_ENOMEM;
		goto err1;
	}

	err = _ggi_create_dbs(vis);
	if (err)
		goto err1;

	DPRINT_MODE("X: XImage %p and slave visual %p share buffer at %p\n",
		       priv->ximage, priv->slave, priv->fb);

	return GGI_OK;

err1:
	_ggi_x_freefb(vis);
err0:
	return err;
}
Exemple #14
0
static unsigned __stdcall
DDEventLoop(void *lpParm)
{
	MSG msg;
	struct ggi_visual *vis = (struct ggi_visual *) lpParm;
	directx_priv *priv = GGIDIRECTX_PRIV(vis);

	priv->nThreadID = GetCurrentThreadId();

	/* create the window */
	if (!DDCreateWindow(vis)) {
		SetEvent(priv->hInit);
		return 0;
	}

	SetEvent(priv->hInit);

	while (GetMessage(&msg, NULL, 0, 0)) {
		if (msg.hwnd == NULL && msg.message == WM_DDEND) {
			/* Use PostThreadMessage to get here */
			DPRINT("Ending session, "
				  "destroying window.\n");
			DestroyWindow(priv->hWnd);
			break;
		}
		if (msg.hwnd == NULL && msg.message == WM_DDFULLSCREEN) {
			directx_fullscreen *dxfull =
				(directx_fullscreen *)msg.lParam;
			if (!dxfull) {
				fprintf(stderr, "Aieee! "
					"No lParam for WM_DDFULLSCREEN\n");
				exit(1);
			}
			DPRINT_MODE("Set coop level\n");
			dxfull->hr = IDirectDraw2_SetCooperativeLevel(
				dxfull->priv->lpddext, dxfull->priv->hWnd,
				DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
			if (FAILED(dxfull->hr))
				DPRINT_MODE("SetCooperativeLevel failed %x\n",
					dxfull->hr);
			DPRINT_MODE("Set fullscreen mode "
				"(%i,%i) size %d\n",
				dxfull->mode->visible.x,
				dxfull->mode->visible.y,
				GT_SIZE(dxfull->mode->graphtype));
			dxfull->hr = IDirectDraw2_SetDisplayMode(
				dxfull->priv->lpddext,
				dxfull->mode->visible.x,
				dxfull->mode->visible.y,
				GT_SIZE(dxfull->mode->graphtype), 0, 0);
			if (FAILED(dxfull->hr))
				DPRINT_MODE("SetDisplayMode failed %x\n",
					dxfull->hr);
			SetEvent(dxfull->event);
			continue;
		}
		if (msg.hwnd == NULL && msg.message == WM_DDHOTKEY) {
			if (msg.wParam) {
				DPRINT("Grab hotkeys\n");
				RegisterHotKey(priv->hWnd, 0x0000,
					MOD_ALT, VK_TAB);
				RegisterHotKey(priv->hWnd, 0x0001,
					MOD_ALT | MOD_SHIFT, VK_TAB);
				RegisterHotKey(priv->hWnd, 0x0002,
					MOD_ALT, VK_F4);
			}
			else {
				DPRINT("Ungrab hotkeys\n");
				UnregisterHotKey(priv->hWnd, 0x0000);
				UnregisterHotKey(priv->hWnd, 0x0001);
				UnregisterHotKey(priv->hWnd, 0x0002);
			}
			continue;
		}

		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	DPRINT("Helper thread terminating\n");

#ifndef __CYGWIN__
	_endthreadex(msg.wParam);
#endif
	return msg.wParam;
}
Exemple #15
0
static BOOL CALLBACK
ModeCallback(LPDDSURFACEDESC sd, LPVOID ctx)
{
	matchmode *mm = (matchmode *)ctx;
	ggi_mode *mode = mm->mode;
	const char *msg;
	int ndx, bdx, ndy, bdy;

	if (GT_DEPTH(mode->graphtype) != GT_AUTO) {
		if (sd->ddpfPixelFormat.dwRGBBitCount <
			GT_DEPTH(mode->graphtype))
		{
			if (sd->ddpfPixelFormat.dwRGBBitCount > mm->bits)
				goto accept;
			if (sd->ddpfPixelFormat.dwRGBBitCount < mm->bits) {
				msg = "rej mode (%i,%i) "
					"poorer depth %i\n";
				goto next;
			}
		}
		if (sd->ddpfPixelFormat.dwRGBBitCount >
			GT_DEPTH(mode->graphtype))
		{
			if (mm->bits < GT_DEPTH(mode->graphtype))
				goto accept;
			if (sd->ddpfPixelFormat.dwRGBBitCount < mm->bits)
				goto accept;
			if (sd->ddpfPixelFormat.dwRGBBitCount > mm->bits) {
				msg = "rej mode (%i,%i) "
					"poorer depth %i\n";
				goto next;
			}
		}
		if (sd->ddpfPixelFormat.dwRGBBitCount != mm->bits)
			goto accept;
	}

	if (mm->x == GGI_AUTO && mm->y == GGI_AUTO) {
		if (sd->ddpfPixelFormat.dwRGBBitCount > mm->bits)
			goto accept;
		if (mm->bestx * mm->besty < (int)(sd->dwWidth * sd->dwHeight))
			goto accept;
		msg = "rej smaller mode (%i,%i) depth %i\n";
		goto next;
	}

	ndx = sd->dwWidth - mm->x;
	ndy = sd->dwHeight - mm->y;
	bdx = mm->bestx - mm->x;
	bdy = mm->besty - mm->y;
	if (mm->x == GGI_AUTO)
		ndx = bdx = 0;
	if (mm->y == GGI_AUTO)
		ndy = bdy = 0;

	if (ndx >= 0 && ndy >= 0 && (bdx < 0 || bdy < 0))
		goto accept;
	if ((ndx < 0 || ndy < 0) && bdx >= 0 && bdy >= 0) {
		msg = "rej bad mode (%i,%i) depth %i\n";
		goto next;
	}
	if (ndx*ndx + ndy*ndy < bdx*bdx + bdy*bdy)
		goto accept;
	if (ndx*ndx + ndy*ndy == bdx*bdx + bdy*bdy) {
		if (sd->ddpfPixelFormat.dwRGBBitCount >= mm->bits)
			goto accept;
		msg = "rej mode (%i,%i) poorer depth %i\n";
		goto next;
	}
	msg = "rej worse mode (%i,%i) depth %i\n";
	goto next;

accept:
	msg = "best mode so far (%i,%i) depth %i\n";
	mm->bestx = sd->dwWidth;
	mm->besty = sd->dwHeight;
	mm->bits  = sd->ddpfPixelFormat.dwRGBBitCount;
next:
	DPRINT_MODE(msg, sd->dwWidth, sd->dwHeight,
		sd->ddpfPixelFormat.dwRGBBitCount);
	return DDENUMRET_OK;
}
Exemple #16
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;
}
Exemple #17
0
int GGI_monotext_checkmode(struct ggi_visual *vis, ggi_mode *mode)
{
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	int err = 0;

	if ((vis == NULL) || (mode == NULL)) {
		DPRINT_MODE("display-monotext: vis/mode == NULL\n");
		return GGI_EARGINVAL;
	}

	DPRINT_MODE("display-monotext: checkmode %dx%d (gt=%d)\n",
		mode->visible.x, mode->visible.y, mode->graphtype);

	/* Handle GGI_AUTO */
	if (mode->graphtype == GGI_AUTO) {
		mode->graphtype = GT_8BIT;
	}

	if ((mode->visible.x == GGI_AUTO) &&
	    (mode->virt.x    == GGI_AUTO)) {
		mode->visible.x = mode->virt.x = target_width * priv->accuracy.x;
	} else if (mode->virt.x == GGI_AUTO) {
		mode->virt.x = mode->visible.x;
	} else if ((mode->visible.x == GGI_AUTO) ||
		   (mode->visible.x > mode->virt.x)) {
		mode->visible.x = mode->virt.y;
	}


	if ((mode->visible.y == GGI_AUTO) &&
	    (mode->virt.y    == GGI_AUTO)) {
		mode->visible.y = mode->virt.y = target_height * priv->accuracy.y;
	} else if (mode->virt.y == GGI_AUTO) {
		mode->virt.y = mode->visible.y;
	} else if ((mode->visible.y == GGI_AUTO) ||
		   (mode->visible.y > mode->virt.y)) {
		mode->visible.y = mode->virt.y;
	}

	if (mode->frames != 1 && mode->frames != GGI_AUTO) {
		err = -1;
	}
	mode->frames = 1;

	if ((mode->dpp.x != 1 && mode->dpp.x != GGI_AUTO) ||
	    (mode->dpp.y != 1 && mode->dpp.y != GGI_AUTO)) {
		err = -1;
	}
	mode->dpp.x = mode->dpp.y = 1;

	if (mode->size.x != GGI_AUTO || mode->size.y != GGI_AUTO) {
		err = -1;
	}
	mode->size.x = mode->size.y = GGI_AUTO;

	/* Check stuff */
	if (mode->graphtype != GT_8BIT) {
		mode->graphtype = GT_8BIT;
		err = -1;
	}

	if (mode->visible.x != mode->virt.x) {
		mode->virt.x = mode->visible.x;
		err = -1;
	}
	if (mode->visible.y != mode->virt.y) {
		mode->virt.y = mode->visible.y;
		err = -1;
	}

	if (calc_squish(priv, mode, target_width, target_height) != 0) {
		mode->visible.x = target_width * priv->accuracy.x;
		mode->visible.y = target_width * priv->accuracy.y;
		err = -1;
	}

	return err;
}
Exemple #18
0
int GGI_palemu_checkmode(struct ggi_visual *vis, ggi_mode *mode)
{
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	ggi_mode par_mode;
	int tmperr, err = 0;

	DPRINT_MODE("display-palemu: checkmode %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);

	/* Handle graphtype */
	if (GT_SCHEME(mode->graphtype) == GT_AUTO) {
		GT_SETSCHEME(mode->graphtype, GT_PALETTE);
	}

	mode->graphtype = _GGIhandle_gtauto(mode->graphtype);

	if (GT_SCHEME(mode->graphtype) != GT_PALETTE) {
		GT_SETSCHEME(mode->graphtype, GT_PALETTE);
		err = -1;
	}

	if (GT_DEPTH(mode->graphtype) > 8) {
		GT_SETDEPTH(mode->graphtype, 8);
		err = -1;
	}

	if (GT_SIZE(mode->graphtype) != GT_DEPTH(mode->graphtype)) {
		GT_SETSIZE(mode->graphtype, GT_DEPTH(mode->graphtype));
		err = -1;
	}

	/* Handle geometry */
	if (mode->visible.x == GGI_AUTO) {
		mode->visible.x = priv->parent_defmode.visible.x;
	}
	if (mode->visible.y == GGI_AUTO) {
		mode->visible.y = priv->parent_defmode.visible.y;
	}
	if (mode->virt.x == GGI_AUTO) {
		mode->virt.x = priv->parent_defmode.virt.x;
	}
	if (mode->virt.y == GGI_AUTO) {
		mode->virt.y = priv->parent_defmode.virt.y;
	}
	if (mode->dpp.x == GGI_AUTO) {
		mode->dpp.x = priv->parent_defmode.dpp.x;
	}
	if (mode->dpp.y == GGI_AUTO) {
		mode->dpp.y = priv->parent_defmode.dpp.y;
	}
	if (mode->size.x == GGI_AUTO) {
		mode->size.x = priv->parent_defmode.size.x;
	}
	if (mode->size.y == GGI_AUTO) {
		mode->size.y = priv->parent_defmode.size.y;
	}
	if (mode->frames == GGI_AUTO) {
		mode->frames = 1;
	}

	/* Now check mode against the parent target (letting the parent
	 * target handle any remaining GT_AUTO and GGI_AUTO values).
	 */
	par_mode = *mode;

	par_mode.graphtype = priv->parent_defmode.graphtype;

	tmperr = ggiCheckMode(priv->parent, &par_mode);
	if (tmperr) err = tmperr;

	mode->visible = par_mode.visible;
	mode->virt    = par_mode.virt;
	mode->dpp     = par_mode.dpp;
	mode->size    = par_mode.size;

	/* When the parent is palettized, we must limit the
	 * resulting depth to be <= the parent depth.
	 */

	if ((GT_SCHEME(par_mode.graphtype) == GT_PALETTE) &&
	    (GT_DEPTH(par_mode.graphtype) < 
	     GT_DEPTH(mode->graphtype))) {
		GT_SETDEPTH(mode->graphtype, 
			GT_DEPTH(par_mode.graphtype));
		GT_SETSIZE(mode->graphtype, 
			GT_DEPTH(par_mode.graphtype));
		err = -1;
	}
	
	DPRINT_MODE("display-palemu: result %d %dx%d#%dx%dF%d[0x%02x]\n",
			err, mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y, 
			mode->frames, mode->graphtype);
	return err;
}
Exemple #19
0
int GGI_trueemu_checkmode(struct ggi_visual *vis, ggi_mode *mode)
{
	ggi_trueemu_priv *priv = TRUEEMU_PRIV(vis);
	ggi_mode par_mode;
	int tmperr, err = 0;
	
	DPRINT_MODE("display-trueemu: checkmode %dx%d#%dx%dF%d[0x%02x]\n",
		       mode->visible.x, mode->visible.y,
		       mode->virt.x, mode->virt.y,
		       mode->frames, mode->graphtype);

	/* Handle graphtype */
	if (GT_SCHEME(mode->graphtype) == GT_AUTO) {
		GT_SETSCHEME(mode->graphtype, GT_TRUECOLOR);
	}

	mode->graphtype = _GGIhandle_gtauto(mode->graphtype);

	if (GT_SCHEME(mode->graphtype) != GT_TRUECOLOR) {
		GT_SETSCHEME(mode->graphtype, GT_TRUECOLOR);
		err = -1;
	}

	if (GT_DEPTH(mode->graphtype) != 24) {
		GT_SETDEPTH(mode->graphtype, 24);
		err = -1;
	}

	if ((GT_SIZE(mode->graphtype) != GT_DEPTH(mode->graphtype)) &&
	    (GT_SIZE(mode->graphtype) != 32)) {
		GT_SETSIZE(mode->graphtype, GT_DEPTH(mode->graphtype));
		err = -1;
	}
	
	/* Handle geometry */
	if (mode->visible.x == GGI_AUTO) {
		mode->visible.x = priv->mode.visible.x;
	}
	if (mode->visible.y == GGI_AUTO) {
		mode->visible.y = priv->mode.visible.y;
	}
	if (mode->virt.x == GGI_AUTO) {
		mode->virt.x = priv->mode.virt.x;
	}
	if (mode->virt.y == GGI_AUTO) {
		mode->virt.y = priv->mode.virt.y;
	}
	if (mode->dpp.x == GGI_AUTO) {
		mode->dpp.x = priv->mode.dpp.x;
	}
	if (mode->dpp.y == GGI_AUTO) {
		mode->dpp.y = priv->mode.dpp.y;
	}
	if (mode->size.x == GGI_AUTO) {
		mode->size.x = priv->mode.size.x;
	}
	if (mode->size.y == GGI_AUTO) {
		mode->size.y = priv->mode.size.y;
	}
	if (mode->frames == GGI_AUTO) {
		mode->frames = 1;
	}

	/* Now let the parent target have it's say in the checkmode
	 * process.  It can deal with any remaining GGI_AUTO or GT_AUTO
	 * values that came from priv->mode.
	 */
	par_mode = *mode;

	par_mode.graphtype = priv->mode.graphtype;

	tmperr = ggiCheckMode(priv->parent, &par_mode);
	if (tmperr) err = tmperr;

	mode->visible = par_mode.visible;
	mode->virt    = par_mode.virt;
	mode->dpp     = par_mode.dpp;
	mode->size    = par_mode.size;

	DPRINT_MODE("display-trueemu: upgraded to %dx%d#%dx%dF%d[0x%02x]\n",
			mode->visible.x, mode->visible.y,
			mode->virt.x, mode->virt.y,
			mode->frames, mode->graphtype);

	return err;
}