Add function prototype for resize_mini_window.
[bpt/emacs.git] / src / xfns.c
index 251b48d..dbb7dae 100644 (file)
@@ -50,7 +50,13 @@ Boston, MA 02111-1307, USA.  */
 #include "termhooks.h"
 
 #ifdef HAVE_X_WINDOWS
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
 extern void abort ();
+#endif
+#include <ctype.h>
 
 /* On some systems, the character-composition stuff is broken in X11R5.  */
 
@@ -834,7 +840,7 @@ x_set_frame_parameters (f, alist)
   /* Record in these vectors all the parms specified.  */
   Lisp_Object *parms;
   Lisp_Object *values;
-  int i;
+  int i, p;
   int left_no_change = 0, top_no_change = 0;
   int icon_left_no_change = 0, icon_top_no_change = 0;
 
@@ -882,6 +888,29 @@ x_set_frame_parameters (f, alist)
   else
     height = FRAME_HEIGHT (f);
 
+  /* Process foreground_color and background_color before anything else.
+     They are independent of other properties, but other properties (e.g.,
+     cursor_color) are dependent upon them.  */
+  for (p = 0; p < i; p++) 
+    {
+      Lisp_Object prop, val;
+
+      prop = parms[p];
+      val = values[p];
+      if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+       {
+         register Lisp_Object param_index, old_value;
+
+         param_index = Fget (prop, Qx_frame_parameter);
+         old_value = get_frame_param (f, prop);
+         store_frame_param (f, prop, val);
+         if (NATNUMP (param_index)
+             && (XFASTINT (param_index)
+                 < sizeof (x_frame_parms)/sizeof (x_frame_parms[0])))
+           (*x_frame_parms[XINT (param_index)].setter)(f, val, old_value);
+       }
+    }
+
   /* Now process them in reverse of specified order.  */
   for (i--; i >= 0; i--)
     {
@@ -902,6 +931,9 @@ x_set_frame_parameters (f, alist)
        icon_top = val;
       else if (EQ (prop, Qicon_left))
        icon_left = val;
+      else if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+       /* Processed above.  */
+       continue;
       else
        {
          register Lisp_Object param_index, old_value;
@@ -1314,10 +1346,7 @@ x_set_foreground_color (f, arg, oldval)
   unsigned long pixel
     = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
 
-  if (f->output_data.x->foreground_pixel != f->output_data.x->mouse_pixel
-      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_pixel
-      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_foreground_pixel)
-    unload_color (f, f->output_data.x->foreground_pixel);
+  unload_color (f, f->output_data.x->foreground_pixel);
   f->output_data.x->foreground_pixel = pixel;
 
   if (FRAME_X_WINDOW (f) != 0)
@@ -1345,10 +1374,7 @@ x_set_background_color (f, arg, oldval)
   unsigned long pixel
     = x_decode_color (f, arg, WHITE_PIX_DEFAULT (f));
 
-  if (f->output_data.x->background_pixel != f->output_data.x->mouse_pixel
-      && f->output_data.x->background_pixel != f->output_data.x->cursor_pixel
-      && f->output_data.x->background_pixel != f->output_data.x->cursor_foreground_pixel)
-    unload_color (f, f->output_data.x->background_pixel);
+  unload_color (f, f->output_data.x->background_pixel);
   f->output_data.x->background_pixel = pixel;
 
   if (FRAME_X_WINDOW (f) != 0)
@@ -1388,23 +1414,15 @@ x_set_mouse_color (f, arg, oldval)
   Cursor cursor, nontext_cursor, mode_cursor, cross_cursor;
   Cursor busy_cursor;
   int count;
-  int mask_color;
-  unsigned long pixel = f->output_data.x->mouse_pixel;
-  
-  if (!EQ (Qnil, arg))
-    pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+  unsigned long pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f));
+  unsigned long mask_color = f->output_data.x->background_pixel;
 
-  mask_color = f->output_data.x->background_pixel;
-                               /* No invisible pointers.  */
+  /* Don't let pointers be invisible.  */
   if (mask_color == pixel
       && mask_color == f->output_data.x->background_pixel)
     pixel = f->output_data.x->foreground_pixel;
 
