Index: src/macterm.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/macterm.c,v
retrieving revision 1.123
diff -c -r1.123 macterm.c
*** src/macterm.c	14 Jul 2005 09:23:24 -0000	1.123
--- src/macterm.c	15 Jul 2005 23:15:49 -0000
***************
*** 86,99 ****
  #include "atimer.h"
  #include "keymap.h"
  
! /* Set of macros that handle mapping of Mac modifier keys to emacs.  */
! #define macCtrlKey     (NILP (Vmac_reverse_ctrl_meta) ? controlKey :	\
! 			(NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
  #define macShiftKey    (shiftKey)
! #define macMetaKey     (NILP (Vmac_reverse_ctrl_meta) ?			\
! 			(NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
! 			: controlKey)
! #define macAltKey      (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
  
  
  /* Non-nil means Emacs uses toolkit scroll bars.  */
--- 86,118 ----
  #include "atimer.h"
  #include "keymap.h"
  
! /* Set of macros that handle mapping of Mac modifier keys to emacs.  
!     If any of the newer-style mac_*_modifier variables is set, these 
!     macros are basically out of function.
!  */
!  
! #define macOldModifierSetting   (  NILP(Vmac_control_modifier) && \
! 				   NILP(Vmac_option_modifier) && \
! 				   NILP(Vmac_command_modifier)   )
!  
! #define macCtrlKey     (macOldModifierSetting ? \
!  			(NILP(Vmac_reverse_ctrl_meta) ? controlKey :	\
!  			       (NILP(Vmac_command_key_is_meta) ? \
! 				optionKey : cmdKey)) :		 \
!  			controlKey)
  #define macShiftKey    (shiftKey)
!  
! #define macMetaKey     (macOldModifierSetting ? \
!  			(NILP(Vmac_reverse_ctrl_meta) ?		\
!  			 (NILP(Vmac_command_key_is_meta) ? optionKey : \
! 			  cmdKey) : controlKey) :		       \
!  			(cmdKey | controlKey | optionKey))
!  
! #define macAltKey     (macOldModifierSetting ?  \
! 			(NILP(Vmac_command_key_is_meta) ? \
! 			 cmdKey : optionKey) : optionKey)
!  
! #define macCmdKey (cmdKey)
  
  
  /* Non-nil means Emacs uses toolkit scroll bars.  */
***************
*** 205,211 ****
  
  /* The keysyms to use for the various modifiers.  */
  
! static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value;
  
  extern int inhibit_window_system;
  
--- 224,230 ----
  
  /* The keysyms to use for the various modifiers.  */
  
! static Lisp_Object Qalt, Qhyper, Qsuper, Qctrl, Qmeta, Qmodifier_value;
  
  extern int inhibit_window_system;
  
***************
*** 7321,7333 ****
  /* Contains the string "reverse", which is a constant for mouse button emu.*/
  Lisp_Object Qreverse;
  
! /* True if using command key as meta key.  */
  Lisp_Object Vmac_command_key_is_meta;
  
  /* Modifier associated with the option key, or nil for normal behavior. */
  Lisp_Object Vmac_option_modifier;
  
! /* True if the ctrl and meta keys should be reversed.  */
  Lisp_Object Vmac_reverse_ctrl_meta;
  
  /* True if the option and command modifiers should be used to emulate
--- 7340,7360 ----
  /* Contains the string "reverse", which is a constant for mouse button emu.*/
  Lisp_Object Qreverse;
  
! /* True if using command key as meta key.  
!    Deprecated; only use if macOldModifierSetting evaluates to true. */
  Lisp_Object Vmac_command_key_is_meta;
  
+ /* Modifier associated with the control key, or nil for normal behavior. */
+ Lisp_Object Vmac_control_modifier;
+ 
  /* Modifier associated with the option key, or nil for normal behavior. */
  Lisp_Object Vmac_option_modifier;
  
! /* Modifier associated with the command key, or nil for normal behavior. */
! Lisp_Object Vmac_command_modifier;
! 
! /* True if the ctrl and meta keys should be reversed. 
! 	Deprecated; only use if macOldModifierSetting evaluates to true. */
  Lisp_Object Vmac_reverse_ctrl_meta;
  
  /* True if the option and command modifiers should be used to emulate
***************
*** 7347,7352 ****
--- 7374,7386 ----
     for processing before Emacs sees it.  */
  Lisp_Object Vmac_pass_control_to_system;
  
