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; }
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; }
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; }
void _terminfo_finalize_ncurses(void) { ggLock(ncurses_lock); if (!(--count)) { ggUnlock(ncurses_lock); ggLockDestroy(ncurses_lock); } else { ggUnlock(ncurses_lock); } }
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; }
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; }
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; }
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; }