#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, };