diff src/keyboard.c @ 91204:53108e6cea98

Merge from emacs--devo--0 Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-294
author Miles Bader <miles@gnu.org>
date Thu, 06 Dec 2007 09:51:45 +0000
parents 880960b70474 2dd672d9fe75
children 2fcaae6177a5
line wrap: on
line diff
--- a/src/keyboard.c	Thu Dec 06 07:36:30 2007 +0000
+++ b/src/keyboard.c	Thu Dec 06 09:51:45 2007 +0000
@@ -514,7 +514,9 @@
 #ifdef MAC_OS
 Lisp_Object Qmac_apple_event;
 #endif
-
+#ifdef HAVE_DBUS
+Lisp_Object Qdbus_event;
+#endif
 /* Lisp_Object Qmouse_movement; - also an event header */
 
 /* Properties of event headers.  */
@@ -1570,7 +1572,7 @@
 #ifdef MULTI_KBOARD
   int was_locked = single_kboard;
 #endif
-#endif  
+#endif
   int already_adjusted = 0;
 
   current_kboard->Vprefix_arg = Qnil;
@@ -2566,7 +2568,7 @@
    USED_MOUSE_MENU is null, we don't dereference it.
 
    Value is -2 when we find input on another keyboard.  A second call
-   to read_char will read it. 
+   to read_char will read it.
 
    If END_TIME is non-null, it is a pointer to an EMACS_TIME
    specifying the maximum time to wait until.  If no input arrives by
@@ -3181,7 +3183,7 @@
       int count = SPECPDL_INDEX ();
       record_single_kboard_state ();
 #endif
-      
+
       last_input_char = c;
       Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
 
@@ -4097,7 +4099,7 @@
 	 events.  */
       if (CONSP (Vunread_command_events))
 	break;
-      
+
       if (kbd_fetch_ptr != kbd_store_ptr)
 	break;
 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
@@ -4309,6 +4311,13 @@
 	  internal_last_event_frame = frame;
 	  kbd_fetch_ptr = event + 1;
 	}
