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; }
static int do_cleanup(ggi_visual *vis) { ggi_lcd823_priv *priv = LCD823_PRIV(vis); /* We may be called more than once due to the LibGG cleanup stuff */ if (priv == NULL) return 0; DPRINT("display-lcd823: do_cleanup start.\n"); _GGI_lcd823_free_dbs(vis); if (LIBGGI_FD(vis) >= 0) { if (priv->fb_ptr) { munmap(priv->fb_ptr, priv->fb_size); } ioctl(LIBGGI_FD(vis), 2); /* Disable LCD */ close(LIBGGI_FD(vis)); LIBGGI_FD(vis) = -1; } if (vis->input != NULL) { giiClose(vis->input); vis->input = NULL; } free(priv); LIBGGI_PRIVATE(vis) = NULL; if (LIBGGI_GC(vis)) { free(LIBGGI_GC(vis)); } ggUnregisterCleanup((ggcleanup_func *)do_cleanup, vis); DPRINT("display-lcd823: do_cleanup done.\n"); return 0; }
void GGI_fbdev_color_setup(ggi_visual *vis) { ggi_fbdev_priv *priv = FBDEV_PRIV(vis); struct fb_cmap cmap; int len; /* We rely on caller to have deallocated old storage */ priv->orig_cmap = LIBGGI_PAL(vis)->clut.data = priv->gamma.map = NULL; vis->gamma = NULL; priv->reds = priv->greens = priv->blues = NULL; priv->gamma.maxread_r = priv->gamma.maxread_g = priv->gamma.maxread_b = priv->gamma.maxread_r = priv->gamma.maxwrite_g = priv->gamma.maxwrite_b = -1; priv->gamma.len = priv->gamma.start = 0; if (!priv->var.bits_per_pixel) return; if (priv->fix.visual == FB_VISUAL_TRUECOLOR) return; /* No gamma. */ if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR) { DPRINT("display-fbdev: trying gamma.\n"); priv->gamma.maxwrite_r = priv->gamma.maxread_r = 1 << priv->var.red.length; priv->gamma.maxwrite_g = priv->gamma.maxread_g = 1 << priv->var.green.length; priv->gamma.maxwrite_b = priv->gamma.maxread_b = 1 << priv->var.blue.length; len = priv->gamma.maxread_r; if (len < priv->gamma.maxread_g) len = priv->gamma.maxread_g; if (len < priv->gamma.maxread_b) len = priv->gamma.maxread_b; priv->gamma.len = len; priv->gamma.start = 0; LIBGGI_PAL(vis)->clut.size = len * 2; LIBGGI_PAL(vis)->clut.data = calloc(len * 2 /* orig */, sizeof(ggi_color)); if (LIBGGI_PAL(vis)->clut.data == NULL) return; priv->gamma.map = LIBGGI_PAL(vis)->clut.data; /* All of the above is moot until we turn it on like so: */ vis->gamma = &(priv->gamma); } else { DPRINT("display-fbdev: trying palette.\n"); len = 1 << priv->var.bits_per_pixel; LIBGGI_PAL(vis)->clut.size = len * 2; LIBGGI_PAL(vis)->clut.data = calloc(len * 2 /* orig */, sizeof(ggi_color)); if (LIBGGI_PAL(vis)->clut.data == NULL) return; } cmap.start = 0; cmap.len = len; cmap.red = calloc(len * 3, 2); if (cmap.red == NULL) goto bail; cmap.green = cmap.red + len; cmap.blue = cmap.green + len; cmap.transp = NULL; if (ioctl(LIBGGI_FD(vis), FBIOGETCMAP, &cmap) < 0) { DPRINT_COLOR("display-fbdev: GETCMAP failed.\n"); free(cmap.red); goto bail; } priv->orig_cmap = LIBGGI_PAL(vis)->clut.data + len; if (vis->gamma != NULL) { DPRINT_COLOR("display-fbdev: Saved gamma (len=%d/%d/%d).\n", priv->gamma.maxread_r, priv->gamma.maxread_g, priv->gamma.maxread_b); while (len--) { if (len < priv->gamma.maxread_r) priv->orig_cmap[len].r = cmap.red[len]; if (len < priv->gamma.maxread_g) priv->orig_cmap[len].g = cmap.green[len]; if (len < priv->gamma.maxread_b) priv->orig_cmap[len].b = cmap.blue[len]; } vis->opcolor->getgammamap = GGI_fbdev_getgammamap; vis->opcolor->setgammamap = GGI_fbdev_setgammamap; } else { DPRINT_COLOR("display-fbdev: Saved palette (len=%d).\n", len); while (len--) { priv->orig_cmap[len].r = cmap.red[len]; priv->orig_cmap[len].g = cmap.green[len]; priv->orig_cmap[len].b = cmap.blue[len]; } if (priv->fix.visual != FB_VISUAL_STATIC_PSEUDOCOLOR) { LIBGGI_PAL(vis)->setPalette = GGI_fbdev_setPalette; LIBGGI_PAL(vis)->getPrivSize = GGI_fbdev_getPrivSize; } } LIBGGI_PAL(vis)->priv = cmap.red; priv->reds = cmap.red; priv->greens = cmap.green; priv->blues = cmap.blue; return; bail: free(LIBGGI_PAL(vis)->clut.data); LIBGGI_PAL(vis)->clut.data = NULL; vis->gamma = NULL; return; }
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh, const char *args, void *argptr, uint32_t *dlret) { ggi_lcd823_priv *priv; int size; DPRINT("display-lcd823: GGIopen start.\n"); LIBGGI_PRIVATE(vis) = priv = malloc(sizeof(ggi_lcd823_priv)); if (priv == NULL) { return GGI_ENOMEM; } priv->fb_ptr = NULL; /* Now open the framebuffer device */ LIBGGI_FD(vis) = open(LCD_DEVNAME, O_RDWR); if (LIBGGI_FD(vis) < 0) { fprintf(stderr, "display-lcd823: Couldn't open " "framebuffer device %s: %s\n", LCD_DEVNAME, strerror(errno)); do_cleanup(vis); return GGI_ENODEVICE; } if (ioctl(LIBGGI_FD(vis), 1) != 0) { fprintf(stderr, "display-lcd823: Unable to enable LCD: %s\n", strerror(errno)); do_cleanup(vis); return GGI_ENODEVICE; } if (ioctl(LIBGGI_FD(vis), 5, &size) != 0) { fprintf(stderr, "display-lcd823: Unable to get size of LCD " "memory: %s\n", strerror(errno)); do_cleanup(vis); return GGI_ENODEVICE; } priv->fb_size = size * getpagesize(); priv->fb_ptr = mmap(NULL, priv->fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, LIBGGI_FD(vis), 0); if (priv->fb_ptr == MAP_FAILED) { fprintf(stderr, "display-lcd823: Unable to map LCD " "memory: %s\n", strerror(errno)); priv->fb_ptr = NULL; do_cleanup(vis); return GGI_ENODEVICE; } priv->frame_size = priv->fb_size; LIBGGI_GC(vis) = malloc(sizeof(ggi_gc)); if (LIBGGI_GC(vis) == NULL) { do_cleanup(vis); return GGI_ENOMEM; } /* Mode management */ vis->opdisplay->getmode = GGI_lcd823_getmode; vis->opdisplay->setmode = GGI_lcd823_setmode; vis->opdisplay->checkmode = GGI_lcd823_checkmode; vis->opdisplay->getapi = GGI_lcd823_getapi; vis->opdisplay->flush = GGI_lcd823_flush; vis->opdisplay->setflags = GGI_lcd823_setflags; /* Register cleanup handler */ ggRegisterCleanup((ggcleanup_func *)do_cleanup, vis); DPRINT("display-lc823: GGIopen success.\n"); *dlret = GGI_DL_OPDISPLAY; return 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; }
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_fbdev_priv *fbdevpriv = FBDEV_PRIV(vis); struct m2164w_priv *priv; unsigned long usedmemend; size_t fontlen; int pixbytes; int fd = LIBGGI_FD(vis); int i; if (GT_SIZE(LIBGGI_GT(vis)) % 8 != 0 || GT_SIZE(LIBGGI_GT(vis)) > 32 || GT_SIZE(LIBGGI_GT(vis)) < 8) { /* Unsupported mode */ return GGI_ENOFUNC; } pixbytes = GT_ByPP(LIBGGI_GT(vis)); priv = malloc(sizeof(struct m2164w_priv)); if (priv == NULL) { return GGI_ENOMEM; } fbdevpriv->mmioaddr = mmap(NULL, fbdevpriv->orig_fix.mmio_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (signed)fbdevpriv->orig_fix.smem_len); if (fbdevpriv->mmioaddr == MAP_FAILED) { /* Can't mmap() MMIO region - bail out */ DPRINT_LIBS("mga-2164w: Unable to map MMIO region: %s\n" " fd: %d, len: %ld, offset: %ld\n", strerror(errno), fd, fbdevpriv->orig_fix.mmio_len, fbdevpriv->orig_fix.smem_len); fbdevpriv->mmioaddr = NULL; free(priv); return GGI_ENODEVICE; } DPRINT_MISC("mga-2164w: Mapped MMIO region at %p\n", fbdevpriv->mmioaddr); /* Set up DirectBuffers */ for (i=0; i < LIBGGI_MODE(vis)->frames; i++) { ggi_directbuffer *buf = LIBGGI_APPBUFS(vis)[i]; ggi_resource *res; res = malloc(sizeof(ggi_resource)); if (res == NULL) { do_cleanup(vis); return GGI_ENOMEM; } buf->resource = res; buf->resource->acquire = m2164w_acquire; buf->resource->release = m2164w_release; buf->resource->self = buf; buf->resource->priv = vis; buf->resource->count = 0; buf->resource->curactype = 0; } priv->drawboxcmd = BOP_COPY | SHFTZERO | SGNZERO | ARZERO | SOLID | OP_TRAP; if (pixbytes != 3) { switch (fbdevpriv->orig_fix.accel) { case FB_ACCEL_MATROX_MGA2064W: case FB_ACCEL_MATROX_MGA1064SG: case FB_ACCEL_MATROX_MGA2164W: case FB_ACCEL_MATROX_MGA2164W_AGP: /* Use block mode */ priv->drawboxcmd |= ATYPE_BLK; break; default: /* For now - assume SDRAM for other cards */ break; } } priv->dwgctl = 0; priv->oldfgcol = LIBGGI_GC(vis)->fg_color - 1; priv->oldbgcol = LIBGGI_GC(vis)->bg_color - 1; priv->oldtl.x = -1; priv->oldtl.y = -1; priv->oldbr.x = -1; priv->oldbr.y = -1; priv->oldyadd = -1; priv->curopmode = priv->origopmode = mga_in16(fbdevpriv->mmioaddr, OPMODE); /* Use the 7k Pseudo-DMA window */ priv->dmaaddr = (void*)fbdevpriv->mmioaddr; priv->dma_len = 0x1c00; vis->needidleaccel = 1; fbdevpriv->idleaccel = m2164w_idleaccel; /* Accelerate fonts if possible */ priv->font = (uint8_t *)(font); usedmemend = LIBGGI_MODE(vis)->frames * fbdevpriv->fix.line_length * LIBGGI_VIRTY(vis); fontlen = 256*8; priv->fontoffset = fbdevpriv->orig_fix.smem_len - fontlen; priv->fontoffset &= ~127; /* Align */ DPRINT_MISC("mga-2164w: usedmemend: %ld, fontoffset: %ld\n", usedmemend, priv->fontoffset); if (usedmemend <= priv->fontoffset) { memcpy((uint8_t*)fbdevpriv->fb_ptr + priv->fontoffset, font, fontlen); priv->fontoffset *= 8; /* In bits */ priv->charadd = FWIDTH*FHEIGHT; vis->opdraw->putc = GGI_m2164w_fastputc; vis->opdraw->puts = GGI_m2164w_fastputs; DPRINT_MISC("mga-2164w: Using fast chars\n"); } else { priv->fontoffset = 0; vis->opdraw->putc = GGI_m2164w_putc; vis->opdraw->puts = GGI_m2164w_puts; DPRINT_MISC("mga-2164w: Using slow chars\n"); } /* Save previous function pointers */ priv->crossblit = vis->opdraw->crossblit; /* Initialize function pointers */ vis->opdraw->getcharsize= GGI_m2164w_getcharsize; vis->opdraw->drawhline = GGI_m2164w_drawhline; vis->opdraw->drawvline = GGI_m2164w_drawvline; vis->opdraw->drawline = GGI_m2164w_drawline; vis->opdraw->drawbox = GGI_m2164w_drawbox; vis->opdraw->copybox = GGI_m2164w_copybox; vis->opdraw->fillscreen = GGI_m2164w_fillscreen; /* The crossblit in linear-* is faster on truecolor modes! */ if (GT_SCHEME(LIBGGI_GT(vis)) == GT_PALETTE || GT_SCHEME(LIBGGI_GT(vis)) == GT_STATIC_PALETTE) { vis->opdraw->crossblit = GGI_m2164w_crossblit; } FBDEV_PRIV(vis)->accelpriv = priv; /* Register cleanup handler */ ggRegisterCleanup((ggcleanup_func *)do_cleanup, vis); *dlret = GGI_DL_OPDRAW; return 0; }