[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(&ltxt[*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