forked from Mirrorlandia_minetest/irrlicht
Fix X11 selections (#55)
This fixes all the issues with the X11 selection in addition to switching the clipboard to always be UTF-8.
This commit is contained in:
parent
75b4c05741
commit
9c4b6f25ab
@ -11,6 +11,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
@ -36,6 +37,7 @@ outside the string class for explicit use.
|
|||||||
template <typename T, typename TAlloc = irrAllocator<T> >
|
template <typename T, typename TAlloc = irrAllocator<T> >
|
||||||
class string;
|
class string;
|
||||||
static size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
|
static size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
|
||||||
|
static size_t wStringToMultibyte(string<c8>& destination, const wchar_t* source, u32 sourceSize);
|
||||||
inline s32 isdigit(s32 c);
|
inline s32 isdigit(s32 c);
|
||||||
|
|
||||||
enum eLocaleID
|
enum eLocaleID
|
||||||
@ -1424,6 +1426,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
friend size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
|
friend size_t multibyteToWString(string<wchar_t>& destination, const char* source, u32 sourceSize);
|
||||||
|
friend size_t wStringToMultibyte(string<c8>& destination, const wchar_t* source, u32 sourceSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -1517,6 +1520,53 @@ static size_t multibyteToWString(string<wchar_t>& destination, const char* sourc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Same as multibyteToWString, but the other way around
|
||||||
|
static inline size_t wStringToMultibyte(string<c8>& destination, const core::string<wchar_t>& source)
|
||||||
|
{
|
||||||
|
return wStringToMultibyte(destination, source.c_str(), (u32)source.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Same as multibyteToWString, but the other way around
|
||||||
|
static inline size_t wStringToMultibyte(string<c8>& destination, const wchar_t* source)
|
||||||
|
{
|
||||||
|
const u32 s = source ? (u32)wcslen(source) : 0;
|
||||||
|
return wStringToMultibyte(destination, source, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Same as multibyteToWString, but the other way around
|
||||||
|
static size_t wStringToMultibyte(string<c8>& destination, const wchar_t* source, u32 sourceSize)
|
||||||
|
{
|
||||||
|
if ( sourceSize )
|
||||||
|
{
|
||||||
|
destination.reserve(sourceSize+1);
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe. Consider using wcstombs_s instead.
|
||||||
|
#endif
|
||||||
|
const size_t written = wcstombs(destination.array, source, (size_t)sourceSize);
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
if ( written != (size_t)-1 )
|
||||||
|
{
|
||||||
|
destination.used = (u32)written+1;
|
||||||
|
destination.array[destination.used-1] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Likely character which got converted until the invalid character was encountered are in destination now.
|
||||||
|
// And it seems even 0-terminated, but I found no documentation anywhere that this (the 0-termination) is guaranteed :-(
|
||||||
|
destination.clear();
|
||||||
|
}
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destination.clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace core
|
} // end namespace core
|
||||||
} // end namespace irr
|
} // end namespace irr
|
||||||
|
@ -300,7 +300,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||||||
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
|
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
|
||||||
|
|
||||||
core::stringc s;
|
core::stringc s;
|
||||||
s = Text.subString(realmbgn, realmend - realmbgn).c_str();
|
wStringToMultibyte(s, Text.subString(realmbgn, realmend - realmbgn));
|
||||||
Operator->copyToClipboard(s.c_str());
|
Operator->copyToClipboard(s.c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -313,7 +313,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||||||
|
|
||||||
// copy
|
// copy
|
||||||
core::stringc sc;
|
core::stringc sc;
|
||||||
sc = Text.subString(realmbgn, realmend - realmbgn).c_str();
|
wStringToMultibyte(sc, Text.subString(realmbgn, realmend - realmbgn));
|
||||||
Operator->copyToClipboard(sc.c_str());
|
Operator->copyToClipboard(sc.c_str());
|
||||||
|
|
||||||
if (isEnabled())
|
if (isEnabled())
|
||||||
@ -341,8 +341,8 @@ bool CGUIEditBox::processKey(const SEvent& event)
|
|||||||
const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
|
const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
|
||||||
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
|
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
|
||||||
|
|
||||||
// add new character
|
// add the string
|
||||||
const c8* p = Operator->getTextFromClipboard();
|
const c8 *p = Operator->getTextFromClipboard();
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
irr::core::stringw widep;
|
irr::core::stringw widep;
|
||||||
|
@ -90,6 +90,7 @@ namespace
|
|||||||
Atom X_ATOM_CLIPBOARD;
|
Atom X_ATOM_CLIPBOARD;
|
||||||
Atom X_ATOM_TARGETS;
|
Atom X_ATOM_TARGETS;
|
||||||
Atom X_ATOM_UTF8_STRING;
|
Atom X_ATOM_UTF8_STRING;
|
||||||
|
Atom X_ATOM_UTF8_MIME_TYPE;
|
||||||
Atom X_ATOM_TEXT;
|
Atom X_ATOM_TEXT;
|
||||||
Atom X_ATOM_NETWM_MAXIMIZE_VERT;
|
Atom X_ATOM_NETWM_MAXIMIZE_VERT;
|
||||||
Atom X_ATOM_NETWM_MAXIMIZE_HORZ;
|
Atom X_ATOM_NETWM_MAXIMIZE_HORZ;
|
||||||
@ -1010,49 +1011,104 @@ bool CIrrDeviceLinux::run()
|
|||||||
|
|
||||||
case SelectionRequest:
|
case SelectionRequest:
|
||||||
{
|
{
|
||||||
XEvent respond;
|
|
||||||
XSelectionRequestEvent *req = &(event.xselectionrequest);
|
XSelectionRequestEvent *req = &(event.xselectionrequest);
|
||||||
if ( req->target == XA_STRING)
|
|
||||||
{
|
auto send_response = [this, req](Atom property) {
|
||||||
XChangeProperty (XDisplay,
|
XEvent response;
|
||||||
|
response.xselection.type = SelectionNotify;
|
||||||
|
response.xselection.display = req->display;
|
||||||
|
response.xselection.requestor = req->requestor;
|
||||||
|
response.xselection.selection = req->selection;
|
||||||
|
response.xselection.target = req->target;
|
||||||
|
response.xselection.property = property;
|
||||||
|
response.xselection.time = req->time;
|
||||||
|
XSendEvent (XDisplay, req->requestor, 0, 0, &response);
|
||||||
|
XFlush (XDisplay);
|
||||||
|
};
|
||||||
|
auto send_response_refuse = [&send_response] {
|
||||||
|
send_response(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
// sets the required property to data of type type and
|
||||||
|
// sends the according response
|
||||||
|
auto set_property_and_notify = [this, req, &send_response]
|
||||||
|
(Atom type, int format, const void *data, u32 data_size) {
|
||||||
|
XChangeProperty(XDisplay,
|
||||||
req->requestor,
|
req->requestor,
|
||||||
req->property, req->target,
|
req->property,
|
||||||
8, // format
|
type,
|
||||||
|
format,
|
||||||
PropModeReplace,
|
PropModeReplace,
|
||||||
(unsigned char*) Clipboard.c_str(),
|
(const unsigned char *)data,
|
||||||
|
data_size);
|
||||||
|
send_response(req->property);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (req->selection != X_ATOM_CLIPBOARD ||
|
||||||
|
req->owner != XWindow) {
|
||||||
|
// we are not the owner, refuse request
|
||||||
|
send_response_refuse();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for debugging:
|
||||||
|
//~ {
|
||||||
|
//~ char *target_name = XGetAtomName(XDisplay, req->target);
|
||||||
|
//~ fprintf(stderr, "CIrrDeviceLinux::run: target: %s (=%ld)\n",
|
||||||
|
//~ target_name, req->target);
|
||||||
|
//~ XFree(target_name);
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
if (req->property == None) {
|
||||||
|
// req is from obsolete client, use target as property name
|
||||||
|
// and X_ATOM_UTF8_STRING as type
|
||||||
|
// Note: this was not tested and might be incorrect
|
||||||
|
os::Printer::log("CIrrDeviceLinux::run: SelectionRequest from obsolete client",
|
||||||
|
ELL_WARNING);
|
||||||
|
XChangeProperty(XDisplay,
|
||||||
|
req->requestor,
|
||||||
|
req->target, X_ATOM_UTF8_STRING,
|
||||||
|
8, // format = 8-bit
|
||||||
|
PropModeReplace,
|
||||||
|
(unsigned char *)Clipboard.c_str(),
|
||||||
Clipboard.size());
|
Clipboard.size());
|
||||||
respond.xselection.property = req->property;
|
send_response(req->target);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if ( req->target == X_ATOM_TARGETS )
|
|
||||||
{
|
|
||||||
long data[2];
|
|
||||||
|
|
||||||
data[0] = X_ATOM_TEXT;
|
if (req->target == X_ATOM_TARGETS) {
|
||||||
data[1] = XA_STRING;
|
Atom data[] = {
|
||||||
|
X_ATOM_TARGETS,
|
||||||
|
X_ATOM_TEXT,
|
||||||
|
X_ATOM_UTF8_STRING,
|
||||||
|
X_ATOM_UTF8_MIME_TYPE
|
||||||
|
};
|
||||||
|
set_property_and_notify(
|
||||||
|
XA_ATOM,
|
||||||
|
32, // Atom is long, we need to set 32 for longs
|
||||||
|
&data,
|
||||||
|
sizeof(data) / sizeof(*data)
|
||||||
|
);
|
||||||
|
|
||||||
XChangeProperty (XDisplay, req->requestor,
|
} else if (req->target == X_ATOM_TEXT ||
|
||||||
req->property, req->target,
|
req->target == X_ATOM_UTF8_STRING ||
|
||||||
8, PropModeReplace,
|
req->target == X_ATOM_UTF8_MIME_TYPE) {
|
||||||
(unsigned char *) &data,
|
set_property_and_notify(
|
||||||
sizeof (data));
|
X_ATOM_UTF8_STRING,
|
||||||
respond.xselection.property = req->property;
|
8,
|
||||||
|
Clipboard.c_str(),
|
||||||
|
Clipboard.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// refuse the request
|
||||||
|
send_response_refuse();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
respond.xselection.property= None;
|
|
||||||
}
|
|
||||||
respond.xselection.type= SelectionNotify;
|
|
||||||
respond.xselection.display= req->display;
|
|
||||||
respond.xselection.requestor= req->requestor;
|
|
||||||
respond.xselection.selection=req->selection;
|
|
||||||
respond.xselection.target= req->target;
|
|
||||||
respond.xselection.time = req->time;
|
|
||||||
XSendEvent (XDisplay, req->requestor,0,0,&respond);
|
|
||||||
XFlush (XDisplay);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if defined(_IRR_LINUX_X11_XINPUT2_)
|
#if defined(_IRR_LINUX_X11_XINPUT2_)
|
||||||
case GenericEvent:
|
case GenericEvent:
|
||||||
{
|
{
|
||||||
XGenericEventCookie *cookie = &event.xcookie;
|
XGenericEventCookie *cookie = &event.xcookie;
|
||||||
if (XGetEventData(XDisplay, cookie) && cookie->extension == XI_EXTENSIONS_OPCODE && XI_EXTENSIONS_OPCODE
|
if (XGetEventData(XDisplay, cookie) && cookie->extension == XI_EXTENSIONS_OPCODE && XI_EXTENSIONS_OPCODE
|
||||||
@ -1799,58 +1855,105 @@ bool CIrrDeviceLinux::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &bright
|
|||||||
|
|
||||||
|
|
||||||
//! gets text from the clipboard
|
//! gets text from the clipboard
|
||||||
//! \return Returns 0 if no string is in there.
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
const c8* CIrrDeviceLinux::getTextFromClipboard() const
|
const c8 *CIrrDeviceLinux::getTextFromClipboard() const
|
||||||
{
|
{
|
||||||
#if defined(_IRR_COMPILE_WITH_X11_)
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
Window ownerWindow = XGetSelectionOwner (XDisplay, X_ATOM_CLIPBOARD);
|
Window ownerWindow = XGetSelectionOwner(XDisplay, X_ATOM_CLIPBOARD);
|
||||||
if ( ownerWindow == XWindow )
|
if (ownerWindow == XWindow) {
|
||||||
{
|
|
||||||
return Clipboard.c_str();
|
return Clipboard.c_str();
|
||||||
}
|
}
|
||||||
Clipboard = "";
|
|
||||||
if (ownerWindow != None )
|
|
||||||
{
|
|
||||||
XConvertSelection (XDisplay, X_ATOM_CLIPBOARD, XA_STRING, XA_PRIMARY, ownerWindow, CurrentTime);
|
|
||||||
XFlush (XDisplay);
|
|
||||||
|
|
||||||
// check for data
|
Clipboard = "";
|
||||||
Atom type;
|
|
||||||
int format;
|
if (ownerWindow == None) {
|
||||||
unsigned long numItems, bytesLeft, dummy;
|
return Clipboard.c_str();
|
||||||
unsigned char *data;
|
|
||||||
XGetWindowProperty (XDisplay, ownerWindow,
|
|
||||||
XA_PRIMARY, // property name
|
|
||||||
0, // offset
|
|
||||||
0, // length (we only check for data, so 0)
|
|
||||||
0, // Delete 0==false
|
|
||||||
AnyPropertyType, // AnyPropertyType or property identifier
|
|
||||||
&type, // return type
|
|
||||||
&format, // return format
|
|
||||||
&numItems, // number items
|
|
||||||
&bytesLeft, // remaining bytes for partial reads
|
|
||||||
&data); // data
|
|
||||||
if ( bytesLeft > 0 )
|
|
||||||
{
|
|
||||||
// there is some data to get
|
|
||||||
int result = XGetWindowProperty (XDisplay, ownerWindow, XA_PRIMARY, 0,
|
|
||||||
bytesLeft, 0, AnyPropertyType, &type, &format,
|
|
||||||
&numItems, &dummy, &data);
|
|
||||||
if (result == Success)
|
|
||||||
Clipboard = (irr::c8*)data;
|
|
||||||
XFree (data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete the property to be set beforehand
|
||||||
|
XDeleteProperty(XDisplay, XWindow, XA_PRIMARY);
|
||||||
|
|
||||||
|
XConvertSelection(XDisplay, X_ATOM_CLIPBOARD, X_ATOM_UTF8_STRING, XA_PRIMARY,
|
||||||
|
XWindow, CurrentTime);
|
||||||
|
XFlush(XDisplay);
|
||||||
|
|
||||||
|
// wait for event via a blocking call
|
||||||
|
XEvent event_ret;
|
||||||
|
XIfEvent(XDisplay, &event_ret, [](Display *_display, XEvent *event, XPointer arg) {
|
||||||
|
return (Bool) (event->type == SelectionNotify &&
|
||||||
|
event->xselection.requestor == *(Window *)arg &&
|
||||||
|
event->xselection.selection == X_ATOM_CLIPBOARD &&
|
||||||
|
event->xselection.target == X_ATOM_UTF8_STRING);
|
||||||
|
}, (XPointer)&XWindow);
|
||||||
|
|
||||||
|
_IRR_DEBUG_BREAK_IF(!(event_ret.type == SelectionNotify &&
|
||||||
|
event_ret.xselection.requestor == XWindow &&
|
||||||
|
event_ret.xselection.selection == X_ATOM_CLIPBOARD &&
|
||||||
|
event_ret.xselection.target == X_ATOM_UTF8_STRING));
|
||||||
|
|
||||||
|
Atom property_set = event_ret.xselection.property;
|
||||||
|
if (event_ret.xselection.property == None) {
|
||||||
|
// request failed => empty string
|
||||||
|
return Clipboard.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for data
|
||||||
|
Atom type;
|
||||||
|
int format;
|
||||||
|
unsigned long numItems, bytesLeft, dummy;
|
||||||
|
unsigned char *data = nullptr;
|
||||||
|
XGetWindowProperty (XDisplay, XWindow,
|
||||||
|
property_set, // property name
|
||||||
|
0, // offset
|
||||||
|
0, // length (we only check for data, so 0)
|
||||||
|
0, // Delete 0==false
|
||||||
|
AnyPropertyType, // AnyPropertyType or property identifier
|
||||||
|
&type, // return type
|
||||||
|
&format, // return format
|
||||||
|
&numItems, // number items
|
||||||
|
&bytesLeft, // remaining bytes for partial reads
|
||||||
|
&data); // data
|
||||||
|
if (data) {
|
||||||
|
XFree(data);
|
||||||
|
data = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for debugging:
|
||||||
|
//~ {
|
||||||
|
//~ char *type_name = XGetAtomName(XDisplay, type);
|
||||||
|
//~ fprintf(stderr, "CIrrDeviceLinux::getTextFromClipboard: actual type: %s (=%ld)\n",
|
||||||
|
//~ type_name, type);
|
||||||
|
//~ XFree(type_name);
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
if (type != X_ATOM_UTF8_STRING && type != X_ATOM_UTF8_MIME_TYPE) {
|
||||||
|
os::Printer::log("CIrrDeviceLinux::getTextFromClipboard: did not get utf-8 string",
|
||||||
|
ELL_WARNING);
|
||||||
|
return Clipboard.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytesLeft > 0) {
|
||||||
|
// there is some data to get
|
||||||
|
int result = XGetWindowProperty (XDisplay, XWindow, property_set, 0,
|
||||||
|
bytesLeft, 0, AnyPropertyType, &type, &format,
|
||||||
|
&numItems, &dummy, &data);
|
||||||
|
if (result == Success)
|
||||||
|
Clipboard = (irr::c8 *)data;
|
||||||
|
XFree (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the property again, to inform the owner about the successful transfer
|
||||||
|
XDeleteProperty(XDisplay, XWindow, property_set);
|
||||||
|
|
||||||
return Clipboard.c_str();
|
return Clipboard.c_str();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
return 0;
|
return nullptr;
|
||||||
#endif
|
#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
|
||||||
{
|
{
|
||||||
#if defined(_IRR_COMPILE_WITH_X11_)
|
#if defined(_IRR_COMPILE_WITH_X11_)
|
||||||
// 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.
|
||||||
@ -1858,6 +1961,10 @@ void CIrrDeviceLinux::copyToClipboard(const c8* text) const
|
|||||||
Clipboard = text;
|
Clipboard = text;
|
||||||
XSetSelectionOwner (XDisplay, X_ATOM_CLIPBOARD, XWindow, CurrentTime);
|
XSetSelectionOwner (XDisplay, X_ATOM_CLIPBOARD, XWindow, CurrentTime);
|
||||||
XFlush (XDisplay);
|
XFlush (XDisplay);
|
||||||
|
Window owner = XGetSelectionOwner(XDisplay, X_ATOM_CLIPBOARD);
|
||||||
|
if (owner != XWindow) {
|
||||||
|
os::Printer::log("CIrrDeviceLinux::copyToClipboard: failed to set owner", ELL_WARNING);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1900,8 +2007,9 @@ void CIrrDeviceLinux::initXAtoms()
|
|||||||
#ifdef _IRR_COMPILE_WITH_X11_
|
#ifdef _IRR_COMPILE_WITH_X11_
|
||||||
X_ATOM_CLIPBOARD = XInternAtom(XDisplay, "CLIPBOARD", False);
|
X_ATOM_CLIPBOARD = XInternAtom(XDisplay, "CLIPBOARD", False);
|
||||||
X_ATOM_TARGETS = XInternAtom(XDisplay, "TARGETS", False);
|
X_ATOM_TARGETS = XInternAtom(XDisplay, "TARGETS", False);
|
||||||
X_ATOM_UTF8_STRING = XInternAtom (XDisplay, "UTF8_STRING", False);
|
X_ATOM_UTF8_STRING = XInternAtom(XDisplay, "UTF8_STRING", False);
|
||||||
X_ATOM_TEXT = XInternAtom (XDisplay, "TEXT", False);
|
X_ATOM_UTF8_MIME_TYPE = XInternAtom(XDisplay, "text/plain;charset=utf-8", False);
|
||||||
|
X_ATOM_TEXT = XInternAtom(XDisplay, "TEXT", False);
|
||||||
X_ATOM_NETWM_MAXIMIZE_VERT = XInternAtom(XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", true);
|
X_ATOM_NETWM_MAXIMIZE_VERT = XInternAtom(XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", true);
|
||||||
X_ATOM_NETWM_MAXIMIZE_HORZ = XInternAtom(XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", true);
|
X_ATOM_NETWM_MAXIMIZE_HORZ = XInternAtom(XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", true);
|
||||||
X_ATOM_NETWM_STATE = XInternAtom(XDisplay, "_NET_WM_STATE", true);
|
X_ATOM_NETWM_STATE = XInternAtom(XDisplay, "_NET_WM_STATE", true);
|
||||||
|
@ -108,12 +108,13 @@ namespace irr
|
|||||||
virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) _IRR_OVERRIDE_;
|
virtual bool getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! gets text from the clipboard
|
//! gets text from the clipboard
|
||||||
//! \return Returns 0 if no string is in there.
|
//! \return Returns 0 if no string is in there, otherwise utf-8 text.
|
||||||
virtual const c8* getTextFromClipboard() const;
|
virtual const c8 *getTextFromClipboard() 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 which you have on X on the middle mouse button.
|
||||||
virtual void copyToClipboard(const c8* text) const;
|
//! @param text The text in utf-8
|
||||||
|
virtual void copyToClipboard(const c8 *text) const;
|
||||||
|
|
||||||
//! Remove all messages pending in the system message loop
|
//! Remove all messages pending in the system message loop
|
||||||
virtual void clearSystemMessages() _IRR_OVERRIDE_;
|
virtual void clearSystemMessages() _IRR_OVERRIDE_;
|
||||||
@ -425,6 +426,7 @@ namespace irr
|
|||||||
XIM XInputMethod;
|
XIM XInputMethod;
|
||||||
XIC XInputContext;
|
XIC XInputContext;
|
||||||
bool HasNetWM;
|
bool HasNetWM;
|
||||||
|
// text is utf-8
|
||||||
mutable core::stringc Clipboard;
|
mutable core::stringc Clipboard;
|
||||||
#endif
|
#endif
|
||||||
u32 Width, Height;
|
u32 Width, Height;
|
||||||
|
@ -56,7 +56,8 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const
|
|||||||
|
|
||||||
|
|
||||||
//! copies text to the clipboard
|
//! copies text to the clipboard
|
||||||
void COSOperator::copyToClipboard(const c8* text) const
|
//! \param text: text in utf-8
|
||||||
|
void COSOperator::copyToClipboard(const c8 *text) const
|
||||||
{
|
{
|
||||||
if (strlen(text)==0)
|
if (strlen(text)==0)
|
||||||
return;
|
return;
|
||||||
@ -103,7 +104,7 @@ void COSOperator::copyToClipboard(const c8* text) const
|
|||||||
|
|
||||||
|
|
||||||
//! gets text from the clipboard
|
//! gets 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.
|
||||||
const c8* COSOperator::getTextFromClipboard() const
|
const c8* COSOperator::getTextFromClipboard() const
|
||||||
{
|
{
|
||||||
#if defined(_IRR_XBOX_PLATFORM_)
|
#if defined(_IRR_XBOX_PLATFORM_)
|
||||||
|
@ -27,10 +27,11 @@ public:
|
|||||||
virtual const core::stringc& getOperatingSystemVersion() const _IRR_OVERRIDE_;
|
virtual const core::stringc& getOperatingSystemVersion() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! copies text to the clipboard
|
//! copies text to the clipboard
|
||||||
virtual void copyToClipboard(const c8* text) const _IRR_OVERRIDE_;
|
//! \param text: text in utf-8
|
||||||
|
virtual void copyToClipboard(const c8 *text) const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! gets text from the clipboard
|
//! gets 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 _IRR_OVERRIDE_;
|
virtual const c8* getTextFromClipboard() const _IRR_OVERRIDE_;
|
||||||
|
|
||||||
//! gets the total and available system RAM in kB
|
//! gets the total and available system RAM in kB
|
||||||
|
Loading…
Reference in New Issue
Block a user