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 <[email protected]> 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 > [email protected] > http://lists.blender.org/mailman/listinfo/bf-blender-cvs > _______________________________________________ Bf-blender-cvs mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-blender-cvs