+ /* If  non-nil, the Mac \"Option\" key can be used to compose
+        characters as handled by the system and depending on the
+        keyboard layout chosen. Only if the Mac \"Command\" or \"Ctrl\" key
+        is depressed at the same time, Emacs evaluates the combination using
+        whatever modifier is set in mac-option-modifier.  */
+ Lisp_Object Vmac_pass_option_to_system;
+ 
  /* Points to the variable `inev' in the function XTread_socket.  It is
     used for passing an input event to the function back from
     Carbon/Apple event handlers.  */
***************
*** 7404,7420 ****
    unsigned int result = 0;
    if (mods & macShiftKey)
      result |= shift_modifier;
!   if (mods & macCtrlKey)
!     result |= ctrl_modifier;
!   if (mods & macMetaKey)
!     result |= meta_modifier;
!   if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey))
!     result |= alt_modifier;
!   if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
!       Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
!       if (!NILP(val))
            result |= XUINT(val);
!   }
  
    return result;
  }
--- 7438,7512 ----
    unsigned int result = 0;
    if (mods & macShiftKey)
      result |= shift_modifier;
! 
!   if (macOldModifierSetting)   /* compatibility with old-style modifier keys */
!     {
!       if (mods & macCtrlKey)
! 	result |= ctrl_modifier;
!       if (mods & macMetaKey)
! 	result |= meta_modifier;
! 
!       if ( ( NILP(Vmac_pass_option_to_system) || 
! 	     ( /* only for ctrl/cmd combos if option is handled by system */
! 	      (mods & cmdKey) || (mods & controlKey) 
! 	       )
! 	     ) &&
! 	   !NILP (Vmac_command_key_is_meta) &&
! 	   (mods & macAltKey) 
! 	)
! 	result |= alt_modifier;
!     } else
!     {
!       /* new-style modifier keys */ 
! 
!       /* if Vmac_pass_option_to_system is NIL, we fully process the Option
! 	 key. Otherwise, we only process it if an additional Ctrl or Command
! 	 is pressed. That way the system may convert the character to a 
! 	 composed one.
!       */
! 
!       if (
! 	  (mods & optionKey) &&
! 	  (
! 	   ( NILP(Vmac_pass_option_to_system) || 
! 	     ( 
! 	      (mods & cmdKey) || (mods & controlKey) 
! 	       )
! 	     )
! 	   )
! 	  )
! 	{
! 	  if (!NILP (Vmac_option_modifier)) {
! 	    Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
! 	    if (!NILP(val))
! 	      result |= XUINT(val);
! 	  } else { /* default behavior if modifier variable is set to nil: 
! 		      do NOT assume alt modifier, because the OS already 
! 		      sends a modified key (e.g. option-l -> @ 
! 		      on German keyboard) */
! 	      
! 	      result |= alt_modifier;  
! 	  }
! 
! 	}
!       if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) {
! 	Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value);
! 	if (!NILP(val))
            result |= XUINT(val);
!       } else { /* default behavior if modifier variable is not set: 
! 		  assign hyper*/
! 	if (mods & macCmdKey)
! 	  result |= hyper_modifier;
!       }
!       if (!NILP (Vmac_control_modifier) && (mods & controlKey)) {
! 	Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value);
! 	if (!NILP(val))
!           result |= XUINT(val);
!       } else { /* default behavior if modifier variable is not set */
! 	if (mods & macCtrlKey)
! 	  result |= ctrl_modifier;
!       }
!     }
  
    return result;
  }
***************
*** 9326,9334 ****
  		 || !(er.modifiers & cmdKey))
  		&& (!NILP (Vmac_pass_control_to_system)
  		    || !(er.modifiers & controlKey))
! 		&& (!NILP (Vmac_command_key_is_meta)
! 		    && NILP (Vmac_option_modifier)
! 		    || !(er.modifiers & optionKey)))
  	      if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
  		  != eventNotHandledErr)
  		break;
--- 9418,9431 ----
  		 || !(er.modifiers & cmdKey))
  		&& (!NILP (Vmac_pass_control_to_system)
  		    || !(er.modifiers & controlKey))
