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; }
static inline void do_drawhline(struct ggi_visual *vis, int x, int y, int w) { uint8_t *fb; uint8_t fg; fb = (uint8_t *) LIBGGI_CURWRITE(vis)+y*LIBGGI_FB_W_STRIDE(vis)+(x/2); fg = (uint8_t) LIBGGI_GC_FGCOLOR(vis) | (LIBGGI_GC_FGCOLOR(vis)<<4); PREPARE_FB(vis); /* x is odd. Read-modify-write right pixel. */ if (x & 0x01) { *fb = (*fb & 0x0f) | (fg & 0xf0); fb++; w--; } memset(fb, fg, (size_t)(w/2)); /* Dangling right pixel. */ if (w & 0x01) { fb += w/2; *fb = (*fb & 0xf0) | (fg & 0x0f); } }
static inline void do_drawhline(ggi_visual *vis, int x, int y, int w) { int i, w32; uint32_t *fb32; uint16_t *fb16; uint32_t val = LIBGGI_GC_FGCOLOR(vis) | (LIBGGI_GC_FGCOLOR(vis) << 16); PREPARE_FB(vis); fb16 = (uint16_t*)((uint8_t*)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis) + x*2); if (x%2) { *(fb16++) = val; w--; } w32 = w/2; fb32 = (uint32_t*) fb16; for (i = 0; i < w32; i++) { *(fb32++) = val; } if (w%2) { fb16 = (uint16_t *) fb32; *fb16 = val; } }
/* Default fallback */ static inline void fallback(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy) { ggi_pixel cur_src; ggi_pixel cur_dst = 0; uint8_t *dstptr; int stride; DPRINT_DRAW("linear-8: fallback to slow crossblit.\n"); LIBGGIGetPixel(src, sx, sy, &cur_src); cur_src++; /* assure safe init */ stride = LIBGGI_FB_W_STRIDE(dst); dstptr = (uint8_t*) LIBGGI_CURWRITE(dst) + dy*stride + dx; for (; h > 0; h--, sy++, dy++) { int x; for (x=0; x < w; x++) { ggi_pixel pixel; LIBGGIGetPixel(src, sx+x, sy, &pixel); if (pixel != cur_src) { ggi_color col; LIBGGIUnmapPixel(src, pixel, &col); cur_dst = LIBGGIMapColor(dst, &col); cur_src = pixel; } *(dstptr+x) = cur_dst; } dstptr += stride; } }
int GGI_lin16_putbox(struct ggi_visual *vis, int x, int y, int w, int h, const void *buffer) { const uint16_t *src = buffer; uint8_t *dest; int srcwidth = w; int destwidth = LIBGGI_FB_W_STRIDE(vis); LIBGGICLIP_PUTBOX(vis,x,y,w,h,src,srcwidth, *1); PREPARE_FB(vis); dest = (uint8_t *)LIBGGI_CURWRITE(vis) + (y*destwidth + x*2); /* Width should be in bytes */ w *= 2; /* Optimized full-width case */ if (w == destwidth && x == 0) { memcpy(dest, src, (size_t)(w*h)); return 0; } while (h > 0) { memcpy(dest, src, (size_t)(w)); dest += destwidth; src += srcwidth; h--; } return 0; }
int GGI_lin32_putpixel_nc(ggi_visual *vis,int x,int y,ggi_pixel col) { *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = col; return 0; }
int GGI_lin32_drawpixel_nc(ggi_visual *vis,int x,int y) { *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = LIBGGI_GC_FGCOLOR(vis); return 0; }
int GGI_lin32_putpixela(struct ggi_visual *vis,int x,int y,ggi_pixel col) { CHECKXY(vis,x,y); PREPARE_FB(vis); *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = col; return 0; }
int GGI_lin32_drawpixela(struct ggi_visual *vis,int x,int y) { CHECKXY(vis,x,y); PREPARE_FB(vis); *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = LIBGGI_GC_FGCOLOR(vis); 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; } }
int GGI_lin16_puthline(ggi_visual *vis, int x, int y, int w, const void *buffer) { const uint16_t *buf16 = buffer; uint8_t *mem; LIBGGICLIP_XYW_BUFMOD(vis, x, y, w, buf16, *1); PREPARE_FB(vis); mem = (uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis) + x*2; memcpy(mem, buf16, (size_t)(w*2)); return 0; }
/* 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; } }
int GGI_lin16_drawbox(struct ggi_visual *vis, int x, int y, int origw, int h) { uint32_t *buf32; uint16_t *buf16; uint32_t val; int linediff, oddx; LIBGGICLIP_XYWH(vis, x, y, origw, h); PREPARE_FB(vis); val = LIBGGI_GC_FGCOLOR(vis) | (LIBGGI_GC_FGCOLOR(vis) << 16); buf16 = (uint16_t*)((uint8_t*)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis) + x*2); linediff = LIBGGI_FB_W_STRIDE(vis) - origw*2; if (x%2) oddx = 1; else oddx = 0; while (h--) { int w = origw; if (oddx) { *(buf16++) = val; w--; } buf32 = (uint32_t*) buf16; while (w > 1) { *(buf32++) = val; w -= 2; } buf16 = (uint16_t*) buf32; if (w) { *(buf16++) = val; } buf16 = (uint16_t*) ((uint8_t*)buf16 + linediff); } return 0; }
static inline void dbblit_32bpp(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy, uint32_t srcfmt) { struct m2164w_priv *priv = M2164W_PRIV(dst); volatile uint8_t *mmioaddr = FBDEV_PRIV(dst)->mmioaddr; int yadd = dst->w_frame_num * LIBGGI_VIRTY(dst); volatile uint32_t *dstptr; uint32_t dwgctl, bltmod = BLTMOD_BU32RGB; uint16_t opmode; uint8_t *srcptr; uint32_t *srcptr32; int srcinc; int maxpix; dstptr = priv->dmaaddr; srcinc = LIBGGI_FB_R_STRIDE(src); srcptr = (uint8_t*) LIBGGI_CURWRITE(src) + sy*srcinc + sx*4; srcinc -= w*4; maxpix = priv->dma_len/4; dy += yadd; switch (srcfmt) { #if 0 /* This case is the default. */ case GGI_DB_STD_24a32p8r8g8b8: bltmod = BLTMOD_BU32RGB; break; #endif case GGI_DB_STD_24a32p8b8g8r8: bltmod = BLTMOD_BU32BGR; break; } dwgctl = bltmod | BOP_COPY | SHFTZERO | OP_ILOAD | SGNZERO; #ifdef GGI_BIG_ENDIAN opmode = OPMODE_DMA_BLIT_WRITE | OPMODE_DMA_BE_32BPP; #else opmode = OPMODE_DMA_BLIT_WRITE | OPMODE_DMA_LE; #endif mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(dst), LIBGGI_GC(dst), LIBGGI_VIRTX(dst), yadd); if (priv->curopmode != opmode) { priv->curopmode = opmode; mga_waitidle(mmioaddr); mga_out16(mmioaddr, opmode, OPMODE); } if (priv->dwgctl != dwgctl) { mga_waitfifo(mmioaddr, 6); mga_setdwgctl(mmioaddr, priv, dwgctl); } else { mga_waitfifo(mmioaddr, 5); } mga_out32(mmioaddr, RS18(w-1), AR0); mga_out32(mmioaddr, 0, AR3); mga_out32(mmioaddr, 0, AR5); mga_out32(mmioaddr, (unsigned)(RS16(dx + w - 1) << 16) | RS16(dx), FXBNDRY); mga_out32(mmioaddr, (unsigned)(RS16(dy) << 16) | RS16(h), YDSTLEN | EXECUTE); dst->accelactive = 1; if (w > maxpix) { while (h--) { int tmpw = w; while (tmpw) { int tmpw2 = (tmpw > maxpix ? maxpix : tmpw); tmpw -= tmpw2; while (tmpw2--) { srcptr32 = (uint32_t *)srcptr; *(dstptr++) = *(srcptr32++); srcptr = (uint8_t *)srcptr32; } dstptr = priv->dmaaddr; } srcptr += srcinc; } } else { while (h--) { int tmpw = w; while (tmpw--) { srcptr32 = (uint32_t *)srcptr; *(dstptr++) = *(srcptr32++); srcptr = (uint8_t *)srcptr32; } srcptr += srcinc; dstptr = priv->dmaaddr; } } }
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; }
int GGI_lin8_putc(struct ggi_visual *vis, int x, int y, char c) { #define char_width 8 #define char_height 8 int offset, x_run, y_run; uint8_t *bitmap; bitmap = (uint8_t *)(font) + ( c * char_height ); x_run = char_width; y_run = char_height; offset = 0; { int delta; delta = LIBGGI_GC(vis)->cliptl.x - x; if ( delta > 0 ) { if ( delta >= x_run ) { return 0; } else { x_run -= delta; offset += delta; x += delta; } } delta = ( x + x_run ) - LIBGGI_GC(vis)->clipbr.x; if ( delta > 0 ) { if ( delta >= x_run ) { return 0; } else { x_run -= delta; } } delta = LIBGGI_GC(vis)->cliptl.y - y; if ( delta > 0 ) { if ( delta >= y_run ) { return 0; } else { y_run -= delta; bitmap += delta; y += delta; } } delta = ( y + y_run ) - LIBGGI_GC(vis)->clipbr.y; if ( delta > 0 ) { if ( delta >= y_run ) { return 0; } else { y_run -= delta; } } } { int y_iter; register uint8_t *fb; int add_stride; PREPARE_FB(vis); add_stride = LIBGGI_FB_W_STRIDE(vis); fb = (uint8_t *)LIBGGI_CURWRITE(vis) + ( y * add_stride ) + x; add_stride -= x_run; y_run += y; x_run += x; for ( y_iter = y ; y_iter < y_run ; y_iter++, bitmap++, fb += add_stride ) { register int x_iter; register uint8_t row; row = *bitmap << offset; for ( x_iter = x ; x_iter < x_run ; x_iter++, row <<= 1, fb++ ) { *fb = ( row & 128 ) ? (uint8_t)LIBGGI_GC_FGCOLOR(vis) : (uint8_t)LIBGGI_GC_BGCOLOR(vis); } } } return 0; #undef char_width #undef char_height }