Merge from trunk.
[bpt/emacs.git] / src / frame.c
index 19ce78d..1b29bd8 100644 (file)
@@ -160,7 +160,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
   if (FRAME_MINIBUF_ONLY_P (f))
     return;
 
-  if (INTEGERP (value))
+  if (TYPE_RANGED_INTEGERP (int, value))
     nlines = XINT (value);
   else
     nlines = 0;
@@ -497,7 +497,7 @@ make_minibuffer_frame (void)
 \f
 /* Construct a frame that refers to a terminal.  */
 
-static int tty_frame_count;
+static printmax_t tty_frame_count;
 
 struct frame *
 make_initial_frame (void)
@@ -551,7 +551,7 @@ make_terminal_frame (struct terminal *terminal)
 {
   register struct frame *f;
   Lisp_Object frame;
-  char name[20];
+  char name[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
 
   if (!terminal->name)
     error ("Terminal is not live, can't create new frames on it");
@@ -562,7 +562,7 @@ make_terminal_frame (struct terminal *terminal)
   Vframe_list = Fcons (frame, Vframe_list);
 
   tty_frame_count++;
-  sprintf (name, "F%d", tty_frame_count);
+  sprintf (name, "F%"pMd, tty_frame_count);
   f->name = build_string (name);
 
   f->visible = 1;              /* FRAME_SET_VISIBLE wd set frame_garbaged. */
@@ -1155,17 +1155,6 @@ other_visible_frames (FRAME_PTR f)
   return 1;
 }
 
-DEFUN ("other-visible-frames-p", Fother_visible_frames_p, Sother_visible_frames_p, 0, 1, 0,
-       doc: /* Return t if there are other visible frames beside FRAME.
-FRAME defaults to the selected frame.  */)
-  (Lisp_Object frame)
-{
-  if (NILP (frame))
-    frame = selected_frame;
-  CHECK_LIVE_FRAME (frame);
-  return other_visible_frames (XFRAME (frame)) ? Qt : Qnil;
-}
-
 /* Delete FRAME.  When FORCE equals Qnoelisp, delete FRAME
   unconditionally.  x_connection_closed and delete_terminal use
   this.  Any other value of FORCE implements the semantics
@@ -1616,8 +1605,8 @@ before calling this function on it, like this.
   (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
 {
   CHECK_LIVE_FRAME (frame);
-  CHECK_NUMBER (x);
-  CHECK_NUMBER (y);
+  CHECK_TYPE_RANGED_INTEGER (int, x);
+  CHECK_TYPE_RANGED_INTEGER (int, y);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1657,8 +1646,8 @@ before calling this function on it, like this.
   (Lisp_Object frame, Lisp_Object x, Lisp_Object y)
 {
   CHECK_LIVE_FRAME (frame);
-  CHECK_NUMBER (x);
-  CHECK_NUMBER (y);
+  CHECK_TYPE_RANGED_INTEGER (int, x);
+  CHECK_TYPE_RANGED_INTEGER (int, y);
 
   /* I think this should be done with a hook.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -2050,7 +2039,7 @@ store_in_alist (Lisp_Object *alistptr, Lisp_Object prop, Lisp_Object val)
 }
 
 static int
-frame_name_fnn_p (char *str, EMACS_INT len)
+frame_name_fnn_p (char *str, ptrdiff_t len)
 {
   if (len > 1 && str[0] == 'F' && '0' <= str[1] && str[1] <= '9')
     {
@@ -2074,7 +2063,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
   /* If NAME is nil, set the name to F<num>.  */
   if (NILP (name))
     {
-      char namebuf[20];
+      char namebuf[sizeof "F" + INT_STRLEN_BOUND (printmax_t)];
 
       /* Check for no change needed in this very common case
         before we do any consing.  */
@@ -2083,7 +2072,7 @@ set_term_frame_name (struct frame *f, Lisp_Object name)
        return;
 
       tty_frame_count++;
-      sprintf (namebuf, "F%d", tty_frame_count);
+      sprintf (namebuf, "F%"pMd, tty_frame_count);
       name = build_string (namebuf);
     }
   else
@@ -2334,7 +2323,7 @@ If FRAME is nil, describe the currently selected frame.  */)
              if (STRINGP (value) && !FRAME_WINDOW_P (f))
                {
                  const char *color_name;
-                 EMACS_INT csz;
+                 ptrdiff_t csz;
 
                  if (EQ (parameter, Qbackground_color))
                    {
@@ -2410,12 +2399,13 @@ use is not recommended.  Explicitly check for a frame-parameter instead.  */)
 #endif
 
     {
-      int length = XINT (Flength (alist));
-      int i;
-      Lisp_Object *parms
-       = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
-      Lisp_Object *values
-       = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+      EMACS_INT length = XFASTINT (Flength (alist));
+      ptrdiff_t i;
+      Lisp_Object *parms;
+      Lisp_Object *values;
+      USE_SAFE_ALLOCA;
+      SAFE_ALLOCA_LISP (parms, 2 * length);
+      values = parms + length;
 
       /* Extract parm names and values into those vectors.  */
 
@@ -2441,6 +2431,8 @@ use is not recommended.  Explicitly check for a frame-parameter instead.  */)
              || EQ (prop, Qbackground_color))
            update_face_from_frame_parameter (f, prop, val);
        }
