🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.epoch.misc
Article #1781

Patch to allow Epoch to use Selection instead of CutBuffs

#1781
From: Michael A. Petonic
Date: Sat, 31 Aug 1991 21:26
400 lines
14158 bytes
Because of the mail that my previous post generated, I decided to post the
patches that make Epoch use the X11 selection mechanism instead of the
older cut buffers.

Included in this shar file are two patches:
	epoch-lisp.patch
		motion.el
	src.patch
		emacs.c
		x11fns.c
		x11term.c
		xevent.c

These patches are based off of the original Epoch 3.2 release with the two
"official" Epoch patches assumed to have been applied.  

epoch-lisp.patch modifies motion.el to allow Epoch to un-highlight the selected
region when another X client requests ownership of the selection (i.e., when
you double-click on a word in an xterm).  In order for this patch to work,
you *must* byte-compile (somehow, perhaps with a previous version of Epoch)
motion.el to generate a new motion.elc.  If you don't, nothing is hurt, but
then you miss the behaviour of a real X11 client.

I've done a basic functional check of the patches and they seem to work.  Remember,
there's now another event available to Epoch, "selection-clear".  

And, as always, Caveat Emptor.

Enjoy,
-MikeP

--
Michael A. Petonic	       petonic@hal.com		       +1-512-794-2855
    HaL Computer Systems - Director of Custodial Services and Entertainment
				 Austin, Texas
		      "If you *have* to live in Texas..."

