xserver: Branch 'master' - 7 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Fri Sep 26 12:31:43 PDT 2008


 hw/xquartz/X11Application.h      |    1 
 hw/xquartz/X11Application.m      |   78 ++++++--
 hw/xquartz/darwinEvents.c        |   13 -
 hw/xquartz/pbproxy/main.m        |    6 
 hw/xquartz/pbproxy/pbproxy.h     |    3 
 hw/xquartz/pbproxy/x-input.m     |    9 
 hw/xquartz/pbproxy/x-selection.h |    4 
 hw/xquartz/pbproxy/x-selection.m |  376 +++++++++++++++++++++------------------
 hw/xquartz/quartzKeyboard.c      |   75 +++----
 hw/xquartz/quartzKeyboard.h      |    4 
 10 files changed, 314 insertions(+), 255 deletions(-)

New commits:
commit eb8be3e90a9c90a428696026d1e3b2152d7eefb4
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date:   Thu Sep 25 14:16:20 2008 -0600

    XQuartz: pbproxy: Fix another STRING bug.
    
    Fix the usage of the NSString cStringUsingEncoding: - it doesn't NUL
    terminate the string, which lead to a bus error.  So, we use
    lengthOfBytesUsingEncoding: to get the length in bytes instead of
    strlen().
    (cherry picked from commit 6333d619e747c3b6bd3ba7557e35c0e5f6daa40f)

diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 14f6967..b141db0 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -528,7 +528,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     pbtypes = [pb types];
     if (pbtypes)
     {
-	long list[6];
+	long list[6]; /* Don't forget to increase this if we handle more types! */
         long count = 0;
  	
 	if ([pbtypes containsObject:NSStringPboardType])
@@ -619,7 +619,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     {
 	DB ("Latin-1\n");
 	bytes = [data cStringUsingEncoding:NSISOLatin1StringEncoding];
-	length = strlen (bytes);
+	/*WARNING: bytes is not NUL-terminated. */
+	length = [data lengthOfBytesUsingEncoding:NSISOLatin1StringEncoding];
     }
 
     DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
@@ -760,7 +761,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    [self send_reply:&reply];
 	    return;
 	}
-	/*FIXME Why is [bmimage retainCount] 2 here? */
 
 	DB ("bmimage retainCount after initWithData %u\n", [bmimage retainCount]);
 
commit edfa3f8233fde490cb4255f21473684e96d595a3
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date:   Thu Sep 25 12:29:57 2008 -0600

    XQuartz: pbproxy: Fix a bug that rxvt brought out in STRING copying.  Now I can copy and paste to/from rxvt correctly.
    (cherry picked from commit 82a4dc5f0f31a7911ee1cce5d1b162077befa811)

diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 9556032..14f6967 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -890,8 +890,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	return;
     }
 
-    DB ("e->selection %s\n", XGetAtomName (x_dpy, e->selection));
-    DB ("e->property %s\n", XGetAtomName (x_dpy, e->property));
+#if 0
+    printf ("e->selection %s\n", XGetAtomName (x_dpy, e->selection));
+    printf ("e->property %s\n", XGetAtomName (x_dpy, e->property));
+#endif
 
     if ([self is_incr_type:e]) 
     {
@@ -1114,11 +1116,14 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
 
-    if (nil != pbtypes)
+    if (nil == pbtypes)
     {
-	[pb declareTypes:pbtypes owner:nil];
-	[pb setString:string forType:NSStringPboardType];
+	[string autorelease];
+	return;
     }
+
+    [pb declareTypes:pbtypes owner:nil];
+    [pb setString:string forType:NSStringPboardType];
     [string autorelease];
 }
 
@@ -1138,7 +1143,14 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	free_propdata (pdata);
 	return;
     }