+
+      SAFE_FREE ();
     }
   return Qnil;
 }
@@ -2579,7 +2571,7 @@ but that the idea of the actual height of the frame should not be changed.  */)
 {
   register struct frame *f;
 
-  CHECK_NUMBER (lines);
+  CHECK_TYPE_RANGED_INTEGER (int, lines);
   if (NILP (frame))
     frame = selected_frame;
   CHECK_LIVE_FRAME (frame);
@@ -2606,7 +2598,7 @@ but that the idea of the actual width of the frame should not be changed.  */)
   (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
 {
   register struct frame *f;
-  CHECK_NUMBER (cols);
+  CHECK_TYPE_RANGED_INTEGER (int, cols);
   if (NILP (frame))
     frame = selected_frame;
   CHECK_LIVE_FRAME (frame);
@@ -2633,8 +2625,8 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
   register struct frame *f;
 
   CHECK_LIVE_FRAME (frame);
-  CHECK_NUMBER (cols);
-  CHECK_NUMBER (rows);
+  CHECK_TYPE_RANGED_INTEGER (int, cols);
+  CHECK_TYPE_RANGED_INTEGER (int, rows);
   f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
@@ -2665,8 +2657,8 @@ the rightmost or bottommost possible position (that stays within the screen).  *
   register struct frame *f;
 
   CHECK_LIVE_FRAME (frame);
-  CHECK_NUMBER (xoffset);
-  CHECK_NUMBER (yoffset);
+  CHECK_TYPE_RANGED_INTEGER (int, xoffset);
+  CHECK_TYPE_RANGED_INTEGER (int, yoffset);
   f = XFRAME (frame);
 
   /* I think this should be done with a hook.  */
@@ -2885,12 +2877,12 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
       prop = parms[i];
       val = values[i];
 
-      if (EQ (prop, Qwidth) && NATNUMP (val))
+      if (EQ (prop, Qwidth) && RANGED_INTEGERP (0, val, INT_MAX))
         {
           size_changed = 1;
           width = XFASTINT (val);
         }
-      else if (EQ (prop, Qheight) && NATNUMP (val))
+      else if (EQ (prop, Qheight) && RANGED_INTEGERP (0, val, INT_MAX))
         {
           size_changed = 1;
           height = XFASTINT (val);
@@ -2926,7 +2918,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
     }
 
   /* Don't die if just one of these was set.  */
-  if (EQ (left, Qunbound))
+  if (! TYPE_RANGED_INTEGERP (int, left))
     {
       left_no_change = 1;
       if (f->left_pos < 0)
@@ -2934,7 +2926,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
       else
        XSETINT (left, f->left_pos);
     }
-  if (EQ (top, Qunbound))
+  if (! TYPE_RANGED_INTEGERP (int, top))
     {
       top_no_change = 1;
       if (f->top_pos < 0)
@@ -2944,14 +2936,14 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
     }
 
   /* If one of the icon positions was not set, preserve or default it.  */
-  if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
+  if (! TYPE_RANGED_INTEGERP (int, icon_left))
     {
       icon_left_no_change = 1;
       icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
       if (NILP (icon_left))
        XSETINT (icon_left, 0);
     }
-  if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
+  if (! TYPE_RANGED_INTEGERP (int, icon_top))
     {
       icon_top_no_change = 1;
       icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
@@ -2992,7 +2984,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
        f->size_hint_flags &= ~ (XNegative | YNegative);
        if (EQ (left, Qminus))
          f->size_hint_flags |= XNegative;
-       else if (INTEGERP (left))
+       else if (TYPE_RANGED_INTEGERP (int, left))
          {
            leftpos = XINT (left);
            if (leftpos < 0)
@@ -3000,21 +2992,21 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
          }
        else if (CONSP (left) && EQ (XCAR (left), Qminus)
                 && CONSP (XCDR (left))
-                && INTEGERP (XCAR (XCDR (left))))
+                && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (left)), INT_MAX))
          {
            leftpos = - XINT (XCAR (XCDR (left)));
            f->size_hint_flags |= XNegative;
          }
        else if (CONSP (left) && EQ (XCAR (left), Qplus)
                 && CONSP (XCDR (left))
-                && INTEGERP (XCAR (XCDR (left))))
+                && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (left))))
          {
            leftpos = XINT (XCAR (XCDR (left)));
          }
 
        if (EQ (top, Qminus))
          f->size_hint_flags |= YNegative;