-------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  epoch-lisp.patches src.patches
# Wrapped by petonic@hal.com on Sat Aug 31 15:16:30 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'epoch-lisp.patches' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'epoch-lisp.patches'\"
else
echo shar: Extracting \"'epoch-lisp.patches'\" \(807 characters\)
sed "s/^X//" >'epoch-lisp.patches' <<'END_OF_FILE'
Xdiff -c /users/halserv1/petonic/epoch-files/epoch-3.2/epoch-lisp/motion.el ./motion.el
X*** /users/halserv1/petonic/epoch-files/epoch-3.2/epoch-lisp/motion.el	Fri Aug 30 11:04:41 1991
X--- ./motion.el	Sun Aug 25 17:46:34 1991
X***************
X*** 306,308 ****
X--- 306,322 ----
X  (global-set-mouse mouse-right mouse-down 'extend-mouse-drag)
X  (global-set-mouse mouse-right mouse-up 'end-mouse-drag)
X  (global-set-mouse mouse-middle mouse-down 'mouse::paste-cut-buffer)
X+ (install-event 'selection-clear)
X+ (defun clear-drag-button (type value screen)
X+   "Clears the highlighted drag button."
X+   (interactive)
X+   (if drag-button
X+       (progn
X+ 	(delete-button drag-button)
X+ 	(setq drag-button nil)
X+ 	)
X+     )
X+   )
X+ ;; Handle selection-clear events
X+ (push-event 'selection-clear 'clear-drag-button)
X+ 
END_OF_FILE
if test 807 -ne `wc -c <'epoch-lisp.patches'`; then
    echo shar: \"'epoch-lisp.patches'\" unpacked with wrong size!
fi
# end of 'epoch-lisp.patches'
fi
if test -f 'src.patches' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src.patches'\"
else
echo shar: Extracting \"'src.patches'\" \(9380 characters\)
sed "s/^X//" >'src.patches' <<'END_OF_FILE'
X*** /users/halserv1/petonic/epoch-files/epoch-3.2/src/emacs.c	Thu Oct 18 19:21:38 1990
X--- emacs.c	Fri Aug 30 10:33:45 1991
X***************
X*** 84,89 ****
X--- 84,94 ----
X    on subsequent starts.  */
X  int initialized;
X  
X+ /* Variables used for the selection mechanism. [-MikeP] */
X+ int PET_SelectionOwner;
X+ char *PET_SelectionBuffer;
X+ int PET_SelectionSize;
X+ 
X  /* Variable whose value is symbol giving operating system type */
X  Lisp_Object Vsystem_type;
X    
X*** /users/halserv1/petonic/epoch-files/epoch-3.2/src/x11fns.c	Fri Aug 30 11:11:00 1991
X--- x11fns.c	Fri Aug 30 10:34:11 1991
X***************
X*** 56,61 ****
X--- 56,65 ----
X  /* Non-nil if Emacs is running with an X window for display.
X     Nil if Emacs is run on an ordinary terminal.  */
X  
X+ extern int PET_SelectionOwner;
X+ extern char *PET_SelectionBuffer;
X+ extern int PET_SelectionSize;
X+ 
X  Lisp_Object Vxterm;
X  
X  Lisp_Object Vx_mouse_pos;
X***************
X*** 93,106 ****
X    check_xterm ();
X  
X    BLOCK_INPUT ();
X!   XSetSelectionOwner(XD_display, XA_PRIMARY, None, CurrentTime);
X!   XStoreBytes (XD_display, XSTRING (string)->data,
X! 	       XSTRING (string)->size);
X    UNBLOCK_INPUT ();
X  
X    return Qnil;
X  }
X  
X  DEFUN ("epoch::get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 0, 0,
X    "Return contents of cut buffer of the X window system, as a string.")
X       ()
X--- 98,135 ----
X    check_xterm ();
X  
X    BLOCK_INPUT ();
X!   
X!   /* If we don't have the selection, we have to get it. */
X!   if (!PET_SelectionOwner) {
X!     XSetSelectionOwner(cur_Xscreen->display, XA_PRIMARY, cur_Xscreen->xid, 
X! 		       CurrentTime);
X!     if (XGetSelectionOwner(cur_Xscreen->display, XA_PRIMARY) != 
X! 	cur_Xscreen->xid) {
X!       /* What else can we do but return?  Panic??!?!?!?! */
X!       return Qnil;
X!     }
X!     PET_SelectionOwner = 1;
X!     PET_SelectionBuffer = (char *) 0;
X!     PET_SelectionSize = 0;
X!   }
X!   /* If we have a previous buffer of selection, then we have to free it. */
X!   if (PET_SelectionBuffer != ((char *) 0)) {
X!     free(PET_SelectionBuffer);
X!     PET_SelectionSize = 0;
X!   }
X!   /* Allocate enough room for the data. */
X!   PET_SelectionBuffer  = (char *) xmalloc(XSTRING (string)->size);
X!   /* Copy the data into the selection buffer. */
X!   memcpy(PET_SelectionBuffer, XSTRING (string)->data, XSTRING (string)->size);
X!   PET_SelectionSize = XSTRING (string)->size;
X    UNBLOCK_INPUT ();
X  
X    return Qnil;
X  }
X  
X+ 
X+ static int egcb_alarmed;
X+ 
X  DEFUN ("epoch::get-cut-buffer", Fx_get_cut_buffer, Sx_get_cut_buffer, 0, 0, 0,
X    "Return contents of cut buffer of the X window system, as a string.")
X       ()
X***************
X*** 109,121 ****
X    register Lisp_Object string;
X    BLOCK_INPUT_DECLARE ();
X    register char *d;
X  
X    BLOCK_INPUT ();
X-   d = XFetchBytes (XD_display, &len);
X-   string = make_string (d, len);
X-   UNBLOCK_INPUT ();
X  
X    return string;
X  }
X  
X  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X--- 138,229 ----
X    register Lisp_Object string;
X    BLOCK_INPUT_DECLARE ();
X    register char *d;
X+   Window w;
X+   extern int PET_SelectionOwner;	/* Externalize */
X+   Atom prop;
X+   extern int egcb_handler();
X+   int (*old_alarm)();
X+   XEvent levent;
X+ #define EPOCHSELPROP	"EpochSelection"
X+ #define MAXEVENTS	40
X+   XEvent eventq[MAXEVENTS];
X+   int eventc = 0;
X+   int i;
X  
X+   /* Set w = minibuffer window. */
X+   w = cur_Xscreen->xid;
X+   
X    BLOCK_INPUT ();
X  
X+   if (!PET_SelectionOwner) {
X+     prop = XInternAtom(cur_Xscreen->display, EPOCHSELPROP, False);
X+ 
X+     XConvertSelection(cur_Xscreen->display, XA_PRIMARY, XA_STRING, prop, 
X+ 		      cur_Xscreen->xid, CurrentTime);
X+     egcb_alarmed = 0;
X+     old_alarm = (int (*)()) signal (SIGALRM, egcb_handler);
X+     alarm(5);
X+     for (;;) {
X+       XNextEvent(cur_Xscreen->display, &levent);
X+       alarm(0);
X+       if (egcb_alarmed) {
X+ 	string = make_string("", 0);
X+ 	break;
X+       }
X+       if (levent.type == SelectionNotify) {
X+ 	int ret_format, ret_len, ret_after;
X+ 	Atom ret_type;
X+ 	char *ret_prop;
X+ 	if (levent.xselection.property != None) {
X+ 	  XGetWindowProperty(cur_Xscreen->display,
X+ 			     levent.xselection.requestor,
X+ 			     levent.xselection.property,
X+ 			     0, 8192, False,
X+ 			     levent.xselection.target,
X+ 			     &ret_type, &ret_format, &ret_len,
X+ 			     &ret_after, &ret_prop);
X+ 	  string = make_string(ret_prop, ret_len);
X+ 	  XFree(ret_prop);
X+ 	  XDeleteProperty(cur_Xscreen->display,
X+ 			  levent.xselection.requestor,
X+ 			  levent.xselection.property);
X+ 	}
X+ 	/* Ooops, there was no owner of the selection. */
X+ 	else {
X+ 	  string = make_string("", 0);
X+ 	}
X+ 	break;
X+       }
X+       /* place the unknown event on the queue and check for exit conditions. */
X+       eventq[eventc++] = levent;
X+       if (eventc == (MAXEVENTS - 2)) {
X+ 	string = make_string("", 0);
X+ 	break;
X+       }
X+     }
X+   }
X+   /* We have the selection, so we should just copy that string into a newly
X+    * allocated string. */
X+   else {
X+     string = make_string(PET_SelectionBuffer, PET_SelectionSize);
X+   }
X+ 
X+   /* We have to put the information back in the reverse order of how we
X+    * received it since XPutBackEvent queues the event at the HEAD of the
X+    * event queue. */
X+   for (i=eventc-1; i >= 0; --i) {
X+     XPutBackEvent(cur_Xscreen->display, eventq + i);
X+   }
X+   (void) signal(SIGALRM, old_alarm);
X+ 
X+   UNBLOCK_INPUT ();
X    return string;
X+ }
X+ int
X+ egcb_handler()
X+ {
X+   ++egcb_alarmed;
X+   return;
X  }
X  
X  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X*** /users/halserv1/petonic/epoch-files/epoch-3.2/src/x11term.c	Fri Aug 30 11:11:00 1991
X--- x11term.c	Fri Aug 30 10:34:22 1991
X***************
X*** 140,145 ****
X--- 140,151 ----
X  extern char * XD_screen_name;
X  /* end of changed section */
X  
X+ /* Variables used for the selection mechanism. [-MikeP] */
X+ extern int PET_SelectionOwner;
X+ extern char *PET_SelectionBuffer;
X+ extern int PET_SelectionSize;
X+ 
X+ 
X  int configure_pending;
X  extern int initialized;
X  
X***************
X*** 1433,1438 ****
X--- 1443,1488 ----
X  	
X  	switch (event.type)
X  	    {
X+ 	    case SelectionClear:
X+ 	      /* Give up our selection shit and free the memory. */
X+ 	      PET_SelectionOwner = 0;
X+ 	      free(PET_SelectionBuffer);
X+ 	      PET_SelectionSize = 0;
X+ 	      /* Store this so our Lisp code can work on it. */
X+ 	      QUEUE_EVENT(&event);
X+ 	      break;
X+ 
X+ 
X+ 	    case SelectionRequest:
X+ 	      /* Someone's asking for the selection data and we currently own
X+ 	       * it, so we have to shovel the shit out in a property.
X+ 	       */
X+ 	      {
X+ 		XEvent ev;
X+ 		ev.type = SelectionNotify;
X+ 		ev.xselection.requestor = event.xselectionrequest.requestor;
X+ 		ev.xselection.selection = event.xselectionrequest.selection;
X+ 		ev.xselection.target = event.xselectionrequest.target;
X+ 		ev.xselection.time = event.xselectionrequest.time;
X+ 		ev.xselection.property = event.xselectionrequest.property;
X+ 		/* Check to make sure that they're asking for the primary 
X+ 		 * selection and that the target data type is STRING. */
X+ 		if ((event.xselectionrequest.selection = XA_PRIMARY) &&
X+ 		    (event.xselectionrequest.target == XA_STRING)) {
X+ 		  XChangeProperty(XD_display, ev.xselection.requestor,
X+ 				  ev.xselection.property,
X+ 				  ev.xselection.target,
X+ 				  8, 			/* Byte format */
X+ 				  PropModeReplace, 	/* Replace the prop data */
X+ 				  PET_SelectionBuffer,
X+ 				  PET_SelectionSize);
X+ 		} else {
X+ 		  /* Wrong selection or wrong target data type. */
X+ 		  ev.xselection.property = None;
X+ 		}
X+ 		XSendEvent(XD_display, ev.xselection.requestor, False, 0, &ev);
X+ 	      }
X+ 	      break;
X  	    case MappingNotify:
X  		XRefreshKeyboardMapping(&event);
X  		break;
X*** /users/halserv1/petonic/epoch-files/epoch-3.2/src/xevent.c	Fri Aug 30 11:11:05 1991
X--- xevent.c	Sun Aug 25 16:52:41 1991
X***************
X*** 46,52 ****
X  Lisp_Object Vx_mouse_events;
X  
X  Lisp_Object Qx_property_change,Qx_focus,Qx_map,Qx_move,Qx_resize;
X! Lisp_Object Qx_client_message,Qx_motion,Qx_button;
X  #ifdef DENYS_ALARM
X  Lisp_Object Qx_timer;
X  #endif /* DENYS_ALARM */
X--- 46,52 ----
X  Lisp_Object Vx_mouse_events;
X  
X  Lisp_Object Qx_property_change,Qx_focus,Qx_map,Qx_move,Qx_resize;
X! Lisp_Object Qx_client_message,Qx_motion,Qx_button,Qx_selection_clear;
X  #ifdef DENYS_ALARM
X  Lisp_Object Qx_timer;
X  #endif /* DENYS_ALARM */
X***************
X*** 247,252 ****
X--- 247,259 ----
X  
X    switch (xp->xany.type)
X      {
X+       /* Received when the Selection Ownership is lost to another client.
X+        */
X+     case SelectionClear:
X+       evp->contents[0] = Qx_selection_clear;
X+       evp->contents[1] = Qnil;
X+       break;
X+ 
X      case PropertyNotify :
X        evp->contents[0] = Qx_property_change;
X        evp->contents[1] = ReadPropertyEvent((XPropertyEvent *)xp,xs);
X***************
X*** 370,375 ****
X--- 377,383 ----
X      Qx_client_message = intern("client-message");       staticpro(&Qx_client_message);
X      Qx_motion = intern("motion");                       staticpro(&Qx_motion);
X      Qx_button = intern("button");                       staticpro(&Qx_button);
X+     Qx_selection_clear = intern("selection-clear");	staticpro(&Qx_selection_clear);
X  
X  #ifdef DENYS_ALARM
X      Qx_timer = intern("timer");                         staticpro(&Qx_timer);
END_OF_FILE
if test 9380 -ne `wc -c <'src.patches'`; then
    echo shar: \"'src.patches'\" unpacked with wrong size!
fi
# end of 'src.patches'
fi
echo shar: End of shell archive.
exit 0
Technical Details
Message-ID: <PETONIC.91Aug31172643@daisy.hal.com>
Path: arc1-ca.pugleaf.net!gmdzi!unido!fauern!iraun1.ira.uka.de!sol.ctr.columbia.edu!samsung!uunet!decwrl!hal.com!halaus!halaus!petonic

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fc7ee,214d3784b315c558,start
X-Google-Attributes: gidfc7ee,public
X-Google-ArrivalTime: 1991-08-31 16:00:20 PST
Path: arc1-ca.pugleaf.net!gmdzi!unido!fauern!iraun1.ira.uka.de!sol.ctr.columbia.edu!samsung!uunet!decwrl!hal.com!halaus!halaus!petonic
From: petonic@hal.com (Michael A. Petonic)
Newsgroups: gnu.epoch.misc
Subject: Patch to allow Epoch to use Selection instead of CutBuffs
Message-ID: <PETONIC.91Aug31172643@daisy.hal.com>
Date: 31 Aug 91 21:26:43 GMT
Sender: news@hal.com
Distribution: gnu
Organization: Henry's Laughing Gas Co., Inc.
Lines: 400