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; }
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(ggi_visual * vis, struct ggi_dlhandle *dlh, const char *args, void *argptr, uint32_t * dlret) { int err = GGI_OK; directx_priv *priv; GGIGII ggigii; gg_option options[NUM_OPTS]; DPRINT("DirectX-target starting\n"); memcpy(options, optlist, sizeof(options)); priv = malloc(sizeof(directx_priv)); if (priv == NULL) { err = GGI_ENOMEM; goto err0; } if ((LIBGGI_GC(vis) = malloc(sizeof(ggi_gc))) == NULL) { err = GGI_ENOMEM; goto err1; } memset(priv, 0, sizeof(directx_priv)); LIBGGI_PRIVATE(vis) = priv; priv->cs = GGI_directx_LockCreate(); if (priv->cs == NULL) { err = GGI_ENOMEM; goto err2; } priv->spincs = GGI_directx_LockCreate(); if (priv->spincs == NULL) { err = GGI_ENOMEM; goto err3; } priv->redraw = 1; priv->setpalette = 1; priv->sizingcs = GGI_directx_LockCreate(); if (priv->sizingcs == NULL) { err = GGI_ENOMEM; goto err4; } priv->xmin = 0; priv->ymin = 0; priv->xmax = 0; priv->ymax = 0; priv->xstep = -1; priv->ystep = -1; if (args) { args = ggParseOptions(args, options, NUM_OPTS); if (args == NULL) { fprintf(stderr, "display-directx: error in " "arguments.\n"); } } if (_ggi_physz_parse_option(options[OPT_PHYSZ].result, &(priv->physzflags), &(priv->physz))) { err = GGI_EARGINVAL; goto err5; } if (options[OPT_KEEPCURSOR].result[0] == 'n') { priv->cursortype = (options[OPT_NOCURSOR].result[0] == 'n') ? 1 : 0; } else { priv->cursortype = 2; } if (options[OPT_INWIN].result[0] != 'n') { if (strcmp(options[OPT_INWIN].result, "root")) { priv->hParent = (HANDLE) strtoul(options[OPT_INWIN].result, NULL, 0); if (!IsWindow(priv->hParent)) { fprintf(stderr, "0x%08x " "is not a valid window handle.\n", (unsigned) priv->hParent); priv->hParent = NULL; } } else priv->hParent = GetDesktopWindow(); } if (options[OPT_FULLSCREEN].result[0] == 'n') { priv->fullscreen = 0; } else { priv->fullscreen = 1; } if (!DDInit(vis)) { err = GGI_ENODEVICE; goto err3; } ggigii.hWnd = priv->hWnd; ggigii.hInstance = priv->hInstance; if (tolower((uint8_t) options[OPT_NOINPUT].result[0]) == 'n' && /* FIXME: dxinput doesn't work with -inwin yet; the following condition disables the default input target if -inwin has been specified */ (!priv->hParent || getenv("GGI_INPUT") || getenv("GGI_INPUT_directx"))) { gii_input *inp; inp = giiOpen("directx", &ggigii, NULL); if (inp == NULL) { DPRINT_MISC("Unable to open directx inputlib\n"); GGIclose(vis, dlh); err = GGI_ENODEVICE; goto err3; } priv->inp = inp; /* Now join the new event source in. */ vis->input = giiJoinInputs(vis->input, inp); } else { priv->inp = NULL; } vis->opdisplay->setmode = GGI_directx_setmode; vis->opdisplay->getmode = GGI_directx_getmode; vis->opdisplay->setflags = GGI_directx_setflags; vis->opdisplay->checkmode = GGI_directx_checkmode; vis->opdisplay->flush = GGI_directx_flush; vis->opdisplay->getapi = GGI_directx_getapi; *dlret = GGI_DL_OPDISPLAY | GGI_DL_OPDRAW; return GGI_OK; err5: GGI_directx_LockDestroy(priv->cs); err4: GGI_directx_LockDestroy(priv->spincs); err3: GGI_directx_LockDestroy(priv->sizingcs); err2: free(LIBGGI_GC(vis)); err1: free(priv); err0: return err; }
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; }
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh, const char *args, void *argptr, uint32_t *dlret) { struct TIhooks *priv; gg_option options[NUM_OPTS]; char *term_type; char *term_path; int i, err; memcpy(options, optlist, sizeof(options)); if (args != NULL) { args = ggParseOptions(args, options, NUM_OPTS); if (args == NULL) { fprintf(stderr, "display-x: error in arguments.\n"); return GGI_EARGINVAL; } } term_path = options[OPT_PATH].result; term_type = options[OPT_TERM].result; if ((*term_type) == '\0') term_type = NULL; DPRINT("display-terminfo: initializing %s on %s.\n", term_type, ( ( *term_path == '\0' ) ? "stdin/stdout" : term_path )); priv = (struct TIhooks *)malloc(sizeof(struct TIhooks)); if (priv == NULL) return GGI_ENOMEM; LIBGGI_PRIVATE(vis) = priv; err = _ggi_physz_parse_option(options[OPT_PHYSZ].result, &(priv->physzflags), &(priv->physz)); if (err != GGI_OK) { free(priv); return err; } LIBGGI_GC(vis) = malloc(sizeof(ggi_gc)); if (LIBGGI_GC(vis) == NULL) { free(priv); return GGI_ENOMEM; } priv->splitline = 0; priv->virgin = 1; if ( *term_path == '\0' ) { priv->f_in = fdopen(dup(fileno(stdin)), "r"); priv->f_out = fdopen(dup(fileno(stdout)), "w"); } else { priv->f_in = priv->f_out = fopen(term_path, "rw"); } _terminfo_init_ncurses(); priv->scr = _terminfo_new_screen(term_type, priv->f_out, priv->f_in); if (priv->scr == NULL) { fprintf(stderr, "display-terminfo: error creating ncurses" " SCREEN\n"); fclose(priv->f_in); fclose(priv->f_out); free(LIBGGI_GC(vis)); free(priv); return GGI_ENODEVICE; } LIBGGI_FD(vis) = fileno(priv->f_out); if ( has_colors() ) { static const int vga_color[8] = { COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE }; int j; DPRINT("display-terminfo: terminal supports %d colors\n", COLORS); DPRINT("display-terminfo: initializing %d - 1 color pairs\n", COLOR_PAIRS); for ( i = 1 ; i < COLOR_PAIRS ; i++ ) { if ( init_pair(i, COLORS - ( i % COLORS ) - 1, i / COLORS) == ERR ) { DPRINT("display-terminfo: error initializing color pair %d to %d,%d\n", i, COLORS - ( i % COLORS ) - 1, i / COLORS); fprintf(stderr, "display-terminfo: error initializing colors\n"); break; } } for ( i = 0 ; i < 16 ; i++ ) { for ( j = 0 ; j < 16 ; j++ ) { priv->color16_table[i+(j<<4)] = COLOR_PAIR(((COLORS-vga_color[i&0x07]%COLORS-1) +(vga_color[j&0x07]%COLORS*COLORS))%COLOR_PAIRS) | ( ( i > 7 ) ? A_BOLD : A_NORMAL ) | ( ( j > 7 ) ? A_BLINK : A_NORMAL ); } } } else { DPRINT("display-terminfo: terminal lacks color support\n"); } construct_charmap(priv->charmap); #if ( NCURSES_MOUSE_VERSION == 1 ) DPRINT("display-terminfo: mouse support is enabled\n"); mousemask(REPORT_MOUSE_POSITION | BUTTON1_PRESSED | BUTTON1_RELEASED | BUTTON2_PRESSED | BUTTON2_RELEASED | BUTTON3_PRESSED | BUTTON3_RELEASED | BUTTON4_PRESSED | BUTTON4_RELEASED, NULL); #else DPRINT("display-terminfo: mouse support is disabled\n"); #endif /* mode management */ vis->opdisplay->flush = GGI_terminfo_flush; vis->opdisplay->getmode = GGI_terminfo_getmode; vis->opdisplay->setmode = GGI_terminfo_setmode; vis->opdisplay->checkmode = GGI_terminfo_checkmode; vis->opdisplay->getapi = GGI_terminfo_getapi; vis->opdisplay->setflags = GGI_terminfo_setflags; /* event management */ { gii_input *inp; inp = _giiInputAlloc(); if (inp == NULL) { fprintf(stderr, "display-terminfo: error allocating gii_input\n"); _terminfo_destroy_screen(); fclose(priv->f_in); fclose(priv->f_out); free(LIBGGI_GC(vis)); free(priv); return GGI_ENOMEM; } #if ( NCURSES_MOUSE_VERSION == 1 ) inp->targetcan =emKey | emPtrButton | emPtrAbsolute, #else inp->targetcan =emKey, /* without mouse support */ #endif inp->GIIseteventmask(inp,inp->targetcan); inp->GIIeventpoll = GII_terminfo_eventpoll; inp->GIIsendevent = GII_terminfo_sendevent; priv->vis = vis; inp->priv = (void *)priv; inp->maxfd=0; /* This is polled. */ inp->flags|=GII_FLAGS_HASPOLLED; vis->input = giiJoinInputs(vis->input, inp); } _terminfo_release_screen(); *dlret = GGI_DL_OPDISPLAY; return 0; }
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh, const char *args, void *argptr, uint32_t *dlret) { ggi_ipc_priv *priv; gg_option options[NUM_OPTS]; struct sockaddr_un address; DPRINT_MISC("display-ipc coming up.\n"); memcpy(options, optlist, sizeof(options)); LIBGGI_GC(vis) = malloc(sizeof(ggi_gc)); if (!LIBGGI_GC(vis)) return GGI_ENOMEM; /* Allocate descriptor for screen memory */ priv = malloc(sizeof(ggi_ipc_priv)); if (!priv) { free(LIBGGI_GC(vis)); return GGI_ENOMEM; } /* if */ LIBGGI_PRIVATE(vis) = priv; priv->inputbuffer = NULL; /* Default to no input */ priv->inputoffset = 0; /* Setup offset. */ if (!args) { DPRINT("display-ipc: required arguments missing\n"); return GGI_EARGREQ; } /* if */ args = ggParseOptions(args, options, NUM_OPTS); if (args == NULL) { DPRINT("display-ipc: error in arguments.\n"); return GGI_EARGREQ; } /* if */ if (_ggi_physz_parse_option(options[OPT_PHYSZ].result, &(priv->physzflags), &(priv->physz))) { free(priv); free(LIBGGI_GC(vis)); return GGI_EARGINVAL; } /* if */ if (!options[OPT_SOCKET].result[0] && !options[OPT_SEMID].result[0] && !options[OPT_SHMID].result[0]) { DPRINT("display-ipc: required arguments missing\n"); return GGI_EARGREQ; } /* if */ if (!(sscanf(options[OPT_SOCKET].result,"%s", address.sun_path) && sscanf(options[OPT_SEMID].result,"%d", &(priv->semid)) && sscanf(options[OPT_SHMID].result,"%d", &(priv->shmid)))) { DPRINT("display-ipc: argument format error\n"); return GGI_EARGREQ; } /* if */ DPRINT("display-ipc parsed args: socket: %s semid: %d shmid: %d\n", address.sun_path, priv->semid, priv->shmid); address.sun_family = AF_UNIX; if ((priv->sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1 || connect(priv->sockfd, (const struct sockaddr *)(&address), sizeof(struct sockaddr_un)) == -1 || (priv->memptr = (char *)shmat(priv->shmid, 0, 0)) == (char *)-1) { DPRINT("display-ipc initialization failed : %s\n", strerror(errno)); return GGI_ENODEVICE; } /* if */ if (options[OPT_INPUT].result[0]) { priv->inputbuffer=priv->memptr; priv->memptr=(char *)priv->memptr+INPBUFSIZE; DPRINT("display-ipc: moved mem to %p for input-buffer.\n", priv->memptr); } /* if */ vis->opdisplay->flush = GGI_ipc_flush; vis->opdisplay->getmode = GGI_ipc_getmode; vis->opdisplay->setmode = GGI_ipc_setmode; vis->opdisplay->getapi = GGI_ipc_getapi; vis->opdisplay->checkmode = GGI_ipc_checkmode; vis->opdisplay->setflags = GGI_ipc_setflags; if (priv->inputbuffer) { gii_input *inp; priv->inputbuffer->visx = priv->inputbuffer->visy = priv->inputbuffer->virtx = priv->inputbuffer->virty = priv->inputbuffer->frames = priv->inputbuffer->visframe = 0; DPRINT_MISC("Adding gii to shmem-memtarget\n"); /* First allocate a new gii_input descriptor. */ if (NULL==(inp=_giiInputAlloc())) { DPRINT_MISC("giiInputAlloc failure.\n"); goto out; } /* if */ DPRINT_MISC("gii inp=%p\n",inp); /* Now fill in the blanks. */ inp->priv = priv; /* We need that in poll() */ priv->inputbuffer->writeoffset = 0; /* Not too good, but ... */ inp->targetcan= emAll; inp->GIIseteventmask(inp,inp->targetcan); inp->maxfd = 0; /* This is polled. */ inp->flags |= GII_FLAGS_HASPOLLED; inp->GIIeventpoll = GII_ipc_poll; inp->GIIsendevent = GII_ipc_send; /* Now join the new event source in. */ vis->input=giiJoinInputs(vis->input,inp); out: while(0){}; } /* if */ *dlret = GGI_DL_OPDISPLAY; return 0; } /* GGIopen */
static int GGIopen(struct ggi_visual *vis, struct ggi_dlhandle *dlh, const char *args, void *argptr, uint32_t *dlret) { ggi_memory_priv *priv; gg_option options[NUM_OPTS]; int err = 0; DPRINT_MISC("GGIopen: coming up.\n"); memcpy(options, optlist, sizeof(options)); LIBGGI_GC(vis) = malloc(sizeof(ggi_gc)); if (!LIBGGI_GC(vis)) return GGI_ENOMEM; /* Allocate descriptor for screen memory */ priv = calloc(1, sizeof(ggi_memory_priv)); if (!priv) { err = GGI_ENOMEM; goto err0; } LIBGGI_PRIVATE(vis) = priv; priv->inp = NULL; priv->memtype = MT_MALLOC; /* Default to mallocing. */ priv->inputbuffer = NULL; /* Default to no input */ if (args) { args = ggParseOptions(args, options, NUM_OPTS); if (args == NULL) { fprintf(stderr, "display-memory: error in " "arguments.\n"); } } if (_ggi_physz_parse_option(options[OPT_PHYSZ].result, &(priv->physzflags), &(priv->physz))) { err = GGI_EARGINVAL; goto err1; } if (args && *args) { /* We have parameters. Analyze them. */ DPRINT("has args: \"%s\"\n", args); #ifdef _GG_HAVE_SHM if (strncmp(args, "shmid:", 6) == 0) { sscanf(args + 6, "%i", &(priv->shmid)); DPRINT("has shmid-arg: %d.\n", priv->shmid); priv->memptr = shmat(priv->shmid, NULL, 0); DPRINT("shmat at %p.\n", priv->memptr); if (priv->memptr != (void *)-1) { priv->memtype = MT_SHMID; if (options[OPT_INPUT].result[0]) { priv->inputbuffer = priv->memptr; priv->memptr = (char *)priv->memptr + INPBUFSIZE; DPRINT("moved mem to %p for input-buffer.\n", priv->memptr); } } } else if (strncmp(args, "keyfile:", 8) == 0) { unsigned int size; char id; char filename[1024]; sscanf(args + 8, "%u:%c:%s", &size, &id, filename); DPRINT("has keyfile-arg:%d:%c:%s.\n", size, id, filename); priv->shmid = shmget(ftok(filename,id), size, IPC_CREAT|0666); DPRINT("has shmid:%d.\n", priv->shmid); priv->memptr = shmat(priv->shmid,NULL,0); DPRINT("shmat at %p.\n", priv->memptr); if (priv->memptr != (void *)-1) { priv->memtype = MT_SHMID; if (options[OPT_INPUT].result[0]) { priv->inputbuffer = priv->memptr; priv->memptr = (char *)priv->memptr + INPBUFSIZE; DPRINT("moved mem to %p for input-buffer.\n", priv->memptr); } } } else #endif /* _GG_HAVE_SHM */ if (strncmp(args, "pointer", 7) == 0) { priv->memptr = argptr; if (priv->memptr) { priv->memtype = MT_EXTERN; } } } /* Explicit pixelformat. */ if (options[OPT_PIXFMT].result[0]) { _ggi_parse_pixfmtstr(options[OPT_PIXFMT].result, '\0', NULL, strlen(options[OPT_PIXFMT].result)+1, &priv->r_mask, &priv->g_mask, &priv->b_mask, &priv->a_mask, &priv->pixfmt_flags); } /* Explicit layout for preallocated buffers with nontrivial layouts. */ if (options[OPT_LAYOUT].result[0] != 'n') { char *idx; priv->fstride = strtoul(options[OPT_LAYOUT].result, &idx, 10); if (strncmp(idx, "plb", 3) == 0) { priv->layout = blPixelLinearBuffer; idx += 3; priv->buffer.plb.stride = strtoul(idx, NULL, 10); } else if (strncmp(idx, "plan", 4) == 0) { priv->layout = blPixelPlanarBuffer; idx += 4; priv->buffer.plan.next_plane = strtoul(idx, &idx, 10); if (*idx != ',') { priv->buffer.plan.next_line = 0; } else { idx++; priv->buffer.plan.next_line = strtoul(idx, &idx, 10); } } else { if (*idx != '\0') fprintf(stderr, "bad layout params\n"); priv->layout = blPixelLinearBuffer; priv->buffer.plb.stride = 0; } } /* Do not blank the framebuffer on SetMode. * (Preserves data in prealloced memory area.) */ priv->noblank = (options[OPT_NOBLANK].result[0] != 'n'); vis->opdisplay->flush = GGI_memory_flush; vis->opdisplay->getmode = GGI_memory_getmode; vis->opdisplay->setmode = GGI_memory_setmode; vis->opdisplay->getapi = GGI_memory_getapi; vis->opdisplay->checkmode = GGI_memory_checkmode; vis->opdisplay->setflags = GGI_memory_setflags; if (priv->inputbuffer) { struct gg_api *gii; #if 0 priv->inputbuffer->visx = priv->inputbuffer->visy = priv->inputbuffer->virtx = priv->inputbuffer->virty = priv->inputbuffer->frames = priv->inputbuffer->visframe = 0; #endif DPRINT_MISC("Adding gii to shmem-memtarget\n"); gii = ggGetAPIByName("gii"); if (gii != NULL && STEM_HAS_API(vis->instance.stem, gii)) { char inputstr[1024]; snprintf(inputstr, sizeof(inputstr), "-size=%i:-pointer", INPBUFSIZE); DPRINT("\"input-memory\" inputstr \"%s\" at %p\n", inputstr, priv->inputbuffer->buffer); priv->inp = ggPlugModule(gii, vis->instance.stem, "input-memory", inputstr, priv->inputbuffer->buffer); DPRINT("ggPlugModule for input-memory returned %p\n", priv->inp); if (priv->inp == NULL) { fprintf(stderr, "display-memory: unable to open input-memory\n"); err = GGI_ENODEVICE; goto err1; } } } *dlret = GGI_DL_OPDISPLAY; return 0; err1: free(priv); err0: free(LIBGGI_GC(vis)); *dlret = GGI_DL_OPDISPLAY; return err; }