#include <config.h>
-#define FRAME_INLINE EXTERN_INLINE
-
#include <stdio.h>
#include <errno.h>
#include <limits.h>
static Lisp_Object Qx_frame_parameter;
Lisp_Object Qx_resource_name;
Lisp_Object Qterminal;
-Lisp_Object Qterminal_live_p;
/* Frame parameters (set or reported). */
Lisp_Object Qauto_raise, Qauto_lower;
Lisp_Object Qborder_color, Qborder_width;
Lisp_Object Qcursor_color, Qcursor_type;
-static Lisp_Object Qgeometry; /* Not used */
Lisp_Object Qheight, Qwidth;
Lisp_Object Qleft, Qright;
Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
Lisp_Object Qtooltip;
Lisp_Object Qinternal_border_width;
+Lisp_Object Qright_divider_width, Qbottom_divider_width;
Lisp_Object Qmouse_color;
Lisp_Object Qminibuffer;
Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
Lisp_Object Qface_set_after_frame_default;
+static Lisp_Object Qfocus_in_hook;
+static Lisp_Object Qfocus_out_hook;
static Lisp_Object Qdelete_frame_functions;
+static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes, Qsource;
+
+/* The currently selected frame. */
+
+Lisp_Object selected_frame;
+
+/* A frame which is not just a mini-buffer, or NULL if there are no such
+ frames. This is usually the most recent such frame that was selected. */
+
+static struct frame *last_nonminibuf_frame;
+
+/* Nonzero means there is at least one garbaged frame. */
+
+bool frame_garbaged;
+
#ifdef HAVE_WINDOW_SYSTEM
static void x_report_frame_params (struct frame *, Lisp_Object *);
#endif
decode_window_system_frame (Lisp_Object frame)
{
struct frame *f = decode_live_frame (frame);
-
+
if (!window_system_available (f))
error ("Window system frame should be used");
return f;
set_menu_bar_lines_1 (Lisp_Object window, int n)
{
struct window *w = XWINDOW (window);
+ struct frame *f = XFRAME (WINDOW_FRAME (w));
- w->last_modified = 0;
w->top_line += n;
+ w->pixel_top += n * FRAME_LINE_HEIGHT (f);
w->total_lines -= n;
+ w->pixel_height -= n * FRAME_LINE_HEIGHT (f);
/* Handle just the top child in a vertical split. */
if (WINDOW_VERTICAL_COMBINATION_P (w))
if (nlines != olines)
{
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 14;
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
FRAME_MENU_BAR_LINES (f) = nlines;
+ FRAME_MENU_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
set_menu_bar_lines_1 (f->root_window, nlines - olines);
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
}
}
\f
}
struct frame *
-make_frame (int mini_p)
+make_frame (bool mini_p)
{
Lisp_Object frame;
register struct frame *f;
+ register struct window *rw, *mw;
register Lisp_Object root_window;
register Lisp_Object mini_window;
non-Lisp data, so do it only for slots which should not be zero.
To avoid subtle bugs and for the sake of readability, it's better to
initialize enum members explicitly even if their values are zero. */
- f->wants_modeline = 1;
- f->garbaged = 1;
- f->has_minibuffer = mini_p;
+ f->wants_modeline = true;
+ f->redisplay = true;
+ f->garbaged = true;
f->vertical_scroll_bar_type = vertical_scroll_bar_none;
- f->column_width = 1; /* !FRAME_WINDOW_P value */
- f->line_height = 1; /* !FRAME_WINDOW_P value */
+ f->column_width = 1; /* !FRAME_WINDOW_P value. */
+ f->line_height = 1; /* !FRAME_WINDOW_P value. */
#ifdef HAVE_WINDOW_SYSTEM
f->want_fullscreen = FULLSCREEN_NONE;
#endif
root_window = make_window ();
+ rw = XWINDOW (root_window);
if (mini_p)
{
mini_window = make_window ();
- wset_next (XWINDOW (root_window), mini_window);
- wset_prev (XWINDOW (mini_window), root_window);
- XWINDOW (mini_window)->mini = 1;
- wset_frame (XWINDOW (mini_window), frame);
+ mw = XWINDOW (mini_window);
+ wset_next (rw, mini_window);
+ wset_prev (mw, root_window);
+ mw->mini = 1;
+ wset_frame (mw, frame);
fset_minibuffer_window (f, mini_window);
}
else
{
mini_window = Qnil;
- wset_next (XWINDOW (root_window), Qnil);
+ wset_next (rw, Qnil);
fset_minibuffer_window (f, Qnil);
}
- wset_frame (XWINDOW (root_window), frame);
+ wset_frame (rw, frame);
/* 10 is arbitrary,
just so that there is "something there."
SET_FRAME_COLS (f, 10);
FRAME_LINES (f) = 10;
+ SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
+ SET_FRAME_HEIGHT (f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
- XWINDOW (root_window)->total_cols = 10;
- XWINDOW (root_window)->total_lines = mini_p ? 9 : 10;
+ rw->total_cols = 10;
+ rw->pixel_width = rw->total_cols * FRAME_COLUMN_WIDTH (f);
+ rw->total_lines = mini_p ? 9 : 10;
+ rw->pixel_height = rw->total_lines * FRAME_LINE_HEIGHT (f);
if (mini_p)
{
- XWINDOW (mini_window)->total_cols = 10;
- XWINDOW (mini_window)->top_line = 9;
- XWINDOW (mini_window)->total_lines = 1;
+ mw->top_line = rw->total_lines;
+ mw->pixel_top = rw->pixel_height;
+ mw->total_cols = rw->total_cols;
+ mw->pixel_width = rw->pixel_width;
+ mw->total_lines = 1;
+ mw->pixel_height = FRAME_LINE_HEIGHT (f);
}
/* Choose a buffer for the frame's root window. */
etc. Running Lisp functions at this point surely ends in a
SEGV. */
set_window_buffer (root_window, buf, 0, 0);
- fset_buffer_list (f, Fcons (buf, Qnil));
+ fset_buffer_list (f, list1 (buf));
}
if (mini_p)
f->auto_lower = 0;
f->no_split = 1;
f->wants_modeline = 0;
- f->has_minibuffer = 1;
/* Now label the root window as also being the minibuffer.
Avoid infinite looping on the window chain by marking next pointer
if (!noninteractive)
init_frame_faces (f);
+ last_nonminibuf_frame = f;
+
return f;
}
#endif /* not MSDOS */
FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
- FRAME_MENU_BAR_LINES(f) = NILP (Vmenu_bar_mode) ? 0 : 1;
+ FRAME_MENU_BAR_LINES (f) = NILP (Vmenu_bar_mode) ? 0 : 1;
+ FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f);
/* Set the top frame to the newly created frame. */
if (FRAMEP (FRAME_TTY (f)->top_frame)
? FRAME_TTY (XFRAME (selected_frame))->name
: NULL));
if (!NILP (tty))
- {
- name = alloca (SBYTES (tty) + 1);
- memcpy (name, SSDATA (tty), SBYTES (tty));
- name[SBYTES (tty)] = 0;
- }
+ name = xlispstrdupa (tty);
tty_type = get_future_frame_param
(Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
? FRAME_TTY (XFRAME (selected_frame))->type
: NULL));
if (!NILP (tty_type))
- {
- type = alloca (SBYTES (tty_type) + 1);
- memcpy (type, SSDATA (tty_type), SBYTES (tty_type));
- type[SBYTES (tty_type)] = 0;
- }
+ type = xlispstrdupa (tty_type);
- t = init_tty (name, type, 0); /* Errors are not fatal. */
+ t = init_tty (name, type, 0); /* Errors are not fatal. */
}
f = make_terminal_frame (t);
{
int width, height;
get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
- change_frame_size (f, height, width, 0, 0, 0);
+ change_frame_size (f, width, height, 0, 0, 0, 0);
}
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
calculate_costs (f);
XSETFRAME (frame, f);
+
+ store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
+ store_in_alist (&parms, Qtty,
+ (t->display_info.tty->name
+ ? build_string (t->display_info.tty->name)
+ : Qnil));
Fmodify_frame_parameters (frame, parms);
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
- build_string (t->display_info.tty->type)),
- Qnil));
- if (t->display_info.tty->name != NULL)
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
- build_string (t->display_info.tty->name)),
- Qnil));
- else
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
/* Make the frame face alist be frame-specific, so that each
frame could change its face definitions independently. */
if (sf == XFRAME (frame))
return frame;
- /* This is too greedy; it causes inappropriate focus redirection
- that's hard to get rid of. */
-#if 0
/* If a frame's focus has been redirected toward the currently
selected frame, we should change the redirection to point to the
newly selected frame. This means that if the focus is redirected
can use `other-window' to switch between all the frames using
that minibuffer frame, and the focus redirection will follow us
around. */
+#if 0
+ /* This is too greedy; it causes inappropriate focus redirection
+ that's hard to get rid of. */
if (track)
{
Lisp_Object tail;
return do_switch_frame (frame, 1, 0, norecord);
}
-
DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
doc: /* Handle a switch-frame event EVENT.
Switch-frame events are usually bound to this function.
/* Preserve prefix arg that the command loop just cleared. */
kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
Frun_hooks (1, &Qmouse_leave_buffer_hook);
+ /* `switch-frame' implies a focus in. */
+ call1 (intern ("handle-focus-in"), event);
return do_switch_frame (event, 0, 0, Qnil);
}
CHECK_LIVE_FRAME (frame);
return prev_frame (frame, miniframe);
}
+
+DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
+ Slast_nonminibuf_frame, 0, 0, 0,
+ doc: /* Return last non-minibuffer frame selected. */)
+ (void)
+{
+ Lisp_Object frame = Qnil;
+
+ if (last_nonminibuf_frame)
+ XSETFRAME (frame, last_nonminibuf_frame);
+
+ return frame;
+}
\f
/* Return 1 if it is ok to delete frame F;
0 if all frames aside from F are invisible.
(Exception: if F is the terminal frame, and we are using X, return 1.) */
static int
-other_visible_frames (FRAME_PTR f)
+other_visible_frames (struct frame *f)
{
Lisp_Object frames, this;
/* Verify that we can still talk to the frame's X window,
and note any recent change in visibility. */
-#ifdef HAVE_WINDOW_SYSTEM
+#ifdef HAVE_X_WINDOWS
if (FRAME_WINDOW_P (XFRAME (this)))
x_sync (XFRAME (this));
#endif
return 0;
}
+/* Make sure that minibuf_window doesn't refer to FRAME's minibuffer
+ window. Preferably use the selected frame's minibuffer window
+ instead. If the selected frame doesn't have one, get some other
+ frame's minibuffer window. SELECT non-zero means select the new
+ minibuffer window. */
+static void
+check_minibuf_window (Lisp_Object frame, int select)
+{
+ struct frame *f = decode_live_frame (frame);
+
+ XSETFRAME (frame, f);
+
+ if (WINDOWP (minibuf_window) && EQ (f->minibuffer_window, minibuf_window))
+ {
+ Lisp_Object frames, this, window = make_number (0);
+
+ if (!EQ (frame, selected_frame)
+ && FRAME_HAS_MINIBUF_P (XFRAME (selected_frame)))
+ window = FRAME_MINIBUF_WINDOW (XFRAME (selected_frame));
+ else
+ FOR_EACH_FRAME (frames, this)
+ {
+ if (!EQ (this, frame) && FRAME_HAS_MINIBUF_P (XFRAME (this)))
+ {
+ window = FRAME_MINIBUF_WINDOW (XFRAME (this));
+ break;
+ }
+ }
+
+ /* Don't abort if no window was found (Bug#15247). */
+ if (WINDOWP (window))
+ {
+ /* Use set_window_buffer instead of Fset_window_buffer (see
+ discussion of bug#11984, bug#12025, bug#12026). */
+ set_window_buffer (window, XWINDOW (minibuf_window)->contents, 0, 0);
+ minibuf_window = window;
+
+ /* SELECT non-zero usually means that FRAME's minibuffer
+ window was selected; select the new one. */
+ if (select)
+ Fselect_window (minibuf_window, 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
delete_frame (Lisp_Object frame, Lisp_Object force)
{
struct frame *f = decode_any_frame (frame);
- struct frame *sf = SELECTED_FRAME ();
+ struct frame *sf;
struct kboard *kb;
int minibuffer_selected, is_tooltip_frame;
FOR_EACH_FRAME (frames, this)
{
- if (! EQ (this, frame)
- && EQ (frame,
- WINDOW_FRAME (XWINDOW
- (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
+ Lisp_Object fminiw;
+
+ if (EQ (this, frame))
+ continue;
+
+ fminiw = FRAME_MINIBUF_WINDOW (XFRAME (this));
+
+ if (WINDOWP (fminiw) && EQ (frame, WINDOW_FRAME (XWINDOW (fminiw))))
{
/* If we MUST delete this frame, delete the other first.
But do this only if FORCE equals `noelisp'. */
There is no more chance for errors to prevent it. */
minibuffer_selected = EQ (minibuf_window, selected_window);
-
+ sf = SELECTED_FRAME ();
/* Don't let the frame remain selected. */
if (f == sf)
{
- Lisp_Object tail, frame1;
-
- /* Look for another visible frame on the same terminal. */
- frame1 = next_frame (frame, Qvisible);
+ Lisp_Object tail;
+ Lisp_Object frame1 = Qnil;
+
+ /* Look for another visible frame on the same terminal.
+ Do not call next_frame here because it may loop forever.
+ See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
+ FOR_EACH_FRAME (tail, frame1)
+ if (!EQ (frame, frame1)
+ && (FRAME_TERMINAL (XFRAME (frame))
+ == FRAME_TERMINAL (XFRAME (frame1)))
+ && FRAME_VISIBLE_P (XFRAME (frame1)))
+ break;
/* If there is none, find *some* other frame. */
if (NILP (frame1) || EQ (frame1, frame))
}
/* Don't allow minibuf_window to remain on a deleted frame. */
- if (EQ (f->minibuffer_window, minibuf_window))
- {
- /* Use set_window_buffer instead of Fset_window_buffer (see
- discussion of bug#11984, bug#12025, bug#12026). */
- set_window_buffer (sf->minibuffer_window,
- XWINDOW (minibuf_window)->contents, 0, 0);
- minibuf_window = sf->minibuffer_window;
-
- /* If the dying minibuffer window was selected,
- select the new one. */
- if (minibuffer_selected)
- Fselect_window (minibuf_window, Qnil);
- }
+ check_minibuf_window (frame, minibuffer_selected);
/* Don't let echo_area_window to remain on a deleted frame. */
if (EQ (f->minibuffer_window, echo_area_window))
have called the window-system-dependent frame destruction
routine. */
- if (FRAME_TERMINAL (f)->delete_frame_hook)
- (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
{
+ block_input ();
+ if (FRAME_TERMINAL (f)->delete_frame_hook)
+ (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
struct terminal *terminal = FRAME_TERMINAL (f);
f->output_data.nothing = 0;
f->terminal = 0; /* Now the frame is dead. */
+ unblock_input ();
/* If needed, delete the terminal that this frame was on.
(This must be done after the frame is killed.) */
/* Cause frame titles to update--necessary if we now have just one frame. */
if (!is_tooltip_frame)
- update_mode_lines = 1;
+ update_mode_lines = 15;
return Qnil;
}
and returns whatever that function returns. */)
(void)
{
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object lispy_dummy;
Lisp_Object x, y, retval;
struct gcpro gcpro1;
and nil for X and Y. */)
(void)
{
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object lispy_dummy;
Lisp_Object x, y;
make_frame_visible_1 (f->root_window);
/* Make menu bar update for the Buffers and Frames menus. */
- windows_or_buffers_changed++;
+ /* windows_or_buffers_changed = 15; FIXME: Why? */
XSETFRAME (frame, f);
return frame;
if (NILP (force) && !other_visible_frames (f))
error ("Attempt to make invisible the sole visible or iconified frame");
- /* Don't allow minibuf_window to remain on a deleted frame. */
- if (EQ (f->minibuffer_window, minibuf_window))
- {
- struct frame *sf = XFRAME (selected_frame);
- /* Use set_window_buffer instead of Fset_window_buffer (see
- discussion of bug#11984, bug#12025, bug#12026). */
- set_window_buffer (sf->minibuffer_window,
- XWINDOW (minibuf_window)->contents, 0, 0);
- minibuf_window = sf->minibuffer_window;
- }
+ /* Don't allow minibuf_window to remain on an invisible frame. */
+ check_minibuf_window (frame, EQ (minibuf_window, selected_window));
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
#endif
/* Make menu bar update for the Buffers and Frames menus. */
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 16;
return Qnil;
}
struct frame *f = decode_live_frame (frame);
/* Don't allow minibuf_window to remain on an iconified frame. */
- if (EQ (f->minibuffer_window, minibuf_window))
- {
- struct frame *sf = XFRAME (selected_frame);
- /* Use set_window_buffer instead of Fset_window_buffer (see
- discussion of bug#11984, bug#12025, bug#12026). */
- set_window_buffer (sf->minibuffer_window,
- XWINDOW (minibuf_window)->contents, 0, 0);
- minibuf_window = sf->minibuffer_window;
- }
+ check_minibuf_window (frame, EQ (minibuf_window, selected_window));
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
#endif
/* Make menu bar update for the Buffers and Frames menus. */
- windows_or_buffers_changed++;
+ windows_or_buffers_changed = 17;
return Qnil;
}
return FRAME_FOCUS_FRAME (decode_live_frame (frame));
}
+DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
+ doc: /* Set the input focus to FRAME.
+FRAME nil means use the selected frame.
+If there is no window system support, this function does nothing. */)
+ (Lisp_Object frame)
+{
+#ifdef HAVE_WINDOW_SYSTEM
+ x_focus_frame (decode_window_system_frame (frame));
+#endif
+ return Qnil;
+}
\f
/* Return the value of frame parameter PROP in frame FRAME. */
#ifdef HAVE_WINDOW_SYSTEM
-#if !HAVE_NS && !defined(WINDOWSNT)
+#if !HAVE_NS && !HAVE_NTGUI
static
#endif
Lisp_Object
}
fset_name (f, name);
- update_mode_lines = 1;
+ update_mode_lines = 16;
}
+#ifdef HAVE_NTGUI
+void
+set_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
+{
+ register Lisp_Object old_alist_elt;
+
+ old_alist_elt = Fassq (prop, f->param_alist);
+ if (EQ (old_alist_elt, Qnil))
+ fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist));
+ else
+ Fsetcdr (old_alist_elt, val);
+}
+#endif
+
void
store_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val)
{
:"tty"));
}
store_in_alist (&alist, Qname, f->name);
- height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
+ height = (f->new_height
+ ? (f->new_pixelwise
+ ? (f->new_height / FRAME_LINE_HEIGHT (f))
+ : f->new_height)
+ : FRAME_LINES (f));
store_in_alist (&alist, Qheight, make_number (height));
- width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
+ width = (f->new_width
+ ? (f->new_pixelwise
+ ? (f->new_width / FRAME_COLUMN_WIDTH (f))
+ : f->new_width)
+ : FRAME_COLS (f));
store_in_alist (&alist, Qwidth, make_number (width));
store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
store_in_alist (&alist, Qminibuffer,
value = f->name;
#ifdef HAVE_X_WINDOWS
else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
- value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
+ value = XCAR (FRAME_DISPLAY_INFO (f)->name_list_element);
#endif /* HAVE_X_WINDOWS */
else if (EQ (parameter, Qbackground_color)
|| EQ (parameter, Qforeground_color))
(Lisp_Object frame, Lisp_Object alist)
{
struct frame *f = decode_live_frame (frame);
- register Lisp_Object tail, prop, val;
+ register Lisp_Object prop, val;
+
+ CHECK_LIST (alist);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
/* Extract parm names and values into those vectors. */
- i = 0;
- for (tail = alist; CONSP (tail); tail = XCDR (tail))
+ for (i = 0; CONSP (alist); alist = XCDR (alist))
{
Lisp_Object elt;
- elt = XCAR (tail);
+ elt = XCAR (alist);
parms[i] = Fcar (elt);
values[i] = Fcdr (elt);
i++;
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
- return make_number (x_pixel_height (f));
+ return make_number (FRAME_PIXEL_HEIGHT (f));
else
#endif
return make_number (FRAME_LINES (f));
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
- return make_number (x_pixel_width (f));
+ return make_number (FRAME_PIXEL_WIDTH (f));
else
#endif
return make_number (FRAME_COLS (f));
#endif
return make_number (0);
}
+
+DEFUN ("frame-text-cols", Fframe_text_cols, Sframe_text_cols, 0, 1, 0,
+ doc: /* Return width in columns of FRAME's text area. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_COLS (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-text-lines", Fframe_text_lines, Sframe_text_lines, 0, 1, 0,
+ doc: /* Return height in lines of FRAME's text area. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_LINES (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-total-cols", Fframe_total_cols, Sframe_total_cols, 0, 1, 0,
+ doc: /* Return total columns of FRAME. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TOTAL_COLS (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-text-width", Fframe_text_width, Sframe_text_width, 0, 1, 0,
+ doc: /* Return text area width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TEXT_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-text-height", Fframe_text_height, Sframe_text_height, 0, 1, 0,
+ doc: /* Return text area height of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TEXT_HEIGHT (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-scroll-bar-width", Fscroll_bar_width, Sscroll_bar_width, 0, 1, 0,
+ doc: /* Return scroll bar width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (decode_any_frame (frame)->scroll_bar_actual_width);
+}
+
+DEFUN ("frame-fringe-width", Ffringe_width, Sfringe_width, 0, 1, 0,
+ doc: /* Return fringe width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_TOTAL_FRINGE_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-border-width", Fborder_width, Sborder_width, 0, 1, 0,
+ doc: /* Return border width of FRAME in pixels. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_INTERNAL_BORDER_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-right-divider-width", Fright_divider_width, Sright_divider_width, 0, 1, 0,
+ doc: /* Return width (in pixels) of vertical window dividers on FRAME. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_RIGHT_DIVIDER_WIDTH (decode_any_frame (frame)));
+}
+
+DEFUN ("frame-bottom-divider-width", Fbottom_divider_width, Sbottom_divider_width, 0, 1, 0,
+ doc: /* Return width (in pixels) of horizontal window dividers on FRAME. */)
+ (Lisp_Object frame)
+{
+ return make_number (FRAME_BOTTOM_DIVIDER_WIDTH (decode_any_frame (frame)));
+}
\f
-DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
- doc: /* Specify that the frame FRAME has LINES lines.
-Optional third arg non-nil means that redisplay should use LINES lines
-but that the idea of the actual height of the frame should not be changed. */)
- (Lisp_Object frame, Lisp_Object lines, Lisp_Object pretend)
+DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 4, 0,
+ doc: /* Specify that the frame FRAME has HEIGHT text lines.
+Optional third arg PRETEND non-nil means that redisplay should use
+HEIGHT lines but that the idea of the actual height of the frame should
+not be changed. Optional fourth argument PIXELWISE non-nil means that
+FRAME should be HEIGHT pixels high. */)
+ (Lisp_Object frame, Lisp_Object height, Lisp_Object pretend, Lisp_Object pixelwise)
{
register struct frame *f = decode_live_frame (frame);
- CHECK_TYPE_RANGED_INTEGER (int, lines);
+ CHECK_TYPE_RANGED_INTEGER (int, height);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
- if (XINT (lines) != FRAME_LINES (f))
- x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
- do_pending_window_change (0);
+ if (NILP (pixelwise))
+ {
+ if (XINT (height) != FRAME_LINES (f))
+ x_set_window_size (f, 1, FRAME_COLS (f), XINT (height), 0);
+
+ do_pending_window_change (0);
+ }
+ else if (XINT (height) != FRAME_TEXT_HEIGHT (f))
+ {
+ x_set_window_size (f, 1, FRAME_TEXT_WIDTH (f), XINT (height), 1);
+ do_pending_window_change (0);
+ }
}
else
#endif
- change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
+ change_frame_size (f, 0, XINT (height), !NILP (pretend), 0, 0,
+ NILP (pixelwise) ? 0 : 1);
return Qnil;
}
-DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
- doc: /* Specify that the frame FRAME has COLS columns.
-Optional third arg non-nil means that redisplay should use COLS columns
-but that the idea of the actual width of the frame should not be changed. */)
- (Lisp_Object frame, Lisp_Object cols, Lisp_Object pretend)
+DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 4, 0,
+ doc: /* Specify that the frame FRAME has WIDTH columns.
+Optional third arg PRETEND non-nil means that redisplay should use WIDTH
+columns but that the idea of the actual width of the frame should not
+be changed. Optional fourth argument PIXELWISE non-nil means that FRAME
+should be WIDTH pixels wide. */)
+ (Lisp_Object frame, Lisp_Object width, Lisp_Object pretend, Lisp_Object pixelwise)
{
register struct frame *f = decode_live_frame (frame);
- CHECK_TYPE_RANGED_INTEGER (int, cols);
+ CHECK_TYPE_RANGED_INTEGER (int, width);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
- if (XINT (cols) != FRAME_COLS (f))
- x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
- do_pending_window_change (0);
+ if (NILP (pixelwise))
+ {
+ if (XINT (width) != FRAME_COLS (f))
+ x_set_window_size (f, 1, XINT (width), FRAME_LINES (f), 0);
+
+ do_pending_window_change (0);
+ }
+ else if (XINT (width) != FRAME_TEXT_WIDTH (f))
+ {
+ x_set_window_size (f, 1, XINT (width), FRAME_TEXT_HEIGHT (f), 1);
+ do_pending_window_change (0);
+ }
}
else
#endif
- change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
+ change_frame_size (f, XINT (width), 0, !NILP (pretend), 0, 0,
+ NILP (pixelwise) ? 0 : 1);
return Qnil;
}
-DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
- doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
- (Lisp_Object frame, Lisp_Object cols, Lisp_Object rows)
+DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 4, 0,
+ doc: /* Sets size of FRAME to WIDTH by HEIGHT, measured in characters.
+Optional argument PIXELWISE non-nil means to measure in pixels. */)
+ (Lisp_Object frame, Lisp_Object width, Lisp_Object height, Lisp_Object pixelwise)
{
- register struct frame *f;
+ register struct frame *f = decode_live_frame (frame);
- CHECK_LIVE_FRAME (frame);
- CHECK_TYPE_RANGED_INTEGER (int, cols);
- CHECK_TYPE_RANGED_INTEGER (int, rows);
- f = XFRAME (frame);
+ CHECK_TYPE_RANGED_INTEGER (int, width);
+ CHECK_TYPE_RANGED_INTEGER (int, height);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
if (FRAME_WINDOW_P (f))
{
- if (XINT (rows) != FRAME_LINES (f)
- || XINT (cols) != FRAME_COLS (f)
- || f->new_text_lines || f->new_text_cols)
- x_set_window_size (f, 1, XINT (cols), XINT (rows));
- do_pending_window_change (0);
+ if (!NILP (pixelwise)
+ ? (XINT (width) != FRAME_TEXT_WIDTH (f)
+ || XINT (height) != FRAME_TEXT_HEIGHT (f)
+ || f->new_height || f->new_width)
+ : (XINT (width) != FRAME_COLS (f)
+ || XINT (height) != FRAME_LINES (f)
+ || f->new_height || f->new_width))
+ {
+ x_set_window_size (f, 1, XINT (width), XINT (height),
+ NILP (pixelwise) ? 0 : 1);
+ do_pending_window_change (0);
+ }
}
else
#endif
- change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
+ change_frame_size (f, XINT (width), XINT (height), 0, 0, 0,
+ NILP (pixelwise) ? 0 : 1);
return Qnil;
}
DEFUN ("set-frame-position", Fset_frame_position,
Sset_frame_position, 3, 3, 0,
doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
-This is actually the position of the upper left corner of the frame.
-Negative values for XOFFSET or YOFFSET are interpreted relative to
-the rightmost or bottommost possible position (that stays within the screen). */)
+If FRAME is nil, the selected frame is used. XOFFSET and YOFFSET are
+actually the position of the upper left corner of the frame. Negative
+values for XOFFSET or YOFFSET are interpreted relative to the rightmost
+or bottommost possible position (that stays within the screen). */)
(Lisp_Object frame, Lisp_Object xoffset, Lisp_Object yoffset)
{
- register struct frame *f;
+ register struct frame *f = decode_live_frame (frame);
- CHECK_LIVE_FRAME (frame);
CHECK_TYPE_RANGED_INTEGER (int, xoffset);
CHECK_TYPE_RANGED_INTEGER (int, yoffset);
- f = XFRAME (frame);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
{"icon-name", &Qicon_name},
{"icon-type", &Qicon_type},
{"internal-border-width", &Qinternal_border_width},
+ {"right-divider-width", &Qright_divider_width},
+ {"bottom-divider-width", &Qbottom_divider_width},
{"menu-bar-lines", &Qmenu_bar_lines},
{"mouse-color", &Qmouse_color},
{"name", &Qname},
{
int newwidth = FRAME_COLS (f);
int newheight = FRAME_LINES (f);
- Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
*top_pos = f->top_pos;
*left_pos = f->left_pos;
to store the new value in the parameter alist. */
void
-x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
+x_set_frame_parameters (struct frame *f, Lisp_Object alist)
{
Lisp_Object tail;
Lisp_Object *parms;
Lisp_Object *values;
ptrdiff_t i, p;
- int left_no_change = 0, top_no_change = 0;
- int icon_left_no_change = 0, icon_top_no_change = 0;
- int size_changed = 0;
+ bool left_no_change = 0, top_no_change = 0;
+ bool icon_left_no_change = 0, icon_top_no_change = 0;
+ bool size_changed = 0;
struct gcpro gcpro1, gcpro2;
i = 0;
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));
+ width = (f->new_width
+ ? (f->new_pixelwise
+ ? (f->new_width / FRAME_COLUMN_WIDTH (f))
+ : f->new_width)
+ : FRAME_COLS (f));
+ height = (f->new_height
+ ? (f->new_pixelwise
+ ? (f->new_height / FRAME_LINE_HEIGHT (f))
+ : f->new_height)
+ : FRAME_LINES (f));
/* Process foreground_color and background_color before anything else.
They are independent of other properties, but other properties (e.g.,
{
left_no_change = 1;
if (f->left_pos < 0)
- left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
+ left = list2 (Qplus, make_number (f->left_pos));
else
XSETINT (left, f->left_pos);
}
{
top_no_change = 1;
if (f->top_pos < 0)
- top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
+ top = list2 (Qplus, make_number (f->top_pos));
else
XSETINT (top, f->top_pos);
}
{
Lisp_Object frame;
- check_frame_size (f, &height, &width);
+ /* Make this 1, eventually. */
+ check_frame_size (f, &width, &height, 0);
XSETFRAME (frame, f);
if (size_changed
&& (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));
+ || f->new_height || f->new_width))
+ Fset_frame_size (frame, make_number (width), make_number (height), Qnil);
if ((!NILP (left) || !NILP (top))
&& ! (left_no_change && top_no_change)
/* Actually set that position, and convert to absolute. */
x_set_offset (f, leftpos, toppos, -1);
}
-
+#ifdef HAVE_X_WINDOWS
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));
+#endif /* HAVE_X_WINDOWS */
}
UNGCPRO;
if (f->left_pos >= 0)
store_in_alist (alistptr, Qleft, tem);
else
- store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
+ store_in_alist (alistptr, Qleft, list2 (Qplus, tem));
XSETINT (tem, f->top_pos);
if (f->top_pos >= 0)
store_in_alist (alistptr, Qtop, tem);
else
- store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
+ store_in_alist (alistptr, Qtop, list2 (Qplus, tem));
store_in_alist (alistptr, Qborder_width,
make_number (f->border_width));
store_in_alist (alistptr, Qinternal_border_width,
make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
+ store_in_alist (alistptr, Qright_divider_width,
+ make_number (FRAME_RIGHT_DIVIDER_WIDTH (f)));
+ store_in_alist (alistptr, Qbottom_divider_width,
+ make_number (FRAME_BOTTOM_DIVIDER_WIDTH (f)));
store_in_alist (alistptr, Qleft_fringe,
make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
store_in_alist (alistptr, Qright_fringe,
(FRAME_VISIBLE_P (f) ? Qt
: FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
store_in_alist (alistptr, Qdisplay,
- XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
+ XCAR (FRAME_DISPLAY_INFO (f)->name_list_element));
- if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
+ if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_DISPLAY_INFO (f)->root_window)
tem = Qnil;
else
- XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
+ tem = make_natnum ((uintptr_t) FRAME_X_OUTPUT (f)->parent_desc);
store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
store_in_alist (alistptr, Qparent_id, tem);
store_in_alist (alistptr, Qtool_bar_position, f->tool_bar_position);
f->extra_line_spacing = 0;
else if (RANGED_INTEGERP (0, new_value, INT_MAX))
f->extra_line_spacing = XFASTINT (new_value);
+ else if (FLOATP (new_value))
+ {
+ int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f) + 0.5;
+
+ if (new_spacing >= 0)
+ f->extra_line_spacing = new_spacing;
+ else
+ signal_error ("Invalid line-spacing", new_value);
+ }
else
signal_error ("Invalid line-spacing", new_value);
if (FRAME_VISIBLE_P (f))
#endif
/* Recalculate toolbar height. */
f->n_tool_bar_rows = 0;
+
/* Ensure we redraw it. */
clear_current_matrices (f);
+ /* Attempt to hunt down bug#16028. */
+ SET_FRAME_GARBAGED (f);
+
recompute_basic_faces (f);
do_pending_window_change (0);
XSETFRAME (frame, f);
x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
++face_change_count;
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 18;
}
}
if (FRAME_X_WINDOW (f) != 0)
{
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
+ SET_FRAME_GARBAGED (f);
+ do_pending_window_change (0);
+ }
+ else
+ SET_FRAME_GARBAGED (f);
+}
+
+void
+x_set_right_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int old = FRAME_RIGHT_DIVIDER_WIDTH (f);
+
+ CHECK_TYPE_RANGED_INTEGER (int, arg);
+ FRAME_RIGHT_DIVIDER_WIDTH (f) = XINT (arg);
+ if (FRAME_RIGHT_DIVIDER_WIDTH (f) < 0)
+ FRAME_RIGHT_DIVIDER_WIDTH (f) = 0;
+
+ if (FRAME_RIGHT_DIVIDER_WIDTH (f) == old)
+ return;
+
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
+ SET_FRAME_GARBAGED (f);
+ do_pending_window_change (0);
+ }
+ else
+ SET_FRAME_GARBAGED (f);
+}
+
+void
+x_set_bottom_divider_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int old = FRAME_BOTTOM_DIVIDER_WIDTH (f);
+
+ CHECK_TYPE_RANGED_INTEGER (int, arg);
+ FRAME_BOTTOM_DIVIDER_WIDTH (f) = XINT (arg);
+ if (FRAME_BOTTOM_DIVIDER_WIDTH (f) < 0)
+ FRAME_BOTTOM_DIVIDER_WIDTH (f) = 0;
+
+ if (FRAME_BOTTOM_DIVIDER_WIDTH (f) == old)
+ return;
+
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
SET_FRAME_GARBAGED (f);
do_pending_window_change (0);
}
However, if the window hasn't been created yet, we shouldn't
call x_set_window_size. */
if (FRAME_X_WINDOW (f))
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (0);
}
}
void
x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
- int wid = FRAME_COLUMN_WIDTH (f);
+ int unit = FRAME_COLUMN_WIDTH (f);
if (NILP (arg))
{
x_set_scroll_bar_default_width (f);
if (FRAME_X_WINDOW (f))
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (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)
- XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
-
FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + unit - 1) / unit;
if (FRAME_X_WINDOW (f))
- x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+ x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f),
+ FRAME_TEXT_HEIGHT (f), 1);
do_pending_window_change (0);
}
- change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
+ change_frame_size (f, 0, 0, 0, 0, 0, 1);
XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
}
-
-
-/* Return non-nil if frame F wants a bitmap icon. */
-
-Lisp_Object
-x_icon_type (FRAME_PTR f)
-{
- Lisp_Object tem;
-
- tem = assq_no_quit (Qicon_type, f->param_alist);
- if (CONSP (tem))
- return XCDR (tem);
- else
- return Qnil;
-}
-
void
x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
return;
}
-\f
+#ifndef HAVE_NS
+
+/* Non-zero if mouse is grabbed on DPYINFO
+ and we know the frame where it is. */
+
+bool x_mouse_grabbed (Display_Info *dpyinfo)
+{
+ return (dpyinfo->grabbed
+ && dpyinfo->last_mouse_frame
+ && FRAME_LIVE_P (dpyinfo->last_mouse_frame));
+}
+
+/* Re-highlight something with mouse-face properties
+ on DPYINFO using saved frame and mouse position. */
+
+void
+x_redo_mouse_highlight (Display_Info *dpyinfo)
+{
+ if (dpyinfo->last_mouse_motion_frame
+ && FRAME_LIVE_P (dpyinfo->last_mouse_motion_frame))
+ note_mouse_highlight (dpyinfo->last_mouse_motion_frame,
+ dpyinfo->last_mouse_motion_x,
+ dpyinfo->last_mouse_motion_y);
+}
+
+#endif /* HAVE_NS */
+
/* Subroutines of creating an X frame. */
/* Make sure that Vx_resource_name is set to a reasonable value.
}
}
-
-extern char *x_get_string_resource (XrmDatabase, const char *, const char *);
-extern Display_Info *check_x_display_info (Lisp_Object);
-
-
/* Get specified attribute from resource database RDB.
See Fx_get_resource below for other parameters. */
value = x_get_string_resource (rdb, name_key, class_key);
- if (value != (char *) 0 && *value)
+ if (value && *value)
return build_string (value);
else
return Qnil;
esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
sprintf (class_key, "%s.%s", EMACS_CLASS, class);
- result = x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
+ result = x_get_string_resource (FRAME_DISPLAY_INFO (sf)->xrdb,
name_key, class_key);
SAFE_FREE ();
return result;
const char *attribute, const char *class,
enum resource_types type)
{
- return x_get_arg (FRAME_X_DISPLAY_INFO (f),
+ return x_get_arg (FRAME_DISPLAY_INFO (f),
alist, param, attribute, class, type);
}
{
Lisp_Object value;
- value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
+ value = x_get_arg (FRAME_DISPLAY_INFO (f), alist, param,
attribute, class, type);
if (! NILP (value) && ! EQ (value, Qunbound))
store_frame_param (f, param, value);
tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
if (EQ (tem, Qunbound))
tem = deflt;
- x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
+ x_set_frame_parameters (f, list1 (Fcons (prop, tem)));
return tem;
}
{
int mask = NoValue;
char *strind;
- unsigned long int tempWidth, tempHeight;
+ unsigned long tempWidth, tempHeight;
long int tempX, tempY;
char *nextCharacter;
Lisp_Object element;
if (x >= 0 && (geometry & XNegative))
- element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
+ element = list3 (Qleft, Qminus, make_number (-x));
else if (x < 0 && ! (geometry & XNegative))
- element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
+ element = list3 (Qleft, Qplus, make_number (x));
else
element = Fcons (Qleft, make_number (x));
result = Fcons (element, result);
Lisp_Object element;
if (y >= 0 && (geometry & YNegative))
- element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
+ element = list3 (Qtop, Qminus, make_number (-y));
else if (y < 0 && ! (geometry & YNegative))
- element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
+ element = list3 (Qtop, Qplus, make_number (y));
else
element = Fcons (Qtop, make_number (y));
result = Fcons (element, result);
#define DEFAULT_ROWS 35
#define DEFAULT_COLS 80
-int
-x_figure_window_size (struct frame *f, Lisp_Object parms, int toolbar_p)
+long
+x_figure_window_size (struct frame *f, Lisp_Object parms, bool toolbar_p)
{
register Lisp_Object tem0, tem1, tem2;
long window_prompting = 0;
- Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
/* Default values if we fall through.
Actually, if that happens we should get
window manager prompting. */
+ SET_FRAME_WIDTH (f, DEFAULT_COLS * FRAME_COLUMN_WIDTH (f));
SET_FRAME_COLS (f, DEFAULT_COLS);
+ SET_FRAME_HEIGHT (f, DEFAULT_ROWS * FRAME_LINE_HEIGHT (f));
FRAME_LINES (f) = DEFAULT_ROWS;
+
/* Window managers expect that if program-specified
positions are not (0,0), they're intentional, not defaults. */
f->top_pos = 0;
f->left_pos = 0;
- /* Ensure that old new_text_cols and new_text_lines will not override the
+ /* Ensure that old new_width and new_height will not override the
values set here. */
/* ++KFS: This was specific to W32, but seems ok for all platforms */
- f->new_text_cols = f->new_text_lines = 0;
+ f->new_width = f->new_height = f->new_pixelwise = 0;
tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
change the frame size. This is done so that users can create
tall Emacs frames without having to guess how tall the tool-bar
will get. */
- if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
+ if (toolbar_p && FRAME_TOOL_BAR_HEIGHT (f))
{
int margin, relief, bar_height;
else
margin = 0;
+ /* PXW: We should be able to not round here. */
bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
}
compute_fringe_widths (f, 0);
- FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
- FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
+ SET_FRAME_WIDTH (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f));
+ SET_FRAME_HEIGHT(f, FRAME_LINES (f) * FRAME_LINE_HEIGHT (f));
tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
}
+
+\f
+/***********************************************************************
+ Multimonitor data
+ ***********************************************************************/
+
+#ifdef HAVE_WINDOW_SYSTEM
+
+# if (defined HAVE_NS \
+ || (!defined USE_GTK && (defined HAVE_XINERAMA || defined HAVE_XRANDR)))
+void
+free_monitors (struct MonitorInfo *monitors, int n_monitors)
+{
+ int i;
+ for (i = 0; i < n_monitors; ++i)
+ xfree (monitors[i].name);
+ xfree (monitors);
+}
+# endif
+
+Lisp_Object
+make_monitor_attribute_list (struct MonitorInfo *monitors,
+ int n_monitors,
+ int primary_monitor,
+ Lisp_Object monitor_frames,
+ const char *source)
+{
+ Lisp_Object attributes_list = Qnil;
+ Lisp_Object primary_monitor_attributes = Qnil;
+ int i;
+
+ for (i = 0; i < n_monitors; ++i)
+ {
+ Lisp_Object geometry, workarea, attributes = Qnil;
+ struct MonitorInfo *mi = &monitors[i];
+
+ if (mi->geom.width == 0) continue;
+
+ workarea = list4i (mi->work.x, mi->work.y,
+ mi->work.width, mi->work.height);
+ geometry = list4i (mi->geom.x, mi->geom.y,
+ mi->geom.width, mi->geom.height);
+ attributes = Fcons (Fcons (Qsource, build_string (source)),
+ attributes);
+ attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
+ attributes);
+ attributes = Fcons (Fcons (Qmm_size,
+ list2i (mi->mm_width, mi->mm_height)),
+ attributes);
+ attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
+ attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
+ if (mi->name)
+ attributes = Fcons (Fcons (Qname, make_string (mi->name,
+ strlen (mi->name))),
+ attributes);
+
+ if (i == primary_monitor)
+ primary_monitor_attributes = attributes;
+ else
+ attributes_list = Fcons (attributes, attributes_list);
+ }
+
+ if (!NILP (primary_monitor_attributes))
+ attributes_list = Fcons (primary_monitor_attributes, attributes_list);
+ return attributes_list;
+}
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
\f
/***********************************************************************
Initialization
DEFSYM (Qx_frame_parameter, "x-frame-parameter");
DEFSYM (Qterminal, "terminal");
- DEFSYM (Qterminal_live_p, "terminal-live-p");
+
+ DEFSYM (Qgeometry, "geometry");
+ DEFSYM (Qworkarea, "workarea");
+ DEFSYM (Qmm_size, "mm-size");
+ DEFSYM (Qframes, "frames");
+ DEFSYM (Qsource, "source");
#ifdef HAVE_NS
DEFSYM (Qns_parse_geometry, "ns-parse-geometry");
The pointer becomes visible again when the mouse is moved. */);
Vmake_pointer_invisible = Qt;
+ DEFVAR_LISP ("focus-in-hook", Vfocus_in_hook,
+ doc: /* Normal hook run when a frame gains input focus. */);
+ Vfocus_in_hook = Qnil;
+ DEFSYM (Qfocus_in_hook, "focus-in-hook");
+
+ DEFVAR_LISP ("focus-out-hook", Vfocus_out_hook,
+ doc: /* Normal hook run when a frame loses input focus. */);
+ Vfocus_out_hook = Qnil;
+ DEFSYM (Qfocus_out_hook, "focus-out-hook");
+
DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
doc: /* Functions run before deleting a frame.
The functions are run with one arg, the frame to be deleted.
automatically. See also `mouse-autoselect-window'. */);
focus_follows_mouse = 0;
+ DEFVAR_BOOL ("frame-resize-pixelwise", frame_resize_pixelwise,
+ doc: /* Non-nil means frames are resized pixelwise.
+If this is nil, resizing a frame will round sizes to the frame's
+current values of `frame-char-height' and `frame-char-width'. */);
+ frame_resize_pixelwise = 0;
+
staticpro (&Vframe_list);
defsubr (&Sframep);
defsubr (&Sframe_list);
defsubr (&Snext_frame);
defsubr (&Sprevious_frame);
+ defsubr (&Slast_nonminibuf_frame);
defsubr (&Sdelete_frame);
defsubr (&Smouse_position);
defsubr (&Smouse_pixel_position);
defsubr (&Svisible_frame_list);
defsubr (&Sraise_frame);
defsubr (&Slower_frame);
+ defsubr (&Sx_focus_frame);
defsubr (&Sredirect_frame_focus);
defsubr (&Sframe_focus);
defsubr (&Sframe_parameters);
defsubr (&Sframe_char_width);
defsubr (&Sframe_pixel_height);
defsubr (&Sframe_pixel_width);
+ defsubr (&Sframe_text_cols);
+ defsubr (&Sframe_text_lines);
+ defsubr (&Sframe_total_cols);
+ defsubr (&Sframe_text_width);
+ defsubr (&Sframe_text_height);
+ defsubr (&Sscroll_bar_width);
+ defsubr (&Sfringe_width);
+ defsubr (&Sborder_width);
+ defsubr (&Sright_divider_width);
+ defsubr (&Sbottom_divider_width);
defsubr (&Stool_bar_pixel_width);
defsubr (&Sset_frame_height);
defsubr (&Sset_frame_width);