int GGI_X_drawvline_nc_slave_draw(ggi_visual *vis, int x, int y, int h) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); GGI_X_CLEAN(vis, x, y, 1, h); priv->slave->opdraw->drawvline_nc(priv->slave, x, y, h); y = GGI_X_WRITE_Y; GGI_X_LOCK_XLIB(vis); XDrawLine(priv->disp, priv->drawable, priv->gc, x, y, x, y+h-1); GGI_X_MAYBE_SYNC(vis); GGI_X_UNLOCK_XLIB(vis); return 0; }
int GGI_X_flush_ximage_child(struct ggi_visual *vis, int x, int y, int w, int h, int tryflag) { ggi_x_priv *priv; int mansync; priv = GGIX_PRIV(vis); if (tryflag == 0) { /* flush later, this is in signal handler context * when using the signal based scheduler */ ggUnlock(priv->flushlock); return 0; } if (priv->opmansync) MANSYNC_ignore(vis); mansync = 1; /* Do we call MANSYNC_cont later? By default, yes. */ if (tryflag != 2) GGI_X_LOCK_XLIB(vis); _ggi_x_flush_cmap(vis); /* Update the palette/gamma */ /* Flush any pending Xlib operations. */ XSync(priv->disp, 0); if (priv->fullflush || (GGI_ACTYPE_WRITE & vis->w_frame->resource->curactype)) { /* Flush all requested data */ if (tryflag != 2) { GGI_X_CLEAN(vis, x, y, w, h); y = GGI_X_WRITE_Y; } /* else it's a non-translated exposure event. */ XPutImage(priv->disp, priv->drawable, priv->tempgc, priv->ximage, x, y, x, y, (unsigned)w, (unsigned)h); if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) mansync = 0; } else { /* Just flush the intersection with the dirty region */ int x2, y2; if (priv->dirtytl.x > priv->dirtybr.x) goto clean; if (x > priv->dirtybr.x) goto clean; if (y > priv->dirtybr.y) goto clean; x2 = x + w - 1; if (x2 < priv->dirtytl.x) goto clean; y2 = y + h - 1; if (y2 < priv->dirtytl.y) goto clean; if (x < priv->dirtytl.x) x = priv->dirtytl.x; if (y < priv->dirtytl.y) y = priv->dirtytl.y; if (x2 > priv->dirtybr.x) x2 = priv->dirtybr.x; if (y2 > priv->dirtybr.y) y2 = priv->dirtybr.y; w = x2 - x + 1; h = y2 - y + 1; if ((w <= 0) || (h <= 0)) goto clean; XPutImage(priv->disp, priv->drawable, priv->tempgc, priv->ximage, x, GGI_X_WRITE_Y, x, GGI_X_WRITE_Y, (unsigned)w, (unsigned)h); GGI_X_CLEAN(vis, x, y, w, h); } /* Tell X Server to start blitting */ XFlush(priv->disp); clean: if (tryflag != 2) GGI_X_UNLOCK_XLIB(vis); if (priv->opmansync && mansync) MANSYNC_cont(vis); return 0; }
int GGI_X_fillscreen_slave_draw(ggi_visual *vis) { ggi_x_priv *priv; XGCValues gcValue; GC gc; priv = GGIX_PRIV(vis); DPRINT("X_fillscreen_slave_draw enter!\n"); GGI_X_LOCK_XLIB(vis); /* XXX: What is priv->gc ? is it appropriate to use that here? */ gcValue.foreground = LIBGGI_GC(vis)->fg_color; gcValue.background = LIBGGI_GC(vis)->fg_color; gcValue.function = GXcopy; gc = XCreateGC( priv->disp, priv->drawable, GCForeground | GCBackground | GCFunction, &gcValue); if (LIBGGI_GC(vis)->cliptl.x > 0 || LIBGGI_GC(vis)->cliptl.y > 0 || LIBGGI_GC(vis)->clipbr.x < LIBGGI_VIRTX(vis) || LIBGGI_GC(vis)->clipbr.y < LIBGGI_VIRTY(vis)) { int y; DPRINT("X_fillscreen_slave_draw small clip!\n"); GGI_X_CLEAN(vis, LIBGGI_GC(vis)->cliptl.x, LIBGGI_GC(vis)->cliptl.y, LIBGGI_GC(vis)->clipbr.x-LIBGGI_GC(vis)->cliptl.x, LIBGGI_GC(vis)->clipbr.y-LIBGGI_GC(vis)->cliptl.y); DPRINT("X_fillscreen_slave_draw calling opdraw->fillscreen\n"); priv->slave->opdraw->fillscreen(priv->slave); /* What is this? y is set twice? which value is * proper? Answer: GGI_X_WRITE_Y is a macro that makes * use of the value stored in y. */ y = LIBGGI_GC(vis)->cliptl.y; y = GGI_X_WRITE_Y; #define CLIPSIZE(xy) \ (unsigned)LIBGGI_GC(vis)->clipbr.xy-LIBGGI_GC(vis)->cliptl.xy XFillRectangle(priv->disp, priv->drawable, gc, LIBGGI_GC(vis)->cliptl.x, y, CLIPSIZE(x), CLIPSIZE(y) ); } else { DPRINT("X_fillscreen_slave_draw large clip!\n"); GGI_X_CLEAN(vis, 0, 0, LIBGGI_VIRTX(vis), LIBGGI_VIRTY(vis)); DPRINT("X_fillscreen_slave_draw calling opdraw->fillscreen\n"); priv->slave->opdraw->fillscreen(priv->slave); XFillRectangle(priv->disp, priv->drawable, gc, 0, 0, LIBGGI_VIRTX(vis), LIBGGI_VIRTY(vis) ); } GGI_X_MAYBE_SYNC(vis); XFreeGC(priv->disp, gc); GGI_X_UNLOCK_XLIB(vis); return GGI_OK; }