xfreerdp: implement XInput 2.2 mouse pointer events

This commit is contained in:
Marc-André Moreau 2013-06-17 21:54:38 -04:00
parent b55725487f
commit d006891207
4 changed files with 99 additions and 64 deletions

View File

@ -130,32 +130,29 @@ static BOOL xf_event_VisibilityNotify(xfContext* xfc, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app)
{
int x, y;
rdpInput* input;
Window childWindow;
input = xfc->instance->input;
x = event->xmotion.x;
y = event->xmotion.y;
if (!xfc->settings->MouseMotion)
{
if ((event->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
return TRUE;
}
}
if (app)
{
/* make sure window exists */
if (xf_rdpWindowFromWindow(xfc, event->xmotion.window) == 0)
if (xf_rdpWindowFromWindow(xfc, window) == 0)
{
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfc->display, event->xmotion.window,
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
x, y, &x, &y, &childWindow);
}
@ -177,40 +174,38 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
{
return xf_generic_MotionNotify(xfc, event->xmotion.x, event->xmotion.y,
event->xmotion.state, event->xmotion.window, app);
}
BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app)
{
int x, y;
int flags;
BOOL wheel;
BOOL extended;
rdpInput* input;
Window childWindow;
input = xfc->instance->input;
x = 0;
y = 0;
flags = 0;
wheel = FALSE;
extended = FALSE;
input = xfc->instance->input;
switch (event->xbutton.button)
printf("ButtonPress: x: %d y: %d button: %d\n", x, y, button);
switch (button)
{
case 1:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1;
break;
case 2:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3;
break;
case 3:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2;
break;
@ -228,8 +223,6 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
case 8: /* back */
case 97: /* Xming */
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON1;
break;
@ -237,8 +230,6 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
case 9: /* forward */
case 112: /* Xming */
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON2;
break;
@ -260,12 +251,12 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
if (app)
{
/* make sure window exists */
if (xf_rdpWindowFromWindow(xfc, event->xbutton.window) == 0)
if (xf_rdpWindowFromWindow(xfc, window) == 0)
{
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfc->display, event->xbutton.window,
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
x, y, &x, &y, &childWindow);
}
@ -287,38 +278,36 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
{
return xf_generic_ButtonPress(xfc, event->xbutton.x, event->xbutton.y,
event->xbutton.button, event->xbutton.window, app);
}
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app)
{
int x, y;
int flags;
BOOL wheel;
BOOL extended;
rdpInput* input;
Window childWindow;
flags = 0;
wheel = FALSE;
extended = FALSE;
input = xfc->instance->input;
x = 0;
y = 0;
flags = 0;
extended = FALSE;
switch (event->xbutton.button)
switch (button)
{
case 1:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_BUTTON1;
break;
case 2:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_BUTTON3;
break;
case 3:
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_FLAGS_BUTTON2;
break;
@ -326,8 +315,6 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
case 8:
case 97:
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_BUTTON1;
break;
@ -335,8 +322,6 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
case 9:
case 112:
extended = TRUE;
x = event->xbutton.x;
y = event->xbutton.y;
flags = PTR_XFLAGS_BUTTON2;
break;
@ -350,12 +335,12 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
if (app)
{
/* make sure window exists */
if (xf_rdpWindowFromWindow(xfc, event->xbutton.window) == NULL)
if (xf_rdpWindowFromWindow(xfc, window) == NULL)
{
return TRUE;
}
/* Translate to desktop coordinates */
XTranslateCoordinates(xfc->display, event->xbutton.window,
XTranslateCoordinates(xfc->display, window,
RootWindowOfScreen(xfc->screen),
x, y, &x, &y, &childWindow);
}
@ -376,6 +361,12 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
return TRUE;
}
static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
{
return xf_generic_ButtonRelease(xfc, event->xbutton.x, event->xbutton.y,
event->xbutton.button, event->xbutton.window, app);
}
static BOOL xf_event_KeyPress(xfContext* xfc, XEvent* event, BOOL app)
{
KeySym keysym;

View File

@ -28,4 +28,8 @@
BOOL xf_event_process(freerdp* instance, XEvent* event);
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window window, BOOL app);
BOOL xf_generic_ButtonPress(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
BOOL xf_generic_ButtonRelease(xfContext* xfc, int x, int y, int button, Window window, BOOL app);
#endif /* __XF_EVENT_H */

View File

@ -27,6 +27,8 @@
#include <math.h>
#include "xf_event.h"
#include "xf_input.h"
#ifdef WITH_XI
@ -63,7 +65,7 @@ int xf_input_init(xfContext* xfc, Window window)
int minor = 2;
Status xstatus;
XIDeviceInfo* info;
XIEventMask evmasks[8];
XIEventMask evmasks[64];
int opcode, event, error;
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
@ -88,6 +90,9 @@ int xf_input_init(xfContext* xfc, Window window)
return -1;
}
if (xfc->settings->MultiTouchInput)
xfc->use_xinput = TRUE;
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
for (i = 0; i < ndevices; i++)
@ -99,28 +104,36 @@ int xf_input_init(xfContext* xfc, Window window)
XIAnyClassInfo* class = dev->classes[j];
XITouchClassInfo* t = (XITouchClassInfo*) class;
if (class->type != XITouchClass)
continue;
if (t->mode != XIDirectTouch)
continue;
if (strcmp(dev->name, "Virtual core pointer") == 0)
continue;
printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n",
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
dev->deviceid, t->mode, t->num_touches);
//printf("class->type: %d name: %s\n", class->type, dev->name);
evmasks[nmasks].mask = masks[nmasks];
evmasks[nmasks].mask_len = sizeof(masks[0]);
ZeroMemory(masks[nmasks], sizeof(masks[0]));
evmasks[nmasks].deviceid = dev->deviceid;
XISetMask(masks[nmasks], XI_TouchBegin);
XISetMask(masks[nmasks], XI_TouchUpdate);
XISetMask(masks[nmasks], XI_TouchEnd);
nmasks++;
if ((class->type == XITouchClass) && (t->mode == XIDirectTouch) &&
(strcmp(dev->name, "Virtual core pointer") != 0))
{
printf("%s %s touch device (id: %d, mode: %d), supporting %d touches.\n",
dev->name, (t->mode == XIDirectTouch) ? "direct" : "dependent",
dev->deviceid, t->mode, t->num_touches);
XISetMask(masks[nmasks], XI_TouchBegin);
XISetMask(masks[nmasks], XI_TouchUpdate);
XISetMask(masks[nmasks], XI_TouchEnd);
nmasks++;
}
if (xfc->use_xinput)
{
if (class->type == XIButtonClass)
{
XISetMask(masks[nmasks], XI_ButtonPress);
XISetMask(masks[nmasks], XI_ButtonRelease);
XISetMask(masks[nmasks], XI_Motion);
nmasks++;
}
}
}
}
@ -365,6 +378,31 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
return 0;
}
int xf_input_event(xfContext* xfc, XIDeviceEvent* event, int evtype)
{
return TRUE;
switch (evtype)
{
case XI_ButtonPress:
xf_generic_ButtonPress(xfc, (int) event->event_x, (int) event->event_y,
event->detail, event->event, xfc->remote_app);
break;
case XI_ButtonRelease:
xf_generic_ButtonRelease(xfc, (int) event->event_x, (int) event->event_y,
event->detail, event->event, xfc->remote_app);
break;
case XI_Motion:
xf_generic_MotionNotify(xfc, (int) event->event_x, (int) event->event_y,
event->detail, event->event, xfc->remote_app);
break;
}
return 0;
}
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
{
XGenericEventCookie* cookie = &event->xcookie;
@ -388,6 +426,7 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
break;
default:
xf_input_event(xfc, cookie->data, cookie->evtype);
break;
}
}

View File

@ -115,6 +115,7 @@ struct xf_context
BOOL enableScaling;
BOOL focused;
BOOL use_xinput;
BOOL mouse_active;
BOOL suppress_output;
BOOL fullscreen_toggle;