[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freedesktop-xorg
Subject:    Issue with multitouch monitors and xcb_grab/ungrab_pointer.
From:       "Nelson, Andrew R." <Andrew.R.Nelson () leidos ! com>
Date:       2019-10-28 16:49:57
Message-ID: 8d9179b1b46245a6a9d8915e3aa35277 () leidos ! com
[Download RAW message or body]

Leidos Proprietary

We are encountering an issue with Xorg 1.17.2 (Yes I know it is very old).  

    1. Compile the attached program  [gcc touchbug.c -o touchbug -lxcb]
    2. Run the program [./touchbug ]
    3. Move the mouse over the application window, notice the console output \
indicates no buttons are pressed.  4. Press and hold the mouse in the window created \
by the attached program (this will grab the pointer).  5. Without releasing the mouse \
generate a touch event outside of the window (this will ungrab the pointer).  6. Move \
the mouse over the window (notice the console output indicates Button1 is pressed). 

I would have expected, in step 6, the console output would again indicate no button \
is pressed.  

I've tried this with xscope between the example application and the xserver and \
xscope indicates the motion events sent by the XServer are also reporting Button1 is \
pressed.    I have though noticed [xinput --query-state <id>] for the mouse indicates \
all buttons are "up".

It appears this issue has been fixed in Xorg 1.20.4 (at least I'm not seeing the \
issue on a upgraded workstation that happens to have a later version of Xorg).   

What I'm trying to figure out is what component might be involved in this issue \
(XServer, XInputExtention, Kernel Driver)?  Is the issue core to the Xserver or is \
this because the XInput extension has somehow modified the events so that XCB cannot \
read them correctly?   Is it possible anyone has heard of this issue and can point to \
where it was fixed?  Is it possible we have somehow misconfigured our XServer?

Thanks,

Andrew Nelson

This email and any attachments to it are intended only for the identified recipients. \
It may contain proprietary or otherwise legally protected information of Leidos. Any \
unauthorized use or disclosure of this communication is strictly prohibited. If you \
have received this communication in error, please notify the sender and delete or \
otherwise destroy the email and all attachments immediately.


["touchbug.c" (text/plain)]

// Compile:
// gcc touchbug.c -o touchbug -lxcb

#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <inttypes.h>
#include <unistd.h>

#define TRUE 1
#define FALSE 0

void print_state(uint16_t mask)
{
    if(mask & XCB_EVENT_MASK_NO_EVENT) {
        printf("NO_EVENT\n");
    }
    if(mask & XCB_EVENT_MASK_KEY_PRESS) {
        printf("KEY_PRESS\n");
    }
    if(mask & XCB_EVENT_MASK_KEY_RELEASE) {
        printf("KEY_RELEASE\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_PRESS) {
        printf("BUTTON_PRESS\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_RELEASE) {
        printf("BUTTON_RELEASE\n");
    }
    if(mask & XCB_EVENT_MASK_ENTER_WINDOW) {
        printf("ENTER_WINDOW\n");
    }
    if(mask & XCB_EVENT_MASK_LEAVE_WINDOW) {
        printf("LEAVE_WINDOW\n");
    }
    if(mask & XCB_EVENT_MASK_POINTER_MOTION) {
        printf("POINTER MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_POINTER_MOTION_HINT) {
        printf("POINTER_MOTION_HINT\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_1_MOTION) {
        printf("BUTTON_1_MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_2_MOTION) {
        printf("BUTTON_2_MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_3_MOTION) {
        printf("BUTTON_3_MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_4_MOTION) {
        printf("BUTTON_4_MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_5_MOTION) {
        printf("BUTTON_5_MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_BUTTON_MOTION) {
        printf("BUTTON_MOTION\n");
    }
    if(mask & XCB_EVENT_MASK_KEYMAP_STATE) {
        printf("KEYMAP_STATE\n");
    }
    if(mask & XCB_EVENT_MASK_EXPOSURE) {
        printf("EXPOSURE\n");
    }
    if(mask & XCB_EVENT_MASK_VISIBILITY_CHANGE) {
        printf("VISIBILITY_CHANGE\n");
    }
    if(mask & XCB_EVENT_MASK_STRUCTURE_NOTIFY) {
        printf("STRUCTURE_NOTIFY\n");
    }
    if(mask & XCB_EVENT_MASK_RESIZE_REDIRECT) {
        printf("RESIZE_REDIRECT\n");
    }
    if(mask & XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY) {
        printf("SUBSTRUCTURE_NOTIFY\n");
    }
    if(mask & XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT) {
        printf("SUBSTRUCTURE_REDIRECT\n");
    }
    if(mask & XCB_EVENT_MASK_FOCUS_CHANGE) {
        printf("FOCUS_CHANGE\n");
    }
    if(mask & XCB_EVENT_MASK_PROPERTY_CHANGE) {
        printf("PROPERTY_CHANGE\n");
    }
}

int grab_pointer(xcb_connection_t *conn, xcb_screen_t *screen)
{
    xcb_grab_pointer_cookie_t cookie;
    xcb_grab_pointer_reply_t *reply;

    uint16_t event_mask = XCB_EVENT_MASK_BUTTON_PRESS
        | XCB_EVENT_MASK_BUTTON_RELEASE
        | XCB_EVENT_MASK_ENTER_WINDOW
        | XCB_EVENT_MASK_LEAVE_WINDOW
        | XCB_EVENT_MASK_POINTER_MOTION
        | XCB_EVENT_MASK_BUTTON_MOTION;

    cookie = xcb_grab_pointer(
        conn,
        TRUE,                /* If 1, the grab_window will still get the pointer \
events. If 0, events are not reported to the grab_window. */  screen->root,        /* \
grab the root window */  event_mask,          /* which events to let through */
        XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
        XCB_GRAB_MODE_ASYNC, /* keyboard mode */
        XCB_NONE,            /* confine_to = in which window should the cursor stay \
*/  XCB_NONE,            /* leave the cursor alone */
        XCB_CURRENT_TIME
    );

    int success = FALSE;

    if ((reply = xcb_grab_pointer_reply(conn, cookie, NULL))) {
        if (reply->status == XCB_GRAB_STATUS_SUCCESS)
            success = TRUE;
        free(reply);
    }

    return success;
}

int ungrab_pointer(xcb_connection_t *conn)
{
    xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
    xcb_flush(conn);
    return TRUE;
}

int main()
{
    xcb_connection_t *connection;
    const xcb_setup_t *setup;
    xcb_screen_t *screen;
    xcb_window_t win;
    xcb_gcontext_t foreground;
    xcb_generic_event_t *event;

    uint32_t mask;
    uint32_t values[2];

    uint32_t configure_mask;
    uint32_t configure_values[4];

    /* Option the connection to the X server.
       Using DISPLAY environment variable as the default
       display name */
    connection = xcb_connect(NULL, NULL);

    if (xcb_connection_has_error(connection)) {
        fprintf(stderr, "Unable to connect to xserver. Please check $DISPLAY.\n");
        xcb_disconnect(connection);
        return 0;
    }

    /* Get the first screen */
    setup = xcb_get_setup(connection);
    screen = xcb_setup_roots_iterator(setup).data;

    /* Create black (foreground) graphic context */
    win = screen->root;

    foreground = xcb_generate_id(connection);
    mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES,
    values[0] = screen->black_pixel;
    values[1] = 0;
    xcb_create_gc(connection, foreground, win, mask, values);

    /* Ask for the window id */
    win = xcb_generate_id(connection);

    /* Create the window */
    mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    values[0] = screen->white_pixel;
    values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | \
XCB_EVENT_MASK_POINTER_MOTION;

    xcb_create_window(connection,
                      XCB_COPY_FROM_PARENT,
                      win,
                      screen->root,
                      50, 0,
                      150, 150,
                      10,
                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
                      screen->root_visual,
                      mask,
                      values);

    configure_mask = 0;
    configure_mask |= XCB_CONFIG_WINDOW_X;
    configure_mask |= XCB_CONFIG_WINDOW_Y;
    configure_mask |= XCB_CONFIG_WINDOW_WIDTH;
    configure_mask |= XCB_CONFIG_WINDOW_HEIGHT;

    configure_values[0] = 300;
    configure_values[1] = 20;
    configure_values[2] = 250;
    configure_values[2] = 350;

    /* Map the window on the screen */
    xcb_map_window(connection, win);

    /* We flush the request */
    xcb_flush(connection);

    uint16_t grabbed = FALSE;

    while((event = xcb_wait_for_event(connection))) {
        switch(event->response_type & ~0x80) {
            case XCB_EXPOSE: {
		printf("XCB_EXPOSE\n");
                break;
            }
            case XCB_BUTTON_PRESS: {
                xcb_button_press_event_t *press = (xcb_button_press_event_t *)event;
		printf("XCB_BUTTON_PRESS\n");
                if(grabbed) {
                    int success = ungrab_pointer(connection);
                    if(success) {
                        printf("successfully ungrabbed the pointer\n");
                        grabbed = FALSE;
                    }
	        } else {
                    int success = grab_pointer(connection, screen);	
                    if(success) {
                        printf("successfully grabbed the pointer\n");
                        grabbed = TRUE;
                    }
		}
                break;
            }
            case XCB_MOTION_NOTIFY: {
                xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t \
*)event;  printf("XCB_POINTER_MOTION: detail (%"PRIi8") coordinates \
                (%"PRIi16",%"PRIi16"), state %"PRIi16"\n",
                        motion->detail, motion->event_x, motion->event_y, \
motion->state);  print_state(motion->state);
                break;
            }
        }
        free(event);
    }
    
    xcb_disconnect(connection);

    return 0;
}


[Attachment #4 (text/plain)]

_______________________________________________
xorg@lists.x.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: https://lists.x.org/mailman/listinfo/xorg
Your subscription address: %(user_address)s

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic