[comp.sources.x] v10i072: xsel, Patch2, Part01/01

rlh2@ukc.ac.uk (Richard Hesketh) (11/16/90)

Submitted-by: Richard Hesketh <rlh2@ukc.ac.uk>
Posting-number: Volume 10, Issue 72
Archive-name: xsel/patch2
Patch-To: xsel: Volume 6, Issue 79
Patch-To: xsel: Volume 7, Issue 35 (patch 1)

This is the second patch to "xselection" to allow it to set and retrieve
cutbuffer values.  It also now allows prepending and appending of values to
both selection properties and cutbuffers.

These additions were contributed by trost@reed.earn

Richard Hesketh   :   rlh2@ukc.ac.uk
Computing Officer, Computing Lab., University of Kent at Canterbury,
Canterbury, Kent, CT2 7NF, United Kingdom.
        Tel: +44 227 764000 ext 7620/7590      Fax: +44 227 762811

*** /tmp/,RCSt1a24678	Fri Oct 12 11:27:39 1990
--- patchlevel.h	Fri Oct 12 11:26:27 1990
***************
*** 1 ****
! #define PATCHLEVEL 1
--- 1 ----
! #define PATCHLEVEL 2

*** /tmp/,RCSt1a24681	Fri Oct 12 11:27:41 1990
--- xselection.c	Fri Oct 12 11:26:27 1990
***************
*** 1,6 ****
  #ifndef lint
! static char rcsid[] = "$Header: xselection.c 1.2 90/07/31 09:06:57 rlh2 Rel $";
! #endif !lint
  
  /* 
   * Copyright 1990 Richard Hesketh / rlh2@ukc.ac.uk
--- 1,7 ----
  #ifndef lint
! static char rcsid[] =
!    "$Xukc: xselection.c,v 1.3 90/10/12 11:12:53 rlh2 Rel $";
! #endif /* !lint */
  
  /* 
   * Copyright 1990 Richard Hesketh / rlh2@ukc.ac.uk
***************
*** 41,46 ****
--- 42,48 ----
  #include <X11/Xresource.h>
  
  #define PROG_NAME "xselection"
+ #define PROG_CLASS "XSelection"
  
  #define CHUNK 1000
  
***************
*** 49,57 ****
--- 51,66 ----
  
  static Atom selection_atom = NULL;
  static unsigned char *current_selection = NULL;
+ static unsigned char *old_selection = NULL;
  
+ static int selection_mode;
+ 
  static XrmOptionDescRec options[] = {
  	{ "-display", ".display", XrmoptionSepArg, (caddr_t)NULL },
+ 	{ "-append", ".mode", XrmoptionNoArg, (caddr_t)"2" },
+ 	{ "-prepend", ".mode", XrmoptionNoArg, (caddr_t)"1" },
+ 	{ "-replace", ".mode", XrmoptionNoArg, (caddr_t)"0" },
+ 	{ "-cutbuffer", ".cutbuffer", XrmoptionNoArg, (caddr_t)"true" },
  };
  
  static unsigned char *get_selection();
***************
*** 59,66 ****
  static void
  usage()
  {
! 	fprintf(stderr, "usage: %s property [- | [--] new_value]\n",
! 								PROG_NAME);
  	exit (-1);
  }
  
--- 68,79 ----
  static void
  usage()
  {
! 	fprintf(stderr,
! 		"usage: %s [ -display display_name ] [ -append | -prepend",
! 		PROG_NAME);
! 	fprintf(stderr, " | -replace ]\n");
! 	fprintf(stderr, "\t\t  [ PROPERTY_NAME | -cutbuffer [0-7] ]");
! 	fprintf(stderr, " [ - | [--] new_value ]\n");
  	exit (-1);
  }
  
***************
*** 136,151 ****
  	Display *dpy;
  	XEvent ev;
  	char resource[100];
  	char *blank, *display;
! 	XrmDatabase db = NULL;
  	XrmValue value;
  	Window window;
  	int want_to_own = 0;
  
! 	XrmParseCommand(&db, options, 1, PROG_NAME, &argc, argv);
  
  	(void)sprintf(resource, "%s.display", PROG_NAME);
! 	if (XrmGetResource(db, resource, "", &blank, &value))
  		display = (char *)value.addr;
  	else
  		display = NULL;
--- 149,167 ----
  	Display *dpy;
  	XEvent ev;
  	char resource[100];
+ 	char Resource[100];	/* for class information */
  	char *blank, *display;
! 	XrmDatabase odb = NULL, db = NULL;
  	XrmValue value;
  	Window window;
  	int want_to_own = 0;
  
! 	XrmParseCommand(&odb, options, sizeof(options)/sizeof(options[0]),
! 			PROG_NAME, &argc, argv);
  
  	(void)sprintf(resource, "%s.display", PROG_NAME);
! 	(void)sprintf(Resource, "%s.Display", PROG_CLASS);
! 	if (XrmGetResource(odb, resource, Resource, &blank, &value))
  		display = (char *)value.addr;
  	else
  		display = NULL;
***************
*** 158,170 ****
  
  	if (argc < 2 || argc > 4)
  		usage();
- 		
- 	selection_atom = XInternAtom(dpy, argv[1], argc == 2);
  
! 	if (selection_atom == NULL) {
! 		fprintf(stderr, "%s: %s not a name of a known selection property\n",
! 					PROG_NAME, argv[1]);
! 		exit (-2);
  	}
  
  	if (argc == 3) {
--- 174,207 ----
  
  	if (argc < 2 || argc > 4)
  		usage();
  
! 	XrmMergeDatabases(dpy->db, &db);
! 	XrmMergeDatabases(odb, &db);
! 
! 	(void)sprintf(resource, "%s.mode", PROG_NAME);
! 	(void)sprintf(Resource, "%s.Mode", PROG_CLASS);
! 	if (XrmGetResource(db, resource, Resource, &blank, &value) ||
! 	    XrmGetResource(dpy->db, resource, Resource, &blank, &value))
! 	    switch (value.addr[0]) {
! 	    case '0':
! 	            selection_mode = PropModeReplace;
! 	            break;
! 	    case '1':
! 	            selection_mode = PropModePrepend;
! 	            break;
! 	    case '2':
! 	            selection_mode = PropModeAppend;
! 	            break;
! 	    }
! 	else
! 	    selection_mode = PropModeReplace;
! 
! 	if (selection_mode != PropModeReplace &&
! 	    selection_mode != PropModeAppend &&
! 	    selection_mode != PropModePrepend) {
! 	        fprintf(stderr, "%s: Bad selection mode %d.\n",
! 	                PROG_NAME, selection_mode);
! 	        exit(-2);
  	}
  
  	if (argc == 3) {
***************
*** 184,197 ****
  		want_to_own = 1;
  	}
  
  	/* this window never gets mapped - its simply used as an ID */
  	window = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
  							0, 0, 1, 1, 0, 0, 0);
  
! 	if (want_to_own)
  		/* set the selection and wait for someone to take it */
  		own_selection(dpy, window, selection_atom);
! 	else {
  		/* get the selection */
  		current_selection = get_selection(dpy, window, selection_atom);
  		if (current_selection != NULL)
--- 221,279 ----
  		want_to_own = 1;
  	}
  
+ 	(void)sprintf(resource, "%s.cutbuffer", PROG_NAME);
+ 	(void)sprintf(Resource, "%s.Cutbuffer", PROG_CLASS);
+ 	if (XrmGetResource(db, resource, Resource, &blank, &value) ||
+ 	    XrmGetResource(dpy->db, resource, Resource, &blank, &value)) {
+ 		int cutbuffer = atoi(argv[1]);
+ 		if (cutbuffer < 0 || cutbuffer > 7) {
+ 			fprintf(stderr,
+ 			    "%s: %d is not a valid cut buffer, must be 0-7.\n",
+ 			    PROG_NAME, cutbuffer);
+ 			exit(-8);
+ 		}
+ 		if (want_to_own)
+ 			XChangeProperty(dpy, DefaultRootWindow(dpy),
+ 					XA_CUT_BUFFER0 + cutbuffer, XA_STRING,
+ 					8, selection_mode, current_selection,
+ 					strlen(current_selection));
+ 		else {
+ 			Atom actual_type;
+ 			int actual_format;
+ 			unsigned long nitems, bytes_after;
+ 			unsigned char* data;
+ 
+ 			XGetWindowProperty(dpy, DefaultRootWindow(dpy),
+ 					   XA_CUT_BUFFER0 + cutbuffer,
+ 					   0L, 10240L, False, AnyPropertyType,
+ 					   &actual_type, &actual_format,
+ 					   &nitems, &bytes_after, &data);
+ 			printf("%s", data);
+ 		}
+ 		XCloseDisplay(dpy);
+ 		exit(0);
+ 	}
+ 
+ 	selection_atom = XInternAtom(dpy, argv[1], argc == 2);
+ 
+ 	if (selection_atom == NULL) {
+ 		fprintf(stderr,
+ 			"%s: %s not a name of a known selection property.\n",
+ 			PROG_NAME, argv[1]);
+ 		exit (-2);
+ 	}
+ 
  	/* this window never gets mapped - its simply used as an ID */
  	window = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
  							0, 0, 1, 1, 0, 0, 0);
  