-       else if (INTEGERP (top))
+       else if (TYPE_RANGED_INTEGERP (int, top))
          {
            toppos = XINT (top);
            if (toppos < 0)
@@ -3022,14 +3014,14 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
          }
        else if (CONSP (top) && EQ (XCAR (top), Qminus)
                 && CONSP (XCDR (top))
-                && INTEGERP (XCAR (XCDR (top))))
+                && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (top)), INT_MAX))
          {
            toppos = - XINT (XCAR (XCDR (top)));
            f->size_hint_flags |= YNegative;
          }
        else if (CONSP (top) && EQ (XCAR (top), Qplus)
                 && CONSP (XCDR (top))
-                && INTEGERP (XCAR (XCDR (top))))
+                && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (top))))
          {
            toppos = XINT (XCAR (XCDR (top)));
          }
@@ -3065,6 +3057,7 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
 {
   char buf[16];
   Lisp_Object tem;
+  unsigned long w;
 
   /* Represent negative positions (off the top or left screen edge)
      in a way that Fmodify_frame_parameters will understand correctly.  */
@@ -3097,7 +3090,12 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
                      for non-toolkit scroll bar.
                      ruler-mode.el depends on this.  */
                   : Qnil));
-  sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
+  /* FRAME_X_WINDOW is not guaranteed to return an integer.  E.g., on
+     MS-Windows it returns a value whose type is HANDLE, which is
+     actually a pointer.  Explicit casting avoids compiler
+     warnings.  */
+  w = (unsigned long) FRAME_X_WINDOW (f);
+  sprintf (buf, "%lu", w);
   store_in_alist (alistptr, Qwindow_id,
                  build_string (buf));
 #ifdef HAVE_X_WINDOWS
@@ -3105,7 +3103,10 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
   /* Tooltip frame may not have this widget.  */
   if (FRAME_X_OUTPUT (f)->widget)
 #endif
-    sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
+    {
+      w = (unsigned long) FRAME_OUTER_WINDOW (f);
+      sprintf (buf, "%lu", w);
+    }
   store_in_alist (alistptr, Qouter_window_id,
                  build_string (buf));
 #endif
