Article View: gnu.epoch.misc
Article #1781Patch to allow Epoch to use Selection instead of CutBuffs
From: Michael A. Petonic
Date: Sat, 31 Aug 1991 21:26
Date: Sat, 31 Aug 1991 21:26
400 lines
14158 bytes
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!petonicShow 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