Patch 7.0.138 (extra)
Problem:    Mac: modifiers don't work with function keys.
Solution:   Use GetEventParameter() to obtain modifiers. (Nicolas Weber)
Files:      src/gui_mac.c


*** ../vim-7.0.137/src/gui_mac.c        Tue Aug 22 21:39:18 2006
--- src/gui_mac.c       Sun Oct 15 14:53:38 2006
***************
*** 2014,2020 ****
        void *data)
  {
      /* Multibyte-friendly key event handler */
!     OSStatus  e = -1;
      UInt32    actualSize;
      UniChar   *text;
      char_u    result[INLINE_KEY_BUFFER_SIZE];
--- 2014,2020 ----
        void *data)
  {
      /* Multibyte-friendly key event handler */
!     OSStatus  err = -1;
      UInt32    actualSize;
      UniChar   *text;
      char_u    result[INLINE_KEY_BUFFER_SIZE];
***************
*** 2022,2195 ****
      UInt32    key_sym;
      char      charcode;
      int               key_char;
!     UInt32    modifiers;
      size_t    encLen;
      char_u    *to = NULL;
      Boolean   isSpecial = FALSE;
      int               i;
  
      /* Mask the mouse (as per user setting) */
      if (p_mh)
        ObscureCursor();
  
!     do
!     {
!       /* Don't use the keys when the dialog wants them. */
!       if (dialog_busy)
!           break;
  
!       if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText,
!                   typeUnicodeText, NULL, 0, &actualSize, NULL))
!           break;
  
!       text = (UniChar *)alloc(actualSize);
  
!       if (text)
!       {
!           do
!           {
!               if (noErr != GetEventParameter(theEvent,
!                           kEventParamTextInputSendText,
!                           typeUnicodeText, NULL, actualSize, NULL, text))
!                   break;
!               EventRef keyEvent;
!               if (noErr != GetEventParameter(theEvent,
!                           kEventParamTextInputSendKeyboardEvent,
!                           typeEventRef, NULL, sizeof(EventRef), NULL, 
&keyEvent))
!                   break;
!               if (noErr != GetEventParameter(keyEvent,
!                           kEventParamKeyModifiers,
!                           typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers))
!                   break;
!               if (noErr != GetEventParameter(keyEvent,
!                           kEventParamKeyCode,
!                           typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym))
!                   break;
!               if (noErr != GetEventParameter(keyEvent,
!                           kEventParamKeyMacCharCodes,
!                           typeChar, NULL, sizeof(char), NULL, &charcode))
!                   break;
  
!               key_char = charcode;
  
!               if (modifiers & controlKey)
!               {
!                   if ((modifiers & ~(controlKey|shiftKey)) == 0
!                           && (key_char == '2' || key_char == '6'))
!                   {
!                       /* CTRL-^ and CTRL-@ don't work in the normal way. */
!                       if (key_char == '2')
!                           key_char = Ctrl_AT;
!                       else
!                           key_char = Ctrl_HAT;
  
!                       text[0] = (UniChar)key_char;
!                       modifiers = 0;
!                   }
!               }
  
!               if (modifiers & cmdKey)
! #ifndef USE_CMD_KEY
!                   break;  /* Let system handle Cmd+... */
! #else
!               {
!                   /* Intercept CMD-. */
!                   if (key_char == '.')
!                       got_int = TRUE;
! 
!                   /* Convert the modifiers */
!                   modifiers = EventModifiers2VimModifiers(modifiers);
! 
!                   /* Following code to simplify and consolidate modifiers
!                    * taken liberally from gui_w48.c */
! 
!                   key_char = simplify_key(key_char, (int *)&modifiers);
! 
!                   /* remove SHIFT for keys that are already shifted, e.g.,
!                    * '(' and '*' */
!                   if (key_char < 0x100 &&
!                           !isalpha(key_char) && isprint(key_char))
!                       modifiers &= ~MOD_MASK_SHIFT;
! 
!                   /* Interpret META, include SHIFT, etc. */
!                   key_char = extract_modifiers(key_char, (int *)&modifiers);
!                   if (key_char == CSI)
!                       key_char = K_CSI;
  
!                   if (modifiers)
!                   {
!                       result[len++] = CSI;
!                       result[len++] = KS_MODIFIER;
!                       result[len++] = modifiers;
!                   }
  
!                   isSpecial = TRUE;
!               }
! #endif
!               else
!               {
!                   /* Find the special key (eg., for cursor keys) */
!                   if (!(actualSize > sizeof(UniChar)) &&
!                           ((text[0] < 0x20) || (text[0] == 0x7f)))
!                   {
!                       for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i)
!                           if (special_keys[i].key_sym == key_sym)
!                           {
!                               key_char = TO_SPECIAL(special_keys[i].vim_code0,
!                                       special_keys[i].vim_code1);
!                               key_char = simplify_key(key_char,
!                                       (int *)&modifiers);
!                               isSpecial = TRUE;
!                               break;
!                           }
!                   }
!               }
  
!               if (isSpecial && IS_SPECIAL(key_char))
!               {
!                   result[len++] = CSI;
!                   result[len++] = K_SECOND(key_char);
!                   result[len++] = K_THIRD(key_char);
!               }
!               else
!               {
!                   encLen = actualSize;
!                   to = mac_utf16_to_enc(text, actualSize, &encLen);
!               }
  
!               if (to)
!               {
!                   /* This is basically add_to_input_buf_csi() */
!                   for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); 
++i)
!                   {
!                       result[len++] = to[i];
!                       if (to[i] == CSI)
!                       {
!                           result[len++] = KS_EXTRA;
!                           result[len++] = (int)KE_CSI;
!                       }
!                   }
!                   vim_free(to);
!               }
  
