- defsubr (&Sactive_minibuffer_window);
- defsubr (&Sframep);
- defsubr (&Sframe_live_p);
- defsubr (&Smake_terminal_frame);
- defsubr (&Shandle_switch_frame);
- defsubr (&Sselect_frame);
- defsubr (&Sselected_frame);
- defsubr (&Swindow_frame);
- defsubr (&Sframe_root_window);
- defsubr (&Sframe_first_window);
- defsubr (&Sframe_selected_window);
- defsubr (&Sset_frame_selected_window);
- defsubr (&Sframe_list);
- defsubr (&Snext_frame);
- defsubr (&Sprevious_frame);
- defsubr (&Sdelete_frame);
- defsubr (&Smouse_position);
- defsubr (&Smouse_pixel_position);
- defsubr (&Sset_mouse_position);
- defsubr (&Sset_mouse_pixel_position);
-#if 0
- defsubr (&Sframe_configuration);
- defsubr (&Srestore_frame_configuration);
-#endif
- defsubr (&Smake_frame_visible);
- defsubr (&Smake_frame_invisible);
- defsubr (&Siconify_frame);
- defsubr (&Sframe_visible_p);
- defsubr (&Svisible_frame_list);
- defsubr (&Sraise_frame);
- defsubr (&Slower_frame);
- defsubr (&Sredirect_frame_focus);
- defsubr (&Sframe_focus);
- defsubr (&Sframe_parameters);
- defsubr (&Smodify_frame_parameters);
- defsubr (&Sframe_char_height);
- defsubr (&Sframe_char_width);
- defsubr (&Sframe_pixel_height);
- defsubr (&Sframe_pixel_width);
- defsubr (&Sset_frame_height);
- defsubr (&Sset_frame_width);
- defsubr (&Sset_frame_size);
- defsubr (&Sset_frame_position);
+ i = 0;
+ for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+ i++;
+
+ parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
+ values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
+
+ /* Extract parm names and values into those vectors. */
+
+ i = 0;
+ for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+ {
+ Lisp_Object elt;
+
+ elt = Fcar (tail);
+ parms[i] = Fcar (elt);
+ values[i] = Fcdr (elt);
+ i++;
+ }
+ /* TAIL and ALIST are not used again below here. */
+ alist = tail = Qnil;
+
+ GCPRO2 (*parms, *values);
+ gcpro1.nvars = i;
+ gcpro2.nvars = i;
+
+ /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
+ because their values appear in VALUES and strings are not valid. */
+ top = left = Qunbound;
+ icon_left = icon_top = Qunbound;
+
+ /* Provide default values for HEIGHT and WIDTH. */
+ width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
+ height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (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. */
+ /* Process default font as well, since fringe widths depends on it. */
+ /* Also, process fullscreen, width and height depend upon that */
+ 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)
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
+ {
+ register Lisp_Object param_index, old_value;
+
+ old_value = get_frame_param (f, prop);
+ fullscreen_is_being_set |= EQ (prop, Qfullscreen);
+
+ if (NILP (Fequal (val, old_value)))
+ {
+ store_frame_param (f, prop, val);
+
+ param_index = Fget (prop, Qx_frame_parameter);
+ if (NATNUMP (param_index)
+ && (XFASTINT (param_index)
+ < sizeof (frame_parms)/sizeof (frame_parms[0]))
+ && rif->frame_parm_handlers[XINT (param_index)])
+ (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
+ }
+ }
+ }
+
+ /* Now process them in reverse of specified order. */
+ for (i--; i >= 0; i--)
+ {
+ Lisp_Object prop, val;
+
+ prop = parms[i];
+ val = values[i];
+
+ if (EQ (prop, Qwidth) && NUMBERP (val))
+ width = XFASTINT (val);
+ else if (EQ (prop, Qheight) && NUMBERP (val))
+ height = XFASTINT (val);
+ else if (EQ (prop, Qtop))
+ top = val;
+ else if (EQ (prop, Qleft))
+ left = val;
+ else if (EQ (prop, Qicon_top))
+ icon_top = val;
+ else if (EQ (prop, Qicon_left))
+ icon_left = val;
+ else if (EQ (prop, Qforeground_color)
+ || EQ (prop, Qbackground_color)
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
+ /* Processed above. */
+ continue;
+ else
+ {
+ register Lisp_Object param_index, old_value;
+
+ old_value = get_frame_param (f, prop);
+
+ store_frame_param (f, prop, val);
+
+ param_index = Fget (prop, Qx_frame_parameter);
+ if (NATNUMP (param_index)
+ && (XFASTINT (param_index)
+ < sizeof (frame_parms)/sizeof (frame_parms[0]))
+ && rif->frame_parm_handlers[XINT (param_index)])
+ (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
+ }
+ }
+
+ /* Don't die if just one of these was set. */
+ if (EQ (left, Qunbound))
+ {
+ left_no_change = 1;
+ if (f->left_pos < 0)
+ left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
+ else
+ XSETINT (left, f->left_pos);
+ }
+ if (EQ (top, Qunbound))
+ {
+ top_no_change = 1;
+ if (f->top_pos < 0)
+ top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
+ else
+ XSETINT (top, f->top_pos);
+ }
+
+ /* If one of the icon positions was not set, preserve or default it. */
+ if (EQ (icon_left, Qunbound) || ! INTEGERP (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))
+ {
+ icon_top_no_change = 1;
+ icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
+ if (NILP (icon_top))
+ XSETINT (icon_top, 0);
+ }
+
+ if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
+ {
+ /* If the frame is visible already and the fullscreen parameter is
+ being set, it is too late to set WM manager hints to specify
+ size and position.
+ Here we first get the width, height and position that applies to
+ fullscreen. We then move the frame to the appropriate
+ position. Resize of the frame is taken care of in the code after
+ this if-statement. */
+ int new_left, new_top;
+
+ x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
+ if (new_top != f->top_pos || new_left != f->left_pos)
+ x_set_offset (f, new_left, new_top, 1);
+ }
+
+ /* Don't set these parameters unless they've been explicitly
+ specified. The window might be mapped or resized while we're in
+ this function, and we don't want to override that unless the lisp
+ code has asked for it.
+
+ Don't set these parameters unless they actually differ from the
+ window's current parameters; the window may not actually exist
+ yet. */
+ {
+ Lisp_Object frame;
+
+ check_frame_size (f, &height, &width);
+
+ XSETFRAME (frame, f);
+
+ if (width != FRAME_COLS (f)
+ || height != FRAME_LINES (f)
+ || f->new_text_lines || f->new_text_cols)
+ Fset_frame_size (frame, make_number (width), make_number (height));
+
+ if ((!NILP (left) || !NILP (top))
+ && ! (left_no_change && top_no_change)
+ && ! (NUMBERP (left) && XINT (left) == f->left_pos
+ && NUMBERP (top) && XINT (top) == f->top_pos))
+ {
+ int leftpos = 0;
+ int toppos = 0;
+
+ /* Record the signs. */
+ f->size_hint_flags &= ~ (XNegative | YNegative);
+ if (EQ (left, Qminus))
+ f->size_hint_flags |= XNegative;
+ else if (INTEGERP (left))
+ {
+ leftpos = XINT (left);
+ if (leftpos < 0)
+ f->size_hint_flags |= XNegative;
+ }
+ else if (CONSP (left) && EQ (XCAR (left), Qminus)
+ && CONSP (XCDR (left))
+ && INTEGERP (XCAR (XCDR (left))))
+ {
+ 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))))
+ {
+ leftpos = XINT (XCAR (XCDR (left)));
+ }
+
+ if (EQ (top, Qminus))
+ f->size_hint_flags |= YNegative;
+ else if (INTEGERP (top))
+ {
+ toppos = XINT (top);
+ if (toppos < 0)
+ f->size_hint_flags |= YNegative;
+ }
+ else if (CONSP (top) && EQ (XCAR (top), Qminus)
+ && CONSP (XCDR (top))
+ && INTEGERP (XCAR (XCDR (top))))
+ {
+ 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))))
+ {
+ toppos = XINT (XCAR (XCDR (top)));
+ }
+
+
+ /* Store the numeric value of the position. */
+ f->top_pos = toppos;
+ f->left_pos = leftpos;
+
+ f->win_gravity = NorthWestGravity;
+
+ /* Actually set that position, and convert to absolute. */
+ x_set_offset (f, leftpos, toppos, -1);
+ }
+
+ if ((!NILP (icon_left) || !NILP (icon_top))
+ && ! (icon_left_no_change && icon_top_no_change))
+ x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
+ }
+
+ UNGCPRO;