xserver: Branch 'xorg-server-1.4-apple'

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Sat Oct 4 18:54:21 PDT 2008


 hw/xquartz/pbproxy/app-main.m    |    4 
 hw/xquartz/pbproxy/main.m        |    4 
 hw/xquartz/pbproxy/pbproxy.h     |    4 
 hw/xquartz/pbproxy/x-input.m     |   60 ++++++------
 hw/xquartz/pbproxy/x-selection.h |    2 
 hw/xquartz/pbproxy/x-selection.m |  185 ++++++++++++++++++++++-----------------
 6 files changed, 144 insertions(+), 115 deletions(-)

New commits:
commit f7673bb4de3c1f71eb390a3279eed3589efc3df4
Author: Jeremy Huddleston <jeremyhu at freedesktop.org>
Date:   Sat Oct 4 18:54:15 2008 -0700

    XQuartz: xpbproxy: Support some of the preference toggles from X11.app, cleaned up CLIPBOARD_MANAGER atom management.

diff --git a/hw/xquartz/pbproxy/app-main.m b/hw/xquartz/pbproxy/app-main.m
index 7611eef..4847851 100644
--- a/hw/xquartz/pbproxy/app-main.m
+++ b/hw/xquartz/pbproxy/app-main.m
@@ -15,8 +15,10 @@ static void signal_handler (int sig) {
 }
 
 int main (int argc, const char *argv[]) {
+#ifdef TEST
     printf("pid: %u\n", getpid());
-    
+#endif
+
     x_init ();
     
     signal (SIGINT, signal_handler);
diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m
index e2156a7..448bec4 100644
--- a/hw/xquartz/pbproxy/main.m
+++ b/hw/xquartz/pbproxy/main.m
@@ -55,10 +55,6 @@ void x_init (void) {
     _selection_object = [[x_selection alloc] init];
     
     x_input_register ();
-   
-    [_selection_object set_clipboard_manager];
-    [_selection_object claim_clipboard];
-
     x_input_run ();
 
     [pool release];
diff --git a/hw/xquartz/pbproxy/pbproxy.h b/hw/xquartz/pbproxy/pbproxy.h
index bd5f65b..bfeb868 100644
--- a/hw/xquartz/pbproxy/pbproxy.h
+++ b/hw/xquartz/pbproxy/pbproxy.h
@@ -12,7 +12,9 @@
 #include <X11/extensions/shape.h>
 #undef   Cursor
 
+#ifndef DEBUG
 #define DEBUG 0
+#endif
 
 /* from main.m */
 extern void x_set_is_active (BOOL state);
@@ -27,7 +29,7 @@ extern int x_apple_wm_event_base, x_apple_wm_error_base;
 /* from x-input.m */
 extern void x_input_register (void);
 extern void x_input_run (void);
- 
+
 #if DEBUG == 0
 # define DB(msg, args...) do {} while (0)
 #else
diff --git a/hw/xquartz/pbproxy/x-input.m b/hw/xquartz/pbproxy/x-input.m
index c11ffb3..1b2475c 100644
--- a/hw/xquartz/pbproxy/x-input.m
+++ b/hw/xquartz/pbproxy/x-input.m
@@ -21,29 +21,35 @@ static CFRunLoopSourceRef x_dpy_source;
 static Time last_activation_time;
 
 static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) {
+    int type = e->type - x_apple_wm_event_base;
+    int kind = e->kind;
 
-    switch (e->type - x_apple_wm_event_base) {              
+    /* We want to reload prefs even if we're not active */
+    if(type == AppleWMActivationNotify &&
+       kind == AppleWMReloadPreferences)
+        [x_selection_object() reload_preferences];
+
+    if(![x_selection_object() is_active])
+        return;
+
+    switch (type) {              
         case AppleWMActivationNotify:
-            switch (e->kind) {
+            switch (kind) {
                 case AppleWMIsActive:
                     last_activation_time = e->time;
-                    [x_selection_object () x_active:e->time];
+                    [x_selection_object() x_active:e->time];
                     break;
                     
                 case AppleWMIsInactive:
-                    [x_selection_object () x_inactive:e->time];
+                    [x_selection_object() x_inactive:e->time];
                     break;
-
-  	        case AppleWMReloadPreferences:
-		    [x_selection_object () reload_preferences];
-		    break;
             }
             break;
             
         case AppleWMPasteboardNotify:
-            switch (e->kind) {
-	        case AppleWMCopyToPasteboard:
-                    [x_selection_object () x_copy:e->time];
+            switch (kind) {
+                case AppleWMCopyToPasteboard:
+                    [x_selection_object() x_copy:e->time];
             }
             break;
     }
@@ -54,22 +60,18 @@ void x_input_run (void) {
     
     if (nil == pool) 
     {
-	fprintf(stderr, "unable to allocate/init auto release pool!\n");
-	return;
+        fprintf(stderr, "unable to allocate/init auto release pool!\n");
+        return;
     }
-
+    
     while (XPending (x_dpy) != 0) {
-        XEvent e;       
-
+        XEvent e;
         XNextEvent (x_dpy, &e);
-
-	/* If pbproxy isn't active (in the preferences), then don't do anything. */
-	if (![x_selection_object() is_active])
-	    continue;
-
+        
         switch (e.type) {                
             case SelectionClear:
-	        [x_selection_object () clear_event:&e.xselectionclear];
+                if([x_selection_object() is_active])
+                    [x_selection_object () clear_event:&e.xselectionclear];
                 break;
                 
             case SelectionRequest:
@@ -80,10 +82,10 @@ void x_input_run (void) {
                 [x_selection_object () notify_event:&e.xselection];
                 break;
                 
-	    case PropertyNotify:
-		[x_selection_object () property_event:&e.xproperty];
-		break;
-
+            case PropertyNotify:
+                [x_selection_object () property_event:&e.xproperty];
+                break;
+                
             default:
                 if (e.type - x_apple_wm_event_base >= 0
                     && e.type - x_apple_wm_event_base < AppleWMNumberEvents) {
@@ -91,10 +93,10 @@ void x_input_run (void) {
                 }
                 break;
         }
-
-	XFlush(x_dpy);
+        
+        XFlush(x_dpy);
     }
-
+    
     [pool release];
 }
 
diff --git a/hw/xquartz/pbproxy/x-selection.h b/hw/xquartz/pbproxy/x-selection.h
index 9c408b4..c93b676 100644
--- a/hw/xquartz/pbproxy/x-selection.h
+++ b/hw/xquartz/pbproxy/x-selection.h
@@ -97,7 +97,7 @@ struct atom_list {
 - (void) property_event:(XPropertyEvent *)e;
 - (void) handle_selection:(Atom)selection type:(Atom)type propdata:(struct propdata *)pdata;
 - (void) claim_clipboard;
-- (void) set_clipboard_manager;
+- (BOOL) set_clipboard_manager_status:(BOOL)value;
 - (void) own_clipboard;
 - (void) copy_completed:(Atom)selection;
 
diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 0997b3a..67de866 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -56,22 +56,36 @@
 
 /*
  * TODO:
- * 1. finish handling these pbproxy control knobs.
+ * 1. handle primary_on_grab
  * 2. handle  MULTIPLE - I need to study the ICCCM further.
  * 3. Handle PICT images properly.
+ * 4. Handle NSPasteboard updates immediately, not on active/inactive
+ *    - Open xterm, run 'cat readme.txt | pbcopy'
+ * 5. Detect if CLIPBOARD_MANAGER atom belongs to a dead client rather than just None
  */
 
-// These will be set by X11Controller.m once this is integrated into a server thread
-BOOL pbproxy_active = YES;
-BOOL pbproxy_primary_on_grab = NO; // This is provided as an option for people who want it and has issues that won't ever be addressed to make it *always* work
-BOOL pbproxy_clipboard_to_pasteboard = YES;
-BOOL pbproxy_pasteboard_to_primary = YES;
-BOOL pbproxy_pasteboard_to_clipboard = YES;
+static struct {
+    BOOL active ;
+    BOOL primary_on_grab; // This is provided as an option for people who want it and has issues that won't ever be addressed to make it *always* work
+    BOOL clipboard_to_pasteboard;
+    BOOL pasteboard_to_primary;
+    BOOL pasteboard_to_clipboard;
+} pbproxy_prefs = { YES, NO, YES, YES, YES };
 
 @implementation x_selection
 
 static struct propdata null_propdata = {NULL, 0};
 
+#define APP_PREFS "org.x.X11"
+static BOOL prefs_get_bool (CFStringRef key, BOOL def) {
+     int ret;
+     Boolean ok;
+
+     ret = CFPreferencesGetAppBooleanValue (key, CFSTR (APP_PREFS), &ok);
+
+     return ok ? (BOOL) ret : def;
+}
+
 static void
 init_propdata (struct propdata *pdata)
 {
@@ -321,19 +335,17 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (countNow != changeCount)
     {
-	DB ("changed pasteboard!\n");
-	changeCount = countNow;
-
-	if (pbproxy_pasteboard_to_primary)
-	{
-	    
-	    XSetSelectionOwner (x_dpy, atoms->primary, _selection_window, CurrentTime);
-	}
-
-	if (pbproxy_pasteboard_to_clipboard)
-	{
-	    [self own_clipboard];
-	}
+        DB ("changed pasteboard!\n");
+        changeCount = countNow;
+        
+        if (pbproxy_prefs.pasteboard_to_primary)
+        {
+            XSetSelectionOwner (x_dpy, atoms->primary, _selection_window, CurrentTime);
+        }
+        
+        if (pbproxy_prefs.pasteboard_to_clipboard) {
+            [self own_clipboard];
+        }
     }
 
 #if 0
@@ -395,23 +407,36 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     }
 }
 
-/*
- * Set pbproxy as owner of the SELECTION_MANAGER selection.
+/* Set pbproxy as owner of the SELECTION_MANAGER selection.
  * This prevents tools like xclipboard from causing havoc.
+ * Returns TRUE on success
  */
-- (void) set_clipboard_manager
+- (BOOL) set_clipboard_manager_status:(BOOL)value
 {
     TRACE ();
 
-    if (None != XGetSelectionOwner (x_dpy, atoms->clipboard_manager))
-    {
-	fprintf (stderr, "A clipboard manager is already running!\n"
-		 "pbproxy can not continue!\n");
-	exit (EXIT_FAILURE);
+    Window owner = XGetSelectionOwner (x_dpy, atoms->clipboard_manager);
+
+    if(value) {
+        if(owner == _selection_window)
+            return TRUE;
+
+//        if(None != _selection_window) {
+//            fprintf (stderr, "A clipboard manager is already running.  pbproxy will not sync clipboard to pasteboard.\n");
+//            return FALSE;
+//        }
+        
+        XSetSelectionOwner(x_dpy, atoms->clipboard_manager, _selection_window, CurrentTime);
+        return (_selection_window == XGetSelectionOwner(x_dpy, atoms->clipboard_manager));
+    } else {
+        if(owner != _selection_window)
+            return TRUE;
+
+        XSetSelectionOwner(x_dpy, atoms->clipboard_manager, None, CurrentTime);
+        return(None == XGetSelectionOwner(x_dpy, atoms->clipboard_manager));
     }
-
-    XSetSelectionOwner (x_dpy, atoms->clipboard_manager, _selection_window,
-			CurrentTime);
+    
+    return FALSE;
 }
 
 /*
@@ -423,28 +448,25 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     TRACE ();
     
     DB ("e->selection %s\n", XGetAtomName (x_dpy, e->selection));
- 
-    if (atoms->clipboard == e->selection)
-    {
-	/* 
-	 * We lost ownership of the CLIPBOARD.
-	 */
-	++pending_clipboard;
-
-	if (1 == pending_clipboard) 
-	{
-	    /* Claim the clipboard contents from the new owner. */
-	    [self claim_clipboard];
-	}
-    } 
-    else if (atoms->clipboard_manager == e->selection)
-    {
-	/* Another CLIPBOARD_MANAGER has set itself as owner.
-         * a) we can call [self set_clipboard_manager] here and risk a war.
-	 * b) we can print a message and exit.  Ideally we would popup a message box.
-	 */
-	fprintf (stderr, "error: another clipboard manager was started!\n"); 
-	//exit (EXIT_FAILURE);
+    
+    if(e->selection == atoms->clipboard) {
+        /* 
+         * We lost ownership of the CLIPBOARD.
+         */
+        ++pending_clipboard;
+        
+        if (1 == pending_clipboard) {
+            /* Claim the clipboard contents from the new owner. */
+            [self claim_clipboard];
+        }
+    } else if(e->selection == atoms->clipboard_manager) {
+        if(pbproxy_prefs.clipboard_to_pasteboard) {
+            /* Another CLIPBOARD_MANAGER has set itself as owner.  Disable syncing
+             * to avoid a race.
+             */
+            fprintf(stderr, "Another clipboard manager was started!  xpbproxy is disabling syncing with clipboard.\n"); 
+            pbproxy_prefs.clipboard_to_pasteboard = NO;
+        }
     }
 }
 
@@ -456,32 +478,29 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     Window owner;
     
     TRACE ();
-
-    if (!pbproxy_clipboard_to_pasteboard)
-	return;
+    
+    if (!pbproxy_prefs.clipboard_to_pasteboard)
+        return;
     
     owner = XGetSelectionOwner (x_dpy, atoms->clipboard);
-    if (None == owner)
-    {
-	/*
-	 * The owner probably died or we are just starting up pbproxy.
-	 * Set pbproxy's _selection_window as the owner, and continue.
-	 */
-	DB ("No clipboard owner.\n");
-	[self copy_completed:atoms->clipboard];
-	return;
-    } 
-    else if (owner == _selection_window) 
-    {
-	[self copy_completed:atoms->clipboard];
-	return;
+    if (None == owner) {
+        /*
+         * The owner probably died or we are just starting up pbproxy.
+         * Set pbproxy's _selection_window as the owner, and continue.
+         */
+        DB ("No clipboard owner.\n");
+        [self copy_completed:atoms->clipboard];
+        return;
+    } else if (owner == _selection_window) {
+        [self copy_completed:atoms->clipboard];
+        return;
     }
     
     DB ("requesting targets\n");
-
+    
     request_atom = atoms->targets;
     XConvertSelection (x_dpy, atoms->clipboard, atoms->targets,
-		       atoms->clipboard, _selection_window, CurrentTime);
+                       atoms->clipboard, _selection_window, CurrentTime);
     XFlush (x_dpy);
     /* Now we will get a SelectionNotify event in the future. */
 }
@@ -1236,18 +1255,25 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 - (void) reload_preferences
 {
-    if (pbproxy_clipboard_to_pasteboard)
-    {
-	[self claim_clipboard];
-    }
+    pbproxy_prefs.active = prefs_get_bool(CFSTR("sync_pasteboard"), pbproxy_prefs.active);
+    pbproxy_prefs.primary_on_grab = prefs_get_bool(CFSTR("sync_primary_on_select"), pbproxy_prefs.primary_on_grab);
+    pbproxy_prefs.clipboard_to_pasteboard = prefs_get_bool(CFSTR("sync_clibpoard_to_pasteboard"), pbproxy_prefs.clipboard_to_pasteboard);
+    pbproxy_prefs.pasteboard_to_primary = prefs_get_bool(CFSTR("sync_pasteboard_to_primary"), pbproxy_prefs.pasteboard_to_primary);
+    pbproxy_prefs.pasteboard_to_clipboard =  prefs_get_bool(CFSTR("sync_pasteboard_to_clipboard"), pbproxy_prefs.pasteboard_to_clipboard);
+
+    /* Claim or release the CLIPBOARD_MANAGER atom */
+    if(![self set_clipboard_manager_status:(pbproxy_prefs.active && pbproxy_prefs.clipboard_to_pasteboard)])
+        pbproxy_prefs.clipboard_to_pasteboard = NO;
+    
+    if(pbproxy_prefs.active && pbproxy_prefs.clipboard_to_pasteboard)
+        [self claim_clipboard];
 }
 
 - (BOOL) is_active 
 {
-    return pbproxy_active;
+    return pbproxy_prefs.active;
 }
 
-
 /* NSPasteboard-required methods */
 
 - (void) paste:(id)sender
@@ -1267,7 +1293,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     /* Right now we don't care with this. */
 }
 
-
 /* Allocation */
 
 - init
@@ -1310,6 +1335,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     pending_copy = 0;
     pending_clipboard = 0;
 
+    [self reload_preferences];
+    
     return self;
 }
 


More information about the xorg-commit mailing list