!               add_to_input_buf(result, len);
!               e = noErr;
!           }
!           while (0);
  
!           vim_free(text);
!           if (e == noErr)
!           {
!               /* Fake event to wake up WNE (required to get
!                * key repeat working */
!               PostEvent(keyUp, 0);
!               return noErr;
!           }
!       }
      }
-     while (0);
  
!     return CallNextEventHandler(nextHandler, theEvent);
  }
  #else
      void
--- 2022,2174 ----
      UInt32    key_sym;
      char      charcode;
      int               key_char;
!     UInt32    modifiers, vimModifiers;
      size_t    encLen;
      char_u    *to = NULL;
      Boolean   isSpecial = FALSE;
      int               i;
+     EventRef keyEvent;
  
      /* Mask the mouse (as per user setting) */
      if (p_mh)
        ObscureCursor();
  
!     /* Don't use the keys when the dialog wants them. */
!     if (dialog_busy)
!         return eventNotHandledErr;
! 
!     if (noErr != GetEventParameter(theEvent, kEventParamTextInputSendText,
!                 typeUnicodeText, NULL, 0, &actualSize, NULL))
!         return eventNotHandledErr;
! 
!     text = (UniChar *)alloc(actualSize);
!     if (!text)
!         return eventNotHandledErr;
! 
!     err = GetEventParameter(theEvent, kEventParamTextInputSendText,
!             typeUnicodeText, NULL, actualSize, NULL, text);
!     require_noerr(err, done);
! 
!     err = GetEventParameter(theEvent, kEventParamTextInputSendKeyboardEvent,
!             typeEventRef, NULL, sizeof(EventRef), NULL, &keyEvent);
!     require_noerr(err, done);
! 
!     err = GetEventParameter(keyEvent, kEventParamKeyModifiers,
!             typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
!     require_noerr(err, done);
! 
!     err = GetEventParameter(keyEvent, kEventParamKeyCode,
!             typeUInt32, NULL, sizeof(UInt32), NULL, &key_sym);
!     require_noerr(err, done);
! 
!     err = GetEventParameter(keyEvent, kEventParamKeyMacCharCodes,
!             typeChar, NULL, sizeof(char), NULL, &charcode);
!     require_noerr(err, done);
  
! #ifndef USE_CMD_KEY
!     if (modifiers & cmdKey)
!         goto done;  /* Let system handle Cmd+... */
! #endif
  
!     key_char = charcode;
!     vimModifiers = EventModifiers2VimModifiers(modifiers);
  
!     /* Find the special key (eg., for cursor keys) */
!     if (actualSize <= sizeof(UniChar) &&
!             ((text[0] < 0x20) || (text[0] == 0x7f)))
!     {
!         for (i = 0; special_keys[i].key_sym != (KeySym)0; ++i)
!             if (special_keys[i].key_sym == key_sym)
!             {
!                 key_char = TO_SPECIAL(special_keys[i].vim_code0,
!                         special_keys[i].vim_code1);
!                 key_char = simplify_key(key_char,
!                         (int *)&vimModifiers);
!                 isSpecial = TRUE;
!                 break;
!             }
!     }
  
!     /* Intercept CMD-. and CTRL-c */
!     if (((modifiers & controlKey) && key_char == 'c') ||
!             ((modifiers & cmdKey) && key_char == '.'))
!         got_int = TRUE;
  
!     if (!isSpecial)
!     {
!         /* remove SHIFT for keys that are already shifted, e.g.,
!          * '(' and '*' */
!         if (key_char < 0x100 && !isalpha(key_char) && isprint(key_char))
!             vimModifiers &= ~MOD_MASK_SHIFT;
  
!         /* remove CTRL from keys that already have it */
!         if (key_char < 0x20)
!             vimModifiers &= ~MOD_MASK_CTRL;
  
!         /* don't process unicode characters here */
!         if (!IS_SPECIAL(key_char))
!         {
!             /* Following code to simplify and consolidate vimModifiers
!              * taken liberally from gui_w48.c */
!             key_char = simplify_key(key_char, (int *)&vimModifiers);
  
!             /* Interpret META, include SHIFT, etc. */
!             key_char = extract_modifiers(key_char, (int *)&vimModifiers);
!             if (key_char == CSI)
!                 key_char = K_CSI;
  
!             if (IS_SPECIAL(key_char))
!                 isSpecial = TRUE;
!         }
!     }
  
!     if (vimModifiers)
!     {
!         result[len++] = CSI;
!         result[len++] = KS_MODIFIER;
!         result[len++] = vimModifiers;
!     }
  
!     if (isSpecial && IS_SPECIAL(key_char))
!     {
!         result[len++] = CSI;
!         result[len++] = K_SECOND(key_char);
!         result[len++] = K_THIRD(key_char);
!     }
!     else
!     {
!         encLen = actualSize;
!         to = mac_utf16_to_enc(text, actualSize, &encLen);
!         if (to)
!         {
!             /* This is basically add_to_input_buf_csi() */
!             for (i = 0; i < encLen && len < (INLINE_KEY_BUFFER_SIZE-1); ++i)
!             {
!                 result[len++] = to[i];
!                 if (to[i] == CSI)
!                 {
!                     result[len++] = KS_EXTRA;
!                     result[len++] = (int)KE_CSI;
!                 }
!             }
!             vim_free(to);
!         }
!     }
  
!     add_to_input_buf(result, len);
!     err = noErr;
  
! done:
!     vim_free(text);
!     if (err == noErr)
!     {
!         /* Fake event to wake up WNE (required to get
!          * key repeat working */
!         PostEvent(keyUp, 0);
!         return noErr;
      }
  
!     return eventNotHandledErr;
  }
  #else
      void