! 	if (want_to_own) {
  		/* set the selection and wait for someone to take it */
+ 		if (selection_mode != PropModeReplace)
+ 			old_selection = get_selection(dpy, window,
+ 						      selection_atom);
  		own_selection(dpy, window, selection_atom);
! 	} else {
  		/* get the selection */
  		current_selection = get_selection(dpy, window, selection_atom);
  		if (current_selection != NULL)
***************
*** 242,247 ****
--- 324,340 ----
          XSelectionRequestEvent  *req_event;
          unsigned char *data;
  
+ 	if (selection_mode != PropModeReplace) {
+ 		data = old_selection;
+ 		XChangeProperty(ptr_event->xselectionrequest.display,
+ 				ptr_event->xselectionrequest.requestor,
+ 				ptr_event->xselectionrequest.property,
+ 				ptr_event->xselectionrequest.target,
+ 				8, PropModeReplace, data,
+ 				(old_selection == NULL) ? 0 :
+ 				strlen(old_selection));
+ 	}
+ 
          data = current_selection;
  
          XChangeProperty(ptr_event->xselectionrequest.display,
***************
*** 248,254 ****
                          ptr_event->xselectionrequest.requestor,
                          ptr_event->xselectionrequest.property,
                          ptr_event->xselectionrequest.target,
!                         8, PropModeReplace, data,
                          (current_selection == NULL) ?
  			0 : strlen(current_selection));
  
--- 341,347 ----
                          ptr_event->xselectionrequest.requestor,
                          ptr_event->xselectionrequest.property,
                          ptr_event->xselectionrequest.target,
!                         8, selection_mode, data,
                          (current_selection == NULL) ?
  			0 : strlen(current_selection));
  
***************
*** 267,273 ****
                  notify_event.property = req_event->property;
  
  	/* tell the requestor he has a copy of the selection */
!         (void) XSendEvent(req_event->display, req_event->requestor,
  					False, 0, (XEvent *)&notify_event);
  	XFlush(dpy);
  }
--- 360,366 ----
                  notify_event.property = req_event->property;
  
  	/* tell the requestor he has a copy of the selection */
!         (void)XSendEvent(req_event->display, req_event->requestor,
  					False, 0, (XEvent *)&notify_event);
  	XFlush(dpy);
  }

*** /tmp/,RCSt1a24684	Fri Oct 12 11:27:42 1990
--- xselection.man	Fri Oct 12 11:26:28 1990
***************
*** 1,8 ****
  .TH XSELECTION l "31 March 1990"
  .SH NAME
! xselection \- get or set an X selection property value
  .SH SYNOPSIS
! \fBxselection\fP [ -display display_name ] PROPERTY_NAME [- | [--] new_value ]
  .SH DESCRIPTION
  If the \fInew_value\fP argument is not given \fIxselection\fP retrieves the
  current value of the named selection property
--- 1,12 ----
  .TH XSELECTION l "31 March 1990"
  .SH NAME
! xselection \- get or set an X selection or cutbuffer property value
  .SH SYNOPSIS
! \fBxselection\fP
! [ -display display_name ]
! [ -append | -prepend | -replace ]
! [ PROPERTY_NAME | -cutbuffer [0-7] ]
! [- | [--] new_value ]
  .SH DESCRIPTION
  If the \fInew_value\fP argument is not given \fIxselection\fP retrieves the
  current value of the named selection property
***************
*** 16,21 ****
--- 20,32 ----
  flag definition off using the '--' argument, e.g.
  \fIxselection PRIMARY -- -\fP
  
+ By using the '-cutbuffer' flag, the program will modify the contents
+ of the specified cut buffer instead of a selection.
+ The '-append', '-prepend', and '-replace' flags are used to modify how
+ the program changes the selection.  By default, it simple overwrites
+ the selection's value (equivalent to '-replace').  By using the
+ '-append' flag, the new value is append to the old selection's
+ contents.  The '-prepend' flag behaves similarly.
  This program can be used
  from within shell scripts to set and retrieve the contents of the cut buffer.
  The standard cut buffer selection property is accessed with the property
***************
*** 24,31 ****
  .SH ENVIRONMENT VARIABLES
  DISPLAY \- default X Server to enquire.
  .SH BUGS
! As yet unknown.
  .SH AUTHOR
! Richard Hesketh, University of Kent at Canterbury, March 1990
  .br
! rlh2@ukc.ac.uk
--- 35,43 ----
  .SH ENVIRONMENT VARIABLES
  DISPLAY \- default X Server to enquire.
  .SH BUGS
! The program pays no attention to the resources specified on the server
! (commonly defined in $HOME/.Xdefaults).
  .SH AUTHOR
! Richard Hesketh (rlh2@ukc.ac.uk), University of Kent at Canterbury, March 1990
  .br
! prepend/append and cutbuffer support by trost@reed.earn

dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.
--
dan
----------------------------------------------------
O'Reilly && Associates   argv@sun.com / argv@ora.com
Opinions expressed reflect those of the author only.