Handle system default font and changing font parameters.
[bpt/emacs.git] / src / keyboard.c
index a6bfb08..f15b797 100644 (file)
@@ -489,6 +489,8 @@ Lisp_Object Qsave_session;
 #ifdef HAVE_DBUS
 Lisp_Object Qdbus_event;
 #endif
+Lisp_Object Qconfig_changed_event;
+
 /* Lisp_Object Qmouse_movement; - also an event header */
 
 /* Properties of event headers.  */
@@ -4283,6 +4285,11 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
          kbd_fetch_ptr = event + 1;
        }
 #endif
+      else if (event->kind == CONFIG_CHANGED_EVENT)
+       {
+         obj = make_lispy_event (event);
+         kbd_fetch_ptr = event + 1;
+       }
       else
        {
          /* If this event is on a different frame, return a switch-frame this
@@ -4509,19 +4516,16 @@ extern Lisp_Object Qapply;
    disregard elements that are not proper timers.  Do not make a circular
    timer list for the time being.
 
-   Returns the number of seconds to wait until the next timer fires.  If a
-   timer is triggering now, return zero seconds.
-   If no timer is active, return -1 seconds.
+   Returns the time to wait until the next timer fires.  If a
+   timer is triggering now, return zero.
+   If no timer is active, return -1.
 
    If a timer is ripe, we run it, with quitting turned off.
+   In that case we return 0 to indicate that a new timer_check_2 call
+   should be done.  */
 
-   DO_IT_NOW is now ignored.  It used to mean that we should
-   run the timer directly instead of queueing a timer-event.
-   Now we always run timers directly.  */
-
-EMACS_TIME
-timer_check (do_it_now)
-     int do_it_now;
+static EMACS_TIME
+timer_check_2 ()
 {
   EMACS_TIME nexttime;
   EMACS_TIME now, idleness_now;
@@ -4685,7 +4689,12 @@ timer_check (do_it_now)
 
              /* Since we have handled the event,
                 we don't need to tell the caller to wake up and do it.  */
+              /* But the caller must still wait for the next timer, so
+                 return 0 to indicate that.  */
            }
+
+          EMACS_SET_SECS (nexttime, 0);
+          EMACS_SET_USECS (nexttime, 0);
        }
       else
        /* When we encounter a timer that is still waiting,
@@ -4702,6 +4711,35 @@ timer_check (do_it_now)
   return nexttime;
 }
 
+
+/* Check whether a timer has fired.  To prevent larger problems we simply
+   disregard elements that are not proper timers.  Do not make a circular
+   timer list for the time being.
+
+   Returns the time to wait until the next timer fires.
+   If no timer is active, return -1.
+
+   As long as any timer is ripe, we run it.
+
+   DO_IT_NOW is now ignored.  It used to mean that we should
+   run the timer directly instead of queueing a timer-event.
+   Now we always run timers directly.  */
+
+EMACS_TIME
+timer_check (do_it_now)
+     int do_it_now;
+{
+  EMACS_TIME nexttime;
+
+  do 
+    {
+      nexttime = timer_check_2 ();
+    }
+  while (EMACS_SECS (nexttime) == 0 && EMACS_USECS (nexttime) == 0);
+
+  return nexttime;
+}
+
 DEFUN ("current-idle-time", Fcurrent_idle_time, Scurrent_idle_time, 0, 0, 0,
        doc: /* Return the current length of Emacs idleness, or nil.
 The value when Emacs is idle is a list of three integers.  The first has
@@ -4739,7 +4777,7 @@ static Lisp_Object drag_n_drop_syms;
 /* This is a list of keysym codes for special "accent" characters.
    It parallels lispy_accent_keys.  */
 
-static int lispy_accent_codes[] =
+static const int lispy_accent_codes[] =
 {
 #ifdef XK_dead_circumflex
   XK_dead_circumflex,
@@ -6165,6 +6203,10 @@ make_lispy_event (event)
       }
 #endif /* HAVE_DBUS */
 
+    case CONFIG_CHANGED_EVENT:
+       return Fcons (Qconfig_changed_event,
+                      Fcons (event->arg,
+                             Fcons (event->frame_or_window, Qnil)));
 #ifdef HAVE_GPM
     case GPM_CLICK_EVENT:
       {
@@ -6453,7 +6495,7 @@ apply_modifiers_uncached (modifiers, base, base_len, base_len_byte)
 }
 
 
-static char *modifier_names[] =
+static const char *modifier_names[] =
 {
   "up", "down", "drag", "click", "double", "triple", 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -7797,7 +7839,7 @@ menu_bar_item (key, item, dummy1, dummy2)
      parse_menu_item, so that if it turns out it wasn't a menu item,
      it still correctly hides any further menu item.  */
   GCPRO1 (key);
-  i = parse_menu_item (item, 0, 1);
+  i = parse_menu_item (item, 1);
   UNGCPRO;
   if (!i)
     return;
@@ -7865,8 +7907,6 @@ menu_item_eval_property (sexpr)
 /* This function parses a menu item and leaves the result in the
    vector item_properties.
    ITEM is a key binding, a possible menu item.
-   If NOTREAL is nonzero, only check for equivalent key bindings, don't
-   evaluate dynamic expressions in the menu item.
    INMENUBAR is > 0 when this is considered for an entry in a menu bar
    top level.
    INMENUBAR is < 0 when this is considered for an entry in a keyboard menu.
@@ -7874,9 +7914,9 @@ menu_item_eval_property (sexpr)
    otherwise.  */
 
 int
-parse_menu_item (item, notreal, inmenubar)
+parse_menu_item (item, inmenubar)
      Lisp_Object item;
-     int notreal, inmenubar;
+     int inmenubar;
 {
   Lisp_Object def, tem, item_string, start;
   Lisp_Object filter;
@@ -7966,7 +8006,7 @@ parse_menu_item (item, notreal, inmenubar)
                  else
                    ASET (item_properties, ITEM_PROPERTY_ENABLE, XCAR (item));
                }
-             else if (EQ (tem, QCvisible) && !notreal)
+             else if (EQ (tem, QCvisible))
                {
                  /* If got a visible property and that evaluates to nil
                     then ignore this item.  */
@@ -8015,7 +8055,7 @@ parse_menu_item (item, notreal, inmenubar)
   /* If item string is not a string, evaluate it to get string.
      If we don't get a string, skip this item.  */
   item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
-  if (!(STRINGP (item_string) || notreal))
+  if (!(STRINGP (item_string)))
     {
       item_string = menu_item_eval_property (item_string);
       if (!STRINGP (item_string))
@@ -8037,10 +8077,7 @@ parse_menu_item (item, notreal, inmenubar)
   tem = AREF (item_properties, ITEM_PROPERTY_ENABLE);
   if (!EQ (tem, Qt))
     {
-      if (notreal)
-       tem = Qt;
-      else
-       tem = menu_item_eval_property (tem);
+      tem = menu_item_eval_property (tem);
       if (inmenubar && NILP (tem))
        return 0;               /* Ignore disabled items in menu bar.  */
       ASET (item_properties, ITEM_PROPERTY_ENABLE, tem);
@@ -8068,65 +8105,64 @@ parse_menu_item (item, notreal, inmenubar)
   if (inmenubar > 0)
     return 1;
 
-  /* This is a command.  See if there is an equivalent key binding. */
-  tem = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
-  /* The previous code preferred :key-sequence to :keys, so we
-     preserve this behavior.  */
-  if (STRINGP (tem) && !CONSP (keyhint))
-    tem = Fsubstitute_command_keys (tem);
-  else
-    {
-      Lisp_Object prefix = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
-      Lisp_Object keys = Qnil;
+  { /* This is a command.  See if there is an equivalent key binding. */
+    Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
 
-      if (CONSP (prefix))
-       {
-         def = XCAR (prefix);
-         prefix = XCDR (prefix);
-       }
-      else
-       def = AREF (item_properties, ITEM_PROPERTY_DEF);
+    /* The previous code preferred :key-sequence to :keys, so we
+       preserve this behavior.  */
+    if (STRINGP (keyeq) && !CONSP (keyhint))
+      keyeq = Fsubstitute_command_keys (keyeq);
+    else
+      {
+       Lisp_Object prefix = keyeq;
+       Lisp_Object keys = Qnil;
 
-      if (CONSP (keyhint) && !NILP (XCAR (keyhint)))
-       {
-         keys = XCAR (keyhint);
-         tem = Fkey_binding (keys, Qnil, Qnil, Qnil);
-
-         /* We have a suggested key.  Is it bound to the command?  */
-         if (NILP (tem)
-             || (!EQ (tem, def)
-                 /* If the command is an alias for another
-                    (such as lmenu.el set it up), check if the
-                    original command matches the cached command.  */
-                 && !(SYMBOLP (def) && EQ (tem, XSYMBOL (def)->function))))
-           keys = Qnil;
-       }
-      
-      if (NILP (keys))
-       keys = Fwhere_is_internal (def, Qnil, Qt, Qnil, Qnil);
-         
-      if (!NILP (keys))
-       {
-         tem = Fkey_description (keys, Qnil);
-         if (CONSP (prefix))
-           {
-             if (STRINGP (XCAR (prefix)))
-               tem = concat2 (XCAR (prefix), tem);
-             if (STRINGP (XCDR (prefix)))
-               tem = concat2 (tem, XCDR (prefix));
-           }
-         tem = concat2 (build_string ("  "), tem);
-         /* tem = concat3 (build_string ("  ("), tem, build_string (")")); */
-       }
-    }
-  
+       if (CONSP (prefix))
+         {
+           def = XCAR (prefix);
+           prefix = XCDR (prefix);
+         }
+       else
+         def = AREF (item_properties, ITEM_PROPERTY_DEF);
 
-  /* If we only want to precompute equivalent key bindings, stop here. */
-  if (notreal)
-    return 1;
+       if (CONSP (keyhint) && !NILP (XCAR (keyhint)))
+         {
+           keys = XCAR (keyhint);
+           tem = Fkey_binding (keys, Qnil, Qnil, Qnil);
+
+           /* We have a suggested key.  Is it bound to the command?  */
+           if (NILP (tem)
+               || (!EQ (tem, def)
+                   /* If the command is an alias for another
+                      (such as lmenu.el set it up), check if the
+                      original command matches the cached command.  */
+                   && !(SYMBOLP (def) && EQ (tem, XSYMBOL (def)->function))))
+             keys = Qnil;
+         }
 
-  /* If we have an equivalent key binding, use that.  */
-  ASET (item_properties, ITEM_PROPERTY_KEYEQ, tem);
+       if (NILP (keys))
+         keys = Fwhere_is_internal (def, Qnil, Qt, Qnil, Qnil);
+
+       if (!NILP (keys))
+         {
+           tem = Fkey_description (keys, Qnil);
+           if (CONSP (prefix))
+             {
+               if (STRINGP (XCAR (prefix)))
+                 tem = concat2 (XCAR (prefix), tem);
+               if (STRINGP (XCDR (prefix)))
+                 tem = concat2 (tem, XCDR (prefix));
+             }
+           keyeq = concat2 (build_string ("  "), tem);
+           /* keyeq = concat3(build_string("  ("),tem,build_string(")")); */
+         }
+       else
+         keyeq = Qnil;
+      }
+
+    /* If we have an equivalent key binding, use that.  */
+    ASET (item_properties, ITEM_PROPERTY_KEYEQ, keyeq);
+  }
 
   /* Include this when menu help is implemented.
   tem = XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP];
@@ -8759,7 +8795,7 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps)
                }
 
              /* Ignore the element if it has no prompt string.  */
-             if (INTEGERP (event) && parse_menu_item (elt, 0, -1))
+             if (INTEGERP (event) && parse_menu_item (elt, -1))
                {
                  /* 1 if the char to type matches the string.  */
                  int char_matches;
@@ -11704,7 +11740,7 @@ syms_of_keyboard ()
   pending_funcalls = Qnil;
   staticpro (&pending_funcalls);
 
-  Vlispy_mouse_stem = build_string ("mouse");
+  Vlispy_mouse_stem = make_pure_c_string ("mouse");
   staticpro (&Vlispy_mouse_stem);
 
   /* Tool-bars.  */
@@ -11780,6 +11816,9 @@ syms_of_keyboard ()
   staticpro (&Qdbus_event);
 #endif
 
+  Qconfig_changed_event = intern_c_string ("config-changed-event");
+  staticpro (&Qconfig_changed_event);
+
   Qmenu_enable = intern_c_string ("menu-enable");
   staticpro (&Qmenu_enable);
   QCenable = intern_c_string (":enable");
@@ -12522,6 +12561,9 @@ keys_of_keyboard ()
   initial_define_lispy_key (Vspecial_event_map, "dbus-event",
                            "dbus-handle-event");
 #endif
+
+  initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
+                           "ignore");
 }
 
 /* Mark the pointers in the kboard objects.