- 
+
+#if 0
+    if (None != request_atom)
+	printf ("request_atom %s\n", XGetAtomName (x_dpy, request_atom));
+	       
+    printf ("type %s\n", XGetAtomName (x_dpy, type));
+#endif
+
     if (request_atom == atoms->targets && type == atoms->atom)
     {
 	[self handle_targets:selection propdata:pdata];
@@ -1159,7 +1171,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     {
 	[self handle_string:pdata pasteboard:pb];
     } 
- 
+    
     free_propdata(pdata);
 
     [self copy_completed:selection];
@@ -1244,6 +1256,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     atoms->clipboard = XInternAtom (x_dpy, "CLIPBOARD", False);
     atoms->text = XInternAtom (x_dpy, "TEXT", False);
     atoms->utf8_string = XInternAtom (x_dpy, "UTF8_STRING", False);
+    atoms->string = XInternAtom (x_dpy, "STRING", False);
     atoms->targets = XInternAtom (x_dpy, "TARGETS", False);
     atoms->multiple = XInternAtom (x_dpy, "MULTIPLE", False);
     atoms->cstring = XInternAtom (x_dpy, "CSTRING", False);
commit 12a59c44cb68843a60fc43257930d1cbeb971b7a
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Wed Sep 24 22:51:03 2008 -0700

    XQuartz: Fixed threading issue with TSM.
    (cherry picked from commit 93ab4e0071670bb80bfa1170dd97ed9d6d51c67a)

diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h
index ce3fa7b..0caaba8 100644
--- a/hw/xquartz/X11Application.h
+++ b/hw/xquartz/X11Application.h
@@ -56,7 +56,6 @@
 - (void) prefs_synchronize;
 
 - (OSX_BOOL) x_active;
-
 @end
 
 extern X11Application *X11App;
diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 213d9ed..0436db8 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -39,6 +39,7 @@
 
 #include "darwin.h"
 #include "darwinEvents.h"
+#include "quartzKeyboard.h"
 #include "quartz.h"
 #define _APPLEWM_SERVER_
 #include "X11/extensions/applewm.h"
@@ -61,6 +62,8 @@
 int X11EnableKeyEquivalents = TRUE;
 int quartzHasRoot = FALSE, quartzEnableRootless = TRUE;
 
+static TISInputSourceRef last_key_layout;
+
 extern int darwinFakeButtons;
 extern Bool enable_stereo;
 
@@ -163,8 +166,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) {
 
 - (void) activateX:(OSX_BOOL)state {
     /* Create a TSM document that supports full Unicode input, and
-	 have it activated while X is active (unless using the old
-	 keymapping files) */
+	 have it activated while X is active */
     static TSMDocumentID x11_document;
 	DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active)
     if (state) {
@@ -589,8 +591,8 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) {
 
 - (void) prefs_set_boolean:(NSString *)key value:(int)value {
   CFPreferencesSetValue ((CFStringRef) key,
-			 (CFTypeRef) value ? kCFBooleanTrue
-			 : kCFBooleanFalse, CFSTR (APP_PREFS),
+			 (CFTypeRef) (value ? kCFBooleanTrue
+			 : kCFBooleanFalse), CFSTR (APP_PREFS),
 			 kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
   
 }
@@ -847,9 +849,21 @@ void X11ApplicationMain (int argc, char **argv, char **envp) {
     aquaMenuBarHeight = NSHeight([[NSScreen mainScreen] frame]) -
     NSMaxY([[NSScreen mainScreen] visibleFrame]);
 
+    /* Set the key layout seed before we start the server */
+    last_key_layout = TISCopyCurrentKeyboardLayoutInputSource();
+    
+    if(!last_key_layout) {
+        fprintf(stderr, "X11ApplicationMain: Unable to determine TISCopyCurrentKeyboardLayoutInputSource() at startup.\n");
+    }
+
+    memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
+    if (!QuartzReadSystemKeymap(&keyInfo)) {
+        fprintf(stderr, "X11ApplicationMain: Could not build a valid keymap.\n");
+    }
+
     /* Tell the server thread that it can proceed */
     QuartzInitServer(argc, argv, envp);
-    
+           
     [NSApp run];
     /* not reached */
 }
@@ -880,12 +894,12 @@ static void send_nsevent(NSEvent *e) {
 	NSWindow *window;
 	int pointer_x, pointer_y, ev_button, ev_type;
 	float pressure, tilt_x, tilt_y;
-
+    
 	/* convert location to be relative to top-left of primary display */
 	location = [e locationInWindow];
 	window = [e window];
 	screen = [[[NSScreen screens] objectAtIndex:0] frame];
-
+    
     if (window != nil)	{
 		NSRect frame = [window frame];
 		pointer_x = location.x + frame.origin.x;
@@ -895,18 +909,18 @@ static void send_nsevent(NSEvent *e) {
 		pointer_x = location.x;
 		pointer_y = (screen.origin.y + screen.size.height) - location.y;
 	}
-
+    
 	pressure = 0;  // for tablets
 	tilt_x = 0;
 	tilt_y = 0;
-
+    
     /* We don't receive modifier key events while out of focus, and 3button
      * emulation mucks this up, so we need to check our modifier flag state
      * on every event... ugg
      */
     if(darwin_modifier_flags != [e modifierFlags])
         DarwinUpdateModKeys([e modifierFlags]);
-
+    
 	switch ([e type]) {
 		case NSLeftMouseDown:     ev_button=1; ev_type=ButtonPress;   goto handle_mouse;
 		case NSOtherMouseDown:    ev_button=2; ev_type=ButtonPress;   goto handle_mouse;
@@ -919,7 +933,7 @@ static void send_nsevent(NSEvent *e) {
 		case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify;  goto handle_mouse;
 		case NSMouseMoved:        ev_button=0; ev_type=MotionNotify;  goto handle_mouse;
         case NSTabletPoint:       ev_button=0; ev_type=MotionNotify;  goto handle_mouse;
-
+            
         handle_mouse:
 			if ([e type] == NSTabletPoint || [e subtype] == NSTabletPointEventSubtype) {
                 pressure = [e pressure];
@@ -941,16 +955,16 @@ static void send_nsevent(NSEvent *e) {
                         darwinTabletCurrent=darwinTabletCursor;
                         break;
                 }
-
+                
                 DarwinSendProximityEvents([e isEnteringProximity]?ProximityIn:ProximityOut,
                                           pointer_x, pointer_y);
             }
-
+            
             DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y,
                                     pressure, tilt_x, tilt_y);
-
+            
             break;
-
+            
 		case NSTabletProximity:
             switch([e pointingDeviceType]) {
                 case NSEraserPointingDevice:
@@ -965,20 +979,44 @@ static void send_nsevent(NSEvent *e) {
                     darwinTabletCurrent=darwinTabletCursor;
                     break;
             }
-                    
+            
 			DarwinSendProximityEvents([e isEnteringProximity]?ProximityIn:ProximityOut,
                                       pointer_x, pointer_y);
             break;
-
+            
 		case NSScrollWheel:
 			DarwinSendScrollEvents([e deltaX], [e deltaY], pointer_x, pointer_y,
                                    pressure, tilt_x, tilt_y);
             break;
-
-		case NSKeyDown: case NSKeyUp:
+            
+        case NSKeyDown: case NSKeyUp:
+            if(darwinSyncKeymap) {
+                TISInputSourceRef key_layout = TISCopyCurrentKeyboardLayoutInputSource();
+                TISInputSourceRef clear;
+                if (CFEqual(key_layout, last_key_layout)) {
+                    CFRelease(key_layout);
+                } else {
+                    /* Swap/free thread-safely */
+                    clear = last_key_layout;
+                    last_key_layout = key_layout;
+                    CFRelease(clear);
+
+                    /* Update keyInfo */
+                    pthread_mutex_lock(&keyInfo_mutex);
+                    memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
+                    if (!QuartzReadSystemKeymap(&keyInfo)) {
+                        fprintf(stderr, "sendX11NSEvent: Could not build a valid keymap.\n");
+                    }
+                    pthread_mutex_unlock(&keyInfo_mutex);
+                    
+                    /* Tell server thread to deal with new keyInfo */
+                    DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
+                }
+            }
+            
             DarwinSendKeyboardEvents(([e type] == NSKeyDown) ? KeyPress : KeyRelease, [e keyCode]);
             break;
-
+            
         default: break; /* for gcc */
 	}	
 }
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 1db61d9..729cc9a 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -473,19 +473,6 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
 		return;
 	}
 
-	if (darwinSyncKeymap) {
-		/* See if keymap has changed. */
-
-		static unsigned int last_seed;
-		unsigned int this_seed;
-
-		this_seed = QuartzSystemKeymapSeed();
-		if (this_seed != last_seed) {
-			last_seed = this_seed;
-			DarwinSendDDXEvent(kXquartzReloadKeymap, 0);
-		}
-	}
-
     darwinEvents_lock(); {
         num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE);
         for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard,&darwinEvents[i]);
diff --git a/hw/xquartz/quartzKeyboard.c b/hw/xquartz/quartzKeyboard.c
index cee582b..cd46fb2 100644
--- a/hw/xquartz/quartzKeyboard.c
+++ b/hw/xquartz/quartzKeyboard.c
@@ -52,6 +52,8 @@
 #include "quartzKeyboard.h"
 #include "quartzAudio.h"
 
+#include "threadSafety.h"
+
 #ifdef NDEBUG
 #undef NDEBUG
 #include <assert.h>
@@ -59,6 +61,7 @@
 #else
 #include <assert.h>
 #endif
+#include <pthread.h>
 
 #include "xkbsrv.h"
 #include "exevents.h"
@@ -304,6 +307,7 @@ const static struct {
 };
 
 darwinKeyboardInfo keyInfo;
+pthread_mutex_t keyInfo_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 static void DarwinChangeKeyboardControl( DeviceIntPtr device, KeybdCtrl *ctrl )
 {
@@ -411,18 +415,16 @@ static void DarwinBuildModifierMaps(darwinKeyboardInfo *info) {
  *  it to an equivalent X keyboard map and modifier map.
  */
 static void DarwinLoadKeyboardMapping(KeySymsRec *keySyms) {
-    memset(keyInfo.keyMap, 0, sizeof(keyInfo.keyMap));
-
-    if (!QuartzReadSystemKeymap(&keyInfo)) {
-        FatalError("Could not build a valid keymap.");
-    }
-
+    pthread_mutex_lock(&keyInfo_mutex);
+    
     DarwinBuildModifierMaps(&keyInfo);
 
     keySyms->map        = keyInfo.keyMap;
     keySyms->mapWidth   = GLYPHS_PER_KEY;
     keySyms->minKeyCode = MIN_KEYCODE;
     keySyms->maxKeyCode = MAX_KEYCODE;
+
+    pthread_mutex_unlock(&keyInfo_mutex);
 }
 
 void QuartzXkbUpdate(DeviceIntPtr pDev) {
@@ -450,27 +452,27 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) {
     assert( darwinParamConnect = NXOpenEventStatus() );
 
     DarwinLoadKeyboardMapping(&keySyms);
-    /* Initialize the seed, so we don't reload the keymap unnecessarily
-       (and possibly overwrite xinitrc changes) */
-    QuartzSystemKeymapSeed();
-
 #ifdef XQUARTZ_USE_XKB
 	XkbComponentNamesRec names;
 	bzero(&names, sizeof(names));
     /* We need to really have rules... or something... */
     XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
+    pthread_mutex_lock(&keyInfo_mutex);
     assert(XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, keyInfo.modMap,
                                         QuartzBell, DarwinChangeKeyboardControl));
 	assert(SetKeySymsMap(&pDev->key->curKeySyms, &keySyms));
 	assert(keyInfo.modMap!=NULL);
 	assert(pDev->key->modifierMap!=NULL);
 	memcpy(pDev->key->modifierMap, keyInfo.modMap, sizeof(keyInfo.modMap));
+    pthread_mutex_unlock(&keyInfo_mutex);
 	
 	QuartzXkbUpdate(pDev);
 #else
+    pthread_mutex_lock(&keyInfo_mutex);
     assert( InitKeyboardDeviceStruct( (DevicePtr)pDev, &keySyms,
                                       keyInfo.modMap, QuartzBell,
                                       DarwinChangeKeyboardControl ));
+    pthread_mutex_unlock(&keyInfo_mutex);
     SwitchCoreKeyboard(pDev);
 #endif
 }
@@ -492,11 +494,14 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
         if (pDev->key->modifierKeyMap) xfree(pDev->key->modifierKeyMap);
         xfree(pDev->key);
     }
-    
+
+    pthread_mutex_lock(&keyInfo_mutex);
     if (!InitKeyClassDeviceStruct(pDev, &keySyms, keyInfo.modMap)) {
         DEBUG_LOG("InitKeyClassDeviceStruct failed\n");
+        pthread_mutex_unlock(&keyInfo_mutex);
         return;
     }
+    pthread_mutex_unlock(&keyInfo_mutex);
 
     SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0);
     SendMappingNotify(MappingModifier, 0, 0, 0);
@@ -521,7 +526,12 @@ void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr pDev,
  *      Returns 0 if key+side is not a known modifier.
  */
 int DarwinModifierNXKeyToNXKeycode(int key, int side) {
-    return keyInfo.modifierKeycodes[key][side];
+    int retval;
+    pthread_mutex_lock(&keyInfo_mutex);
+    retval = keyInfo.modifierKeycodes[key][side];
+    pthread_mutex_unlock(&keyInfo_mutex);
+
+    return retval;
 }
 
 /*
@@ -532,6 +542,7 @@ int DarwinModifierNXKeyToNXKeycode(int key, int side) {
 int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) {
     int key, side;
 
+    pthread_mutex_lock(&keyInfo_mutex);
     keycode += MIN_KEYCODE;
     // search modifierKeycodes for this keycode+side
     for (key = 0; key < NX_NUMMODIFIERS; key++) {
@@ -539,8 +550,13 @@ int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide) {
             if (keyInfo.modifierKeycodes[key][side] == keycode) break;
         }
     }
-    if (key == NX_NUMMODIFIERS) return -1;
+    if (key == NX_NUMMODIFIERS) {
+        pthread_mutex_unlock(&keyInfo_mutex);
+        return -1;
+    }
     if (outSide) *outSide = side;
+
+    pthread_mutex_unlock(&keyInfo_mutex);
     return key;
 }
 
@@ -666,39 +682,6 @@ Bool LegalModifier(unsigned int key, DeviceIntPtr pDev)
     return 1;
 }
 
-/* TODO: Not thread safe */
-unsigned int QuartzSystemKeymapSeed(void) {
-    static unsigned int seed = 0;
-//#if defined(__x86_64__) || defined(__ppc64__)
-#if 1
-    static TISInputSourceRef last_key_layout = NULL;
-    TISInputSourceRef key_layout;
-
-    key_layout = TISCopyCurrentKeyboardLayoutInputSource();
-
-    if(last_key_layout) {
-        if (CFEqual(key_layout, last_key_layout)) {
-            CFRelease(key_layout);
-        } else {
-            seed++;
-            CFRelease(last_key_layout);
-            last_key_layout = key_layout;
-        }
-    } else {
-        last_key_layout = key_layout;
-    }
-#else
-    static KeyboardLayoutRef last_key_layout;
-    KeyboardLayoutRef key_layout;
-
-    KLGetCurrentKeyboardLayout (&key_layout);
-    if (key_layout != last_key_layout)
-        seed++;
-    last_key_layout = key_layout;
-#endif
-    return seed;
-}
-
 static inline UniChar macroman2ucs(unsigned char c) {
     /* Precalculated table mapping MacRoman-128 to Unicode. Generated
        by creating single element CFStringRefs then extracting the
diff --git a/hw/xquartz/quartzKeyboard.h b/hw/xquartz/quartzKeyboard.h
index d62a79d..eb79366 100644
--- a/hw/xquartz/quartzKeyboard.h
+++ b/hw/xquartz/quartzKeyboard.h
@@ -32,6 +32,8 @@
 #include "X11/keysym.h"
 #include "inputstr.h"
 
+#include <pthread.h>
+
 // Each key can generate 4 glyphs. They are, in order:
 // unshifted, shifted, modeswitch unshifted, modeswitch shifted
 #define GLYPHS_PER_KEY  4
@@ -47,10 +49,10 @@ typedef struct darwinKeyboardInfo_struct {
 
 /* These functions need to be implemented by Xquartz, XDarwin, etc. */
 Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info);
-unsigned int QuartzSystemKeymapSeed(void);
 
 /* Provided for darwinEvents.c */
 extern darwinKeyboardInfo keyInfo;
+extern pthread_mutex_t keyInfo_mutex;
 void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents);
 void DarwinKeyboardInit(DeviceIntPtr pDev);
 int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide);
