*** autocutsel-0.7.0/autocutsel.c	2004-09-10 13:47:10.000000000 -0700
--- myautocutsel/autocutsel.c	2004-09-22 16:42:30.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,63 ****
  static Widget box;
  static Display* dpy;
  static XtAppContext context;
- static Atom selection;
  static int buffer;
  
  static XrmOptionDescRec optionDesc[] = {
--- 57,62 ----
***************
*** 80,86 ****
       char *call;
  {
    fprintf (stderr,
! 	   "usage:  %s [-selection <name>] [-cutbuffer <number>] [-pause <milliseconds>] [-debug] [-verbose]\n", 
  	   call);
    exit (1);
  }
--- 79,85 ----
       char *call;
  {
    fprintf (stderr,
! 	   "usage:  %s [-selection <name>[,<name>]] [-cutbuffer <number>] [-pause <milliseconds>] [-debug] [-verbose]\n", 
  	   call);
    exit (1);
  }
***************
*** 94,103 ****
    int     pause;
    int     debug; 
    int     verbose; 
!   Atom    selection;
    char*   value;
    int     length;
!   int     own_selection;
  } OptionsRec;
  
  OptionsRec options;
--- 93,103 ----
    int     pause;
    int     debug; 
    int     verbose; 
!   Atom    selections[2];
!   int     num_selections;
    char*   value;
    int     length;
!   int     own_selection[2];
  } OptionsRec;
  
  OptionsRec options;
***************
*** 159,165 ****
      }
    putc('"', stdout);
  }
! 	
  // called when someone requests the selection value
  static Boolean ConvertSelection(w, selection, target,
                                  type, value, length, format)
--- 159,179 ----
      }
    putc('"', stdout);
  }
! 
! // print the selections we're currently synchronizing. if except is non-null,
! // any selection equal to it will not be printed.
! static void PrintSelections(except)
!      Atom *except;
! {
!   int i = 0;
! 
!   for (i = 0; i < options.num_selections; i++)
!     {
!       if (!except || options.selections[i] != *except)
! 	printf("%s, ", XGetAtomName(dpy, options.selections[i]));
!     }
! }
! 
  // called when someone requests the selection value
  static Boolean ConvertSelection(w, selection, target,
                                  type, value, length, format)
***************
*** 172,177 ****
--- 186,192 ----
    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");
        }
--- 220,226 ----
  
      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;
    }
--- 236,242 ----
      *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;
    }
--- 249,255 ----
      *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
--- 276,295 ----
    return False;
  }
  
! // Called when we no longer own a selection
  static void LoseSelection(w, selection)
       Widget w;
       Atom *selection;
  {
+   int i;
+ 
    if (options.debug)
!     printf("%s lost\n", XGetAtomName(dpy, *selection));
! 
!   for (i = 0; i < options.num_selections; i++) {
!     if (*selection == options.selections[i])
!       options.own_selection[i] = 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);
  }
--- 333,376 ----
  // 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 i, 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);
  	  
! 	  for (i = 0; i < options.num_selections; i++) {
! 	    if (*selection == options.selections[i])
! 	      options.own_selection[i] = 1;
! 	  }
  	}
        else
! 	printf("WARNING: Unable to own %s!\n", sel_name);
      }
    XtFree(value);
  }