@@ -3157,7 +3158,7 @@ x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
 {
   if (NILP (new_value))
     f->extra_line_spacing = 0;
-  else if (NATNUMP (new_value))
+  else if (RANGED_INTEGERP (0, new_value, INT_MAX))
     f->extra_line_spacing = XFASTINT (new_value);
   else
     signal_error ("Invalid line-spacing", new_value);
@@ -3366,7 +3367,7 @@ x_set_fringe_width (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
 void
 x_set_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
-  CHECK_NUMBER (arg);
+  CHECK_TYPE_RANGED_INTEGER (int, arg);
 
   if (XINT (arg) == f->border_width)
     return;
@@ -3382,7 +3383,7 @@ x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldva
 {
   int old = FRAME_INTERNAL_BORDER_WIDTH (f);
 
-  CHECK_NUMBER (arg);
+  CHECK_TYPE_RANGED_INTEGER (int, arg);
   FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
   if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
     FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
@@ -3481,7 +3482,7 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
         x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
       do_pending_window_change (0);
     }
-  else if (INTEGERP (arg) && XINT (arg) > 0
+  else if (RANGED_INTEGERP (1, arg, INT_MAX)
           && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
     {
       if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
@@ -3520,7 +3521,7 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 {
   double alpha = 1.0;
   double newval[2];
-  int i, ialpha;
+  int i;
   Lisp_Object item;
 
   for (i = 0; i < 2; i++)
@@ -3544,7 +3545,7 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
        }
       else if (INTEGERP (item))
        {
-         ialpha = XINT (item);
+         EMACS_INT ialpha = XINT (item);
          if (ialpha < 0 || 100 < ialpha)
            args_out_of_range (make_number (0), make_number (100));
          else
@@ -3576,13 +3577,13 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
 void
 validate_x_resource_name (void)
 {
-  int len = 0;
+  ptrdiff_t len = 0;
   /* Number of valid characters in the resource name.  */
-  int good_count = 0;
+  ptrdiff_t good_count = 0;
   /* Number of invalid characters in the resource name.  */
-  int bad_count = 0;
+  ptrdiff_t bad_count = 0;
   Lisp_Object new;
-  int i;
+  ptrdiff_t i;
 
   if (!STRINGP (Vx_resource_class))
     Vx_resource_class = build_string (EMACS_CLASS);
@@ -3615,8 +3616,9 @@ validate_x_resource_name (void)
   if (bad_count == 0)
     return;
 
-  /* If name is entirely invalid, or nearly so, use `emacs'.  */
-  if (good_count < 2)
+  /* If name is entirely invalid, or nearly so, or is so implausibly
+     large that alloca might not work, use `emacs'.  */
+  if (good_count < 2 || MAX_ALLOCA - sizeof ".customization" < len)
     {
       Vx_resource_name = build_string ("emacs");
       return;
@@ -3745,20 +3747,24 @@ x_get_resource_string (const char *attribute, const char *class)
 {
   char *name_key;
   char *class_key;
+  char *result;
   struct frame *sf = SELECTED_FRAME ();
+  ptrdiff_t invocation_namelen = SBYTES (Vinvocation_name);
+  USE_SAFE_ALLOCA;
 
   /* Allocate space for the components, the dots which separate them,
      and the final '\0'.  */
-  name_key = (char *) alloca (SBYTES (Vinvocation_name)
-                             + strlen (attribute) + 2);
+  SAFE_ALLOCA (name_key, char *, invocation_namelen + strlen (attribute) + 2);
   class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
                               + strlen (class) + 2);
 
-  sprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
+  esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
   sprintf (class_key, "%s.%s", EMACS_CLASS, class);
 
-  return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
-                               name_key, class_key);
+  result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
+                                 name_key, class_key);
+  SAFE_FREE ();
+  return result;
 }
 #endif
 
@@ -4031,11 +4037,15 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
       if (!EQ (tem0, Qunbound))
        {
          CHECK_NUMBER (tem0);
+         if (! (0 <= XINT (tem0) && XINT (tem0) <= INT_MAX))
+           xsignal1 (Qargs_out_of_range, tem0);
          FRAME_LINES (f) = XINT (tem0);
        }
       if (!EQ (tem1, Qunbound))
        {
          CHECK_NUMBER (tem1);
+         if (! (0 <= XINT (tem1) && XINT (tem1) <= INT_MAX))
+           xsignal1 (Qargs_out_of_range, tem1);
          SET_FRAME_COLS (f, XINT (tem1));
        }
       if (!NILP (tem2) && !EQ (tem2, Qunbound))
@@ -4066,12 +4076,10 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
                ? tool_bar_button_relief
                : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
 
-      if (INTEGERP (Vtool_bar_button_margin)
-         && XINT (Vtool_bar_button_margin) > 0)
+      if (RANGED_INTEGERP (1, Vtool_bar_button_margin, INT_MAX))
        margin = XFASTINT (Vtool_bar_button_margin);
       else if (CONSP (Vtool_bar_button_margin)
-              && INTEGERP (XCDR (Vtool_bar_button_margin))
-              && XINT (XCDR (Vtool_bar_button_margin)) > 0)
+              && RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin), INT_MAX))
        margin = XFASTINT (XCDR (Vtool_bar_button_margin));
       else
        margin = 0;
@@ -4097,14 +4105,14 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
        }
       else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
               && CONSP (XCDR (tem0))
-              && INTEGERP (XCAR (XCDR (tem0))))
+              && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem0)), INT_MAX))
        {
          f->top_pos = - XINT (XCAR (XCDR (tem0)));
          window_prompting |= YNegative;
        }
       else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
               && CONSP (XCDR (tem0))