***************
*** 5748,5754 ****
      /* TODO: Get the text selection from Vim */
  
      /* Call to Handle Popup */
!     status = ContextualMenuSelect(CntxMenu, where, false, kCMHelpItemNoHelp, 
HelpName, NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
  
      if (status == noErr)
      {
--- 5727,5734 ----
      /* TODO: Get the text selection from Vim */
  
      /* Call to Handle Popup */
!     status = ContextualMenuSelect(CntxMenu, where, false, kCMHelpItemNoHelp,
!                      HelpName, NULL, &CntxType, &CntxMenuID, &CntxMenuItem);
  
      if (status == noErr)
      {
***************
*** 5756,5762 ****
        {
            /* Handle the menu CntxMenuID, CntxMenuItem */
            /* The submenu can be handle directly by gui_mac_handle_menu */
!           /* But what about the current menu, is the menu changed by 
ContextualMenuSelect */
            gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
        }
        else if (CntxMenuID == kCMShowHelpSelected)
--- 5736,5743 ----
        {
            /* Handle the menu CntxMenuID, CntxMenuItem */
            /* The submenu can be handle directly by gui_mac_handle_menu */
!           /* But what about the current menu, is the menu changed by
!            * ContextualMenuSelect */
            gui_mac_handle_menu((CntxMenuID << 16) + CntxMenuItem);
        }
        else if (CntxMenuID == kCMShowHelpSelected)
*** ../vim-7.0.137/src/version.c        Tue Oct 17 11:50:45 2006
--- src/version.c       Tue Oct 17 12:51:21 2006
***************
*** 668,669 ****
--- 668,671 ----
  {   /* Add new patch number below this line */
+ /**/
+     138,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
52. You ask a plumber how much it would cost to replace the chair in front of
    your computer with a toilet.

 /// Bram Moolenaar -- [EMAIL PROTECTED] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

Reply via email to