From:	CRDGW2::CRDGW2::MRGATE::"SMTP::PREP.AI.MIT.EDU::HELP-GNU-EMACS-REQUEST"  3-MAR-1992 22:16:21.45
To:	ARISIA::EVERHART
CC:	
Subj:	x-rebind-key patch for Gnue Emacs 18.58

From:	help-gnu-emacs-request@prep.ai.mit.edu@SMTP@CRDGW2
To:	Everhart@Arisia@MRGATE

Received:  by crdgw1.ge.com (5.57/GE 1.123)
	 id AA18068; Tue, 3 Mar 92 21:36:36 EST
Received: by life.ai.mit.edu (4.1/AI-4.10) id AA10714; Tue, 3 Mar 92 20:32:59 EST
Return-Path: <help-gnu-emacs-request@prep.ai.mit.edu>
Received: from news.cis.ohio-state.edu by life.ai.mit.edu (4.1/AI-4.10) id AA10653; Tue, 3 Mar 92 20:31:26 EST
Received: by news.cis.ohio-state.edu (5.61-kk/5.911008)
	id AA04513; Tue, 3 Mar 92 20:04:45 -0500
Received: from USENET by news.cis.ohio-state.edu with netnews
	for help-gnu-emacs@prep.ai.mit.edu (help-gnu-emacs@prep.ai.mit.edu);
	contact usenet@news.cis.ohio-state.edu if you have questions.
To: help-gnu-emacs@prep.ai.mit.edu
Date: 3 Mar 92 21:16:33 GMT
Message-Id: <SCOTTH.92Mar3161633@hoshi.corp.sgi.com>
Organization: Silicon Graphics Inc, Mountain View, CA
From: scotth@hoshi.corp.sgi.com (Scott Henry)
Sender: help-gnu-emacs-request@prep.ai.mit.edu
Subject: x-rebind-key patch for Gnue Emacs 18.58


I believe that this patch was originally based upon the epoch code.
I've been hand patching this since 18.55, so I thought that I'd make
some new diffs and post them. I've only tested them on an IRIS running
Irix 4.0.2, so use at your own risk.

*** src/x11fns.c-orig	Sat Oct  5 11:01:14 1991
--- src/x11fns.c	Thu Feb 20 11:12:18 1992
***************
*** 866,871 ****
--- 866,961 ----
  
  #endif foobar
  
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ /* Re-written version of x-rebind-key [AMC] Copied from Epoch. */
+ static KeySym modtable[] =
+     { XK_Shift_Lock, XK_Shift_L, XK_Shift_R, XK_Meta_L, XK_Meta_R,
+       XK_Control_L, XK_Control_R, XK_Alt_L, XK_Alt_R };
+ #define MODTABLESIZE (sizeof(modtable)/sizeof(KeySym))
+ 
+ DEFUN ("x-rebind-key", Fx_rebind_key, Sx_rebind_key, 3, 3, 0,
+   "Rebind KEYCODE, with shift bits SHIFT-MASK, to new string NEWSTRING.\n\
+ KEYCODE should be the string name of an X KeySym\n\
+ SHIFT-MASK should be a number representing the shift mask.\n\
+ NEWSTRING is an arbitrary string of keystrokes.\n\
+ Shift Lock    1\n\
+ Left Shift    2      Right Shift    4\n\
+ Left Meta     8	     Right Meta     16\n\
+ Left Control  32     Right Control  64\n\
+ Left Alt      128    Right Alt      256")
+ 
+ 	(keycode, shift_mask, newstring)
+ 	register Lisp_Object keycode;
+ 	register Lisp_Object shift_mask;
+ 	register Lisp_Object newstring;
+     {
+     KeySym xkey,modlist[10];
+     int imod = 0;
+     int modrequest;
+     int i,mask;
+ 
+     /* check arguments */
+     CHECK_STRING(keycode,0);
+     CHECK_NUMBER(shift_mask,1);
+     CHECK_STRING(newstring,2);
+ 
+     xkey = XStringToKeysym(XSTRING(keycode)->data);
+     if (xkey == NoSymbol) error("Invalid X-key name");
+ 
+     modrequest = XFASTINT(shift_mask);
+ 
+     /* build the mod list */
+     for ( i=0 , mask=1 ; i < MODTABLESIZE ; ++i, mask <<= 1 )
+ 	{
+ 	if (modrequest & mask)
+ 	    modlist[imod++] = modtable[i];
+ 	}
+ 
+     XRebindKeysym(XXdisplay,xkey,modlist,imod,
+ 		  XSTRING(newstring)->data,
+ 		  strlen(XSTRING(newstring)->data));
+     return Qt;
+     }
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ static int
+ MaskFromKeysym(keysym) KeySym keysym;
+     {
+     int i;
+ 
+     for ( i=0 ; i < MODTABLESIZE ; ++i )
+ 	if (modtable[i] == keysym) return i ? 1<<i : 1;
+     return 0;
+     }
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ DEFUN ("x-mod-to-shiftmask",Fx_mod_to_shiftmask,Sx_mod_to_shiftmask,1,1,0,
+ "Given an index from 0..7, returns the shift mask corresponding to that\
+  modifier under X windows. Indexes are Shift, Lock, Control, Mod1, Mod2,\
+  Mod3, Mod4, Mod5")
+         (mod) Lisp_Object mod;
+     {
+     int i,index,result;
+     XModifierKeymap *xkmap;
+     KeyCode *map;
+     BLOCK_INPUT_DECLARE();
+ 
+     CHECK_NUMBER(mod,0);
+     index = XFASTINT(mod);
+     if (index < 0 || index > 7) return make_number(0);
+ 
+     BLOCK_INPUT();
+     xkmap = XGetModifierMapping(XXdisplay);
+     UNBLOCK_INPUT();
+ 
+     /* ugly, since the X structure is bizarro */
+     map = xkmap->modifiermap + xkmap->max_keypermod * index;
+ 
+     for ( i=0 , result=0 ; i < xkmap->max_keypermod ; ++i)
+ 	if (map[i])
+ 	    result |= MaskFromKeysym(XKeycodeToKeysym(XXdisplay,map[i],0));
+     return make_number(result);
+     }
+ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+ 
  XExitWithCoreDump ()
  {
  	XCleanUp ();
***************
*** 955,960 ****
--- 1045,1052 ----
    defsubr (&Sx_rebind_key);
    defsubr (&Sx_rebind_keys);
  #endif notdef
+   defsubr (&Sx_rebind_key);
+   defsubr (&Sx_mod_to_shiftmask);
    defsubr (&Sx_debug);
  }
  
=-=-=-=
--
 Scott Henry <scotth@sgi.com> / Traveller on Dragon Wings
 Networking Services,        / Help! My disclaimer is missing!
 Silicon Graphics, Inc      / Bureaucracy is the enemy of success.
