1 // X11 implementation of clipboard access for Nasal
3 // Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 #include "NasalClipboard.hxx"
21 #include <simgear/debug/logstream.hxx>
24 #include <X11/Xatom.h>
31 _display( XOpenDisplay(NULL) ),
32 _window( XCreateSimpleWindow(
34 DefaultRootWindow(_display),
35 0, 0, 1, 1, // dummy dimensions -> window will never be mapped
39 _atom_targets( XInternAtom(_display, "TARGETS", False) ),
40 _atom_primary( XInternAtom(_display, "PRIMARY", False) ),
41 _atom_clipboard( XInternAtom(_display, "CLIPBOARD", False) )
44 assert(_atom_targets != None);
45 assert(_atom_primary != None);
46 assert(_atom_clipboard != None);
50 * Get clipboard contents as text
52 virtual std::string getText(Type type)
54 Atom atom_type = (type == CLIPBOARD ? _atom_clipboard : _atom_primary);
56 //Request a list of possible conversions
57 XConvertSelection( _display, atom_type, _atom_targets, atom_type,
58 _window, CurrentTime );
61 Atom requested_type = None;
62 bool sent_request = false;
64 for(int cnt = 0; cnt < 5;)
67 XNextEvent(_display, &event);
69 if( event.type == SelectionNotify )
71 Atom target = event.xselection.target;
72 if(event.xselection.property == None)
74 if( target == _atom_targets )
75 // If TARGETS can not be converted no selection is available
82 "ClipboardX11::getText: Conversion failed: "
83 "target=" << getAtomName(target)
89 //If we're being given a list of targets (possible conversions)
90 if(target == _atom_targets && !sent_request)
93 requested_type = XA_STRING; // TODO select other type
94 XConvertSelection( _display, atom_type, requested_type, atom_type,
95 _window, CurrentTime );
97 else if(target == requested_type)
99 Property prop = readProperty(_window, atom_type);
100 if( prop.format != 8 )
106 "ClipboardX11::getText: can only handle 8-bit data (is "
107 << prop.format << "-bit) -> retry "
114 std::string result((const char*)prop.data, prop.num_items);
125 "ClipboardX11::getText: wrong target: " << getAtomName(target)
137 "ClipboardX11::getText: unexpected XEvent: " << event.type
143 return std::string();
147 * Set clipboard contents as text
149 virtual bool setText(const std::string& text, Type type)
155 "ClipboardX11::setText: not yet implemented!"
171 int format, num_items;
175 // Get all data from a property
176 Property readProperty(Window w, Atom property)
180 unsigned long nitems;
181 unsigned long bytes_after;
182 unsigned char *ret=0;
184 int read_bytes = 1024;
186 //Keep trying to read the property until there are no
195 _display, w, property, 0, read_bytes, False, AnyPropertyType,
196 &actual_type, &actual_format, &nitems, &bytes_after,
201 } while( bytes_after );
203 Property p = {ret, actual_format, nitems, actual_type};
207 std::string getAtomName(Atom atom)
209 return atom == None ? "None" : XGetAtomName(_display, atom);
214 //------------------------------------------------------------------------------
215 NasalClipboard::Ptr NasalClipboard::create()
217 return NasalClipboard::Ptr(new ClipboardX11);