! 		&& (!NILP (Vmac_pass_option_to_system)
! 		    || (macOldModifierSetting ?
! 		    ((!NILP (Vmac_command_key_is_meta)
! 		      && NILP (Vmac_option_modifier)
! 		      || !(er.modifiers & optionKey)))
! 			:  !(er.modifiers & optionKey))
! 		    )
! 		)
  	      if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
  		  != eventNotHandledErr)
  		break;
***************
*** 9377,9386 ****
  		inev.kind = NON_ASCII_KEYSTROKE_EVENT;
  	      }
  	    else
! 	      {
! 		if (er.modifiers & (controlKey |
! 				    (NILP (Vmac_command_key_is_meta) ? optionKey
! 				     : cmdKey)))
  		  {
  		    /* This code comes from Keyboard Resource,
  		       Appendix C of IM - Text.  This is necessary
--- 9474,9492 ----
  		inev.kind = NON_ASCII_KEYSTROKE_EVENT;
  	      }
  	    else
! 	      { 
! 		if  (er.modifiers & (controlKey | 
! 				     (NILP (Vmac_pass_option_to_system) ? optionKey : 0) | 
!  				     (
!  				      (macOldModifierSetting ?  
!  				       (NILP (Vmac_command_key_is_meta) ? 
!  					optionKey : cmdKey
!  					) 
!  				       : cmdKey
!  				       )
!  				      )  
!  				     )
!  		     )
  		  {
  		    /* This code comes from Keyboard Resource,
  		       Appendix C of IM - Text.  This is necessary
***************
*** 9388,9394 ****
  		       translation when option or command is pressed.
  		       It also does not translate correctly
  		       control-shift chars like C-% so mask off shift
! 		       here also */
  		    int new_modifiers = er.modifiers & 0xe600;
  		    /* mask off option and command */
  		    int new_keycode = keycode | new_modifiers;
--- 9494,9507 ----
  		       translation when option or command is pressed.
  		       It also does not translate correctly
  		       control-shift chars like C-% so mask off shift
! 		       here also.
! 
! 		       For combinations with the option key (alt), this is only
! 		       done if either command or control are used additionally,
! 		       in which case this isn't handled 
! 		       or if mac-pass-option-to-system is nil  -- in order
! 		       to preserve key combinations translated by the OS, such as Alt-3.
! 		    */
  		    int new_modifiers = er.modifiers & 0xe600;
  		    /* mask off option and command */
  		    int new_keycode = keycode | new_modifiers;
***************
*** 9397,9415 ****
  		    inev.code = KeyTranslate (kchr_ptr, new_keycode,
  					      &some_state) & 0xff;
  		  }
- 		else if (!NILP (Vmac_option_modifier)
- 			 && (er.modifiers & optionKey))
- 		  {
- 		    /* When using the option key as an emacs modifier,
- 		       convert the pressed key code back to one
- 		       without the Mac option modifier applied. */
- 		    int new_modifiers = er.modifiers & ~optionKey;
- 		    int new_keycode = keycode | new_modifiers;
- 		    Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- 		    unsigned long some_state = 0;
- 		    inev.code = KeyTranslate (kchr_ptr, new_keycode,
- 					      &some_state) & 0xff;
- 		  }
  		else
  		  inev.code = er.message & charCodeMask;
  		inev.kind = ASCII_KEYSTROKE_EVENT;
--- 9510,9515 ----
***************
*** 10029,10034 ****
--- 10129,10138 ----
  #if TARGET_API_MAC_CARBON
    init_required_apple_events ();
  
+   Qctrl = intern ("ctrl");
+   Fput (Qctrl, Qmodifier_value, make_number (ctrl_modifier));
+   Qmeta = intern ("meta");
+   Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); 
  #if USE_CARBON_EVENTS
  #ifdef MAC_OSX
    init_service_handler ();
***************
*** 10079,10084 ****
--- 10183,10191 ----
  #ifdef MAC_OSX
    Fprovide (intern ("mac-carbon"), Qnil);
  #endif
+ /* Deprecated variables to configure modifier key assignment.
+ 	Retained for backward-compatibility. */
+ 	
  
    staticpro (&Qreverse);
    Qreverse = intern ("reverse");
