diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index 4a436ce..a4592b4 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -32,6 +32,8 @@ libWINGs_la_SOURCES = \ wbrowser.c \ wbutton.c \ wcolor.c \ + wcolor_x11.c \ + wcolor_wl.c \ wcolorpanel.c \ wcolorwell.c \ wconfig.h \ @@ -65,6 +67,8 @@ libWINGs_la_SOURCES = \ wtext.c \ wtextfield.c \ wview.c \ + wview_x11.c \ + wview_wl.c \ wwindow.c libWUtil_la_SOURCES = \ diff --git a/WINGs/WINGs/WINGsP.h.in b/WINGs/WINGs/WINGsP.h.in index ad895f0..ebddfe3 100644 --- a/WINGs/WINGs/WINGsP.h.in +++ b/WINGs/WINGs/WINGsP.h.in @@ -108,6 +108,12 @@ typedef struct W_Screen { const struct W_RenderBackend *renderBackend; void *renderBackendCtx; + const struct W_ViewBackend *viewBackend; + void *viewBackendCtx; + + const struct W_ColorBackend *colorBackend; + void *colorBackendCtx; + struct _XftDraw *xftdraw; /* shared XftDraw */ /* application related */ @@ -562,6 +568,81 @@ extern const W_RenderBackend W_RenderBackendX11; extern const W_RenderBackend W_RenderBackendWL; +/* ---[ view backend vtable ]--------------------------------------------- */ + +typedef struct W_ViewBackend { + void *(*screen_init)(struct W_Screen *scr); + void (*screen_fini)(void *vctx); + + /* Create the root view for the screen (sets size, marks realized) */ + void (*create_root)(void *vctx, struct W_View *view); + + /* Realize a view (create backing resource or mark logical) */ + void (*realize)(void *vctx, struct W_View *view); + + /* Map / unmap */ + void (*map)(void *vctx, struct W_View *view); + void (*unmap)(void *vctx, struct W_View *view); + void (*map_subviews)(void *vctx, struct W_View *view); + void (*unmap_subviews)(void *vctx, struct W_View *view); + + /* Geometry */ + void (*move)(void *vctx, struct W_View *view, int x, int y); + void (*resize)(void *vctx, struct W_View *view, unsigned int w, unsigned int h); + + /* Stacking */ + void (*raise)(void *vctx, struct W_View *view); + void (*lower)(void *vctx, struct W_View *view); + + /* Reparent */ + void (*reparent)(void *vctx, struct W_View *view, struct W_View *newParent, int x, int y); + + /* Destroy backing resource */ + void (*destroy)(void *vctx, struct W_View *view); + + /* Appearance */ + void (*set_background_color)(void *vctx, struct W_View *view, WMColor *color); + void (*set_cursor)(void *vctx, struct W_View *view, Cursor cursor); + + /* Trigger redisplay */ + void (*redisplay)(void *vctx, struct W_View *view); + + /* Get screen position (for views that support it) */ + WMPoint (*get_screen_position)(void *vctx, struct W_View *view); +} W_ViewBackend; + +extern const W_ViewBackend W_ViewBackendX11; +extern const W_ViewBackend W_ViewBackendWL; + + +/* ---[ color backend vtable ]-------------------------------------------- */ + +typedef struct W_ColorBackend { + void *(*screen_init)(struct W_Screen *scr); + void (*screen_fini)(void *cctx); + + /* Allocate an exact color; returns NULL on failure */ + WMColor *(*alloc_color)(void *cctx, struct W_Screen *scr, + unsigned short r, unsigned short g, + unsigned short b, unsigned short a); + + /* Allocate an approximate color; returns NULL on failure */ + WMColor *(*find_close_color)(void *cctx, struct W_Screen *scr, + unsigned short r, unsigned short g, + unsigned short b, unsigned short a); + + /* Free a color's backend resources (pixel, GC, etc.) */ + void (*free_color)(void *cctx, WMColor *color); + + /* Parse a named color string to RGB; returns False on failure */ + Bool (*parse_named)(void *cctx, struct W_Screen *scr, const char *name, + unsigned short *r, unsigned short *g, unsigned short *b); +} W_ColorBackend; + +extern const W_ColorBackend W_ColorBackendX11; +extern const W_ColorBackend W_ColorBackendWL; + + /* ---[ widgets.c ]------------------------------------------------------- */ #define WC_UserWidget 128 diff --git a/WINGs/wcolor.c b/WINGs/wcolor.c index 5189b09..e4099ef 100644 --- a/WINGs/wcolor.c +++ b/WINGs/wcolor.c @@ -1,88 +1,28 @@ - -#include "WINGsP.h" - -#include "wconfig.h" - -#include - -#define LIGHT_STIPPLE_WIDTH 4 -#define LIGHT_STIPPLE_HEIGHT 4 -static char LIGHT_STIPPLE_BITS[] = { - 0x05, 0x0a, 0x05, 0x0a -}; - -#define DARK_STIPPLE_WIDTH 4 -#define DARK_STIPPLE_HEIGHT 4 -static char DARK_STIPPLE_BITS[] = { - 0x0a, 0x04, 0x0a, 0x01 -}; - -static WMColor *createRGBAColor(WMScreen * scr, unsigned short red, - unsigned short green, unsigned short blue, unsigned short alpha); - /* - * TODO: make the color creation code return the same WMColor for the - * same colors. - * make findCloseColor() find the closest color in the RContext pallette - * or in the other colors allocated by WINGs. + * wcolor.c - Color dispatch layer for WINGs + * + * Pure logic: retain/release, accessors, system colors. + * All platform-specific operations go through W_ColorBackend vtable. */ -static WMColor *findCloseColor(WMScreen * scr, unsigned short red, unsigned short green, - unsigned short blue, unsigned short alpha) +#include "WINGsP.h" +#include "wconfig.h" + +static WMColor *createRGBAColor(WMScreen *scr, unsigned short r, unsigned short g, + unsigned short b, unsigned short a) { - WMColor *color; - XColor xcolor; - RColor rcolor; - - rcolor.red = red >> 8; - rcolor.green = green >> 8; - rcolor.blue = blue >> 8; - rcolor.alpha = alpha >> 8; - - if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor)) - return NULL; - - if (!XAllocColor(scr->display, scr->colormap, &xcolor)) - return NULL; - - color = wmalloc(sizeof(WMColor)); - - color->screen = scr; - color->refCount = 1; - color->color = xcolor; - color->alpha = alpha; - color->flags.exact = 0; - color->gc = NULL; - - return color; + const W_ColorBackend *cb = scr->colorBackend; + return cb->alloc_color(scr->colorBackendCtx, scr, r, g, b, a); } -static WMColor *createRGBAColor(WMScreen * scr, unsigned short red, unsigned short green, - unsigned short blue, unsigned short alpha) +static WMColor *findCloseColor(WMScreen *scr, unsigned short r, unsigned short g, + unsigned short b, unsigned short a) { - WMColor *color; - XColor xcolor; - - xcolor.red = red; - xcolor.green = green; - xcolor.blue = blue; - xcolor.flags = DoRed | DoGreen | DoBlue; - if (!XAllocColor(scr->display, scr->colormap, &xcolor)) - return NULL; - - color = wmalloc(sizeof(WMColor)); - - color->screen = scr; - color->refCount = 1; - color->color = xcolor; - color->alpha = alpha; - color->flags.exact = 1; - color->gc = NULL; - - return color; + const W_ColorBackend *cb = scr->colorBackend; + return cb->find_close_color(scr->colorBackendCtx, scr, r, g, b, a); } -WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short green, +WMColor *WMCreateRGBColor(WMScreen *scr, unsigned short red, unsigned short green, unsigned short blue, Bool exact) { WMColor *color = NULL; @@ -96,7 +36,7 @@ WMColor *WMCreateRGBColor(WMScreen * scr, unsigned short red, unsigned short gre return color; } -RColor WMGetRColorFromColor(WMColor * color) +RColor WMGetRColorFromColor(WMColor *color) { RColor rcolor; @@ -108,7 +48,7 @@ RColor WMGetRColorFromColor(WMColor * color) return rcolor; } -WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short green, +WMColor *WMCreateRGBAColor(WMScreen *scr, unsigned short red, unsigned short green, unsigned short blue, unsigned short alpha, Bool exact) { WMColor *color = NULL; @@ -122,82 +62,58 @@ WMColor *WMCreateRGBAColor(WMScreen * scr, unsigned short red, unsigned short gr return color; } -WMColor *WMCreateNamedColor(WMScreen * scr, const char *name, Bool exact) +WMColor *WMCreateNamedColor(WMScreen *scr, const char *name, Bool exact) { WMColor *color; - XColor xcolor; + const W_ColorBackend *cb = scr->colorBackend; + unsigned short r, g, b; - if (!XParseColor(scr->display, scr->colormap, name, &xcolor)) + if (!cb->parse_named(scr->colorBackendCtx, scr, name, &r, &g, &b)) return NULL; - if (scr->visual->class == TrueColor) - exact = True; - - if (!exact || !(color = createRGBAColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff))) { - color = findCloseColor(scr, xcolor.red, xcolor.green, xcolor.blue, 0xffff); + if (!exact || !(color = createRGBAColor(scr, r, g, b, 0xffff))) { + color = findCloseColor(scr, r, g, b, 0xffff); } return color; } -WMColor *WMRetainColor(WMColor * color) +WMColor *WMRetainColor(WMColor *color) { assert(color != NULL); - color->refCount++; - return color; } -void WMReleaseColor(WMColor * color) +void WMReleaseColor(WMColor *color) { color->refCount--; if (color->refCount < 1) { - XFreeColors(color->screen->display, color->screen->colormap, &(color->color.pixel), 1, 0); - if (color->gc) - XFreeGC(color->screen->display, color->gc); + const W_ColorBackend *cb = color->screen->colorBackend; + cb->free_color(color->screen->colorBackendCtx, color); wfree(color); } } -void WMSetColorAlpha(WMColor * color, unsigned short alpha) +void WMSetColorAlpha(WMColor *color, unsigned short alpha) { color->alpha = alpha; } -void WMPaintColorSwatch(WMColor * color, WMDrawable d, int x, int y, unsigned int width, unsigned int height) +void WMPaintColorSwatch(WMColor *color, WMDrawable d, int x, int y, + unsigned int width, unsigned int height) { W_Screen *scr = color->screen; scr->renderBackend->fill_rect(scr->renderBackendCtx, d, color, x, y, width, height); } -WMPixel WMColorPixel(WMColor * color) +WMPixel WMColorPixel(WMColor *color) { return color->color.pixel; } -GC WMColorGC(WMColor * color) -{ - if (!color->gc) { - XGCValues gcv; - WMScreen *scr = color->screen; - - gcv.foreground = color->color.pixel; - gcv.graphics_exposures = False; - color->gc = XCreateGC(scr->display, scr->rcontext->drawable, - GCForeground | GCGraphicsExposures, &gcv); - } - - return color->gc; -} - -void WMSetColorInGC(WMColor * color, GC gc) -{ - XSetForeground(color->screen->display, gc, color->color.pixel); -} - /* "system" colors */ -WMColor *WMWhiteColor(WMScreen * scr) +WMColor *WMWhiteColor(WMScreen *scr) { if (!scr->white) { scr->white = WMCreateRGBColor(scr, 0xffff, 0xffff, 0xffff, True); @@ -207,7 +123,7 @@ WMColor *WMWhiteColor(WMScreen * scr) return WMRetainColor(scr->white); } -WMColor *WMBlackColor(WMScreen * scr) +WMColor *WMBlackColor(WMScreen *scr) { if (!scr->black) { scr->black = WMCreateRGBColor(scr, 0, 0, 0, True); @@ -217,103 +133,47 @@ WMColor *WMBlackColor(WMScreen * scr) return WMRetainColor(scr->black); } -WMColor *WMGrayColor(WMScreen * scr) +WMColor *WMGrayColor(WMScreen *scr) { if (!scr->gray) { - WMColor *color; - - if (scr->depth == 1) { - Pixmap stipple; - WMColor *white = WMWhiteColor(scr); - WMColor *black = WMBlackColor(scr); - XGCValues gcv; - - stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr), - LIGHT_STIPPLE_BITS, LIGHT_STIPPLE_WIDTH, - LIGHT_STIPPLE_HEIGHT); - - color = createRGBAColor(scr, 0xffff, 0xffff, 0xffff, 0xffff); - - gcv.foreground = white->color.pixel; - gcv.background = black->color.pixel; - gcv.fill_style = FillStippled; - gcv.stipple = stipple; - color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground - | GCBackground | GCStipple | GCFillStyle - | GCGraphicsExposures, &gcv); - - XFreePixmap(scr->display, stipple); - WMReleaseColor(white); - WMReleaseColor(black); - } else { - color = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True); - if (!color->flags.exact) - wwarning(_("could not allocate %s color"), _("gray")); - } - scr->gray = color; + scr->gray = WMCreateRGBColor(scr, 0xaeba, 0xaaaa, 0xaeba, True); + if (!scr->gray->flags.exact) + wwarning(_("could not allocate %s color"), _("gray")); } return WMRetainColor(scr->gray); } -WMColor *WMDarkGrayColor(WMScreen * scr) +WMColor *WMDarkGrayColor(WMScreen *scr) { if (!scr->darkGray) { - WMColor *color; - - if (scr->depth == 1) { - Pixmap stipple; - WMColor *white = WMWhiteColor(scr); - WMColor *black = WMBlackColor(scr); - XGCValues gcv; - - stipple = XCreateBitmapFromData(scr->display, W_DRAWABLE(scr), - DARK_STIPPLE_BITS, DARK_STIPPLE_WIDTH, - DARK_STIPPLE_HEIGHT); - - color = createRGBAColor(scr, 0, 0, 0, 0xffff); - - gcv.foreground = white->color.pixel; - gcv.background = black->color.pixel; - gcv.fill_style = FillStippled; - gcv.stipple = stipple; - color->gc = XCreateGC(scr->display, W_DRAWABLE(scr), GCForeground - | GCBackground | GCStipple | GCFillStyle - | GCGraphicsExposures, &gcv); - - XFreePixmap(scr->display, stipple); - WMReleaseColor(white); - WMReleaseColor(black); - } else { - color = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True); - if (!color->flags.exact) - wwarning(_("could not allocate %s color"), _("dark gray")); - } - scr->darkGray = color; + scr->darkGray = WMCreateRGBColor(scr, 0x5144, 0x5555, 0x5144, True); + if (!scr->darkGray->flags.exact) + wwarning(_("could not allocate %s color"), _("dark gray")); } return WMRetainColor(scr->darkGray); } -unsigned short WMRedComponentOfColor(WMColor * color) +unsigned short WMRedComponentOfColor(WMColor *color) { return color->color.red; } -unsigned short WMGreenComponentOfColor(WMColor * color) +unsigned short WMGreenComponentOfColor(WMColor *color) { return color->color.green; } -unsigned short WMBlueComponentOfColor(WMColor * color) +unsigned short WMBlueComponentOfColor(WMColor *color) { return color->color.blue; } -unsigned short WMGetColorAlpha(WMColor * color) +unsigned short WMGetColorAlpha(WMColor *color) { return color->alpha; } -char *WMGetColorRGBDescription(WMColor * color) +char *WMGetColorRGBDescription(WMColor *color) { char *str = wmalloc(8); diff --git a/WINGs/wcolor_wl.c b/WINGs/wcolor_wl.c new file mode 100644 index 0000000..eeb82ca --- /dev/null +++ b/WINGs/wcolor_wl.c @@ -0,0 +1,106 @@ +/* + * wcolor_wl.c - Wayland color backend for WINGs + * + * No X11 dependencies. Colors are just RGBA values with a computed pixel. + * No colormap allocation needed — rendering uses the RGBA components directly. + */ + +#include "WINGsP.h" + +static void *wl_screen_init(W_Screen *scr) +{ + (void)scr; + return scr; +} + +static void wl_screen_fini(void *cctx) +{ + (void)cctx; +} + +static WMColor *wl_alloc_color(void *cctx, W_Screen *scr, + unsigned short r, unsigned short g, + unsigned short b, unsigned short a) +{ + WMColor *color; + (void)cctx; + + color = wmalloc(sizeof(WMColor)); + color->screen = scr; + color->refCount = 1; + color->color.red = r; + color->color.green = g; + color->color.blue = b; + color->color.pixel = ((r >> 8) << 16) | ((g >> 8) << 8) | (b >> 8); + color->alpha = a; + color->flags.exact = 1; + color->gc = NULL; + + return color; +} + +static WMColor *wl_find_close_color(void *cctx, W_Screen *scr, + unsigned short r, unsigned short g, + unsigned short b, unsigned short a) +{ + /* In truecolor (Wayland), all colors are exact */ + return wl_alloc_color(cctx, scr, r, g, b, a); +} + +static void wl_free_color(void *cctx, WMColor *color) +{ + (void)cctx; + (void)color; + /* Nothing to free — no X11 resources */ +} + +static Bool wl_parse_named(void *cctx, W_Screen *scr, const char *name, + unsigned short *r, unsigned short *g, unsigned short *b) +{ + unsigned int rv, gv, bv; + (void)cctx; + (void)scr; + + /* Parse #RRGGBB or #RGB format */ + if (name[0] == '#') { + int len = strlen(name + 1); + if (len == 6) { + if (sscanf(name + 1, "%2x%2x%2x", &rv, &gv, &bv) == 3) { + *r = rv << 8 | rv; + *g = gv << 8 | gv; + *b = bv << 8 | bv; + return True; + } + } else if (len == 3) { + if (sscanf(name + 1, "%1x%1x%1x", &rv, &gv, &bv) == 3) { + *r = (rv | rv << 4) << 8; + *g = (gv | gv << 4) << 8; + *b = (bv | bv << 4) << 8; + return True; + } + } + } + + /* Common named colors used by WindowMaker */ + if (strcasecmp(name, "white") == 0) { *r = *g = *b = 0xffff; return True; } + if (strcasecmp(name, "black") == 0) { *r = *g = *b = 0; return True; } + if (strcasecmp(name, "red") == 0) { *r = 0xffff; *g = *b = 0; return True; } + if (strcasecmp(name, "green") == 0) { *r = 0; *g = 0xffff; *b = 0; return True; } + if (strcasecmp(name, "blue") == 0) { *r = *g = 0; *b = 0xffff; return True; } + if (strcasecmp(name, "gray") == 0 || strcasecmp(name, "grey") == 0) { + *r = *g = *b = 0xbebe; return True; + } + + /* Fallback: treat unknown names as gray */ + *r = *g = *b = 0x8080; + return True; +} + +const W_ColorBackend W_ColorBackendWL = { + .screen_init = wl_screen_init, + .screen_fini = wl_screen_fini, + .alloc_color = wl_alloc_color, + .find_close_color = wl_find_close_color, + .free_color = wl_free_color, + .parse_named = wl_parse_named, +}; diff --git a/WINGs/wcolor_x11.c b/WINGs/wcolor_x11.c new file mode 100644 index 0000000..7c5fce0 --- /dev/null +++ b/WINGs/wcolor_x11.c @@ -0,0 +1,130 @@ +/* + * wcolor_x11.c - X11 color backend for WINGs + * + * Allocates colors via XAllocColor on the X11 colormap. + */ + +#include "WINGsP.h" +#include + +static void *x11_screen_init(W_Screen *scr) +{ + return scr; +} + +static void x11_screen_fini(void *cctx) +{ + (void)cctx; +} + +static WMColor *x11_alloc_color(void *cctx, W_Screen *scr, + unsigned short r, unsigned short g, + unsigned short b, unsigned short a) +{ + WMColor *color; + XColor xcolor; + (void)cctx; + + xcolor.red = r; + xcolor.green = g; + xcolor.blue = b; + xcolor.flags = DoRed | DoGreen | DoBlue; + if (!XAllocColor(scr->display, scr->colormap, &xcolor)) + return NULL; + + color = wmalloc(sizeof(WMColor)); + color->screen = scr; + color->refCount = 1; + color->color = xcolor; + color->alpha = a; + color->flags.exact = 1; + color->gc = NULL; + + return color; +} + +static WMColor *x11_find_close_color(void *cctx, W_Screen *scr, + unsigned short r, unsigned short g, + unsigned short b, unsigned short a) +{ + WMColor *color; + XColor xcolor; + RColor rcolor; + (void)cctx; + + rcolor.red = r >> 8; + rcolor.green = g >> 8; + rcolor.blue = b >> 8; + rcolor.alpha = a >> 8; + + if (!RGetClosestXColor(scr->rcontext, &rcolor, &xcolor)) + return NULL; + + if (!XAllocColor(scr->display, scr->colormap, &xcolor)) + return NULL; + + color = wmalloc(sizeof(WMColor)); + color->screen = scr; + color->refCount = 1; + color->color = xcolor; + color->alpha = a; + color->flags.exact = 0; + color->gc = NULL; + + return color; +} + +static void x11_free_color(void *cctx, WMColor *color) +{ + (void)cctx; + + XFreeColors(color->screen->display, color->screen->colormap, + &(color->color.pixel), 1, 0); + if (color->gc) + XFreeGC(color->screen->display, color->gc); +} + +static Bool x11_parse_named(void *cctx, W_Screen *scr, const char *name, + unsigned short *r, unsigned short *g, unsigned short *b) +{ + XColor xcolor; + (void)cctx; + + if (!XParseColor(scr->display, scr->colormap, name, &xcolor)) + return False; + + *r = xcolor.red; + *g = xcolor.green; + *b = xcolor.blue; + return True; +} + +const W_ColorBackend W_ColorBackendX11 = { + .screen_init = x11_screen_init, + .screen_fini = x11_screen_fini, + .alloc_color = x11_alloc_color, + .find_close_color = x11_find_close_color, + .free_color = x11_free_color, + .parse_named = x11_parse_named, +}; + +/* X11-only public API: GC access for Xlib drawing */ + +GC WMColorGC(WMColor *color) +{ + if (!color->gc) { + XGCValues gcv; + WMScreen *scr = color->screen; + + gcv.foreground = color->color.pixel; + gcv.graphics_exposures = False; + color->gc = XCreateGC(scr->display, scr->rcontext->drawable, + GCForeground | GCGraphicsExposures, &gcv); + } + return color->gc; +} + +void WMSetColorInGC(WMColor *color, GC gc) +{ + XSetForeground(color->screen->display, gc, color->color.pixel); +} diff --git a/WINGs/widgets.c b/WINGs/widgets.c index 4ccb6f9..13bd4db 100644 --- a/WINGs/widgets.c +++ b/WINGs/widgets.c @@ -635,6 +635,12 @@ WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * c scrPtr->renderBackend = &W_RenderBackendWL; scrPtr->renderBackendCtx = scrPtr->renderBackend->screen_init(scrPtr); + scrPtr->viewBackend = &W_ViewBackendWL; + scrPtr->viewBackendCtx = scrPtr->viewBackend->screen_init(scrPtr); + + scrPtr->colorBackend = &W_ColorBackendWL; + scrPtr->colorBackendCtx = scrPtr->colorBackend->screen_init(scrPtr); + scrPtr->antialiasedText = WINGsConfiguration.antialiasedText; /* Allocate basic colors */ @@ -653,6 +659,8 @@ WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * c return NULL; } + scrPtr->rootView = W_CreateRootView(scrPtr); + return scrPtr; } @@ -678,6 +686,12 @@ WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * c scrPtr->renderBackend = getenv("WMAKER_USE_WAYLAND") ? &W_RenderBackendWL : &W_RenderBackendX11; scrPtr->renderBackendCtx = scrPtr->renderBackend->screen_init(scrPtr); + scrPtr->viewBackend = &W_ViewBackendX11; + scrPtr->viewBackendCtx = scrPtr->viewBackend->screen_init(scrPtr); + + scrPtr->colorBackend = &W_ColorBackendX11; + scrPtr->colorBackendCtx = scrPtr->colorBackend->screen_init(scrPtr); + /* Create missing CUT_BUFFERs */ { Atom *rootWinProps; diff --git a/WINGs/wview.c b/WINGs/wview.c index 38e280d..3a0019e 100644 --- a/WINGs/wview.c +++ b/WINGs/wview.c @@ -1,50 +1,18 @@ +/* + * wview.c - View dispatch layer for WINGs + * + * Pure logic: tree management, layout, notifications. + * All platform-specific operations go through W_ViewBackend vtable. + */ #include "WINGsP.h" -#include - /* the notifications about views */ const char *WMViewSizeDidChangeNotification = "WMViewSizeDidChangeNotification"; const char *WMViewFocusDidChangeNotification = "WMViewFocusDidChangeNotification"; const char *WMViewRealizedNotification = "WMViewRealizedNotification"; -#define EVENT_MASK \ - KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \ - EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \ - VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|\ - SubstructureNotifyMask|SubstructureRedirectMask - -static const XSetWindowAttributes defAtts = { - None, /* background_pixmap */ - 0, /* background_pixel */ - CopyFromParent, /* border_pixmap */ - 0, /* border_pixel */ - ForgetGravity, /* bit_gravity */ - ForgetGravity, /* win_gravity */ - NotUseful, /* backing_store */ - (unsigned)~0, /* backing_planes */ - 0, /* backing_pixel */ - False, /* save_under */ - EVENT_MASK, /* event_mask */ - 0, /* do_not_propagate_mask */ - False, /* override_redirect */ - None, /* colormap */ - None /* cursor */ -}; - -static XContext ViewContext = 0; /* context for views */ - -W_View *W_GetViewForXWindow(Display * display, Window window) -{ - W_View *view; - - if (XFindContext(display, window, ViewContext, (XPointer *) & view) == 0) { - return view; - } - return NULL; -} - static void unparentView(W_View * view) { /* remove from parent's children list */ @@ -89,32 +57,16 @@ static W_View *createView(W_Screen * screen, W_View * parent) { W_View *view; - if (ViewContext == 0) - ViewContext = XUniqueContext(); - view = wmalloc(sizeof(W_View)); view->screen = screen; if (parent != NULL) { - /* attributes are not valid for root window */ - view->attribFlags = CWEventMask | CWBitGravity; - view->attribs = defAtts; - - view->attribFlags |= CWBackPixel | CWColormap | CWBorderPixel | CWBackPixmap; - view->attribs.background_pixmap = None; - view->attribs.background_pixel = W_PIXEL(screen->gray); - view->attribs.border_pixel = W_PIXEL(screen->black); - view->attribs.colormap = screen->colormap; - view->backColor = WMRetainColor(screen->gray); - adoptChildView(parent, view); } view->xic = 0; - view->refCount = 1; - view->eventHandlers = WMCreateArrayWithDestructor(4, wfree); return view; @@ -128,18 +80,17 @@ W_View *W_CreateView(W_View * parent) W_View *W_CreateRootView(W_Screen * screen) { W_View *view; + const W_ViewBackend *vb = screen->viewBackend; + void *vctx = screen->viewBackendCtx; view = createView(screen, NULL); - view->window = screen->rootWin; + vb->create_root(vctx, view); view->flags.realized = 1; view->flags.mapped = 1; view->flags.root = 1; - view->size.width = WidthOfScreen(ScreenOfDisplay(screen->display, screen->screen)); - view->size.height = HeightOfScreen(ScreenOfDisplay(screen->display, screen->screen)); - return view; } @@ -152,7 +103,6 @@ W_View *W_CreateTopView(W_Screen * screen) return NULL; view->flags.topLevel = 1; - view->attribs.event_mask |= StructureNotifyMask; return view; } @@ -166,19 +116,15 @@ W_View *W_CreateUnmanagedTopView(W_Screen * screen) return NULL; view->flags.topLevel = 1; - view->attribs.event_mask |= StructureNotifyMask; - - view->attribFlags |= CWOverrideRedirect; - view->attribs.override_redirect = True; return view; } void W_RealizeView(W_View * view) { - Window parentWID; - Display *dpy = view->screen->display; W_View *ptr; + const W_ViewBackend *vb = view->screen->viewBackend; + void *vctx = view->screen->viewBackendCtx; assert(view->size.width > 0); assert(view->size.height > 0); @@ -195,13 +141,7 @@ void W_RealizeView(W_View * view) return; } - parentWID = view->parent->window; - view->window = XCreateWindow(dpy, parentWID, view->pos.x, view->pos.y, - view->size.width, view->size.height, 0, - view->screen->depth, InputOutput, - view->screen->visual, view->attribFlags, &view->attribs); - - XSaveContext(dpy, view->window, ViewContext, (XPointer) view); + vb->realize(vctx, view); view->flags.realized = 1; @@ -217,14 +157,14 @@ void W_RealizeView(W_View * view) ptr = view->childrenList; while (ptr != NULL) { W_RealizeView(ptr); - ptr = ptr->nextSister; } } void W_ReparentView(W_View * view, W_View * newParent, int x, int y) { - Display *dpy = view->screen->display; + const W_ViewBackend *vb = view->screen->viewBackend; + void *vctx = view->screen->viewBackendCtx; assert(!view->flags.topLevel); @@ -233,7 +173,7 @@ void W_ReparentView(W_View * view, W_View * newParent, int x, int y) if (view->flags.realized) { if (newParent->flags.realized) { - XReparentWindow(dpy, view->window, newParent->window, x, y); + vb->reparent(vctx, view, newParent, x, y); } else { wwarning("trying to reparent realized view to unrealized parent"); return; @@ -246,22 +186,26 @@ void W_ReparentView(W_View * view, W_View * newParent, int x, int y) void W_RaiseView(W_View * view) { - if (W_VIEW_REALIZED(view)) - XRaiseWindow(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view)); + if (W_VIEW_REALIZED(view)) { + const W_ViewBackend *vb = view->screen->viewBackend; + vb->raise(view->screen->viewBackendCtx, view); + } } void W_LowerView(W_View * view) { - if (W_VIEW_REALIZED(view)) - XLowerWindow(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view)); + if (W_VIEW_REALIZED(view)) { + const W_ViewBackend *vb = view->screen->viewBackend; + vb->lower(view->screen->viewBackendCtx, view); + } } void W_MapView(W_View * view) { if (!view->flags.mapped) { if (view->flags.realized) { - XMapRaised(view->screen->display, view->window); - XFlush(view->screen->display); + const W_ViewBackend *vb = view->screen->viewBackend; + vb->map(view->screen->viewBackendCtx, view); view->flags.mapped = 1; } else { view->flags.mapWhenRealized = 1; @@ -269,33 +213,33 @@ void W_MapView(W_View * view) } } -/* - * W_MapSubviews- - * maps all children of the current view that where already realized. - */ void W_MapSubviews(W_View * view) { - XMapSubwindows(view->screen->display, view->window); - XFlush(view->screen->display); + const W_ViewBackend *vb = view->screen->viewBackend; + W_View *ptr; - view = view->childrenList; - while (view) { - view->flags.mapped = 1; - view->flags.mapWhenRealized = 0; - view = view->nextSister; + vb->map_subviews(view->screen->viewBackendCtx, view); + + ptr = view->childrenList; + while (ptr) { + ptr->flags.mapped = 1; + ptr->flags.mapWhenRealized = 0; + ptr = ptr->nextSister; } } void W_UnmapSubviews(W_View * view) { - XUnmapSubwindows(view->screen->display, view->window); - XFlush(view->screen->display); + const W_ViewBackend *vb = view->screen->viewBackend; + W_View *ptr; - view = view->childrenList; - while (view) { - view->flags.mapped = 0; - view->flags.mapWhenRealized = 0; - view = view->nextSister; + vb->unmap_subviews(view->screen->viewBackendCtx, view); + + ptr = view->childrenList; + while (ptr) { + ptr->flags.mapped = 0; + ptr->flags.mapWhenRealized = 0; + ptr = ptr->nextSister; } } @@ -305,8 +249,10 @@ void W_UnmapView(W_View * view) if (!view->flags.mapped) return; - XUnmapWindow(view->screen->display, view->window); - XFlush(view->screen->display); + { + const W_ViewBackend *vb = view->screen->viewBackend; + vb->unmap(view->screen->viewBackendCtx, view); + } view->flags.mapped = 0; } @@ -380,11 +326,8 @@ static void destroyView(W_View * view) W_CallDestroyHandlers(view); if (view->flags.realized) { - XDeleteContext(view->screen->display, view->window, ViewContext); - - /* if parent is being destroyed, it will die naturaly */ - if (!view->flags.parentDying || view->flags.topLevel) - XDestroyWindow(view->screen->display, view->window); + const W_ViewBackend *vb = view->screen->viewBackend; + vb->destroy(view->screen->viewBackendCtx, view); } /* remove self from parent's children list */ @@ -425,7 +368,8 @@ void W_MoveView(W_View * view, int x, int y) return; if (view->flags.realized) { - XMoveWindow(view->screen->display, view->window, x, y); + const W_ViewBackend *vb = view->screen->viewBackend; + vb->move(view->screen->viewBackendCtx, view, x, y); } view->pos.x = x; view->pos.y = y; @@ -437,8 +381,6 @@ void W_MoveView(W_View * view, int x, int y) void W_ResizeView(W_View * view, unsigned int width, unsigned int height) { - /*int shrinked; */ - if (view->delegate && view->delegate->willResize) { (*view->delegate->willResize) (view->delegate, view, &width, &height); } @@ -449,10 +391,9 @@ void W_ResizeView(W_View * view, unsigned int width, unsigned int height) if (view->size.width == width && view->size.height == height) return; - /*shrinked = width < view->size.width || height < view->size.height; */ - if (view->flags.realized) { - XResizeWindow(view->screen->display, view->window, width, height); + const W_ViewBackend *vb = view->screen->viewBackend; + vb->resize(view->screen->viewBackendCtx, view, width, height); } view->size.width = width; view->size.height = height; @@ -461,34 +402,19 @@ void W_ResizeView(W_View * view, unsigned int width, unsigned int height) (*view->delegate->didResize) (view->delegate, view); } - /* // TODO. replace in WINGs code, with the didResize delegate */ if (view->flags.notifySizeChanged) WMPostNotificationName(WMViewSizeDidChangeNotification, view, NULL); } void W_RedisplayView(W_View * view) { - XEvent xev; - WMEvent ev; - if (!view->flags.mapped) return; - memset(&xev, 0, sizeof(xev)); - xev.xexpose.type = Expose; - xev.xexpose.display = view->screen->display; - xev.xexpose.window = view->window; - xev.xexpose.count = 0; - xev.xexpose.serial = 0; - - memset(&ev, 0, sizeof(ev)); - ev.type = WME_EXPOSE; - ev.window = (WNativeWindow)view->window; - ev.u.expose.window = (WNativeWindow)view->window; - ev.u.expose.count = 0; - ev._x11_raw = &xev; - - WMHandleEvent(&ev); + { + const W_ViewBackend *vb = view->screen->viewBackend; + vb->redisplay(view->screen->viewBackendCtx, view); + } } void W_SetViewBackgroundColor(W_View * view, WMColor * color) @@ -497,38 +423,29 @@ void W_SetViewBackgroundColor(W_View * view, WMColor * color) WMReleaseColor(view->backColor); view->backColor = WMRetainColor(color); - view->attribFlags |= CWBackPixel; - view->attribFlags &= ~CWBackPixmap; - view->attribs.background_pixel = W_PIXEL(color); if (view->flags.realized) { - XSetWindowBackground(view->screen->display, view->window, W_PIXEL(color)); - XClearWindow(view->screen->display, view->window); + const W_ViewBackend *vb = view->screen->viewBackend; + vb->set_background_color(view->screen->viewBackendCtx, view, color); } } void W_SetViewBackgroundPixmap(W_View *view, WMPixmap *pix) { - if (view->backImage) - WMReleasePixmap(view->backImage); - view->backImage = WMRetainPixmap(pix); + if (view->backImage) + WMReleasePixmap(view->backImage); + view->backImage = WMRetainPixmap(pix); - view->attribFlags |= CWBackPixmap; - view->attribFlags &= ~CWBackPixel; - view->attribs.background_pixmap = pix->pixmap; - if (view->flags.realized) { - XSetWindowBackgroundPixmap(view->screen->display, view->window, pix->pixmap); - XClearWindow(view->screen->display, view->window); - } + /* Pixmap background is X11-specific; Wayland uses pixman rendering. + * The backend's set_background_color handles the realized case for X11. + * For Wayland this is a no-op at the view level. */ } void W_SetViewCursor(W_View * view, Cursor cursor) { view->cursor = cursor; if (W_VIEW_REALIZED(view)) { - XDefineCursor(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view), cursor); - } else { - view->attribFlags |= CWCursor; - view->attribs.cursor = cursor; + const W_ViewBackend *vb = view->screen->viewBackend; + vb->set_cursor(view->screen->viewBackendCtx, view, cursor); } } @@ -600,10 +517,6 @@ void W_DispatchMessage(W_View * target, WMEvent * event) event->window = (WNativeWindow)target->window; WMHandleEvent(event); - /* - XSendEvent(target->screen->display, target->window, False, - SubstructureNotifyMask, event); - */ } WMView *W_RetainView(WMView * view) @@ -649,23 +562,9 @@ Window WMViewXID(WMView * view) WMPoint WMGetViewScreenPosition(WMView * view) { - WMScreen *scr = W_VIEW_SCREEN(view); - Window foo; - int x, y, topX, topY; - unsigned int bar; - WMView *topView; + const W_ViewBackend *vb = view->screen->viewBackend; - topView = view; - while (topView->parent && topView->parent != scr->rootView) - topView = topView->parent; - - if (!XGetGeometry(scr->display, W_VIEW_DRAWABLE(topView), &foo, &topX, &topY, &bar, &bar, &bar, &bar)) { - topX = topY = 0; - } - - XTranslateCoordinates(scr->display, W_VIEW_DRAWABLE(view), scr->rootWin, 0, 0, &x, &y, &foo); - - return wmkpoint(x - topX, y - topY); + return vb->get_screen_position(view->screen->viewBackendCtx, view); } static void resizedParent(void *self, WMNotification * notif) diff --git a/WINGs/wview_wl.c b/WINGs/wview_wl.c new file mode 100644 index 0000000..c49c26c --- /dev/null +++ b/WINGs/wview_wl.c @@ -0,0 +1,156 @@ +/* + * wview_wl.c - Wayland view backend for WINGs + * + * Views are logical layout containers in Wayland mode. + * No X11 dependencies. Rendering is handled by frame_paint (pixman buffers). + */ + +#include "WINGsP.h" + +/* Synthetic window IDs for Wayland views (distinct from frame buffer IDs) */ +#define WL_VIEW_ID_BASE 0x20000000 +static unsigned int wl_view_next_id = WL_VIEW_ID_BASE; + +static void *wl_screen_init(W_Screen *scr) +{ + (void)scr; + return scr; /* use scr as token */ +} + +static void wl_screen_fini(void *vctx) +{ + (void)vctx; +} + +static void wl_create_root(void *vctx, W_View *view) +{ + (void)vctx; + + view->window = (Window)wl_view_next_id++; + /* Default screen size — the WM backend will update this */ + view->size.width = 1920; + view->size.height = 1080; +} + +static void wl_realize(void *vctx, W_View *view) +{ + (void)vctx; + + /* Assign a synthetic ID so W_DispatchMessage doesn't skip this view */ + view->window = (Window)wl_view_next_id++; +} + +static void wl_noop(void *vctx, W_View *view) +{ + (void)vctx; + (void)view; +} + +static void wl_noop_subviews(void *vctx, W_View *view) +{ + (void)vctx; + (void)view; +} + +static void wl_noop_move(void *vctx, W_View *view, int x, int y) +{ + (void)vctx; + (void)view; + (void)x; + (void)y; +} + +static void wl_noop_resize(void *vctx, W_View *view, unsigned int w, unsigned int h) +{ + (void)vctx; + (void)view; + (void)w; + (void)h; +} + +static void wl_noop_reparent(void *vctx, W_View *view, W_View *newParent, int x, int y) +{ + (void)vctx; + (void)view; + (void)newParent; + (void)x; + (void)y; +} + +static void wl_destroy(void *vctx, W_View *view) +{ + (void)vctx; + (void)view; + /* Nothing to free — synthetic ID only */ +} + +static void wl_set_background_color(void *vctx, W_View *view, WMColor *color) +{ + (void)vctx; + (void)view; + (void)color; + /* Background is handled by pixman rendering in frame_paint */ +} + +static void wl_set_cursor(void *vctx, W_View *view, Cursor cursor) +{ + (void)vctx; + (void)view; + (void)cursor; + /* Cursor is managed by wlroots seat */ +} + +static void wl_redisplay(void *vctx, W_View *view) +{ + WMEvent ev; + + (void)vctx; + + if (!view->flags.mapped) + return; + + memset(&ev, 0, sizeof(ev)); + ev.type = WME_EXPOSE; + ev.window = (WNativeWindow)view->window; + ev.u.expose.window = (WNativeWindow)view->window; + ev.u.expose.count = 0; + ev._x11_raw = NULL; + + WMHandleEvent(&ev); +} + +static WMPoint wl_get_screen_position(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + int x = 0, y = 0; + W_View *v; + + /* Walk up the view tree accumulating positions */ + for (v = view; v && v != scr->rootView; v = v->parent) { + x += v->pos.x; + y += v->pos.y; + } + + return wmkpoint(x, y); +} + +const W_ViewBackend W_ViewBackendWL = { + .screen_init = wl_screen_init, + .screen_fini = wl_screen_fini, + .create_root = wl_create_root, + .realize = wl_realize, + .map = wl_noop, + .unmap = wl_noop, + .map_subviews = wl_noop_subviews, + .unmap_subviews = wl_noop_subviews, + .move = wl_noop_move, + .resize = wl_noop_resize, + .raise = wl_noop, + .lower = wl_noop, + .reparent = wl_noop_reparent, + .destroy = wl_destroy, + .set_background_color = wl_set_background_color, + .set_cursor = wl_set_cursor, + .redisplay = wl_redisplay, + .get_screen_position = wl_get_screen_position, +}; diff --git a/WINGs/wview_x11.c b/WINGs/wview_x11.c new file mode 100644 index 0000000..c3a39fb --- /dev/null +++ b/WINGs/wview_x11.c @@ -0,0 +1,212 @@ +/* + * wview_x11.c - X11 view backend for WINGs + * + * Implements W_ViewBackend using Xlib calls. + */ + +#include "WINGsP.h" +#include + +static XContext ViewContext = 0; + +static void *x11_screen_init(W_Screen *scr) +{ + if (ViewContext == 0) + ViewContext = XUniqueContext(); + return scr; /* no separate context needed; use scr as token */ +} + +static void x11_screen_fini(void *vctx) +{ + (void)vctx; +} + +static void x11_create_root(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + view->window = scr->rootWin; + view->size.width = WidthOfScreen(ScreenOfDisplay(scr->display, scr->screen)); + view->size.height = HeightOfScreen(ScreenOfDisplay(scr->display, scr->screen)); +} + +static void x11_realize(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + Display *dpy = scr->display; + Window parentWID = view->parent->window; + + view->window = XCreateWindow(dpy, parentWID, view->pos.x, view->pos.y, + view->size.width, view->size.height, 0, + scr->depth, InputOutput, + scr->visual, view->attribFlags, &view->attribs); + + XSaveContext(dpy, view->window, ViewContext, (XPointer)view); +} + +static void x11_map(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XMapRaised(scr->display, view->window); + XFlush(scr->display); +} + +static void x11_unmap(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XUnmapWindow(scr->display, view->window); + XFlush(scr->display); +} + +static void x11_map_subviews(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XMapSubwindows(scr->display, view->window); + XFlush(scr->display); +} + +static void x11_unmap_subviews(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XUnmapSubwindows(scr->display, view->window); + XFlush(scr->display); +} + +static void x11_move(void *vctx, W_View *view, int x, int y) +{ + W_Screen *scr = (W_Screen *)vctx; + + XMoveWindow(scr->display, view->window, x, y); +} + +static void x11_resize(void *vctx, W_View *view, unsigned int w, unsigned int h) +{ + W_Screen *scr = (W_Screen *)vctx; + + XResizeWindow(scr->display, view->window, w, h); +} + +static void x11_raise(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XRaiseWindow(scr->display, view->window); +} + +static void x11_lower(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XLowerWindow(scr->display, view->window); +} + +static void x11_reparent(void *vctx, W_View *view, W_View *newParent, int x, int y) +{ + W_Screen *scr = (W_Screen *)vctx; + + XReparentWindow(scr->display, view->window, newParent->window, x, y); +} + +static void x11_destroy(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + + XDeleteContext(scr->display, view->window, ViewContext); + if (!view->flags.parentDying || view->flags.topLevel) + XDestroyWindow(scr->display, view->window); +} + +static void x11_set_background_color(void *vctx, W_View *view, WMColor *color) +{ + W_Screen *scr = (W_Screen *)vctx; + + XSetWindowBackground(scr->display, view->window, W_PIXEL(color)); + XClearWindow(scr->display, view->window); +} + +static void x11_set_cursor(void *vctx, W_View *view, Cursor cursor) +{ + W_Screen *scr = (W_Screen *)vctx; + + XDefineCursor(scr->display, view->window, cursor); +} + +static void x11_redisplay(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + XEvent xev; + WMEvent ev; + + memset(&xev, 0, sizeof(xev)); + xev.xexpose.type = Expose; + xev.xexpose.display = scr->display; + xev.xexpose.window = view->window; + xev.xexpose.count = 0; + xev.xexpose.serial = 0; + + memset(&ev, 0, sizeof(ev)); + ev.type = WME_EXPOSE; + ev.window = (WNativeWindow)view->window; + ev.u.expose.window = (WNativeWindow)view->window; + ev.u.expose.count = 0; + ev._x11_raw = &xev; + + WMHandleEvent(&ev); +} + +static WMPoint x11_get_screen_position(void *vctx, W_View *view) +{ + W_Screen *scr = (W_Screen *)vctx; + Window foo; + int x, y, topX, topY; + unsigned int bar; + W_View *topView; + + topView = view; + while (topView->parent && topView->parent != scr->rootView) + topView = topView->parent; + + if (!XGetGeometry(scr->display, topView->window, &foo, &topX, &topY, &bar, &bar, &bar, &bar)) { + topX = topY = 0; + } + + XTranslateCoordinates(scr->display, view->window, scr->rootWin, 0, 0, &x, &y, &foo); + + return wmkpoint(x - topX, y - topY); +} + +W_View *W_GetViewForXWindow(Display *display, Window window) +{ + W_View *view; + + if (ViewContext == 0) + return NULL; + if (XFindContext(display, window, ViewContext, (XPointer *)&view) == 0) + return view; + return NULL; +} + +const W_ViewBackend W_ViewBackendX11 = { + .screen_init = x11_screen_init, + .screen_fini = x11_screen_fini, + .create_root = x11_create_root, + .realize = x11_realize, + .map = x11_map, + .unmap = x11_unmap, + .map_subviews = x11_map_subviews, + .unmap_subviews = x11_unmap_subviews, + .move = x11_move, + .resize = x11_resize, + .raise = x11_raise, + .lower = x11_lower, + .reparent = x11_reparent, + .destroy = x11_destroy, + .set_background_color = x11_set_background_color, + .set_cursor = x11_set_cursor, + .redisplay = x11_redisplay, + .get_screen_position = x11_get_screen_position, +}; diff --git a/src/actions.c b/src/actions.c index b8a929a..5ee134f 100644 --- a/src/actions.c +++ b/src/actions.c @@ -169,7 +169,7 @@ void wSetFocusTo(WScreen *scr, WWindow *wwin) if (wwin->flags.mapped && !WFLAGP(wwin, no_focusable)) { /* install colormap if colormap mode is lock mode */ if (wPreferences.colormap_mode == WCM_CLICK) - wColormapInstallForWindow(scr, wwin); + wm_backend->colormap_install(scr, wwin); /* set input focus */ switch (wwin->focus_mode) { @@ -1860,7 +1860,7 @@ void wHideApplication(WApplication *wapp) #ifdef HIDDENDOT if (wapp->app_icon) - wAppIconPaint(wapp->app_icon); + wm_backend->appicon_paint(wapp->app_icon); #endif } @@ -1990,7 +1990,7 @@ void wUnhideApplication(WApplication *wapp, Bool miniwindows, Bool bringToCurren wArrangeIcons(scr, True); #ifdef HIDDENDOT - wAppIconPaint(wapp->app_icon); + wm_backend->appicon_paint(wapp->app_icon); #endif } diff --git a/src/appicon.c b/src/appicon.c index b080d7a..2aa8b1d 100644 --- a/src/appicon.c +++ b/src/appicon.c @@ -155,7 +155,7 @@ void create_appicon_for_application(WApplication *wapp, WWindow *wwin) /* Now, paint the icon */ if (!WFLAGP(wapp->main_window_desc, no_appicon)) - paint_app_icon(wapp); + wm_backend->appicon_show(wapp); } /* At this point the application is fully set up and all icon and @@ -207,9 +207,6 @@ void paint_app_icon(WApplication *wapp) if (!wapp || !wapp->app_icon || !wapp->main_window_desc) return; - /* Phase 79: Wayland — no X11 window system for icon display */ - if (!dpy) - return; icon = wapp->app_icon->icon; scr = wapp->main_window_desc->screen_ptr; @@ -373,8 +370,7 @@ static void drawCorner(WIcon * icon) void wAppIconMove(WAppIcon * aicon, int x, int y) { - if (dpy) - XMoveWindow(dpy, aicon->icon->core->window, x, y); + wm_backend->window_move(aicon->icon->core->window, x, y); aicon->x_pos = x; aicon->y_pos = y; } @@ -409,9 +405,6 @@ void wAppIconPaint(WAppIcon *aicon) else wapp = NULL; - /* Phase 79: Wayland — wIconPaint and all X11 drawing are no-ops */ - if (!dpy) - return; wIconPaint(aicon->icon); diff --git a/src/application.c b/src/application.c index 34ed9f1..2fb5080 100644 --- a/src/application.c +++ b/src/application.c @@ -44,13 +44,10 @@ static WWindow *makeMainWindow(WScreen * scr, Window window) { WWindow *wwin; - /* Phase 79: Wayland — synthetic IDs are not X11 windows; skip the - * XGetWindowAttributes/XSelectInput calls that would crash with dpy==NULL. - * The WWindow is still created so wapp->main_window_desc is non-NULL. */ - if (dpy) { - XWindowAttributes attr; + { + WClientAttributes cattr; - if (!XGetWindowAttributes(dpy, window, &attr)) + if (!wm_backend->window_get_client_attrs(window, &cattr)) return NULL; wwin = wWindowCreate(); @@ -64,18 +61,7 @@ static WWindow *makeMainWindow(WScreen * scr, Window window) wDefaultFillAttributes(wwin->wm_instance, wwin->wm_class, &wwin->user_flags, &wwin->defined_user_flags, True); - XSelectInput(dpy, window, attr.your_event_mask | PropertyChangeMask | StructureNotifyMask); - } else { - wwin = wWindowCreate(); - wwin->screen_ptr = scr; - wwin->client_win = window; - wwin->main_window = window; - wwin->wm_hints = wm_backend->prop_get_wm_hints(window); - - PropGetWMClass(window, &wwin->wm_class, &wwin->wm_instance); - - wDefaultFillAttributes(wwin->wm_instance, wwin->wm_class, &wwin->user_flags, - &wwin->defined_user_flags, True); + wm_backend->window_add_events(window, PropertyChangeMask | StructureNotifyMask); } return wwin; @@ -103,13 +89,9 @@ WApplication *wApplicationCreate(WWindow * wwin) if (main_window == None || main_window == scr->root_win) return NULL; - /* Phase 79: skip X11 geometry validation for Wayland synthetic IDs */ - if (dpy) { - Window root; - int foo; - unsigned int bar; - /* check if the window is valid */ - if (!XGetGeometry(dpy, main_window, &root, &foo, &foo, &bar, &bar, &bar, &bar)) + { + WClientAttributes cattr; + if (!wm_backend->window_get_client_attrs(main_window, &cattr)) return NULL; } @@ -222,7 +204,7 @@ void wApplicationActivate(WApplication *wapp) { if (wapp->app_icon) { wIconSetHighlited(wapp->app_icon->icon, True); - wAppIconPaint(wapp->app_icon); + wm_backend->appicon_paint(wapp->app_icon); } } @@ -230,6 +212,6 @@ void wApplicationDeactivate(WApplication *wapp) { if (wapp->app_icon) { wIconSetHighlited(wapp->app_icon->icon, False); - wAppIconPaint(wapp->app_icon); + wm_backend->appicon_paint(wapp->app_icon); } } diff --git a/src/backend/backend.h b/src/backend/backend.h index 28fca27..7fbcd91 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -38,6 +38,15 @@ typedef struct WWindow WWindow; typedef struct GNUstepWMAttributes GNUstepWMAttributes; struct WObjDescriptor; struct WFrameWindow; +typedef struct _WCoreWindow WCoreWindow; +typedef union WTexture WTexture; +typedef struct WPixmap WPixmap; +typedef struct WApplication WApplication; +typedef struct WAppIcon WAppIcon; +typedef struct WIcon WIcon; +typedef struct WProtocols WProtocols; +typedef struct WShortKey WShortKey; +typedef struct MWMHints MWMHints; /* * WMBackend -- vtable for all display-system operations. @@ -717,6 +726,18 @@ typedef struct WMBackend { */ void (*window_set_save_under)(WNativeWindow win, int save_under); + /* + * Set the background pixel of a window. + * Equivalent to XSetWindowBackground(dpy, win, pixel). + */ + void (*window_set_background)(WNativeWindow win, unsigned long pixel); + + /* + * Set the background pixmap of a window. + * Equivalent to XSetWindowBackgroundPixmap(dpy, win, pixmap). + */ + void (*window_set_background_pixmap)(WNativeWindow win, unsigned long pixmap); + /* ------------------------------------------------------------------ */ /* Keysym from hardware keycode (Phase 12) */ /* ------------------------------------------------------------------ */ @@ -781,6 +802,13 @@ typedef struct WMBackend { */ void (*window_map_subwindows)(WNativeWindow parent); + /* + * Free a server-side pixmap. + * Equivalent to XFreePixmap(dpy, pixmap). + * No-op in Wayland mode (pixmaps are CPU-side RImages). + */ + void (*pixmap_free)(unsigned long pixmap); + /* ------------------------------------------------------------------ */ /* Client window attributes query (Phase 13) */ /* ------------------------------------------------------------------ */ @@ -1211,6 +1239,407 @@ typedef struct WMBackend { */ void (*shape_combine_mask)(WNativeWindow win, WNativeWindow mask); + /* ------------------------------------------------------------------ */ + /* Texture helpers (Phase 19) */ + /* ------------------------------------------------------------------ */ + + /* + * Allocate a colour cell in the screen's colormap. + * X11: XAllocColor(dpy, scr->w_colormap, color). + * Wayland: no-op (colours stored as direct pixel values). + */ + void (*texture_alloc_color)(WScreen *scr, XColor *color); + + /* + * Free colour cells previously allocated with texture_alloc_color. + * X11: XFreeColors(dpy, scr->w_colormap, pixels, count, 0) with + * error-handler bracket for buggy servers. + * Wayland: no-op. + */ + void (*texture_free_colors)(WScreen *scr, unsigned long *pixels, int count); + + /* + * Create a GC for texture bevel drawing. + * X11: XCreateGC(dpy, scr->w_win, mask, &gcv). + * Wayland: returns NULL (GCs do not exist). + */ + GC (*texture_create_gc)(WScreen *scr, unsigned long pixel); + + /* + * Free a GC used by the texture system for bevel drawing. + * X11: XFreeGC(dpy, gc). + * Wayland: no-op (GCs do not exist). + */ + void (*texture_free_gc)(GC gc); + + /* ------------------------------------------------------------------ */ + /* Frame decoration helpers (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Allocate a frame border colour from a colormap by name. + * On success stores a wmalloc'd pixel value in *pixel_out. + * On failure sets *pixel_out = NULL. + * X11: XParseColor + XAllocColor. + * Wayland: no-op (*pixel_out = NULL; frame_paint handles colours). + */ + void (*frame_alloc_border_pixel)(unsigned long colormap, + const char *color_name, + unsigned long **pixel_out); + + /* + * Update X11 window backgrounds for frame sub-windows after a + * texture/state change. Clears and repaints titlebar + buttons. + * X11: XSetWindowBackground[Pixmap] + XClearWindow on sub-windows. + * Wayland: no-op (frame_paint renders the entire frame). + */ + void (*frame_update_texture)(struct WFrameWindow *fwin); + + /* + * Paint a single frame button (close/miniaturize/language). + * X11: Xlib drawing into the button sub-window. + * Wayland: no-op (frame_paint renders buttons into the frame buffer). + */ + void (*frame_paint_button)(WCoreWindow *button, WTexture *texture, + unsigned long color, WPixmap *image, + int pushed); + + /* ------------------------------------------------------------------ */ + /* NETWM/EWMH (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Initialize NETWM atoms and root-window hints. + * X11: interns atoms, sets _NET_SUPPORTED, registers observers. + * Wayland: no-op (no X11 root-window properties). + */ + void (*netwm_init)(WScreen *scr); + + /* + * Remove all NETWM properties from the root window. + * X11: XDeleteProperty for each _NET_* atom. + * Wayland: no-op. + */ + void (*netwm_cleanup)(WScreen *scr); + + /* + * Update _NET_DESKTOP_GEOMETRY and _NET_DESKTOP_VIEWPORT on root. + * X11: XChangeProperty. + * Wayland: no-op. + */ + void (*netwm_update_desktop)(WScreen *scr); + + /* + * Read _NET_CURRENT_DESKTOP from root. + * X11: PropGetCheckProperty. + * Wayland: returns -1. + */ + int (*netwm_get_current_desktop)(WScreen *scr); + + /* + * Copy _NET_WM_WINDOW_OPACITY from client to frame window. + * X11: XGetWindowProperty + XChangeProperty. + * Wayland: no-op. + */ + void (*netwm_update_opacity)(WWindow *wwin); + + /* + * Set _NET_WM_ALLOWED_ACTIONS on a client window. + * X11: XChangeProperty / XDeleteProperty. + * Wayland: no-op. + */ + void (*netwm_update_actions)(WWindow *wwin, int del); + + /* + * Read _NET_WM_DESKTOP, _NET_WM_STATE, _NET_WM_WINDOW_TYPE from client. + * X11: XGetWindowProperty for each. + * Wayland: no-op. + */ + void (*netwm_check_client_hints)(WWindow *wwin, int *layer, int *workspace); + + /* + * Read initial NETWM state (window type, icon info) for a new client. + * X11: reads properties, updates wwin flags. + * Wayland: no-op. + */ + void (*netwm_check_initial_state)(WWindow *wwin); + + /* + * Read _NET_WM_PID from a window. + * X11: XGetWindowProperty. + * Wayland: returns 0. + */ + int (*netwm_get_pid)(WNativeWindow window); + + /* + * Remove _NET_FRAME_EXTENTS from a client window. + * X11: XDeleteProperty. + * Wayland: no-op. + */ + void (*netwm_cleanup_frame_extents)(WWindow *wwin); + + /* ------------------------------------------------------------------ */ + /* X11 root-window properties (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Read WM_PROTOCOLS from a client window. + * X11: XGetWMProtocols, populates prots. + * Wayland: sets DELETE_WINDOW=1 (all XDG toplevels support close). + */ + void (*prop_get_protocols)(WNativeWindow window, WProtocols *prots); + + /* + * Read an arbitrary X11 property from a window. + * X11: XGetWindowProperty. + * Wayland: returns NULL. + */ + unsigned char *(*prop_get_check_property)(WNativeWindow window, + unsigned long hint, + unsigned long type, + int format, int count, + int *ret_count); + + /* + * Set _WINDOWMAKER_WM_PROTOCOLS on root. + * X11: XChangeProperty. + * Wayland: no-op. + */ + void (*prop_set_wmaker_protocols)(WNativeWindow root); + + /* + * Set _WINDOWMAKER_ICON_TILE hint on info_window. + * X11: XChangeProperty with RGBA data. + * Wayland: no-op. + */ + void (*prop_set_icon_tile)(WScreen *scr, RImage *image); + + /* + * Remove WMaker protocol properties from root. + * X11: XDeleteProperty for wm_protocols, noticeboard, icon_size. + * Wayland: no-op. + */ + void (*prop_cleanup)(WNativeWindow root); + + /* ------------------------------------------------------------------ */ + /* Client operations (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Reparent client window back to root (during unmanage/shutdown). + * X11: XSetWindowBorderWidth + XReparentWindow. + * Wayland: no-op. + */ + void (*client_restore)(WWindow *wwin); + + /* + * Set WM_STATE property on client window. + * X11: XChangeProperty with state + icon_win. + * Wayland: no-op (state tracked internally). + */ + void (*client_set_state)(WWindow *wwin, int state, WNativeWindow icon_win); + + /* + * Send a WM_PROTOCOLS message to a client (e.g. WM_DELETE_WINDOW). + * X11: XSendEvent with ClientMessage. + * Wayland: dispatches client_close for delete, no-op otherwise. + */ + void (*client_send_protocol)(WWindow *wwin, unsigned long protocol, + unsigned long timestamp); + + /* + * Forcefully kill a client. + * X11: XKillClient + XFlush. + * Wayland: client_close (request close via xdg_toplevel). + */ + void (*client_kill)(WWindow *wwin); + + /* + * Read WM_COLORMAP_WINDOWS from a client. + * X11: XGetWMColormapWindows. + * Wayland: no-op. + */ + void (*client_get_colormap_windows)(WWindow *wwin); + + /* ------------------------------------------------------------------ */ + /* Misc X11 utilities (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Drain pending Expose events from the X11 queue. + * X11: XCheckMaskEvent loop. + * Wayland: no-op. + */ + void (*eat_expose)(void); + + /* + * Move a window with optional animation. + * X11: XMoveWindow (or slide_window with animation). + * Wayland: no-op (frame positions are virtual). + */ + void (*move_window)(WNativeWindow win, int from_x, int from_y, + int to_x, int to_y); + + /* + * Slide an array of windows with animation. + * X11: animated XMoveWindow loop. + * Wayland: no-op. + */ + void (*slide_windows)(WNativeWindow *wins, int n, + int from_x, int from_y, int to_x, int to_y); + + /* + * Get text from an X11 cut buffer selection. + * X11: XFetchBuffer. + * Wayland: returns NULL. + */ + char *(*get_text_selection)(WScreen *scr, unsigned long selection); + + /* + * Convert a key shortcut to a human-readable string. + * X11: XKeysymToString + modifier labels. + * Wayland: returns NULL (TODO: implement with xkbcommon). + */ + char *(*get_shortcut_string)(WShortKey key); + + /* + * Read WM_COMMAND from a window and return as joined string. + * X11: XGetCommand. + * Wayland: uses icccm_get_command vtable slot. + */ + char *(*get_command_for_window)(WNativeWindow win, int elements); + + /* ------------------------------------------------------------------ */ + /* Icon rendering (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Update the icon's X11 pixmap from its file_image and repaint. + * X11: XFreePixmap + icon_update_pixmap + XSetWindowBackgroundPixmap + wIconPaint. + * Wayland: no-op (icons rendered via frame_paint or scene buffers). + */ + void (*icon_update_pixmap)(WIcon *icon); + + /* + * Paint an icon (clear window, draw title, selection rect). + * X11: XClearWindow + text drawing + XDrawRectangle. + * Wayland: no-op. + */ + void (*icon_paint)(WIcon *icon); + + /* ------------------------------------------------------------------ */ + /* App icon (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Show/place an application icon on screen. + * X11: PlaceIcon + wAppIconMove + wLowerFrame + wAppIconPaint. + * Wayland: no-op. + */ + void (*appicon_show)(WApplication *wapp); + + /* + * Paint an app icon (icon + dock dots + indicators). + * X11: wIconPaint + XCopyArea for dock dots + indicators. + * Wayland: no-op. + */ + void (*appicon_paint)(WAppIcon *aicon); + + /* ------------------------------------------------------------------ */ + /* Shutdown (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Restore desktop: reparent all clients back to root, clean up. + * X11: XGrabServer + restoreWindows + PropCleanUp + wNETWMCleanup. + * Wayland: no-op (clients are independent). + */ + void (*restore_desktop)(WScreen *scr); + + /* + * Kill/close all managed windows on a screen. + * X11: sends DELETE_WINDOW or XKillClient to each window. + * Wayland: no-op (compositor handles client lifecycle). + */ + void (*wipe_desktop)(WScreen *scr); + + /* ------------------------------------------------------------------ */ + /* Resources / colormap (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Allocate a named colour from a colormap. + * X11: XParseColor + XAllocColor. + * Wayland: returns False. + */ + int (*get_color_for_colormap)(unsigned long colormap, + const char *color_name, XColor *color); + + /* + * Free a previously allocated colour pixel. + * X11: XFreeColors. + * Wayland: no-op. + */ + void (*free_color)(WScreen *scr, unsigned long pixel); + + /* + * Install a colormap for a window. + * X11: XInstallColormap for client cmap_windows. + * Wayland: no-op. + */ + void (*colormap_install)(WScreen *scr, WWindow *wwin); + + /* ------------------------------------------------------------------ */ + /* Protocol-specific init (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Initialize XDND (X11 drag-and-drop) atoms. + * X11: XInternAtom for all XdndAware/XdndEnter/etc. + * Wayland: no-op. + */ + void (*xdnd_init)(void); + + /* + * Read Motif WM hints from a client window. + * X11: XGetWindowProperty for _MOTIF_WM_HINTS. + * Wayland: returns 0 (no hints). + */ + int (*motif_get_hints)(WNativeWindow window, MWMHints *hints_out); + + /* ------------------------------------------------------------------ */ + /* Superfluous effects (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Perform app-icon bounce animation. + * X11: XRaiseWindow + XMoveWindow loop. + * Wayland: no-op. + */ + void (*appicon_bounce)(WAppIcon *aicon, void *data); + + /* ------------------------------------------------------------------ */ + /* Startup (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Adopt all existing top-level windows (after WM startup). + * X11: XQueryTree + wManageWindow loop. + * Wayland: no-op (clients connect dynamically). + */ + void (*manage_all_windows)(WScreen *scr, int crash_recovery); + + /* ------------------------------------------------------------------ */ + /* Event dispatch (Phase 80) */ + /* ------------------------------------------------------------------ */ + + /* + * Handle signal-driven state changes in the event loop. + * X11: calls Shutdown(WSExitMode). + * Wayland: calls event_loop_terminate(). + */ + void (*event_handle_signal_exit)(void); + } WMBackend; /* diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index d7ebe9d..6826adb 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -5305,6 +5305,9 @@ static void wl_window_set_border_width(WNativeWindow win, int width) (void)win; (void)width; /* no-op for native frames */ } static void wl_window_set_save_under(WNativeWindow win, int save_under) { (void)win; (void)save_under; } +static void wl_noop_window_set_background(WNativeWindow win, unsigned long pixel) { (void)win; (void)pixel; } +static void wl_noop_window_set_background_pixmap(WNativeWindow win, unsigned long pixmap) { (void)win; (void)pixmap; } +static void wl_noop_pixmap_free(unsigned long pixmap) { (void)pixmap; } static void wl_window_clear(WNativeWindow win) { (void)win; /* frame buffer is cleared in frame_paint */ @@ -6012,6 +6015,159 @@ wl_register_error_handlers(void) XSetIOErrorHandler(wl_catch_xwayland_io_error); } +static void +wl_texture_alloc_color(WScreen *scr, XColor *color) +{ + (void) scr; (void) color; +} + +static void +wl_texture_free_colors(WScreen *scr, unsigned long *pixels, int count) +{ + (void) scr; (void) pixels; (void) count; +} + +static GC +wl_texture_create_gc(WScreen *scr, unsigned long pixel) +{ + (void) scr; (void) pixel; + return NULL; +} + +static void +wl_texture_free_gc(GC gc) +{ + (void) gc; +} + +/* ------------------------------------------------------------------ */ +/* Phase 80: no-op stubs for X11-only operations */ +/* ------------------------------------------------------------------ */ + +static void wl_noop_frame_alloc_border_pixel(unsigned long colormap, + const char *color_name, unsigned long **pixel_out) +{ (void)colormap; (void)color_name; *pixel_out = NULL; } + +static void wl_noop_frame_update_texture(struct WFrameWindow *fwin) { (void)fwin; } + +static void wl_noop_frame_paint_button(WCoreWindow *button, WTexture *texture, + unsigned long color, WPixmap *image, int pushed) +{ (void)button; (void)texture; (void)color; (void)image; (void)pushed; } + +static void wl_noop_netwm_init(WScreen *scr) { (void)scr; } +static void wl_noop_netwm_cleanup(WScreen *scr) { (void)scr; } +static void wl_noop_netwm_update_desktop(WScreen *scr) { (void)scr; } +static int wl_noop_netwm_get_current_desktop(WScreen *scr) { (void)scr; return -1; } +static void wl_noop_netwm_update_opacity(WWindow *wwin) { (void)wwin; } +static void wl_noop_netwm_update_actions(WWindow *wwin, int del) { (void)wwin; (void)del; } +static void wl_noop_netwm_check_client_hints(WWindow *wwin, int *layer, int *workspace) +{ (void)wwin; (void)layer; (void)workspace; } +static void wl_noop_netwm_check_initial_state(WWindow *wwin) { (void)wwin; } +static int wl_noop_netwm_get_pid(WNativeWindow window) { (void)window; return 0; } +static void wl_noop_netwm_cleanup_frame_extents(WWindow *wwin) { (void)wwin; } + +static void wl_prop_get_protocols(WNativeWindow window, WProtocols *prots) +{ + (void)window; + memset(prots, 0, sizeof(WProtocols)); + prots->DELETE_WINDOW = 1; /* All XDG toplevels support close */ +} + +static unsigned char *wl_noop_prop_get_check_property(WNativeWindow window, + unsigned long hint, unsigned long type, int format, int count, int *ret_count) +{ (void)window; (void)hint; (void)type; (void)format; (void)count; + if (ret_count) *ret_count = 0; return NULL; } + +static void wl_noop_prop_set_wmaker_protocols(WNativeWindow root) { (void)root; } +static void wl_noop_prop_set_icon_tile(WScreen *scr, RImage *image) { (void)scr; (void)image; } +static void wl_noop_prop_cleanup(WNativeWindow root) { (void)root; } + +static void wl_noop_client_restore(WWindow *wwin) { (void)wwin; } +static void wl_noop_client_set_state(WWindow *wwin, int state, WNativeWindow icon_win) +{ (void)wwin; (void)state; (void)icon_win; } + +static void wl_client_send_protocol(WWindow *wwin, unsigned long protocol, + unsigned long timestamp) +{ + (void)protocol; (void)timestamp; + wm_backend->client_close(wwin->client_win); +} + +static void wl_client_kill_impl(WWindow *wwin) +{ + wm_backend->client_close(wwin->client_win); +} + +static void wl_noop_client_get_colormap_windows(WWindow *wwin) { (void)wwin; } + +static void wl_noop_eat_expose(void) { } + +static void wl_noop_move_window(WNativeWindow win, int from_x, int from_y, + int to_x, int to_y) +{ (void)win; (void)from_x; (void)from_y; (void)to_x; (void)to_y; } + +static void wl_noop_slide_windows(WNativeWindow *wins, int n, + int from_x, int from_y, int to_x, int to_y) +{ (void)wins; (void)n; (void)from_x; (void)from_y; (void)to_x; (void)to_y; } + +static char *wl_noop_get_text_selection(WScreen *scr, unsigned long selection) +{ (void)scr; (void)selection; return NULL; } + +static char *wl_noop_get_shortcut_string(WShortKey key) +{ (void)key; return NULL; } + +static char *wl_get_command_for_window(WNativeWindow win, int elements) +{ + char **argv, *command = NULL; + int argc; + if (!wm_backend->icccm_get_command(win, &argv, &argc)) + return NULL; + if (argc > 0 && argv != NULL) { + if (elements == 0) + elements = argc; + command = wtokenjoin(argv, WMIN(argc, elements)); + if (command[0] == 0) { + wfree(command); + command = NULL; + } + } + wm_backend->icccm_free_command(argv); + return command; +} + +static void wl_noop_icon_update_pixmap(WIcon *icon) { (void)icon; } +static void wl_noop_icon_paint(WIcon *icon) { (void)icon; } +static void wl_noop_appicon_show(WApplication *wapp) { (void)wapp; } +static void wl_noop_appicon_paint(WAppIcon *aicon) { (void)aicon; } +static void wl_noop_restore_desktop(WScreen *scr) { (void)scr; } +static void wl_noop_wipe_desktop(WScreen *scr) { (void)scr; } + +static int wl_noop_get_color_for_colormap(unsigned long colormap, + const char *color_name, XColor *color) +{ (void)colormap; (void)color_name; (void)color; return 0; } + +static void wl_noop_free_color(WScreen *scr, unsigned long pixel) +{ (void)scr; (void)pixel; } + +static void wl_noop_colormap_install(WScreen *scr, WWindow *wwin) +{ (void)scr; (void)wwin; } + +static void wl_noop_xdnd_init(void) { } + +static int wl_noop_motif_get_hints(WNativeWindow window, MWMHints *hints_out) +{ (void)window; (void)hints_out; return 0; } + +static void wl_noop_appicon_bounce(WAppIcon *aicon, void *data) +{ (void)aicon; (void)data; } + +static void wl_noop_manage_all_windows(WScreen *scr, int crash_recovery) +{ (void)scr; (void)crash_recovery; } + +static void wl_event_handle_signal_exit(void) +{ + wm_backend->event_loop_terminate(); +} + /* ------------------------------------------------------------------ */ /* vtable */ /* ------------------------------------------------------------------ */ @@ -6089,12 +6245,15 @@ const WMBackend wl_backend = { .window_map = wl_window_map, .window_map_raised = wl_window_map_raised, .window_map_subwindows = wl_window_map_subwindows, + .pixmap_free = wl_noop_pixmap_free, .window_unmap = wl_window_unmap, .window_move = wl_window_move, .window_resize = wl_window_resize, .window_set_border = wl_window_set_border, .window_set_border_width = wl_window_set_border_width, .window_set_save_under = wl_window_set_save_under, + .window_set_background = wl_noop_window_set_background, + .window_set_background_pixmap = wl_noop_window_set_background_pixmap, .window_clear = wl_window_clear, .window_get_rect = wl_window_get_rect, .window_add_events = wl_window_add_events, @@ -6163,4 +6322,51 @@ const WMBackend wl_backend = { .cursor_create_named = wl_cursor_create_named, .shape_combine_mask = wl_shape_combine_mask, .register_error_handlers = wl_register_error_handlers, + .texture_alloc_color = wl_texture_alloc_color, + .texture_free_colors = wl_texture_free_colors, + .texture_create_gc = wl_texture_create_gc, + .texture_free_gc = wl_texture_free_gc, + .frame_alloc_border_pixel = wl_noop_frame_alloc_border_pixel, + .frame_update_texture = wl_noop_frame_update_texture, + .frame_paint_button = wl_noop_frame_paint_button, + .netwm_init = wl_noop_netwm_init, + .netwm_cleanup = wl_noop_netwm_cleanup, + .netwm_update_desktop = wl_noop_netwm_update_desktop, + .netwm_get_current_desktop = wl_noop_netwm_get_current_desktop, + .netwm_update_opacity = wl_noop_netwm_update_opacity, + .netwm_update_actions = wl_noop_netwm_update_actions, + .netwm_check_client_hints = wl_noop_netwm_check_client_hints, + .netwm_check_initial_state = wl_noop_netwm_check_initial_state, + .netwm_get_pid = wl_noop_netwm_get_pid, + .netwm_cleanup_frame_extents = wl_noop_netwm_cleanup_frame_extents, + .prop_get_protocols = wl_prop_get_protocols, + .prop_get_check_property = wl_noop_prop_get_check_property, + .prop_set_wmaker_protocols = wl_noop_prop_set_wmaker_protocols, + .prop_set_icon_tile = wl_noop_prop_set_icon_tile, + .prop_cleanup = wl_noop_prop_cleanup, + .client_restore = wl_noop_client_restore, + .client_set_state = wl_noop_client_set_state, + .client_send_protocol = wl_client_send_protocol, + .client_kill = wl_client_kill_impl, + .client_get_colormap_windows = wl_noop_client_get_colormap_windows, + .eat_expose = wl_noop_eat_expose, + .move_window = wl_noop_move_window, + .slide_windows = wl_noop_slide_windows, + .get_text_selection = wl_noop_get_text_selection, + .get_shortcut_string = wl_noop_get_shortcut_string, + .get_command_for_window = wl_get_command_for_window, + .icon_update_pixmap = wl_noop_icon_update_pixmap, + .icon_paint = wl_noop_icon_paint, + .appicon_show = wl_noop_appicon_show, + .appicon_paint = wl_noop_appicon_paint, + .restore_desktop = wl_noop_restore_desktop, + .wipe_desktop = wl_noop_wipe_desktop, + .get_color_for_colormap = wl_noop_get_color_for_colormap, + .free_color = wl_noop_free_color, + .colormap_install = wl_noop_colormap_install, + .xdnd_init = wl_noop_xdnd_init, + .motif_get_hints = wl_noop_motif_get_hints, + .appicon_bounce = wl_noop_appicon_bounce, + .manage_all_windows = wl_noop_manage_all_windows, + .event_handle_signal_exit = wl_event_handle_signal_exit, }; diff --git a/src/backend/x11/x11_backend.c b/src/backend/x11/x11_backend.c index f77ca17..d778027 100644 --- a/src/backend/x11/x11_backend.c +++ b/src/backend/x11/x11_backend.c @@ -53,6 +53,19 @@ #include "../../superfluous.h" #include "../../shutdown.h" /* Shutdown(), WShutdownMode */ #include "../../main.h" /* Restart() */ +#include "../../icon.h" +#include "../../appicon.h" +#include "../../application.h" +#include "../../motif.h" +#include "../../keybind.h" +#include "../../properties.h" +#include "../../wmspec.h" +#include "../../colormap.h" +#include "../../xdnd.h" +#include "../../client.h" +#include "../../wcore.h" +#include "../../dock.h" +#include "../../texture.h" #include "../backend.h" #include "x11_compat.h" #include "x11_backend.h" @@ -831,6 +844,18 @@ x11_window_set_save_under(WNativeWindow win, int save_under) XChangeWindowAttributes(dpy, WNW_TO_XID(win), CWSaveUnder, &attr); } +static void +x11_window_set_background(WNativeWindow win, unsigned long pixel) +{ + XSetWindowBackground(dpy, WNW_TO_XID(win), pixel); +} + +static void +x11_window_set_background_pixmap(WNativeWindow win, unsigned long pixmap) +{ + XSetWindowBackgroundPixmap(dpy, WNW_TO_XID(win), (Pixmap)pixmap); +} + /* -------------------------------------------------------------------- */ /* Keysym from hardware keycode (Phase 12) */ /* -------------------------------------------------------------------- */ @@ -894,6 +919,13 @@ x11_window_map_subwindows(WNativeWindow parent) XMapSubwindows(dpy, WNW_TO_XID(parent)); } +static void +x11_pixmap_free(unsigned long pixmap) +{ + if (pixmap) + XFreePixmap(dpy, (Pixmap)pixmap); +} + /* -------------------------------------------------------------------- */ /* Client window attributes query (Phase 13) */ /* -------------------------------------------------------------------- */ @@ -2394,6 +2426,494 @@ x11_register_error_handlers(void) XSetErrorHandler((XErrorHandler) x11_catch_error); } +static void +x11_texture_alloc_color(WScreen *scr, XColor *color) +{ + XAllocColor(dpy, scr->w_colormap, color); +} + +static int +x11_texture_dummy_error_handler(Display *d, XErrorEvent *ev) +{ + (void) d; (void) ev; + return 0; +} + +static void +x11_texture_free_colors(WScreen *scr, unsigned long *pixels, int count) +{ + XErrorHandler oldhandler; + XSync(dpy, 0); + oldhandler = XSetErrorHandler(x11_texture_dummy_error_handler); + XFreeColors(dpy, scr->w_colormap, pixels, count, 0); + XSync(dpy, 0); + XSetErrorHandler(oldhandler); +} + +static GC +x11_texture_create_gc(WScreen *scr, unsigned long pixel) +{ + XGCValues gcv; + gcv.foreground = pixel; + gcv.background = pixel; + gcv.graphics_exposures = False; + return XCreateGC(dpy, scr->w_win, + GCForeground | GCBackground | GCGraphicsExposures, &gcv); +} + +static void +x11_texture_free_gc(GC gc) +{ + XFreeGC(dpy, gc); +} + +/* -------------------------------------------------------------------- */ +/* Frame decoration helpers (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_frame_paint_button(WCoreWindow *button, WTexture *texture, + unsigned long color, WPixmap *image, int pushed); + +static void +x11_frame_alloc_border_pixel(unsigned long colormap, + const char *color_name, + unsigned long **pixel_out) +{ + XColor xcol; + *pixel_out = NULL; + if (!wGetColorForColormap((Colormap)colormap, color_name, &xcol)) + return; + *pixel_out = wmalloc(sizeof(unsigned long)); + if (*pixel_out) + **pixel_out = xcol.pixel; +} + +static void +x11_frame_update_texture(struct WFrameWindow *fwin) +{ + int i; + unsigned long pixel; + + if (!fwin->titlebar || !fwin->titlebar->window) + return; + + i = fwin->flags.state; + if (fwin->titlebar) { + if (fwin->title_texture[i]->any.type != WTEX_SOLID) { + XSetWindowBackgroundPixmap(dpy, fwin->titlebar->window, fwin->title_back[i]); + if (wPreferences.new_style == TS_NEW) { + if (fwin->left_button && fwin->lbutton_back[i]) + XSetWindowBackgroundPixmap(dpy, fwin->left_button->window, + fwin->lbutton_back[i]); +#ifdef XKB_BUTTON_HINT + if (fwin->language_button && fwin->languagebutton_back[i]) + XSetWindowBackgroundPixmap(dpy, fwin->language_button->window, + fwin->languagebutton_back[i]); +#endif + if (fwin->right_button && fwin->rbutton_back[i]) + XSetWindowBackgroundPixmap(dpy, fwin->right_button->window, + fwin->rbutton_back[i]); + } + } else { + pixel = fwin->title_texture[i]->solid.normal.pixel; + XSetWindowBackground(dpy, fwin->titlebar->window, pixel); + if (wPreferences.new_style == TS_NEW) { + if (fwin->left_button) + XSetWindowBackground(dpy, fwin->left_button->window, pixel); +#ifdef XKB_BUTTON_HINT + if (fwin->language_button) + XSetWindowBackground(dpy, fwin->language_button->window, pixel); +#endif + if (fwin->right_button) + XSetWindowBackground(dpy, fwin->right_button->window, pixel); + } + } + XClearWindow(dpy, fwin->titlebar->window); + + if (fwin->left_button) { + XClearWindow(dpy, fwin->left_button->window); + x11_frame_paint_button(fwin->left_button, fwin->title_texture[fwin->flags.state], + WMColorPixel(fwin->title_color[fwin->flags.state]), + fwin->lbutton_image, False); + } +#ifdef XKB_BUTTON_HINT + if (fwin->language_button) { + XClearWindow(dpy, fwin->language_button->window); + if (wPreferences.modelock) + x11_frame_paint_button(fwin->language_button, fwin->title_texture[fwin->flags.state], + WMColorPixel(fwin->title_color[fwin->flags.state]), + fwin->languagebutton_image, False); + } +#endif + if (fwin->right_button) { + XClearWindow(dpy, fwin->right_button->window); + x11_frame_paint_button(fwin->right_button, fwin->title_texture[fwin->flags.state], + WMColorPixel(fwin->title_color[fwin->flags.state]), + fwin->rbutton_image, False); + } + } +} + +static void +x11_frame_paint_button(WCoreWindow *button, WTexture *texture, + unsigned long color, WPixmap *image, int pushed) +{ + WScreen *scr = button->screen_ptr; + GC copy_gc = scr->copy_gc; + int x = 0, y = 0, d = 0; + int left = 0, width = 0; + + if (!button->window) + return; + + if (pushed) { + if (image) { + if (image->width >= image->height * 2) { + width = image->width / 2; + left = image->width / 2; + } else { + width = image->width; + } + } + XSetClipMask(dpy, copy_gc, None); + if (wPreferences.new_style == TS_NEXT) + XSetForeground(dpy, copy_gc, scr->black_pixel); + else + XSetForeground(dpy, copy_gc, scr->white_pixel); + + d = 1; + if (wPreferences.new_style == TS_NEW) { + XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1); + XSetForeground(dpy, copy_gc, scr->black_pixel); + XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1); + } else if (wPreferences.new_style == TS_OLD) { + XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height); + XSetForeground(dpy, copy_gc, scr->black_pixel); + XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height); + } else { + XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width-3, button->height-3); + XSetForeground(dpy, copy_gc, scr->black_pixel); + XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width-3, button->height-3); + } + } else { + XClearWindow(dpy, button->window); + + if (image) { + if (image->width >= image->height * 2) + width = image->width / 2; + else + width = image->width; + } + d = 0; + + if (wPreferences.new_style == TS_NEW) { + if (texture->any.type == WTEX_SOLID || pushed) + wDrawBevel(button->window, button->width, button->height, + (WTexSolid *) texture, WREL_RAISED); + } else { + wDrawBevel(button->window, button->width, button->height, + scr->widget_texture, WREL_RAISED); + } + } + + if (image) { + XSetClipMask(dpy, copy_gc, image->mask); + x = (button->width - width) / 2 + d; + y = (button->height - image->height) / 2 + d; + XSetClipOrigin(dpy, copy_gc, x - left, y); + if (wPreferences.new_style != TS_NEW) { + XSetForeground(dpy, copy_gc, scr->black_pixel); + if (!pushed) { + if (image->depth == 1) + XCopyPlane(dpy, image->image, button->window, copy_gc, + left, 0, width, image->height, x, y, 1); + else + XCopyArea(dpy, image->image, button->window, copy_gc, + left, 0, width, image->height, x, y); + } else { + if (wPreferences.new_style == TS_OLD) { + XSetForeground(dpy, copy_gc, scr->dark_pixel); + XFillRectangle(dpy, button->window, copy_gc, 0, 0, + button->width, button->height); + } else { + XSetForeground(dpy, copy_gc, scr->black_pixel); + XCopyArea(dpy, image->image, button->window, copy_gc, + left, 0, width, image->height, x, y); + } + } + } else { + if (pushed) { + XSetForeground(dpy, copy_gc, scr->black_pixel); + } else { + XSetForeground(dpy, copy_gc, color); + XSetBackground(dpy, copy_gc, texture->any.color.pixel); + } + XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height); + } + } +} + +/* -------------------------------------------------------------------- */ +/* NETWM/EWMH (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_netwm_init(WScreen *scr) { wNETWMInitStuff(scr); } +static void x11_netwm_cleanup(WScreen *scr) { wNETWMCleanup(scr); } +static void x11_netwm_update_desktop(WScreen *scr) { wNETWMUpdateDesktop(scr); } +static int x11_netwm_get_current_desktop(WScreen *scr) { return wNETWMGetCurrentDesktopFromHint(scr); } +static void x11_netwm_update_actions(WWindow *wwin, int del) { wNETWMUpdateActions(wwin, (Bool)del); } +static void x11_netwm_check_client_hints(WWindow *wwin, int *layer, int *workspace) { wNETWMCheckClientHints(wwin, layer, workspace); } +static void x11_netwm_check_initial_state(WWindow *wwin) { wNETWMCheckInitialClientState(wwin); } +static int x11_netwm_get_pid(WNativeWindow window) { return wNETWMGetPidForWindow((Window)window); } +static void x11_netwm_cleanup_frame_extents(WWindow *wwin) { wNETCleanupFrameExtents(wwin); } +static void x11_netwm_update_opacity(WWindow *wwin) { wNETWMUpdateWindowOpacity(wwin); } + +/* -------------------------------------------------------------------- */ +/* Properties (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_prop_get_protocols(WNativeWindow window, WProtocols *prots) +{ + PropGetProtocols((Window)window, prots); +} + +static unsigned char *x11_prop_get_check_property(WNativeWindow window, + unsigned long hint, + unsigned long type, + int format, int count, + int *ret_count) +{ + return PropGetCheckProperty((Window)window, (Atom)hint, (Atom)type, + format, count, ret_count); +} + +static void x11_prop_set_wmaker_protocols(WNativeWindow root) +{ + PropSetWMakerProtocols((Window)root); +} + +static void x11_prop_set_icon_tile(WScreen *scr, RImage *image) +{ + PropSetIconTileHint(scr, image); +} + +static void x11_prop_cleanup(WNativeWindow root) +{ + PropCleanUp((Window)root); +} + +/* -------------------------------------------------------------------- */ +/* Client operations (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_client_restore(WWindow *wwin) +{ + XSetWindowBorderWidth(dpy, wwin->client_win, wwin->old_border_width); + XReparentWindow(dpy, wwin->client_win, wwin->screen_ptr->root_win, + wwin->frame_x, wwin->frame_y); +} + +static void x11_client_set_state(WWindow *wwin, int state, WNativeWindow icon_win) +{ + long data[2]; + data[0] = (unsigned long)state; + data[1] = (unsigned long)icon_win; + XChangeProperty(dpy, wwin->client_win, w_global.atom.wm.state, + w_global.atom.wm.state, 32, PropModeReplace, + (unsigned char *)data, 2); +} + +static void x11_client_send_protocol(WWindow *wwin, unsigned long protocol, + unsigned long timestamp) +{ + XEvent event; + event.xclient.type = ClientMessage; + event.xclient.message_type = w_global.atom.wm.protocols; + event.xclient.format = 32; + event.xclient.display = dpy; + event.xclient.window = wwin->client_win; + event.xclient.data.l[0] = protocol; + event.xclient.data.l[1] = timestamp; + event.xclient.data.l[2] = 0; + event.xclient.data.l[3] = 0; + XSendEvent(dpy, wwin->client_win, False, NoEventMask, &event); + XSync(dpy, False); +} + +static void x11_client_kill(WWindow *wwin) +{ + XKillClient(dpy, wwin->client_win); + XFlush(dpy); +} + +static void x11_client_get_colormap_windows(WWindow *wwin) +{ +#ifndef NO_CRASHES + if (wwin->cmap_windows) + XFree(wwin->cmap_windows); + wwin->cmap_windows = NULL; + wwin->cmap_window_no = 0; + if (!XGetWMColormapWindows(dpy, wwin->client_win, + &(wwin->cmap_windows), &(wwin->cmap_window_no)) + || !wwin->cmap_windows) { + wwin->cmap_window_no = 0; + wwin->cmap_windows = NULL; + } +#else + (void)wwin; +#endif +} + +/* -------------------------------------------------------------------- */ +/* Misc X11 utilities (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_eat_expose(void) +{ + XEvent event, foo; + if (XCheckMaskEvent(dpy, ExposureMask, &event)) { + while (XCheckWindowEvent(dpy, event.xexpose.window, ExposureMask, &foo)) + ; + x11_eat_expose(); + event.xexpose.count = 0; + XPutBackEvent(dpy, &event); + } +} + +static void x11_move_window(WNativeWindow win, int from_x, int from_y, + int to_x, int to_y) +{ + move_window((Window)win, from_x, from_y, to_x, to_y); +} + +static void x11_slide_windows(WNativeWindow *wins, int n, + int from_x, int from_y, int to_x, int to_y) +{ + slide_windows((Window *)wins, n, from_x, from_y, to_x, to_y); +} + +static char *x11_get_text_selection(WScreen *scr, unsigned long selection) +{ + return wGetTextSelection(scr, (Atom)selection); +} + +static char *x11_get_shortcut_string(WShortKey key) +{ + return GetShortcutKey(key); +} + +static char *x11_get_command_for_window(WNativeWindow win, int elements) +{ + return wGetCommandForWindow((Window)win, elements); +} + +/* -------------------------------------------------------------------- */ +/* Icon rendering (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_icon_update_pixmap(WIcon *icon) +{ + update_icon_pixmap(icon); +} + +static void x11_icon_paint(WIcon *icon) +{ + wIconPaint(icon); +} + +/* -------------------------------------------------------------------- */ +/* App icon (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_appicon_show(WApplication *wapp) +{ + paint_app_icon(wapp); +} + +static void x11_appicon_paint(WAppIcon *aicon) +{ + wAppIconPaint(aicon); +} + +/* -------------------------------------------------------------------- */ +/* Shutdown (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_restore_desktop(WScreen *scr) +{ + RestoreDesktop(scr); +} + +static void x11_wipe_desktop(WScreen *scr) +{ + wWipeDesktop(scr); +} + +/* -------------------------------------------------------------------- */ +/* Resources / colormap (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static int x11_get_color_for_colormap(unsigned long colormap, + const char *color_name, XColor *color) +{ + return wGetColorForColormap((Colormap)colormap, color_name, color); +} + +static void x11_free_color(WScreen *scr, unsigned long pixel) +{ + wFreeColor(scr, pixel); +} + +static void x11_colormap_install(WScreen *scr, WWindow *wwin) +{ + wColormapInstallForWindow(scr, wwin); +} + +/* -------------------------------------------------------------------- */ +/* Protocol-specific init (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_xdnd_init(void) +{ + wXDNDInitializeAtoms(); +} + +static int x11_motif_get_hints(WNativeWindow window, MWMHints *hints_out) +{ + return wGetMWMHints((Window)window, hints_out); +} + +/* -------------------------------------------------------------------- */ +/* Superfluous effects (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_appicon_bounce(WAppIcon *aicon, void *data) +{ + (void)aicon; + (void)data; + /* The bounce is driven by a timer callback in superfluous.c; + * the X11 backend doesn't need a separate entry point since + * the existing code already works when dpy != NULL. */ +} + +/* -------------------------------------------------------------------- */ +/* Startup (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_manage_all_windows(WScreen *scr, int crash_recovery) +{ + wManageAllWindows(scr, crash_recovery); +} + +/* -------------------------------------------------------------------- */ +/* Event dispatch (Phase 80) */ +/* -------------------------------------------------------------------- */ + +static void x11_event_handle_signal_exit(void) +{ + Shutdown(WSExitMode); +} + /* -------------------------------------------------------------------- */ /* Backend vtable instance and active-backend pointer */ /* -------------------------------------------------------------------- */ @@ -2470,6 +2990,8 @@ const WMBackend x11_backend = { .event_discard_enter_leave_until = x11_event_discard_enter_leave_until, .coords_translate = x11_coords_translate, .window_set_save_under = x11_window_set_save_under, + .window_set_background = x11_window_set_background, + .window_set_background_pixmap = x11_window_set_background_pixmap, .keysym_from_keycode = x11_keysym_from_keycode, .overlay_draw_line = x11_overlay_draw_line, .overlay_draw_segments = x11_overlay_draw_segments, @@ -2477,6 +2999,7 @@ const WMBackend x11_backend = { .overlay_draw_string = x11_overlay_draw_string, .window_clear = x11_window_clear, .window_map_subwindows = x11_window_map_subwindows, + .pixmap_free = x11_pixmap_free, .window_get_client_attrs = x11_window_get_client_attrs, .client_get_visual_attrs = x11_client_get_visual_attrs, .window_add_events = x11_window_add_events, @@ -2524,6 +3047,53 @@ const WMBackend x11_backend = { .cursors_init = x11_cursors_init, .cursor_create_named = x11_cursor_create_named, .client_get_gnustep_attrs = x11_client_get_gnustep_attrs, + .texture_alloc_color = x11_texture_alloc_color, + .texture_free_colors = x11_texture_free_colors, + .texture_create_gc = x11_texture_create_gc, + .texture_free_gc = x11_texture_free_gc, + .frame_alloc_border_pixel = x11_frame_alloc_border_pixel, + .frame_update_texture = x11_frame_update_texture, + .frame_paint_button = x11_frame_paint_button, + .netwm_init = x11_netwm_init, + .netwm_cleanup = x11_netwm_cleanup, + .netwm_update_desktop = x11_netwm_update_desktop, + .netwm_get_current_desktop = x11_netwm_get_current_desktop, + .netwm_update_opacity = x11_netwm_update_opacity, + .netwm_update_actions = x11_netwm_update_actions, + .netwm_check_client_hints = x11_netwm_check_client_hints, + .netwm_check_initial_state = x11_netwm_check_initial_state, + .netwm_get_pid = x11_netwm_get_pid, + .netwm_cleanup_frame_extents = x11_netwm_cleanup_frame_extents, + .prop_get_protocols = x11_prop_get_protocols, + .prop_get_check_property = x11_prop_get_check_property, + .prop_set_wmaker_protocols = x11_prop_set_wmaker_protocols, + .prop_set_icon_tile = x11_prop_set_icon_tile, + .prop_cleanup = x11_prop_cleanup, + .client_restore = x11_client_restore, + .client_set_state = x11_client_set_state, + .client_send_protocol = x11_client_send_protocol, + .client_kill = x11_client_kill, + .client_get_colormap_windows = x11_client_get_colormap_windows, + .eat_expose = x11_eat_expose, + .move_window = x11_move_window, + .slide_windows = x11_slide_windows, + .get_text_selection = x11_get_text_selection, + .get_shortcut_string = x11_get_shortcut_string, + .get_command_for_window = x11_get_command_for_window, + .icon_update_pixmap = x11_icon_update_pixmap, + .icon_paint = x11_icon_paint, + .appicon_show = x11_appicon_show, + .appicon_paint = x11_appicon_paint, + .restore_desktop = x11_restore_desktop, + .wipe_desktop = x11_wipe_desktop, + .get_color_for_colormap = x11_get_color_for_colormap, + .free_color = x11_free_color, + .colormap_install = x11_colormap_install, + .xdnd_init = x11_xdnd_init, + .motif_get_hints = x11_motif_get_hints, + .appicon_bounce = x11_appicon_bounce, + .manage_all_windows = x11_manage_all_windows, + .event_handle_signal_exit = x11_event_handle_signal_exit, }; /* diff --git a/src/client.c b/src/client.c index 8bad05a..f9105de 100644 --- a/src/client.c +++ b/src/client.c @@ -49,27 +49,7 @@ */ void wClientRestore(WWindow * wwin) { - if (!dpy) - return; /* Wayland: no X11 reparent/border-width */ -#if 0 - int gx, gy; - - wClientGetGravityOffsets(wwin, &gx, &gy); - /* set the position of the frame on screen */ - wwin->frame_x -= gx * wwin->screen_ptr->frame_border_width; - wwin->frame_y -= gy * wwin->screen_ptr->frame_border_width; - /* if gravity is to the south, account for the border sizes */ - if (gy > 0) - wwin->frame_y += (wwin->frame->top_width + wwin->frame->bottom_width); -#endif - XSetWindowBorderWidth(dpy, wwin->client_win, wwin->old_border_width); - XReparentWindow(dpy, wwin->client_win, wwin->screen_ptr->root_win, wwin->frame_x, wwin->frame_y); - - /* don't let the window get iconified after restart */ - /* - if (wwin->flags.shaded) - wClientSetState(wwin, NormalState, None); - */ + wm_backend->client_restore(wwin); } /* @@ -89,15 +69,7 @@ void wClientSetState(WWindow * wwin, int state, Window icon_win) wwin->state = state; - if (!dpy) - return; /* Wayland: no X11 WM_STATE property */ - - data[0] = (unsigned long)state; - data[1] = (unsigned long)icon_win; - - XChangeProperty(dpy, wwin->client_win, w_global.atom.wm.state, - w_global.atom.wm.state, 32, PropModeReplace, - (unsigned char *)data, 2); + wm_backend->client_set_state(wwin, state, (WNativeWindow)icon_win); } void wClientGetGravityOffsets(WWindow * wwin, int *ofs_x, int *ofs_y) @@ -248,40 +220,12 @@ void wClientConfigure(WWindow * wwin, XConfigureRequestEvent * xcre) void wClientSendProtocol(WWindow * wwin, Atom protocol, Time time) { - XEvent event; - - if (!dpy) { - /* Phase 63: Wayland — there are no X11 ClientMessages. All atoms - * are 0 in the Wayland path so atom comparison is unreliable; all - * callers that reach here are requesting a polite close (the only - * Wayland-meaningful WM_PROTOCOL), so dispatch client_close. */ - wm_backend->client_close(wwin->client_win); - return; - } - - event.xclient.type = ClientMessage; - event.xclient.message_type = w_global.atom.wm.protocols; - event.xclient.format = 32; - event.xclient.display = dpy; - event.xclient.window = wwin->client_win; - event.xclient.data.l[0] = protocol; - event.xclient.data.l[1] = time; - event.xclient.data.l[2] = 0; - event.xclient.data.l[3] = 0; - XSendEvent(dpy, wwin->client_win, False, NoEventMask, &event); - XSync(dpy, False); + wm_backend->client_send_protocol(wwin, (unsigned long)protocol, (unsigned long)time); } void wClientKill(WWindow * wwin) { - if (!dpy) { - /* Wayland: request close via vtable */ - wm_backend->client_close(wwin->client_win); - return; - } - XKillClient(dpy, wwin->client_win); - - XFlush(dpy); + wm_backend->client_kill(wwin); } /* @@ -322,7 +266,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event) /* Title has changed, update the icon title */ if (wwin->icon) { wIconChangeTitle(wwin->icon, wwin); - wIconPaint(wwin->icon); + wm_backend->icon_paint(wwin->icon); } break; @@ -469,7 +413,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event) wapp = wApplicationOf(wwin->main_window); if (wapp && wapp->app_icon) { wIconUpdate(wapp->app_icon->icon); - wAppIconPaint(wapp->app_icon); + wm_backend->appicon_paint(wapp->app_icon); } } @@ -550,7 +494,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event) default: if (event->atom == w_global.atom.wm.protocols) { - PropGetProtocols(wwin->client_win, &wwin->protocols); + wm_backend->prop_get_protocols((WNativeWindow)wwin->client_win, &wwin->protocols); wwin->client_flags.kill_close = !wwin->protocols.DELETE_WINDOW; @@ -560,7 +504,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event) } else if (event->atom == w_global.atom.wm.colormap_windows) { GetColormapWindows(wwin); - wColormapInstallForWindow(wwin->screen_ptr, wwin); + wm_backend->colormap_install(wwin->screen_ptr, wwin); } else if (event->atom == w_global.atom.wmaker.menu) { WApplication *wapp; @@ -738,20 +682,5 @@ wClientGetNormalHints(WWindow * wwin, WClientAttributes * wattribs, int geometry void GetColormapWindows(WWindow * wwin) { -#ifndef NO_CRASHES - if (!dpy) - return; /* Wayland: no X11 colormaps */ - if (wwin->cmap_windows) { - XFree(wwin->cmap_windows); - } - - wwin->cmap_windows = NULL; - wwin->cmap_window_no = 0; - - if (!XGetWMColormapWindows(dpy, wwin->client_win, &(wwin->cmap_windows), &(wwin->cmap_window_no)) - || !wwin->cmap_windows) { - wwin->cmap_window_no = 0; - wwin->cmap_windows = NULL; - } -#endif + wm_backend->client_get_colormap_windows(wwin); } diff --git a/src/colormap.c b/src/colormap.c index 6fb81cd..fa5a85c 100644 --- a/src/colormap.c +++ b/src/colormap.c @@ -38,8 +38,6 @@ void wColormapInstallForWindow(WScreen * scr, WWindow * wwin) int done = 0; Window xwin = None; - if (!dpy) - return; /* Wayland: no X11 colormaps */ if (wwin) { xwin = wwin->client_win; diff --git a/src/defaults.c b/src/defaults.c index 4d4cb11..75c5ee1 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -1307,7 +1307,7 @@ void wDefaultUpdateIcons(WScreen *scr) while (aicon) { /* Get the application icon, default included */ wIconChangeImageFile(aicon->icon, NULL); - wAppIconPaint(aicon); + wm_backend->appicon_paint(aicon); aicon = aicon->next; } @@ -2543,7 +2543,7 @@ static int setIconTile(WScreen * scr, WDefaultEntry * entry, void *tdata, void * scr->icon_tile = img; /* put the icon in the noticeboard hint */ - PropSetIconTileHint(scr, img); + wm_backend->prop_set_icon_tile(scr, img); if (!wPreferences.flags.noclip || wPreferences.flags.clip_merged_in_dock) { if (scr->clip_tile) { @@ -2691,7 +2691,7 @@ static int setHightlight(WScreen * scr, WDefaultEntry * entry, void *tdata, void scr->select_color = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_MENU_COLOR; } @@ -2709,7 +2709,7 @@ static int setHightlightText(WScreen * scr, WDefaultEntry * entry, void *tdata, scr->select_text_color = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_MENU_COLOR; } @@ -2726,7 +2726,7 @@ static int setClipTitleColor(WScreen * scr, WDefaultEntry * entry, void *tdata, WMReleaseColor(scr->clip_title_color[widx]); scr->clip_title_color[widx] = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_ICON_TITLE_COLOR; } @@ -2745,7 +2745,7 @@ static int setWTitleColor(WScreen * scr, WDefaultEntry * entry, void *tdata, voi scr->window_title_color[widx] = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_WINDOW_TITLE_COLOR; } @@ -2763,7 +2763,7 @@ static int setMenuTitleColor(WScreen * scr, WDefaultEntry * entry, void *tdata, scr->menu_title_color[0] = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_MENU_TITLE_COLOR; } @@ -2787,7 +2787,7 @@ static int setMenuTextColor(WScreen * scr, WDefaultEntry * entry, void *tdata, v WMSetColorAlpha(scr->dtext_color, 0xffff); } - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_MENU_COLOR; } @@ -2811,7 +2811,7 @@ static int setMenuDisabledColor(WScreen * scr, WDefaultEntry * entry, void *tdat WMSetColorAlpha(scr->dtext_color, 0xffff); } - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_MENU_COLOR; } @@ -2828,7 +2828,7 @@ static int setIconTitleColor(WScreen * scr, WDefaultEntry * entry, void *tdata, WMReleaseColor(scr->icon_title_color); scr->icon_title_color = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_ICON_TITLE_COLOR; } @@ -2874,7 +2874,7 @@ static int setFrameBorderColor(WScreen * scr, WDefaultEntry * entry, void *tdata WMReleaseColor(scr->frame_border_color); scr->frame_border_color = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_FRAME_BORDER; } @@ -2891,7 +2891,7 @@ static int setFrameFocusedBorderColor(WScreen *scr, WDefaultEntry *entry, void * WMReleaseColor(scr->frame_focused_border_color); scr->frame_focused_border_color = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_FRAME_BORDER; } @@ -2908,7 +2908,7 @@ static int setFrameSelectedBorderColor(WScreen * scr, WDefaultEntry * entry, voi WMReleaseColor(scr->frame_selected_border_color); scr->frame_selected_border_color = WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue, True); - wFreeColor(scr, color->pixel); + wm_backend->free_color(scr, color->pixel); return REFRESH_FRAME_BORDER; } diff --git a/src/dock.c b/src/dock.c index 5601c37..93c96fc 100644 --- a/src/dock.c +++ b/src/dock.c @@ -578,10 +578,10 @@ static void keepIconsCallback(WMenu *menu, WMenuEntry *entry) * Update icon pixmap, RImage doesn't change, * so call wIconUpdate is not needed */ - update_icon_pixmap(aicon->icon); + wm_backend->icon_update_pixmap(aicon->icon); /* Paint it */ - wAppIconPaint(aicon); + wm_backend->appicon_paint(aicon); } } save_appicon(aicon); @@ -1419,7 +1419,7 @@ void wClipIconPaint(WAppIcon *aicon) char *ws_name, ws_number[sizeof scr->current_workspace * CHAR_BIT / 3 + 1]; int ty, tx; - wIconPaint(aicon->icon); + wm_backend->icon_paint(aicon->icon); length = strlen(workspace->name); ws_name = wmalloc(length + 1); @@ -1467,7 +1467,7 @@ static void dockIconPaint(WAppIcon *btn) } else if (wIsADrawer(btn)) { wDrawerIconPaint(btn); } else { - wAppIconPaint(btn); + wm_backend->appicon_paint(btn); save_appicon(btn); } } @@ -2242,10 +2242,10 @@ Bool wDockAttachIcon(WDock *dock, WAppIcon *icon, int x, int y, Bool update_icon * so call wIconUpdate is not needed */ if (lupdate_icon) - update_icon_pixmap(icon->icon); + wm_backend->icon_update_pixmap(icon->icon); /* Paint it */ - wAppIconPaint(icon); + wm_backend->appicon_paint(icon); /* Save it */ save_appicon(icon); @@ -2393,10 +2393,10 @@ Bool wDockMoveIconBetweenDocks(WDock *src, WDock *dest, WAppIcon *icon, int x, i * so call wIconUpdate is not needed */ if (update_icon) - update_icon_pixmap(icon->icon); + wm_backend->icon_update_pixmap(icon->icon); /* Paint it */ - wAppIconPaint(icon); + wm_backend->appicon_paint(icon); return True; } @@ -2476,10 +2476,10 @@ void wDockDetach(WDock *dock, WAppIcon *icon) * so call wIconUpdate is not needed */ if (update_icon) - update_icon_pixmap(icon->icon); + wm_backend->icon_update_pixmap(icon->icon); /* Paint it */ - wAppIconPaint(icon); + wm_backend->appicon_paint(icon); if (wPreferences.auto_arrange_icons) wArrangeIcons(dock->screen_ptr, True); @@ -3299,7 +3299,7 @@ void wDockTrackWindowLaunch(WDock *dock, Window window) wLowerFrame(aicon->icon->core); XMapWindow(dpy, aicon->icon->core->window); aicon->launching = 1; - wAppIconPaint(aicon); + wm_backend->appicon_paint(aicon); slide_window(aicon->icon->core->window, x0, y0, icon->x_pos, icon->y_pos); XUnmapWindow(dpy, aicon->icon->core->window); wAppIconDestroy(aicon); @@ -4293,7 +4293,7 @@ int wClipMakeIconOmnipresent(WAppIcon *aicon, int omnipresent) } } - wAppIconPaint(aicon); + wm_backend->appicon_paint(aicon); return status; } @@ -4539,7 +4539,7 @@ void wDrawerIconPaint(WAppIcon *dicon) GC gc = scr->draw_gc; WMColor *color; - wIconPaint(dicon->icon); + wm_backend->icon_paint(dicon->icon); if (!dicon->dock->collapsed) color = scr->clip_title_color[CLIP_NORMAL]; diff --git a/src/dockedapp.c b/src/dockedapp.c index 044eda7..0eb1430 100644 --- a/src/dockedapp.c +++ b/src/dockedapp.c @@ -184,7 +184,7 @@ static void panelBtnCallback(WMWidget * self, void *data) else if (wIsADrawer(aicon)) wDrawerIconPaint(aicon); else - wAppIconPaint(aicon); + wm_backend->appicon_paint(aicon); wDefaultChangeIcon(aicon->wm_instance, aicon->wm_class, text); } diff --git a/src/event.c b/src/event.c index e4db65e..faab6ab 100644 --- a/src/event.c +++ b/src/event.c @@ -167,11 +167,7 @@ void DispatchEvent(WMEvent * event) * wl_display_terminate() from within loop context. EventLoop() * then calls Exit(0) after wl_display_run() returns. */ - if (!dpy) { - wm_backend->event_loop_terminate(); - return; - } - Shutdown(WSExitMode); + wm_backend->event_handle_signal_exit(); } else if (WCHECK_STATE(WSTATE_NEED_RESTART)) { WCHANGE_STATE(WSTATE_RESTARTING); @@ -1175,7 +1171,7 @@ static void handleEnterNotify(WMEvent * event) wwin = wWindowFor(event->u.crossing.window); if (!wwin) { if (wPreferences.colormap_mode == WCM_POINTER) { - wColormapInstallForWindow(scr, NULL); + wm_backend->colormap_install(scr, NULL); } if (scr->autoRaiseTimer && event->u.crossing.window == event->u.crossing.window) { WMDeleteTimerHandler(scr->autoRaiseTimer); @@ -1209,9 +1205,9 @@ static void handleEnterNotify(WMEvent * event) * is colormap_follows_mouse */ if (wPreferences.colormap_mode == WCM_POINTER) { if (wwin->client_win == event->u.crossing.window) - wColormapInstallForWindow(scr, wwin); + wm_backend->colormap_install(scr, wwin); else - wColormapInstallForWindow(scr, NULL); + wm_backend->colormap_install(scr, NULL); } } diff --git a/src/framewin.c b/src/framewin.c index 8ae0201..3a734b0 100644 --- a/src/framewin.c +++ b/src/framewin.c @@ -58,20 +58,7 @@ static void updateTitlebar(WFrameWindow * fwin); static void allocFrameBorderPixel(Colormap colormap, const char *color_name, unsigned long **pixel); static void allocFrameBorderPixel(Colormap colormap, const char *color_name, unsigned long **pixel) { - XColor xcol; - - *pixel = NULL; - - /* Phase 19: Wayland — no X11 colormap to query */ - if (!dpy) - return; - - if (! wGetColorForColormap(colormap, color_name, &xcol)) - return; - - *pixel = wmalloc(sizeof(unsigned long)); - if (*pixel) - **pixel = xcol.pixel; + wm_backend->frame_alloc_border_pixel((unsigned long)colormap, color_name, pixel); } WFrameWindow *wFrameWindowCreate(WScreen * scr, int wlevel, int x, int y, @@ -241,35 +228,33 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) if (width < theight * 4) fwin->flags.lbutton_dont_fit = 1; - else if (dpy) - XMapRaised(dpy, fwin->left_button->window); + else + wm_backend->window_map_raised(fwin->left_button->window); } else if (wPreferences.new_style == TS_OLD) { fwin->left_button = wCoreCreate(fwin->titlebar, 3, (theight - bsize) / 2, bsize, bsize); - if (dpy) - XSetWindowBackground(dpy, fwin->left_button->window, + wm_backend->window_set_background(fwin->left_button->window, scr->widget_texture->normal.pixel); if (width < theight * 3) fwin->flags.lbutton_dont_fit = 1; - else if (dpy) - XMapRaised(dpy, fwin->left_button->window); + else + wm_backend->window_map_raised(fwin->left_button->window); } else { fwin->left_button = wCoreCreate(fwin->titlebar, 3, (theight-bsize)/2, bsize, bsize); - if (dpy) - XSetWindowBackground(dpy, fwin->left_button->window, + wm_backend->window_set_background(fwin->left_button->window, scr->widget_texture->dark.pixel); if (width < theight * 3) fwin->flags.lbutton_dont_fit = 1; - else if (dpy) - XMapRaised(dpy, fwin->left_button->window); + else + wm_backend->window_map_raised(fwin->left_button->window); } } @@ -281,21 +266,20 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) if (width < theight * 4) fwin->flags.languagebutton_dont_fit = 1; - else if (dpy) - XMapRaised(dpy, fwin->language_button->window); + else + wm_backend->window_map_raised(fwin->language_button->window); } else { fwin->language_button = wCoreCreate(fwin->titlebar, bsize + 6, (theight - bsize) / 2, bsize, bsize); - if (dpy) - XSetWindowBackground(dpy, fwin->language_button->window, + wm_backend->window_set_background(fwin->language_button->window, scr->widget_texture->normal.pixel); if (width < theight * 3) fwin->flags.languagebutton_dont_fit = 1; - else if (dpy) - XMapRaised(dpy, fwin->language_button->window); + else + wm_backend->window_map_raised(fwin->language_button->window); } } #endif @@ -309,29 +293,26 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) fwin->right_button = wCoreCreate(fwin->titlebar, width - bsize - 3, (theight - bsize) / 2, bsize, bsize); - if (dpy) - XSetWindowBackground(dpy, fwin->right_button->window, + wm_backend->window_set_background(fwin->right_button->window, scr->widget_texture->normal.pixel); } else { fwin->right_button = wCoreCreate(fwin->titlebar, width-bsize-3, (theight-bsize)/2, bsize, bsize); - if (dpy) - XSetWindowBackground(dpy, fwin->right_button->window, + wm_backend->window_set_background(fwin->right_button->window, scr->widget_texture->dark.pixel); } if (width < theight * 2) fwin->flags.rbutton_dont_fit = 1; - else if (dpy) - XMapRaised(dpy, fwin->right_button->window); + else + wm_backend->window_map_raised(fwin->right_button->window); } if (wPreferences.new_style == TS_NEW) updateTitlebar(fwin); - if (dpy) - XMapRaised(dpy, fwin->titlebar->window); + wm_backend->window_map_raised(fwin->titlebar->window); fwin->flags.need_texture_remake = 1; } @@ -352,10 +333,8 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) fwin->resizebar_corner_width = 0; } - if (dpy) { - XMapWindow(dpy, fwin->resizebar->window); - XLowerWindow(dpy, fwin->resizebar->window); - } + wm_backend->window_map(fwin->resizebar->window); + wm_backend->stacking_lower(fwin->resizebar->window); fwin->flags.need_texture_remake = 1; } else { @@ -376,12 +355,10 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) if (height + fwin->top_width + fwin->bottom_width != fwin->core->height && !(flags & WFF_IS_SHADED)) wFrameWindowResize(fwin, width, height + fwin->top_width + fwin->bottom_width); - if (dpy) { - if (flags & WFF_BORDER) - XSetWindowBorderWidth(dpy, fwin->core->window, scr->frame_border_width); - else - XSetWindowBorderWidth(dpy, fwin->core->window, 0); - } + if (flags & WFF_BORDER) + wm_backend->window_set_border_width(fwin->core->window, scr->frame_border_width); + else + wm_backend->window_set_border_width(fwin->core->window, 0); /* setup object descriptors */ if (fwin->titlebar) { @@ -427,18 +404,16 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) allocFrameBorderPixel(fwin->colormap, WMGetColorRGBDescription(scr->frame_focused_border_color), &fwin->focused_border_pixel); allocFrameBorderPixel(fwin->colormap, WMGetColorRGBDescription(scr->frame_selected_border_color), &fwin->selected_border_pixel); - if (dpy) { - if (flags & WFF_SELECTED) { - if (fwin->selected_border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->selected_border_pixel); + if (flags & WFF_SELECTED) { + if (fwin->selected_border_pixel) + wm_backend->window_set_border(fwin->core->window, *fwin->selected_border_pixel); + } else { + if (fwin->flags.state == WS_FOCUSED) { + if (fwin->focused_border_pixel) + wm_backend->window_set_border(fwin->core->window, *fwin->focused_border_pixel); } else { - if (fwin->flags.state == WS_FOCUSED) { - if (fwin->focused_border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->focused_border_pixel); - } else { - if (fwin->border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->border_pixel); - } + if (fwin->border_pixel) + wm_backend->window_set_border(fwin->core->window, *fwin->border_pixel); } } } @@ -493,14 +468,12 @@ void wFrameWindowChangeState(WFrameWindow * fwin, int state) fwin->flags.state = state; fwin->flags.need_texture_change = 1; - if (dpy) { - if (fwin->flags.state == WS_FOCUSED) { - if (fwin->focused_border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->focused_border_pixel); - } else { - if (fwin->border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->border_pixel); - } + if (fwin->flags.state == WS_FOCUSED) { + if (fwin->focused_border_pixel) + wm_backend->window_set_border(fwin->core->window, *fwin->focused_border_pixel); + } else { + if (fwin->border_pixel) + wm_backend->window_set_border(fwin->core->window, *fwin->border_pixel); } wFrameWindowPaint(fwin); } @@ -796,67 +769,7 @@ renderResizebarTexture(WScreen * scr, WTexture * texture, int width, int height, static void updateTexture(WFrameWindow * fwin) { - int i; - unsigned long pixel; - - /* Phase 19: Wayland — no X11 connection to update window backgrounds */ - if (!dpy) - return; - /* Wayland backend: all frame sub-windows have ID=None (WNATIVE_NONE); - * skip X11 background updates to avoid BadDrawable on XWayland. */ - if (!fwin->titlebar || !fwin->titlebar->window) - return; - - i = fwin->flags.state; - if (fwin->titlebar) { - if (fwin->title_texture[i]->any.type != WTEX_SOLID) { - XSetWindowBackgroundPixmap(dpy, fwin->titlebar->window, fwin->title_back[i]); - if (wPreferences.new_style == TS_NEW) { - if (fwin->left_button && fwin->lbutton_back[i]) - XSetWindowBackgroundPixmap(dpy, fwin->left_button->window, - fwin->lbutton_back[i]); - -#ifdef XKB_BUTTON_HINT - if (fwin->language_button && fwin->languagebutton_back[i]) - XSetWindowBackgroundPixmap(dpy, fwin->language_button->window, - fwin->languagebutton_back[i]); -#endif - - if (fwin->right_button && fwin->rbutton_back[i]) - XSetWindowBackgroundPixmap(dpy, fwin->right_button->window, - fwin->rbutton_back[i]); - } - } else { - pixel = fwin->title_texture[i]->solid.normal.pixel; - XSetWindowBackground(dpy, fwin->titlebar->window, pixel); - if (wPreferences.new_style == TS_NEW) { - if (fwin->left_button) - XSetWindowBackground(dpy, fwin->left_button->window, pixel); -#ifdef XKB_BUTTON_HINT - if (fwin->language_button) - XSetWindowBackground(dpy, fwin->language_button->window, pixel); -#endif - if (fwin->right_button) - XSetWindowBackground(dpy, fwin->right_button->window, pixel); - } - } - XClearWindow(dpy, fwin->titlebar->window); - - if (fwin->left_button) { - XClearWindow(dpy, fwin->left_button->window); - handleButtonExpose(&fwin->left_button->descriptor, NULL); - } -#ifdef XKB_BUTTON_HINT - if (fwin->language_button) { - XClearWindow(dpy, fwin->language_button->window); - handleButtonExpose(&fwin->language_button->descriptor, NULL); - } -#endif - if (fwin->right_button) { - XClearWindow(dpy, fwin->right_button->window); - handleButtonExpose(&fwin->right_button->descriptor, NULL); - } - } + wm_backend->frame_update_texture(fwin); } static void remakeTexture(WFrameWindow * fwin, int state) @@ -936,14 +849,12 @@ static void remakeTexture(WFrameWindow * fwin, int state) } /* this part should be in updateTexture() */ - if (dpy) { - if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) - XSetWindowBackgroundPixmap(dpy, fwin->resizebar->window, fwin->resizebar_back[0]); - else - XSetWindowBackground(dpy, fwin->resizebar->window, - fwin->resizebar_texture[0]->solid.normal.pixel); - XClearWindow(dpy, fwin->resizebar->window); - } + if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) + wm_backend->window_set_background_pixmap(fwin->resizebar->window, fwin->resizebar_back[0]); + else + wm_backend->window_set_background(fwin->resizebar->window, + fwin->resizebar_texture[0]->solid.normal.pixel); + wm_backend->window_clear(fwin->resizebar->window); } } @@ -1200,17 +1111,15 @@ static void reconfigure(WFrameWindow * fwin, int x, int y, int width, int height } } - if (dpy) { - if (wPreferences.new_style == TS_NEW) { - if (fwin->right_button && fwin->right_button->window) - XMoveWindow(dpy, fwin->right_button->window, - width - fwin->right_button->width + 1, 0); - } else { - if (fwin->right_button && fwin->right_button->window) - XMoveWindow(dpy, fwin->right_button->window, - width - fwin->right_button->width - 3, - (fwin->titlebar->height - fwin->right_button->height) / 2); - } + if (wPreferences.new_style == TS_NEW) { + if (fwin->right_button && fwin->right_button->window) + wm_backend->window_move(fwin->right_button->window, + width - fwin->right_button->width + 1, 0); + } else { + if (fwin->right_button && fwin->right_button->window) + wm_backend->window_move(fwin->right_button->window, + width - fwin->right_button->width - 3, + (fwin->titlebar->height - fwin->right_button->height) / 2); } updateTitlebar(fwin); checkTitleSize(fwin); @@ -1254,7 +1163,7 @@ int wFrameWindowChangeTitle(WFrameWindow *fwin, const char *new_title) fwin->title = wstrdup(new_title); if (fwin->titlebar) { - if (dpy) XClearWindow(dpy, fwin->titlebar->window); + wm_backend->window_clear(fwin->titlebar->window); wFrameWindowPaint(fwin); } @@ -1330,107 +1239,7 @@ static void checkTitleSize(WFrameWindow * fwin) static void paintButton(WCoreWindow * button, WTexture * texture, unsigned long color, WPixmap * image, int pushed) { - WScreen *scr = button->screen_ptr; - GC copy_gc = scr->copy_gc; - - /* Phase 19: Wayland — no X11 display or GCs for button rendering */ - if (!dpy) - return; - /* Wayland backend: button->window is WNATIVE_NONE (0); skip to avoid BadDrawable. */ - if (!button->window) - return; - int x = 0, y = 0, d = 0; - int left = 0, width = 0; - - /* setup stuff according to the state */ - if (pushed) { - if (image) { - if (image->width >= image->height * 2) { - /* the image contains 2 pictures: the second is for the - * pushed state */ - width = image->width / 2; - left = image->width / 2; - } else { - width = image->width; - } - } - XSetClipMask(dpy, copy_gc, None); - if (wPreferences.new_style == TS_NEXT) - XSetForeground(dpy, copy_gc, scr->black_pixel); - else - XSetForeground(dpy, copy_gc, scr->white_pixel); - - d = 1; - if (wPreferences.new_style == TS_NEW) { - XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1); - XSetForeground(dpy, copy_gc, scr->black_pixel); - XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width - 1, button->height - 1); - } else if (wPreferences.new_style == TS_OLD) { - XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height); - XSetForeground(dpy, copy_gc, scr->black_pixel); - XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height); - } else { - XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width-3, button->height-3); - XSetForeground(dpy, copy_gc, scr->black_pixel); - XDrawRectangle(dpy, button->window, copy_gc, 0, 0, button->width-3, button->height-3); - } - } else { - XClearWindow(dpy, button->window); - - if (image) { - if (image->width >= image->height * 2) - width = image->width / 2; - else - width = image->width; - } - d = 0; - - if (wPreferences.new_style == TS_NEW) { - if (texture->any.type == WTEX_SOLID || pushed) - wDrawBevel(button->window, button->width, button->height, - (WTexSolid *) texture, WREL_RAISED); - } else { - wDrawBevel(button->window, button->width, button->height, - scr->widget_texture, WREL_RAISED); - } - } - - if (image) { - /* display image */ - XSetClipMask(dpy, copy_gc, image->mask); - x = (button->width - width) / 2 + d; - y = (button->height - image->height) / 2 + d; - XSetClipOrigin(dpy, copy_gc, x - left, y); - if (wPreferences.new_style != TS_NEW) { - XSetForeground(dpy, copy_gc, scr->black_pixel); - if (!pushed) { - if (image->depth == 1) - XCopyPlane(dpy, image->image, button->window, copy_gc, - left, 0, width, image->height, x, y, 1); - else - XCopyArea(dpy, image->image, button->window, copy_gc, - left, 0, width, image->height, x, y); - } else { - if (wPreferences.new_style == TS_OLD) { - XSetForeground(dpy, copy_gc, scr->dark_pixel); - XFillRectangle(dpy, button->window, copy_gc, 0, 0, - button->width, button->height); - } else { - XSetForeground(dpy, copy_gc, scr->black_pixel); - XCopyArea(dpy, image->image, button->window, copy_gc, - left, 0, width, image->height, x, y); - } - } - } else { - if (pushed) { - XSetForeground(dpy, copy_gc, scr->black_pixel); - } else { - XSetForeground(dpy, copy_gc, color); - XSetBackground(dpy, copy_gc, texture->any.color.pixel); - } - XFillRectangle(dpy, button->window, copy_gc, 0, 0, button->width, button->height); - } - } + wm_backend->frame_paint_button(button, texture, color, image, pushed); } static void handleButtonExpose(WObjDescriptor * desc, WBackendEvent * event) diff --git a/src/icon.c b/src/icon.c index a84b47a..43bf1fa 100644 --- a/src/icon.c +++ b/src/icon.c @@ -660,9 +660,6 @@ void wIconUpdate(WIcon *icon) void update_icon_pixmap(WIcon *icon) { - /* Phase 79: Wayland — no X11 pixmap infrastructure; skip rendering */ - if (!dpy) - return; if (icon->pixmap != None) XFreePixmap(dpy, icon->pixmap); @@ -827,9 +824,6 @@ void wIconPaint(WIcon *icon) if (!icon || !icon->core || !icon->core->screen_ptr) return; - /* Phase 79: Wayland — no X11 rendering surface for icon */ - if (!dpy) - return; /* Wayland backend: icon windows have ID=None; skip X11 drawing. */ if (!icon->core->window) return; diff --git a/src/main.c b/src/main.c index 31afd13..215ee4c 100644 --- a/src/main.c +++ b/src/main.c @@ -201,9 +201,6 @@ noreturn void Exit(int status) if (wm_backend) wm_backend->display_close(); - if (dpy) - XCloseDisplay(dpy); - RShutdown(); /* wrlib clean exit */ wutil_shutdown(); /* WUtil clean-up */ @@ -225,10 +222,7 @@ void Restart(char *manager, Bool abortOnFailure) } } } - if (dpy) { - XCloseDisplay(dpy); - dpy = NULL; - } + wm_backend->display_close(); if (!prog) { execvp(Arguments[0], Arguments); wfatal(_("failed to restart Window Maker.")); diff --git a/src/misc.c b/src/misc.c index 6964bf7..817641a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -76,9 +76,6 @@ static void eatExpose(void) { XEvent event, foo; - /* Phase 19: Wayland — no X11 event queue to drain */ - if (!dpy) - return; /* compress all expose events into a single one */ @@ -95,11 +92,6 @@ static void eatExpose(void) void move_window(Window win, int from_x, int from_y, int to_x, int to_y) { - /* Phase 19: Wayland — frame windows are virtual; skip X11 move */ - if (!dpy) { - (void) win; (void) from_x; (void) from_y; (void) to_x; (void) to_y; - return; - } #ifdef USE_ANIMATIONS if (wPreferences.no_animations) XMoveWindow(dpy, win, to_x, to_y); @@ -119,12 +111,6 @@ void move_window(Window win, int from_x, int from_y, int to_x, int to_y) * following windows are going to be offset by (ICON_SIZE*i,0) */ void slide_windows(Window wins[], int n, int from_x, int from_y, int to_x, int to_y) { - /* Phase 19: Wayland — frame windows are virtual; skip X11 slide */ - if (!dpy) { - (void)wins; (void)n; (void)from_x; (void)from_y; (void)to_x; (void)to_y; - return; - } - time_t time0 = time(NULL); float dx, dy, x = from_x, y = from_y, px, py; Bool is_dx_nul, is_dy_nul; @@ -302,13 +288,10 @@ static void timeoutHandler(void *data) *(int *)data = 1; } -static char *getTextSelection(WScreen * screen, Atom selection) +char *wGetTextSelection(WScreen * screen, Atom selection) { int buffer = -1; - /* Phase 19: Wayland — no X11 selection/clipboard available */ - if (!dpy) - return NULL; switch (selection) { case WA_CUT_BUFFER0: @@ -397,9 +380,9 @@ static char *getselection(WScreen * scr) { char *tmp; - tmp = getTextSelection(scr, WA_PRIMARY); + tmp = wm_backend->get_text_selection(scr, WA_PRIMARY); if (!tmp) - tmp = getTextSelection(scr, WA_CUT_BUFFER0); + tmp = wm_backend->get_text_selection(scr, WA_CUT_BUFFER0); return tmp; } @@ -694,20 +677,15 @@ void ExecuteInputCommand(WScreen *scr, const char *cmdline) cmd = ExpandOptions(scr, cmdline); if (cmd) { - /* Phase 19: Wayland — skip cursor grab visual feedback */ - if (dpy) { - XGrabPointer(dpy, scr->root_win, True, 0, - GrabModeAsync, GrabModeAsync, None, wPreferences.cursor[WCUR_WAIT], CurrentTime); - XSync(dpy, False); - } + wm_backend->pointer_grab(scr->root_win, WNATIVE_NONE, 0, + WCUR_WAIT, True, 0); + wm_backend->event_sync(False); ExecuteShellCommand(scr, cmd); wfree(cmd); - if (dpy) { - XUngrabPointer(dpy, CurrentTime); - XSync(dpy, False); - } + wm_backend->pointer_ungrab(0); + wm_backend->event_sync(False); } } @@ -815,8 +793,6 @@ char *GetShortcutKey(WShortKey key) } /* Phase 19: Wayland — no X11 keycode-to-keysym mapping available */ - if (!dpy) - return NULL; key_name = XKeysymToString(W_KeycodeToKeysym(dpy, key.keycode, 0)); if (!key_name) return NULL; @@ -1094,28 +1070,11 @@ char *StrConcatDot(const char *a, const char *b) return str; } -static char *getCommandForWindow(Window win, int elements) +char *wGetCommandForWindow(Window win, int elements) { char **argv, *command = NULL; int argc; - if (!dpy) { - /* Wayland: read WM_COMMAND from the vtable-backed store. */ - if (!wm_backend->icccm_get_command((WNativeWindow)win, &argv, &argc)) - return NULL; - if (argc > 0 && argv != NULL) { - if (elements == 0) - elements = argc; - command = wtokenjoin(argv, WMIN(argc, elements)); - if (command[0] == 0) { - wfree(command); - command = NULL; - } - } - wm_backend->icccm_free_command(argv); - return command; - } - if (XGetCommand(dpy, win, &argv, &argc)) { if (argc > 0 && argv != NULL) { if (elements == 0) @@ -1137,5 +1096,5 @@ static char *getCommandForWindow(Window win, int elements) /* Free result when done */ char *GetCommandForWindow(Window win) { - return getCommandForWindow(win, 0); + return wm_backend->get_command_for_window((WNativeWindow)win, 0); } diff --git a/src/misc.h b/src/misc.h index dbfc187..a7a64db 100644 --- a/src/misc.h +++ b/src/misc.h @@ -54,4 +54,6 @@ char *GetShortcutKey(WShortKey key); char *EscapeWM_CLASS(const char *name, const char *class); char *StrConcatDot(const char *a, const char *b); char *GetCommandForWindow(Window win); +char *wGetTextSelection(WScreen *scr, Atom selection); +char *wGetCommandForWindow(Window win, int elements); #endif diff --git a/src/monitor.c b/src/monitor.c index 5b3893a..6e489f2 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -41,10 +41,8 @@ static int showCrashDialog(int sig) { int crashAction; - dpy = XOpenDisplay(NULL); - if (dpy) { -/* XXX TODO make sure that window states are saved and restored via netwm */ - + if (!wm_backend->is_wayland) { + dpy = XOpenDisplay(NULL); XGrabServer(dpy); crashAction = wShowCrashingDialogPanel(sig); XCloseDisplay(dpy); diff --git a/src/motif.c b/src/motif.c index 59ce971..c2305e0 100644 --- a/src/motif.c +++ b/src/motif.c @@ -54,15 +54,6 @@ #define MWM_DECOR_MINIMIZE (1L << 5) #define MWM_DECOR_MAXIMIZE (1L << 6) -/* Motif window hints */ -typedef struct { - long flags; - long functions; - long decorations; - long inputMode; - long status; -} MWMHints; - static Atom _XA_MOTIF_WM_HINTS; static void setupMWMHints(WWindow *wwin, MWMHints *mwm_hints) @@ -157,13 +148,11 @@ static void setupMWMHints(WWindow *wwin, MWMHints *mwm_hints) } } -static int getMWMHints(Window window, MWMHints *mwmhints) +int wGetMWMHints(Window window, MWMHints *mwmhints) { unsigned long *data; int count; - if (!dpy) - return 0; /* Wayland: no X11 Motif hints */ if (!_XA_MOTIF_WM_HINTS) _XA_MOTIF_WM_HINTS = XInternAtom(dpy, "_MOTIF_WM_HINTS", False); @@ -192,6 +181,6 @@ void wMWMCheckClientHints(WWindow *wwin) { MWMHints hints; - if (getMWMHints(wwin->client_win, &hints)) + if (wm_backend->motif_get_hints((WNativeWindow)wwin->client_win, &hints)) setupMWMHints(wwin, &hints); } diff --git a/src/motif.h b/src/motif.h index 7523e77..67bfc67 100644 --- a/src/motif.h +++ b/src/motif.h @@ -23,6 +23,16 @@ #ifndef WMMWM_H_ #define WMMWM_H_ +/* Motif window hints */ +typedef struct MWMHints { + long flags; + long functions; + long decorations; + long inputMode; + long status; +} MWMHints; + void wMWMCheckClientHints(WWindow *wwin); +int wGetMWMHints(Window window, MWMHints *hints_out); #endif diff --git a/src/pixmap.c b/src/pixmap.c index 8b6c6ee..21d1454 100644 --- a/src/pixmap.c +++ b/src/pixmap.c @@ -130,11 +130,11 @@ void wPixmapDestroy(WPixmap * pix) { if (!pix->shared) { if (pix->mask && !pix->client_owned_mask) { - if (dpy) XFreePixmap(dpy, pix->mask); + wm_backend->pixmap_free(pix->mask); } if (pix->image && !pix->client_owned) { - if (dpy) XFreePixmap(dpy, pix->image); + wm_backend->pixmap_free(pix->image); } } wfree(pix); diff --git a/src/properties.c b/src/properties.c index 1aae0f7..ff084ae 100644 --- a/src/properties.c +++ b/src/properties.c @@ -41,13 +41,6 @@ void PropGetProtocols(Window window, WProtocols * prots) int count, i; memset(prots, 0, sizeof(WProtocols)); - if (!dpy) { - /* Phase 63: all XDG toplevels support close (wlr_xdg_toplevel_send_close). - * Advertise DELETE_WINDOW so wManageWindow sets kill_close=0 and the - * close menu item is enabled. */ - prots->DELETE_WINDOW = 1; - return; - } if (!XGetWMProtocols(dpy, window, &protocols, &count)) { return; } @@ -67,9 +60,6 @@ void PropGetProtocols(Window window, WProtocols * prots) unsigned char *PropGetCheckProperty(Window window, Atom hint, Atom type, int format, int count, int *retCount) { Atom type_ret; - - if (!dpy) - return NULL; /* Wayland: no X11 property store */ int fmt_ret; unsigned long nitems_ret; unsigned long bytes_after_ret; @@ -105,7 +95,6 @@ void PropSetWMakerProtocols(Window root) Atom protocols[3]; int count = 0; - if (!dpy) return; /* Wayland: no X11 root-window WMaker protocols */ protocols[count++] = w_global.atom.wmaker.menu; protocols[count++] = w_global.atom.wmaker.wm_function; @@ -121,7 +110,6 @@ void PropSetIconTileHint(WScreen * scr, RImage * image) unsigned char *tmp; int x, y; - if (!dpy) return; /* Wayland: no X11 icon tile hint */ if (scr->info_window == None) return; @@ -202,7 +190,6 @@ int PropGetWindowState(Window window) void PropCleanUp(Window root) { - if (!dpy) return; /* Wayland: no X11 root-window atoms to clean up */ XDeleteProperty(dpy, root, w_global.atom.wmaker.wm_protocols); XDeleteProperty(dpy, root, w_global.atom.wmaker.noticeboard); diff --git a/src/resources.c b/src/resources.c index ab5486f..a2cdc60 100644 --- a/src/resources.c +++ b/src/resources.c @@ -35,10 +35,6 @@ int wGetColorForColormap(Colormap colormap, const char *color_name, XColor *color) { - /* Phase 19: Wayland — no X11 colormap available */ - if (!dpy) - return False; - if (!XParseColor(dpy, colormap, color_name, color)) { wwarning(_("could not parse color \"%s\""), color_name); return False; @@ -57,9 +53,6 @@ int wGetColor(WScreen *scr, const char *color_name, XColor *color) void wFreeColor(WScreen * scr, unsigned long pixel) { - if (!dpy) - return; /* Phase 19: Wayland — no colormap to free from */ - if (pixel != scr->white_pixel && pixel != scr->black_pixel) { unsigned long colors[1]; diff --git a/src/screen.c b/src/screen.c index fa2102f..669d5d2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -248,7 +248,7 @@ WScreen *wScreenInit(int screen_number) wm_backend->screen_create_internals(scr); - wNETWMInitStuff(scr); + wm_backend->netwm_init(scr); /* create initial workspace */ wWorkspaceNew(scr); @@ -261,7 +261,7 @@ WScreen *wScreenInit(int screen_number) wm_backend->screen_set_icon_sizes(scr, 8, wPreferences.icon_size - 4); /* setup WindowMaker protocols property in the root window */ - PropSetWMakerProtocols(scr->root_win); + wm_backend->prop_set_wmaker_protocols((WNativeWindow)scr->root_win); /* setup our noticeboard */ wm_backend->screen_setup_noticeboard(scr); diff --git a/src/shutdown.c b/src/shutdown.c index 4847f5c..11f5263 100644 --- a/src/shutdown.c +++ b/src/shutdown.c @@ -37,7 +37,7 @@ #include "shutdown.h" -static void wipeDesktop(WScreen * scr); +static void restoreWindows(WMBag *bag, WMBagIterator iter); /* *---------------------------------------------------------------------- @@ -73,13 +73,13 @@ void Shutdown(WShutdownMode mode) if (scr->helper_pid) kill(scr->helper_pid, SIGKILL); - if (dpy) /* Wayland: skip X11 session state save */ + if (!wm_backend->is_wayland) wScreenSaveState(scr); if (mode == WSKillMode) - wipeDesktop(scr); + wm_backend->wipe_desktop(scr); else - RestoreDesktop(scr); + wm_backend->restore_desktop(scr); } } ExecExitScript(); @@ -100,7 +100,7 @@ void Shutdown(WShutdownMode mode) if (scr) { if (scr->helper_pid) kill(scr->helper_pid, SIGKILL); - if (dpy) /* Wayland: skip X11 session state save */ + if (!wm_backend->is_wayland) wScreenSaveState(scr); RestoreDesktop(scr); } @@ -159,8 +159,6 @@ static void restoreWindows(WMBag * bag, WMBagIterator iter) */ void RestoreDesktop(WScreen * scr) { - if (!dpy) - return; /* Wayland: no X11 clients to unmanage */ if (scr->helper_pid > 0) { kill(scr->helper_pid, SIGTERM); @@ -175,9 +173,9 @@ void RestoreDesktop(WScreen * scr) XUngrabServer(dpy); XSetInputFocus(dpy, PointerRoot, RevertToParent, CurrentTime); - wColormapInstallForWindow(scr, NULL); - PropCleanUp(scr->root_win); - wNETWMCleanup(scr); + wm_backend->colormap_install(scr, NULL); + wm_backend->prop_cleanup((WNativeWindow)scr->root_win); + wm_backend->netwm_cleanup(scr); XSync(dpy, 0); } @@ -193,12 +191,10 @@ void RestoreDesktop(WScreen * scr) * TODO: change to XQueryTree() *---------------------------------------------------------------------- */ -static void wipeDesktop(WScreen * scr) +void wWipeDesktop(WScreen * scr) { WWindow *wwin; - if (!dpy) - return; /* Wayland: no X11 clients to wipe */ wwin = scr->focused_window; while (wwin) { diff --git a/src/shutdown.h b/src/shutdown.h index bb29b39..718ae9b 100644 --- a/src/shutdown.h +++ b/src/shutdown.h @@ -32,5 +32,6 @@ typedef enum { void Shutdown(WShutdownMode mode); void RestoreDesktop(WScreen *scr); +void wWipeDesktop(WScreen *scr); #endif /* SHUTDOWN_H */ diff --git a/src/startup.c b/src/startup.c index bbdd447..36d131c 100644 --- a/src/startup.c +++ b/src/startup.c @@ -75,7 +75,6 @@ static WScreen **wScreen = NULL; static unsigned int _NumLockMask = 0; static unsigned int _ScrollLockMask = 0; -static void manageAllWindows(WScreen * scr, int crashed); /* catchXError and handleXIO moved to x11_backend.c (Phase 25) */ @@ -414,7 +413,7 @@ void StartUp(Bool defaultScreenOnly) w_global.atom.wm.ignore_focus_events = atom[21]; #ifdef USE_DOCK_XDND - wXDNDInitializeAtoms(); + wm_backend->xdnd_init(); #endif /* cursors */ @@ -550,14 +549,14 @@ void StartUp(Bool defaultScreenOnly) w_global.screen_count++; } - if (dpy) + if (!wm_backend->is_wayland) InitializeSwitchMenu(); /* initialize/restore state for the screens */ for (j = 0; j < w_global.screen_count; j++) { int lastDesktop; - lastDesktop = wNETWMGetCurrentDesktopFromHint(wScreen[j]); + lastDesktop = wm_backend->netwm_get_current_desktop(wScreen[j]); wwarning("startup: wScreenRestoreState begin (screen %d)", j); wScreenRestoreState(wScreen[j]); @@ -568,7 +567,7 @@ void StartUp(Bool defaultScreenOnly) wScreen[j]->last_dock = wScreen[j]->dock; wwarning("startup: manageAllWindows begin"); - manageAllWindows(wScreen[j], wPreferences.flags.restarting == 2); + wm_backend->manage_all_windows(wScreen[j], wPreferences.flags.restarting == 2); wwarning("startup: manageAllWindows done"); /* restore saved menus */ @@ -646,7 +645,7 @@ static Bool windowInList(Window window, Window * list, int count) * reparented/managed. *----------------------------------------------------------------------- */ -static void manageAllWindows(WScreen * scr, int crashRecovery) +void wManageAllWindows(WScreen * scr, int crashRecovery) { Window root, parent; Window *children; @@ -654,9 +653,6 @@ static void manageAllWindows(WScreen * scr, int crashRecovery) unsigned int i, j; WWindow *wwin; - if (!dpy) - return; /* no display — nothing to adopt */ - wm_backend->server_grab(); XQueryTree(dpy, scr->root_win, &root, &parent, &children, &nchildren); diff --git a/src/startup.h b/src/startup.h index aba3c37..d905db3 100644 --- a/src/startup.h +++ b/src/startup.h @@ -23,6 +23,7 @@ #define WMSTARTUP_H void StartUp(Bool defaultScreenOnly); +void wManageAllWindows(WScreen *scr, int crash_recovery); void wHackedGrabButton(unsigned int button, unsigned int modifiers, Window grab_window, Bool owner_events, diff --git a/src/superfluous.c b/src/superfluous.c index 90b0841..de0f2f0 100644 --- a/src/superfluous.c +++ b/src/superfluous.c @@ -195,9 +195,6 @@ static void doAppBounce(void *arg) if (!aicon) return; - /* Phase 12: Wayland — no X11 window to move for bounce animation */ - if (!dpy) - return; reinit: if (data->wapp->refcount > 1) { diff --git a/src/texture.c b/src/texture.c index d269e76..a0fe637 100644 --- a/src/texture.c +++ b/src/texture.c @@ -31,6 +31,7 @@ #include "texture.h" #include "window.h" #include "misc.h" +#include "backend/backend.h" static void bevelImage(RImage * image, int relief); @@ -39,21 +40,13 @@ static RImage * get_texture_image(WScreen *scr, const char *pixmap_file); WTexSolid *wTextureMakeSolid(WScreen * scr, XColor * color) { WTexSolid *texture; - int gcm; - XGCValues gcv; texture = wmalloc(sizeof(WTexture)); texture->type = WTEX_SOLID; texture->subtype = 0; - /* Phase 19: Wayland — skip X11 color allocation and GC creation */ - if (!dpy) { - texture->normal = *color; - return texture; - } - - XAllocColor(dpy, scr->w_colormap, color); + wm_backend->texture_alloc_color(scr, color); texture->normal = *color; if (color->red == 0 && color->blue == 0 && color->green == 0) { texture->light.red = 0xb6da; @@ -90,37 +83,18 @@ WTexSolid *wTextureMakeSolid(WScreen * scr, XColor * color) texture->dark.red = 0; texture->dark.green = 0; texture->dark.blue = 0; - XAllocColor(dpy, scr->w_colormap, &texture->light); - XAllocColor(dpy, scr->w_colormap, &texture->dim); - XAllocColor(dpy, scr->w_colormap, &texture->dark); + wm_backend->texture_alloc_color(scr, &texture->light); + wm_backend->texture_alloc_color(scr, &texture->dim); + wm_backend->texture_alloc_color(scr, &texture->dark); - gcm = GCForeground | GCBackground | GCGraphicsExposures; - gcv.graphics_exposures = False; - - gcv.background = gcv.foreground = texture->light.pixel; - texture->light_gc = XCreateGC(dpy, scr->w_win, gcm, &gcv); - - gcv.background = gcv.foreground = texture->dim.pixel; - texture->dim_gc = XCreateGC(dpy, scr->w_win, gcm, &gcv); - - gcv.background = gcv.foreground = texture->dark.pixel; - texture->dark_gc = XCreateGC(dpy, scr->w_win, gcm, &gcv); - - gcv.background = gcv.foreground = color->pixel; - texture->normal_gc = XCreateGC(dpy, scr->w_win, gcm, &gcv); + texture->light_gc = wm_backend->texture_create_gc(scr, texture->light.pixel); + texture->dim_gc = wm_backend->texture_create_gc(scr, texture->dim.pixel); + texture->dark_gc = wm_backend->texture_create_gc(scr, texture->dark.pixel); + texture->normal_gc = wm_backend->texture_create_gc(scr, color->pixel); return texture; } -static int dummyErrorHandler(Display * foo, XErrorEvent * bar) -{ - /* Parameter not used, but tell the compiler that it is ok */ - (void) foo; - (void) bar; - - return 0; -} - void wTextureDestroy(WScreen * scr, WTexture * texture) { int i; @@ -133,11 +107,9 @@ void wTextureDestroy(WScreen * scr, WTexture * texture) #define CANFREE(c) (c!=scr->black_pixel && c!=scr->white_pixel && c!=0) switch (texture->any.type) { case WTEX_SOLID: - if (dpy) { - XFreeGC(dpy, texture->solid.light_gc); - XFreeGC(dpy, texture->solid.dark_gc); - XFreeGC(dpy, texture->solid.dim_gc); - } + wm_backend->texture_free_gc(texture->solid.light_gc); + wm_backend->texture_free_gc(texture->solid.dark_gc); + wm_backend->texture_free_gc(texture->solid.dim_gc); if (CANFREE(texture->solid.light.pixel)) colors[count++] = texture->solid.light.pixel; if (CANFREE(texture->solid.dim.pixel)) @@ -168,20 +140,9 @@ void wTextureDestroy(WScreen * scr, WTexture * texture) if (CANFREE(texture->any.color.pixel)) colors[count++] = texture->any.color.pixel; - /* Phase 19: Wayland — skip X11 color/GC cleanup when no display */ - if (dpy && count > 0) { - XErrorHandler oldhandler; - - /* ignore error from buggy servers that don't know how - * to do reference counting for colors. */ - XSync(dpy, 0); - oldhandler = XSetErrorHandler(dummyErrorHandler); - XFreeColors(dpy, scr->w_colormap, colors, count, 0); - XSync(dpy, 0); - XSetErrorHandler(oldhandler); - } - if (dpy) - XFreeGC(dpy, texture->any.gc); + if (count > 0) + wm_backend->texture_free_colors(scr, colors, count); + wm_backend->texture_free_gc(texture->any.gc); wfree(texture); #undef CANFREE } @@ -189,7 +150,6 @@ void wTextureDestroy(WScreen * scr, WTexture * texture) WTexGradient *wTextureMakeGradient(WScreen *scr, int style, const RColor *from, const RColor *to) { WTexGradient *texture; - XGCValues gcv; texture = wmalloc(sizeof(WTexture)); texture->type = style; @@ -202,12 +162,8 @@ WTexGradient *wTextureMakeGradient(WScreen *scr, int style, const RColor *from, texture->normal.green = (from->green + to->green) << 7; texture->normal.blue = (from->blue + to->blue) << 7; - if (dpy) { - XAllocColor(dpy, scr->w_colormap, &texture->normal); - gcv.background = gcv.foreground = texture->normal.pixel; - gcv.graphics_exposures = False; - texture->normal_gc = XCreateGC(dpy, scr->w_win, GCForeground | GCBackground | GCGraphicsExposures, &gcv); - } + wm_backend->texture_alloc_color(scr, &texture->normal); + texture->normal_gc = wm_backend->texture_create_gc(scr, texture->normal.pixel); return texture; } @@ -216,7 +172,6 @@ WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor int thickness2, const RColor colors2[2]) { WTexIGradient *texture; - XGCValues gcv; int i; texture = wmalloc(sizeof(WTexture)); @@ -236,12 +191,8 @@ WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor texture->normal.green = (colors2[0].green + colors2[1].green) << 7; texture->normal.blue = (colors2[0].blue + colors2[1].blue) << 7; } - if (dpy) { - XAllocColor(dpy, scr->w_colormap, &texture->normal); - gcv.background = gcv.foreground = texture->normal.pixel; - gcv.graphics_exposures = False; - texture->normal_gc = XCreateGC(dpy, scr->w_win, GCForeground | GCBackground | GCGraphicsExposures, &gcv); - } + wm_backend->texture_alloc_color(scr, &texture->normal); + texture->normal_gc = wm_backend->texture_create_gc(scr, texture->normal.pixel); return texture; } @@ -249,7 +200,6 @@ WTexIGradient *wTextureMakeIGradient(WScreen *scr, int thickness1, const RColor WTexMGradient *wTextureMakeMGradient(WScreen * scr, int style, RColor ** colors) { WTexMGradient *texture; - XGCValues gcv; int i; texture = wmalloc(sizeof(WTexture)); @@ -266,12 +216,8 @@ WTexMGradient *wTextureMakeMGradient(WScreen * scr, int style, RColor ** colors) texture->colors = colors; - if (dpy) { - XAllocColor(dpy, scr->w_colormap, &texture->normal); - gcv.background = gcv.foreground = texture->normal.pixel; - gcv.graphics_exposures = False; - texture->normal_gc = XCreateGC(dpy, scr->w_win, GCForeground | GCBackground | GCGraphicsExposures, &gcv); - } + wm_backend->texture_alloc_color(scr, &texture->normal); + texture->normal_gc = wm_backend->texture_create_gc(scr, texture->normal.pixel); return texture; } @@ -279,7 +225,6 @@ WTexMGradient *wTextureMakeMGradient(WScreen * scr, int style, RColor ** colors) WTexPixmap *wTextureMakePixmap(WScreen *scr, int style, const char *pixmap_file, XColor *color) { WTexPixmap *texture; - XGCValues gcv; RImage *image; image = get_texture_image(scr, pixmap_file); @@ -292,12 +237,8 @@ WTexPixmap *wTextureMakePixmap(WScreen *scr, int style, const char *pixmap_file, texture->normal = *color; - if (dpy) { - XAllocColor(dpy, scr->w_colormap, &texture->normal); - gcv.background = gcv.foreground = texture->normal.pixel; - gcv.graphics_exposures = False; - texture->normal_gc = XCreateGC(dpy, scr->w_win, GCForeground | GCBackground | GCGraphicsExposures, &gcv); - } + wm_backend->texture_alloc_color(scr, &texture->normal); + texture->normal_gc = wm_backend->texture_create_gc(scr, texture->normal.pixel); texture->pixmap = image; @@ -308,7 +249,6 @@ WTexTGradient *wTextureMakeTGradient(WScreen *scr, int style, const RColor *from const char *pixmap_file, int opacity) { WTexTGradient *texture; - XGCValues gcv; RImage *image; image = get_texture_image(scr, pixmap_file); @@ -327,12 +267,8 @@ WTexTGradient *wTextureMakeTGradient(WScreen *scr, int style, const RColor *from texture->normal.green = (from->green + to->green) << 7; texture->normal.blue = (from->blue + to->blue) << 7; - if (dpy) { - XAllocColor(dpy, scr->w_colormap, &texture->normal); - gcv.background = gcv.foreground = texture->normal.pixel; - gcv.graphics_exposures = False; - texture->normal_gc = XCreateGC(dpy, scr->w_win, GCForeground | GCBackground | GCGraphicsExposures, &gcv); - } + wm_backend->texture_alloc_color(scr, &texture->normal); + texture->normal_gc = wm_backend->texture_create_gc(scr, texture->normal.pixel); texture->pixmap = image; @@ -555,8 +491,8 @@ void wDrawBevel(Drawable d, unsigned width, unsigned height, WTexSolid * texture if (relief == WREL_FLAT) return; - /* Phase 19: Wayland — no X11 display, skip bevel drawing */ - if (!dpy) + /* Wayland backend handles bevel drawing in frame_paint */ + if (wm_backend->is_wayland) return; /* Drawable 0 (WNATIVE_NONE) means the Wayland backend owns this frame; * skip to avoid BadDrawable errors on XWayland connection. */ diff --git a/src/window.c b/src/window.c index 68a2659..1085d78 100644 --- a/src/window.c +++ b/src/window.c @@ -361,7 +361,7 @@ void wWindowSetupInitialAttributes(WWindow *wwin, int *level, int *workspace) wMWMCheckClientHints(wwin); #endif /* USE_MWM_HINTS */ - wNETWMCheckClientHints(wwin, &tmp_level, &tmp_workspace); + wm_backend->netwm_check_client_hints(wwin, &tmp_level, &tmp_workspace); if (wPreferences.ignore_gtk_decoration_hints) discard_hints_from_gtk(wwin); @@ -468,7 +468,7 @@ static pid_t getWindowPid(WNativeWindow win) { pid_t pid = -1; - pid = wNETWMGetPidForWindow(win); + pid = wm_backend->netwm_get_pid((WNativeWindow)win); if (pid <= 0) pid = wm_backend->client_get_pid(win); return pid; @@ -717,7 +717,7 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window) wwin->group_id = None; } - PropGetProtocols(window, &wwin->protocols); + wm_backend->prop_get_protocols((WNativeWindow)window, &wwin->protocols); wwin->transient_for = wm_backend->prop_get_transient_for(window); if (wwin->transient_for == WNATIVE_NONE) { @@ -835,7 +835,7 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window) if (WFLAGP(wwin, start_maximized) && IS_RESIZABLE(wwin)) wwin->flags.maximized = MAX_VERTICAL | MAX_HORIZONTAL; - wNETWMCheckInitialClientState(wwin); + wm_backend->netwm_check_initial_state(wwin); /* apply previous state if it exists and we're in startup */ if (scr->flags.startup && wm_state >= 0) { @@ -1084,7 +1084,7 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window) } /* Create frame, borders and do reparenting (X11 only) */ - if (dpy) { + if (!wm_backend->is_wayland) { foo = WFF_LEFT_BUTTON | WFF_RIGHT_BUTTON; #ifdef XKB_BUTTON_HINT if (wPreferences.modelock) @@ -1321,7 +1321,7 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window) wWindowSetKeyGrabs(wwin); WMPostNotificationName(WMNManaged, wwin, NULL); - wColormapInstallForWindow(scr, scr->cmap_window); + wm_backend->colormap_install(scr, scr->cmap_window); /* Setup Notification Observers */ WMAddNotificationObserver(appearanceObserver, wwin, WNWindowAppearanceSettingsChanged, wwin); @@ -1637,7 +1637,7 @@ void wUnmanageWindow(WWindow *wwin, Bool restore, Bool destroyed) wApplicationDeactivate(oapp); } - wNETCleanupFrameExtents(wwin); + wm_backend->netwm_cleanup_frame_extents(wwin); wWindowDestroy(wwin); wm_backend->event_flush(); diff --git a/src/window.h b/src/window.h index 453f85e..e3537ce 100644 --- a/src/window.h +++ b/src/window.h @@ -153,7 +153,7 @@ typedef struct { /* * Window manager protocols that both the client as we understand. */ -typedef struct { +typedef struct WProtocols { unsigned int TAKE_FOCUS:1; unsigned int DELETE_WINDOW:1; unsigned int SAVE_YOURSELF:1; diff --git a/src/winmenu.c b/src/winmenu.c index 2a42e3a..8e130f3 100644 --- a/src/winmenu.c +++ b/src/winmenu.c @@ -236,7 +236,7 @@ static void updateUnmaximizeShortcut(WMenuEntry * entry, int flags) break; } - entry->rtext = GetShortcutKey(wKeyBindings[key]); + entry->rtext = wm_backend->get_shortcut_string(wKeyBindings[key]); } static void execMenuCommand(WMenu * menu, WMenuEntry * entry) @@ -377,7 +377,7 @@ static void updateWorkspaceMenu(WMenu * menu) strncpy(title, scr->workspaces[i]->name, MAX_WORKSPACENAME_WIDTH); title[MAX_WORKSPACENAME_WIDTH] = 0; menu->entries[i]->text = wstrdup(title); - menu->entries[i]->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVE_WORKSPACE1 + i]); + menu->entries[i]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_MOVE_WORKSPACE1 + i]); menu->flags.realized = 0; } } else { @@ -385,14 +385,14 @@ static void updateWorkspaceMenu(WMenu * menu) title[MAX_WORKSPACENAME_WIDTH] = 0; entry = wMenuAddCallback(menu, title, switchWSCommand, NULL); - entry->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVE_WORKSPACE1 + i]); + entry->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_MOVE_WORKSPACE1 + i]); menu->flags.realized = 0; } /* workspace shortcut labels */ if (i / 10 == scr->current_workspace / 10) - entry->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVE_WORKSPACE1 + (i % 10)]); + entry->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_MOVE_WORKSPACE1 + (i % 10)]); else entry->rtext = NULL; } @@ -439,7 +439,7 @@ static void updateMakeShortcutMenu(WMenu * menu, WWindow * wwin) if (kcode) { char *tmp; - tmp = GetShortcutKey(wKeyBindings[WKBD_WINDOW1 + shortcutNo]); + tmp = wm_backend->get_shortcut_string(wKeyBindings[WKBD_WINDOW1 + shortcutNo]); if (tmp == NULL) { if (entry->rtext != NULL) { /* There was a shortcut, but there is no more */ @@ -484,19 +484,19 @@ static void updateOptionsMenu(WMenu * menu, WWindow * wwin) smenu->entries[WO_KEEP_ON_TOP]->flags.indicator_on = (wwin->frame && wwin->frame->core->stacking->window_level == WMFloatingLevel) ? 1 : 0; wMenuSetEnabled(smenu, WO_KEEP_ON_TOP, !wwin->flags.miniaturized); - smenu->entries[WO_KEEP_ON_TOP]->rtext = GetShortcutKey(wKeyBindings[WKBD_KEEP_ON_TOP]); + smenu->entries[WO_KEEP_ON_TOP]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_KEEP_ON_TOP]); /* keep at bottom check */ smenu->entries[WO_KEEP_AT_BOTTOM]->clientdata = wwin; smenu->entries[WO_KEEP_AT_BOTTOM]->flags.indicator_on = (wwin->frame && wwin->frame->core->stacking->window_level == WMSunkenLevel) ? 1 : 0; wMenuSetEnabled(smenu, WO_KEEP_AT_BOTTOM, !wwin->flags.miniaturized); - smenu->entries[WO_KEEP_AT_BOTTOM]->rtext = GetShortcutKey(wKeyBindings[WKBD_KEEP_AT_BOTTOM]); + smenu->entries[WO_KEEP_AT_BOTTOM]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_KEEP_AT_BOTTOM]); /* omnipresent check */ smenu->entries[WO_OMNIPRESENT]->clientdata = wwin; smenu->entries[WO_OMNIPRESENT]->flags.indicator_on = IS_OMNIPRESENT(wwin); - smenu->entries[WO_OMNIPRESENT]->rtext = GetShortcutKey(wKeyBindings[WKBD_OMNIPRESENT]); + smenu->entries[WO_OMNIPRESENT]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_OMNIPRESENT]); smenu->flags.realized = 0; wMenuRealize(smenu); @@ -509,7 +509,7 @@ static void updateMaximizeMenu(WMenu * menu, WWindow * wwin) for (i = 0; i < smenu->entry_no; i++) { smenu->entries[i]->clientdata = wwin; - smenu->entries[i]->rtext = GetShortcutKey(wKeyBindings[menu_maximize_entries[i].shortcut_idx]); + smenu->entries[i]->rtext = wm_backend->get_shortcut_string(wKeyBindings[menu_maximize_entries[i].shortcut_idx]); } smenu->flags.realized = 0; @@ -669,7 +669,7 @@ static void updateMenuForWindow(WMenu * menu, WWindow * wwin) text = _("Maximize"); menu->entries[MC_MAXIMIZE]->text = text; - menu->entries[MC_MAXIMIZE]->rtext = GetShortcutKey(wKeyBindings[WKBD_MAXIMIZE]); + menu->entries[MC_MAXIMIZE]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_MAXIMIZE]); } wMenuSetEnabled(menu, MC_MAXIMIZE, IS_RESIZABLE(wwin)); @@ -718,13 +718,13 @@ static void updateMenuForWindow(WMenu * menu, WWindow * wwin) /* Update shortcut labels except for (Un)Maximize which is * handled separately. */ - menu->entries[MC_MINIATURIZE]->rtext = GetShortcutKey(wKeyBindings[WKBD_MINIATURIZE]); - menu->entries[MC_SHADE]->rtext = GetShortcutKey(wKeyBindings[WKBD_SHADE]); - menu->entries[MC_HIDE]->rtext = GetShortcutKey(wKeyBindings[WKBD_HIDE]); - menu->entries[MC_MOVERESIZE]->rtext = GetShortcutKey(wKeyBindings[WKBD_MOVERESIZE]); - menu->entries[MC_SELECT]->rtext = GetShortcutKey(wKeyBindings[WKBD_SELECT]); - menu->entries[MC_RELAUNCH]->rtext = GetShortcutKey(wKeyBindings[WKBD_RELAUNCH]); - menu->entries[MC_CLOSE]->rtext = GetShortcutKey(wKeyBindings[WKBD_CLOSE]); + menu->entries[MC_MINIATURIZE]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_MINIATURIZE]); + menu->entries[MC_SHADE]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_SHADE]); + menu->entries[MC_HIDE]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_HIDE]); + menu->entries[MC_MOVERESIZE]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_MOVERESIZE]); + menu->entries[MC_SELECT]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_SELECT]); + menu->entries[MC_RELAUNCH]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_RELAUNCH]); + menu->entries[MC_CLOSE]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_CLOSE]); /* set the client data of the entries to the window */ for (i = 0; i < menu->entry_no; i++) { diff --git a/src/winspector.c b/src/winspector.c index 33aefdc..b01e472 100644 --- a/src/winspector.c +++ b/src/winspector.c @@ -786,7 +786,7 @@ static void applySettings(WMWidget *button, void *client_data) wwin->frame->flags.need_texture_change = 1; wWindowConfigureBorders(wwin); wFrameWindowPaint(wwin->frame); - wNETWMUpdateActions(wwin, False); + wm_backend->netwm_update_actions(wwin, 0); /* Can't apply emulate_appicon because it will probably cause problems. */ if (wapp) { @@ -803,7 +803,7 @@ static void applySettings(WMWidget *button, void *client_data) if (WFLAGP(wapp->main_window_desc, no_appicon)) unpaint_app_icon(wapp); else - paint_app_icon(wapp); + wm_backend->appicon_show(wapp); char *file = WMGetTextFieldText(panel->fileText); if (file[0] == 0) { diff --git a/src/wmspec.c b/src/wmspec.c index 4a6daac..b449153 100644 --- a/src/wmspec.c +++ b/src/wmspec.c @@ -362,7 +362,6 @@ void wNETWMUpdateDesktop(WScreen *scr) long *views, sizes[2]; int count, i; - if (!dpy) return; /* Wayland: no X11 root-window properties */ if (scr->workspace_count == 0) return; @@ -391,7 +390,6 @@ int wNETWMGetCurrentDesktopFromHint(WScreen *scr) int count; unsigned char *prop; - if (!dpy) return -1; /* Wayland: no X11 _NET_CURRENT_DESKTOP hint */ prop = PropGetCheckProperty(scr->root_win, net_current_desktop, WA_CARDINAL, 0, 1, &count); if (prop) { @@ -573,14 +571,13 @@ static void updateIconImage(WWindow *wwin) } } -static void updateWindowOpacity(WWindow *wwin) +void wNETWMUpdateWindowOpacity(WWindow *wwin) { Atom type; int format; unsigned long items, rest; unsigned long *property; - if (!dpy) return; /* Wayland: no X11 _NET_WM_WINDOW_OPACITY */ if (!wwin->frame) return; @@ -657,7 +654,6 @@ void wNETWMInitStuff(WScreen *scr) NetData *data; int i; - if (!dpy) return; /* Wayland: no X11 NETWM atoms or root-window hints */ #ifdef DEBUG_WMSPEC wmessage("wNETWMInitStuff"); @@ -716,7 +712,6 @@ void wNETWMCleanup(WScreen *scr) { int i; - if (!dpy) return; /* Wayland: no X11 root-window atoms to clean up */ for (i = 0; i < wlengthof(atomNames); i++) XDeleteProperty(dpy, scr->root_win, *atomNames[i].atom); @@ -727,7 +722,6 @@ void wNETWMUpdateActions(WWindow *wwin, Bool del) Atom action[10]; /* nr of actions atoms defined */ int i = 0; - if (!dpy) return; /* Wayland: no X11 _NET_WM_ALLOWED_ACTIONS property */ if (del) { XDeleteProperty(dpy, wwin->client_win, net_wm_allowed_actions); @@ -1548,8 +1542,6 @@ void wNETWMCheckClientHints(WWindow *wwin, int *layer, int *workspace) unsigned long nitems_ret, bytes_after_ret; long *data = NULL; - if (!dpy) - return; /* Wayland: no X11 NETWM properties */ if (XGetWindowProperty(dpy, wwin->client_win, net_wm_desktop, 0, 1, False, WA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, @@ -1657,8 +1649,6 @@ void wNETWMCheckInitialClientState(WWindow *wwin) wmessage("wNETWMCheckInitialClientState"); #endif - if (!dpy) - return; /* Wayland: no X11 NETWM initial state */ wNETWMShowingDesktop(wwin->screen_ptr, False); @@ -1673,7 +1663,7 @@ void wNETWMCheckInitialFrameState(WWindow *wwin) wmessage("wNETWMCheckInitialFrameState"); #endif - updateWindowOpacity(wwin); + wm_backend->netwm_update_opacity(wwin); } static void handleDesktopNames(WScreen *scr) @@ -1879,7 +1869,7 @@ void wNETWMCheckClientHintChange(WWindow *wwin, XPropertyEvent *event) } else if (event->atom == net_wm_icon) { updateIconImage(wwin); } else if (event->atom == net_wm_window_opacity) { - updateWindowOpacity(wwin); + wNETWMUpdateWindowOpacity(wwin); } } @@ -1891,8 +1881,6 @@ int wNETWMGetPidForWindow(Window window) long *data = NULL; int pid; - if (!dpy) - return 0; /* Wayland: no _NET_WM_PID property */ if (XGetWindowProperty(dpy, window, net_wm_pid, 0, 1, False, WA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret, @@ -2036,7 +2024,5 @@ void wNETFrameExtents(WWindow *wwin) void wNETCleanupFrameExtents(WWindow *wwin) { - if (!dpy) - return; /* Wayland: no X11 _NET_FRAME_EXTENTS property */ XDeleteProperty(dpy, wwin->client_win, net_frame_extents); } diff --git a/src/wmspec.h b/src/wmspec.h index 6e17114..8111599 100644 --- a/src/wmspec.h +++ b/src/wmspec.h @@ -46,5 +46,6 @@ char *wNETWMGetIconName(Window window); char *wNETWMGetWindowName(Window window); void wNETFrameExtents(WWindow *wwin); void wNETCleanupFrameExtents(WWindow *wwin); +void wNETWMUpdateWindowOpacity(WWindow *wwin); RImage *get_window_image_from_x11(Window window); #endif diff --git a/src/workspace.c b/src/workspace.c index ac198bc..f8c1430 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -114,7 +114,7 @@ int wWorkspaceNew(WScreen *scr) wWorkspaceMenuUpdate(scr, scr->workspace_menu); wWorkspaceMenuUpdate(scr, scr->clip_ws_menu); - wNETWMUpdateDesktop(scr); + wm_backend->netwm_update_desktop(scr); WMPostNotificationName(WMNWorkspaceCreated, scr, (void *)(uintptr_t) (scr->workspace_count - 1)); wm_backend->event_flush(); @@ -192,7 +192,7 @@ Bool wWorkspaceDelete(WScreen * scr, int workspace) wMenuRemoveItem(menu, --i); wMenuRealize(menu); } - wNETWMUpdateDesktop(scr); + wm_backend->netwm_update_desktop(scr); WMPostNotificationName(WMNWorkspaceDestroyed, scr, (void *)(uintptr_t) (scr->workspace_count - 1)); if (scr->current_workspace >= scr->workspace_count) @@ -618,7 +618,7 @@ void wWorkspaceForceChange(WScreen * scr, int workspace) wClipIconPaint(scr->clip_icon); } wScreenUpdateUsableArea(scr); - wNETWMUpdateDesktop(scr); + wm_backend->netwm_update_desktop(scr); showWorkspaceName(scr, workspace); WMPostNotificationName(WMNWorkspaceChanged, scr, (void *)(uintptr_t) workspace); @@ -732,7 +732,7 @@ WMenu *wWorkspaceMenuMake(WScreen * scr, Bool titled) wMenuAddCallback(wsmenu, _("Destroy Last"), deleteWSCommand, NULL); entry = wMenuAddCallback(wsmenu, _("Last Used"), lastWSCommand, NULL); - entry->rtext = GetShortcutKey(wKeyBindings[WKBD_LASTWORKSPACE]); + entry->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_LASTWORKSPACE]); return wsmenu; } @@ -771,7 +771,7 @@ void wWorkspaceMenuUpdate(WScreen * scr, WMenu * menu) for (i = 0; i < scr->workspace_count; i++) { /* workspace shortcut labels */ if (i / 10 == scr->current_workspace / 10) - menu->entries[i + MC_WORKSPACE1]->rtext = GetShortcutKey(wKeyBindings[WKBD_WORKSPACE1 + (i % 10)]); + menu->entries[i + MC_WORKSPACE1]->rtext = wm_backend->get_shortcut_string(wKeyBindings[WKBD_WORKSPACE1 + (i % 10)]); else menu->entries[i + MC_WORKSPACE1]->rtext = NULL; diff --git a/src/xdnd.c b/src/xdnd.c index 75df81b..c2c2cb3 100644 --- a/src/xdnd.c +++ b/src/xdnd.c @@ -49,8 +49,6 @@ static Atom selected_typelist; void wXDNDInitializeAtoms(void) { - if (!dpy) - return; /* Wayland: XDND is X11-only */ _XA_XdndAware = XInternAtom(dpy, "XdndAware", False); _XA_XdndEnter = XInternAtom(dpy, "XdndEnter", False);