x11: Wrap platform functions in XWindowsClipboard class

This commit is contained in:
Monika Kairaityte 2018-11-10 11:53:23 +02:00 committed by Adrian Lucrèce Céleste
parent ce3e8243a9
commit 624a718f2d
6 changed files with 81 additions and 38 deletions

View File

@ -197,4 +197,10 @@ public:
virtual int XFree(void* data) = 0; virtual int XFree(void* data) = 0;
virtual Status DPMSEnable(Display* display) = 0; virtual Status DPMSEnable(Display* display) = 0;
virtual Status DPMSDisable(Display* display) = 0; virtual Status DPMSDisable(Display* display) = 0;
virtual int XSetSelectionOwner(Display* display, Atom selection, Window w,
Time time) = 0;
virtual Window XGetSelectionOwner(Display* display, Atom selection) = 0;
virtual Atom* XListProperties(Display* display, Window w,
int* num_prop_return) = 0;
virtual char* XGetAtomName(Display* display, Atom atom) = 0;
}; };

View File

@ -38,7 +38,7 @@
// XWindowsClipboard // XWindowsClipboard
// //
XWindowsClipboard::XWindowsClipboard(Display* display, XWindowsClipboard::XWindowsClipboard(IXWindowsImpl* impl, Display* display,
Window window, ClipboardID id) : Window window, ClipboardID id) :
m_display(display), m_display(display),
m_window(window), m_window(window),
@ -49,25 +49,30 @@ XWindowsClipboard::XWindowsClipboard(Display* display,
m_timeOwned(0), m_timeOwned(0),
m_timeLost(0) m_timeLost(0)
{ {
m_impl = impl;
// get some atoms // get some atoms
m_atomTargets = XInternAtom(m_display, "TARGETS", False); m_atomTargets = m_impl->XInternAtom(m_display, "TARGETS", False);
m_atomMultiple = XInternAtom(m_display, "MULTIPLE", False); m_atomMultiple = m_impl->XInternAtom(m_display, "MULTIPLE", False);
m_atomTimestamp = XInternAtom(m_display, "TIMESTAMP", False); m_atomTimestamp = m_impl->XInternAtom(m_display, "TIMESTAMP", False);
m_atomInteger = XInternAtom(m_display, "INTEGER", False); m_atomInteger = m_impl->XInternAtom(m_display, "INTEGER", False);
m_atomAtom = XInternAtom(m_display, "ATOM", False); m_atomAtom = m_impl->XInternAtom(m_display, "ATOM", False);
m_atomAtomPair = XInternAtom(m_display, "ATOM_PAIR", False); m_atomAtomPair = m_impl->XInternAtom(m_display, "ATOM_PAIR", False);
m_atomData = XInternAtom(m_display, "CLIP_TEMPORARY", False); m_atomData = m_impl->XInternAtom(m_display, "CLIP_TEMPORARY",
m_atomINCR = XInternAtom(m_display, "INCR", False); False);
m_atomMotifClipLock = XInternAtom(m_display, "_MOTIF_CLIP_LOCK", False); m_atomINCR = m_impl->XInternAtom(m_display, "INCR", False);
m_atomMotifClipHeader = XInternAtom(m_display, "_MOTIF_CLIP_HEADER", False); m_atomMotifClipLock = m_impl->XInternAtom(m_display, "_MOTIF_CLIP_LOCK",
m_atomMotifClipAccess = XInternAtom(m_display, False);
m_atomMotifClipHeader = m_impl->XInternAtom(m_display, "_MOTIF_CLIP_HEADER",
False);
m_atomMotifClipAccess = m_impl->XInternAtom(m_display,
"_MOTIF_CLIP_LOCK_ACCESS_VALID", False); "_MOTIF_CLIP_LOCK_ACCESS_VALID", False);
m_atomGDKSelection = XInternAtom(m_display, "GDK_SELECTION", False); m_atomGDKSelection = m_impl->XInternAtom(m_display, "GDK_SELECTION",
False);
// set selection atom based on clipboard id // set selection atom based on clipboard id
switch (id) { switch (id) {
case kClipboardClipboard: case kClipboardClipboard:
m_selection = XInternAtom(m_display, "CLIPBOARD", False); m_selection = m_impl->XInternAtom(m_display, "CLIPBOARD", False);
break; break;
case kClipboardSelection: case kClipboardSelection:
@ -273,8 +278,8 @@ XWindowsClipboard::empty()
LOG((CLOG_DEBUG "empty clipboard %d", m_id)); LOG((CLOG_DEBUG "empty clipboard %d", m_id));
// assert ownership of clipboard // assert ownership of clipboard
XSetSelectionOwner(m_display, m_selection, m_window, m_time); m_impl->XSetSelectionOwner(m_display, m_selection, m_window, m_time);
if (XGetSelectionOwner(m_display, m_selection) != m_window) { if (m_impl->XGetSelectionOwner(m_display, m_selection) != m_window) {
LOG((CLOG_DEBUG "failed to grab clipboard %d", m_id)); LOG((CLOG_DEBUG "failed to grab clipboard %d", m_id));
return false; return false;
} }
@ -610,7 +615,7 @@ bool
XWindowsClipboard::motifLockClipboard() const XWindowsClipboard::motifLockClipboard() const
{ {
// fail if anybody owns the lock (even us, so this is non-recursive) // fail if anybody owns the lock (even us, so this is non-recursive)
Window lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock); Window lockOwner = m_impl->XGetSelectionOwner(m_display, m_atomMotifClipLock);
if (lockOwner != None) { if (lockOwner != None) {
LOG((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner)); LOG((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner));
return false; return false;
@ -621,8 +626,8 @@ XWindowsClipboard::motifLockClipboard() const
// A grabs successfully, B grabs successfully, A thinks it // A grabs successfully, B grabs successfully, A thinks it
// still has the grab until it gets a SelectionClear. // still has the grab until it gets a SelectionClear.
Time time = XWindowsUtil::getCurrentTime(m_display, m_window); Time time = XWindowsUtil::getCurrentTime(m_display, m_window);
XSetSelectionOwner(m_display, m_atomMotifClipLock, m_window, time); m_impl->XSetSelectionOwner(m_display, m_atomMotifClipLock, m_window, time);
lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock); lockOwner = m_impl->XGetSelectionOwner(m_display, m_atomMotifClipLock);
if (lockOwner != m_window) { if (lockOwner != m_window) {
LOG((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner)); LOG((CLOG_DEBUG1 "motif lock owner 0x%08x", lockOwner));
return false; return false;
@ -638,14 +643,14 @@ XWindowsClipboard::motifUnlockClipboard() const
LOG((CLOG_DEBUG1 "unlocked motif clipboard")); LOG((CLOG_DEBUG1 "unlocked motif clipboard"));
// fail if we don't own the lock // fail if we don't own the lock
Window lockOwner = XGetSelectionOwner(m_display, m_atomMotifClipLock); Window lockOwner = m_impl->XGetSelectionOwner(m_display, m_atomMotifClipLock);
if (lockOwner != m_window) { if (lockOwner != m_window) {
return; return;
} }
// release lock // release lock
Time time = XWindowsUtil::getCurrentTime(m_display, m_window); Time time = XWindowsUtil::getCurrentTime(m_display, m_window);
XSetSelectionOwner(m_display, m_atomMotifClipLock, None, time); m_impl->XSetSelectionOwner(m_display, m_atomMotifClipLock, None, time);
} }
bool bool
@ -655,7 +660,7 @@ XWindowsClipboard::motifOwnsClipboard() const
// FIXME -- this can't be right. even if the window is destroyed // FIXME -- this can't be right. even if the window is destroyed
// Motif will still have a valid clipboard. how can we tell if // Motif will still have a valid clipboard. how can we tell if
// some other client owns CLIPBOARD? // some other client owns CLIPBOARD?
Window owner = XGetSelectionOwner(m_display, m_selection); Window owner = m_impl->XGetSelectionOwner(m_display, m_selection);
if (owner == None) { if (owner == None) {
return false; return false;
} }
@ -712,7 +717,7 @@ XWindowsClipboard::motifFillCache()
// get the Motif item property from the root window // get the Motif item property from the root window
char name[18 + 20]; char name[18 + 20];
sprintf(name, "_MOTIF_CLIP_ITEM_%d", header.m_item); sprintf(name, "_MOTIF_CLIP_ITEM_%d", header.m_item);
Atom atomItem = XInternAtom(m_display, name, False); Atom atomItem = m_impl->XInternAtom(m_display, name, False);
data = ""; data = "";
if (!XWindowsUtil::getWindowProperty(m_display, root, if (!XWindowsUtil::getWindowProperty(m_display, root,
atomItem, &data, atomItem, &data,
@ -741,7 +746,7 @@ XWindowsClipboard::motifFillCache()
for (SInt32 i = 0; i < numFormats; ++i) { for (SInt32 i = 0; i < numFormats; ++i) {
// get Motif format property from the root window // get Motif format property from the root window
sprintf(name, "_MOTIF_CLIP_ITEM_%d", formats[i]); sprintf(name, "_MOTIF_CLIP_ITEM_%d", formats[i]);
Atom atomFormat = XInternAtom(m_display, name, False); Atom atomFormat = m_impl->XInternAtom(m_display, name, False);
String data; String data;
if (!XWindowsUtil::getWindowProperty(m_display, root, if (!XWindowsUtil::getWindowProperty(m_display, root,
atomFormat, &data, atomFormat, &data,
@ -824,7 +829,7 @@ XWindowsClipboard::motifGetSelection(const MotifClipFormat* format,
// part that i don't know. // part that i don't know.
char name[18 + 20]; char name[18 + 20];
sprintf(name, "_MOTIF_CLIP_ITEM_%d", format->m_data); sprintf(name, "_MOTIF_CLIP_ITEM_%d", format->m_data);
Atom target = XInternAtom(m_display, name, False); Atom target = m_impl->XInternAtom(m_display, name, False);
Window root = RootWindow(m_display, DefaultScreen(m_display)); Window root = RootWindow(m_display, DefaultScreen(m_display));
return XWindowsUtil::getWindowProperty(m_display, root, return XWindowsUtil::getWindowProperty(m_display, root,
target, data, target, data,
@ -919,11 +924,11 @@ XWindowsClipboard::insertReply(Reply* reply)
// get and save the current event mask // get and save the current event mask
XWindowAttributes attr; XWindowAttributes attr;
XGetWindowAttributes(m_display, reply->m_requestor, &attr); m_impl->XGetWindowAttributes(m_display, reply->m_requestor, &attr);
m_eventMasks[reply->m_requestor] = attr.your_event_mask; m_eventMasks[reply->m_requestor] = attr.your_event_mask;
// add the events we want // add the events we want
XSelectInput(m_display, reply->m_requestor, attr.your_event_mask | m_impl->XSelectInput(m_display, reply->m_requestor, attr.your_event_mask |
StructureNotifyMask | PropertyChangeMask); StructureNotifyMask | PropertyChangeMask);
} }
@ -979,7 +984,7 @@ XWindowsClipboard::pushReplies(ReplyMap::iterator& mapIndex,
if (replies.empty()) { if (replies.empty()) {
XWindowsUtil::ErrorLock lock(m_display); XWindowsUtil::ErrorLock lock(m_display);
Window requestor = mapIndex->first; Window requestor = mapIndex->first;
XSelectInput(m_display, requestor, m_eventMasks[requestor]); m_impl->XSelectInput(m_display, requestor, m_eventMasks[requestor]);
m_replies.erase(mapIndex++); m_replies.erase(mapIndex++);
m_eventMasks.erase(requestor); m_eventMasks.erase(requestor);
} }
@ -1055,7 +1060,7 @@ XWindowsClipboard::sendReply(Reply* reply)
reply->m_done = true; reply->m_done = true;
if (reply->m_property != None) { if (reply->m_property != None) {
XWindowsUtil::ErrorLock lock(m_display); XWindowsUtil::ErrorLock lock(m_display);
XDeleteProperty(m_display, reply->m_requestor, reply->m_property); m_impl->XDeleteProperty(m_display, reply->m_requestor, reply->m_property);
} }
if (!reply->m_replied) { if (!reply->m_replied) {
@ -1091,12 +1096,13 @@ XWindowsClipboard::sendReply(Reply* reply)
if (CLOG->getFilter() >= kDEBUG2) { if (CLOG->getFilter() >= kDEBUG2) {
XWindowsUtil::ErrorLock lock(m_display); XWindowsUtil::ErrorLock lock(m_display);
int n; int n;
Atom* props = XListProperties(m_display, reply->m_requestor, &n); Atom* props = m_impl->XListProperties(m_display, reply->m_requestor,
&n);
LOG((CLOG_DEBUG2 "properties of 0x%08x:", reply->m_requestor)); LOG((CLOG_DEBUG2 "properties of 0x%08x:", reply->m_requestor));
for (int i = 0; i < n; ++i) { for (int i = 0; i < n; ++i) {
Atom target; Atom target;
String data; String data;
char* name = XGetAtomName(m_display, props[i]); char* name = m_impl->XGetAtomName(m_display, props[i]);
if (!XWindowsUtil::getWindowProperty(m_display, if (!XWindowsUtil::getWindowProperty(m_display,
reply->m_requestor, reply->m_requestor,
props[i], &data, &target, NULL, False)) { props[i], &data, &target, NULL, False)) {
@ -1120,18 +1126,18 @@ XWindowsClipboard::sendReply(Reply* reply)
break; break;
} }
} }
char* type = XGetAtomName(m_display, target); char* type = m_impl->XGetAtomName(m_display, target);
LOG((CLOG_DEBUG2 " %s (%s): %s", name, type, data.c_str())); LOG((CLOG_DEBUG2 " %s (%s): %s", name, type, data.c_str()));
if (type != NULL) { if (type != NULL) {
XFree(type); m_impl->XFree(type);
} }
} }
if (name != NULL) { if (name != NULL) {
XFree(name); m_impl->XFree(name);
} }
} }
if (props != NULL) { if (props != NULL) {
XFree(props); m_impl->XFree(props);
} }
} }
@ -1178,7 +1184,7 @@ XWindowsClipboard::sendNotify(Window requestor,
event.xselection.property = property; event.xselection.property = property;
event.xselection.time = time; event.xselection.time = time;
XWindowsUtil::ErrorLock lock(m_display); XWindowsUtil::ErrorLock lock(m_display);
XSendEvent(m_display, requestor, False, 0, &event); m_impl->XSendEvent(m_display, requestor, False, 0, &event);
} }
bool bool

View File

@ -23,6 +23,7 @@
#include "common/stdmap.h" #include "common/stdmap.h"
#include "common/stdlist.h" #include "common/stdlist.h"
#include "common/stdvector.h" #include "common/stdvector.h"
#include "XWindowsImpl.h"
#if X_DISPLAY_MISSING #if X_DISPLAY_MISSING
# error X11 is required to build barrier # error X11 is required to build barrier
@ -39,7 +40,8 @@ public:
Use \c window as the window that owns or interacts with the Use \c window as the window that owns or interacts with the
clipboard identified by \c id. clipboard identified by \c id.
*/ */
XWindowsClipboard(Display*, Window window, ClipboardID id); XWindowsClipboard(IXWindowsImpl* impl, Display*, Window window,
ClipboardID id);
virtual ~XWindowsClipboard(); virtual ~XWindowsClipboard();
//! Notify clipboard was lost //! Notify clipboard was lost
@ -284,6 +286,7 @@ private:
private: private:
typedef std::vector<IXWindowsClipboardConverter*> ConverterList; typedef std::vector<IXWindowsClipboardConverter*> ConverterList;
IXWindowsImpl* m_impl;
Display* m_display; Display* m_display;
Window m_window; Window m_window;

View File

@ -528,3 +528,25 @@ Status XWindowsImpl::DPMSDisable(Display* display)
{ {
return ::DPMSDisable(display); return ::DPMSDisable(display);
} }
int XWindowsImpl::XSetSelectionOwner(Display* display, Atom selection, Window w,
Time time)
{
return ::XSetSelectionOwner(display, selection, w, time);
}
Window XWindowsImpl::XGetSelectionOwner(Display* display, Atom selection)
{
return ::XGetSelectionOwner(display, selection);
}
Atom* XWindowsImpl::XListProperties(Display* display, Window w,
int* num_prop_return)
{
return ::XListProperties(display, w, num_prop_return);
}
char* XWindowsImpl::XGetAtomName(Display* display, Atom atom)
{
return ::XGetAtomName(display, atom);
}

View File

@ -159,4 +159,10 @@ public:
virtual int XFree(void* data); virtual int XFree(void* data);
virtual Status DPMSEnable(Display* display); virtual Status DPMSEnable(Display* display);
virtual Status DPMSDisable(Display* display); virtual Status DPMSDisable(Display* display);
virtual int XSetSelectionOwner(Display* display, Atom selection, Window w,
Time time);
virtual Window XGetSelectionOwner(Display* display, Atom selection);
virtual Atom* XListProperties(Display* display, Window w,
int* num_prop_return);
virtual char* XGetAtomName(Display* display, Atom atom);
}; };

View File

@ -150,7 +150,7 @@ XWindowsScreen::XWindowsScreen(
// initialize the clipboards // initialize the clipboards
for (ClipboardID id = 0; id < kClipboardEnd; ++id) { for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
m_clipboard[id] = new XWindowsClipboard(m_display, m_window, id); m_clipboard[id] = new XWindowsClipboard(m_impl, m_display, m_window, id);
} }
// install event handlers // install event handlers