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_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(Xinerama ${XINERAMA_FEATURE_TYPE} ${XINERAMA_FEATURE_PURPOSE} ${XINERAMA_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(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_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)
|
||||
add_definitions(-DWITH_XINERAMA)
|
||||
@ -192,6 +197,12 @@ if(WITH_XRENDER)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES})
|
||||
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)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client)
|
||||
|
@ -25,6 +25,10 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
#ifdef WITH_XFIXES
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
@ -88,6 +92,11 @@ struct clipboard_context
|
||||
BOOL incr_starts;
|
||||
BYTE* incr_data;
|
||||
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)
|
||||
@ -121,6 +130,30 @@ void xf_cliprdr_init(xfContext* xfc, rdpChannels* channels)
|
||||
|
||||
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;
|
||||
cb->format_mappings[n].target_format = XInternAtom(xfc->display, "_FREERDP_RAW", FALSE);
|
||||
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
|
||||
xf_cliprdr_send_null_data_response(xfc);
|
||||
|
||||
/* Resend the format list, otherwise the server won't request again for the next paste */
|
||||
xf_cliprdr_send_format_list(xfc);
|
||||
if (!cb->xfixes_supported)
|
||||
{
|
||||
/* 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)
|
||||
@ -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;
|
||||
|
||||
@ -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 fmt;
|
||||
@ -1218,7 +1254,7 @@ BOOL xf_cliprdr_process_selection_request(xfContext* xfc, XEvent* xevent)
|
||||
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;
|
||||
|
||||
@ -1230,7 +1266,7 @@ BOOL xf_cliprdr_process_selection_clear(xfContext* xfc, XEvent* xevent)
|
||||
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;
|
||||
|
||||
@ -1257,7 +1293,7 @@ BOOL xf_cliprdr_process_property_notify(xfContext* xfc, XEvent* xevent)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void xf_cliprdr_check_owner(xfContext* xfc)
|
||||
static void xf_cliprdr_check_owner(xfContext* xfc)
|
||||
{
|
||||
Window owner;
|
||||
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_uninit(xfContext* xfc);
|
||||
void xf_process_cliprdr_event(xfContext* xfc, wMessage* event);
|
||||
BOOL xf_cliprdr_process_selection_notify(xfContext* xfc, XEvent* xevent);
|
||||
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);
|
||||
|
||||
void xf_cliprdr_handle_xevent(xfContext* xfc, XEvent* event);
|
||||
#endif /* __XF_CLIPRDR_H */
|
||||
|
@ -545,9 +545,6 @@ static BOOL xf_event_FocusIn(xfContext* xfc, XEvent* event, BOOL app)
|
||||
|
||||
xf_keyboard_focus_in(xfc);
|
||||
|
||||
if (!app)
|
||||
xf_cliprdr_check_owner(xfc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -793,39 +790,6 @@ static BOOL xf_event_UnmapNotify(xfContext* xfc, XEvent* event, BOOL app)
|
||||
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)
|
||||
{
|
||||
/*
|
||||
@ -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;
|
||||
}
|
||||
@ -1112,24 +1071,17 @@ BOOL xf_event_process(freerdp* instance, XEvent* event)
|
||||
status = xf_event_ClientMessage(xfc, event, xfc->remote_app);
|
||||
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:
|
||||
status = xf_event_PropertyNotify(xfc, event, xfc->remote_app);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (!xfc->remote_app)
|
||||
{
|
||||
xf_cliprdr_handle_xevent(xfc, event);
|
||||
}
|
||||
|
||||
xf_input_handle_event(xfc, event);
|
||||
|
||||
XSync(xfc->display, FALSE);
|
||||
|
Loading…
Reference in New Issue
Block a user