static void DDNotifyResize(struct ggi_visual *vis, int xsize, int ysize) { gii_event ev; ggi_cmddata_switchrequest *swreq; directx_priv *priv = GGIDIRECTX_PRIV(vis); DPRINT_DRAW("DDNotifyResize(%p, %dx%d) called\n", vis, xsize, ysize); if (!priv->inp) return; /* This is racy, what if window is resized and * resized back before the app gets to react * to the first resize notification? */ if (!LIBGGI_X(vis) || !LIBGGI_Y(vis)) { DPRINT_DRAW("DDNotifyResize: No old size, ignore\n"); return; } if ((LIBGGI_X(vis) == xsize) && (LIBGGI_Y(vis) == ysize)) { DPRINT_DRAW("DDNotifyResize: Same size, ignore\n"); return; } DPRINT_DRAW("DDNotifyResize: Old size %ux%u\n", LIBGGI_X(vis), LIBGGI_Y(vis)); ev.any.size= sizeof(gii_cmd_nodata_event) + sizeof(ggi_cmddata_switchrequest); ev.any.type= evCommand; ev.cmd.code= GGICMD_REQUEST_SWITCH; swreq = (ggi_cmddata_switchrequest *) ev.cmd.data; swreq->request = GGI_REQSW_MODE; swreq->mode = *LIBGGI_MODE(vis); swreq->mode.visible.x = xsize; swreq->mode.visible.y = ysize; if (swreq->mode.virt.x < xsize) swreq->mode.virt.x = xsize; if (swreq->mode.virt.y < ysize) swreq->mode.virt.y = ysize; swreq->mode.size.x = GGI_AUTO; swreq->mode.size.y = GGI_AUTO; ggControl(priv->inp->channel, GII_CMDCODE_RESIZE, &ev); }
/* 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_3dlabs_pm2_drawhline(struct ggi_visual *vis, int x, int y, int w) { struct _3dlabs_pm2_priv *priv = PM2_PRIV(vis); volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr; int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis); DPRINT_DRAW("drawhline(%p, %i,%i, %i) entered\n", vis, x,y, w); y += yadd; pm2_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis), yadd); pm2_waitfifo(mmioaddr, 6); pm2_out32(mmioaddr, x << 16, PM2R_START_X_DOM); pm2_out32(mmioaddr, y << 16, PM2R_START_Y); /* Horizontal */ pm2_out32(mmioaddr, 1 << 16, PM2R_D_X_DOM); pm2_out32(mmioaddr, 0 << 16, PM2R_D_Y); pm2_out32(mmioaddr, w, PM2R_COUNT); pm2_out32(mmioaddr, PM2F_RENDER_LINE | PM2F_RENDER_XPOSITIVE | PM2F_RENDER_YPOSITIVE, PM2R_RENDER); vis->accelactive = 1; return 0; }
static int m2164w_idleaccel(ggi_visual *vis) { DPRINT_DRAW("m2164w_idleaccel(%p) called \n", vis); mga_waitidle(FBDEV_PRIV(vis)->mmioaddr); vis->accelactive = 0; 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_libkgi_idleaccel(struct ggi_visual *vis) { ggi_libkgi_priv *priv = LIBKGI_PRIV(vis); fprintf(stderr, "GGI_libkgi_idleaccel\n"); DPRINT_DRAW("GGI_libkgi_idleaccel(%p) called \n", vis); if (priv->idleaccel) return priv->idleaccel(vis); 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; } }
static void DDSizing(struct ggi_visual *vis, WPARAM wParam, LPRECT rect) { directx_priv *priv = GGIDIRECTX_PRIV(vis); int xsize, ysize; RECT diff, test1, test2; DWORD ws_style = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX; /* Calculate diff between client and window coords */ test1.top = 200; test1.left = 200; test1.right = 400; test1.bottom = 400; test2 = test1; AdjustWindowRectEx(&test2, ws_style, FALSE, 0); diff.top = test1.top - test2.top; diff.bottom = test1.bottom - test2.bottom; diff.left = test1.left - test2.left; diff.right = test1.right - test2.right; /* Adjust to client coords */ rect->top += diff.top; rect->bottom += diff.bottom; rect->left += diff.left; rect->right += diff.right; /* Calculate new size, with regard to max/min/step */ xsize = rect->right - rect->left; ysize = rect->bottom - rect->top; DPRINT_DRAW("Wants resize to %ux%u\n", xsize, ysize); if (xsize < priv->xmin) xsize = priv->xmin; if (xsize > priv->xmax) xsize = priv->xmax; if (ysize < priv->ymin) ysize = priv->ymin; if (ysize > priv->ymax) ysize = priv->ymax; xsize -= (xsize - priv->xmin) % priv->xstep; ysize -= (ysize - priv->ymin) % priv->ystep; /* Move the appropriate edge(s) */ switch (wParam) { case WMSZ_LEFT: case WMSZ_BOTTOMLEFT: case WMSZ_TOPLEFT: rect->left = rect->right - xsize; break; case WMSZ_RIGHT: case WMSZ_BOTTOMRIGHT: case WMSZ_TOPRIGHT: rect->right = rect->left + xsize; break; } switch (wParam) { case WMSZ_TOP: case WMSZ_TOPRIGHT: case WMSZ_TOPLEFT: rect->top = rect->bottom - ysize; break; case WMSZ_BOTTOM: case WMSZ_BOTTOMRIGHT: case WMSZ_BOTTOMLEFT: rect->bottom = rect->top + ysize; break; } /* Adjust back to window coords */ rect->top -= diff.top; rect->bottom -= diff.bottom; rect->left -= diff.left; rect->right -= diff.right; DPRINT_DRAW("Gets resize to %ux%u\n", xsize, ysize); DDNotifyResize(vis, xsize, ysize); }
int GGI_3dlabs_pm2_puthline(struct ggi_visual *vis, int x, int y, int w, const void *buf) { struct _3dlabs_pm2_priv *priv = PM2_PRIV(vis); volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr; int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis); int count; #if 0 uint32_t srcwidth; #endif const uint8_t *src; const uint32_t *srcp; uint32_t *dest; /* 0 width not OK */ if (w == 0) return 0; DPRINT_DRAW("puthline(%p, %i,%i, %i, %p) entered\n", vis, x, y, w, buf); y += yadd; #if 0 if (LIBGGI_GT(vis) & GT_SUB_PACKED_GETPUT) { srcwidth = GT_ByPPP(w, LIBGGI_GT(vis)); } else { srcwidth = w * GT_ByPP(LIBGGI_GT(vis)); } #endif pm2_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis), yadd); pm2_waitfifo(mmioaddr, 6); /* Setting for Image download from Host */ pm2_out32(mmioaddr, priv->pprod, PM2R_FB_READ_MODE); pm2_out32(mmioaddr, UNIT_ENABLE, PM2R_FB_WRITE_MODE); pm2_out32(mmioaddr, UNIT_DISABLE, PM2R_COLOR_DDA_MODE); pm2_loadcoord(mmioaddr, x,y, w, 1); pm2_out32(mmioaddr, PM2F_RENDER_RECTANGLE | PM2F_RENDER_XPOSITIVE | PM2F_RENDER_YPOSITIVE | PM2F_RENDER_SYNC_ON_HOST, PM2R_RENDER); src = (const uint8_t *)buf; dest = (uint32_t *)((volatile uint8_t *) (mmioaddr + PM2R_OUT_FIFO + 4)); count = w; srcp = (const uint32_t *)src; while (count >= priv->fifosize) { pm2_waitfifo(mmioaddr, priv->fifosize); /* 0x0155 is the TAG for FBSourceData */ pm2_out32(mmioaddr, ((priv->fifosize - 2) << 16) | 0x0155, PM2R_OUT_FIFO); pm2_move32(dest, srcp, priv->fifosize - 1); count -= priv->fifosize - 1; srcp += priv->fifosize - 1; } if (count) { pm2_waitfifo(mmioaddr, count + 1); pm2_out32(mmioaddr, ((count - 1) << 16) | 0x0155, PM2R_OUT_FIFO); pm2_move32(dest, srcp, count); } /* Re-enable fb readmode when done */ pm2_waitfifo(mmioaddr, 2); pm2_out32(mmioaddr, 0, PM2R_WAIT_FOR_COMPLETION); priv->oldfgcol = ~priv->oldfgcol; vis->accelactive = 1; return 0; }