179 lines
5.2 KiB
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,
|
|
|
|
};
|