commit ee87c9b02401a7a08b396884ba412a503b078bbd
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Wed Sep 24 18:57:36 2008 -0700

    XQuartz: pbproxy: Removed stray SPI include.
    (cherry picked from commit 2fb2bc77b804d7b63002c1423cb0bfc658eeee45)

diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m
index 9bf19f0..32b325f 100644
--- a/hw/xquartz/pbproxy/main.m
+++ b/hw/xquartz/pbproxy/main.m
@@ -10,7 +10,6 @@
 #include <unistd.h> /*for getpid*/
 
 #include <X11/extensions/applewm.h>
-#include <HIServices/CoreDockServices.h>
 
 Display *x_dpy;
 int x_apple_wm_event_base, x_apple_wm_error_base;
commit 591cc57627a9137159fb5a13287c1d61d8d2fc8c
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date:   Tue Sep 23 13:59:25 2008 -0600

    XQuartz: pbproxy: Fix 3 paths that could leak memory.
    
    2 of the paths leaked, when INCR transfers were done.  Now we
    are leak free according to the leaks program for all transfers
    I have tried so far.
    (cherry picked from commit aa98db576bc02f0765cb35d0282a894ba3778213)

diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 7e4bd7c..9556032 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -110,9 +110,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     if(None == property)
 	return True;
     
