diff -rc autocutsel-0.7.0/autocutsel.c myautocutsel/autocutsel.c
*** autocutsel-0.7.0/autocutsel.c	2004-09-10 13:47:10.000000000 -0700
--- myautocutsel/autocutsel.c	2004-09-17 09:59:20.000000000 -0700
***************
*** 1,7 ****
  /*
   * autocutsel.c by Michael Witrant <mike @ lepton . fr>
!  * Synchronizes the cutbuffer and the selection
!  * version 0.6.2
   * Copyright (c) 2001,2002,2004 Michael Witrant.
   * 
   * Most code taken from:
--- 1,7 ----
  /*
   * autocutsel.c by Michael Witrant <mike @ lepton . fr>
!  * Synchronizes the cutbuffer, the primary selection, and the clipboard.
!  * version 0.7.0
   * Copyright (c) 2001,2002,2004 Michael Witrant.
   * 
   * Most code taken from:
***************
*** 57,70 ****
  static Widget box;
  static Display* dpy;
  static XtAppContext context;
! static Atom selection;
  static int buffer;
  
  static XrmOptionDescRec optionDesc[] = {
-   {"-selection", "selection", XrmoptionSepArg, NULL},
-   {"-select",    "selection", XrmoptionSepArg, NULL},
-   {"-sel",       "selection", XrmoptionSepArg, NULL},
-   {"-s",         "selection", XrmoptionSepArg, NULL},
    {"-cutbuffer", "cutBuffer", XrmoptionSepArg, NULL},
    {"-cut",       "cutBuffer", XrmoptionSepArg, NULL},
    {"-c",         "cutBuffer", XrmoptionSepArg, NULL},
--- 57,67 ----
  static Widget box;
  static Display* dpy;
  static XtAppContext context;
! static Atom primary;
! static Atom clipboard;
  static int buffer;
  
  static XrmOptionDescRec optionDesc[] = {
    {"-cutbuffer", "cutBuffer", XrmoptionSepArg, NULL},
    {"-cut",       "cutBuffer", XrmoptionSepArg, NULL},
    {"-c",         "cutBuffer", XrmoptionSepArg, NULL},
***************
*** 80,92 ****
       char *call;
  {
    fprintf (stderr,
! 	   "usage:  %s [-selection <name>] [-cutbuffer <number>] [-pause <milliseconds>] [-debug] [-verbose]\n", 
  	   call);
    exit (1);
  }
  
  typedef struct {
-   String  selection_name;
    int     buffer;
    String  debug_option;
    String  verbose_option;
--- 77,88 ----
       char *call;
  {
    fprintf (stderr,
! 	   "usage:  %s [-cutbuffer <number>] [-pause <milliseconds>] [-debug] [-verbose]\n", 
  	   call);
    exit (1);
  }
  
  typedef struct {
    int     buffer;
    String  debug_option;
    String  verbose_option;
***************
*** 94,103 ****
    int     pause;
    int     debug; 
    int     verbose; 
-   Atom    selection;
    char*   value;
    int     length;
!   int     own_selection;
  } OptionsRec;
  
  OptionsRec options;
--- 90,99 ----
    int     pause;
    int     debug; 
    int     verbose; 
    char*   value;
    int     length;
!   int     own_primary;
!   int     own_clipboard;
  } OptionsRec;
  
  OptionsRec options;
***************
*** 105,112 ****
  #define Offset(field) XtOffsetOf(OptionsRec, field)
  
  static XtResource resources[] = {
-   {"selection", "Selection", XtRString, sizeof(String),
-    Offset(selection_name), XtRString, "CLIPBOARD"},
    {"cutBuffer", "CutBuffer", XtRInt, sizeof(int),
     Offset(buffer), XtRImmediate, (XtPointer)0},
    {"debug", "Debug", XtRString, sizeof(String),
--- 101,106 ----
***************
*** 116,122 ****
    {"kill", "kill", XtRString, sizeof(String),
     Offset(kill), XtRString, "off"},
    {"pause", "Pause", XtRInt, sizeof(int),
!    Offset(pause), XtRImmediate, (XtPointer)500},
  };
  
  #undef Offset
--- 110,116 ----
    {"kill", "kill", XtRString, sizeof(String),
     Offset(kill), XtRString, "off"},
    {"pause", "Pause", XtRInt, sizeof(int),
!    Offset(pause), XtRImmediate, (XtPointer)300},
  };
  
  #undef Offset
***************
*** 172,177 ****
--- 166,172 ----
    Display* d = XtDisplay(w);
    XSelectionRequestEvent* req =
      XtGetSelectionRequest(w, *selection, (XtRequestId)NULL);
+   char *sel_name = XGetAtomName(dpy, *selection);
     
    if (*target == XA_TARGETS(d)) {
      Atom* targetP;
***************
*** 205,211 ****
  
      if (options.debug)
        {
! 	printf("Giving selection as string: ");
  	PrintValue((char*)*value, *length);
  	printf("\n");
        }
--- 200,206 ----
  
      if (options.debug)
        {
! 	printf("Giving %s as string: ", sel_name);
  	PrintValue((char*)*value, *length);
  	printf("\n");
        }
***************
*** 221,227 ****
      *format = 32;
  
      if (options.debug)
!       printf("Giving selection list length: %d\n", *temp);
  
      return True;
    }
--- 216,222 ----
      *format = 32;
  
      if (options.debug)
!       printf("Giving %s list length: %d\n", sel_name, *temp);
  
      return True;
    }
***************
*** 234,240 ****
      *format = 32;
  
      if (options.debug)
!       printf("Giving selection length: %d\n", *temp);
  
      return True;
    }
--- 229,235 ----
      *format = 32;
  
      if (options.debug)
!       printf("Giving %s length: %d\n", sel_name, *temp);
  
      return True;
    }
***************
*** 261,274 ****
    return False;
  }
  
! // Called when we no longer own the selection
  static void LoseSelection(w, selection)
       Widget w;
       Atom *selection;
  {
    if (options.debug)
!     printf("Selection lost\n");
!   options.own_selection = 0;
  }
  
  // Returns true if value (or length) is different
--- 256,274 ----
    return False;
  }
  
! // Called when we no longer own a selection
  static void LoseSelection(w, selection)
       Widget w;
       Atom *selection;
  {
    if (options.debug)
!     printf("%s lost\n", XGetAtomName(dpy, *selection));
! 
!   if (*selection == clipboard) {
!     options.own_clipboard = 0;
!   } else if (*selection == primary) {
!     options.own_primary = 0;
!   }
  }
  
  // Returns true if value (or length) is different
***************
*** 312,351 ****
  // do it if the selection already has the same value
  static void OwnSelectionIfDiffers(w, client_data, selection, type, value, received_length, format)
       Widget w;
!      XtPointer client_data;
       Atom *selection, *type;
       XtPointer value;
       unsigned long *received_length;
       int *format;
  {
    int length = *received_length;
!   
    if (*type == 0 || 
        *type == XT_CONVERT_FAIL || 
        length == 0 || 
        ValueDiffers(value, length))
      {
        if (options.debug)
! 	printf("Selection is out of date. Owning it\n");
        
        if (options.verbose)
  	{
! 	  printf("cut -> sel: ");
  	  PrintValue(options.value, options.length);
  	  printf("\n");
  	}
        
!       if (XtOwnSelection(box, options.selection,
  			 0, //XtLastTimestampProcessed(dpy),
  			 ConvertSelection, LoseSelection, NULL) == True)
  	{
  	  if (options.debug)
! 	    printf("Selection owned\n");
  	  
! 	  options.own_selection = 1;
  	}
        else
! 	printf("WARNING: Unable to own selection!\n");
      }
    XtFree(value);
  }
--- 312,355 ----
  // do it if the selection already has the same value
  static void OwnSelectionIfDiffers(w, client_data, selection, type, value, received_length, format)
       Widget w;
!      XtPointer client_data;  // name of the buffer or selection that changed
       Atom *selection, *type;
       XtPointer value;
       unsigned long *received_length;
       int *format;
  {
    int length = *received_length;
!   char *sel_name = XGetAtomName(dpy, *selection);
! 
    if (*type == 0 || 
        *type == XT_CONVERT_FAIL || 
        length == 0 || 
        ValueDiffers(value, length))
      {
        if (options.debug)
! 	printf("%s is out of date. Owning it\n", sel_name);
        
        if (options.verbose)
  	{
! 	  printf("%s -> %s: ", (char *)client_data, sel_name);
  	  PrintValue(options.value, options.length);
  	  printf("\n");
  	}
        
!       if (XtOwnSelection(box, *selection,
  			 0, //XtLastTimestampProcessed(dpy),
  			 ConvertSelection, LoseSelection, NULL) == True)
  	{
  	  if (options.debug)
! 	    printf("%s owned\n", sel_name);
  	  
! 	  if (*selection == primary)
! 	    options.own_primary = 1;
! 	  else
! 	    options.own_clipboard = 1;
  	}
        else
! 	printf("WARNING: Unable to own %s!\n", sel_name);
      }
    XtFree(value);
  }
***************
*** 369,383 ****
  	}
        
        ChangeValue(value, length);
!       XtGetSelectionValue(box, selection, XA_STRING,
! 			  OwnSelectionIfDiffers, NULL,
  			  XtLastTimestampProcessed(XtDisplay(box)));
      }
  
    XFree(value);
  }
  
! // Called when the requested selection value is availiable
  static void SelectionReceived(w, client_data, selection, type, value, received_length, format)
       Widget w;
       XtPointer client_data;
--- 373,390 ----
  	}
        
        ChangeValue(value, length);
!       XtGetSelectionValue(box, primary, XA_STRING,
! 			  OwnSelectionIfDiffers, "CUTBUFFER",
! 			  XtLastTimestampProcessed(XtDisplay(box)));
!       XtGetSelectionValue(box, clipboard, XA_STRING,
! 			  OwnSelectionIfDiffers, "CUTBUFFER",
  			  XtLastTimestampProcessed(XtDisplay(box)));
      }
  
    XFree(value);
  }
  
! // Called when the requested selection value is available
  static void SelectionReceived(w, client_data, selection, type, value, received_length, format)
       Widget w;
       XtPointer client_data;
***************
*** 387,392 ****
--- 394,404 ----
       int *format;
  {
    int length = *received_length;
+   char *sel_name = XGetAtomName(dpy, *selection);
+   Atom other_sel =
+     (*selection == primary) ? clipboard : primary;
+   int own_other_sel = 
+     (other_sel == primary) ? options.own_primary : options.own_clipboard;
    
    if (*type != 0 && *type != XT_CONVERT_FAIL)
      {
***************
*** 394,400 ****
  	{
  	  if (options.debug)
  	    {
! 	      printf("Selection changed: ");
  	      PrintValue((char*)value, length);
  	      printf("\n");
  	    }
--- 406,412 ----
  	{
  	  if (options.debug)
  	    {
! 	      printf("%s changed: ", sel_name);
  	      PrintValue((char*)value, length);
  	      printf("\n");
  	    }
***************
*** 402,419 ****
  	  ChangeValue((char*)value, length);
  	  if (options.verbose)
  	    {
! 	      printf("sel -> cut: ");
  	      PrintValue(options.value, options.length);
  	      printf("\n");
  	    }
  	  if (options.debug)
! 	    printf("Updating buffer\n");
! 	  
  	  XStoreBuffer(XtDisplay(w),
  		       (char*)options.value,
  		       (int)(options.length),
! 		       buffer );
! 	  
  	  XtFree(value);
  	  return;
  	}
--- 414,439 ----
  	  ChangeValue((char*)value, length);
  	  if (options.verbose)
  	    {
! 	      printf("%s -> %s, cut: ", sel_name, XGetAtomName(dpy, other_sel));
  	      PrintValue(options.value, options.length);
  	      printf("\n");
  	    }
  	  if (options.debug)
! 	    printf("Updating %s and buffer\n",
! 		   XGetAtomName(dpy, other_sel));
! 
! 	  // update the other selection (if necessary)...
! 	  if (!own_other_sel)
! 	    XtGetSelectionValue(box, other_sel, XA_STRING,
! 				OwnSelectionIfDiffers, sel_name,
! 				XtLastTimestampProcessed(XtDisplay(box)));
! 
! 	  // ...and the cut buffer
  	  XStoreBuffer(XtDisplay(w),
  		       (char*)options.value,
  		       (int)(options.length),
! 		       buffer);
! 
  	  XtFree(value);
  	  return;
  	}
***************
*** 423,439 ****
    CheckBuffer();
  }
  
! // Called each <pause arg=500> milliseconds
! void timeout(XtPointer p, XtIntervalId* i)
  {
!   if (options.own_selection)
!     CheckBuffer();
!   else
!     XtGetSelectionValue(box, selection, XA_STRING,
  			SelectionReceived, NULL,
  			CurrentTime);
!   
!   XtAppAddTimeOut(context, options.pause, timeout, 0);
  }
  
  int main(int argc, char* argv[])
--- 443,480 ----
    CheckBuffer();
  }
  
! // The timeout methods are called each <pause arg=500> milliseconds.
! // There are three separate timeouts to give X a chance to call the callbacks
! // passed to XtGetSelectionValue and XtOwnSelection.
! 
! // forward declaration, since the timeout_* methods are circular
! void timeout_clipboard(XtPointer, XtIntervalId*);
! 
! void timeout_buffer(XtPointer p, XtIntervalId* i)
! {
!   CheckBuffer();
! 
!   XtAppAddTimeOut(context, options.pause, timeout_clipboard, 0);
! }
! 
! void timeout_primary(XtPointer p, XtIntervalId* i)
  {
!   if (!options.own_primary)
!     XtGetSelectionValue(box, primary, XA_STRING,
  			SelectionReceived, NULL,
  			CurrentTime);
! 
!   XtAppAddTimeOut(context, options.pause, timeout_buffer, 0);
! }
! 
! void timeout_clipboard(XtPointer p, XtIntervalId* i)
! {
!   if (!options.own_clipboard)
!     XtGetSelectionValue(box, clipboard, XA_STRING,
! 			SelectionReceived, NULL,
! 			CurrentTime);
! 
!   XtAppAddTimeOut(context, options.pause, timeout_primary, 0);
  }
  
  int main(int argc, char* argv[])
***************
*** 465,482 ****
    options.value = NULL;
    options.length = 0;
  
!   options.own_selection = 0;
     
    box = XtCreateManagedWidget("box", boxWidgetClass, top, NULL, 0);
    dpy = XtDisplay(top);
    
!   selection = XInternAtom(dpy, options.selection_name, 0);
!   options.selection = selection;
    buffer = 0;
     
    options.value = XFetchBuffer(dpy, &options.length, buffer);
  
!   XtAppAddTimeOut(context, options.pause, timeout, 0);
    XtRealizeWidget(top);
    XtAppMainLoop(context);
    return 0;
--- 506,524 ----
    options.value = NULL;
    options.length = 0;
  
!   options.own_primary = 0;
!   options.own_clipboard = 0;
     
    box = XtCreateManagedWidget("box", boxWidgetClass, top, NULL, 0);
    dpy = XtDisplay(top);
    
!   primary = XInternAtom(dpy, "PRIMARY", 0);
!   clipboard = XInternAtom(dpy, "CLIPBOARD", 0);
    buffer = 0;
     
    options.value = XFetchBuffer(dpy, &options.length, buffer);
  
!   XtAppAddTimeOut(context, options.pause, timeout_buffer, 0);
    XtRealizeWidget(top);
    XtAppMainLoop(context);
    return 0;
