示例#1
0
文件: init.c 项目: Nekrofage/DoomRPi
int giiExit(void)
{
	DPRINT_CORE("giiExit() called\n");
	if (!_giiLibIsUp)
		return GGI_ENOTALLOC;
	
	if (_giiLibIsUp > 1) {
		_giiLibIsUp--;
		return _giiLibIsUp;
	}
	
	DPRINT_CORE("giiExit: really destroying.\n");

	_giiExitBuiltins();

	ggFreeConfig(_giiconfhandle);
	ggLockDestroy(_gii_global_lock);
	ggLockDestroy(_gii_safe_lock);
	ggLockDestroy(_gii_event_lock);

	/* Set them back to initialization value.
	 * Otherwise this leads to a memory corruption bug,
	 * when gii is initialized again in the same application.
	 */
	_giiconfhandle = NULL;
	_gii_global_lock = NULL;
	_gii_safe_lock = NULL;
	_gii_event_lock = NULL;

	ggExit();
	_giiLibIsUp=0;
	
	DPRINT_CORE("giiExit: done!\n");
	return 0;
}
示例#2
0
文件: visual.c 项目: antrik/libggi
static int GGIclose_monotext(struct ggi_visual *vis, struct ggi_dlhandle *dlh)
{
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);
	struct gg_api *api;

	DPRINT("display-monotext: GGIclose start.\n");

	if (priv->fb_ptr != NULL) {
		_ggi_monotext_Close(vis);
		free(priv->fb_ptr);
	}

	if (priv->parent != NULL) {
		ggiClose(priv->parent);
		ggiDetach(priv->parent);
		/* XXX What if gii has been detached before close? */
		api = ggGetAPIByName("gii");
		if (api && STEM_HAS_API(priv->parent, api)) {
			ggDetach(api, priv->parent);
		}
		ggDelStem(priv->parent);
		priv->parent = NULL;
	}

	ggLockDestroy(priv->flush_lock);
	free(priv->opmansync);
	free(priv);
	free(LIBGGI_GC(vis));

	DPRINT("display-monotext: GGIclose done.\n");

	return 0;
}
示例#3
0
文件: visual.c 项目: antrik/libggi
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;
}
示例#4
0
文件: ncurses.c 项目: antrik/libggi
void _terminfo_finalize_ncurses(void)
{
	ggLock(ncurses_lock);
	if (!(--count)) {
		ggUnlock(ncurses_lock);
		ggLockDestroy(ncurses_lock);
	} else {
		ggUnlock(ncurses_lock);
	}
}
示例#5
0
文件: lock.c 项目: Nekrofage/DoomRPi
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;
}
示例#6
0
文件: visual.c 项目: antrik/libggi
static int GGIopen_monotext(struct ggi_visual *vis, struct ggi_dlhandle *dlh,
				const char *args, void *argptr, uint32_t *dlret)
{
	ggi_palemu_priv *priv;
	gg_option options[MONOTEXT_NUM_OPTS];
	char target[1024];
	struct gg_api *api;
	struct gg_observer *obs = NULL;
	int val;
	int err = 0;

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

	memcpy(options, monotext_optlist, sizeof(options));
	if (args) {
		args = ggParseOptions(args, options, MONOTEXT_NUM_OPTS);
		if (args == NULL) {
			fprintf(stderr,
				"display-monotext: error in arguments\n");
			return GGI_EARGINVAL;
		}
	}

	/* open the parent visual */
	DPRINT("display-monotext: opening target: %s\n", args);

	if (args != NULL) {
		if (ggParseTarget(args, target, sizeof(target)) == NULL) {
			/* error occured */
			return GGI_EARGINVAL;
		}
	}

	/* Find out the parent target */
	while (args && *args && isspace((uint8_t)*args)) {
		args++;
	}

	*target = '\0';
	if (args) {
		if (ggParseTarget(args, target, sizeof(target)) == NULL) {
			return GGI_EARGINVAL;
		}
	}

	if (*target == '\0') {
		strcpy(target, "auto");
	}

	LIBGGI_GC(vis) = malloc(sizeof(ggi_gc));
	if (LIBGGI_GC(vis) == NULL) {
		err = GGI_ENOMEM;
		goto err0;
	}
	LIBGGI_PRIVATE(vis) = priv = malloc(sizeof(ggi_palemu_priv));
	if (priv == NULL) {
		err = GGI_ENOMEM;
		goto err1;
	}

	priv->flush_lock = ggLockCreate();
	if (priv->flush_lock == NULL) {
		err = GGI_ENOMEM;
		goto err2;
	}
	priv->opmansync = malloc(sizeof(_ggi_opmansync));
	if (priv->opmansync == NULL) {
		err = GGI_ENOMEM;
		goto err3;
	}

	priv->flags = 0;
	priv->fb_ptr = NULL;
	priv->target = MONOTEXT_TARGET;


	DPRINT("display-monotext: opening target: %s\n", target);
	priv->parent = ggNewStem(NULL);
	if (priv->parent == NULL) {
		fprintf(stderr,
			"display-monotext: Failed to create stem for target: %s\n",
			target);
		err = GGI_ENODEVICE;
		goto err3;
	}

	/* XXX Should iterate over the apis attached to vis->instance.stem
	 * instead of only looking for ggi and gii.
	 */
	if (ggiAttach(priv->parent) < 0) {
		ggDelStem(priv->parent);
		priv->parent = NULL;
		fprintf(stderr,
			"display-monotext: Failed to attach ggi to stem for target: %s\n",
			target);
		err = GGI_ENODEVICE;
		goto err4;
	}

	api = ggGetAPIByName("gii");
	if (api != NULL) {
		/* XXX This should probably be done in pseudo-stubs-gii */
		if (STEM_HAS_API(vis->instance.stem, api)) {
			if (ggAttach(api, priv->parent) < 0) {
				ggDelStem(priv->parent);
				priv->parent = NULL;
				fprintf(stderr,
					"Failed to attach gii to stem for target: %s\n",
					target);
				err = GGI_ENODEVICE;
				goto err4;
			}
			obs = ggObserve(GG_STEM_API_CHANNEL(priv->parent, api),
					transfer_gii_src, vis->instance.stem);
		}
	}

	if (ggiOpen(priv->parent, target, NULL) < 0) {
		if (obs) {
			ggDelObserver(obs);
			obs = NULL;
		}
		fprintf(stderr,
			"display-monotext: Failed to open target: '%s'\n",
			target);
		ggDelStem(priv->parent);
		priv->parent = NULL;
		err = GGI_ENODEVICE;
		goto err4;
	}
	if (obs) {
		ggDelObserver(obs);
		obs = NULL;
	}

	ggiSetFlags(priv->parent, GGIFLAG_ASYNC);


	/* set defaults */
	priv->parent_defmode.graphtype = GT_TEXT16;
	priv->flags = 0;
	priv->squish.x = priv->squish.y = 1;

	val = strtol(options[OPT_A].result, NULL, 0);	
	if (val != 0) {
		priv->accuracy.x = priv->accuracy.y = val;
	} else {
		priv->accuracy.x = strtol(options[OPT_X].result, NULL, 0);
		priv->accuracy.y = strtol(options[OPT_Y].result, NULL, 0);
	}

	/* Setup mansync */
	MANSYNC_open(vis, priv);
	if (priv->mod_mansync == NULL) {
		fprintf(stderr,
			"display-monotext: Cannot load helper-mansync!\n");
		GGIclose_monotext(vis, dlh);
		goto err4;
	}

	MANSYNC_init(vis);
	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) {
		MANSYNC_start(vis);
	}

	/* Has mode management */
	vis->opdisplay->getmode   = GGI_palemu_getmode;
	vis->opdisplay->setmode   = GGI_palemu_setmode;
	vis->opdisplay->checkmode = GGI_monotext_checkmode;
	vis->opdisplay->getapi    = GGI_palemu_getapi;
	vis->opdisplay->flush     = GGI_palemu_flush;
	vis->opdisplay->setflags  = GGI_palemu_setflags;

	DPRINT("display-monotext: GGIopen succeeded.\n");

	*dlret = GGI_DL_OPDISPLAY;
	return 0;

