(menu_face_changed_default): New variable.
[bpt/emacs.git] / src / xfaces.c
index 68371ef..e39dfe2 100644 (file)
@@ -473,10 +473,6 @@ static int clear_font_table_count;
 
 int face_change_count;
 
-/* Incremented for every change in the `menu' face.  */
-
-int menu_face_change_count;
-
 /* Non-zero means don't display bold text if a face's foreground
    and background colors are the inverse of the default colors of the
    display.   This is a kluge to suppress `bold black' foreground text
@@ -497,6 +493,10 @@ static int npixmaps_allocated;
 static int ngcs;
 #endif
 
+/* Non-zero means the definition of the `menu' face for new frames has
+   been changed.  */
+
+int menu_face_changed_default;
 
 \f
 /* Function prototypes.  */
@@ -597,7 +597,7 @@ static void sort_fonts P_ ((struct frame *, struct font_name *, int,
                               int (*cmpfn) P_ ((const void *, const void *))));
 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *));
 static void x_free_gc P_ ((struct frame *, GC));
-static void clear_font_table P_ ((struct frame *));
+static void clear_font_table P_ ((struct x_display_info *));
 
 #ifdef WINDOWSNT
 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int));
@@ -979,6 +979,14 @@ clear_face_cache (clear_fonts_p)
   if (clear_fonts_p
       || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT)
     {
+      struct x_display_info *dpyinfo;
+      
+      /* Fonts are common for frames on one display, i.e. on
+        one X screen.  */
+      for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+       if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS)
+         clear_font_table (dpyinfo);
+      
       /* From time to time see if we can unload some fonts.  This also
         frees all realized faces on all frames.  Fonts needed by
         faces will be loaded again when faces are realized again.  */
@@ -986,13 +994,10 @@ clear_face_cache (clear_fonts_p)
 
       FOR_EACH_FRAME (tail, frame)
        {
-         f = XFRAME (frame);
+         struct frame *f = XFRAME (frame);
          if (FRAME_WINDOW_P (f)
              && FRAME_X_DISPLAY_INFO (f)->n_fonts > CLEAR_FONT_TABLE_NFONTS)
-           {
-             free_all_realized_faces (frame);
-             clear_font_table (f);
-           }
+           free_all_realized_faces (frame);
        }
     }
   else
@@ -1029,26 +1034,37 @@ Optional THOROUGHLY non-nil means try to free unused fonts, too.")
 #ifdef HAVE_WINDOW_SYSTEM
 
 
-/* Remove those fonts from the font table of frame F exept for the
-   default ASCII font for the frame.  Called from clear_face_cache
+/* Remove fonts from the font table of DPYINFO except for the default
+   ASCII fonts of frames on that display.  Called from clear_face_cache
    from time to time.  */
 
 static void
-clear_font_table (f)
-     struct frame *f;
+clear_font_table (dpyinfo)
+     struct x_display_info *dpyinfo;
 {
-  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   int i;
 
-  xassert (FRAME_WINDOW_P (f));
-
-  /* Free those fonts that are not used by the frame F as the default.  */
+  /* Free those fonts that are not used by frames on DPYINFO.  */
   for (i = 0; i < dpyinfo->n_fonts; ++i)
     {
       struct font_info *font_info = dpyinfo->font_table + i;
+      Lisp_Object tail, frame;
+
+      /* Check if slot is already free.  */
+      if (font_info->name == NULL)
+       continue;
+
+      /* Don't free a default font of some frame on this display.  */
+      FOR_EACH_FRAME (tail, frame)
+       {
+         struct frame *f = XFRAME (frame);
+         if (FRAME_WINDOW_P (f)
+             && FRAME_X_DISPLAY_INFO (f) == dpyinfo
+             && font_info->font == FRAME_FONT (f))
+           break;
+       }
 
-      if (!font_info->name
-         || font_info->font == FRAME_FONT (f))
+      if (!NILP (tail))
        continue;
 
       /* Free names.  */
@@ -1631,9 +1647,12 @@ unload_color (f, pixel)
      unsigned long pixel;
 {
 #ifdef HAVE_X_WINDOWS
-  BLOCK_INPUT;
-  x_free_colors (f, &pixel, 1);
-  UNBLOCK_INPUT;
+  if (pixel != -1)
+    {
+      BLOCK_INPUT;
+      x_free_colors (f, &pixel, 1);
+      UNBLOCK_INPUT;
+    }
 #endif
 }
 
@@ -2148,7 +2167,7 @@ xlfd_point_size (f, font)
          start = end;
        }
 
-      pixel = matrix[3] / 10.0;
+      pixel = matrix[3];
     }
   else
     pixel = atoi (pixel_field);
