WINGs Phase D: port wballoon, wpopupbutton, wtext to vtable

New vtable slots: pointer_grab, pointer_ungrab, bell, balloon_draw, text_init
All implemented in X11 backend, no-ops in Wayland backend.

wballoon.c: XTranslateCoordinates -> get_screen_position, showText -> balloon_draw
wpopupbutton.c: all 7 Xlib calls replaced (grabs, coords, flush)
wtext.c: XMapWindow, XBell, XGrabPointer, XUngrabPointer, cursor, GC init all ported
This commit is contained in:
Window Maker 2026-05-23 15:26:48 +02:00
parent 264679a2d1
commit 9eecb2511c
5 changed files with 89 additions and 50 deletions

View File

@ -650,6 +650,7 @@ typedef struct W_ViewBackend {
void (*bell)(void *vctx);
void (*balloon_draw)(void *vctx, struct W_View *view, int x, int y,
int w, int h, const char *text);
void (*text_init)(void *vctx, struct W_View *view, void *stipple_gc_out);
} W_ViewBackend;
extern const W_ViewBackend W_ViewBackendX11;

View File

@ -441,7 +441,12 @@ static void popUpMenu(PopUpButton * bPtr)
if (WMGetArrayItemCount(bPtr->items) < 1)
return;
XTranslateCoordinates(scr->display, bPtr->view->window, scr->rootWin, 0, 0, &x, &y, &dummyW);
{
WMPoint pos = scr->viewBackend->get_screen_position(
scr->viewBackendCtx, bPtr->view);
x = pos.x;
y = pos.y;
}
if (bPtr->flags.pullsDown) {
y += bPtr->view->size.height;
@ -450,8 +455,7 @@ static void popUpMenu(PopUpButton * bPtr)
}
W_MoveView(bPtr->menuView, x, y);
XSetWindowBackgroundPixmap(scr->display, bPtr->menuView->window, makeMenuPixmap(bPtr));
XClearWindow(scr->display, bPtr->menuView->window);
scr->viewBackend->redisplay(scr->viewBackendCtx, bPtr->menuView);
if (W_VIEW_WIDTH(bPtr->menuView) != W_VIEW_WIDTH(bPtr->view))
resizeMenu(bPtr);
@ -629,9 +633,8 @@ static void handleActionEvents(WMEvent * event, void *data)
bPtr->highlightedItem = -1;
bPtr->flags.insideMenu = 0;
}
XGrabPointer(bPtr->view->screen->display, bPtr->menuView->window,
False, ButtonReleaseMask | ButtonMotionMask | EnterWindowMask
| LeaveWindowMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
bPtr->view->screen->viewBackend->pointer_grab(
bPtr->view->screen->viewBackendCtx, bPtr->menuView, False, CurrentTime);
break;
case WME_BUTTON_RELEASE:
@ -639,7 +642,8 @@ static void handleActionEvents(WMEvent * event, void *data)
event->u.button.button == WINGsConfiguration.mouseWheelDown) {
break;
}
XUngrabPointer(bPtr->view->screen->display, event->u.button.time);
bPtr->view->screen->viewBackend->pointer_ungrab(
bPtr->view->screen->viewBackendCtx, event->u.button.time);
if (!bPtr->flags.pullsDown)
popDownMenu(bPtr);
@ -660,10 +664,10 @@ static void handleActionEvents(WMEvent * event, void *data)
if (bPtr->flags.pullsDown) {
for (i = 0; i < MENU_BLINK_COUNT; i++) {
paintMenuEntry(bPtr, bPtr->highlightedItem, False);
XSync(bPtr->view->screen->display, 0);
bPtr->view->screen->viewBackend->flush(bPtr->view->screen->viewBackendCtx);
wusleep(MENU_BLINK_DELAY);
paintMenuEntry(bPtr, bPtr->highlightedItem, True);
XSync(bPtr->view->screen->display, 0);
bPtr->view->screen->viewBackend->flush(bPtr->view->screen->viewBackendCtx);
wusleep(MENU_BLINK_DELAY);
}
}

View File

