/* Process OLIT ClientMessage */ static void HandleOlitTrigger(Display *dpy, XClientMessageEvent *event) { drop_site_t *site; char success = False; Atom source_handle = event->data.l[OLIT_DROP_SELECTION]; Time time_stamp = event->data.l[OLIT_DROP_TIME]; /* proxy agent only gets ATOM_SUN_DND_TRIGGER if receiver is motif */ /* map site_id to site_window */ for (site = MasterSiteList; site != NULL; site = site->next) { if (site->site_id == event->data.l[OLIT_DROP_SITE_ID]) { drop_info_t *drop_info = NewDropInfo(); drop_info->motif_action = ConvertOlitAction(event->data.l[OLIT_DROP_OPERATION]); drop_info->receiver_win = site->window_id; drop_info->source_handle = source_handle; drop_info->trigger_x = (event->data.l[OLIT_DROP_COORDINATE]) >> 16; drop_info->trigger_y = (event->data.l[OLIT_DROP_COORDINATE]) & 0x0000ffff; drop_info->time_stamp = time_stamp; if ((event->data.l[OLIT_DROP_OPERATION]) & OLIT_DROP_ACKNOWLEDGE_ACTION) { XConvertSelection(dpy, drop_info->source_handle, /* selection */ ATOM_SUN_DND_ACK, ATOM_SUN_DND_ACK, /* property */ drop_info->proxy_sel_req_win, drop_info->time_stamp /* time */ ); } /* get olit initiator targets */ XConvertSelection(dpy, drop_info->source_handle, /* selection */ ATOM_TARGETS, drop_info->proxy_handle, /* property */ drop_info->proxy_sel_req_win, drop_info->time_stamp /* time */ ); success = True; break; } }
/** * st_clipboard_get_text: * @clipboard: A #StCliboard * @type: The type of clipboard data you want * @callback: (scope async): function to be called when the text is retreived * @user_data: data to be passed to the callback * * Request the data from the clipboard in text form. @callback is executed * when the data is retreived. * */ void st_clipboard_get_text (StClipboard *clipboard, StClipboardType type, StClipboardCallbackFunc callback, gpointer user_data) { EventFilterData *data; Display *dpy; g_return_if_fail (ST_IS_CLIPBOARD (clipboard)); g_return_if_fail (callback != NULL); data = g_new0 (EventFilterData, 1); data->clipboard = clipboard; data->callback = callback; data->user_data = user_data; clutter_x11_add_filter ((ClutterX11FilterFunc) st_clipboard_x11_event_filter, data); dpy = clutter_x11_get_default_display (); clutter_x11_trap_x_errors (); /* safety on */ XConvertSelection (dpy, type == ST_CLIPBOARD_TYPE_CLIPBOARD ? __atom_clip : __atom_primary, __utf8_string, __utf8_string, clipboard->priv->clipboard_window, CurrentTime); clutter_x11_untrap_x_errors (); }
static void dndDrop(XClientMessageEvent *evt) { dprintf((stderr, "dndDrop\n")); if (xdndSourceWindow != xdndDrop_sourceWindow(evt)) dprintf((stderr, "dndDrop: wrong source window\n")); else if (xdndWillAccept) { Window owner; dprintf((stderr, "converting selection\n")); if (!(owner= XGetSelectionOwner(stDisplay, XdndSelection))) fprintf(stderr, "dndDrop: XGetSelectionOwner failed\n"); else XConvertSelection(stDisplay, XdndSelection, XdndTextUriList, XdndSelectionAtom, stWindow, xdndDrop_time(evt)); if (uxDropFileCount) { int i; assert(uxDropFileNames); for (i= 0; i < uxDropFileCount; ++i) free(uxDropFileNames[i]); free(uxDropFileNames); uxDropFileCount= 0; uxDropFileNames= 0; } } else dprintf((stderr, "refusing selection -- finishing\n")); dndSendFinished(evt->window); dndLeave(evt); xdndState= XdndStateIdle; }
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; }
static boolean X11TextConvertSelectionHelper( FcitxX11 *x11priv, Atom selection, Atom target, int format, size_t nitems, const void *buff, X11ConvertSelection *convert) { boolean res = true; char *sel_str = XGetAtomName(x11priv->dpy, selection); if (!buff) { Atom new_tgt; if (target == x11priv->utf8Atom) { new_tgt = x11priv->compTextAtom; } else if (target == x11priv->compTextAtom) { new_tgt = x11priv->stringAtom; } else { new_tgt = None; } if (new_tgt != None) { fcitx_utils_local_cat_str(prop_str, 256, FCITX_X11_SEL, sel_str); Atom prop = XInternAtom(x11priv->dpy, prop_str, False); XConvertSelection(x11priv->dpy, selection, new_tgt, prop, x11priv->eventWindow, CurrentTime); res = false; goto out; } } X11ConvertSelectionCallback cb; cb = (X11ConvertSelectionCallback)convert->func; char *tgt_str = XGetAtomName(x11priv->dpy, target); /* compound text also looks fine here, need more info.. */ cb(convert->owner, sel_str, tgt_str, format, nitems, buff, convert->data); XFree(tgt_str); out: XFree(sel_str); return res; }
std::string X11Window::getClipboardText() { Atom clipboard = XInternAtom(m_display, "CLIPBOARD", False); Window ownerWindow = XGetSelectionOwner(m_display, clipboard); if(ownerWindow == m_window) return m_clipboardText; std::string clipboardText; if(ownerWindow != None) { XConvertSelection(m_display, clipboard, XA_STRING, XA_PRIMARY, ownerWindow, CurrentTime); XFlush(m_display); // hack to wait SelectioNotify event, otherwise we will get wrong clipboard pastes // TODO: fix this in a correct way stdext::millisleep(100); // check for data Atom type; int format; ulong len, bytesLeft; uchar *data; XGetWindowProperty(m_display, ownerWindow, XA_PRIMARY, 0, 10000000L, 0, XA_STRING, &type, &format, &len, &bytesLeft, &data); if(len > 0) { clipboardText = stdext::utf8_to_latin1(data); } } return clipboardText; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { BOOL rawTransfer; xfCliprdrFormat* format = NULL; UINT32 formatId = formatDataRequest->requestedFormatId; xfClipboard* clipboard = (xfClipboard*) context->custom; xfContext* xfc = clipboard->xfc; rawTransfer = xf_cliprdr_is_raw_transfer_available(clipboard); if (rawTransfer) { format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW); XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom, XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1); } else format = xf_cliprdr_get_client_format_by_id(clipboard, formatId); if (!format) return xf_cliprdr_send_data_response(clipboard, NULL, 0); clipboard->requestedFormatId = rawTransfer ? CF_RAW : formatId; XConvertSelection(xfc->display, clipboard->clipboard_atom, format->atom, clipboard->property_atom, xfc->drawable, CurrentTime); XFlush(xfc->display); /* After this point, we expect a SelectionNotify event from the clipboard owner. */ return CHANNEL_RC_OK; }
int xf_cliprdr_send_client_format_list(xfClipboard* clipboard) { UINT32 i, numFormats; CLIPRDR_FORMAT* formats; CLIPRDR_FORMAT_LIST formatList; xfContext* xfc = clipboard->xfc; ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST)); numFormats = clipboard->numClientFormats; formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT)); for (i = 0; i < numFormats; i++) { formats[i].formatId = clipboard->clientFormats[i].formatId; formats[i].formatName = clipboard->clientFormats[i].formatName; } formatList.msgFlags = CB_RESPONSE_OK; formatList.numFormats = numFormats; formatList.formats = formats; clipboard->context->ClientFormatList(clipboard->context, &formatList); free(formats); if (clipboard->owner && clipboard->owner != xfc->drawable) { /* Request the owner for TARGETS, and wait for SelectionNotify event */ XConvertSelection(xfc->display, clipboard->clipboard_atom, clipboard->targets[1], clipboard->property_atom, xfc->drawable, CurrentTime); } return 1; }
// get the data from XA_CLIPBOARD with specific Atom type. // currently the 3rd parameter is always XA_CLIPBOARD. // this is because XA_PRIMARY is not often used. // the 4th parameter is the format that requestor want get. unsigned char *GetClipboardDataByFormat(Display* disp, Window win, Atom clipbrdType, Atom target, unsigned long *length) { // some variables that used to get the data in window property unsigned char *clipbrddata = NULL; int read_bytes = 1024; Atom type; int format, result; unsigned long bytes_after; XConvertSelection(disp, XA_CLIPBOARD, target, XA_CLIPBOARD, win, CurrentTime); do { if ( clipbrddata != 0 ) { XFree(clipbrddata); clipbrddata = NULL; } result = XGetWindowProperty(disp, win, clipbrdType, 0, read_bytes, False, AnyPropertyType, &type, &format, length, &bytes_after, &clipbrddata); read_bytes *= 2; } while ( bytes_after != 0 ); // if we got any data, copy it. if ( result == Success && clipbrddata ) return clipbrddata; return NULL; }
void gui_paste(struct gui_instance *gi, enum gui_clipboard source) { Window selowner; Atom selection; switch (source) { case GUI_PRIMARY_SELECTION: selection = XA_PRIMARY; break; case GUI_SECONDARY_SELECTION: selection = XA_SECONDARY; break; case GUI_CLIPBOARD: selection = xa_clipboard; break; default: return; } selowner = XGetSelectionOwner(GUI_display, selection); if (selowner == None) { fprintf (stderr, "No selection owner\n"); return; } XDeleteProperty(GUI_display, gi->window, xa_prop_paste); XConvertSelection(GUI_display, selection, xa_utf8_string, xa_prop_paste, gi->window, CurrentTime); }
CL_String CL_Clipboard_X11::get_clipboard_text() const { if ( ( atom_CLIPBOARD == None ) ) { // X Server does not have clipboard support return CL_String(); } XConvertSelection(disp, atom_CLIPBOARD, XA_STRING, atom_CLIPBOARD, window, CurrentTime); XFlush(disp); XEvent event; if (!x11_window->get_xevent( event, SelectionNotify )) { return CL_String(); } Atom actual_type; int actual_format; unsigned long number_items; unsigned char *read_data = x11_window->get_property(window, atom_CLIPBOARD, &number_items, &actual_format, &actual_type); if ( (actual_format != 8) || (actual_type != XA_STRING) || (number_items <=0) || (read_data==NULL) ) { if (read_data) { XFree(read_data); } return CL_String(); } CL_String buffer( (char *) read_data); XFree(read_data); return buffer; }
Clipboard::Clipboard(char const * clipProperty): sel(XInternAtom(resourceManager->dpy, clipProperty, False)), XA_TARGETS(XInternAtom(resourceManager->dpy, "TARGETS", False)) { window.reset(resourceManager->createTopLevelWindow(0,0,100,100)); XConvertSelection(resourceManager->dpy, sel, XA_TARGETS, sel, window.get(), CurrentTime); XFlush(resourceManager->dpy); }
/** * Tries to grab a given target. * Returns true if successful, false otherwise. */ static bool try_grab_target(Atom source, Atom target, std::string& ret) { UseX x11; // Cleanup previous data XDeleteProperty(x11->dpy(), x11->window(), x11->WES_PASTE()); XSync (x11->dpy(), False); //std::cout<<"We request target:"<<XGetAtomName(x11->dpy(), target)<<"\n"; // Request information XConvertSelection(x11->dpy(), source, target, x11->WES_PASTE(), x11->window(), CurrentTime); // Wait (with timeout) for a response SelectionNotify for (int attempt = 0; attempt < 15; attempt++) { if (XPending(x11->dpy())) { XEvent selectNotify; while (XCheckTypedWindowEvent(x11->dpy(), x11->window(), SelectionNotify, &selectNotify)) { if (selectNotify.xselection.property == None) //Not supported. Say so. return false; else if (selectNotify.xselection.property == x11->WES_PASTE() && selectNotify.xselection.target == target) { // The size unsigned long length = 0; unsigned char* data; // These 3 XGetWindowProperty returns but we don't use Atom typeRet; int formatRet; unsigned long remaining; // std::cout<<"Grab:"<<XGetAtomName(x11->dpy(), target)<<"\n"; // Grab the text out of the property XGetWindowProperty(x11->dpy(), x11->window(), selectNotify.xselection.property, 0, 65535/4, True, target, &typeRet, &formatRet, &length, &remaining, &data); if (data && length) { ret = reinterpret_cast<char*>(data); XFree(data); return true; } else { return false; } } } } usleep(10000); } // Timed out -- return empty string return false; }
static String _get_clipboard(Atom p_source, Window x11_window, ::Display* x11_display, String p_internal_clipboard) { String ret; Atom type; Atom selection = XA_PRIMARY; int format, result; unsigned long len, bytes_left, dummy; unsigned char *data; Window Sown = XGetSelectionOwner (x11_display, p_source); if (Sown == x11_window) { printf("returning internal clipboard\n"); return p_internal_clipboard; }; if (Sown != None) { XConvertSelection (x11_display, p_source, XA_STRING, selection, x11_window, CurrentTime); XFlush (x11_display); while (true) { XEvent event; XNextEvent(x11_display, &event); if (event.type == SelectionNotify && event.xselection.requestor == x11_window) { break; }; }; // // Do not get any data, see how much data is there // XGetWindowProperty (x11_display, x11_window, selection, // Tricky.. 0, 0, // offset - len 0, // Delete 0==FALSE AnyPropertyType, //flag &type, // return type &format, // return format &len, &bytes_left, //that &data); // DATA is There if (bytes_left > 0) { result = XGetWindowProperty (x11_display, x11_window, selection, 0,bytes_left,0, AnyPropertyType, &type,&format, &len, &dummy, &data); if (result == Success) { ret.parse_utf8((const char*)data); } else printf ("FAIL\n"); XFree (data); } } return ret; };
char * X11_GetClipboardText(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; Display *display = videodata->display; Atom format; Window window; Window owner; Atom selection; Atom seln_type; int seln_format; unsigned long nbytes; unsigned long overflow; unsigned char *src; char *text; text = NULL; /* Get the window that holds the selection */ window = GetWindow(_this); format = TEXT_FORMAT; owner = XGetSelectionOwner(display, XA_PRIMARY); if ((owner == None) || (owner == window)) { owner = DefaultRootWindow(display); selection = XA_CUT_BUFFER0; } else { /* Request that the selection owner copy the data to our window */ owner = window; selection = XInternAtom(display, "SDL_SELECTION", False); XConvertSelection(display, XA_PRIMARY, format, selection, owner, CurrentTime); /* FIXME: Should we have a timeout here? */ videodata->selection_waiting = SDL_TRUE; while (videodata->selection_waiting) { SDL_PumpEvents(); } } if (XGetWindowProperty(display, owner, selection, 0, INT_MAX/4, False, format, &seln_type, &seln_format, &nbytes, &overflow, &src) == Success) { if (seln_type == format) { text = (char *)SDL_malloc(nbytes+1); if (text) { SDL_memcpy(text, src, nbytes); text[nbytes] = '\0'; } } XFree(src); } if (!text) { text = SDL_strdup(""); } return text; }
void xclippaste(void) { Atom clipboard; clipboard = XInternAtom(xw.dpy, "CLIPBOARD", 0); XConvertSelection(xw.dpy, clipboard, xsel.xtarget, clipboard, xw.win, CurrentTime); }
void X11DragDrop::dndDrop( ldata_t data ) { Window src = data[0]; Time time = data[2]; Atom selectionAtom = XInternAtom( XDISPLAY, "XdndSelection", 0 ); Atom targetAtom = XInternAtom( XDISPLAY, "text/plain", 0 ); Atom propAtom = XInternAtom( XDISPLAY, "VLC_SELECTION", 0 ); Atom actionAtom = XInternAtom( XDISPLAY, "XdndActionCopy", 0 ); Atom typeAtom = XInternAtom( XDISPLAY, "XdndFinished", 0 ); // Convert the selection into the given target XConvertSelection( XDISPLAY, selectionAtom, targetAtom, propAtom, src, time ); // Read the selection Atom type; int format; unsigned long nitems, nbytes; char *buffer; XGetWindowProperty( XDISPLAY, src, propAtom, 0, 1024, False, AnyPropertyType, &type, &format, &nitems, &nbytes, (unsigned char**)&buffer ); if( buffer != NULL ) { char* psz_dup = strdup( buffer ); char* psz_new = psz_dup; while( psz_new && *psz_new ) { char* psz_end = strchr( psz_new, '\n' ); if( psz_end ) *psz_end = '\0'; CmdAddItem cmd( getIntf(), psz_new, m_playOnDrop ); cmd.execute(); psz_new = psz_end ? psz_end + 1 : NULL; } free( psz_dup ); XFree( buffer ); } // Tell the source we accepted the drop XEvent event; event.type = ClientMessage; event.xclient.window = src; event.xclient.display = XDISPLAY; event.xclient.message_type = typeAtom; event.xclient.format = 32; event.xclient.data.l[0] = m_wnd; event.xclient.data.l[1] = 1; // drop accepted event.xclient.data.l[2] = actionAtom; XSendEvent( XDISPLAY, src, False, 0, &event ); }
static void cliprdr_clear_selection(XEvent* e) { Window newOwner = XGetSelectionOwner(e->xselectionclear.display, clipboard_atom); log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[clear_selection]: " "New windows owner : %i", (int)newOwner); clipboard_current_clipboard_clear(&clipboard); XConvertSelection(display, clipboard_atom, targets_atom, xrdp_clipboard, wclip, CurrentTime); XSync (e->xselectionclear.display, False); }
static char* getSelection(Display *dpy, Window us, Atom selection) { int max_events = 50; Window owner = XGetSelectionOwner (dpy, selection); int ret; //logger->log("Clipboard: XConvertSelection on %s", XGetAtomName(dpy, selection)); if (owner == None) { //logger->log("Clipboard: No owner"); return NULL; } XConvertSelection(dpy, selection, XA_STRING, XA_PRIMARY, us, CurrentTime); XFlush(dpy); while (max_events--) { XEvent e; XNextEvent(dpy, &e); if (e.type == SelectionNotify) { //logger->log("Clipboard: Received %s", XGetAtomName(dpy, e.xselection.selection)); if (e.xselection.property == None) { //logger->log("Clipboard: Couldn't convert"); return NULL; } long unsigned len, left, dummy; int format; Atom type; unsigned char *data = NULL; XGetWindowProperty(dpy, us, e.xselection.property, 0, 0, False, AnyPropertyType, &type, &format, &len, &left, &data); if (left < 1) return NULL; ret = XGetWindowProperty(dpy, us, e.xselection.property, 0, left, False, AnyPropertyType, &type, &format, &len, &dummy, &data); if (ret != Success) { //logger->log("Clipboard: Failed to get property: %p on %lu", data, len); return NULL; } //logger->log("Clipboard: Got %s: len=%lu left=%lu (event %i)", data, len, left, 50-max_events); return (char*) data; } } logger->log("Clipboard: Timeout"); return NULL; }
bool Dnd::handleDropEvent() { Window win; if (m_DesiredType != 0 && /*time > 0 &&*/ (win = XGetSelectionOwner(m_pDisplay, XdndSelection))) { XConvertSelection(m_pDisplay, XdndSelection, m_DesiredType, XdndActionPrivate, m_Window, m_Time); sendFinished(); return true; } return false; }
bool x_gui_rep::get_selection (string key, tree& t, string& s) { t= "none"; s= ""; bool res=false; if (selection_t->contains (key)) { t= copy (selection_t [key]); s= copy (selection_s [key]); return true; } Atom xsel; if (key == "primary") xsel = XA_CLIPBOARD; else if (key == "mouse") xsel = XA_PRIMARY; else return res; Window selown = XGetSelectionOwner(dpy, xsel); if (selown == None || is_nil (windows_l) || contains (windows_l, selown)) return res; Window win= windows_l->item; x_window x_win= (x_window) Window_to_window[win]; Atom prop= XInternAtom (dpy, "MY_STRING_SELECTION", false); XConvertSelection (dpy, xsel, XA_STRING, prop, win, CurrentTime); int i; XEvent ev; for (i=0; i<1000000; i++) if (XCheckIfEvent (dpy, &ev, my_selnotify_predicate, (XPointer) x_win)) break; if (i==1000000) return res; XSelectionEvent& sel= ev.xselection; if (sel.property==prop) { long offset=0; Atom type; int fm; unsigned long n, remains; unsigned char* ret; do { XGetWindowProperty (dpy, win, sel.property, offset, 1024, true, AnyPropertyType, &type, &fm, &n, &remains, &ret); s << string ((char*) ret, n); offset += (n >> 2); XFree (ret); } while (remains>0); t= tuple ("extern", s); return true; }
/* * Sys_GetClipboardData * * Orginally from EzQuake */ char *Sys_GetClipboardData( qboolean primary ) { Window win; Atom type; int format, ret; unsigned long nitems, bytes_after, bytes_left; unsigned char *data; char *buffer; Atom atom; if( !x11display.dpy ) return NULL; if( primary ) { atom = XInternAtom( x11display.dpy, "PRIMARY", True ); } else { atom = XInternAtom( x11display.dpy, "CLIPBOARD", True ); } if( atom == None ) return NULL; win = XGetSelectionOwner( x11display.dpy, atom ); if( win == None ) return NULL; XConvertSelection( x11display.dpy, atom, XA_utf8_string, atom, win, CurrentTime ); XFlush( x11display.dpy ); XGetWindowProperty( x11display.dpy, win, atom, 0, 0, False, AnyPropertyType, &type, &format, &nitems, &bytes_left, &data ); if( bytes_left <= 0 ) return NULL; ret = XGetWindowProperty( x11display.dpy, win, atom, 0, bytes_left, False, AnyPropertyType, &type, &format, &nitems, &bytes_after, &data ); if( ret == Success ) { buffer = Q_malloc( bytes_left + 1 ); memcpy( buffer, data, bytes_left + 1 ); } else { buffer = NULL; } XFree( data ); return buffer; }
int xdnd_convert_selection(DndClass *dnd, Window window, Window requester, Atom type) { if (window != XGetSelectionOwner (dnd->display, dnd->XdndSelection)) { dnd_debug ("xdnd_convert_selection(): XGetSelectionOwner failed"); return 1; } XConvertSelection (dnd->display, dnd->XdndSelection, type, dnd->Xdnd_NON_PROTOCOL_ATOM, requester, CurrentTime); return 0; }
static uchar* _xgetsnarffrom(XWindow w, Atom clipboard, Atom target, int timeout0, int timeout) { Atom prop, type; ulong len, lastlen, dummy; int fmt, i; uchar *data, *xdata; /* * We should be waiting for SelectionNotify here, but it might never * come, and we have no way to time out. Instead, we will clear * local property #1, request our buddy to fill it in for us, and poll * until he's done or we get tired of waiting. */ prop = 1; XChangeProperty(_x.display, _x.drawable, prop, target, 8, PropModeReplace, (uchar*)"", 0); XConvertSelection(_x.display, clipboard, target, prop, _x.drawable, CurrentTime); XFlush(_x.display); lastlen = 0; timeout0 = (timeout0 + 9)/10; timeout = (timeout + 9)/10; for(i=0; i<timeout0 || (lastlen!=0 && i<timeout); i++){ usleep(10*1000); XGetWindowProperty(_x.display, _x.drawable, prop, 0, 0, 0, AnyPropertyType, &type, &fmt, &dummy, &len, &xdata); if(lastlen == len && len > 0){ XFree(xdata); break; } lastlen = len; XFree(xdata); } if(len == 0) return nil; /* get the property */ xdata = nil; XGetWindowProperty(_x.display, _x.drawable, prop, 0, SnarfSize/sizeof(ulong), 0, AnyPropertyType, &type, &fmt, &len, &dummy, &xdata); if((type != target && type != XA_STRING && type != _x.utf8string) || len == 0){ if(xdata) XFree(xdata); return nil; } if(xdata){ data = (uchar*)strdup((char*)xdata); XFree(xdata); return data; } return nil; }
void Pasteboard::read(PasteboardPlainText &text) { static paster_t *paster = NULL; if (!paster) paster = new paster_t; const Window owner = XGetSelectionOwner(fl_display, XA_PRIMARY); if (owner == None) { text.text = ""; return; } else if (owner == fl_message_window) { Fl::paste(*paster, 0, Fl::clipboard_plain_text); if (paster->text) text.text = paster->text; else text.text = ""; return; } XConvertSelection(fl_display, XA_PRIMARY, XA_STRING, XA_STRING, fl_window, CurrentTime); XFlush(fl_display); unsigned i; Atom target = None; for (i = 0; i < 10; i++) { XEvent ev; XNextEvent(fl_display, &ev); if (ev.type == SelectionNotify) { target = ev.xselection.property; if (target == None) return; break; } } Atom type; int fmt; unsigned long num, bytes = 0, dummy; unsigned char *data; XGetWindowProperty(fl_display, fl_window, XA_STRING, 0, 0, 0, AnyPropertyType, &type, &fmt, &num, &bytes, &data); if (bytes) { int res = XGetWindowProperty(fl_display, fl_window, XA_STRING, 0, bytes, 0, AnyPropertyType, &type, &fmt, &num, &dummy, &data); if (res == Success) { text.text = data; free(data); } } }
void MSWidget::convertSelection(void) { #ifndef MS_WINDOWS XConvertSelection(display(),XA_PRIMARY,XA_STRING, _server->atom(MSAtomTable::MStk),_window,CurrentTime); #else int n; char *buffer=XFetchBytes(display(),&n); if(n!=0) { _server->pasteBuffer(buffer); XFree(buffer); } selectionNotify(0); #endif }
QByteArray QClipboardWatcher::getDataInFormat(Atom fmtatom) const { QByteArray buf; Display *dpy = X11->display; requestor->createWinId(); Window win = requestor->internalWinId(); Q_ASSERT(requestor->testAttribute(Qt::WA_WState_Created)); DEBUG("QClipboardWatcher::getDataInFormat: selection '%s' format '%s'", X11->xdndAtomToString(atom).data(), X11->xdndAtomToString(fmtatom).data()); XSelectInput(dpy, win, NoEventMask); // don't listen for any events XDeleteProperty(dpy, win, ATOM(_QT_SELECTION)); XConvertSelection(dpy, atom, fmtatom, ATOM(_QT_SELECTION), win, X11->time); XSync(dpy, false); VDEBUG("QClipboardWatcher::getDataInFormat: waiting for SelectionNotify event"); XEvent xevent; if (!X11->clipboardWaitForEvent(win,SelectionNotify,&xevent,clipboard_timeout) || xevent.xselection.property == XNone) { DEBUG("QClipboardWatcher::getDataInFormat: format not available"); return buf; } VDEBUG("QClipboardWatcher::getDataInFormat: fetching data..."); Atom type; XSelectInput(dpy, win, PropertyChangeMask); if (X11->clipboardReadProperty(win, ATOM(_QT_SELECTION), true, &buf, 0, &type, 0)) { if (type == ATOM(INCR)) { int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0; buf = X11->clipboardReadIncrementalProperty(win, ATOM(_QT_SELECTION), nbytes, false); } } XSelectInput(dpy, win, NoEventMask); DEBUG("QClipboardWatcher::getDataInFormat: %d bytes received", buf.size()); return buf; }
std::string Clipboard_X11::get_clipboard_text() const { auto handle = x11_window->get_handle(); if (atom_CLIPBOARD == None) { // X Server does not have clipboard support return std::string(); } XConvertSelection(handle.display, atom_CLIPBOARD, XA_STRING, atom_CLIPBOARD, handle.window, CurrentTime); XFlush(handle.display); XEvent event; auto start_time = System::get_time(); while (true) { if (XCheckTypedWindowEvent(handle.display, handle.window, SelectionNotify, &event)) break; // Allow target application half a second of time to respond to this event. // TODO What is the correct way to do this? if ((System::get_time() - start_time) >= 500) { return std::string(); } System::sleep(50); // Sleep for 50ms } Atom actual_type; int actual_format; unsigned long item_count; unsigned char *read_data = X11Atoms::get_property(handle.display, handle.window, atom_CLIPBOARD, actual_type, actual_format, item_count); if (actual_type != XA_STRING || actual_format != 8 || item_count <= 0 || read_data == nullptr) { log_event("debug", "Failed to get X11 CLIPBOARD text."); if (read_data != nullptr) XFree(read_data); return std::string(); } std::string buffer((char *)read_data); XFree(read_data); return buffer; }
bool ClipboardPoll::checkTimestamp( SelectionData& data ) { Window current_owner = XGetSelectionOwner( QX11Info::display(), data.atom ); bool signal = false; updateQtOwnership( data ); if( data.owner_is_qt ) { data.last_change = CurrentTime; #ifdef REALLY_NOISY_KLIPPER_ kDebug() << "(3) Setting last_owner for =" << ( &data==&selection ?"selection":"clipboard" ) << ":" << current_owner; #endif data.last_owner = current_owner; data.waiting_for_timestamp = false; return false; } if( current_owner != data.last_owner ) { signal = true; // owner has changed data.last_owner = current_owner; #ifdef REALLY_NOISY_KLIPPER_ kDebug() << "(4) Setting last_owner for =" << ( &data==&selection ?"selection":"clipboard" ) << ":" << current_owner; #endif data.waiting_for_timestamp = false; data.last_change = CurrentTime; #ifdef REALLY_NOISY_KLIPPER_ kDebug() << "OWNER CHANGE:" << ( data.atom == XA_PRIMARY ) << ":" << current_owner; #endif return true; } if( current_owner == None ) { return false; // None also last_owner... } if( data.waiting_for_timestamp ) { // We're already waiting for the timestamp of the last check return false; } XDeleteProperty( QX11Info::display(), winId(), data.timestamp_atom ); XConvertSelection( QX11Info::display(), data.atom, xa_timestamp, data.timestamp_atom, winId(), QX11Info::appTime() ); data.waiting_for_timestamp = true; data.waiting_x_time = QX11Info::appTime(); #ifdef REALLY_NOISY_KLIPPER_ kDebug() << "WAITING TIMESTAMP:" << ( data.atom == XA_PRIMARY ); #endif return false; }
static void start_paste_from_target(widget_list *widget, int clipboard) { Display *dpy; Window window; SDL_SysWMinfo wminfo; Atom selection; Atom property; SDL_VERSION(&wminfo.version); if (SDL_GetWMInfo(&wminfo) && wminfo.subsystem == SDL_SYSWM_X11) { wminfo.info.x11.lock_func(); dpy = wminfo.info.x11.display; window = wminfo.info.x11.window; paste_to_widget = widget; /* Set selection to XA_PRIMARY to use xterm-style select, * or CLIPBOARD to use Gnome-style cut'n'paste. * KDE3 should use CLIPBOARD also, I'm not sure about older * KDE versions */ if (clipboard) selection = XInternAtom(dpy, "CLIPBOARD", 0); else selection = XA_PRIMARY; property = XInternAtom(dpy, "PASTE", 0); XConvertSelection(dpy, selection, XA_STRING, property, window, CurrentTime); /* - If we used the CLIPBOARD, we don't get a SelectionNotify * event, so we have to call processpaste immediately. * - If we used XA_PRIMARY, the selection-holder will send us a * SelectionNotify-event, as soon as the selection is * available for us. Then finishpaste calls processpaste */ // Alia: we should receive SelectionNotify event, property is NULL until it comes. // Let's try to comment it :) // //if(clipboard) { // processpaste(dpy, window, property); //} wminfo.info.x11.unlock_func(); } }