[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20266] branches/blender2.5/blender: Commit revision 20062 and 20109 from trunk, also fix a small memory

Diego Borghetti bdiego at gmail.com
Mon May 18 21:47:04 CEST 2009


Revision: 20266
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20266
Author:   bdiego
Date:     2009-05-18 21:47:04 +0200 (Mon, 18 May 2009)

Log Message:
-----------
Commit revision 20062 and 20109 from trunk, also fix a small memory
error on interface, was try to free an incorrect pointer.

Revision Links:
--------------
    http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20062

Modified Paths:
--------------
    branches/blender2.5/blender/intern/ghost/intern/GHOST_SystemX11.cpp
    branches/blender2.5/blender/intern/ghost/intern/GHOST_SystemX11.h
    branches/blender2.5/blender/source/blender/editors/interface/interface_handlers.c

Modified: branches/blender2.5/blender/intern/ghost/intern/GHOST_SystemX11.cpp
===================================================================
--- branches/blender2.5/blender/intern/ghost/intern/GHOST_SystemX11.cpp	2009-05-18 18:20:29 UTC (rev 20265)
+++ branches/blender2.5/blender/intern/ghost/intern/GHOST_SystemX11.cpp	2009-05-18 19:47:04 UTC (rev 20266)
@@ -117,8 +117,16 @@
 	m_net_fullscreen= XInternAtom(m_display,
 					"_NET_WM_STATE_FULLSCREEN", False);
 	m_motif= XInternAtom(m_display, "_MOTIF_WM_HINTS", 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;
 	if (gettimeofday(&tv,NULL) == -1) {
@@ -1004,144 +1012,298 @@
 
 #undef GXMAP
 
-	GHOST_TUns8*
-GHOST_SystemX11::
-getClipboard(bool selection
-) 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(!selection) {
-		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;
+			// Send a selection request
+			XConvertSelection(m_display, sel, target, m_xclip_out, win, CurrentTime);
+			*context = XCLIB_XCOUT_SENTCONVSEL;
+			return;
+
+		case XCLIB_XCOUT_SENTCONVSEL:
+			if (evt.type != SelectionNotify)
+				return;
+
+			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 {
+				*len += pty_items;
+				ltxt = (unsigned char *) realloc(ltxt, *len);
+			}
+
+			// 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;
+}
+
+GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
+{
+	Atom sseln;
+	Atom target= m_string;
+	Window owner;
+
+	// from xclip.c doOut() v0.11
+	unsigned char *sel_buf;
+	unsigned long sel_len= 0;
+	XEvent evt;
+	unsigned int context= XCLIB_XCOUT_NONE;
+
+	if (selection == True)
+		sseln= m_primary;
+	else
+		sseln= m_clipboard;
+
+	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);
+	Window win = window->getXWindow();
+
+	/* check if we are the owner. */
+	owner= XGetSelectionOwner(m_display, sseln);
+	if (owner == win) {
+		if (sseln == m_clipboard) {
+			sel_buf= (unsigned char *)malloc(strlen(txt_cut_buffer)+1);
+			strcpy((char *)sel_buf, txt_cut_buffer);
+			return((GHOST_TUns8*)sel_buf);
 		}
-	} 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;
+		else {
+			sel_buf= (unsigned char *)malloc(strlen(txt_select_buffer)+1);
+			strcpy((char *)sel_buf, txt_select_buffer);
+			return((GHOST_TUns8*)sel_buf);
 		}
 	}
+	else if (owner == None)
+		return(NULL);
 
-	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);
+	while (1) {
+		/* only get an event if xcout() is doing something */
+		if (context != XCLIB_XCOUT_NONE)
+			XNextEvent(m_display, &evt);
 
-	//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);
-				}
-			}
-			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;
+		/* fetch the selection, or part of it */
+		getClipboard_xcout(evt, sseln, target, &sel_buf, &sel_len, &context);
 
-						XFree(data);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list