Skip to content
Commits on Source (3)
  • Peter Harris's avatar
    xkb: only swap once in XkbSetMap · 270e4397
    Peter Harris authored
    
    
    The server swaps part of the request in _XkbSetMapChecks instead of
    SProcXkbSetMap (presumably because walking the XkbSetMap request is hard,
    and we don't want to maintain another copy of that code).
    
    Swap the first time _XkbSetMapChecks is called, not the second time.
    
    Signed-off-by: default avatarPeter Harris <pharris@opentext.com>
    270e4397
  • Peter Harris's avatar
    xkb: fix key type index check in _XkbSetMapChecks · de940e06
    Peter Harris authored
    
    
    This code block was moved from a function that returns 0 for failure to a
    function that returns 0 for Success in commit
    649293f6. Change the return value to
    BadValue to match the other checks in _XkbSetMapChecks.
    
    Set nTypes to xkb->map->num_types when XkbKeyTypesMask is not set, to
    allow requests with the XkbKeyTypesMask flag unset in stuff->present to
    succeed.
    
    Fixes a potential heap smash when client->swapped is true, because the
    remainder of the request will not be swapped after "return 0", but
    _XkbSetMap will be called anyway (because 0 is Success).
    
    Signed-off-by: default avatarPeter Harris <pharris@opentext.com>
    de940e06
  • mntmn's avatar
    xwayland: port rooted xwayland from wl_shell to xdg-shell protocol · 3d6efc4a
    mntmn authored and Olivier Fourdan's avatar Olivier Fourdan committed
    
    
    Recently, rooted Xwayland crashes on wlroots-based compositors, because
    wlroots removed the deprecated wl_shell protocol.
    This MR fixes this by changing the code in question to the xdg-shell
    protocol. My motivation do this: on etnaviv-based embedded platforms,
    rooted Xwayland is much faster and doesn't cause UI rendering bugs
    compared to rootless Xwayland.
    
    Signed-off-by: default avatarLukas F. Hartmann <lukas@mntre.com>
    3d6efc4a
......@@ -100,7 +100,9 @@ Xwayland_built_sources += \
linux-dmabuf-unstable-v1-client-protocol.h \
linux-dmabuf-unstable-v1-protocol.c \
viewporter-client-protocol.h \
viewporter-protocol.c
viewporter-protocol.c\
xdg-shell-client-protocol.h\
xdg-shell-protocol.c
if XWAYLAND_EGLSTREAM
Xwayland_built_sources += \
......@@ -154,6 +156,11 @@ viewporter-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter
viewporter-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/viewporter/viewporter.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
xdg-shell-protocol.c: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) @SCANNER_ARG@ < $< > $@
xdg-shell-client-protocol.h: $(WAYLAND_PROTOCOLS_DATADIR)/stable/xdg-shell/xdg-shell.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
wayland-eglstream-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
wayland-eglstream-controller-client-protocol.h : $(WAYLAND_EGLSTREAM_DATADIR)/wayland-eglstream-controller.xml
......
......@@ -40,6 +40,7 @@ kbgrab_xml = join_paths(protodir, 'unstable', 'xwayland-keyboard-grab', 'xwaylan
xdg_output_xml = join_paths(protodir, 'unstable', 'xdg-output', 'xdg-output-unstable-v1.xml')
dmabuf_xml = join_paths(protodir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml')
viewporter_xml = join_paths(protodir, 'stable', 'viewporter', 'viewporter.xml')
xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml')
client_header = generator(scanner,
output : '@BASENAME@-client-protocol.h',
......@@ -63,6 +64,7 @@ srcs += client_header.process(kbgrab_xml)
srcs += client_header.process(xdg_output_xml)
srcs += client_header.process(dmabuf_xml)
srcs += client_header.process(viewporter_xml)
srcs += client_header.process(xdg_shell_xml)
srcs += code.process(relative_xml)
srcs += code.process(pointer_xml)
srcs += code.process(tablet_xml)
......@@ -70,6 +72,7 @@ srcs += code.process(kbgrab_xml)
srcs += code.process(xdg_output_xml)
srcs += code.process(dmabuf_xml)
srcs += code.process(viewporter_xml)
srcs += code.process(xdg_shell_xml)
xwayland_glamor = []
eglstream_srcs = []
......
......@@ -54,6 +54,7 @@
#include "xdg-output-unstable-v1-client-protocol.h"
#include "viewporter-client-protocol.h"
#include "xdg-shell-client-protocol.h"
static DevPrivateKeyRec xwl_screen_private_key;
static DevPrivateKeyRec xwl_client_private_key;
......@@ -318,6 +319,17 @@ xwl_screen_post_damage(struct xwl_screen *xwl_screen)
}
}
static void
xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base,
uint32_t serial)
{
xdg_wm_base_pong(xdg_wm_base, serial);
}
static const struct xdg_wm_base_listener xdg_wm_base_listener = {
xdg_wm_base_ping,
};
static void
registry_global(void *data, struct wl_registry *registry, uint32_t id,
const char *interface, uint32_t version)
......@@ -336,9 +348,12 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id,
else if (strcmp(interface, "wl_shm") == 0) {
xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
}
else if (strcmp(interface, "wl_shell") == 0) {
xwl_screen->shell =
wl_registry_bind(registry, id, &wl_shell_interface, 1);
else if (strcmp(interface, "xdg_wm_base") == 0) {
xwl_screen->xdg_wm_base =
wl_registry_bind(registry, id, &xdg_wm_base_interface, 1);
xdg_wm_base_add_listener(xwl_screen->xdg_wm_base,
&xdg_wm_base_listener,
NULL);
}
else if (strcmp(interface, "wl_output") == 0 && version >= 2) {
if (xwl_output_create(xwl_screen, id))
......
......@@ -79,7 +79,7 @@ struct xwl_screen {
struct wl_compositor *compositor;
struct zwp_tablet_manager_v2 *tablet_manager;
struct wl_shm *shm;
struct wl_shell *shell;
struct xdg_wm_base *xdg_wm_base;
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
struct zwp_pointer_constraints_v1 *pointer_constraints;
struct zwp_xwayland_keyboard_grab_manager_v1 *wp_grab;
......
......@@ -44,6 +44,7 @@
#include "xwayland-shm.h"
#include "viewporter-client-protocol.h"
#include "xdg-shell-client-protocol.h"
static DevPrivateKeyRec xwl_window_private_key;
static DevPrivateKeyRec xwl_damage_private_key;
......@@ -401,28 +402,15 @@ send_surface_id_event(struct xwl_window *xwl_window)
}
static void
shell_surface_ping(void *data,
struct wl_shell_surface *shell_surface, uint32_t serial)
xdg_surface_handle_configure(void *data,
struct xdg_surface *xdg_surface,
uint32_t serial)
{
wl_shell_surface_pong(shell_surface, serial);
xdg_surface_ack_configure(xdg_surface, serial);
}
static void
shell_surface_configure(void *data,
struct wl_shell_surface *wl_shell_surface,
uint32_t edges, int32_t width, int32_t height)
{
}
static void
shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface)
{
}
static const struct wl_shell_surface_listener shell_surface_listener = {
shell_surface_ping,
shell_surface_configure,
shell_surface_popup_done
static const struct xdg_surface_listener xdg_surface_listener = {
xdg_surface_handle_configure,
};
static Bool
......@@ -461,17 +449,19 @@ ensure_surface_for_window(WindowPtr window)
}
if (!xwl_screen->rootless) {
xwl_window->shell_surface =
wl_shell_get_shell_surface(xwl_screen->shell, xwl_window->surface);
if (xwl_window->shell_surface == NULL) {
ErrorF("Failed creating shell surface\n");
xwl_window->xdg_surface =
xdg_wm_base_get_xdg_surface(xwl_screen->xdg_wm_base, xwl_window->surface);
if (xwl_window->xdg_surface == NULL) {
ErrorF("Failed creating xdg_wm_base xdg_surface\n");
goto err_surf;
}
wl_shell_surface_add_listener(xwl_window->shell_surface,
&shell_surface_listener, xwl_window);
xdg_surface_add_listener(xwl_window->xdg_surface,
&xdg_surface_listener, xwl_window);
xdg_surface_get_toplevel(xwl_window->xdg_surface);
wl_shell_surface_set_toplevel(xwl_window->shell_surface);
wl_surface_commit(xwl_window->surface);
region = wl_compositor_create_region(xwl_screen->compositor);
if (region == NULL) {
......@@ -520,8 +510,8 @@ ensure_surface_for_window(WindowPtr window)
return TRUE;
err_surf:
if (xwl_window->shell_surface)
wl_shell_surface_destroy(xwl_window->shell_surface);
if (xwl_window->xdg_surface)
xdg_surface_destroy(xwl_window->xdg_surface);
wl_surface_destroy(xwl_window->surface);
err:
free(xwl_window);
......
......@@ -42,7 +42,7 @@ struct xwl_window {
struct wl_surface *surface;
struct wp_viewport *viewport;
float scale_x, scale_y;
struct wl_shell_surface *shell_surface;
struct xdg_surface *xdg_surface;
WindowPtr window;
struct xorg_list link_damage;
struct xorg_list link_window;
......
......@@ -1587,7 +1587,7 @@ CheckKeyTypes(ClientPtr client,
XkbDescPtr xkb,
xkbSetMapReq * req,
xkbKeyTypeWireDesc ** wireRtrn,
int *nMapsRtrn, CARD8 *mapWidthRtrn)
int *nMapsRtrn, CARD8 *mapWidthRtrn, Bool doswap)
{
unsigned nMaps;
register unsigned i, n;
......@@ -1626,7 +1626,7 @@ CheckKeyTypes(ClientPtr client,
for (i = 0; i < req->nTypes; i++) {
unsigned width;
if (client->swapped) {
if (client->swapped && doswap) {
swaps(&wire->virtualMods);
}
n = i + req->firstType;
......@@ -1653,7 +1653,7 @@ CheckKeyTypes(ClientPtr client,
mapWire = (xkbKTSetMapEntryWireDesc *) &wire[1];
preWire = (xkbModsWireDesc *) &mapWire[wire->nMapEntries];
for (n = 0; n < wire->nMapEntries; n++) {
if (client->swapped) {
if (client->swapped && doswap) {
swaps(&mapWire[n].virtualMods);
}
if (mapWire[n].realMods & (~wire->realMods)) {
......@@ -1671,7 +1671,7 @@ CheckKeyTypes(ClientPtr client,
return 0;
}
if (wire->preserve) {
if (client->swapped) {
if (client->swapped && doswap) {
swaps(&preWire[n].virtualMods);
}
if (preWire[n].realMods & (~mapWire[n].realMods)) {
......@@ -1710,7 +1710,7 @@ CheckKeySyms(ClientPtr client,
xkbSetMapReq * req,
int nTypes,
CARD8 *mapWidths,
CARD16 *symsPerKey, xkbSymMapWireDesc ** wireRtrn, int *errorRtrn)
CARD16 *symsPerKey, xkbSymMapWireDesc ** wireRtrn, int *errorRtrn, Bool doswap)
{
register unsigned i;
XkbSymMapPtr map;
......@@ -1724,7 +1724,7 @@ CheckKeySyms(ClientPtr client,
KeySym *pSyms;
register unsigned nG;
if (client->swapped) {
if (client->swapped && doswap) {
swaps(&wire->nSyms);
}
nG = XkbNumGroups(wire->groupInfo);
......@@ -2371,11 +2371,11 @@ SetVirtualModMap(XkbSrvInfoPtr xkbi,
/**
* Check if the given request can be applied to the given device but don't
* actually do anything..
* actually do anything, except swap values when client->swapped and doswap are both true.
*/
static int
_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
char *values)
char *values, Bool doswap)
{
XkbSrvInfoPtr xkbi;
XkbDescPtr xkb;
......@@ -2415,10 +2415,13 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
if ((req->present & XkbKeyTypesMask) &&
(!CheckKeyTypes(client, xkb, req, (xkbKeyTypeWireDesc **) &values,
&nTypes, mapWidths))) {
&nTypes, mapWidths, doswap))) {
client->errorValue = nTypes;
return BadValue;
}
else {
nTypes = xkb->map->num_types;
}
/* symsPerKey/mapWidths must be filled regardless of client-side flags */
map = &xkb->map->key_sym_map[xkb->min_key_code];
......@@ -2429,7 +2432,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
for (w = g = 0; g < ng; g++) {
if (map->kt_index[g] >= (unsigned) nTypes) {
client->errorValue = _XkbErrCode4(0x13, i, g, map->kt_index[g]);
return 0;
return BadValue;
}
if (mapWidths[map->kt_index[g]] > w)
w = mapWidths[map->kt_index[g]];
......@@ -2439,7 +2442,7 @@ _XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq * req,
if ((req->present & XkbKeySymsMask) &&
(!CheckKeySyms(client, xkb, req, nTypes, mapWidths, symsPerKey,
(xkbSymMapWireDesc **) &values, &error))) {
(xkbSymMapWireDesc **) &values, &error, doswap))) {
client->errorValue = error;
return BadValue;
}
......@@ -2631,7 +2634,7 @@ ProcXkbSetMap(ClientPtr client)
/* Check if we can to the SetMap on the requested device. If this
succeeds, do the same thing for all extension devices (if needed).
If any of them fails, fail. */
rc = _XkbSetMapChecks(client, dev, stuff, tmp);
rc = _XkbSetMapChecks(client, dev, stuff, tmp, TRUE);
if (rc != Success)
return rc;
......@@ -2647,7 +2650,7 @@ ProcXkbSetMap(ClientPtr client)
rc = XaceHook(XACE_DEVICE_ACCESS, client, other,
DixManageAccess);
if (rc == Success) {
rc = _XkbSetMapChecks(client, other, stuff, tmp);
rc = _XkbSetMapChecks(client, other, stuff, tmp, FALSE);
if (rc != Success)
return rc;
}
......@@ -2661,7 +2664,7 @@ ProcXkbSetMap(ClientPtr client)
(other != master || dev != master->lastSlave))
continue;
rc = _XkbSetMapChecks(client, other, stuff, tmp);
rc = _XkbSetMapChecks(client, other, stuff, tmp, FALSE);
if (rc != Success)
return rc;
}
......