bool LinuxEnvironment::requestSelectionContent(UString &selection_content, Atom selection, Atom requested_format) { // send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) // the selection owner will be asked to set the MCENGINE_SEL property on m_window with the selection content Atom property_name = XInternAtom(m_display, "MCENGINE_SEL", false); XConvertSelection(m_display, selection, requested_format, property_name, m_window, CurrentTime); bool gotReply = false; int timeoutMs = 200; // will wait at most for 200 ms do { XEvent event; gotReply = XCheckTypedWindowEvent(m_display, m_window, SelectionNotify, &event); if (gotReply) { if (event.xselection.property == property_name) { selection_content = readWindowProperty(event.xselection.requestor, event.xselection.property, requested_format, true); return true; } else // the format we asked for was denied.. (event.xselection.property == None) return false; } // not very elegant.. we could do a select() or something like that... however clipboard content requesting // is inherently slow on x11, it often takes 50ms or more so... usleep(4000); timeoutMs -= 4; } while (timeoutMs > 0); debugLog("LinuxEnvironment::requestSelectionContent() : Timeout!\n"); return false; }
/* ============================================================================== This file is part of the JUCE library - "Jules' Utility Class Extensions" Copyright 2004-11 by Raw Material Software Ltd. ------------------------------------------------------------------------------ JUCE can be redistributed and/or modified under the terms of the GNU General Public License (Version 2), as published by the Free Software Foundation. A copy of the license is included in the JUCE distribution, or can be found online at www.gnu.org/licenses. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.rawmaterialsoftware.com/juce for more information. ============================================================================== */ extern Display* display; extern Window juce_messageWindowHandle; namespace ClipboardHelpers { static String localClipboardContent; static Atom atom_UTF8_STRING; static Atom atom_CLIPBOARD; static Atom atom_TARGETS; //============================================================================== static void initSelectionAtoms() { static bool isInitialised = false; if (! isInitialised) { atom_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False); atom_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); atom_TARGETS = XInternAtom (display, "TARGETS", False); } } //============================================================================== // Read the content of a window property as either a locale-dependent string or an utf8 string // works only for strings shorter than 1000000 bytes static String readWindowProperty (Window window, Atom prop, Atom fmt) { String returnData; char* clipData; Atom actualType; int actualFormat; unsigned long numItems, bytesLeft; if (XGetWindowProperty (display, window, prop, 0L /* offset */, 1000000 /* length (max) */, False, AnyPropertyType /* format */, &actualType, &actualFormat, &numItems, &bytesLeft, (unsigned char**) &clipData) == Success) { if (actualType == atom_UTF8_STRING && actualFormat == 8) returnData = String::fromUTF8 (clipData, numItems); else if (actualType == XA_STRING && actualFormat == 8) returnData = String (clipData, numItems); if (clipData != nullptr) XFree (clipData); jassert (bytesLeft == 0 || numItems == 1000000); } XDeleteProperty (display, window, prop); return returnData; } //============================================================================== // Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */ static bool requestSelectionContent (String& selectionContent, Atom selection, Atom requestedFormat) { Atom property_name = XInternAtom (display, "JUCE_SEL", false); // The selection owner will be asked to set the JUCE_SEL property on the // juce_messageWindowHandle with the selection content XConvertSelection (display, selection, requestedFormat, property_name, juce_messageWindowHandle, CurrentTime); int count = 50; // will wait at most for 200 ms while (--count >= 0) { XEvent event; if (XCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event)) { if (event.xselection.property == property_name) { jassert (event.xselection.requestor == juce_messageWindowHandle); selectionContent = readWindowProperty (event.xselection.requestor, event.xselection.property, requestedFormat); return true; } else { return false; // the format we asked for was denied.. (event.xselection.property == None) } } // not very elegant.. we could do a select() or something like that... // however clipboard content requesting is inherently slow on x11, it // often takes 50ms or more so... Thread::sleep (4); } return false; }