-              && INTEGERP (XCAR (XCDR (tem0))))
+              && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem0))))
        {
          f->top_pos = XINT (XCAR (XCDR (tem0)));
        }
@@ -4112,7 +4120,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
        f->top_pos = 0;
       else
        {
-         CHECK_NUMBER (tem0);
+         CHECK_TYPE_RANGED_INTEGER (int, tem0);
          f->top_pos = XINT (tem0);
          if (f->top_pos < 0)
            window_prompting |= YNegative;
@@ -4125,14 +4133,14 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
        }
       else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
               && CONSP (XCDR (tem1))
-              && INTEGERP (XCAR (XCDR (tem1))))
+              && RANGED_INTEGERP (-INT_MAX, XCAR (XCDR (tem1)), INT_MAX))
        {
          f->left_pos = - XINT (XCAR (XCDR (tem1)));
          window_prompting |= XNegative;
        }
       else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
               && CONSP (XCDR (tem1))
-              && INTEGERP (XCAR (XCDR (tem1))))
+              && TYPE_RANGED_INTEGERP (int, XCAR (XCDR (tem1))))
        {
          f->left_pos = XINT (XCAR (XCDR (tem1)));
        }
@@ -4140,7 +4148,7 @@ x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
        f->left_pos = 0;
       else
        {
-         CHECK_NUMBER (tem1);
+         CHECK_TYPE_RANGED_INTEGER (int, tem1);
          f->left_pos = XINT (tem1);
          if (f->left_pos < 0)
            window_prompting |= XNegative;
@@ -4358,7 +4366,7 @@ Setting this variable does not affect existing frames, only new ones.  */);
   DEFVAR_LISP ("default-frame-scroll-bars", Vdefault_frame_scroll_bars,
               doc: /* Default position of scroll bars on this window-system.  */);
 #ifdef HAVE_WINDOW_SYSTEM
-#if defined(HAVE_NTGUI) || defined(NS_IMPL_COCOA) || (defined(USE_GTK) && defined(USE_TOOLKIT_SCROLL_BARS))
+#if defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA) || (defined (USE_GTK) && defined (USE_TOOLKIT_SCROLL_BARS))
   /* MS-Windows, Mac OS X, and GTK have scroll bars on the right by
      default.  */
   Vdefault_frame_scroll_bars = Qright;
@@ -4459,7 +4467,6 @@ automatically.  See also `mouse-autoselect-window'.  */);
   defsubr (&Sframe_list);
   defsubr (&Snext_frame);
   defsubr (&Sprevious_frame);
-  defsubr (&Sother_visible_frames_p);
   defsubr (&Sdelete_frame);
   defsubr (&Smouse_position);
   defsubr (&Smouse_pixel_position);