Пример #1
0
void _terminfo_finalize_ncurses(void)
{
	ggLock(ncurses_lock);
	if (!(--count)) {
		ggUnlock(ncurses_lock);
		ggLockDestroy(ncurses_lock);
	} else {
		ggUnlock(ncurses_lock);
	}
}
Пример #2
0
static int GGI_X_flush_draw(struct ggi_visual *vis, 
		     int x, int y, int w, int h, int tryflag)
{
	ggi_x_priv *priv;
	priv = GGIX_PRIV(vis);
	
	if (tryflag == 0) {
		/* flush later, this is in signal handler context
		 * when using the signal based scheduler
		 */
		ggUnlock(priv->flushlock);
		return 0;
	}

	if (tryflag != 2) GGI_X_LOCK_XLIB(vis);

	_ggi_x_flush_cmap(vis);		/* Update the palette/gamma */

	/* Flush any pending Xlib operations. */
	XFlush(priv->disp);

	if (tryflag != 2)
	{
 		GGI_X_UNLOCK_XLIB(vis);
	}

	return 0;
}
Пример #3
0
SCREEN *_terminfo_new_screen(const char *term_type, FILE *out, FILE *in)
{
	SCREEN *_newscr;
	ggLock(ncurses_lock);
        if ( term_type == NULL ) {
                term_type = getenv("TERM");
                if ( term_type == NULL ) {
                        term_type = "vt100";
                }
        }
	{ char *temp;
		temp = (char *)malloc(sizeof(char) * ( strlen(term_type) + 1 ));
		strcpy(temp, term_type);
		_newscr = newterm(temp, out, in);
		free(temp);
	}
	if ( _newscr == NULL ) {
		ggUnlock(ncurses_lock);
	} else {
		ncurses_screen = _newscr;
		set_term(_newscr);
		start_color();
		cbreak();
		noecho();
		nonl();
		timeout(0);
		meta(stdscr, TRUE);
		keypad(stdscr, TRUE);
	}
	return _newscr;
}
Пример #4
0
int GGI_palemu_flush(struct ggi_visual *vis, int x, int y, int w, int h, int tryflag)
{
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	int err;

	MANSYNC_ignore(vis);

	ggLock(priv->flush_lock);

	if (priv->target == PALEMU_TARGET) {
		err = _ggi_palemu_Flush(vis);
	} else {
		err = _ggi_monotext_Flush(vis);
	}

	if (! err) {
		err = _ggiInternFlush(GGI_VISUAL(priv->parent), x, y, w, h, tryflag);
	}

	ggUnlock(priv->flush_lock);

	MANSYNC_cont(vis);

	return err;
}
Пример #5
0
void _terminfo_destroy_screen(void)
{
	endwin();
	delscreen(ncurses_screen);
	ncurses_screen = NULL;
	ggUnlock(ncurses_lock);
}
Пример #6
0
static int do_cleanup(struct ggi_visual *vis)
{
        ggi_libkgi_priv *priv = LIBKGI_PRIV(vis);

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

        DPRINT("display-libkgi: GGIdlcleanup start.\n");

        if (LIBGGI_FD(vis) >= 0) close(LIBGGI_FD(vis));

        if (vis->input != NULL) {
                giiClose(vis->input);
                vis->input = NULL;
        }

	free(priv);
        LIBKGI_PRIV(vis) = NULL;

        ggUnregisterCleanup((ggcleanup_func *)do_cleanup, vis);

        ggLock(_ggi_global_lock);
        refcount--;
        refcount--;
        if (refcount == 0) {
                ggLockDestroy(_ggi_libkgi_lock);
                _ggi_libkgi_lock = NULL;
        }
        ggUnlock(_ggi_global_lock);

        DPRINT("display-libkgi: GGIdlcleanup done.\n");

        return 0;
}
Пример #7
0
static void testcase1(const char *desc)
{
	void *lock;
	int result;
	
	printteststart(__FILE__, __PRETTY_FUNCTION__, EXPECTED2PASS, desc);
	if (dontrun) return;

	lock = ggLockCreate();
	if(lock == NULL) {
		printfailure("Failed to create lock.");
		return;
	}

	ggLock(lock);

	result = ggTryLock(lock);
	if(result == 0) {
		printfailure("Lock should have been locked already.");
		return;
	}
	printassert(result == GGI_EBUSY, "Lock not busy. result: %i\n", result);

	ggUnlock(lock);

	result = ggTryLock(lock);
	printassert(result != GGI_EBUSY, "Lock shouldn't be busy. result: %i\n", result);
	if (result != 0) {
		printfailure("Locking failed.\n"
			"expected result: 0\n"
			"actual result: %i\n", result);
		return;
	}

	ggUnlock(lock);
	result = ggLockDestroy(lock);
	if(result != 0) {
		printfailure("Failed to destroy lock.");
		return;
	}

	printsuccess();
	return;
}
Пример #8
0
void _terminfo_init_ncurses(void)
{
	if (!(count++)) { /* FIXME !!! race condition */
		ncurses_lock = ggLockCreate();
		ggLock(ncurses_lock);
		ncurses_screen = NULL;
		ggUnlock(ncurses_lock);
	} else {
		ggLock(ncurses_lock);
	}
}
Пример #9
0
int GGI_trueemu_flush(struct ggi_visual *vis, int x, int y, int w, int h, int tryflag)
{
	ggi_trueemu_priv *priv = TRUEEMU_PRIV(vis);
	
	int err;

	MANSYNC_ignore(vis);

	ggLock(priv->flush_lock);

	err = _ggi_trueemu_Flush(vis);

	if (! err) {
		err = _ggiInternFlush(GGI_VISUAL(priv->parent), x, y, w, h, tryflag);
	}

	ggUnlock(priv->flush_lock);

	MANSYNC_cont(vis);

	return err;
}
Пример #10
0
int GGI_X_flush_ximage_child(struct ggi_visual *vis, 
			     int x, int y, int w, int h, int tryflag)
{
	ggi_x_priv *priv;
	int mansync;
	priv = GGIX_PRIV(vis);

	if (tryflag == 0) {
		/* flush later, this is in signal handler context
		 * when using the signal based scheduler
		 */
		ggUnlock(priv->flushlock);
		return 0;
	}

	if (priv->opmansync) MANSYNC_ignore(vis);
	mansync = 1; /* Do we call MANSYNC_cont later? By default, yes. */

	if (tryflag != 2) GGI_X_LOCK_XLIB(vis);

	_ggi_x_flush_cmap(vis);		/* Update the palette/gamma */

	/* Flush any pending Xlib operations. */
	XSync(priv->disp, 0);

	if (priv->fullflush || 
	    (GGI_ACTYPE_WRITE & vis->w_frame->resource->curactype)) {
		/* Flush all requested data */
		if (tryflag != 2) {
			GGI_X_CLEAN(vis, x, y, w, h);
			y = GGI_X_WRITE_Y;
		} /* else it's a non-translated exposure event. */
		XPutImage(priv->disp, priv->drawable, priv->tempgc, priv->ximage, 
			  x, y, x, y, (unsigned)w, (unsigned)h);
		if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) mansync = 0;
	} else {
		/* Just flush the intersection with the dirty region */
 	  	int x2, y2;

		if (priv->dirtytl.x > priv->dirtybr.x) goto clean;
		if (x > priv->dirtybr.x) goto clean;
		if (y > priv->dirtybr.y) goto clean;
		x2 = x + w - 1;
		if (x2 < priv->dirtytl.x) goto clean;
		y2 = y + h - 1;
		if (y2 < priv->dirtytl.y) goto clean;
		if (x < priv->dirtytl.x)  x  = priv->dirtytl.x;
		if (y < priv->dirtytl.y)  y  = priv->dirtytl.y;
		if (x2 > priv->dirtybr.x) x2 = priv->dirtybr.x;
		if (y2 > priv->dirtybr.y) y2 = priv->dirtybr.y;
		w = x2 - x + 1;
		h = y2 - y + 1;
		if ((w <= 0) || (h <= 0)) goto clean;

		XPutImage(priv->disp, priv->drawable, priv->tempgc, priv->ximage, 
			  x, GGI_X_WRITE_Y, x, GGI_X_WRITE_Y,
			  (unsigned)w, (unsigned)h);
		GGI_X_CLEAN(vis, x, y, w, h);
	}

	/* Tell X Server to start blitting */
	XFlush(priv->disp);
 clean:

	if (tryflag != 2) GGI_X_UNLOCK_XLIB(vis);
	if (priv->opmansync && mansync) MANSYNC_cont(vis);
	return 0;
}
Пример #11
0
void _terminfo_release_screen(void)
{
	ggUnlock(ncurses_lock);
}
Пример #12
0
static int GGIopen(struct ggi_visual *vis, struct ggi_dlhandle *dlh,
                        const char *args, void *argptr, uint32_t *dlret)
{
        gg_option options[NUM_OPTS];
        ggi_libkgi_priv *priv;
	int err;

	/* We need LibGAlloc to be initialized.  Seems OK to do so
	 * from inside here. It would be nice to Attach it here too,
	 * but I'm less confident that that would work :-)
	 */
	ggiGAInit();

        DPRINT("display-libkgi: GGIopen start.\n");

        memcpy(options, optlist, sizeof(options));
        if (args) {
                args = ggParseOptions(args, options, NUM_OPTS);
                if (args == NULL) {
                        fprintf(stderr, "display-libkgi: error in "
                                "arguments.\n");
                        return GGI_EARGINVAL;
                }
        }

        LIBKGI_PRIV(vis) = priv = malloc(sizeof(ggi_libkgi_priv));
        if (priv == NULL) {
                return GGI_ENOMEM;
        }

        priv->have_accel = 0;
        priv->accelpriv = NULL;
        priv->flush = NULL;
        priv->idleaccel = NULL;

	snprintf(priv->suggest, sizeof(priv->suggest), "foodrv");

        DPRINT("display-libkgi: Parsing physz options.\n");
	err = _ggi_physz_parse_option(options[OPT_PHYSZ].result, 
			       &(priv->physzflags), &(priv->physz)); 
	if (err != GGI_OK) {
		do_cleanup(vis);
		return err;
	}

#if 0
	/* Don't know how this will pan out */
	err = kgiInit(&priv->ctx, &priv->client_name, &priv->client_version);
	if (err != KGI_EOK) {
		do_cleanup(vis);
		return err;
	}
	LIBGGI_FD(vis) = priv->ctx.mapper.fd;
#endif

        DPRINT("display-libkgi: Setting up locks.\n");
        ggLock(_ggi_global_lock);
        if (refcount == 0) {
                _ggi_libkgi_lock = ggLockCreate();
                if (_ggi_libkgi_lock == NULL) {
                        ggUnlock(_ggi_global_lock);
                        free(priv);
                        return GGI_ENOMEM;
                }
        }
        priv->lock = _ggi_libkgi_lock;
        priv->refcount = &refcount;
        refcount++;
        ggUnlock(_ggi_global_lock);

	priv->galloc_loaded = 0;

	LIBKGI_PRIV(vis) = priv;

        /* Mode management */
        vis->opdisplay->flush     = GGI_libkgi_flush;
	/* kgicommand obselete */
        vis->opdisplay->getapi    = GGI_libkgi_getapi;
        vis->opdisplay->setflags  = GGI_libkgi_setflags;
        vis->opdisplay->idleaccel = GGI_libkgi_idleaccel;
        vis->opdisplay->getmode   = GGI_libkgi_getmode;
        vis->opdisplay->checkmode = GGI_libkgi_checkmode;
        vis->opdisplay->setmode   = GGI_libkgi_setmode;
        vis->opdisplay->sendevent = GGI_libkgi_sendevent;

	/* GC management */
        vis->opgc->gcchanged = GGI_libkgi_gcchanged;

	/* Drawops. We don't supply _nc variants as we only do fully 
	 * implemented renderers.
	 */
	vis->opdraw->setorigin		= GGI_libkgi_setorigin;
	vis->opdraw->setdisplayframe	= GGI_libkgi_setdisplayframe;
        vis->opdraw->setreadframe	= GGI_libkgi_setreadframe;
        vis->opdraw->setwriteframe	= GGI_libkgi_setwriteframe;
        vis->opdraw->fillscreen		= GGI_libkgi_fillscreen;
        vis->opdraw->putc		= GGI_libkgi_putc;
        vis->opdraw->puts		= GGI_libkgi_puts;
        vis->opdraw->getcharsize	= GGI_libkgi_getcharsize;
        vis->opdraw->drawpixel		= GGI_libkgi_drawpixel;
        vis->opdraw->putpixel		= GGI_libkgi_putpixel;
        vis->opdraw->getpixel		= GGI_libkgi_getpixel;
        vis->opdraw->drawline		= GGI_libkgi_drawline;
        vis->opdraw->drawhline		= GGI_libkgi_drawhline;
        vis->opdraw->puthline		= GGI_libkgi_puthline;
        vis->opdraw->gethline		= GGI_libkgi_gethline;
        vis->opdraw->drawvline		= GGI_libkgi_drawvline;
        vis->opdraw->putvline		= GGI_libkgi_putvline;
        vis->opdraw->getvline		= GGI_libkgi_getvline;
        vis->opdraw->drawbox		= GGI_libkgi_drawbox;
        vis->opdraw->putbox		= GGI_libkgi_putbox;
        vis->opdraw->getbox		= GGI_libkgi_getbox;
        vis->opdraw->copybox		= GGI_libkgi_copybox;
        vis->opdraw->crossblit		= GGI_libkgi_crossblit;

	/* Color ops will use generic color libs. */

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

        DPRINT("display-libkgi: GGIopen success.\n");

        *dlret = GGI_DL_OPDISPLAY;
        return 0;
}
Пример #13
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;
}
Пример #14
0
int GGI_X_getvline_draw(ggi_visual *vis, int x, int y, int h, void *data)
{	
	ggi_x_priv *priv;
	XImage *ximg;
	int     (*olderrorhandler) (Display *, XErrorEvent *);
	int ret = 0;
	uint8_t *data8;
	priv = GGIX_PRIV(vis);

        GGI_X_LOCK_XLIB(vis);
	XSync(priv->disp, 0);
	ggLock(_ggi_global_lock);
	geterror = 0;
	olderrorhandler = XSetErrorHandler(errorhandler);
	/* This will cause a BadMatch error when the window is
	   iconified or on another virtual screen... */
	ximg = XGetImage(priv->disp, priv->drawable, x, GGI_X_READ_Y,
			 1, (unsigned)h, AllPlanes, ZPixmap);
	XSync(priv->disp,0);
	XSetErrorHandler(olderrorhandler);

#warning honor various ximage format fields here.
#warning 1,2,4-bit support needed

	if (geterror) {
		ret = -1;
		goto out;
	}

	if (ximg->byte_order == 
#ifdef GGI_LITTLE_ENDIAN
	    LSBFirst
#else
	    MSBFirst
#endif
	    ) goto noswab;
	
	if (ximg->bits_per_pixel == 16) {
		uint8_t *ximgptr;
		data8 = (uint8_t *)data;
		ximgptr = (uint8_t *)(ximg->data) + ximg->xoffset * 2;
		while (h--) {
			*(data8) = *(ximgptr + 1);
			*(data8 + 1) = *(ximgptr);
			ximgptr += ximg->bytes_per_line;
			data8 += 2;
		}
	}
	else if (ximg->bits_per_pixel == 32) {
		uint8_t *ximgptr;
		data8 = (uint8_t *)data;
		ximgptr = (uint8_t *)(ximg->data) + ximg->xoffset * 4;
		while (h--) {
			*(data8) = *(ximgptr + 3);
			*(data8 + 1) = *(ximgptr + 2);
			*(data8 + 2) = *(ximgptr + 1);
			*(data8 + 3) = *(ximgptr);
			ximgptr += ximg->bytes_per_line;
			data8 += 4;
		}
	}
	else {
		uint8_t *ximgptr;

	noswab:

		ximgptr = (uint8_t *)(ximg->data) + 
			(ximg->xoffset * ximg->bits_per_pixel)/8;
		data8 = (uint8_t *)data;
		while (h--) {
			memcpy(data8, ximgptr,
				(unsigned)ximg->bits_per_pixel/8);
			ximgptr += ximg->bytes_per_line;
			data8 += ximg->bits_per_pixel/8;
		}
	}
	XDestroyImage(ximg);
 out:
	ggUnlock(_ggi_global_lock);
	GGI_X_UNLOCK_XLIB(vis);

	return ret;
}