windowmaker-wl/WINGs/wrender_x11.c

179 lines
5.2 KiB
C

#include "WINGsP.h"
#include "WINGs/WINGsX11.h"
typedef struct {
W_Screen *scr;
} RenderCtxX11;
static void *
render_x11_screen_init(W_Screen *scr)
{
RenderCtxX11 *ctx = wmalloc(sizeof(*ctx));
ctx->scr = scr;
return ctx;
}
static void
render_x11_screen_fini(void *rctx)
{
wfree(rctx);
}
static WMDrawable
render_x11_pixmap_create(void *rctx, unsigned int width, unsigned int height, int depth)
{
RenderCtxX11 *ctx = rctx;
Pixmap p = XCreatePixmap(ctx->scr->display, ctx->scr->rootWin, width, height, depth);
return (WMDrawable)p;
}
static void
render_x11_pixmap_free(void *rctx, WMDrawable pm)
{
RenderCtxX11 *ctx = rctx;
XFreePixmap(ctx->scr->display, (Pixmap)pm);
}
static void
render_x11_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst,
int sx, int sy, unsigned int w, unsigned int h, int dx, int dy)
{
RenderCtxX11 *ctx = rctx;
XCopyArea(ctx->scr->display, (Drawable)src, (Drawable)dst,
ctx->scr->copyGC, sx, sy, w, h, dx, dy);
}
static void
render_x11_draw_line(void *rctx, WMDrawable d, WMColor *color,
int x1, int y1, int x2, int y2)
{
RenderCtxX11 *ctx = rctx;
XDrawLine(ctx->scr->display, (Drawable)d, WMColorGC(color), x1, y1, x2, y2);
}
static void
render_x11_draw_rect(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h)
{
RenderCtxX11 *ctx = rctx;
XDrawRectangle(ctx->scr->display, (Drawable)d, WMColorGC(color), x, y, w, h);
}
static void
render_x11_fill_rect(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h)
{
RenderCtxX11 *ctx = rctx;
XFillRectangle(ctx->scr->display, (Drawable)d, WMColorGC(color), x, y, w, h);
}
static void
render_x11_fill_stippled(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h)
{
RenderCtxX11 *ctx = rctx;
GC gc = ctx->scr->stippleGC;
XSetForeground(ctx->scr->display, gc, color->color.pixel);
XFillRectangle(ctx->scr->display, (Drawable)d, gc, x, y, w, h);
/* Restore default stipple foreground (darkGray) */
XSetForeground(ctx->scr->display, gc, ctx->scr->darkGray->color.pixel);
}
static void
render_x11_composite_pixmap(void *rctx, WMDrawable dst, W_Pixmap *src,
int sx, int sy, unsigned int w, unsigned int h,
int dx, int dy)
{
RenderCtxX11 *ctx = rctx;
Display *dpy = ctx->scr->display;
GC gc = ctx->scr->clipGC;
if (src->mask) {
XSetClipMask(dpy, gc, src->mask);
XSetClipOrigin(dpy, gc, dx - sx, dy - sy);
} else {
XSetClipMask(dpy, gc, WM_NATIVE_NONE);
}
if (src->depth == 1)
XCopyPlane(dpy, src->pixmap, (Drawable)dst, gc, sx, sy, w, h, dx, dy, 1);
else
XCopyArea(dpy, src->pixmap, (Drawable)dst, gc, sx, sy, w, h, dx, dy);
if (src->mask)
XSetClipMask(dpy, gc, WM_NATIVE_NONE);
}
static void
render_x11_fill_polygon(void *rctx, WMDrawable d, WMColor *color,
void *points_v, int npoints)
{
XPoint *points = points_v;
RenderCtxX11 *ctx = rctx;
XFillPolygon(ctx->scr->display, (Drawable)d, WMColorGC(color),
points, npoints, Convex, CoordModeOrigin);
}
static void
render_x11_fill_arc(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h,
int angle1, int angle2)
{
RenderCtxX11 *ctx = rctx;
XFillArc(ctx->scr->display, (Drawable)d, WMColorGC(color),
x, y, w, h, angle1, angle2);
}
static Pixmap
render_x11_create_disabled_mask(void *rctx, Pixmap src_mask,
unsigned int width, unsigned int height)
{
RenderCtxX11 *ctx = rctx;
W_Screen *scr = ctx->scr;
Display *dpy = scr->display;
XGCValues gcv;
Pixmap mask;
mask = XCreatePixmap(dpy, scr->stipple, width, height, 1);
XSetForeground(dpy, scr->monoGC, 0);
XFillRectangle(dpy, mask, scr->monoGC, 0, 0, width, height);
gcv.foreground = 1;
gcv.background = 0;
gcv.stipple = scr->stipple;
gcv.fill_style = FillStippled;
gcv.clip_mask = src_mask;
gcv.clip_x_origin = 0;
gcv.clip_y_origin = 0;
XChangeGC(dpy, scr->monoGC, GCForeground | GCBackground | GCStipple
| GCFillStyle | GCClipMask | GCClipXOrigin | GCClipYOrigin, &gcv);
XFillRectangle(dpy, mask, scr->monoGC, 0, 0, width, height);
gcv.fill_style = FillSolid;
gcv.clip_mask = WM_NATIVE_NONE;
XChangeGC(dpy, scr->monoGC, GCFillStyle | GCClipMask, &gcv);
return mask;
}
const W_RenderBackend W_RenderBackendX11 = {
.screen_init = render_x11_screen_init,
.screen_fini = render_x11_screen_fini,
.pixmap_create = render_x11_pixmap_create,
.pixmap_free = render_x11_pixmap_free,
.pixmap_copy = render_x11_pixmap_copy,
.draw_line = render_x11_draw_line,
.draw_rect = render_x11_draw_rect,
.fill_rect = render_x11_fill_rect,
.fill_stippled = render_x11_fill_stippled,
.composite_pixmap = render_x11_composite_pixmap,
.fill_polygon = render_x11_fill_polygon,
.fill_arc = render_x11_fill_arc,
.create_disabled_mask = render_x11_create_disabled_mask,
};