[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