-  if (f->output_data.x->background_pixel != f->output_data.x->mouse_pixel
-      && f->output_data.x->foreground_pixel != f->output_data.x->mouse_pixel
-      && f->output_data.x->cursor_pixel != f->output_data.x->mouse_pixel
-      && f->output_data.x->cursor_foreground_pixel != f->output_data.x->mouse_pixel)
-    unload_color (f, f->output_data.x->mouse_pixel);
+  unload_color (f, f->output_data.x->mouse_pixel);
   f->output_data.x->mouse_pixel = pixel;
 
   BLOCK_INPUT;
@@ -1544,18 +1562,10 @@ x_set_cursor_color (f, arg, oldval)
        fore_pixel = f->output_data.x->background_pixel;
     }
 
-  if (f->output_data.x->background_pixel != f->output_data.x->cursor_foreground_pixel
-      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_foreground_pixel
-      && f->output_data.x->mouse_pixel != f->output_data.x->cursor_foreground_pixel
-      && f->output_data.x->cursor_pixel != f->output_data.x->cursor_foreground_pixel)
-    unload_color (f, f->output_data.x->cursor_foreground_pixel);
+  unload_color (f, f->output_data.x->cursor_foreground_pixel);
   f->output_data.x->cursor_foreground_pixel = fore_pixel;
 
-  if (f->output_data.x->background_pixel != f->output_data.x->cursor_pixel
-      && f->output_data.x->foreground_pixel != f->output_data.x->cursor_pixel
-      && f->output_data.x->mouse_pixel != f->output_data.x->cursor_pixel
-      && f->output_data.x->cursor_foreground_pixel != f->output_data.x->cursor_pixel)
-    unload_color (f, f->output_data.x->cursor_pixel);
+  unload_color (f, f->output_data.x->cursor_pixel);
   f->output_data.x->cursor_pixel = pixel;
 
   if (FRAME_X_WINDOW (f) != 0)
@@ -1775,6 +1785,8 @@ x_set_font (f, arg, oldval)
   else
     abort ();
 
+  do_pending_window_change (0);
+
   /* Don't call `face-set-after-frame-default' when faces haven't been
      initialized yet.  This is the case when called from
      Fx_create_frame.  In that case, the X widget or window doesn't
@@ -1825,14 +1837,9 @@ x_set_internal_border_width (f, arg, oldval)
 
   if (FRAME_X_WINDOW (f) != 0)
     {
-      BLOCK_INPUT;
       x_set_window_size (f, 0, f->width, f->height);
-#if 0
-      x_set_resize_hint (f);
-#endif
-      XFlush (FRAME_X_DISPLAY (f));
-      UNBLOCK_INPUT;
       SET_FRAME_GARBAGED (f);
+      do_pending_window_change (0);
     }
 }
 
@@ -2250,6 +2257,7 @@ x_set_vertical_scroll_bars (f, arg, oldval)
         call x_set_window_size.  */
       if (FRAME_X_WINDOW (f))
        x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
+      do_pending_window_change (0);
     }
 }
 
@@ -2262,8 +2270,8 @@ x_set_scroll_bar_width (f, arg, oldval)
 
   if (NILP (arg))
     {
-#ifdef USE_X_TOOLKIT
-      /* A too wide or narrow toolkit scroll bar doesn't look good.  */
+#ifdef USE_TOOLKIT_SCROLL_BARS
+      /* A minimum width of 14 doesn't look good for toolkit scroll bars.  */
       int width = 16 + 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM;
       FRAME_SCROLL_BAR_COLS (f) = (width + wid - 1) / wid;
       FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = width;
@@ -2279,6 +2287,7 @@ x_set_scroll_bar_width (f, arg, oldval)
 
       if (FRAME_X_WINDOW (f))
         x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
+      do_pending_window_change (0);
     }
   else if (INTEGERP (arg) && XINT (arg) > 0
           && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
@@ -2292,7 +2301,7 @@ x_set_scroll_bar_width (f, arg, oldval)
        x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
     }
 
