[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20062] trunk/blender/intern/ghost/intern: BugFix [#18597] Blender's text editor cant paste from SciTE in linux
Diego B
bdiego at gmail.com
Mon May 4 20:51:12 CEST 2009
Brecht, this maybe give conflict if you merge to the 2.5 branchs, so
you can skipped and I made the same commit there.
On Mon, May 4, 2009 at 3:46 PM, Diego Borghetti <bdiego at gmail.com> wrote:
> Revision: 20062
> http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20062
> Author: bdiego
> Date: 2009-05-04 20:46:34 +0200 (Mon, 04 May 2009)
>
> Log Message:
> -----------
> BugFix [#18597] Blender's text editor cant paste from SciTE in linux
>
> Commit patch [#18597] Blender's text editor cant paste from SciTE in linux
> Submitted by Campbell.
>
> I made some changes to cleanup a little the code, atoms are now in the
> System class. The getClipboard_xcout try to convert/request:
> 1) Request for UTF8, if fail
> 2) Request for COMPOUND_TEXT, if fail
> 3) Request for TEXT, if fail
> 4) Request for STRING
>
> Test here with SciTE Version 1.77, firefox, xterm and text editor working
> with both library's gtk/qt and all work fine.
>
> Modified Paths:
> --------------
> trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp
> trunk/blender/intern/ghost/intern/GHOST_SystemX11.h
>
> Modified: trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp
> ===================================================================
> --- trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp 2009-05-04 18:45:58 UTC (rev 20061)
> +++ trunk/blender/intern/ghost/intern/GHOST_SystemX11.cpp 2009-05-04 18:46:34 UTC (rev 20062)
> @@ -107,6 +107,15 @@
>
> m_wm_protocols= XInternAtom(m_display, "WM_PROTOCOLS", False);
> m_wm_take_focus= XInternAtom(m_display, "WM_TAKE_FOCUS", False);
> + m_targets= XInternAtom(m_display, "TARGETS", False);
> + m_string= XInternAtom(m_display, "STRING", False);
> + m_compound_text= XInternAtom(m_display, "COMPOUND_TEXT", False);
> + m_text= XInternAtom(m_display, "TEXT", False);
> + m_clipboard= XInternAtom(m_display, "CLIPBOARD", False);
> + m_primary= XInternAtom(m_display, "PRIMARY", False);
> + m_xclip_out= XInternAtom(m_display, "XCLIP_OUT", False);
> + m_incr= XInternAtom(m_display, "INCR", False);
> + m_utf8_string= XInternAtom(m_display, "UTF8_STRING", False);
>
> // compute the initial time
> timeval tv;
> @@ -992,144 +1001,280 @@
>
> #undef GXMAP
>
> - GHOST_TUns8*
> -GHOST_SystemX11::
> -getClipboard(int flag
> -) const {
> - //Flag
> - //0 = Regular clipboard 1 = selection
> - static Atom Primary_atom, clip_String, compound_text, a_text, a_string;
> - Atom rtype;
> - Window m_window, owner;
> - unsigned char *data, *tmp_data;
> - int bits, count;
> - unsigned long len, bytes;
> - XEvent xevent;
> -
> +
> +/* from xclip.c xcout() v0.11 */
> +
> +#define XCLIB_XCOUT_NONE 0 /* no context */
> +#define XCLIB_XCOUT_SENTCONVSEL 1 /* sent a request */
> +#define XCLIB_XCOUT_INCR 2 /* in an incr loop */
> +#define XCLIB_XCOUT_FALLBACK 3 /* STRING failed, need fallback to UTF8 */
> +#define XCLIB_XCOUT_FALLBACK_UTF8 4 /* UTF8 failed, move to compouned */
> +#define XCLIB_XCOUT_FALLBACK_COMP 5 /* compouned failed, move to text. */
> +#define XCLIB_XCOUT_FALLBACK_TEXT 6
> +
> +// Retrieves the contents of a selections.
> +void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
> + Atom sel, Atom target, unsigned char **txt,
> + unsigned long *len, unsigned int *context) const
> +{
> + Atom pty_type;
> + int pty_format;
> + unsigned char *buffer;
> + unsigned long pty_size, pty_items;
> + unsigned char *ltxt= *txt;
> +
> vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
> vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
> GHOST_WindowX11 * window = static_cast<GHOST_WindowX11 *>(*win_it);
> - m_window = window->getXWindow();
> + Window win = window->getXWindow();
>
> - clip_String = XInternAtom(m_display, "_BLENDER_STRING", False);
> - compound_text = XInternAtom(m_display, "COMPOUND_TEXT", False);
> - a_text= XInternAtom(m_display, "TEXT", False);
> - a_string= XInternAtom(m_display, "STRING", False);
> + switch (*context) {
> + // There is no context, do an XConvertSelection()
> + case XCLIB_XCOUT_NONE:
> + // Initialise return length to 0
> + if (*len > 0) {
> + free(*txt);
> + *len = 0;
> + }
>
> - //lets check the owner and if it is us then return the static buffer
> - if(flag == 0) {
> - Primary_atom = XInternAtom(m_display, "CLIPBOARD", False);
> - owner = XGetSelectionOwner(m_display, Primary_atom);
> - if (owner == m_window) {
> - data = (unsigned char*) malloc(strlen(txt_cut_buffer)+1);
> - strcpy((char*)data, txt_cut_buffer);
> - return (GHOST_TUns8*)data;
> - } else if (owner == None) {
> - return NULL;
> - }
> - } else {
> - Primary_atom = XInternAtom(m_display, "PRIMARY", False);
> - owner = XGetSelectionOwner(m_display, Primary_atom);
> - if (owner == m_window) {
> - data = (unsigned char*) malloc(strlen(txt_select_buffer)+1);
> - strcpy((char*)data, txt_select_buffer);
> - return (GHOST_TUns8*)data;
> - } else if (owner == None) {
> - return NULL;
> - }
> - }
> + // Send a selection request
> + XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime);
> + *context = XCLIB_XCOUT_SENTCONVSEL;
> + return;
>
> - if(!Primary_atom) {
> - return NULL;
> - }
> -
> - XDeleteProperty(m_display, m_window, Primary_atom);
> - XConvertSelection(m_display, Primary_atom, compound_text, clip_String, m_window, CurrentTime); //XA_STRING
> - XFlush(m_display);
> + case XCLIB_XCOUT_SENTCONVSEL:
> + if (evt.type != SelectionNotify)
> + return;
>
> - //This needs to change so we do not wait for ever or check owner first
> - count= 1;
> - while(1) {
> - XNextEvent(m_display, &xevent);
> - if(xevent.type == SelectionNotify) {
> - if (xevent.xselection.property == None) {
> - /* Ok, the client can't convert the property
> - * to some that we can handle, try other types..
> - */
> - if (count == 1) {
> - XConvertSelection(m_display, Primary_atom, a_text, clip_String, m_window, CurrentTime);
> - count++;
> - }
> - else if (count == 2) {
> - XConvertSelection(m_display, Primary_atom, a_string, clip_String, m_window, CurrentTime);
> - count++;
> - }
> - else {
> - /* Ok, the owner of the selection can't
> - * convert the data to something that we can
> - * handle.
> - */
> - return(NULL);
> - }
> + if (target == m_utf8_string && evt.xselection.property == None) {
> + *context= XCLIB_XCOUT_FALLBACK_UTF8;
> + return;
> }
> + else if (target == m_compound_text && evt.xselection.property == None) {
> + *context= XCLIB_XCOUT_FALLBACK_COMP;
> + return;
> + }
> + else if (target == m_text && evt.xselection.property == None) {
> + *context= XCLIB_XCOUT_FALLBACK_TEXT;
> + return;
> + }
> +
> + // find the size and format of the data in property
> + XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
> + AnyPropertyType, &pty_type, &pty_format,
> + &pty_items, &pty_size, &buffer);
> + XFree(buffer);
> +
> + if (pty_type == m_incr) {
> + // start INCR mechanism by deleting property
> + XDeleteProperty(m_display, win, m_xclip_out);
> + XFlush(m_display);
> + *context = XCLIB_XCOUT_INCR;
> + return;
> + }
> +
> + // if it's not incr, and not format == 8, then there's
> + // nothing in the selection (that xclip understands, anyway)
> +
> + if (pty_format != 8) {
> + *context = XCLIB_XCOUT_NONE;
> + return;
> + }
> +
> + // not using INCR mechanism, just read the property
> + XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
> + False, AnyPropertyType, &pty_type,
> + &pty_format, &pty_items, &pty_size, &buffer);
> +
> + // finished with property, delete it
> + XDeleteProperty(m_display, win, m_xclip_out);
> +
> + // copy the buffer to the pointer for returned data
> + ltxt = (unsigned char *) malloc(pty_items);
> + memcpy(ltxt, buffer, pty_items);
> +
> + // set the length of the returned data
> + *len = pty_items;
> + *txt = ltxt;
> +
> + // free the buffer
> + XFree(buffer);
> +
> + *context = XCLIB_XCOUT_NONE;
> +
> + // complete contents of selection fetched, return 1
> + return;
> +
> + case XCLIB_XCOUT_INCR:
> + // To use the INCR method, we basically delete the
> + // property with the selection in it, wait for an
> + // event indicating that the property has been created,
> + // then read it, delete it, etc.
> +
> + // make sure that the event is relevant
> + if (evt.type != PropertyNotify)
> + return;
> +
> + // skip unless the property has a new value
> + if (evt.xproperty.state != PropertyNewValue)
> + return;
> +
> + // check size and format of the property
> + XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
> + AnyPropertyType, &pty_type, &pty_format,
> + &pty_items, &pty_size, (unsigned char **) &buffer);
> +
> + if (pty_format != 8) {
> + // property does not contain text, delete it
> + // to tell the other X client that we have read
> + // it and to send the next property
> + XFree(buffer);
> + XDeleteProperty(m_display, win, m_xclip_out);
> + return;
> + }
> +
> + if (pty_size == 0) {
> + // no more data, exit from loop
> + XFree(buffer);
> + XDeleteProperty(m_display, win, m_xclip_out);
> + *context = XCLIB_XCOUT_NONE;
> +
> + // this means that an INCR transfer is now
> + // complete, return 1
> + return;
> + }
> +
> + XFree(buffer);
> +
> + // if we have come this far, the propery contains
> + // text, we know the size.
> + XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
> + False, AnyPropertyType, &pty_type, &pty_format,
> + &pty_items, &pty_size, (unsigned char **) &buffer);
> +
> + // allocate memory to accommodate data in *txt
> + if (*len == 0) {
> + *len = pty_items;
> + ltxt = (unsigned char *) malloc(*len);
> + }
> else {
> - if(XGetWindowProperty(m_display, m_window, xevent.xselection.property , 0L, 4096L, False, AnyPropertyType, &rtype, &bits, &len, &bytes, &data) == Success) {
> - if (data) {
> - if (bits == 8 && (rtype == compound_text || rtype == a_text || rtype == a_string)) {
> - tmp_data = (unsigned char*) malloc(strlen((char*)data)+1);
> - strcpy((char*)tmp_data, (char*)data);
> - }
> - else
> - tmp_data= NULL;
> + *len += pty_items;
> + ltxt = (unsigned char *) realloc(ltxt, *len);
> + }
>
> - XFree(data);
> - return (GHOST_TUns8*)tmp_data;
> - }
> - }
> - return(NULL);
> - }
> - }
> + // add data to ltxt
> + memcpy(<xt[*len - pty_items], buffer, pty_items);
> +
> + *txt = ltxt;
> + XFree(buffer);
> +
> + // delete property to get the next item
> + XDeleteProperty(m_display, win, m_xclip_out);
> + XFlush(m_display);
> + return;
> }
> + return;
> }
>
> - void
> -GHOST_SystemX11::
> -putClipboard(
> -GHOST_TInt8 *buffer, int flag) const
> +GHOST_TUns8 *GHOST_SystemX11::getClipboard(int flag) const
> {
> - static Atom Primary_atom;
> - Window m_window, owner;
> + //Flag
> + //0 = Regular clipboard 1 = selection
>
> - if(!buffer) {return;}
> -
> - if(flag == 0) {
> - Primary_atom = XInternAtom(m_display, "CLIPBOARD", False);
> - if(txt_cut_buffer) { free((void*)txt_cut_buffer); }
> + // Options for where to get the selection from
> + Atom sseln= flag ? m_clipboard : m_primary;
> + Atom target= m_string;
> +
> + // from xclip.c doOut() v0.11
> + unsigned char *sel_buf; /* buffer for selection data */
> + unsigned long sel_len= 0; /* length of sel_buf */
> + XEvent evt; /* X Event Structures */
> + unsigned int context= XCLIB_XCOUT_NONE;
> +
> + if (sseln == m_string)
> + sel_buf= (unsigned char *)XFetchBuffer(m_display, (int *)&sel_len, 0);
> + else {
> + while (1) {
> + /* only get an event if xcout() is doing something */
> + if (context != XCLIB_XCOUT_NONE)
> + XNextEvent(m_display, &evt);
> +
> + /* fetch the selection, or part of it */
> + getClipboard_xcout(evt, sseln, target, &sel_buf, &sel_len, &context);
> +
> + /* fallback is needed. set XA_STRING to target and restart the loop. */
> + if (context == XCLIB_XCOUT_FALLBACK) {
> + context= XCLIB_XCOUT_NONE;
> + target= m_string;
> + continue;
> + }
> + else if (context == XCLIB_XCOUT_FALLBACK_UTF8) {
>
> @@ Diff output truncated at 10240 characters. @@
>
> _______________________________________________
> Bf-blender-cvs mailing list
> Bf-blender-cvs at blender.org
> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
>
More information about the Bf-blender-cvs
mailing list