diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c index 3ab8344bb..647a298ea 100644 --- a/hw/xnest/Screen.c +++ b/hw/xnest/Screen.c @@ -22,6 +22,7 @@ is" without express or implied warranty. #include +#include "dix/property_priv.h" #include "mi/mi_priv.h" #include "scrnintstr.h" @@ -512,6 +513,8 @@ breakout: &attributes); } + AddCallback(&PropertyStateCallback, xnest_property_state_callback, pScreen); + if (!xnestCreateDefaultColormap(pScreen)) return FALSE; diff --git a/hw/xnest/meson.build b/hw/xnest/meson.build index ef260a13a..004c2f049 100644 --- a/hw/xnest/meson.build +++ b/hw/xnest/meson.build @@ -12,6 +12,7 @@ srcs = [ 'Keyboard.c', 'Pixmap.c', 'Pointer.c', + 'properties.c', 'Screen.c', 'Window.c', '../../mi/miinitext.c', diff --git a/hw/xnest/properties.c b/hw/xnest/properties.c new file mode 100644 index 000000000..0ca9c74f6 --- /dev/null +++ b/hw/xnest/properties.c @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: MIT OR X11 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + * + * @brief property management functions + */ +#include + +#include "dix/dix_priv.h" +#include "dix/property_priv.h" +#include "include/propertyst.h" +#include "include/windowstr.h" + +#include "xnest-xcb.h" + +#include "Drawable.h" + +static xcb_atom_t xnest_xlate_atom(struct xnest_upstream_info *upstream, ATOM outAtom) +{ + return xnest_intern_atom(upstream->conn, NameForAtom(outAtom)); +} + +static xcb_window_t xnest_xlate_window(Window window) +{ + WindowPtr pWin = dixLookupWindowByXID(window); + return (pWin ? xnestWindow(pWin) : 0); +} + +static void xnest_property_xlate(ScreenPtr pScreen, PropertyStateRec *rec, void *dataBuf) +{ + // must translate + switch (rec->prop->type) { + /* nothing to do for these */ + case XCB_ATOM_STRING: + case XCB_ATOM_INTEGER: + case XCB_ATOM_POINT: + case XCB_ATOM_RECTANGLE: + case XCB_ATOM_WM_SIZE_HINTS: + case XCB_ATOM_CARDINAL: + case XCB_ATOM_WM_HINTS: + return; + + case XCB_ATOM_ATOM: + { + xcb_atom_t *atoms = dataBuf; + for (int x=0; xprop->size; x++) + atoms[x] = xnest_xlate_atom(&xnestUpstreamInfo, atoms[x]); + return; + } + + case XCB_ATOM_WINDOW: + { + xcb_window_t *windows = dataBuf; + for (int x=0; xprop->size; x++) + windows[x] = xnest_xlate_window(windows[x]); + return; + } + } + + const char *atomName = NameForAtom(rec->prop->type); + if (strcmp(atomName, "UTF8_STRING")==0) + return; + if (strcmp(atomName, "_MOTIF_DRAG_RECEIVER_INFO")==0) + return; + + fprintf(stderr, "WARN: unknown atom type %s\n", atomName); +} + +static void xnest_property_xlate_set(ScreenPtr pScreen, PropertyStateRec *rec) +{ + void *dataBuf = calloc(rec->prop->format, rec->prop->size); + if (!dataBuf) + return; + + memcpy(dataBuf, rec->prop->data, (rec->prop->format / 8) * rec->prop->size); + + xnest_property_xlate(pScreen, rec, dataBuf); + + xnest_upstream_set_property(&xnestUpstreamInfo, + xnestWindow(rec->win), + NameForAtom(rec->prop->propertyName), + NameForAtom(rec->prop->type), + rec->state, + rec->prop->format, + rec->prop->size, + dataBuf); + + free(dataBuf); +} + +void xnest_property_state_callback(CallbackListPtr *pcbl, void *closure, void *calldata) +{ + ScreenPtr pScreen = closure; + PropertyStateRec *rec = calldata; + + if (rec->win->drawable.pScreen != pScreen) + return; + + if (rec->state == PropertyNewValue) { + xnest_property_xlate_set(pScreen, rec); + return; + } + + xnest_upstream_set_property(&xnestUpstreamInfo, + xnestWindow(rec->win), + NameForAtom(rec->prop->propertyName), + NameForAtom(rec->prop->type), + rec->state, + rec->prop->format, + rec->prop->size, + rec->prop->data); +} diff --git a/hw/xnest/xnest-xcb.h b/hw/xnest/xnest-xcb.h index 4e976bca7..3b8c4cba7 100644 --- a/hw/xnest/xnest-xcb.h +++ b/hw/xnest/xnest-xcb.h @@ -117,4 +117,6 @@ void xnest_upstream_set_property( uint32_t size, void *data); +void xnest_property_state_callback(CallbackListPtr *pcbl, void *closure, void *calldata); + #endif /* __XNEST__XCB_H */