-  change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0);
+  change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0, 0);
   XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
   XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
 }
@@ -2843,7 +2852,7 @@ x_figure_window_size (f, parms)
        ? 0
        : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.x->font)));
   f->output_data.x->flags_areas_extra
-    = 2 * FRAME_FLAGS_AREA_WIDTH (f);
+    = FRAME_FLAGS_AREA_WIDTH (f);
   f->output_data.x->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
   f->output_data.x->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
 
@@ -3231,12 +3240,9 @@ x_window (f, window_prompting, minibuffer_only)
 
   UNBLOCK_INPUT;
 
-  if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
-    initialize_frame_menubar (f);
-  lw_set_main_areas (pane_widget, f->output_data.x->menubar_widget, frame_widget);
-
-  if (FRAME_X_WINDOW (f) == 0)
-    error ("Unable to create window");
+  /* This is a no-op, except under Motif.  Make sure main areas are
+     set to something reasonable, in case we get an error later.  */
+  lw_set_main_areas (pane_widget, 0, frame_widget);
 }
 
 #else /* not USE_X_TOOLKIT */
@@ -3744,6 +3750,9 @@ This function is an internal primitive--use `make-frame' instead.")
 
   f->output_data.x->size_hint_flags = window_prompting;
 
+  tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
+  f->no_split = minibuffer_only || EQ (tem, Qt);
+
   /* Create the X widget or window.  Add the toolbar height to the
      initial frame height so that the user gets a text display area of
      the size he specified with -g or via .Xdefaults.  Later changes
@@ -3751,16 +3760,20 @@ This function is an internal primitive--use `make-frame' instead.")
      so that users can create tall Emacs frames without having to
      guess how tall the toolbar will get.  */
   f->height += FRAME_TOOLBAR_LINES (f);
+
 #ifdef USE_X_TOOLKIT
   x_window (f, window_prompting, minibuffer_only);
 #else
   x_window (f);
 #endif
+  
   x_icon (f, parms);
   x_make_gc (f);
 
-  call1 (Qface_set_after_frame_default, frame);
-  
+  /* Now consider the frame official.  */
+  FRAME_X_DISPLAY_INFO (f)->reference_count++;
+  Vframe_list = Fcons (frame, Vframe_list);
+
   /* We need to do this after creating the X window, so that the
      icon-creation functions can say whose icon they're describing.  */
   x_default_parameter (f, parms, Qicon_type, Qnil,
@@ -3780,32 +3793,37 @@ This function is an internal primitive--use `make-frame' instead.")
   height = f->height;
   f->height = 0;
   SET_FRAME_WIDTH (f, 0);
-  change_frame_size (f, height, width, 1, 0);
+  change_frame_size (f, height, width, 1, 0, 0);
 
-  /* Tell the server what size and position, etc, we want,
-     and how badly we want them.  */
+  /* Set up faces after all frame parameters are known.  */
+  call1 (Qface_set_after_frame_default, frame);
+  
+#ifdef USE_X_TOOLKIT
+  /* Create the menu bar.  */
+  if (!minibuffer_only && FRAME_EXTERNAL_MENU_BAR (f))
+    {
+      /* If this signals an error, we haven't set size hints for the
+        frame and we didn't make it visible.  */
+      initialize_frame_menubar (f);
+
+      /* This is a no-op, except under Motif where it arranges the
+        main window for the widgets on it.  */
+      lw_set_main_areas (f->output_data.x->column_widget,
+                        f->output_data.x->menubar_widget,
+                        f->output_data.x->edit_widget);
+    }
+#endif /* USE_X_TOOLKIT */
+
+  /* Tell the server what size and position, etc, we want, and how
+     badly we want them.  This should be done after we have the menu
+     bar so that its size can be taken into account.  */
   BLOCK_INPUT;
   x_wm_set_size_hint (f, window_prompting, 0);
   UNBLOCK_INPUT;
 
-  tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
-  f->no_split = minibuffer_only || EQ (tem, Qt);
-
-  UNGCPRO;
-
-  /* It is now ok to make the frame official
-     even if we get an error below.
-     And the frame needs to be on Vframe_list
-     or making it visible won't work.  */
-  Vframe_list = Fcons (frame, Vframe_list);
-
-  /* Now that the frame is official, it counts as a reference to
-     its display.  */
-  FRAME_X_DISPLAY_INFO (f)->reference_count++;
-
-  /* Make the window appear on the frame and enable display,
-     unless the caller says not to.  However, with explicit parent,
-     Emacs cannot control visibility, so don't try.  */
+  /* Make the window appear on the frame and enable display, unless
+     the caller says not to.  However, with explicit parent, Emacs
+     cannot control visibility, so don't try.  */
   if (! f->output_data.x->explicit_parent)
     {
       Lisp_Object visibility;
@@ -3824,6 +3842,7 @@ This function is an internal primitive--use `make-frame' instead.")
        ;
     }
 