@@ -2215,8 +2234,8 @@ split_font_name (f, font, numeric_p)
             indicated by tilde characters which we replace with
             `-' characters, here.  */
          if (*p == '['
-             && (i == XLFD_PIXEL_SIZE
-                 || i == XLFD_POINT_SIZE))
+             && (i - 1 == XLFD_PIXEL_SIZE
+                 || i - 1 == XLFD_POINT_SIZE))
            {
              char *start, *end;
              int j;
@@ -2227,7 +2246,7 @@ split_font_name (f, font, numeric_p)
 
              /* Check that the matrix contains 4 floating point
                 numbers.  */
-             for (j = 0, start = font->fields[i] + 1;
+             for (j = 0, start = font->fields[i - 1] + 1;
                   j < 4;
                   ++j, start = end)
                if (strtod (start, &end) == 0 && start == end)
@@ -3751,7 +3770,7 @@ DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
        Sinternal_set_lisp_face_attribute, 3, 4, 0,
   "Set attribute ATTR of FACE to VALUE.\n\
 FRAME being a frame means change the face on that frame.\n\
-FRAME nil means change change the face of the selected frame.\n\
+FRAME nil means change the face of the selected frame.\n\
 FRAME t means change the default for new frames.\n\
 FRAME 0 means change the face on all frames, and change the default\n\
   for new frames.")
@@ -4107,7 +4126,8 @@ FRAME 0 means change the face on all frames, and change the default\n\
 #ifdef HAVE_WINDOW_SYSTEM
          /* Changed font-related attributes of the `default' face are
             reflected in changed `font' frame parameters. */
-         if ((font_related_attr_p || font_attr_p)
+         if (FRAMEP (frame)
+             && (font_related_attr_p || font_attr_p)
              && lface_fully_specified_p (XVECTOR (lface)->contents))
            set_font_frame_param (frame, lface);
          else
@@ -4153,7 +4173,21 @@ FRAME 0 means change the face on all frames, and change the default\n\
        }
 #endif /* HAVE_WINDOW_SYSTEM */
       else if (EQ (face, Qmenu))
-       ++menu_face_change_count;
+       {
+         /* Indicate that we have to update the menu bar when
+            realizing faces on FRAME.  FRAME t change the
+            default for new frames.  We do this by setting
+            setting the flag in new face caches   */
+         if (FRAMEP (frame))
+           {
+             struct frame *f = XFRAME (frame);
+             if (FRAME_FACE_CACHE (f) == NULL)
+               FRAME_FACE_CACHE (f) = make_face_cache (f);
+             FRAME_FACE_CACHE (f)->menu_face_changed_p = 1;
+           }
+         else
+           menu_face_changed_default = 1;
+       }
 
       if (!NILP (param))
        if (EQ (frame, Qt))
@@ -4449,10 +4483,7 @@ x_update_menu_appearance (f)
        }
 
       if (changed_p && f->output_data.x->menubar_widget)
-       {
-         free_frame_menubar (f);
-         set_frame_menubar (f, 1, 1);
-       }
+       free_frame_menubar (f);
     }
 }
 
@@ -4954,6 +4985,7 @@ make_face_cache (f)
   c->size = 50;
   c->faces_by_id = (struct face **) xmalloc (c->size * sizeof *c->faces_by_id);
   c->f = f;
+  c->menu_face_changed_p = menu_face_changed_default;
   return c;
 }
 
@@ -6020,8 +6052,8 @@ realize_basic_faces (f)
   int success_p = 0;
   int count = BINDING_STACK_SIZE ();
 
-  /* Block input there so that we won't be surprised by an X expose
-     event, for instance without having the faces set up.  */
+  /* Block input here so that we won't be surprised by an X expose
+     event, for instance, without having the faces set up.  */
   BLOCK_INPUT;
   specbind (Qscalable_fonts_allowed, Qt);
 
@@ -6038,9 +6070,9 @@ realize_basic_faces (f)
       realize_named_face (f, Qmenu, MENU_FACE_ID);
 
       /* Reflect changes in the `menu' face in menu bars.  */
-      if (menu_face_change_count)
+      if (FRAME_FACE_CACHE (f)->menu_face_changed_p)
        {
-         --menu_face_change_count;
+         FRAME_FACE_CACHE (f)->menu_face_changed_p = 0;
 #ifdef USE_X_TOOLKIT
          x_update_menu_appearance (f);
 #endif