err4:
	free(priv->opmansync);
err3:
	ggLockDestroy(priv->flush_lock);
err2:
	free(priv);
err1:
	free(LIBGGI_GC(vis));
err0:
	return err;
}
示例#7
0
文件: visual.c 项目: antrik/libggi
static int GGIopen_palemu(struct ggi_visual *vis, struct ggi_dlhandle *dlh,
		   const char *args, void *argptr, uint32_t *dlret)
{
	ggi_palemu_priv *priv;
	gg_option options[PALEMU_NUM_OPTS];
	char target[1024];
	int err = GGI_ENOMEM;
	struct gg_api *api;
	struct gg_observer *obs = NULL;

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

	/* handle arguments */
	memcpy(options, palemu_optlist, sizeof(options));
	if (args) {
		args = ggParseOptions(args, options, PALEMU_NUM_OPTS);

		if (args == NULL) {
			fprintf(stderr,
				"display-palemu: error in arguments.\n");
			return GGI_EARGINVAL;
		}
	}
	if (getenv("GGI_PALEMU_OPTIONS") != NULL) {
		if (ggParseOptions(getenv("GGI_PALEMU_OPTIONS"), options,
				   PALEMU_NUM_OPTS) == NULL) {
			fprintf(stderr, "display-palemu: error in ""$GGI_PALEMU_OPTIONS.\n");
			return GGI_EARGINVAL;
		}
	}

	/* Find out the parent target. */
	while (args && *args && isspace((uint8_t)*args)) {
		args++;
	}

	*target = '\0';
	if (args) {
		if (ggParseTarget(args, target, 1024) == NULL) {
			return GGI_EARGINVAL;
		}
	}
	if (*target == '\0') {
		strcpy(target, "auto");
	}

	LIBGGI_GC(vis) = malloc(sizeof(ggi_gc));
	if (LIBGGI_GC(vis) == NULL) {
		return GGI_ENOMEM;
	}
	LIBGGI_PRIVATE(vis) = priv = malloc(sizeof(*priv));
	if (priv == NULL) {
		goto out_freegc;
	}
	priv->flush_lock = ggLockCreate();
	if (priv->flush_lock == NULL) {
		goto out_freepriv;
	}
	priv->opmansync = malloc(sizeof(_ggi_opmansync));
	if (priv->opmansync == NULL) {
		goto out_freelock;
	}

	priv->flags  = 0;
	priv->fb_ptr = NULL;
	priv->target = PALEMU_TARGET;

	DPRINT("display-palemu: parent mode is '%s'\n",
		  options[OPT_PARENT].result);
	ggiParseMode(options[OPT_PARENT].result, &priv->parent_defmode);

	DPRINT("display-palemu: opening target: %s\n", target);
	priv->parent = ggNewStem(NULL);
	if (priv->parent == NULL) {
		fprintf(stderr,
			"display-palemu: Failed to create stem for target: '%s'\n",
			target);
		err = GGI_ENODEVICE;
		goto out_freeopmansync;
	}
	/* FIXME! Should iterate over the apis attached to vis->instance.stem
	 * instead of only looking for ggi and gii.
	 */
	if (ggiAttach(priv->parent) < 0) {
		ggDelStem(priv->parent);
		priv->parent = NULL;
		fprintf(stderr,
			"display-palemu: Failed to attach ggi to stem for target: '%s'\n",
			target);
		err = GGI_ENODEVICE;
		goto out_freeopmansync;
	}
	if ((api = ggGetAPIByName("gii")) != NULL) {
		/* FIXME! This should probably be done in pseudo-stubs-gii */
		if (STEM_HAS_API(vis->instance.stem, api)) {
			if (ggAttach(api, priv->parent) < 0) {
				ggDelStem(priv->parent);
				priv->parent = NULL;
				fprintf(stderr,
					"display-palemu: Failed to attach gii to stem for target: '%s'\n",
					target);
				err = GGI_ENODEVICE;
				goto out_freeopmansync;
			}
			obs = ggObserve(GG_STEM_API_CHANNEL(priv->parent, api),
			    transfer_gii_src, vis->instance.stem);
		}
	}
	if (ggiOpen(priv->parent, target, NULL) < 0) {
		if (obs) {
			ggDelObserver(obs);
			obs = NULL;
		}
		fprintf(stderr,
			"display-palemu: Failed to open target: '%s'\n",
			target);
		ggDelStem(priv->parent);
		priv->parent = NULL;
		err = GGI_ENODEVICE;
		goto out_freeopmansync;
	}
	if (obs) {
		ggDelObserver(obs);
		obs = NULL;
	}

	ggiSetFlags(priv->parent, GGIFLAG_ASYNC);

	/* Setup mansync */
	MANSYNC_open(vis, priv);
	if (priv->mod_mansync == NULL) {
		fprintf(stderr,
			"display-palemu: Cannot load helper-mansync!\n");
		GGIclose_palemu(vis, dlh);
		return err;
	}

	MANSYNC_init(vis);
	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) {
		MANSYNC_start(vis);
	}

	/* Has mode management */
	vis->opdisplay->getmode = GGI_palemu_getmode;
	vis->opdisplay->setmode = GGI_palemu_setmode;
	vis->opdisplay->checkmode = GGI_palemu_checkmode;
	vis->opdisplay->getapi = GGI_palemu_getapi;
	vis->opdisplay->flush = GGI_palemu_flush;
	vis->opdisplay->setflags = GGI_palemu_setflags;

	DPRINT("display-palemu: GGIopen succeeded.\n");

	*dlret = GGI_DL_OPDISPLAY;
	return 0;

  out_freelock:
	ggLockDestroy(priv->flush_lock);
  out_freeopmansync:
	free(priv->opmansync);
  out_freepriv:
	free(priv);
  out_freegc:
	free(LIBGGI_GC(vis));

	return err;
}
示例#8
0
文件: init.c 项目: Nekrofage/DoomRPi
int giiInit(void)
{
	int err;
	const char *str;
	char *conffile;
	
	if (_giiLibIsUp>0) {
		/* Initialize only at first call. */
		_giiLibIsUp++;
		return 0;
	}

	err = ggInit();
	if (err != GGI_OK) {
		fprintf(stderr, "LibGII: unable to initialize LibGG\n");
		return err;
	}

	err = GGI_ENOMEM;
	if ((_gii_event_lock = ggLockCreate()) == NULL) {
		fprintf(stderr,"LibGII: unable to initialize event mutex.\n");
		goto out_ggexit;
	}

	if ((_gii_safe_lock = ggLockCreate()) == NULL) {
		fprintf(stderr,"LibGII: unable to initialize safe mutex.\n");
		goto out_destroy_event;
	}

	if ((_gii_global_lock = ggLockCreate()) == NULL) {
		fprintf(stderr,"LibGII: unable to initialize global mutex.\n");
		goto out_destroy_safe;
	}

	conffile = malloc(strlen(giiGetConfDir()) + 1
			  + strlen(GIICONFFILE) +1);
	if (conffile == NULL) {
		fprintf(stderr,"LibGII: unable to allocate memory for config filename.\n");
		goto out_destroy_global;
	}
	snprintf(conffile, strlen(giiGetConfDir()) + strlen(GIICONFFILE) + 2,
		"%s%c%s", giiGetConfDir(), CHAR_DIRDELIM, GIICONFFILE);
	if(ggLoadConfig(conffile, &_giiconfhandle)) {
		fprintf(stderr, "LibGII: fatal error - could not load %s\n",
			conffile);
		free(conffile);
		goto out_destroy_global;
	}
	free(conffile);
	
	str = getenv("GII_DEBUGSYNC");
	if (str != NULL) {
		_giiDebug |= DEBUG_SYNC;
	}
	
	str = getenv("GII_DEBUG");
	if (str != NULL) {
		_giiDebug |= atoi(str) & DEBUG_ALL;
		DPRINT_CORE("%s Debugging=%d\n",
			    DEBUG_ISSYNC ? "sync" : "async",
			    _giiDebug);
	}

	_giiInitBuiltins();

	_giiLibIsUp++;
	
	return 0;

  out_destroy_global:
	ggLockDestroy(_gii_global_lock);
  out_destroy_safe:
	ggLockDestroy(_gii_safe_lock);
  out_destroy_event:
	ggLockDestroy(_gii_event_lock);
  out_ggexit:
	ggExit();

	return err;
}