***************
*** 10105,10123 ****
  
    DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta,
      doc: /* Non-nil means that the command key is used as the Emacs meta key.
! Otherwise the option key is used.  */);
    Vmac_command_key_is_meta = Qt;
  
    DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
      doc: /* Modifier to use for the Mac alt/option key.  The value can
  be alt, hyper, or super for the respective modifier.  If the value is
! nil then the key will act as the normal Mac option modifier.  */);
    Vmac_option_modifier = Qnil;
  
!   DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
!     doc: /* Non-nil means that the control and meta keys are reversed.  This is
! useful for non-standard keyboard layouts.  */);
!   Vmac_reverse_ctrl_meta = Qnil;
  
    DEFVAR_LISP ("mac-emulate-three-button-mouse",
  	       &Vmac_emulate_three_button_mouse,
--- 10212,10267 ----
  
    DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta,
      doc: /* Non-nil means that the command key is used as the Emacs meta key.
! Otherwise the option key is used. This variable is DEPRECATED. 
! It is only in effect if all of the variables mac-*-modifier are nil. */);
    Vmac_command_key_is_meta = Qt;
+   
+   DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
+     doc: /* Non-nil means that the control and meta keys are reversed.  This is
+ useful for non-standard keyboard layouts. This variable is DEPRECATED. 
+ Backwards-compatibility: It is only in effect if none of the variables 
+ mac-{command|control|option}-modifier is non-nil. */);
+   Vmac_reverse_ctrl_meta = Qnil;
+ 
+ 
+ /* Variables to configure modifier key assignment.  */
+ 	
+   DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier,
+     doc: /* Modifier to use for the Mac control key.  The value can
+ be alt, hyper, or super for the respective modifier.  If the value is
+ nil then the key will act as the normal Mac control modifier.  
+ Backwards-compatibility: If all values of 
+ mac-{command|control|option}-modifier are nil, the deprecated
+ default assignment determined by mac-command-key-is-meta and
+ mac-reverse-ctrl-meta is used. */);
+   Vmac_control_modifier = Qnil;
  
    DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
      doc: /* Modifier to use for the Mac alt/option key.  The value can
  be alt, hyper, or super for the respective modifier.  If the value is
! nil then the key will act as the normal Mac option modifier, and the option
! key can be used to compose characters depending on the chosen Mac keyboard
! setting. 
! Note that mac-pass-option-to-system takes precedence over this setting. If 
! mac-pass-option-to-system is non-nil, simple key combinations with Option
! will be handled by the system in order to produce characters, and only
! combinations in conjunction with Command or Control will let Emacs see
! the modifier that is assigned to the Option key. 
! Backwards-compatibility: If all values of 
! mac-{command|control|option}-modifier are nil, the deprecated default 
! assignment determined by mac-command-key-is-meta and
! mac-reverse-ctrl-meta is used.  */);
    Vmac_option_modifier = Qnil;
  
!   DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier,
!     doc: /* Modifier to use for the Mac command key.  The value can
! be alt, hyper, or super for the respective modifier. If the value is
! nil then the key will act as the Emacs 'hyper' modifier. 
! Backwards-compatibility: If all values of 
! mac-{command|control|option}-modifier are nil, the deprecated
! default assignment determined by mac-command-key-is-meta and
! mac-reverse-ctrl-meta is used.  */);
!   Vmac_command_modifier = Qnil;
  
    DEFVAR_LISP ("mac-emulate-three-button-mouse",
  	       &Vmac_emulate_three_button_mouse,
***************
*** 10146,10151 ****
--- 10290,10303 ----
     doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
  Toolbox for processing before Emacs sees it.  */);
    Vmac_pass_control_to_system = Qt;
+ 
+   DEFVAR_LISP ("mac-pass-option-to-system", &Vmac_pass_option_to_system,
+    doc: /* If  non-nil, the Mac \"Option\" key can be used to compose
+       characters as handled by the system and depending on the
+       keyboard layout chosen. Only if the Mac \"Command\" or \"Ctrl\" key
+       is depressed at the same time, Emacs evaluates the combination using
+       whatever modifier is set in mac-option-modifier.  */);
+   Vmac_pass_option_to_system = Qt;
  
  #endif
  