@ -629,7 +629,6 @@ static void paintText(Text * tPtr)
WMScreen *scr = tPtr->view->screen;
const W_RenderBackend *R = scr->renderBackend;
void *rctx = scr->renderBackendCtx;
Display *dpy = tPtr->view->screen->display;
Window win = tPtr->view->window;
WMColor *color;
@ -762,9 +761,8 @@ static void paintText(Text * tPtr)
if (!view->flags.realized)
WMRealizeWidget(tb->d.widget);
if (!view->flags.mapped) {
XMapWindow(view->screen->display, view->window);
XFlush(view->screen->display);
view->flags.mapped = 1;
W_MapView(view);
view->screen->viewBackend->flush(view->screen->viewBackendCtx);
}
}
@ -876,7 +874,8 @@ static void mouseOverObject(Text * tPtr, int x, int y)
{
XSetWindowAttributes attribs;
attribs.cursor = tPtr->view->attribs.cursor;
XChangeWindowAttributes(tPtr->view->screen->display, tPtr->view->window, CWCursor, &attribs);
tPtr->view->screen->viewBackend->set_cursor(
tPtr->view->screen->viewBackendCtx, tPtr->view, attribs.cursor);
}
}
@ -2331,7 +2330,7 @@ static void handleTextKeyPress(Text * tPtr, WMEvent * event)
WMShowTextRuler(tPtr, i);
tPtr->flags.rulerShown = i;
} else if (control_pressed && *buffer == '\a') {
XBell(tPtr->view->screen->display, 0);
tPtr->view->screen->viewBackend->bell(tPtr->view->screen->viewBackendCtx);
} else {
WMRelayToNextResponder(tPtr->view, event);
}
@ -2391,7 +2390,6 @@ static void pasteText(WMView * view, Atom selection, Atom target, Time timestamp
static void handleActionEvents(WMEvent * event, void *data)
{
Text *tPtr = (Text *) data;
Display *dpy = tPtr->view->screen->display;
KeySym ksym;
switch (event->type) {
@ -2403,10 +2401,9 @@ static void handleActionEvents(WMEvent * event, void *data)
}
if (tPtr->flags.focused) {
XGrabPointer(dpy, W_VIEW(tPtr)->window, False,
PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, None,
tPtr->view->screen->invisibleCursor, CurrentTime);
tPtr->view->screen->viewBackend->pointer_grab(
tPtr->view->screen->viewBackendCtx,
W_VIEW(tPtr), False, CurrentTime);
tPtr->flags.pointerGrabbed = True;
handleTextKeyPress(tPtr, event);
@ -2426,7 +2423,8 @@ static void handleActionEvents(WMEvent * event, void *data)
if (tPtr->flags.pointerGrabbed) {
tPtr->flags.pointerGrabbed = False;
XUngrabPointer(dpy, CurrentTime);
tPtr->view->screen->viewBackend->pointer_ungrab(
tPtr->view->screen->viewBackendCtx, CurrentTime);
}
if (tPtr->flags.waitingForSelection)
@ -2455,7 +2453,8 @@ static void handleActionEvents(WMEvent * event, void *data)
if (tPtr->flags.pointerGrabbed) {
tPtr->flags.pointerGrabbed = False;
XUngrabPointer(dpy, CurrentTime);
tPtr->view->screen->viewBackend->pointer_ungrab(
tPtr->view->screen->viewBackendCtx, CurrentTime);
break;
}
@ -2526,7 +2525,7 @@ static void handleActionEvents(WMEvent * event, void *data)
int n;
if (!tPtr->flags.editable) {
XBell(dpy, 0);
tPtr->view->screen->viewBackend->bell(tPtr->view->screen->viewBackendCtx);
break;
}
@ -2565,7 +2564,8 @@ static void handleActionEvents(WMEvent * event, void *data)
case WME_BUTTON_RELEASE:
if (tPtr->flags.pointerGrabbed) {
tPtr->flags.pointerGrabbed = False;
XUngrabPointer(dpy, CurrentTime);
tPtr->view->screen->viewBackend->pointer_ungrab(
tPtr->view->screen->viewBackendCtx, CurrentTime);
break;
}
@ -2976,9 +2976,7 @@ static WMArray *getXdndDestinationTypeArray(void)
WMText *WMCreateTextForDocumentType(WMWidget * parent, WMAction * parser, WMAction * writer)
{
Text *tPtr;
Display *dpy;
WMScreen *scr;
XGCValues gcv;
tPtr = wmalloc(sizeof(Text));
tPtr->widgetClass = WC_Text;
@ -2989,20 +2987,8 @@ WMText *WMCreateTextForDocumentType(WMWidget * parent, WMAction * parser, WMActi
return NULL;
}
dpy = tPtr->view->screen->display;
scr = tPtr->view->screen;
if (XA_Targets == None) {
/*
* Because the X protocol guaranties that the value will never change in
* the lifespan of the server, we query the values only the first time a
* widget is created
*/
XA_Targets = XInternAtom(dpy, "TARGETS", False);
XA_Format_Text = XInternAtom(dpy, "TEXT", False);
XA_Format_Compound_Text = XInternAtom(dpy, "COMPOUND_TEXT", False);
}
tPtr->view->self = tPtr;
tPtr->view->attribs.cursor = scr->textCursor;
tPtr->view->attribFlags |= CWOverrideRedirect | CWCursor;
@ -3013,15 +2999,8 @@ WMText *WMCreateTextForDocumentType(WMWidget * parent, WMAction * parser, WMActi
tPtr->bgColor = WMWhiteColor(scr);
W_SetViewBackgroundColor(tPtr->view, tPtr->bgColor);
gcv.graphics_exposures = False;
gcv.foreground = W_PIXEL(scr->gray);
gcv.background = W_PIXEL(scr->darkGray);
gcv.fill_style = FillStippled;
/* why not use scr->stipple here? */
gcv.stipple = XCreateBitmapFromData(dpy, W_DRAWABLE(scr), STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT);
tPtr->stippledGC = XCreateGC(dpy, W_DRAWABLE(scr),
GCForeground | GCBackground | GCStipple
| GCFillStyle | GCGraphicsExposures, &gcv);
/* Platform-specific text widget init (atoms, stipple GC) */
scr->viewBackend->text_init(scr->viewBackendCtx, tPtr->view, (void *)&tPtr->stippledGC);
tPtr->ruler = NULL;
tPtr->vS = NULL;

View File

@ -531,6 +531,11 @@ static char *wl_clipboard_fetch(void *vctx, int *len_out)
return NULL;
}
static void wl_text_init(void *vctx, W_View *view, void *stipple_gc_out)
{
(void)vctx; (void)view; (void)stipple_gc_out;
}
static void wl_balloon_draw(void *vctx, W_View *view, int x, int y,
int w, int h, const char *text)
{
@ -614,4 +619,5 @@ const W_ViewBackend W_ViewBackendWL = {
.pointer_ungrab = NULL,
.bell = NULL,
.balloon_draw = wl_balloon_draw,
.text_init = wl_text_init,
};

View File

@ -234,6 +234,54 @@ static char *x11_clipboard_fetch(void *vctx, int *len_out)
return copy;
}
static void x11_pointer_grab(void *vctx, W_View *view, int owner_events, unsigned long time)
{
W_Screen *scr = (W_Screen *)vctx;
XGrabPointer(scr->display, view->window, owner_events,
ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask,
GrabModeAsync, GrabModeAsync, None, None, time);
}
static void x11_pointer_ungrab(void *vctx, unsigned long time)
{
W_Screen *scr = (W_Screen *)vctx;
XUngrabPointer(scr->display, time);
}
static void x11_bell(void *vctx)
{
W_Screen *scr = (W_Screen *)vctx;
XBell(scr->display, 0);
}
static Atom XA_Targets = None;
static Atom XA_Format_Text = None;
static Atom XA_Format_Compound_Text = None;
static void x11_text_init(void *vctx, W_View *view, void *stipple_gc_out)
{
W_Screen *scr = (W_Screen *)vctx;
Display *dpy = scr->display;
GC *gc_out = (GC *)stipple_gc_out;
XGCValues gcv;
if (XA_Targets == None) {
XA_Targets = XInternAtom(dpy, "TARGETS", False);
XA_Format_Text = XInternAtom(dpy, "TEXT", False);
XA_Format_Compound_Text = XInternAtom(dpy, "COMPOUND_TEXT", False);
}
gcv.graphics_exposures = False;
gcv.foreground = W_PIXEL(scr->gray);
gcv.background = W_PIXEL(scr->darkGray);
gcv.fill_style = FillStippled;
gcv.stipple = XCreateBitmapFromData(dpy, W_DRAWABLE(scr),
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55", 8, 8);
*gc_out = XCreateGC(dpy, W_DRAWABLE(scr),
GCForeground | GCBackground | GCStipple
| GCFillStyle | GCGraphicsExposures, &gcv);
}
static void x11_balloon_draw(void *vctx, W_View *view, int x, int y,
int w, int h, const char *text)
{
@ -504,8 +552,9 @@ const W_ViewBackend W_ViewBackendX11 = {
.window_realize = x11_window_realize,
.window_set_geometry = x11_window_set_geometry,
.window_withdraw = x11_window_withdraw,
.pointer_grab = NULL,
.pointer_ungrab = NULL,
.bell = NULL,
.pointer_grab = x11_pointer_grab,
.pointer_ungrab = x11_pointer_ungrab,
.bell = x11_bell,
.balloon_draw = x11_balloon_draw,
.text_init = x11_text_init,
};