forked from Mirrorlandia_minetest/irrlicht
Implement X11 primary selection
This commit is contained in:
parent
1967d71cfb
commit
53b9eaa831
@ -26,12 +26,23 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//! Copies text to the clipboard
|
//! Copies text to the clipboard
|
||||||
|
//! \param text: text in utf-8
|
||||||
virtual void copyToClipboard(const c8* text) const = 0;
|
virtual void copyToClipboard(const c8* text) const = 0;
|
||||||
|
|
||||||
|
//! Copies text to the primary selection
|
||||||
|
//! This is a no-op on some platforms.
|
||||||
|
//! \param text: text in utf-8
|
||||||
|
virtual void copyToPrimarySelection(const c8* text) const = 0;
|
||||||
|
|
||||||
//! Get text from the clipboard
|
//! Get text from the clipboard
|
||||||
/** \return Returns 0 if no string is in there. */
|
//! \return Returns 0 if no string is in there, otherwise an utf-8 string.
|
||||||
virtual const c8* getTextFromClipboard() const = 0;
|
virtual const c8* getTextFromClipboard() const = 0;
|
||||||
|
|
||||||
|
//! Get text from the primary selection
|
||||||
|
//! This is a no-op on some platforms.
|
||||||
|
//! \return Returns 0 if no string is in there, otherwise an utf-8 string.
|
||||||
|
virtual const c8* getTextFromPrimarySelection() const = 0;
|
||||||
|
|
||||||
//! Get the total and available system RAM
|
//! Get the total and available system RAM
|
||||||
/** \param totalBytes: will contain the total system memory in Kilobytes (1024 B)
|
/** \param totalBytes: will contain the total system memory in Kilobytes (1024 B)
|
||||||
\param availableBytes: will contain the available memory in Kilobytes (1024 B)
|
\param availableBytes: will contain the available memory in Kilobytes (1024 B)
|
||||||
|
@ -1000,12 +1000,15 @@ bool CIrrDeviceLinux::run()
|
|||||||
send_response(req->property);
|
send_response(req->property);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (req->selection != X_ATOM_CLIPBOARD ||
|
if ((req->selection != X_ATOM_CLIPBOARD &&
|
||||||
|
req->selection != XA_PRIMARY) ||
|
||||||
req->owner != XWindow) {
|
req->owner != XWindow) {
|
||||||
// we are not the owner, refuse request
|
// we are not the owner, refuse request
|
||||||
send_response_refuse();
|
send_response_refuse();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const core::stringc &text_buffer = req->selection == X_ATOM_CLIPBOARD ?
|
||||||
|
Clipboard : PrimarySelection;
|
||||||
|
|
||||||
// for debugging:
|
// for debugging:
|
||||||
//~ {
|
//~ {
|
||||||
@ -1026,8 +1029,8 @@ bool CIrrDeviceLinux::run()
|
|||||||
req->target, X_ATOM_UTF8_STRING,
|
req->target, X_ATOM_UTF8_STRING,
|
||||||
8, // format = 8-bit
|
8, // format = 8-bit
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(unsigned char *)Clipboard.c_str(),
|
(unsigned char *)text_buffer.c_str(),
|
||||||
Clipboard.size());
|
text_buffer.size());
|
||||||
send_response(req->target);
|
send_response(req->target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1052,8 +1055,8 @@ bool CIrrDeviceLinux::run()
|
|||||||
set_property_and_notify(
|
set_property_and_notify(
|
||||||
X_ATOM_UTF8_STRING,
|
X_ATOM_UTF8_STRING,
|
||||||
8,
|
8,
|
||||||
Clipboard.c_str(),
|
text_buffer.c_str(),
|
||||||
Clipboard.size()
|
text_buffer.size()
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1676,47 +1679,49 @@ void CIrrDeviceLinux::pollJoysticks()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
//! gets text from the clipboard
|
//! gets text from the clipboard
|
||||||
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
const c8 *CIrrDeviceLinux::getTextFromClipboard() const
|
const c8 *CIrrDeviceLinux::getTextFromSelection(Atom selection, core::stringc &text_buffer) const
|
||||||
{
|
{
|
||||||
#if defined(_IRR_COMPILE_WITH_X11_)
|
Window ownerWindow = XGetSelectionOwner(XDisplay, selection);
|
||||||
Window ownerWindow = XGetSelectionOwner(XDisplay, X_ATOM_CLIPBOARD);
|
|
||||||
if (ownerWindow == XWindow) {
|
if (ownerWindow == XWindow) {
|
||||||
return Clipboard.c_str();
|
return text_buffer.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
Clipboard = "";
|
text_buffer = "";
|
||||||
|
|
||||||
if (ownerWindow == None) {
|
if (ownerWindow == None) {
|
||||||
return Clipboard.c_str();
|
return text_buffer.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the property to be set beforehand
|
// delete the property to be set beforehand
|
||||||
XDeleteProperty(XDisplay, XWindow, XA_PRIMARY);
|
XDeleteProperty(XDisplay, XWindow, XA_PRIMARY);
|
||||||
|
|
||||||
XConvertSelection(XDisplay, X_ATOM_CLIPBOARD, X_ATOM_UTF8_STRING, XA_PRIMARY,
|
XConvertSelection(XDisplay, selection, X_ATOM_UTF8_STRING, XA_PRIMARY,
|
||||||
XWindow, CurrentTime);
|
XWindow, CurrentTime);
|
||||||
XFlush(XDisplay);
|
XFlush(XDisplay);
|
||||||
|
|
||||||
// wait for event via a blocking call
|
// wait for event via a blocking call
|
||||||
XEvent event_ret;
|
XEvent event_ret;
|
||||||
|
std::pair<Window, Atom> args(XWindow, selection);
|
||||||
XIfEvent(XDisplay, &event_ret, [](Display *_display, XEvent *event, XPointer arg) {
|
XIfEvent(XDisplay, &event_ret, [](Display *_display, XEvent *event, XPointer arg) {
|
||||||
|
auto p = reinterpret_cast<std::pair<Window, Atom> *>(arg);
|
||||||
return (Bool) (event->type == SelectionNotify &&
|
return (Bool) (event->type == SelectionNotify &&
|
||||||
event->xselection.requestor == *(Window *)arg &&
|
event->xselection.requestor == p->first &&
|
||||||
event->xselection.selection == X_ATOM_CLIPBOARD &&
|
event->xselection.selection == p->second &&
|
||||||
event->xselection.target == X_ATOM_UTF8_STRING);
|
event->xselection.target == X_ATOM_UTF8_STRING);
|
||||||
}, (XPointer)&XWindow);
|
}, (XPointer)&args);
|
||||||
|
|
||||||
_IRR_DEBUG_BREAK_IF(!(event_ret.type == SelectionNotify &&
|
_IRR_DEBUG_BREAK_IF(!(event_ret.type == SelectionNotify &&
|
||||||
event_ret.xselection.requestor == XWindow &&
|
event_ret.xselection.requestor == XWindow &&
|
||||||
event_ret.xselection.selection == X_ATOM_CLIPBOARD &&
|
event_ret.xselection.selection == selection &&
|
||||||
event_ret.xselection.target == X_ATOM_UTF8_STRING));
|
event_ret.xselection.target == X_ATOM_UTF8_STRING));
|
||||||
|
|
||||||
Atom property_set = event_ret.xselection.property;
|
Atom property_set = event_ret.xselection.property;
|
||||||
if (event_ret.xselection.property == None) {
|
if (event_ret.xselection.property == None) {
|
||||||
// request failed => empty string
|
// request failed => empty string
|
||||||
return Clipboard.c_str();
|
return text_buffer.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for data
|
// check for data
|
||||||
@ -1743,15 +1748,15 @@ const c8 *CIrrDeviceLinux::getTextFromClipboard() const
|
|||||||
// for debugging:
|
// for debugging:
|
||||||
//~ {
|
//~ {
|
||||||
//~ char *type_name = XGetAtomName(XDisplay, type);
|
//~ char *type_name = XGetAtomName(XDisplay, type);
|
||||||
//~ fprintf(stderr, "CIrrDeviceLinux::getTextFromClipboard: actual type: %s (=%ld)\n",
|
//~ fprintf(stderr, "CIrrDeviceLinux::getTextFromSelection: actual type: %s (=%ld)\n",
|
||||||
//~ type_name, type);
|
//~ type_name, type);
|
||||||
//~ XFree(type_name);
|
//~ XFree(type_name);
|
||||||
//~ }
|
//~ }
|
||||||
|
|
||||||
if (type != X_ATOM_UTF8_STRING && type != X_ATOM_UTF8_MIME_TYPE) {
|
if (type != X_ATOM_UTF8_STRING && type != X_ATOM_UTF8_MIME_TYPE) {
|
||||||
os::Printer::log("CIrrDeviceLinux::getTextFromClipboard: did not get utf-8 string",
|
os::Printer::log("CIrrDeviceLinux::getTextFromSelection: did not get utf-8 string",
|
||||||
ELL_WARNING);
|
ELL_WARNING);
|
||||||
return Clipboard.c_str();
|
return text_buffer.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytesLeft > 0) {
|
if (bytesLeft > 0) {
|
||||||
@ -1760,20 +1765,49 @@ const c8 *CIrrDeviceLinux::getTextFromClipboard() const
|
|||||||
bytesLeft, 0, AnyPropertyType, &type, &format,
|
bytesLeft, 0, AnyPropertyType, &type, &format,
|
||||||
&numItems, &dummy, &data);
|
&numItems, &dummy, &data);
|
||||||
if (result == Success)
|
if (result == Success)
|
||||||
Clipboard = (irr::c8 *)data;
|
text_buffer = (irr::c8 *)data;
|
||||||
XFree (data);
|
XFree (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the property again, to inform the owner about the successful transfer
|
// delete the property again, to inform the owner about the successful transfer
|
||||||
XDeleteProperty(XDisplay, XWindow, property_set);
|
XDeleteProperty(XDisplay, XWindow, property_set);
|
||||||
|
|
||||||
return Clipboard.c_str();
|
return text_buffer.c_str();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//! gets text from the clipboard
|
||||||
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
|
const c8 *CIrrDeviceLinux::getTextFromClipboard() const
|
||||||
|
{
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
|
return getTextFromSelection(X_ATOM_CLIPBOARD, Clipboard);
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! gets text from the primary selection
|
||||||
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
|
const c8 *CIrrDeviceLinux::getTextFromPrimarySelection() const
|
||||||
|
{
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
|
return getTextFromSelection(XA_PRIMARY, PrimarySelection);
|
||||||
|
#else
|
||||||
|
return nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
|
bool CIrrDeviceLinux::becomeSelectionOwner(Atom selection) const
|
||||||
|
{
|
||||||
|
XSetSelectionOwner (XDisplay, selection, XWindow, CurrentTime);
|
||||||
|
XFlush (XDisplay);
|
||||||
|
Window owner = XGetSelectionOwner(XDisplay, selection);
|
||||||
|
return owner == XWindow;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//! copies text to the clipboard
|
//! copies text to the clipboard
|
||||||
void CIrrDeviceLinux::copyToClipboard(const c8 *text) const
|
void CIrrDeviceLinux::copyToClipboard(const c8 *text) const
|
||||||
{
|
{
|
||||||
@ -1781,15 +1815,23 @@ void CIrrDeviceLinux::copyToClipboard(const c8 *text) const
|
|||||||
// Actually there is no clipboard on X but applications just say they own the clipboard and return text when asked.
|
// Actually there is no clipboard on X but applications just say they own the clipboard and return text when asked.
|
||||||
// Which btw. also means that on X you lose clipboard content when closing applications.
|
// Which btw. also means that on X you lose clipboard content when closing applications.
|
||||||
Clipboard = text;
|
Clipboard = text;
|
||||||
XSetSelectionOwner (XDisplay, X_ATOM_CLIPBOARD, XWindow, CurrentTime);
|
if (!becomeSelectionOwner(X_ATOM_CLIPBOARD)) {
|
||||||
XFlush (XDisplay);
|
|
||||||
Window owner = XGetSelectionOwner(XDisplay, X_ATOM_CLIPBOARD);
|
|
||||||
if (owner != XWindow) {
|
|
||||||
os::Printer::log("CIrrDeviceLinux::copyToClipboard: failed to set owner", ELL_WARNING);
|
os::Printer::log("CIrrDeviceLinux::copyToClipboard: failed to set owner", ELL_WARNING);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! copies text to the primary selection
|
||||||
|
void CIrrDeviceLinux::copyToPrimarySelection(const c8 *text) const
|
||||||
|
{
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
|
PrimarySelection = text;
|
||||||
|
if (!becomeSelectionOwner(XA_PRIMARY)) {
|
||||||
|
os::Printer::log("CIrrDeviceLinux::copyToPrimarySelection: failed to set owner", ELL_WARNING);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _IRR_COMPILE_WITH_X11_
|
#ifdef _IRR_COMPILE_WITH_X11_
|
||||||
// return true if the passed event has the type passed in parameter arg
|
// return true if the passed event has the type passed in parameter arg
|
||||||
Bool PredicateIsEventType(Display *display, XEvent *event, XPointer arg)
|
Bool PredicateIsEventType(Display *display, XEvent *event, XPointer arg)
|
||||||
|
@ -97,11 +97,20 @@ namespace irr
|
|||||||
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
virtual const c8 *getTextFromClipboard() const;
|
virtual const c8 *getTextFromClipboard() const;
|
||||||
|
|
||||||
|
//! gets text from the primary selection
|
||||||
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
|
virtual const c8 *getTextFromPrimarySelection() const;
|
||||||
|
|
||||||
//! copies text to the clipboard
|
//! copies text to the clipboard
|
||||||
//! This sets the clipboard selection and _not_ the primary selection which you have on X on the middle mouse button.
|
//! This sets the clipboard selection and _not_ the primary selection.
|
||||||
//! @param text The text in utf-8
|
//! @param text The text in utf-8
|
||||||
virtual void copyToClipboard(const c8 *text) const;
|
virtual void copyToClipboard(const c8 *text) const;
|
||||||
|
|
||||||
|
//! copies text to the primary selection
|
||||||
|
//! This sets the primary selection which you have on X on the middle mouse button.
|
||||||
|
//! @param text The text in utf-8
|
||||||
|
virtual void copyToPrimarySelection(const c8 *text) const;
|
||||||
|
|
||||||
//! Remove all messages pending in the system message loop
|
//! Remove all messages pending in the system message loop
|
||||||
void clearSystemMessages() override;
|
void clearSystemMessages() override;
|
||||||
|
|
||||||
@ -141,6 +150,9 @@ namespace irr
|
|||||||
bool createInputContext();
|
bool createInputContext();
|
||||||
void destroyInputContext();
|
void destroyInputContext();
|
||||||
EKEY_CODE getKeyCode(XEvent &event);
|
EKEY_CODE getKeyCode(XEvent &event);
|
||||||
|
|
||||||
|
const c8 *getTextFromSelection(Atom selection, core::stringc &text_buffer) const;
|
||||||
|
bool becomeSelectionOwner(Atom selection) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Implementation of the linux cursor control
|
//! Implementation of the linux cursor control
|
||||||
@ -413,6 +425,7 @@ namespace irr
|
|||||||
bool HasNetWM;
|
bool HasNetWM;
|
||||||
// text is utf-8
|
// text is utf-8
|
||||||
mutable core::stringc Clipboard;
|
mutable core::stringc Clipboard;
|
||||||
|
mutable core::stringc PrimarySelection;
|
||||||
#endif
|
#endif
|
||||||
#if defined(_IRR_LINUX_X11_XINPUT2_)
|
#if defined(_IRR_LINUX_X11_XINPUT2_)
|
||||||
int currentTouchedCount;
|
int currentTouchedCount;
|
||||||
|
@ -54,7 +54,6 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const
|
|||||||
|
|
||||||
|
|
||||||
//! copies text to the clipboard
|
//! copies text to the clipboard
|
||||||
//! \param text: text in utf-8
|
|
||||||
void COSOperator::copyToClipboard(const c8 *text) const
|
void COSOperator::copyToClipboard(const c8 *text) const
|
||||||
{
|
{
|
||||||
if (strlen(text)==0)
|
if (strlen(text)==0)
|
||||||
@ -102,8 +101,20 @@ void COSOperator::copyToClipboard(const c8 *text) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! copies text to the primary selection
|
||||||
|
void COSOperator::copyToPrimarySelection(const c8 *text) const
|
||||||
|
{
|
||||||
|
if (strlen(text)==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||||
|
if ( IrrDeviceLinux )
|
||||||
|
IrrDeviceLinux->copyToPrimarySelection(text);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! gets text from the clipboard
|
//! gets text from the clipboard
|
||||||
//! \return Returns 0 if no string is in there, otherwise an utf-8 string.
|
|
||||||
const c8* COSOperator::getTextFromClipboard() const
|
const c8* COSOperator::getTextFromClipboard() const
|
||||||
{
|
{
|
||||||
#if defined(_IRR_WINDOWS_API_)
|
#if defined(_IRR_WINDOWS_API_)
|
||||||
@ -147,6 +158,21 @@ const c8* COSOperator::getTextFromClipboard() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! gets text from the primary selection
|
||||||
|
const c8* COSOperator::getTextFromPrimarySelection() const
|
||||||
|
{
|
||||||
|
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_)
|
||||||
|
if ( IrrDeviceLinux )
|
||||||
|
return IrrDeviceLinux->getTextFromPrimarySelection();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const
|
bool COSOperator::getSystemMemory(u32* Total, u32* Avail) const
|
||||||
{
|
{
|
||||||
#if defined(_IRR_WINDOWS_API_)
|
#if defined(_IRR_WINDOWS_API_)
|
||||||
|
@ -27,13 +27,17 @@ public:
|
|||||||
const core::stringc& getOperatingSystemVersion() const override;
|
const core::stringc& getOperatingSystemVersion() const override;
|
||||||
|
|
||||||
//! copies text to the clipboard
|
//! copies text to the clipboard
|
||||||
//! \param text: text in utf-8
|
|
||||||
void copyToClipboard(const c8 *text) const override;
|
void copyToClipboard(const c8 *text) const override;
|
||||||
|
|
||||||
|
//! copies text to the primary selection
|
||||||
|
void copyToPrimarySelection(const c8 *text) const override;
|
||||||
|
|
||||||
//! gets text from the clipboard
|
//! gets text from the clipboard
|
||||||
//! \return Returns 0 if no string is in there, otherwise an utf-8 string.
|
|
||||||
const c8* getTextFromClipboard() const override;
|
const c8* getTextFromClipboard() const override;
|
||||||
|
|
||||||
|
//! gets text from the primary selection
|
||||||
|
const c8* getTextFromPrimarySelection() const override;
|
||||||
|
|
||||||
//! gets the total and available system RAM in kB
|
//! gets the total and available system RAM in kB
|
||||||
//! \param Total: will contain the total system memory
|
//! \param Total: will contain the total system memory
|
||||||
//! \param Avail: will contain the available memory
|
//! \param Avail: will contain the available memory
|
||||||
|
Loading…
Reference in New Issue
Block a user