-    do {
-	unsigned long newbuflen;
-	unsigned char *newbuf;
+    do 
+    {
+	unsigned long newbuflen = 0;
+	unsigned char *newbuf = NULL;
 	
 #ifdef TEST   
 	printf("bytesleft %lu\n", bytesleft);
@@ -122,8 +123,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 					   offset, length, delete, 
 					   AnyPropertyType,
 					   type, &format, &numitems, 
-					   &bytesleft, &chunk)) {
+					   &bytesleft, &chunk)) 
+	{
 	    DB ("Error while getting window property.\n");
+	    *pdata = null_propdata;
 	    free (buf);
 	    return True;
 	}
@@ -141,10 +144,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 #ifdef TEST
 	printf("chunkbytesize %zu\n", chunkbytesize);
 #endif
-	
 	newbuflen = buflen + chunkbytesize;
 	newbuf = realloc (buf, newbuflen);
-	if (NULL == newbuf) {
+
+	if (NULL == newbuf)
+	{
 	    XFree (chunk);
 	    free (buf);
 	    return True;
@@ -837,7 +841,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     }
     else if (e->target == atoms->multiple)
     {
-	/* This isn't finished, and may never be, unless I can find a good app. */
+	/*
+	 * This isn't finished, and may never be, unless I can find 
+	 * a good test app.
+	 */
 	[self send_multiple:e];
     } 
     else if (e->target == atoms->utf8_string)
@@ -954,14 +961,16 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	{
 	    /* We completed the transfer. */
 	    [self handle_selection:pending.selection type:type propdata:&pending.propdata];
+	    free_propdata(&pdata);
 	    pending.propdata = null_propdata;
 	    pending.requestor = None;
 	    pending.selection = None;
-	} 
+	}
 	else 
 	{
 	    [self append_to_pending:&pdata requestor:e->window];
-	}       
+	    free_propdata (&pdata);
+	}
     }
 }
 
@@ -1084,7 +1093,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     [pb declareTypes:pbtypes owner:nil];
     
     if (YES != [pb setString:string forType:NSStringPboardType]) {
-	DB ("_pasteboard setString:forType: failed!\n");
+	DB ("pasteboard setString:forType: failed!\n");
     }
     [string autorelease];
     DB ("done handling utf8 string\n");
@@ -1126,6 +1135,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     if (nil == pb) 
     {
 	[self copy_completed:selection];
+	free_propdata (pdata);
 	return;
     }
  
commit 586fbc91df731150ff5e39170efe33f3cfac28a2
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date:   Tue Sep 23 12:39:32 2008 -0600

    XQuartz: pbproxy: Fix NSObject memory leaks by properly using the
    NSAutoreleasePool.   Now the usage is consistent.  In x_input_run()
    we create a pool, and release it after processing the XEvents.
    
    Add some getpid() output to main for debugging.  It needs a bit more
    testing before the next release.
    
    Don't retain the NSPasteboard as the old code did.  That may have
    contributed to the leak, and it made it so that we needed the
    NSAutoreleasePool created in main().
    
    Remove the _known_types, and _pasteboard instance variables from
    the x_selection class.  They aren't needed anymore.
    
    The leaks program now indicates 0 leaks after some usage.  I want
    to test further, but this seems much better, and my memory usage
    graph indicates it's not growing.
    (cherry picked from commit b245d84a72ee3929546cd11a6eba3c60fb4a4d95)

diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m
index 6d49070..9bf19f0 100644
--- a/hw/xquartz/pbproxy/main.m
+++ b/hw/xquartz/pbproxy/main.m
@@ -7,6 +7,7 @@
 #import "x-selection.h"
 
 #include <pthread.h>
+#include <unistd.h> /*for getpid*/
 
 #include <X11/extensions/applewm.h>
 #include <HIServices/CoreDockServices.h>
