static int GGI_helper_x_shm_setup(struct ggi_helper *helper, const char *args, void *argptr) { ggi_x_priv *priv; int major, minor; Bool pixmaps; DPRINT_LIBS("GGI_helper_x_shm_setup(%p, %s, %p) called\n", helper, args, argptr); priv = GGIX_PRIV(helper->visual); if (XShmQueryExtension(priv->disp) != True) return GGI_ENOFUNC; if (XShmQueryVersion(priv->disp, &major, &minor, &pixmaps) != True) return GGI_ENOFUNC; DPRINT_LIBS("X: MIT-SHM: SHM version %i.%i %s pixmap support\n", major, minor, pixmaps ? "with" : "without"); priv->createfb = _ggi_xshm_create_ximage; priv->freefb = _ggi_xshm_free_ximage; return GGI_OK; }
static int GGI_X_flush_draw(struct ggi_visual *vis, int x, int y, int w, int h, int tryflag) { ggi_x_priv *priv; 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 (tryflag != 2) GGI_X_LOCK_XLIB(vis); _ggi_x_flush_cmap(vis); /* Update the palette/gamma */ /* Flush any pending Xlib operations. */ XFlush(priv->disp); if (tryflag != 2) { GGI_X_UNLOCK_XLIB(vis); } return 0; }
/* XImage allocation for normal client-side buffer */ void _ggi_x_freefb(struct ggi_visual *vis) { ggi_x_priv *priv = GGIX_PRIV(vis); if (priv->slave) { struct gg_stem *stem = priv->slave->instance.stem; ggiClose(priv->slave->instance.stem); ggDelStem(stem); priv->slave = NULL; } if (priv->ximage) { #ifndef HAVE_XINITIMAGE XFree(priv->ximage); #else free(priv->ximage); #endif priv->ximage = NULL; } if (priv->fb) { free(priv->fb); priv->fb = NULL; } LIB_ASSERT(priv->slave == NULL, "priv->slave: wild pointer\n"); LIB_ASSERT(priv->ximage == NULL, "priv->ximage: wild pointer\n"); LIB_ASSERT(priv->fb == NULL, "priv->fb: wild pointer\n"); _ggi_free_dbs(vis); }
int GGI_X_create_window_drawable (struct ggi_visual *vis) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); priv->drawable = priv->win; if (priv->drawable == None) priv->drawable = priv->parentwin; vis->opdraw->drawpixel = GGI_X_drawpixel_slave_draw; vis->opdraw->drawpixel_nc = GGI_X_drawpixel_nc_slave_draw; vis->opdraw->drawhline = GGI_X_drawhline_slave_draw; vis->opdraw->drawhline_nc = GGI_X_drawhline_nc_slave_draw; vis->opdraw->drawvline = GGI_X_drawvline_slave_draw; vis->opdraw->drawvline_nc = GGI_X_drawvline_nc_slave_draw; vis->opdraw->drawline = GGI_X_drawline_slave_draw; vis->opdraw->drawbox = GGI_X_drawbox_slave_draw; vis->opdraw->copybox = GGI_X_copybox_slave_draw; vis->opdraw->fillscreen = GGI_X_fillscreen_slave_draw; _ggi_x_readback_fontdata(vis); if (priv->fontimg) { vis->opdraw->putc = GGI_X_putc_slave_draw; vis->opdraw->getcharsize = GGI_X_getcharsize_font; } /* else stub will do it */ if (priv->fb) return 0; vis->opgc->gcchanged = GGI_X_gcchanged; vis->opdraw->setorigin = GGI_X_setorigin_child; vis->opdraw->setdisplayframe = GGI_X_setdisplayframe_child; vis->opdisplay->flush = GGI_X_flush_draw; vis->opdraw->drawpixel = GGI_X_drawpixel_draw; vis->opdraw->drawpixel_nc = GGI_X_drawpixel_draw; vis->opdraw->putpixel = GGI_X_putpixel_draw; vis->opdraw->putpixel_nc = GGI_X_putpixel_draw; vis->opdraw->getpixel_nc = GGI_X_getpixel_nc_draw; vis->opdraw->drawhline = GGI_X_drawhline_draw; vis->opdraw->drawhline_nc = GGI_X_drawhline_draw; vis->opdraw->puthline = GGI_X_puthline_draw; vis->opdraw->gethline = GGI_X_gethline_draw; vis->opdraw->drawvline = GGI_X_drawvline_draw; vis->opdraw->drawvline_nc = GGI_X_drawvline_draw; vis->opdraw->drawline = GGI_X_drawline_draw; vis->opdraw->putvline = GGI_X_putvline_draw; vis->opdraw->getvline = GGI_X_getvline_draw; vis->opdraw->drawbox = GGI_X_drawbox_draw; vis->opdraw->putbox = GGI_X_putbox_draw; vis->opdraw->copybox = GGI_X_copybox_draw; vis->opdraw->fillscreen = GGI_X_fillscreen_draw; vis->opdraw->putc = GGI_X_putc_draw; vis->opdraw->getcharsize = GGI_X_getcharsize_font; if (!priv->slave) vis->opdraw->getbox = GGI_X_getbox_draw; return 0; }
int GGI_X_getvline_slave(ggi_visual *vis, int x, int y, int h, void *data) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); /* Slave is always up to date */ return (priv->slave->opdraw->getvline(priv->slave, x, y, h, data)); }
int GGI_X_drawvline_nc_slave(ggi_visual *vis, int x, int y, int h) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); priv->slave->opdraw->drawvline_nc(priv->slave, x, y, h); GGI_X_DIRTY(vis, x, y, 1, h); return 0; }
int GGI_X_setreadframe_slave(struct ggi_visual *vis, int num) { int err; ggi_x_priv *priv; priv = GGIX_PRIV(vis); err = _ggi_default_setreadframe(vis, num); if (err) return err; err = priv->slave->opdraw->setreadframe(priv->slave, num); return err; }
int GGI_X_putvline_slave(ggi_visual *vis, int x, int y, int h, const void *data) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); /* Use slave's clipping for depth adjustment */ priv->slave->opdraw->putvline(priv->slave, x, y, h, data); LIBGGICLIP_XYH(vis, x, y, h); GGI_X_DIRTY(vis, x, y, 1, h); return 0; }
int GGI_X_db_acquire(struct ggi_resource *res, uint32_t actype) { struct ggi_visual *vis; vis = res->priv; if ((LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) && (vis->w_frame->resource == res) && (actype & GGI_ACTYPE_WRITE)) { if (GGIX_PRIV(vis)->opmansync) MANSYNC_stop(vis); } res->curactype = actype; res->count++; return 0; }
int GGI_X_drawvline_draw(ggi_visual *vis, int x, int y, int h) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); 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; }
static void GGI_helper_x_evi_finish(struct ggi_helper *helper) { ggi_x_priv *xpriv = GGIX_PRIV(helper->visual); ggi_xevi_priv *priv = xpriv->evilist; if (priv != NULL) { if (priv->evi != NULL) XFree (priv->evi); free(priv); } }
static void GGI_DBE_swap(struct ggi_visual *vis) { ggi_x_priv *priv; XdbeSwapInfo swapInfo; priv = GGIX_PRIV(vis); /* Set swapping informations */ swapInfo.swap_window = priv->win; swapInfo.swap_action = XdbeUndefined; XdbeSwapBuffers(priv->disp, &swapInfo, 1); /* Swap buffer */ }
static void GGI_helper_x_dbe_finish(struct ggi_helper *helper) { #if 0 ggi_x_priv *priv = GGIX_PRIV(helper->visual); XdbeBackBuffer backBuffer; /* Deallocate back buffer */ if(!XdbeDeallocateBackBufferName(priv->disp, priv->drawable)) { DPRINT_LIBS("X: DOUBLE-BUFFER: Unable to deallocate back buffer.\n"); return GGI_EFATAL; } #endif }
int GGI_X_drawvline_slave_draw(ggi_visual *vis, int x, int y, int h) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); LIBGGICLIP_XYH(vis, x, y, h); 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_db_release(struct ggi_resource *res) { struct ggi_visual *vis; vis = res->priv; if ((vis->w_frame->resource == res) && (res->curactype & GGI_ACTYPE_WRITE)) { if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) { if (GGIX_PRIV(vis)->opmansync) MANSYNC_start(vis); } else { _ggiFlush(vis); } } res->curactype = 0; res->count--; return 0; }
static void GGI_helper_x_shm_finish(struct ggi_helper *helper) { ggi_x_priv *priv; DPRINT_LIBS("GGI_helper_x_shm_teardown(%p) called\n", helper); priv = GGIX_PRIV(helper->visual); if (priv && priv->freefb) { priv->freefb(helper->visual); priv->freefb = NULL; } return; }
static int GGI_helper_x_dbe_setup(struct ggi_helper *helper, const char *args, void *argptr) { ggi_x_priv *priv = GGIX_PRIV(helper->visual); int major_version, minor_version; Status rc; /* Check if DBE is present before initialising */ rc = XdbeQueryExtension(priv->disp, &major_version, &minor_version); if (rc != True) return GGI_ENOFUNC; DPRINT_LIBS("X: DOUBLE-BUFFER: DBE version %i.%i\n", major_version, minor_version); return GGI_OK; }
int GGI_X_setorigin_child(struct ggi_visual *vis, int x, int y) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); if (x < 0) return GGI_EARGINVAL; if (y < 0) return GGI_EARGINVAL; if (x > LIBGGI_VIRTX(vis) - LIBGGI_X(vis)) return GGI_EARGINVAL; if (y > LIBGGI_VIRTY(vis) - LIBGGI_Y(vis)) return GGI_EARGINVAL; vis->origin_x = x; vis->origin_y = y; XMoveWindow(priv->disp, priv->win, -x, - y - priv->pf_offset); GGI_X_MAYBE_SYNC(vis); return 0; }
int GGI_X_fillscreen_draw(ggi_visual *vis) { ggi_x_priv *priv; XGCValues gcValue; GC gc; priv = GGIX_PRIV(vis); DPRINT("X_fillscreen_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; /* Note: 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; /* CLIPSIZE macro is defined above in * GGI_X_fillscreen_slave_draw() */ XFillRectangle(priv->disp, priv->drawable, gc, LIBGGI_GC(vis)->cliptl.x, y, CLIPSIZE(x), CLIPSIZE(y) ); } else { XFillRectangle(priv->disp, priv->drawable, gc, 0, 0, LIBGGI_VIRTX(vis), LIBGGI_VIRTY(vis) ); } GGI_X_MAYBE_SYNC(vis); GGI_X_UNLOCK_XLIB(vis); DPRINT_LIBS("X_fillscreen_draw exit!\n"); return 0; }
int GGI_X_expose(void *arg, int x, int y, int w, int h) { struct ggi_visual *vis; ggi_x_priv *priv; int err; vis = arg; priv = GGIX_PRIV(vis); /* Expose event may be queued from a previous (larger) mode. In that case we just ignore it and return. */ if ((x+w > LIBGGI_VIRTX(vis)) || y+h > LIBGGI_VIRTY(vis) * (vis->d_frame_num + 1)) return 0; priv->fullflush = 1; err = _ggiInternFlush(vis, x, y, w, h, 2); priv->fullflush = 0; return err; }
int GGI_X_setdisplayframe_child(struct ggi_visual *vis, int num) { ggi_x_priv *priv; struct gii_xwin_cmddata_set_page_offset data; priv = GGIX_PRIV(vis); if (_ggi_db_find_frame(vis, num) == NULL) return GGI_EARGINVAL; vis->d_frame_num = num; priv->pf_offset = num*LIBGGI_VIRTY(vis); XMoveWindow(priv->disp, priv->win, -vis->origin_x, - vis->origin_y - priv->pf_offset); GGI_X_MAYBE_SYNC(vis); data.yoffset=priv->pf_offset; ggControl(priv->inp->channel, GII_CMDCODE_SET_PAGE_OFFSET, &data); return 0; }
static int ggi_xdga_getmodelist(struct ggi_visual * vis) { ggi_x_priv *priv; XDGAMode *modes; int screen; priv = GGIX_PRIV(vis); screen = priv->vilist[priv->viidx].vi->screen; priv->modes_num = 0; priv->modes_priv = modes = XDGAQueryModes(priv->disp, screen, &(priv->modes_num)); if (priv->modes_priv == NULL) return GGI_ENODEVICE; if (priv->modes_num <= 0) return GGI_ENODEVICE; return GGI_OK; }
int GGI_X_fillscreen_slave(ggi_visual *vis) { ggi_x_priv *priv; priv = GGIX_PRIV(vis); DPRINT("X_fillscreen_slave enter!\n"); 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)) { GGI_X_DIRTY(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); } else { GGI_X_DIRTY(vis, 0, 0, LIBGGI_VIRTX(vis), LIBGGI_VIRTY(vis)); } priv->slave->opdraw->fillscreen(priv->slave); return GGI_OK; }
/* XImage allocation for normal client-side buffer */ static void _ggi_xshm_free_ximage(struct ggi_visual *vis) { ggi_x_priv *priv; XShmSegmentInfo *myshminfo; priv = GGIX_PRIV(vis); myshminfo = priv->priv; if (myshminfo == NULL) return; if (priv->slave) { struct gg_stem *stem = priv->slave->instance.stem; ggiClose(priv->slave->instance.stem); ggDelStem(stem); priv->slave = NULL; } if (priv->ximage) { XShmDetach(priv->disp, myshminfo); /* Seems OK to destroy image before fb for SHM */ XDestroyImage(priv->ximage); shmdt(myshminfo->shmaddr); /* shmid has already been removed, see below. */ priv->ximage = NULL; priv->fb = NULL; } if (priv->fb) { free(priv->fb); priv->fb = NULL; } LIB_ASSERT(priv->slave == NULL, "priv->slave: wild pointer\n"); LIB_ASSERT(priv->ximage == NULL, "priv->ximage: wild pointer\n"); LIB_ASSERT(priv->fb == NULL, "priv->fb: wild pointer\n"); free(myshminfo); priv->priv = NULL; _ggi_free_dbs(vis); }
int GGI_X_putvline_draw(ggi_visual *vis, int x, int y, int h, const void *data) { XImage *ximg; ggi_x_priv *priv; priv = GGIX_PRIV(vis); GGI_X_LOCK_XLIB(vis); #warning 1,2,4-bit support needed. ximg = _ggi_x_create_ximage( vis, (char*)data, 1, h); if (ximg == NULL) return GGI_ENOMEM; XPutImage(priv->disp, priv->drawable, priv->gc, ximg, 0, 0, x, GGI_X_WRITE_Y, 1, (unsigned)h); #ifndef HAVE_XINITIMAGE XFree(ximg); #else free(ximg); #endif GGI_X_MAYBE_SYNC(vis); GGI_X_UNLOCK_XLIB(vis); return 0; }
int GGI_X_setwriteframe_slave(struct ggi_visual *vis, int num) { int err; ggi_x_priv *priv; ggi_directbuffer *db; db = _ggi_db_find_frame(vis, num); if (db == NULL) { return GGI_ENOSPACE; } priv = GGIX_PRIV(vis); if (LIBGGI_FLAGS(vis) & GGIFLAG_TIDYBUF) { if (priv->opmansync && (GGI_ACTYPE_WRITE & (vis->w_frame->resource->curactype ^ db->resource->curactype))) { vis->w_frame_num = num; vis->w_frame = db; if (GGI_ACTYPE_WRITE & db->resource->curactype) MANSYNC_stop(vis); else { MANSYNC_start(vis); } } else { vis->w_frame_num = num; vis->w_frame = db; } } else { _ggiFlush(vis); vis->w_frame_num = num; vis->w_frame = db; } /* Dirty region doesn't span frames. */ priv->dirtytl.x = 1; priv->dirtybr.x = 0; err = priv->slave->opdraw->setwriteframe(priv->slave, num); return err; }
static int GGI_DBE_create_window_drawable (struct ggi_visual *vis) { ggi_x_priv *priv = GGIX_PRIV(vis); XdbeBackBuffer backBuffer; if(priv->win == None) return GGI_ENODEVICE; priv->drawable = priv->win; /* Allocate back buffer */ backBuffer = XdbeAllocateBackBufferName(priv->disp, priv->win, XdbeUntouched); if (backBuffer != None) { priv->drawable = backBuffer; } else { DPRINT_LIBS("X: DOUBLE-BUFFER: Back buffer allocation failed\n"); return GGI_EFATAL; } 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_createfb(struct ggi_visual *vis) { char target[GGI_MAX_APILEN]; ggi_mode tm; ggi_x_priv *priv; int err, i; err = GGI_OK; priv = GGIX_PRIV(vis); DPRINT_MODE("_ggi_x_createfb(%p) called\n", vis); DPRINT("viidx = %i\n", priv->viidx); _ggi_x_freefb(vis); DPRINT_MODE("Creating vanilla XImage client-side buffer\n"); priv->fb = calloc(1, GT_ByPPP(LIBGGI_VIRTX(vis),LIBGGI_GT(vis)) * LIBGGI_VIRTY(vis) * LIBGGI_MODE(vis)->frames); if (priv->fb == NULL) { DPRINT("_ggi_x_createfb: XImage buffer allocation failed.\n"); err = GGI_ENOMEM; goto err0; } /* We assume LIBGGI_MODE(vis) structure has already been filled out */ memcpy(&tm, LIBGGI_MODE(vis), sizeof(ggi_mode)); /* Make sure we do not fail due to physical size constraints, * which are meaningless on a memory visual. */ tm.size.x = tm.size.y = GGI_AUTO; i = 0; memset(target, '\0', sizeof(target)); i += snprintf(target, sizeof(target), "display-memory:-noblank:-pixfmt="); _ggi_build_pixfmtstr(vis, target + i, sizeof(target) - i, 1); i = strlen(target); snprintf(target + i, sizeof(target) - i, ":-physz=%i,%i:pointer", LIBGGI_MODE(vis)->size.x, LIBGGI_MODE(vis)->size.y); err = _ggi_openslave(vis, target, &tm); if (err) goto err1; priv->ximage = _ggi_x_create_ximage( vis, (char*)priv->fb, LIBGGI_VIRTX(vis), LIBGGI_VIRTY(vis) ); if (priv->ximage == NULL) { DPRINT("_ggi_x_createfb: _ggi_x_create_ximage() failed\n"); err = GGI_ENOMEM; goto err1; } err = _ggi_create_dbs(vis); if (err) goto err1; DPRINT_MODE("X: XImage %p and slave visual %p share buffer at %p\n", priv->ximage, priv->slave, priv->fb); return GGI_OK; err1: _ggi_x_freefb(vis); err0: return err; }
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; }