mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
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;
|
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;
|
rdpInput* input;
|
||||||
Window childWindow;
|
Window childWindow;
|
||||||
|
|
||||||
input = xfc->instance->input;
|
input = xfc->instance->input;
|
||||||
x = event->xmotion.x;
|
|
||||||
y = event->xmotion.y;
|
|
||||||
|
|
||||||
if (!xfc->settings->MouseMotion)
|
if (!xfc->settings->MouseMotion)
|
||||||
{
|
{
|
||||||
if ((event->xmotion.state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
|
if ((state & (Button1Mask | Button2Mask | Button3Mask)) == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app)
|
if (app)
|
||||||
{
|
{
|
||||||
/* make sure window exists */
|
/* make sure window exists */
|
||||||
if (xf_rdpWindowFromWindow(xfc, event->xmotion.window) == 0)
|
if (xf_rdpWindowFromWindow(xfc, window) == 0)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate to desktop coordinates */
|
/* Translate to desktop coordinates */
|
||||||
XTranslateCoordinates(xfc->display, event->xmotion.window,
|
XTranslateCoordinates(xfc->display, window,
|
||||||
RootWindowOfScreen(xfc->screen),
|
RootWindowOfScreen(xfc->screen),
|
||||||
x, y, &x, &y, &childWindow);
|
x, y, &x, &y, &childWindow);
|
||||||
}
|
}
|
||||||
@ -177,40 +174,38 @@ static BOOL xf_event_MotionNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
return TRUE;
|
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;
|
int flags;
|
||||||
BOOL wheel;
|
BOOL wheel;
|
||||||
BOOL extended;
|
BOOL extended;
|
||||||
rdpInput* input;
|
rdpInput* input;
|
||||||
Window childWindow;
|
Window childWindow;
|
||||||
|
|
||||||
input = xfc->instance->input;
|
|
||||||
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
wheel = FALSE;
|
wheel = FALSE;
|
||||||
extended = 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:
|
case 1:
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1;
|
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3;
|
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2;
|
flags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -228,8 +223,6 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
case 8: /* back */
|
case 8: /* back */
|
||||||
case 97: /* Xming */
|
case 97: /* Xming */
|
||||||
extended = TRUE;
|
extended = TRUE;
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON1;
|
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -237,8 +230,6 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
case 9: /* forward */
|
case 9: /* forward */
|
||||||
case 112: /* Xming */
|
case 112: /* Xming */
|
||||||
extended = TRUE;
|
extended = TRUE;
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON2;
|
flags = PTR_XFLAGS_DOWN | PTR_XFLAGS_BUTTON2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -260,12 +251,12 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
if (app)
|
if (app)
|
||||||
{
|
{
|
||||||
/* make sure window exists */
|
/* make sure window exists */
|
||||||
if (xf_rdpWindowFromWindow(xfc, event->xbutton.window) == 0)
|
if (xf_rdpWindowFromWindow(xfc, window) == 0)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* Translate to desktop coordinates */
|
/* Translate to desktop coordinates */
|
||||||
XTranslateCoordinates(xfc->display, event->xbutton.window,
|
XTranslateCoordinates(xfc->display, window,
|
||||||
RootWindowOfScreen(xfc->screen),
|
RootWindowOfScreen(xfc->screen),
|
||||||
x, y, &x, &y, &childWindow);
|
x, y, &x, &y, &childWindow);
|
||||||
}
|
}
|
||||||
@ -287,38 +278,36 @@ static BOOL xf_event_ButtonPress(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
return TRUE;
|
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;
|
int flags;
|
||||||
|
BOOL wheel;
|
||||||
BOOL extended;
|
BOOL extended;
|
||||||
rdpInput* input;
|
rdpInput* input;
|
||||||
Window childWindow;
|
Window childWindow;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
wheel = FALSE;
|
||||||
|
extended = FALSE;
|
||||||
input = xfc->instance->input;
|
input = xfc->instance->input;
|
||||||
|
|
||||||
x = 0;
|
switch (button)
|
||||||
y = 0;
|
|
||||||
flags = 0;
|
|
||||||
extended = FALSE;
|
|
||||||
|
|
||||||
switch (event->xbutton.button)
|
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_FLAGS_BUTTON1;
|
flags = PTR_FLAGS_BUTTON1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_FLAGS_BUTTON3;
|
flags = PTR_FLAGS_BUTTON3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_FLAGS_BUTTON2;
|
flags = PTR_FLAGS_BUTTON2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -326,8 +315,6 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
case 8:
|
case 8:
|
||||||
case 97:
|
case 97:
|
||||||
extended = TRUE;
|
extended = TRUE;
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_XFLAGS_BUTTON1;
|
flags = PTR_XFLAGS_BUTTON1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -335,8 +322,6 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
case 9:
|
case 9:
|
||||||
case 112:
|
case 112:
|
||||||
extended = TRUE;
|
extended = TRUE;
|
||||||
x = event->xbutton.x;
|
|
||||||
y = event->xbutton.y;
|
|
||||||
flags = PTR_XFLAGS_BUTTON2;
|
flags = PTR_XFLAGS_BUTTON2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -350,12 +335,12 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
if (app)
|
if (app)
|
||||||
{
|
{
|
||||||
/* make sure window exists */
|
/* make sure window exists */
|
||||||
if (xf_rdpWindowFromWindow(xfc, event->xbutton.window) == NULL)
|
if (xf_rdpWindowFromWindow(xfc, window) == NULL)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/* Translate to desktop coordinates */
|
/* Translate to desktop coordinates */
|
||||||
XTranslateCoordinates(xfc->display, event->xbutton.window,
|
XTranslateCoordinates(xfc->display, window,
|
||||||
RootWindowOfScreen(xfc->screen),
|
RootWindowOfScreen(xfc->screen),
|
||||||
x, y, &x, &y, &childWindow);
|
x, y, &x, &y, &childWindow);
|
||||||
}
|
}
|
||||||
@ -376,6 +361,12 @@ static BOOL xf_event_ButtonRelease(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
return TRUE;
|
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)
|
static BOOL xf_event_KeyPress(xfContext* xfc, XEvent* event, BOOL app)
|
||||||
{
|
{
|
||||||
KeySym keysym;
|
KeySym keysym;
|
||||||
|
@ -28,4 +28,8 @@
|
|||||||
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
BOOL xf_event_process(freerdp* instance, XEvent* event);
|
||||||
void xf_event_SendClientEvent(xfContext* xfc, xfWindow* window, Atom atom, unsigned int numArgs, ...);
|
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 */
|
#endif /* __XF_EVENT_H */
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "xf_event.h"
|
||||||
|
|
||||||
#include "xf_input.h"
|
#include "xf_input.h"
|
||||||
|
|
||||||
#ifdef WITH_XI
|
#ifdef WITH_XI
|
||||||
@ -63,7 +65,7 @@ int xf_input_init(xfContext* xfc, Window window)
|
|||||||
int minor = 2;
|
int minor = 2;
|
||||||
Status xstatus;
|
Status xstatus;
|
||||||
XIDeviceInfo* info;
|
XIDeviceInfo* info;
|
||||||
XIEventMask evmasks[8];
|
XIEventMask evmasks[64];
|
||||||
int opcode, event, error;
|
int opcode, event, error;
|
||||||
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
|
BYTE masks[8][XIMaskLen(XI_LASTEVENT)];
|
||||||
|
|
||||||
@ -88,6 +90,9 @@ int xf_input_init(xfContext* xfc, Window window)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xfc->settings->MultiTouchInput)
|
||||||
|
xfc->use_xinput = TRUE;
|
||||||
|
|
||||||
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
|
info = XIQueryDevice(xfc->display, XIAllDevices, &ndevices);
|
||||||
|
|
||||||
for (i = 0; i < ndevices; i++)
|
for (i = 0; i < ndevices; i++)
|
||||||
@ -99,29 +104,37 @@ int xf_input_init(xfContext* xfc, Window window)
|
|||||||
XIAnyClassInfo* class = dev->classes[j];
|
XIAnyClassInfo* class = dev->classes[j];
|
||||||
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
XITouchClassInfo* t = (XITouchClassInfo*) class;
|
||||||
|
|
||||||
if (class->type != XITouchClass)
|
//printf("class->type: %d name: %s\n", class->type, dev->name);
|
||||||
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);
|
|
||||||
|
|
||||||
evmasks[nmasks].mask = masks[nmasks];
|
evmasks[nmasks].mask = masks[nmasks];
|
||||||
evmasks[nmasks].mask_len = sizeof(masks[0]);
|
evmasks[nmasks].mask_len = sizeof(masks[0]);
|
||||||
ZeroMemory(masks[nmasks], sizeof(masks[0]));
|
ZeroMemory(masks[nmasks], sizeof(masks[0]));
|
||||||
evmasks[nmasks].deviceid = dev->deviceid;
|
evmasks[nmasks].deviceid = dev->deviceid;
|
||||||
|
|
||||||
|
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_TouchBegin);
|
||||||
XISetMask(masks[nmasks], XI_TouchUpdate);
|
XISetMask(masks[nmasks], XI_TouchUpdate);
|
||||||
XISetMask(masks[nmasks], XI_TouchEnd);
|
XISetMask(masks[nmasks], XI_TouchEnd);
|
||||||
nmasks++;
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nmasks > 0)
|
if (nmasks > 0)
|
||||||
@ -365,6 +378,31 @@ int xf_input_touch_remote(xfContext* xfc, XIDeviceEvent* event, int evtype)
|
|||||||
return 0;
|
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)
|
int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
||||||
{
|
{
|
||||||
XGenericEventCookie* cookie = &event->xcookie;
|
XGenericEventCookie* cookie = &event->xcookie;
|
||||||
@ -388,6 +426,7 @@ int xf_input_handle_event_remote(xfContext* xfc, XEvent* event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
xf_input_event(xfc, cookie->data, cookie->evtype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,7 @@ struct xf_context
|
|||||||
BOOL enableScaling;
|
BOOL enableScaling;
|
||||||
|
|
||||||
BOOL focused;
|
BOOL focused;
|
||||||
|
BOOL use_xinput;
|
||||||
BOOL mouse_active;
|
BOOL mouse_active;
|
||||||
BOOL suppress_output;
|
BOOL suppress_output;
|
||||||
BOOL fullscreen_toggle;
|
BOOL fullscreen_toggle;
|
||||||
|
Loading…
Reference in New Issue
Block a user