+ std::string _clipboard,
+ _selection;
+
+ void handleEvent(const XEvent& event)
+ {
+ switch( event.type )
+ {
+ case SelectionRequest:
+ handleSelectionRequest(event.xselectionrequest);
+ break;
+ case SelectionClear:
+ if( event.xselectionclear.selection == _atom_clipboard )
+ _clipboard.clear();
+ else
+ _selection.clear();
+ break;
+ default:
+ SG_LOG
+ (
+ SG_NASAL,
+ SG_WARN,
+ "ClipboardX11: unexpected XEvent: " << event.type
+ );
+ break;
+ }
+ }
+
+ void handleSelectionRequest(const XSelectionRequestEvent& sel_req)
+ {
+ SG_LOG
+ (
+ SG_NASAL,
+ SG_DEBUG,
+ "ClipboardX11: handle selection request: "
+ "selection=" << getAtomName(sel_req.selection) << ", "
+ "target=" << getAtomName(sel_req.target)
+ );
+
+ const std::string& buf = sel_req.selection == _atom_clipboard
+ ? _clipboard
+ : _selection;
+
+ // Prepare response to notify whether we have written to the property or
+ // are unable to do the conversion
+ XSelectionEvent response;
+ response.type = SelectionNotify;
+ response.display = sel_req.display;
+ response.requestor = sel_req.requestor;
+ response.selection = sel_req.selection;
+ response.target = sel_req.target;
+ response.property = sel_req.property;
+ response.time = sel_req.time;
+
+ if( sel_req.target == _atom_targets )
+ {
+ static Atom supported[] = {
+ XA_STRING,
+ _atom_text,
+ _atom_utf8
+ };
+
+ changeProperty
+ (
+ sel_req.requestor,
+ sel_req.property,
+ sel_req.target,
+ &supported,
+ sizeof(supported)
+ );
+ }
+ else if( sel_req.target == XA_STRING
+ || sel_req.target == _atom_text
+ || sel_req.target == _atom_utf8 )
+ {
+ changeProperty
+ (
+ sel_req.requestor,
+ sel_req.property,
+ sel_req.target,
+ buf.data(),
+ buf.size()
+ );
+ }
+ else
+ {
+ // Notify requestor that we are unable to perform requested conversion
+ response.property = None;
+ }
+
+ XSendEvent(_display, sel_req.requestor, False, 0, (XEvent*)&response);
+ }
+
+ void changeProperty( Window w,
+ Atom prop,
+ Atom type,
+ const void *data,
+ size_t size )
+ {
+ XChangeProperty
+ (
+ _display, w, prop, type, 8, PropModeReplace,
+ static_cast<const unsigned char*>(data), size
+ );
+ }
+