X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/cfbf790d80eaa399afceecd9a6c3e2e76bca59b0..d57f4dde80447f0fcdb1c31df7f0657fd2eea369:/src/frame.c
diff --git a/src/frame.c b/src/frame.c
index 0fa821682f..14e8fabd14 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -19,8 +19,6 @@ along with GNU Emacs. If not, see . */
#include
-#define FRAME_INLINE EXTERN_INLINE
-
#include
#include
#include
@@ -69,14 +67,12 @@ Lisp_Object Qnoelisp;
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;
@@ -115,6 +111,21 @@ Lisp_Object Qface_set_after_frame_default;
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
@@ -149,25 +160,55 @@ decode_any_frame (register Lisp_Object frame)
return XFRAME (frame);
}
+bool
+window_system_available (struct frame *f)
+{
+ if (f)
+ return FRAME_WINDOW_P (f) || FRAME_MSDOS_P (f);
+ else
+#ifdef HAVE_WINDOW_SYSTEM
+ return x_display_list != NULL;
+#else
+ return 0;
+#endif
+}
+
+struct frame *
+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;
+}
+
+void
+check_window_system (struct frame *f)
+{
+ if (!window_system_available (f))
+ error (f ? "Window system frame should be used"
+ : "Window system is not in use or not initialized");
+}
+
static void
set_menu_bar_lines_1 (Lisp_Object window, int n)
{
struct window *w = XWINDOW (window);
- w->last_modified = 0;
- wset_top_line (w, make_number (XFASTINT (w->top_line) + n));
- wset_total_lines (w, make_number (XFASTINT (w->total_lines) - n));
+ w->top_line += n;
+ w->total_lines -= n;
/* Handle just the top child in a vertical split. */
- if (!NILP (w->vchild))
- set_menu_bar_lines_1 (w->vchild, n);
-
- /* Adjust all children in a horizontal split. */
- for (window = w->hchild; !NILP (window); window = w->next)
- {
- w = XWINDOW (window);
- set_menu_bar_lines_1 (window, n);
- }
+ if (WINDOW_VERTICAL_COMBINATION_P (w))
+ set_menu_bar_lines_1 (w->contents, n);
+ else if (WINDOW_HORIZONTAL_COMBINATION_P (w))
+ /* Adjust all children in a horizontal split. */
+ for (window = w->contents; !NILP (window); window = w->next)
+ {
+ w = XWINDOW (window);
+ set_menu_bar_lines_1 (window, n);
+ }
}
void
@@ -194,7 +235,7 @@ set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
FRAME_WINDOW_SIZES_CHANGED (f) = 1;
FRAME_MENU_BAR_LINES (f) = nlines;
set_menu_bar_lines_1 (f->root_window, nlines - olines);
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
}
}
@@ -278,7 +319,7 @@ predicates which report frame's specific UI-related capabilities. */)
}
struct frame *
-make_frame (int mini_p)
+make_frame (bool mini_p)
{
Lisp_Object frame;
register struct frame *f;
@@ -298,7 +339,6 @@ make_frame (int mini_p)
initialize enum members explicitly even if their values are zero. */
f->wants_modeline = 1;
f->garbaged = 1;
- f->has_minibuffer = mini_p;
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 */
@@ -332,14 +372,14 @@ make_frame (int mini_p)
SET_FRAME_COLS (f, 10);
FRAME_LINES (f) = 10;
- wset_total_cols (XWINDOW (root_window), make_number (10));
- wset_total_lines (XWINDOW (root_window), make_number (mini_p ? 9 : 10));
+ XWINDOW (root_window)->total_cols = 10;
+ XWINDOW (root_window)->total_lines = mini_p ? 9 : 10;
if (mini_p)
{
- wset_total_cols (XWINDOW (mini_window), make_number (10));
- wset_top_line (XWINDOW (mini_window), make_number (9));
- wset_total_lines (XWINDOW (mini_window), make_number (1));
+ XWINDOW (mini_window)->total_cols = 10;
+ XWINDOW (mini_window)->top_line = 9;
+ XWINDOW (mini_window)->total_lines = 1;
}
/* Choose a buffer for the frame's root window. */
@@ -357,7 +397,7 @@ make_frame (int mini_p)
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)
@@ -421,7 +461,7 @@ make_frame_without_minibuffer (register Lisp_Object mini_window, KBOARD *kb, Lis
/* Make the chosen minibuffer window display the proper minibuffer,
unless it is already showing a minibuffer. */
- if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
+ if (NILP (Fmemq (XWINDOW (mini_window)->contents, Vminibuffer_list)))
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
set_window_buffer (mini_window,
@@ -448,7 +488,6 @@ make_minibuffer_frame (void)
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
@@ -518,6 +557,8 @@ make_initial_frame (void)
if (!noninteractive)
init_frame_faces (f);
+ last_nonminibuf_frame = f;
+
return f;
}
@@ -662,24 +703,16 @@ affects all frames on the same terminal device. */)
? 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);
@@ -690,19 +723,16 @@ affects all frames on the same terminal device. */)
change_frame_size (f, height, width, 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. */
@@ -803,10 +833,18 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
{
- if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
- /* Mark previously displayed frame as now obscured. */
- SET_FRAME_VISIBLE (XFRAME (FRAME_TTY (XFRAME (frame))->top_frame), 2);
- SET_FRAME_VISIBLE (XFRAME (frame), 1);
+ Lisp_Object top_frame = FRAME_TTY (XFRAME (frame))->top_frame;
+
+ /* Don't mark the frame garbaged and/or obscured if we are
+ switching to the frame that is already the top frame of that
+ TTY. */
+ if (!EQ (frame, top_frame))
+ {
+ if (FRAMEP (top_frame))
+ /* Mark previously displayed frame as now obscured. */
+ SET_FRAME_VISIBLE (XFRAME (top_frame), 2);
+ SET_FRAME_VISIBLE (XFRAME (frame), 1);
+ }
FRAME_TTY (XFRAME (frame))->top_frame = frame;
}
@@ -847,6 +885,26 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
return do_switch_frame (frame, 1, 0, norecord);
}
+DEFUN ("handle-focus-in", Fhandle_focus_in, Shandle_focus_in, 1, 1, "e",
+ doc: /* Handle a focus-in event.
+Focus in events are usually bound to this function.
+Focus in events occur when a frame has focus, but a switch-frame event
+is not generated.
+This function checks if blink-cursor timers should be turned on again. */)
+ (Lisp_Object event)
+{
+ return call0 (intern ("blink-cursor-check"));
+}
+
+DEFUN ("handle-focus-out", Fhandle_focus_out, Shandle_focus_out, 1, 1, "e",
+ doc: /* Handle a focus-out event.
+Focus out events are usually bound to this function.
+Focus out events occur when no frame has focus.
+This function checks if blink-cursor timers should be turned off. */)
+ (Lisp_Object event)
+{
+ return call0 (intern ("blink-cursor-suspend"));
+}
DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
doc: /* Handle a switch-frame event EVENT.
@@ -862,6 +920,7 @@ to that frame. */)
/* Preserve prefix arg that the command loop just cleared. */
kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
Frun_hooks (1, &Qmouse_leave_buffer_hook);
+ Fhandle_focus_in (event); // switch-frame implies a focus in.
return do_switch_frame (event, 0, 0, Qnil);
}
@@ -889,7 +948,7 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
same tty (for tty frames) or among frames which uses FRAME's keyboard.
If MINIBUF is nil, do not consider minibuffer-only candidate.
- If MINIBUF is `visible', do not consider an invisible candidate.
+ If MINIBUF is `visible', do not consider an invisible candidate.
If MINIBUF is a window, consider only its own frame and candidate now
using that window as the minibuffer.
If MINIBUF is 0, consider candidate if it is visible or iconified.
@@ -1030,13 +1089,26 @@ Otherwise, include all frames. */)
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;
+}
/* 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;
@@ -1047,7 +1119,7 @@ other_visible_frames (FRAME_PTR f)
/* 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
@@ -1062,6 +1134,52 @@ other_visible_frames (FRAME_PTR f)
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
@@ -1070,7 +1188,7 @@ Lisp_Object
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;
@@ -1096,10 +1214,14 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
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'. */
@@ -1141,14 +1263,22 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
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))
@@ -1184,19 +1314,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
}
/* 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)->buffer, 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))
@@ -1253,13 +1371,15 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
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.) */
@@ -1406,7 +1526,7 @@ passing the normal return value to that function as an argument,
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;
@@ -1452,7 +1572,7 @@ to read the mouse position, it returns the selected frame for FRAME
and nil for X and Y. */)
(void)
{
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object lispy_dummy;
Lisp_Object x, y;
@@ -1593,17 +1713,13 @@ make_frame_visible_1 (Lisp_Object window)
{
struct window *w;
- for (;!NILP (window); window = w->next)
+ for (; !NILP (window); window = w->next)
{
w = XWINDOW (window);
-
- if (!NILP (w->buffer))
- bset_display_time (XBUFFER (w->buffer), Fcurrent_time ());
-
- if (!NILP (w->vchild))
- make_frame_visible_1 (w->vchild);
- if (!NILP (w->hchild))
- make_frame_visible_1 (w->hchild);
+ if (WINDOWP (w->contents))
+ make_frame_visible_1 (w->contents);
+ else
+ bset_display_time (XBUFFER (w->contents), Fcurrent_time ());
}
}
@@ -1627,16 +1743,8 @@ displayed in the terminal. */)
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)->buffer, 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
@@ -1659,15 +1767,7 @@ If omitted, FRAME defaults to the currently selected frame. */)
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)->buffer, 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
@@ -1814,12 +1914,23 @@ See `redirect-frame-focus'. */)
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;
+}
/* Return the value of frame parameter PROP in frame FRAME. */
#ifdef HAVE_WINDOW_SYSTEM
-#if !HAVE_NS
+#if !HAVE_NS && !defined (WINDOWSNT)
static
#endif
Lisp_Object
@@ -2120,7 +2231,7 @@ If FRAME is nil, describe the currently selected frame. */)
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))
@@ -2192,7 +2303,9 @@ use is not recommended. Explicitly check for a frame-parameter instead. */)
(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
@@ -2217,12 +2330,11 @@ use is not recommended. Explicitly check for a frame-parameter instead. */)
/* 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++;
@@ -2303,7 +2415,7 @@ to `frame-height'). */)
#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));
@@ -2320,7 +2432,7 @@ If FRAME is omitted or nil, the selected frame is used. */)
#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));
@@ -2345,8 +2457,9 @@ is used. */)
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. */)
+If FRAME is nil, the selected frame is used. 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)
{
register struct frame *f = decode_live_frame (frame);
@@ -2369,8 +2482,9 @@ but that the idea of the actual height of the frame should not be changed. */)
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. */)
+If FRAME is nil, the selected frame is used. 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)
{
register struct frame *f = decode_live_frame (frame);
@@ -2392,15 +2506,14 @@ but that the idea of the actual width of the frame should not be changed. */)
}
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. */)
+ doc: /* Sets size of FRAME to COLS by ROWS, measured in characters.
+If FRAME is nil, the selected frame is used. */)
(Lisp_Object frame, Lisp_Object cols, Lisp_Object rows)
{
- 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);
/* I think this should be done with a hook. */
#ifdef HAVE_WINDOW_SYSTEM
@@ -2422,17 +2535,16 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
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
@@ -2510,7 +2622,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int
{
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;
@@ -2552,7 +2664,7 @@ x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int
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;
@@ -2571,9 +2683,9 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
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;
@@ -2695,7 +2807,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
{
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);
}
@@ -2703,7 +2815,7 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
{
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);
}
@@ -2809,10 +2921,11 @@ x_set_frame_parameters (FRAME_PTR f, Lisp_Object alist)
/* 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;
@@ -2838,13 +2951,13 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
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));
@@ -2884,12 +2997,12 @@ x_report_frame_params (struct frame *f, Lisp_Object *alistptr)
(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);
@@ -2928,6 +3041,15 @@ x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
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))
@@ -3260,9 +3382,6 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
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;
if (FRAME_X_WINDOW (f))
@@ -3275,22 +3394,6 @@ x_set_scroll_bar_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
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)
{
@@ -3315,16 +3418,15 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
else if (FLOATP (item))
{
alpha = XFLOAT_DATA (item);
- if (alpha < 0.0 || 1.0 < alpha)
+ if (! (0 <= alpha && alpha <= 1.0))
args_out_of_range (make_float (0.0), make_float (1.0));
}
else if (INTEGERP (item))
{
EMACS_INT ialpha = XINT (item);
- if (ialpha < 0 || 100 < ialpha)
+ if (! (0 <= ialpha && alpha <= 100))
args_out_of_range (make_number (0), make_number (100));
- else
- alpha = ialpha / 100.0;
+ alpha = ialpha / 100.0;
}
else
wrong_type_argument (Qnumberp, item);
@@ -3343,7 +3445,33 @@ x_set_alpha (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
return;
}
-
+#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.
@@ -3415,11 +3543,6 @@ validate_x_resource_name (void)
}
}
-
-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. */
@@ -3478,7 +3601,7 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
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;
@@ -3495,11 +3618,10 @@ The optional arguments COMPONENT and SUBCLASS add to the key and the
class, respectively. You must specify both of them or neither.
If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
and the class is `Emacs.CLASS.SUBCLASS'. */)
- (Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
+ (Lisp_Object attribute, Lisp_Object class, Lisp_Object component,
+ Lisp_Object subclass)
{
-#ifdef HAVE_X_WINDOWS
- check_x ();
-#endif
+ check_window_system (NULL);
return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
attribute, class, component, subclass);
@@ -3508,7 +3630,9 @@ and the class is `Emacs.CLASS.SUBCLASS'. */)
/* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
Lisp_Object
-display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
+display_x_get_resource (Display_Info *dpyinfo, Lisp_Object attribute,
+ Lisp_Object class, Lisp_Object component,
+ Lisp_Object subclass)
{
return xrdb_get_resource (dpyinfo->xrdb,
attribute, class, component, subclass);
@@ -3533,7 +3657,7 @@ x_get_resource_string (const char *attribute, const char *class)
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;
@@ -3655,7 +3779,7 @@ x_frame_get_arg (struct frame *f, Lisp_Object alist, Lisp_Object param,
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);
}
@@ -3669,7 +3793,7 @@ x_frame_get_and_record_arg (struct frame *f, Lisp_Object alist,
{
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);
@@ -3694,7 +3818,7 @@ x_default_parameter (struct frame *f, Lisp_Object alist, Lisp_Object prop,
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;
}
@@ -3720,7 +3844,7 @@ XParseGeometry (char *string,
{
int mask = NoValue;
char *strind;
- unsigned long int tempWidth, tempHeight;
+ unsigned long tempWidth, tempHeight;
long int tempX, tempY;
char *nextCharacter;
@@ -3826,9 +3950,9 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
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);
@@ -3839,9 +3963,9 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
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);
@@ -3868,12 +3992,12 @@ On Nextstep, this just calls `ns-parse-geometry'. */)
#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
@@ -4094,6 +4218,75 @@ selected frame. This is useful when `make-pointer-invisible' is set. */)
return decode_any_frame (frame)->pointer_invisible ? Qnil : Qt;
}
+
+
+/***********************************************************************
+ 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 */
+
/***********************************************************************
Initialization
@@ -4150,7 +4343,12 @@ syms_of_frame (void)
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");
@@ -4328,11 +4526,14 @@ automatically. See also `mouse-autoselect-window'. */);
defsubr (&Swindow_system);
defsubr (&Smake_terminal_frame);
defsubr (&Shandle_switch_frame);
+ defsubr (&Shandle_focus_in);
+ defsubr (&Shandle_focus_out);
defsubr (&Sselect_frame);
defsubr (&Sselected_frame);
defsubr (&Sframe_list);
defsubr (&Snext_frame);
defsubr (&Sprevious_frame);
+ defsubr (&Slast_nonminibuf_frame);
defsubr (&Sdelete_frame);
defsubr (&Smouse_position);
defsubr (&Smouse_pixel_position);
@@ -4349,6 +4550,7 @@ automatically. See also `mouse-autoselect-window'. */);
defsubr (&Svisible_frame_list);
defsubr (&Sraise_frame);
defsubr (&Slower_frame);
+ defsubr (&Sx_focus_frame);
defsubr (&Sredirect_frame_focus);
defsubr (&Sframe_focus);
defsubr (&Sframe_parameters);