mirror of https://github.com/FreeRDP/FreeRDP
xfreerdp: implement XInput 2.2 mouse pointer events
This commit is contained in:
parent
b55725487f
commit
d006891207
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ struct xf_context
|
|||
BOOL enableScaling;
|
||||
|
||||
BOOL focused;
|
||||
BOOL use_xinput;
|
||||
BOOL mouse_active;
|
||||
BOOL suppress_output;
|
||||
BOOL fullscreen_toggle;
|
||||
|
|
Loading…
Reference in New Issue