+  UNGCPRO;
   return unbind_to (count, frame);
 }
 
@@ -6971,8 +6990,13 @@ xpm_load (f, img)
   attrs.visual = FRAME_X_DISPLAY_INFO (f)->visual;
   attrs.valuemask |= XpmVisual;
   attrs.valuemask |= XpmReturnAllocPixels;
+#ifdef XpmAllocCloseColors
   attrs.alloc_close_colors = 1;
   attrs.valuemask |= XpmAllocCloseColors;
+#else
+  attrs.closeness = 600;
+  attrs.valuemask |= XpmCloseness;
+#endif
 
   /* If image specification contains symbolic color definitions, add
      these to `attrs'.  */
@@ -8239,10 +8263,21 @@ png_load (f, img)
 
 #if HAVE_JPEG
 
+/* Work around a warning about HAVE_STDLIB_H being redefined in
+   jconfig.h.  */
+#ifdef HAVE_STDLIB_H
+#define HAVE_STDLIB_H_1
+#undef HAVE_STDLIB_H
+#endif /* HAVE_STLIB_H */
+
 #include <jpeglib.h>
 #include <jerror.h>
 #include <setjmp.h>
 
+#ifdef HAVE_STLIB_H_1
+#define HAVE_STDLIB_H 1
+#endif
+
 static int jpeg_image_p P_ ((Lisp_Object object));
 static int jpeg_load P_ ((struct frame *f, struct image *img));
 
@@ -8489,7 +8524,7 @@ jpeg_load (f, img)
 
 #if HAVE_TIFF
 
-#include <tiff34/tiffio.h>
+#include <tiffio.h>
 
 static int tiff_image_p P_ ((Lisp_Object object));
 static int tiff_load P_ ((struct frame *f, struct image *img));
@@ -9604,11 +9639,6 @@ x_create_tip_frame (dpyinfo, parms)
 
   x_make_gc (f);
 
-  /* We need to do this after creating the X window, so that the
-     icon-creation functions can say whose icon they're describing.  */
-  x_default_parameter (f, parms, Qicon_type, Qnil,
-                      "bitmapIcon", "BitmapIcon", RES_TYPE_SYMBOL);
-
   x_default_parameter (f, parms, Qauto_raise, Qnil,
                       "autoRaise", "AutoRaiseLower", RES_TYPE_BOOLEAN);
   x_default_parameter (f, parms, Qauto_lower, Qnil,
@@ -9623,7 +9653,7 @@ x_create_tip_frame (dpyinfo, parms)
   height = f->height;
   f->height = 0;
   SET_FRAME_WIDTH (f, 0);
-  change_frame_size (f, height, width, 1, 0);
+  change_frame_size (f, height, width, 1, 0, 0);
 
   f->no_split = 1;
 
@@ -9732,9 +9762,8 @@ TIMEOUT nil means use the default timeout of 5 seconds.")
       if (!row->enabled_p || !row->displays_text_p)
        break;
 
-      /* Let the row go over the full width of the frame, not
-        including internal borders.  */
-      row->full_width_p = row->internal_border_p = 1;
+      /* Let the row go over the full width of the frame.  */
+      row->full_width_p = 1;
 
       /* There's a glyph at the end of rows that is use to place
         the cursor there.  Don't include the width of this glyph.  */