Merge pull request #1944 from nfedera/fix-2014-07-07-01
xfreerdp: xfixes selection ownership notification
This commit is contained in:
commit
c005205795
@ -148,6 +148,10 @@ set(XRENDER_FEATURE_TYPE "RECOMMENDED")
|
|||||||
set(XRENDER_FEATURE_PURPOSE "rendering")
|
set(XRENDER_FEATURE_PURPOSE "rendering")
|
||||||
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
|
||||||
|
|
||||||
|
set(XFIXES_FEATURE_TYPE "RECOMMENDED")
|
||||||
|
set(XFIXES_FEATURE_PURPOSE "X11 xfixes extension")
|
||||||
|
set(XFIXES_FEATURE_DESCRIPTION "Useful additions to the X11 core protocol")
|
||||||
|
|
||||||
find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
|
find_feature(XShm ${XSHM_FEATURE_TYPE} ${XSHM_FEATURE_PURPOSE} ${XSHM_FEATURE_DESCRIPTION})
|
||||||
find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
|
find_feature(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_FEATURE_DESCRIPTION})
|
||||||
find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION})
|
find_feature(Xext ${XEXT_FEATURE_TYPE} ${XEXT_FEATURE_PURPOSE} ${XEXT_FEATURE_DESCRIPTION})
|
||||||
@ -155,6 +159,7 @@ find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSO
|
|||||||
find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION})
|
find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION})
|
||||||
find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION})
|
find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION})
|
||||||
find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION})
|
find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION})
|
||||||
|
find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION})
|
||||||
|
|
||||||
if(WITH_XINERAMA)
|
if(WITH_XINERAMA)
|
||||||
add_definitions(-DWITH_XINERAMA)
|
add_definitions(-DWITH_XINERAMA)
|
||||||
@ -192,6 +197,12 @@ if(WITH_XRENDER)
|
|||||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES})
|
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_XFIXES)
|
||||||
|
add_definitions(-DWITH_XFIXES)
|
||||||
|
include_directories(${XFIXES_INCLUDE_DIRS})
|
||||||
|
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XFIXES_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/resources)
|
include_directories(${CMAKE_SOURCE_DIR}/resources)
|
||||||
|
|
||||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client)
|
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client)
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
|
#ifdef WITH_XFIXES
|
||||||
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <winpr/crt.h>
|
#include <winpr/crt.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
|
|
||||||
@ -88,6 +92,11 @@ struct clipboard_context
|
|||||||
BOOL incr_starts;
|
BOOL incr_starts;
|
||||||
BYTE* incr_data;
|
BYTE* incr_data;
|
||||||
int incr_data_length;
|
int incr_data_length;
|
||||||
|
|
||||||
|
/* X Fixes extension */
|
||||||
|
int xfixes_event_base;
|
||||||
|
int xfixes_error_base;
|
||||||
|
BOOL xfixes_supported;
|
||||||
};
|
};
|
||||||
|
|
||||||
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels)
|
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels)
|
||||||
@ -121,6 +130,30 @@ void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels)
|
|||||||
|
|
||||||
XSelectInput(xfc->display, cb->root_window, PropertyChangeMask);
|
XSelectInput(xfc->display, cb->root_window, PropertyChangeMask);
|
||||||
|
|
||||||
|
#ifdef WITH_XFIXES
|
||||||
|
if (XFixesQueryExtension(xfc->display, &cb->xfixes_event_base, &cb->xfixes_error_base))
|
||||||
|
{
|
||||||
|
int xfmajor, xfminor;
|
||||||
|
if (XFixesQueryVersion(xfc->display, &xfmajor, &xfminor))
|
||||||
|
{
|
||||||
|
DEBUG_X11_CLIPRDR("Found X Fixes extension version %d.%d", xfmajor, xfminor);
|
||||||
|
XFixesSelectSelectionInput(xfc->display, cb->root_window,
|
||||||
|
cb->clipboard_atom, XFixesSetSelectionOwnerNotifyMask);
|
||||||
|
cb->xfixes_supported = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: Error querying X Fixes extension version\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: Error loading X Fixes extension\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Warning: Using clipboard redirection without XFIXES extension is strongly discouraged!\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "_FREERDP_RAW", FALSE);
|
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "_FREERDP_RAW", FALSE);
|
||||||
cb->format_mappings[n].format_id = CB_FORMAT_RAW;
|
cb->format_mappings[n].format_id = CB_FORMAT_RAW;
|
||||||
@ -718,8 +751,11 @@ static void xf_cliprdr_process_requested_data(xfContext* xfc, BOOL has_data, BYT
|
|||||||
else
|
else
|
||||||
xf_cliprdr_send_null_data_response(xfc);
|
xf_cliprdr_send_null_data_response(xfc);
|
||||||
|
|
||||||
/* Resend the format list, otherwise the server won't request again for the next paste */
|
if (!cb->xfixes_supported)
|
||||||
xf_cliprdr_send_format_list(xfc);
|
{
|
||||||
|
/* Resend the format list, otherwise the server won't request again for the next paste */
|
||||||
|
xf_cliprdr_send_format_list(xfc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL xf_cliprdr_get_requested_data(xfContext* xfc, Atom target)
|
static BOOL xf_cliprdr_get_requested_data(xfContext* xfc, Atom target)
|
||||||
@ -1077,7 +1113,7 @@ void xf_process_cliprdr_event(xfContext* xfc, wMessage* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent)
|
static BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent)
|
||||||
{
|
{
|
||||||
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
||||||
|
|
||||||
@ -1101,7 +1137,7 @@ BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent)
|
static BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int fmt;
|
int fmt;
|
||||||
@ -1218,7 +1254,7 @@ BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent)
|
static BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent)
|
||||||
{
|
{
|
||||||
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
||||||
|
|
||||||
@ -1230,7 +1266,7 @@ BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent)
|
static BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent)
|
||||||
{
|
{
|
||||||
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
||||||
|
|
||||||
@ -1257,7 +1293,7 @@ BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_cliprdr_check_owner(xfContext* xfc)
|
static void xf_cliprdr_check_owner(xfContext* xfc)
|
||||||
{
|
{
|
||||||
Window owner;
|
Window owner;
|
||||||
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
clipboardContext* cb = (clipboardContext*) xfc->clipboard_context;
|
||||||
@ -1274,3 +1310,53 @@ void xf_cliprdr_check_owner(xfContext* xfc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event)
|
||||||
|
{
|
||||||
|
clipboardContext* cb;
|
||||||
|
|
||||||
|
if (!xfc || !event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!(cb = (clipboardContext*) xfc->clipboard_context))
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef WITH_XFIXES
|
||||||
|
if (cb->xfixes_supported && event->type == XFixesSelectionNotify + cb->xfixes_event_base)
|
||||||
|
{
|
||||||
|
XFixesSelectionNotifyEvent* se = (XFixesSelectionNotifyEvent*) event;
|
||||||
|
if (se->subtype == XFixesSetSelectionOwnerNotify)
|
||||||
|
{
|
||||||
|
if (se->selection != cb->clipboard_atom)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (XGetSelectionOwner(xfc->display, se->selection) == xfc->drawable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cb->owner = None;
|
||||||
|
xf_cliprdr_check_owner(xfc);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
switch (event->type)
|
||||||
|
{
|
||||||
|
case SelectionNotify:
|
||||||
|
xf_cliprdr_process_selection_notify(xfc, event);
|
||||||
|
break;
|
||||||
|
case SelectionRequest:
|
||||||
|
xf_cliprdr_process_selection_request(xfc, event);
|
||||||
|
break;
|
||||||
|
case SelectionClear:
|
||||||
|
xf_cliprdr_process_selection_clear(xfc, event);
|
||||||
|
break;
|
||||||
|
case PropertyNotify:
|
||||||
|
xf_cliprdr_process_property_notify(xfc, event);
|
||||||
|
break;
|
||||||
|
case FocusIn:
|
||||||
|
if (!cb->xfixes_supported)
|
||||||
|
{
|
||||||
|
xf_cliprdr_check_owner(xfc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,10 +26,5 @@
|
|||||||
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels);
|
void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels);
|
||||||
void xf_cliprdr_uninit(xfContext* xfc);
|
void xf_cliprdr_uninit(xfContext* xfc);
|
||||||
void xf_process_cliprdr_event(xfContext* xfc, wMessage* event);
|
void xf_process_cliprdr_event(xfContext* xfc, wMessage* event);
|
||||||
BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent);
|
void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event);
|
||||||
BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent);
|
|
||||||
BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent);
|
|
||||||
BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent);
|
|
||||||
void xf_cliprdr_check_owner(xfContext* xfc);
|
|
||||||
|
|
||||||
#endif /* __XF_CLIPRDR_H */
|
#endif /* __XF_CLIPRDR_H */
|
||||||
|
@ -545,9 +545,6 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
|
|
||||||
xf_keyboard_focus_in(xfc);
|
xf_keyboard_focus_in(xfc);
|
||||||
|
|
||||||
if (!app)
|
|
||||||
xf_cliprdr_check_owner(xfc);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -793,39 +790,6 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL xf_event_SelectionNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|
||||||
{
|
|
||||||
if (!app)
|
|
||||||
{
|
|
||||||
if (xf_cliprdr_process_selection_notify(xfc, event))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL xf_event_SelectionRequest(xfContext* xfc, XEvent* event, BOOL app)
|
|
||||||
{
|
|
||||||
if (!app)
|
|
||||||
{
|
|
||||||
if (xf_cliprdr_process_selection_request(xfc, event))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL xf_event_SelectionClear(xfContext* xfc, XEvent* event, BOOL app)
|
|
||||||
{
|
|
||||||
if (!app)
|
|
||||||
{
|
|
||||||
if (xf_cliprdr_process_selection_clear(xfc, event))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
|
static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -922,11 +886,6 @@ static BOOL xf_event_PropertyNotify(xfContext* xfc, XEvent* event, BOOL app)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (xf_cliprdr_process_property_notify(xfc, event))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1112,24 +1071,17 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
|||||||
status = xf_event_ClientMessage(xfc, event, xfc->remote_app);
|
status = xf_event_ClientMessage(xfc, event, xfc->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SelectionNotify:
|
|
||||||
status = xf_event_SelectionNotify(xfc, event, xfc->remote_app);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionRequest:
|
|
||||||
status = xf_event_SelectionRequest(xfc, event, xfc->remote_app);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SelectionClear:
|
|
||||||
status = xf_event_SelectionClear(xfc, event, xfc->remote_app);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
|
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!xfc->remote_app)
|
||||||
|
{
|
||||||
|
xf_cliprdr_handle_xevent(xfc, event);
|
||||||
|
}
|
||||||
|
|
||||||
xf_input_handle_event(xfc, event);
|
xf_input_handle_event(xfc, event);
|
||||||
|
|
||||||
XSync(xfc->display, FALSE);
|
XSync(xfc->display, FALSE);
|
||||||
|
Loading…
Reference in New Issue
Block a user