+#ifdef HAVE_DBUS
+      else if (event->kind == DBUS_EVENT)
+	{
+	  obj = make_lispy_event (event);
+	  kbd_fetch_ptr = event + 1;
+	}
+#endif
       else
 	{
 	  /* If this event is on a different frame, return a switch-frame this
@@ -6187,6 +6196,13 @@
       }
 #endif
 
+#ifdef HAVE_DBUS
+    case DBUS_EVENT:
+      {
+	return Fcons (Qdbus_event, event->arg);
+      }
+#endif /* HAVE_DBUS */
+
 #ifdef HAVE_GPM
     case GPM_CLICK_EVENT:
       {
@@ -6505,12 +6521,21 @@
    SYMBOL's Qevent_symbol_element_mask property, and maintains the
    Qevent_symbol_elements property.  */
 
+#define KEY_TO_CHAR(k) (XINT (k) & ((1 << CHARACTERBITS) - 1))
+
 Lisp_Object
 parse_modifiers (symbol)
      Lisp_Object symbol;
 {
   Lisp_Object elements;
 
+  if (INTEGERP (symbol))
+    return (Fcons (make_number (KEY_TO_CHAR (symbol)),
+		   Fcons (make_number (XINT (symbol) & CHAR_MODIFIER_MASK),
+			  Qnil)));
+  else if (!SYMBOLP (symbol))
+    return Qnil;
+
   elements = Fget (symbol, Qevent_symbol_element_mask);
   if (CONSP (elements))
     return elements;
@@ -6545,6 +6570,20 @@
     }
 }
 
+DEFUN ("internal-event-symbol-parse-modifiers", Fevent_symbol_parse_modifiers,
+       Sevent_symbol_parse_modifiers, 1, 1, 0,
+       doc: /* Parse the event symbol.  For internal use.  */)
+     (symbol)
+     Lisp_Object symbol;
+{
+  /* Fill the cache if needed.  */
+  parse_modifiers (symbol);
+  /* Ignore the result (which is stored on Qevent_symbol_element_mask)
+     and use the Lispier representation stored on Qevent_symbol_elements
+     instead.  */
+  return Fget (symbol, Qevent_symbol_elements);
+}
+
 /* Apply the modifiers MODIFIERS to the symbol BASE.
    BASE must be unmodified.
 
@@ -6564,6 +6603,9 @@
   /* Mask out upper bits.  We don't know where this value's been.  */
   modifiers &= INTMASK;
 
+  if (INTEGERP (base))
+    return make_number (XINT (base) | modifiers);
+
   /* The click modifier never figures into cache indices.  */
   cache = Fget (base, Qmodifier_cache);
   XSETFASTINT (index, (modifiers & ~click_modifier));
@@ -6975,6 +7017,11 @@
 gobble_input (expected)
      int expected;
 {
+#ifdef HAVE_DBUS
+  /* Check whether a D-Bus message has arrived.  */
+  xd_read_queued_messages ();
+#endif /* HAVE_DBUS */
+
 #ifndef VMS
 #ifdef SIGIO
   if (interrupt_input)
@@ -7094,7 +7141,7 @@
               nread += nr;
               expected = 0;
             }
-          
+
           if (nr == -1)          /* Not OK to read input now. */
             {
               err = 1;
@@ -7102,7 +7149,7 @@
           else if (nr == -2)          /* Non-transient error. */
             {
               /* The terminal device terminated; it should be closed. */
-              
+
               /* Kill Emacs if this was our last terminal. */
               if (!terminal_list->next_terminal)
                 /* Formerly simply reported no input, but that
@@ -7114,7 +7161,7 @@
                    group?  Perhaps on systems with FIONREAD Emacs is
                    alone in its group.  */
                 kill (getpid (), SIGHUP);
-              
+
               /* XXX Is calling delete_terminal safe here?  It calls Fdelete_frame. */
               if (t->delete_terminal_hook)
                 (*t->delete_terminal_hook) (t);
@@ -7287,14 +7334,14 @@
         buf.modifiers = meta_modifier;
       if (tty->meta_key != 2)
         cbuf[i] &= ~0x80;
-      
+
       buf.code = cbuf[i];
       /* Set the frame corresponding to the active tty.  Note that the
          value of selected_frame is not reliable here, redisplay tends
          to temporarily change it. */
       buf.frame_or_window = tty->top_frame;
       buf.arg = Qnil;
-      
+
       kbd_buffer_store_event (&buf);
       /* Don't look at input that follows a C-g too closely.
          This reduces lossage due to autorepeat on C-g.  */
@@ -9210,7 +9257,7 @@
   last_nonmenu_event = Qnil;
 
   delayed_switch_frame = Qnil;
-  
+
   if (INTERACTIVE)
     {
       if (!NILP (prompt))
@@ -10102,32 +10149,44 @@
 	 and is a shifted function key,
 	 use the corresponding unshifted function key instead.  */
       if (first_binding >= nmaps
-	  && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t
-	  && SYMBOLP (key))
-	{
-	  Lisp_Object breakdown;
-	  int modifiers;
-
-	  breakdown = parse_modifiers (key);
-	  modifiers = XINT (XCAR (XCDR (breakdown)));
-	  if (modifiers & shift_modifier)
+	  && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t)
+	{
+	  Lisp_Object breakdown = parse_modifiers (key);
+	  int modifiers
+	    = CONSP (breakdown) ? (XINT (XCAR (XCDR (breakdown)))) : 0;
+
+	  if (modifiers & shift_modifier
+	      /* Treat uppercase keys as shifted.  */
+	      || (INTEGERP (key)
+		  & (KEY_TO_CHAR (key)
+		     < XCHAR_TABLE (current_buffer->downcase_table)->size)
+		  && UPPERCASEP (KEY_TO_CHAR (key))))
 	    {
-	      Lisp_Object new_key;
+	      Lisp_Object new_key
+		= (modifiers & shift_modifier
+		   ? apply_modifiers (modifiers & ~shift_modifier,
+				      XCAR (breakdown))
+		   : make_number (DOWNCASE (KEY_TO_CHAR (key)) | modifiers));
 
 	      original_uppercase = key;
 	      original_uppercase_position = t - 1;
 
-	      modifiers &= ~shift_modifier;
-	      new_key = apply_modifiers (modifiers,
-					 XCAR (breakdown));
-
+	      /* We have to do this unconditionally, regardless of whether
+		 the lower-case char is defined in the keymaps, because they
+		 might get translated through function-key-map.  */
 	      keybuf[t - 1] = new_key;
 	      mock_input = max (t, mock_input);
+	      /* Reset fkey (and consequently keytran) to apply
+		 function-key-map on the result, so that S-backspace is
+		 correctly mapped to DEL (via backspace).  OTOH,
+		 input-decode-map doesn't need to go through it again.  */
+	      fkey.start = fkey.end = 0;
+	      keytran.start = keytran.end = 0;
+
 	      goto replay_sequence;
 	    }
 	}
     }
-
   if (!dummyflag)
     read_key_sequence_cmd = (first_binding < nmaps
 			     ? defs[first_binding]
@@ -11244,7 +11303,7 @@
   new_interrupt_input = 1;
 #endif
 
-  if (new_interrupt_input != interrupt_input) 
+  if (new_interrupt_input != interrupt_input)
     {
 #ifdef POLL_FOR_INPUT
       stop_polling ();
@@ -11324,7 +11383,7 @@
   struct terminal *t = get_terminal (terminal, 1);
   struct tty_display_info *tty;
   int new_meta;
-  
+
   if (t == NULL || t->type != output_termcap)
     return Qnil;
   tty = t->display_info.tty;
@@ -11336,7 +11395,7 @@
   else
     new_meta = 2;
 
-  if (tty->meta_key != new_meta) 
+  if (tty->meta_key != new_meta)
     {
 #ifndef DOS_NT
       /* this causes startup screen to be restored and messes with the mouse */
@@ -11344,7 +11403,7 @@
 #endif
 
       tty->meta_key = new_meta;
-  
+
 #ifndef DOS_NT
       init_sys_modes (tty);
 #endif
@@ -11376,7 +11435,7 @@
   /* this causes startup screen to be restored and messes with the mouse */
   reset_sys_modes (tty);
 #endif
-  
+
   /* Don't let this value be out of range.  */
   quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377);
 
@@ -11386,7 +11445,7 @@
 
   return Qnil;
 }
-       
+
 DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
        doc: /* Set mode of reading keyboard input.
 First arg INTERRUPT non-nil means use input interrupts;
@@ -11785,6 +11844,11 @@
   staticpro (&Qmac_apple_event);
 #endif
 
+#ifdef HAVE_DBUS
+  Qdbus_event = intern ("dbus-event");
+  staticpro (&Qdbus_event);
+#endif
+
   Qmenu_enable = intern ("menu-enable");
   staticpro (&Qmenu_enable);
   Qmenu_alias = intern ("menu-alias");
@@ -11945,6 +12009,7 @@
   staticpro (&help_form_saved_window_configs);
 
   defsubr (&Scurrent_idle_time);
+  defsubr (&Sevent_symbol_parse_modifiers);
   defsubr (&Sevent_convert_list);
   defsubr (&Sread_key_sequence);
   defsubr (&Sread_key_sequence_vector);
@@ -12346,7 +12411,7 @@
 `local-function-key-map' binding and this variable, then the local
 definition will take precendence.  */);
   Vfunction_key_map = Fmake_sparse_keymap (Qnil);
-                    
+
   DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
                doc: /* Keymap of key translations that can override keymaps.
 This keymap works like `function-key-map', but comes after that,
@@ -12468,7 +12533,7 @@
   /* Vwindow_system is left at t for now.  */
   initial_kboard->next_kboard = all_kboards;
   all_kboards = initial_kboard;
-#endif  
+#endif
 }
 
 void
@@ -12513,6 +12578,13 @@
    * 			    "handle-select-window"); */
   initial_define_lispy_key (Vspecial_event_map, "save-session",
 			    "handle-save-session");
+
+#ifdef HAVE_DBUS
+  /* Define a special event which is raised for dbus callback
+     functions.  */
+  initial_define_lispy_key (Vspecial_event_map, "dbus-event",
+			    "dbus-handle-event");
+#endif
 }
 
 /* Mark the pointers in the kboard objects.