Subject: Move Control modifier only in Emacs

From: [email-masked]
Date: Tue, 6 Apr 2010 10:39:01 +0400

This patch allows to move Control modifier only in Emacs.
For example, you can do
(setq x-ctrl-keysym 'meta)
(setq x-meta-keysym 'ctrl)
to swap Control and Meta in Emacs, but not in X Window.

diff -ur emacs.orig/src/xterm.c emacs/src/xterm.c
--- emacs.orig/src/xterm.c	2010-04-06 09:05:46.000000000 +0400
+++ emacs/src/xterm.c	2010-04-06 10:27:24.644183557 +0400
@@ -315,9 +315,9 @@
 
 /* The keysyms to use for the various modifiers.  */
 
-Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
+Lisp_Object Vx_ctrl_keysym, Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym;
 Lisp_Object Vx_keysym_table;
-static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
+static Lisp_Object Qctrl, Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value;
 
 static Lisp_Object Qvendor_specific_keysyms;
 static Lisp_Object Qlatin_1;
@@ -3649,12 +3649,15 @@
      struct x_display_info *dpyinfo;
      unsigned int state;
 {
+  EMACS_UINT mod_ctrl = ctrl_modifier;
   EMACS_UINT mod_meta = meta_modifier;
   EMACS_UINT mod_alt  = alt_modifier;
   EMACS_UINT mod_hyper = hyper_modifier;
   EMACS_UINT mod_super = super_modifier;
   Lisp_Object tem;
 
+  tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_ctrl = XUINT (tem);
   tem = Fget (Vx_alt_keysym, Qmodifier_value);
   if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
   tem = Fget (Vx_meta_keysym, Qmodifier_value);
@@ -3666,7 +3669,7 @@

   return (  ((state & (ShiftMask | dpyinfo->shift_lock_mask)) ? shift_modifier : 0)
-            | ((state & ControlMask)			? ctrl_modifier	: 0)
+            | ((state & ControlMask)		? mod_ctrl	: 0)
             | ((state & dpyinfo->meta_mod_mask)		? mod_meta	: 0)
             | ((state & dpyinfo->alt_mod_mask)		? mod_alt	: 0)
             | ((state & dpyinfo->super_mod_mask)	? mod_super	: 0)
@@ -3678,6 +3681,7 @@
      struct x_display_info *dpyinfo;
      unsigned int state;
 {
+  EMACS_UINT mod_ctrl = ctrl_modifier;
   EMACS_UINT mod_meta = meta_modifier;
   EMACS_UINT mod_alt  = alt_modifier;
   EMACS_UINT mod_hyper = hyper_modifier;
@@ -3685,6 +3689,8 @@
 
   Lisp_Object tem;
 
+  tem = Fget (Vx_ctrl_keysym, Qmodifier_value);
+  if (! EQ (tem, Qnil)) mod_ctrl = XUINT (tem);
   tem = Fget (Vx_alt_keysym, Qmodifier_value);
   if (! EQ (tem, Qnil)) mod_alt = XUINT (tem);
   tem = Fget (Vx_meta_keysym, Qmodifier_value);
@@ -3699,7 +3705,7 @@
             | ((state & mod_super)	? dpyinfo->super_mod_mask : 0)
             | ((state & mod_hyper)	? dpyinfo->hyper_mod_mask : 0)
             | ((state & shift_modifier)	? ShiftMask        : 0)
-            | ((state & ctrl_modifier)	? ControlMask      : 0)
+            | ((state & mod_ctrl)	? ControlMask  : 0)
             | ((state & mod_meta)	? dpyinfo->meta_mod_mask  : 0));
 }
 
@@ -11024,6 +11030,8 @@
   last_mouse_motion_frame = Qnil;
 
   Qmodifier_value = intern_c_string ("modifier-value");
+  Qctrl = intern_c_string ("ctrl");
+  Fput (Qctrl, Qmodifier_value, make_number (ctrl_modifier));
   Qalt = intern_c_string ("alt");
   Fput (Qalt, Qmodifier_value, make_number (alt_modifier));
   Qhyper = intern_c_string ("hyper");
@@ -11035,30 +11043,37 @@
 
   DEFVAR_LISP ("x-alt-keysym", &Vx_alt_keysym,
     doc: /* Which keys Emacs uses for the alt modifier.
-This should be one of the symbols `alt', `hyper', `meta', `super'.
-For example, `alt' means use the Alt_L and Alt_R keysyms.  The default
-is nil, which is the same as `alt'.  */);
+This should be one of the symbols `ctrl', `alt', `hyper', `meta', `super'.
+For example, `alt' means use the Alt_L and Alt_R keysyms.
+The default is nil, which is the same as `alt'.  */);
   Vx_alt_keysym = Qnil;
 
+  DEFVAR_LISP ("x-ctrl-keysym", &Vx_ctrl_keysym,
+    doc: /* Which keys Emacs uses for the ctrl modifier.
+This should be one of the symbols `ctrl', `alt', `hyper', `meta', `super'.
+For example, `ctrl' means use the Control_L and Control_R keysyms.
+The default is nil, which is the same as `ctrl'.  */);
+  Vx_ctrl_keysym = Qnil;
+
   DEFVAR_LISP ("x-hyper-keysym", &Vx_hyper_keysym,
     doc: /* Which keys Emacs uses for the hyper modifier.
-This should be one of the symbols `alt', `hyper', `meta', `super'.
-For example, `hyper' means use the Hyper_L and Hyper_R keysyms.  The
-default is nil, which is the same as `hyper'.  */);
+This should be one of the symbols `ctrl', `alt', `hyper', `meta', `super'.
+For example, `hyper' means use the Hyper_L and Hyper_R keysyms.
+The default is nil, which is the same as `hyper'.  */);
   Vx_hyper_keysym = Qnil;
 
   DEFVAR_LISP ("x-meta-keysym", &Vx_meta_keysym,
     doc: /* Which keys Emacs uses for the meta modifier.
-This should be one of the symbols `alt', `hyper', `meta', `super'.
-For example, `meta' means use the Meta_L and Meta_R keysyms.  The
-default is nil, which is the same as `meta'.  */);
+This should be one of the symbols `ctrl', `alt', `hyper', `meta', `super'.
+For example, `meta' means use the Meta_L and Meta_R keysyms.
+The default is nil, which is the same as `meta'.  */);
   Vx_meta_keysym = Qnil;
 
   DEFVAR_LISP ("x-super-keysym", &Vx_super_keysym,
     doc: /* Which keys Emacs uses for the super modifier.
-This should be one of the symbols `alt', `hyper', `meta', `super'.
-For example, `super' means use the Super_L and Super_R keysyms.  The
-default is nil, which is the same as `super'.  */);
+This should be one of the symbols `ctrl', `alt', `hyper', `meta', `super'.
+For example, `super' means use the Super_L and Super_R keysyms.
+The default is nil, which is the same as `super'.  */);
   Vx_super_keysym = Qnil;
 
   DEFVAR_LISP ("x-keysym-table", &Vx_keysym_table,

-- 
Andrey Astafiev