int GGI_lin8_copybox(ggi_visual *vis, int x, int y, int w, int h, int nx, int ny) { uint8_t *src, *dest; int stride = LIBGGI_FB_W_STRIDE(vis); int line; LIBGGICLIP_COPYBOX(vis, x, y, w, h, nx, ny); PREPARE_FB(vis); if (ny < y) { src = (uint8_t *)LIBGGI_CURREAD(vis) + y*stride + x; dest = (uint8_t *)LIBGGI_CURWRITE(vis) + ny*stride + nx; for (line=0; line < h; line++, src += stride, dest += stride) { memmove(dest, src, (size_t)(w)); } } else { src = (uint8_t *)LIBGGI_CURREAD(vis) + (y+h-1)*stride + x; dest = (uint8_t *)LIBGGI_CURWRITE(vis) + (ny+h-1)*stride + nx; for (line=0; line < h; line++, src -= stride, dest -= stride) { memmove(dest, src, (size_t)(w)); } } return 0; }
int GGI_lin32_getpixel(ggi_visual *vis,int x,int y,ggi_pixel *pixel) { *pixel = *((uint32_t *) ((uint8_t *)LIBGGI_CURREAD(vis) + y*LIBGGI_FB_R_STRIDE(vis)+x*sizeof(uint32_t))); return 0; }
int GGI_lin32_getpixel_nca(struct ggi_visual *vis,int x,int y,ggi_pixel *pixel) { PREPARE_FB(vis); *pixel = *((uint32_t *) ((uint8_t *)LIBGGI_CURREAD(vis) + y*LIBGGI_FB_R_STRIDE(vis)+x*sizeof(uint32_t))); return 0; }
int GGI_lin16_gethline(ggi_visual *vis, int x, int y, int w, void *buffer) { uint8_t *mem; PREPARE_FB(vis); mem = (uint8_t *)LIBGGI_CURREAD(vis) + y*LIBGGI_FB_R_STRIDE(vis) + x*2; memcpy(buffer, mem, (size_t)(w*2)); return 0; }
/* 8 bit to 8 bit crossblitting. */ static inline void crossblit_8_to_8(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy) { uint8_t *srcp, *dstp; int srcstride = LIBGGI_FB_R_STRIDE(src); int dststride = LIBGGI_FB_W_STRIDE(dst); uint8_t conv_tab[256]; DPRINT_DRAW("linear-8: crossblit_8_to_8.\n"); /* Creates the conversion table. A bit simplistic approach, perhaps? */ do { unsigned int i; for (i = 0; i < 256; i++) { ggi_color col; LIBGGIUnmapPixel(src, i, &col); conv_tab[i] = LIBGGIMapColor(dst, &col); } } while (0); srcp = (uint8_t*)LIBGGI_CURREAD(src) + srcstride*sy + sx; dstp = (uint8_t*)LIBGGI_CURWRITE(dst) + dststride*dy + dx*2; srcstride -= w; dststride -= w; for (; h > 0; h--) { int i = (w + 7) / 8; /* We don't believe in the optimizing capabilities of the * compiler hence unroll manually. */ switch (w & 0x7) { default: for (; i > 0; i--) { case 0x0: *dstp++ = conv_tab[*srcp++]; case 0x7: *dstp++ = conv_tab[*srcp++]; case 0x6: *dstp++ = conv_tab[*srcp++]; case 0x5: *dstp++ = conv_tab[*srcp++]; case 0x4: *dstp++ = conv_tab[*srcp++]; case 0x3: *dstp++ = conv_tab[*srcp++]; case 0x2: *dstp++ = conv_tab[*srcp++]; case 0x1: *dstp++ = conv_tab[*srcp++]; } } srcp += srcstride; dstp += dststride; } }
/* Blitting between identical visuals */ static inline void crossblit_same(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy) { uint8_t *srcp, *dstp; int srcstride = LIBGGI_FB_R_STRIDE(src); int dststride = LIBGGI_FB_W_STRIDE(dst); DPRINT_DRAW("linear-8: DB-accelerating crossblit.\n"); srcp = (uint8_t*)LIBGGI_CURREAD(src) + srcstride*sy + sx; dstp = (uint8_t*)LIBGGI_CURWRITE(dst) + dststride*dy + dx; for (; h != 0; h--) { memcpy(dstp, srcp, (size_t)(w)); srcp += srcstride; dstp += dststride; } }
static int GGIopen(struct ggi_visual *vis, struct ggi_dlhandle *dlh, const char *args, void *argptr, uint32_t_t_t *dlret) { ggi_mode mode; void *memptr=NULL; suid_hook *priv; int x, err = GGI_ENOMEM; LIBGGI_GC(vis) = malloc(sizeof(ggi_gc)); if (LIBGGI_GC(vis) == NULL) { return GGI_ENOMEM; } priv = LIBGGI_PRIVATE(vis) = malloc(sizeof(suid_hook)); if (priv == NULL) { goto out_freegc; } priv->is_up=0; priv->dev_mem=_suidtarget_dev_mem=-1; priv->mmap_length=0; /* Open GII for input */ vis->input = giiOpen("input-linux-kbd", NULL); if (vis->input == NULL) { fprintf(stderr, "display-suidkgi: Couldn't open kbd.\n"); goto out_freepriv; } /* Has mode management */ vis->opdisplay->getmode=GGI_suidkgi_getmode; vis->opdisplay->setmode=GGI_suidkgi_setmode; vis->opdisplay->checkmode=GGI_suidkgi_checkmode; vis->opdisplay->flush=GGI_suidkgi_flush; vis->opdisplay->kgicommand=GGI_suidkgi_kgicommand; vis->opdisplay->setflags=GGI_suidkgi_setflags; vis->opdraw->setorigin=GGI_suidkgi_setorigin; vis->w_frame = malloc(sizeof(ggi_directbuffer)); /* FIXME ! */ vis->r_frame = malloc(sizeof(ggi_directbuffer)); /* FIXME ! */ LIBGGI_CURWRITE(vis)=NULL; LIBGGI_CURREAD(vis)=NULL; if (iopl(3)) {perror("iopl");exit(2); } DPRINT("IOPL is here.\n"); if (-1 == (priv->dev_mem = _suidtarget_dev_mem = open("/dev/mem",O_RDWR))) { perror("opening /dev/mem");exit(3); } memptr=mmap(NULL,64*1024,PROT_READ|PROT_WRITE,MAP_SHARED,priv->dev_mem,0xa0000); DPRINT("Have mmap at %p.\n",memptr); /* law_base=0xf3000000; */ if (suidkgi_init_module()) {DPRINT("Init has failed. Tough luck.\n");exit(1); } DPRINT("Init was o.k.\n"); signal(SIGSEGV,get_killed); signal(SIGINT,get_killed); signal(SIGTERM,get_killed); priv->is_up=1; #if 1 /* Not sure, if this is needed, but ... */ mode.frames=1; mode.graphtype=GT_TEXT16; mode.visible.x=mode.virt.x=80; mode.visible.y=mode.virt.y=25; mode.dpp.x = 8;mode.dpp.y =16; x=GGI_suidkgi_checkmode(vis,&mode); DPRINT("TESTMODE1 says %d.\n",x); x=GGI_suidkgi_setmode(vis,&mode); DPRINT("SETMODE1 says %d.\n",x); #endif #undef TESTING_THE_SUID_TARGET #ifdef TESTING_THE_SUID_TARGET #ifdef GoneByeBye for(x=0;x<480;x++) { GGI_suidkgi_setsplitline(vis, x); ggUSleep(100000); } #endif mode.frames=1; mode.graphtype=GT_8BIT; mode.visible.x=mode.virt.x=320; mode.visible.y=mode.virt.y=200; mode.dpp.x =mode.dpp.y =1; x=ggiCheckMode(vis,&mode); DPRINT("TESTMODE3 says %d.\n",x); x=ggiSetMode(vis,&mode); DPRINT("SETMODE3 says %d.\n",x); sleep(1); { int y; for(y=0;y<200;y++) { for(x=0;x<320;x++) { *((unsigned char *)memptr+x+y*320)=x+y; } ggUSleep(1); } } sleep(1); mode.frames=1; mode.graphtype=GT_TEXT16; mode.visible.x=mode.virt.x=80; mode.visible.y=mode.virt.y=25; mode.dpp.x = 8;mode.dpp.y =16; x=GGI_suidkgi_checkmode(vis,&mode); DPRINT("TESTMODE4 says %d.\n",x); x=GGI_suidkgi_setmode(vis,&mode); DPRINT("SETMODE4 says %d.\n",x); sleep(1); suidkgi_cleanup_module(); DPRINT("Cleanup went well.\n"); close(priv->dev_mem); exit(1); #endif *dlret = GGI_DL_OPDISPLAY|GGI_DL_OPDRAW; return 0; out_freepriv: free(priv); out_freegc: free(LIBGGI_GC(vis); return err; }