@@ -130,9 +131,7 @@ static void signal_handler (int sig) {
 }
 
 int main (int argc, const char *argv[]) {
-    NSAutoreleasePool *pool;
-
-    pool = [[NSAutoreleasePool alloc] init];
+    printf("pid: %u\n", getpid());
     
     x_init ();
     
diff --git a/hw/xquartz/pbproxy/x-input.m b/hw/xquartz/pbproxy/x-input.m
index 5261212..fd59881 100644
--- a/hw/xquartz/pbproxy/x-input.m
+++ b/hw/xquartz/pbproxy/x-input.m
@@ -49,6 +49,13 @@ static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) {
 }
 
 void x_input_run (void) {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    if (nil == pool) 
+    {
+	fprintf(stderr, "unable to allocate/init auto release pool!\n");
+	return;
+    }
 
     while (XPending (x_dpy) != 0) {
         XEvent e;       
@@ -82,6 +89,8 @@ void x_input_run (void) {
 
 	XFlush(x_dpy);
     }
+
+    [pool release];
 }
 
 static int add_input_socket (int sock, CFOptionFlags callback_types,
diff --git a/hw/xquartz/pbproxy/x-selection.h b/hw/xquartz/pbproxy/x-selection.h
index 06910b4..1bb1f10 100644
--- a/hw/xquartz/pbproxy/x-selection.h
+++ b/hw/xquartz/pbproxy/x-selection.h
@@ -54,10 +54,6 @@ struct atom_list {
     /* The unmapped window we use for fetching selections. */
     Window _selection_window;
 
-    /* Cached general pasteboard and array of types we can handle. */
-    NSPasteboard *_pasteboard;
-    NSArray *_known_types;
-
     /* Last time we declared anything on the pasteboard. */
     int _my_last_change;
 
diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 5e40613..7e4bd7c 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -302,10 +302,18 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 {
     static NSInteger changeCount;
     NSInteger countNow;
+    NSPasteboard *pb;
 
     TRACE ();
 
-    countNow = [_pasteboard changeCount];
+    pb = [NSPasteboard generalPasteboard];
+
+    if (nil == pb)
+    {
+	return;
+    }
+
+    countNow = [pb changeCount];
 
     if (countNow != changeCount)
     {
@@ -317,8 +325,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     }
 
 #if 0
-    if ([_pasteboard changeCount] != _my_last_change)
-    {
 	/*gstaplin: we should perhaps investigate something like this branch above...*/
 	if ([_pasteboard availableTypeFromArray: _known_types] != nil)
 	{
@@ -330,7 +336,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    XSetSelectionOwner (x_dpy, XA_PRIMARY,
 				_selection_window, timestamp);
 	}
-    }
 #endif
 }
 
@@ -379,7 +384,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 /*
- *
+ * Set pbproxy as owner of the SELECTION_MANAGER selection.
+ * This prevents tools like xclipboard from causing havoc.
  */
 - (void) set_clipboard_manager
 {
@@ -508,19 +514,19 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
  * (in Latin-1 encoding).  The requestor can then make the choice based on
  * the list.
  */
-- (void) send_targets:(XSelectionRequestEvent *)e
+- (void) send_targets:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
 
     [self init_reply:&reply request:e];
 
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
     if (pbtypes)
     {
 	long list[6];
         long count = 0;
-	
+ 	
 	if ([pbtypes containsObject:NSStringPboardType])
 	{
 	    /* We have a string type that we can convert to UTF8, or Latin-1... */
@@ -561,7 +567,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 
-- (void) send_string:(XSelectionRequestEvent *)e utf8:(BOOL)utf8
+- (void) send_string:(XSelectionRequestEvent *)e utf8:(BOOL)utf8 pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
@@ -573,7 +579,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     [self init_reply:&reply request:e];
 
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
  
     if (![pbtypes containsObject:NSStringPboardType])
     {
@@ -583,7 +589,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     DB ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]);
 
-    data = [_pasteboard stringForType:NSStringPboardType];
+    data = [pb stringForType:NSStringPboardType];
 
     if (nil == data)
     {
@@ -591,7 +597,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	return;
     }
 
-
     if (utf8) 
     {
 	bytes = [data UTF8String];
@@ -620,12 +625,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     
     reply.xselection.property = e->property;
 
-    DB ("data retainCount before release %u\n", [data retainCount]);
-    [data release];
     [self send_reply:&reply];
 }
 
-- (void) send_compound_text:(XSelectionRequestEvent *)e
+- (void) send_compound_text:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
@@ -634,11 +637,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     
     [self init_reply:&reply request:e];
      
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
 
     if ([pbtypes containsObject: NSStringPboardType])
     {
-	NSString *data = [_pasteboard stringForType:NSStringPboardType];
+	NSString *data = [pb stringForType:NSStringPboardType];
 	if (nil != data)
 	{
 	    /*
@@ -671,7 +674,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    if (textprop.value)
  		XFree (textprop.value);
 
-	    [data release];
 	}
     }
     
@@ -696,7 +698,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 
-- (void) send_image:(XSelectionRequestEvent *)e
+- (void) send_image:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
@@ -708,7 +710,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     [self init_reply:&reply request:e];
 
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
 
     if (pbtypes) 
     {
@@ -734,7 +736,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	return;
     }
 
-    data = [_pasteboard dataForType:type];
+    data = [pb dataForType:type];
 
     if (nil == data)
     {
@@ -751,7 +753,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 	if (nil == bmimage)
 	{
-	    [data release];
 	    [self send_reply:&reply];
 	    return;
 	}
@@ -775,20 +776,15 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    
 	    DB ("changed property for %s\n", XGetAtomName (x_dpy, e->target));
 	    DB ("encdata retainCount %u\n", [encdata retainCount]);
-	    [encdata release];
-	    [bmimage release];
 	}
 	DB ("dict retainCount before release %u\n", [dict retainCount]);
-	
-	[dict release];
+	[dict autorelease];
 
-	
 	DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
-	/*FIXME Why on earth is retainCount 3? */
-	[bmimage release];
-	[bmimage release];
+	
+	[bmimage autorelease];
     }
-    [data release];
+
     [self send_reply:&reply];
 }
 
@@ -806,6 +802,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 /* Another client requested the data or targets of data available from the clipboard. */
 - (void)request_event:(XSelectionRequestEvent *)e
 {
+    NSPasteboard *pb;
+
     TRACE ();
 
     /* TODO We should also keep track of the time of the selection, and 
@@ -820,29 +818,39 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     /*TODO we need a COMPOUND_TEXT test app*/
     /*TODO we need a MULTIPLE test app*/
+
+    pb = [NSPasteboard generalPasteboard];
+    if (nil == pb) 
+    {
+	[self send_none:e];
+	return;
+    }
+    
+
     if (None != e->target)
 	DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
 
     if (e->target == atoms->targets) 
     {
 	/* The paste requestor wants to know what TARGETS we support. */
-	[self send_targets:e];
+	[self send_targets:e pasteboard:pb];
     }
     else if (e->target == atoms->multiple)
     {
+	/* This isn't finished, and may never be, unless I can find a good app. */
 	[self send_multiple:e];
     } 
     else if (e->target == atoms->utf8_string)
     {
-	[self send_string:e utf8:YES];
+	[self send_string:e utf8:YES pasteboard:pb];
     } 
     else if (e->target == atoms->string)
     {
-	[self send_string:e utf8:NO];
+	[self send_string:e utf8:NO pasteboard:pb];
     }
     else if (e->target == atoms->compound_text)
     {
-	[self send_compound_text:e];
+	[self send_compound_text:e pasteboard:pb];
     }
     else if (e->target == atoms->multiple)
     {
@@ -850,9 +858,9 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     }
     else if (e->target == atoms->image_png || e->target == atoms->image_jpeg)
     {
-	[self send_image:e];
+	[self send_image:e pasteboard:pb];
     }
-    else 
+    else
     {
 	[self send_none:e];
     }
@@ -983,7 +991,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 /* This handles the image type of selection (typically in CLIPBOARD). */
 /* We convert to a TIFF, so that other applications can paste more easily. */
-- (void) handle_image: (struct propdata *)pdata
+- (void) handle_image: (struct propdata *)pdata pasteboard:(NSPasteboard *)pb
 {
     NSArray *pbtypes;
     NSUInteger length;
@@ -1008,7 +1016,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (nil == bmimage)
     {
-	[data release];
+	[data autorelease];
 	DB ("unable to create NSBitmapImageRep!\n");
 	return;
     }
@@ -1024,10 +1032,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     @catch (NSException *e) 
     {
 	DB ("NSTIFFException!\n");
-	[data release];
-	[bmimage release];
-	/*WHY 2?*/
-	[bmimage release];
+	[data autorelease];
+	[bmimage autorelease];
 	return;
     }
     
@@ -1037,40 +1043,29 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (nil == pbtypes)
     {
-	[tiff release];
-	[data release];
-	[bmimage release];
-	/* WHY is the object with a retainCount of 2 after initWithData? */
-	[bmimage release];
+	[data autorelease];
+	[bmimage autorelease];
 	return;
     }
 
- 
-    [_pasteboard declareTypes:pbtypes owner:self];
-    if (YES != [_pasteboard setData:tiff forType:NSTIFFPboardType])
+    [pb declareTypes:pbtypes owner:nil];
+    if (YES != [pb setData:tiff forType:NSTIFFPboardType])
     {
 	DB ("writing pasteboard data failed!\n");
     }
 
-    [pbtypes release];
-    [data release];
-
-    DB ("tiff retainCount before release %u\n", [tiff retainCount]);
-    [tiff release];
+    [data autorelease];
 
     DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
-    /*WHY 3?*/
-    [bmimage release];
-    [bmimage release];
-    [bmimage release];
+    [bmimage autorelease];
 }
 
 /* This handles the UTF8_STRING type of selection. */
-- (void) handle_utf8_string: (struct propdata *)pdata
+- (void) handle_utf8_string:(struct propdata *)pdata pasteboard:(NSPasteboard *)pb
 {
     NSString *string;
     NSArray *pbtypes;
-
+ 
     TRACE ();
 
     string = [[NSString alloc] initWithBytes:pdata->data length:pdata->length encoding:NSUTF8StringEncoding];
@@ -1078,26 +1073,25 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     if (nil == string)
 	return;
 
-    DB ("string retainCount is %u\n", [string retainCount]);
-
     pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
 
-    if (nil != pbtypes)
+    if (nil == pbtypes)
     {
-	[_pasteboard declareTypes:pbtypes owner:self];
-
-	if (YES != [_pasteboard setString:string forType:NSStringPboardType]) {
-	    DB ("_pasteboard setString:forType: failed!\n");
-	}
-	[pbtypes release];
+	[string autorelease];
+	return;	
     }
-    [string release];
 
+    [pb declareTypes:pbtypes owner:nil];
+    
+    if (YES != [pb setString:string forType:NSStringPboardType]) {
+	DB ("_pasteboard setString:forType: failed!\n");
+    }
+    [string autorelease];
     DB ("done handling utf8 string\n");
 }
 
 /* This handles the STRING type, which should be in Latin-1. */
-- (void) handle_string: (struct propdata *)pdata
+- (void) handle_string: (struct propdata *)pdata pasteboard:(NSPasteboard *)pb
 {
     NSString *string; 
     NSArray *pbtypes;
@@ -1113,47 +1107,55 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (nil != pbtypes)
     {
-	[_pasteboard declareTypes:pbtypes owner:self];
-	[_pasteboard setString:string forType:NSStringPboardType];
-
-	DB ("pbtypes retainCount %u\n", [pbtypes retainCount]);
-	[pbtypes release];
+	[pb declareTypes:pbtypes owner:nil];
+	[pb setString:string forType:NSStringPboardType];
     }
-    [string release];
+    [string autorelease];
 }
 
 /* This is called when the selection is completely retrieved from another client. */
 /* Warning: this frees the propdata. */
 - (void) handle_selection:(Atom)selection type:(Atom)type propdata:(struct propdata *)pdata
 {
+    NSPasteboard *pb;
+
     TRACE ();
 
+    pb = [NSPasteboard generalPasteboard];
+
+    if (nil == pb) 
+    {
+	[self copy_completed:selection];
+	return;
+    }
+ 
     if (request_atom == atoms->targets && type == atoms->atom)
     {
 	[self handle_targets:selection propdata:pdata];
     } 
     else if (type == atoms->image_png)
     {
-	[self handle_image:pdata];
+	[self handle_image:pdata pasteboard:pb];
     } 
     else if (type == atoms->image_jpeg)
     {
-	[self handle_image:pdata];
+	[self handle_image:pdata pasteboard:pb];
     }
     else if (type == atoms->utf8_string) 
     {
-	[self handle_utf8_string:pdata];
+	[self handle_utf8_string:pdata pasteboard:pb];
     } 
     else if (type == atoms->string)
     {
-	[self handle_string:pdata];
+	[self handle_string:pdata pasteboard:pb];
     } 
  
     free_propdata(pdata);
-    
+
     [self copy_completed:selection];
 }
 
+
 - (void) copy_completed:(Atom)selection
 {
     TRACE ();
@@ -1243,11 +1245,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     atoms->compound_text = XInternAtom (x_dpy, "COMPOUND_TEXT", False);
     atoms->atom_pair = XInternAtom (x_dpy, "ATOM_PAIR", False);
 
-    _pasteboard = [[NSPasteboard generalPasteboard] retain];
-
-    //_known_types = [[NSArray arrayWithObject:NSStringPboardType] retain];
-    _known_types = nil;
-
     pixel = BlackPixel (x_dpy, DefaultScreen (x_dpy));
     _selection_window = XCreateSimpleWindow (x_dpy, DefaultRootWindow (x_dpy),
 					     0, 0, 1, 1, 0, pixel, pixel);
@@ -1269,14 +1266,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 - (void) dealloc
 {
-
-    [_pasteboard releaseGlobally];
-    [_pasteboard release];
-    _pasteboard = nil;
-
-    //[_known_types release];
-    _known_types = nil;
-
     if (None != _selection_window)
     {
 	XDestroyWindow (x_dpy, _selection_window);
commit 238999cfc99dbf306184f0e846465a8707bcc9d2
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date:   Mon Sep 22 17:36:21 2008 -0600

    XQuartz: pbproxy: Add a comment to pbproxy.h about how the DB()
    macro causes a leak (according to the leaks program).
    
    Attempt to fix several other leaks with release method calls.
    For some reason the process still grows more than it should...
    
    I will need to use some better methods than leaks, and malloc_history
    I suspect.  Whatever is leaking, it's hard to find.  I need to isolate
    the cases more.
    
    Add a missing image/jpeg branch.
    
    Remove read_prop_32 - it's not used.
    (cherry picked from commit 63a680354dcb545fef935ac97596dd35ceaed960)

diff --git a/hw/xquartz/pbproxy/pbproxy.h b/hw/xquartz/pbproxy/pbproxy.h
index 56111f9..b8fbccb 100644
--- a/hw/xquartz/pbproxy/pbproxy.h
+++ b/hw/xquartz/pbproxy/pbproxy.h
@@ -12,7 +12,7 @@
 #include <X11/extensions/shape.h>
 #undef   Cursor
 
-#define DEBUG 1
+#define DEBUG 0
 
 /* from main.m */
 extern void x_set_is_active (BOOL state);
@@ -30,6 +30,7 @@ extern void x_input_run (void);
 #if DEBUG == 0
 # define DB(msg, args...) do {} while (0)
 #else
+/* BEWARE: this can cause a string memory leak, according to the leaks program. */
 # define DB(msg, args...) debug_printf("%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args)
 #endif
 
diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 350b347..5e40613 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -1,7 +1,7 @@
 /* x-selection.m -- proxies between NSPasteboard and X11 selections
    $Id: x-selection.m,v 1.9 2006-07-07 18:24:28 jharper Exp $
 
-   Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+   Copyright (c) 2002, 2008 Apple Computer, Inc. All rights reserved.
 
    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation files
@@ -114,11 +114,16 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	unsigned long newbuflen;
 	unsigned char *newbuf;
 	
+#ifdef TEST   
+	printf("bytesleft %lu\n", bytesleft);
+#endif
+
 	if (Success != XGetWindowProperty (x_dpy, win, property,
 					   offset, length, delete, 
 					   AnyPropertyType,
 					   type, &format, &numitems, 
 					   &bytesleft, &chunk)) {
+	    DB ("Error while getting window property.\n");
 	    free (buf);
 	    return True;
 	}
@@ -127,7 +132,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	printf("format %d numitems %lu bytesleft %lu\n",
 	       format, numitems, bytesleft);
 	
-	printf("type %s\n", XGetAtomName(dis, *type));
+	printf("type %s\n", XGetAtomName (x_dpy, *type));
 #endif
 	
 	/* Format is the number of bits. */
@@ -151,6 +156,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	buflen = newbuflen;
 	/* offset is a multiple of 32 bits*/
 	offset += chunkbytesize / 4;
+
+#ifdef TEST
+	printf("bytesleft %lu\n", bytesleft);
+#endif
     } while (bytesleft > 0);
     
     pdata->data = buf;
@@ -160,40 +169,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 
-static unsigned long *
-read_prop_32 (Window id, Atom prop, int *nitems_ret)
-{
-    int r, format;
-    Atom type;
-    unsigned long nitems, bytes_after;
-    unsigned char *data;
-
-    r = XGetWindowProperty (x_dpy, id, prop, 0, 0,
-			    False, AnyPropertyType, &type, &format,
-			    &nitems, &bytes_after, &data);
-
-    if (r == Success && bytes_after != 0)
-    {
-	XFree (data);
-	r = XGetWindowProperty (x_dpy, id, prop, 0,
-				(bytes_after / 4) + 1, False,
-				AnyPropertyType, &type, &format,
-				&nitems, &bytes_after, &data);
-    }
-
-    if (r != Success)
-	return NULL;
-
-    if (format != 32)
-    {
-	XFree (data);
-	return NULL;
-    }
-
-    *nitems_ret = nitems;
-    return (unsigned long *) data;
-}
-
 /* Implementation methods */
 
 /* This finds the preferred type from a TARGETS list.*/
@@ -201,7 +176,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 {
     Atom a = None;
     size_t i;
-    Bool png = False, utf8 = False, string = False;
+    Bool png = False, jpeg = False, utf8 = False, string = False;
 
     TRACE ();
 
@@ -219,6 +194,10 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	{
 	    png = True;
 	} 
+	else if (a == atoms->image_jpeg)
+	{
+	    jpeg = True;
+	}
 	else if (a == atoms->utf8_string)
 	{
 	    utf8 = True;
@@ -233,6 +212,9 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
     if (png)
 	return atoms->image_png;
 
+    if (jpeg)
+	return atoms->image_jpeg;
+
     if (utf8)
 	return atoms->utf8_string;
 
@@ -309,7 +291,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
     memcpy(newdata + pending.propdata.length, pdata->data, pdata->length);
     pending.propdata.data = newdata;
     pending.propdata.length = newlength;
-	
+    
     return False;
 }
 
@@ -583,51 +565,63 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 {
     XEvent reply;
     NSArray *pbtypes;
-    
+    NSString *data;
+    const char *bytes;
+    NSUInteger length;
+
     TRACE ();
 
     [self init_reply:&reply request:e];
 
     pbtypes = [_pasteboard types];
-
-    if ([pbtypes containsObject: NSStringPboardType])
+ 
+    if (![pbtypes containsObject:NSStringPboardType])
     {
-	NSString *data = [_pasteboard stringForType:NSStringPboardType];
-	if (nil != data)
-	{
-	    const char *bytes;
-	    NSUInteger length;
+	[self send_reply:&reply];
+	return;
+    }
 
-	    if (utf8) 
-	    {
-		bytes = [data UTF8String];
-		/*
-		 * We don't want the UTF-8 string length here.  
-		 * We want the length in bytes.
-		 */
-		length = strlen (bytes);
-
-		if (length < 50) {
-		    DB ("UTF-8: %s\n", bytes);
-		    DB ("UTF-8 length: %u\n", length); 
-		}
-	    } 
-	    else 
-	    {
-		DB ("Latin-1\n");
-		bytes = [data cStringUsingEncoding:NSISOLatin1StringEncoding];
-		length = strlen (bytes);
-	    }
+    DB ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]);
 
-	    DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
+    data = [_pasteboard stringForType:NSStringPboardType];
 
-	    XChangeProperty (x_dpy, e->requestor, e->property, e->target,
-			     8, PropModeReplace, (unsigned char *) bytes, length);
-	    
-	    reply.xselection.property = e->property;
- 	}
+    if (nil == data)
+    {
+	[self send_reply:&reply];
+	return;
+    }
+
+
+    if (utf8) 
+    {
+	bytes = [data UTF8String];
+	/*
+	 * We don't want the UTF-8 string length here.  
+	 * We want the length in bytes.
+	 */
+	length = strlen (bytes);
+	
+	if (length < 50) {
+	    DB ("UTF-8: %s\n", bytes);
+	    DB ("UTF-8 length: %u\n", length); 
+	}
+    } 
+    else 
+    {
+	DB ("Latin-1\n");
+	bytes = [data cStringUsingEncoding:NSISOLatin1StringEncoding];
+	length = strlen (bytes);
     }
 
+    DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
+    
+    XChangeProperty (x_dpy, e->requestor, e->property, e->target,
+		     8, PropModeReplace, (unsigned char *) bytes, length);
+    
+    reply.xselection.property = e->property;
+
+    DB ("data retainCount before release %u\n", [data retainCount]);
+    [data release];
     [self send_reply:&reply];
 }
 
@@ -676,6 +670,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 
 	    if (textprop.value)
  		XFree (textprop.value);
+
+	    [data release];
 	}
     }
     
@@ -730,8 +726,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	imagetype = NSPNGFileType;
     else if (e->target == atoms->image_jpeg)
 	imagetype = NSJPEGFileType;
-        
-
+    
+    
     if (nil == type) 
     {
 	[self send_reply:&reply];
@@ -748,18 +744,21 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	 
     if (NSTIFFPboardType == type)
     {
-	NSBitmapImageRep *bmimage = [[NSBitmapImageRep alloc] initWithData:data];
+  	NSBitmapImageRep *bmimage = [[NSBitmapImageRep alloc] initWithData:data];
 	NSDictionary *dict;
 	NSData *encdata;
+	
 
-	if (nil == bmimage) 
+	if (nil == bmimage)
 	{
+	    [data release];
 	    [self send_reply:&reply];
 	    return;
 	}
+	/*FIXME Why is [bmimage retainCount] 2 here? */
+
+	DB ("bmimage retainCount after initWithData %u\n", [bmimage retainCount]);
 
-	DB ("have valid bmimage\n");
-	
 	dict = [[NSDictionary alloc] init];
 	encdata = [bmimage representationUsingType:imagetype properties:dict];
 	if (encdata)
@@ -769,18 +768,27 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	    
 	    length = [encdata length];
 	    bytes = [encdata bytes];
-		
-	    XChangeProperty (x_dpy, e->requestor, e->property, e->target,
-				 8, PropModeReplace, bytes, length);
 	    
+	    XChangeProperty (x_dpy, e->requestor, e->property, e->target,
+			     8, PropModeReplace, bytes, length);
 	    reply.xselection.property = e->property;
 	    
 	    DB ("changed property for %s\n", XGetAtomName (x_dpy, e->target));
+	    DB ("encdata retainCount %u\n", [encdata retainCount]);
+	    [encdata release];
+	    [bmimage release];
 	}
+	DB ("dict retainCount before release %u\n", [dict retainCount]);
+	
 	[dict release];
-	[bmimage release];
-    } 
 
+	
+	DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
+	/*FIXME Why on earth is retainCount 3? */
+	[bmimage release];
+	[bmimage release];
+    }
+    [data release];
     [self send_reply:&reply];
 }
 
@@ -812,8 +820,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 
     /*TODO we need a COMPOUND_TEXT test app*/
     /*TODO we need a MULTIPLE test app*/
-
-    DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
+    if (None != e->target)
+	DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
 
     if (e->target == atoms->targets) 
     {
@@ -890,7 +898,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 
 	free_propdata (&pdata);
 
-	pending.requestor = e->requestor;
+      	pending.requestor = e->requestor;
 	pending.selection = e->selection;
 
 	DB ("set pending.requestor to 0x%lx\n", pending.requestor);
@@ -993,14 +1001,21 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	return;
     }
 
+    DB ("data retainCount before NSBitmapImageRep initWithData: %u\n",
+	[data retainCount]);
+
     bmimage = [[NSBitmapImageRep alloc] initWithData:data];
 
     if (nil == bmimage)
     {
+	[data release];
 	DB ("unable to create NSBitmapImageRep!\n");
 	return;
     }
 
+    DB ("data retainCount after NSBitmapImageRep initWithData: %u\n", 
+	[data retainCount]);
+
     @try 
     {
 	tiff = [bmimage TIFFRepresentation];
@@ -1011,9 +1026,13 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	DB ("NSTIFFException!\n");
 	[data release];
 	[bmimage release];
+	/*WHY 2?*/
+	[bmimage release];
 	return;
     }
     
+    DB ("bmimage retainCount after TIFFRepresentation %u\n", [bmimage retainCount]);
+
     pbtypes = [NSArray arrayWithObjects:NSTIFFPboardType, nil];
 
     if (nil == pbtypes)
@@ -1021,17 +1040,28 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 	[tiff release];
 	[data release];
 	[bmimage release];
+	/* WHY is the object with a retainCount of 2 after initWithData? */
+	[bmimage release];
+	return;
     }
 
+ 
     [_pasteboard declareTypes:pbtypes owner:self];
-    if (YES != [_pasteboard setData:data forType:NSTIFFPboardType])
+    if (YES != [_pasteboard setData:tiff forType:NSTIFFPboardType])
     {
 	DB ("writing pasteboard data failed!\n");
     }
 
     [pbtypes release];
     [data release];
+
+    DB ("tiff retainCount before release %u\n", [tiff retainCount]);
     [tiff release];
+
+    DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
+    /*WHY 3?*/
+    [bmimage release];
+    [bmimage release];
     [bmimage release];
 }
 
@@ -1048,6 +1078,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
     if (nil == string)
 	return;
 
+    DB ("string retainCount is %u\n", [string retainCount]);
+
     pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
 
     if (nil != pbtypes)
@@ -1083,9 +1115,10 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
     {
 	[_pasteboard declareTypes:pbtypes owner:self];
 	[_pasteboard setString:string forType:NSStringPboardType];
+
+	DB ("pbtypes retainCount %u\n", [pbtypes retainCount]);
 	[pbtypes release];
     }
-
     [string release];
 }
 
@@ -1212,7 +1245,8 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
 
     _pasteboard = [[NSPasteboard generalPasteboard] retain];
 
-    _known_types = [[NSArray arrayWithObject:NSStringPboardType] retain];
+    //_known_types = [[NSArray arrayWithObject:NSStringPboardType] retain];
+    _known_types = nil;
 
     pixel = BlackPixel (x_dpy, DefaultScreen (x_dpy));
     _selection_window = XCreateSimpleWindow (x_dpy, DefaultRootWindow (x_dpy),
@@ -1240,7 +1274,7 @@ read_prop_32 (Window id, Atom prop, int *nitems_ret)
     [_pasteboard release];
     _pasteboard = nil;
 
-    [_known_types release];
+    //[_known_types release];
     _known_types = nil;
 
     if (None != _selection_window)


More information about the xorg-commit mailing list