***************
*** 355,361 ****
  static void CheckBuffer()
  {
    char *value;
!   int length;
    
    value = XFetchBuffer(dpy, &length, buffer);
    
--- 380,386 ----
  static void CheckBuffer()
  {
    char *value;
!   int i, length;
    
    value = XFetchBuffer(dpy, &length, buffer);
    
***************
*** 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;
--- 394,409 ----
  	}
        
        ChangeValue(value, length);
!       for (i = 0; i < options.num_selections; i++)
! 	XtGetSelectionValue(box, options.selections[i], 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;
***************
*** 386,392 ****
       unsigned long *received_length;
       int *format;
  {
!   int length = *received_length;
    
    if (*type != 0 && *type != XT_CONVERT_FAIL)
      {
--- 412,419 ----
       unsigned long *received_length;
       int *format;
  {
!   int i, length = *received_length;
!   char *sel_name = XGetAtomName(dpy, *selection);
    
    if (*type != 0 && *type != XT_CONVERT_FAIL)
      {
***************
*** 394,419 ****
  	{
  	  if (options.debug)
  	    {
! 	      printf("Selection changed: ");
  	      PrintValue((char*)value, length);
  	      printf("\n");
  	    }
  	  
  	  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;
  	}
--- 421,462 ----
  	{
  	  if (options.debug)
  	    {
! 	      printf("%s changed: ", sel_name);
  	      PrintValue((char*)value, length);
  	      printf("\n");
  	    }
  	  
  	  ChangeValue((char*)value, length);
+ 
  	  if (options.verbose)
  	    {
! 	      printf("%s -> ", sel_name);
! 	      PrintSelections(selection);
! 	      printf("cut: ");
  	      PrintValue(options.value, options.length);
  	      printf("\n");
  	    }
+ 
  	  if (options.debug)
! 	    {
! 	      printf("Updating ");
! 	      PrintSelections();
! 	      printf("and buffer\n");
! 	    }
! 
! 	  // update the other selections...
! 	  for (i = 0; i < options.num_selections; i++)
! 	    if (!options.own_selection[i])
! 	      XtGetSelectionValue(box, options.selections[i], 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,443 ****
    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[])
  {
    Widget top;
    top = XtVaAppInitialize(&context, "AutoCutSel",
  			  optionDesc, XtNumber(optionDesc), &argc, argv, NULL,
--- 466,496 ----
    CheckBuffer();
  }
  
! 
! // Called each <pause arg=500> milliseconds. selection_index cycles from -1 to
! // num_selections - 1. -1 means check the cutbuffer, >=0 means check the
! // selection with that index in options.selections.
! static int selection_index = -1;
! 
  void timeout(XtPointer p, XtIntervalId* i)
  {
!   if (selection_index == -1)
      CheckBuffer();
    else
!     if (!options.own_selection[selection_index])
!       XtGetSelectionValue(box, options.selections[selection_index], XA_STRING,
! 			  SelectionReceived, NULL, CurrentTime);
! 
!   selection_index++;
!   if (selection_index == options.num_selections)
!     selection_index = -1;
! 
    XtAppAddTimeOut(context, options.pause, timeout, 0);
  }
  
  int main(int argc, char* argv[])
  {
+   char *second_selection_name;
    Widget top;
    top = XtVaAppInitialize(&context, "AutoCutSel",
  			  optionDesc, XtNumber(optionDesc), &argc, argv, NULL,
***************
*** 451,457 ****
  			    resources, XtNumber(resources),
  			    NULL, ZERO );
  
- 
    if (strcmp(options.debug_option, "on") == 0)
      options.debug = 1;
    else
--- 504,509 ----
***************
*** 465,477 ****
    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);
--- 517,550 ----
    options.value = NULL;
    options.length = 0;
  
!   options.own_selection[0] = 0;
!   options.own_selection[1] = 0;
! 
    box = XtCreateManagedWidget("box", boxWidgetClass, top, NULL, 0);
    dpy = XtDisplay(top);
! 
!   second_selection_name = strchr(options.selection_name, ',');
!   if (!second_selection_name)
!     {
!       options.num_selections = 1;
!       options.selections[0] = XInternAtom(dpy, options.selection_name, 0);
!     } 
!   else if (second_selection_name == strrchr(options.selection_name, ','))
!     {
!       options.num_selections = 2;
!       *second_selection_name++ = '\0';
!       options.selections[0] = XInternAtom(dpy, options.selection_name, 0);
!       options.selections[1] = XInternAtom(dpy, second_selection_name, 0);
!     }
!   else  // user specified three or more selections; unsupported right now
!     Syntax(argv[0]);
! 
!   if (options.debug)
!     {
!       printf("Using selection(s) ");
!       PrintSelections(NULL);
!     }
! 
    buffer = 0;
     
    options.value = XFetchBuffer(dpy, &options.length, buffer);
