/* Generic frame functions.
- Copyright (C) 1989, 1992 Free Software Foundation.
+ Copyright (C) 1993, 1994 Free Software Foundation.
This file is part of GNU Emacs.
along with GNU Emacs; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-#include <stdio.h>
+#include <config.h>
-#include "config.h"
+#include <stdio.h>
#include "lisp.h"
#include "frame.h"
+#include "termhooks.h"
+#include "window.h"
#ifdef MULTI_FRAME
#include "buffer.h"
-#include "window.h"
-#include "termhooks.h"
/* These help us bind and responding to switch-frame events. */
#include "commands.h"
/*&&& symbols declared here &&&*/
Lisp_Object Qframep;
-Lisp_Object Qlive_frame_p;
+Lisp_Object Qframe_live_p;
Lisp_Object Qheight;
Lisp_Object Qicon;
Lisp_Object Qminibuffer;
Lisp_Object Qmodeline;
Lisp_Object Qname;
-Lisp_Object Qnone;
Lisp_Object Qonly;
Lisp_Object Qunsplittable;
+Lisp_Object Qmenu_bar_lines;
Lisp_Object Qwidth;
Lisp_Object Qx;
+Lisp_Object Qvisible;
extern Lisp_Object Vminibuffer_list;
extern Lisp_Object get_minibuffer ();
+extern Lisp_Object Fhandle_switch_frame ();
+extern Lisp_Object Fredirect_frame_focus ();
\f
DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
"Return non-nil if OBJECT is a frame.\n\
(object)
Lisp_Object object;
{
- if (XTYPE (object) != Lisp_Frame)
+ if (!FRAMEP (object))
return Qnil;
switch (XFRAME (object)->output_method)
{
}
}
-DEFUN ("live-frame-p", Flive_frame_p, Slive_frame_p, 1, 1, 0,
+DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
"Return non-nil if OBJECT is a frame which has not been deleted.\n\
Value is nil if OBJECT is not a live frame. If object is a live\n\
frame, the return value indicates what sort of output device it is\n\
f->current_glyphs = 0;
f->desired_glyphs = 0;
f->visible = 0;
+ f->async_visible = 0;
f->display.nothing = 0;
f->iconified = 0;
+ f->async_iconified = 0;
f->wants_modeline = 1;
f->auto_raise = 0;
f->auto_lower = 0;
f->no_split = 0;
f->garbaged = 0;
f->has_minibuffer = mini_p;
- f->focus_frame = frame;
+ f->focus_frame = Qnil;
f->explicit_name = 0;
-
+ f->can_have_scroll_bars = 0;
+ f->has_vertical_scroll_bars = 0;
f->param_alist = Qnil;
+ f->scroll_bars = Qnil;
+ f->condemned_scroll_bars = Qnil;
+ f->face_alist = Qnil;
+ f->menu_bar_items = Qnil;
+ f->menu_bar_vector = Qnil;
+ f->menu_bar_items_used = 0;
root_window = make_window ();
if (mini_p)
f->width = 10;
f->height = 10;
- XFASTINT (XWINDOW (root_window)->width) = 10;
- XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
+ XSETFASTINT (XWINDOW (root_window)->width, 10);
+ XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
if (mini_p)
{
- XFASTINT (XWINDOW (mini_window)->width) = 10;
- XFASTINT (XWINDOW (mini_window)->top) = 9;
- XFASTINT (XWINDOW (mini_window)->height) = 1;
+ XSETFASTINT (XWINDOW (mini_window)->width, 10);
+ XSETFASTINT (XWINDOW (mini_window)->top, 9);
+ XSETFASTINT (XWINDOW (mini_window)->height, 1);
}
/* Choose a buffer for the frame's root window. */
f->selected_window = root_window;
/* Make sure this window seems more recently used than
a newly-created, never-selected window. */
- XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
-
- Vframe_list = Fcons (frame, Vframe_list);
+ XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
return f;
}
/* Choose the minibuffer window to use. */
if (NILP (mini_window))
{
- if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
+ if (!FRAMEP (Vdefault_minibuffer_frame))
error ("default-minibuffer-frame must be set when creating minibufferless frames");
if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
error ("default-minibuffer-frame must be a live frame");
register Lisp_Object mini_window;
register Lisp_Object frame;
- XSET (frame, Lisp_Frame, f);
+ XSETFRAME (frame, f);
f->auto_raise = 0;
f->auto_lower = 0;
make_terminal_frame ()
{
register struct frame *f;
+ Lisp_Object frame;
Vframe_list = Qnil;
f = make_frame (1);
+
+ XSETFRAME (frame, f);
+ Vframe_list = Fcons (frame, Vframe_list);
+
f->name = build_string ("terminal");
- f->visible = 1;
+ FRAME_SET_VISIBLE (f, 1);
f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
- XSET (Vterminal_frame, Lisp_Frame, f);
+ XSETFRAME (Vterminal_frame, f);
return f;
}
\f
-DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
- "Select the frame FRAME. FRAME's selected window becomes \"the\"\n\
-selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
-focus on that frame.\n\
-\n\
-This function is interactive, and may be bound to the ``switch-frame''\n\
-event; when invoked this way, it switches to the frame named in the\n\
-event. When called from lisp, FRAME may be a ``switch-frame'' event;\n\
-if it is, select the frame named in the event.")
- (frame, no_enter)
+static Lisp_Object
+do_switch_frame (frame, no_enter, track)
Lisp_Object frame, no_enter;
+ int track;
{
/* If FRAME is a switch-frame event, extract the frame we should
switch to. */
&& CONSP (XCONS (frame)->cdr))
frame = XCONS (XCONS (frame)->cdr)->car;
- CHECK_LIVE_FRAME (frame, 0);
+ /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
+ a switch-frame event to arrive after a frame is no longer live,
+ especially when deleting the initial frame during startup. */
+ CHECK_FRAME (frame, 0);
+ if (! FRAME_LIVE_P (XFRAME (frame)))
+ return Qnil;
if (selected_frame == XFRAME (frame))
return frame;
- selected_frame = XFRAME (frame);
- if (! FRAME_MINIBUF_ONLY_P (selected_frame))
- last_nonminibuf_frame = selected_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
+ from a minibufferless frame to a surrogate minibuffer frame, we
+ can use `other-window' to switch between all the frames using
+ that minibuffer frame, and the focus redirection will follow us
+ around. */
+ if (track)
+ {
+ Lisp_Object tail;
- Fselect_window (XFRAME (frame)->selected_window);
+ for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
+ {
+ Lisp_Object focus;
+
+ if (!FRAMEP (XCONS (tail)->car))
+ abort ();
+ focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
+
+ if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
+ Fredirect_frame_focus (XCONS (tail)->car, frame);
+ }
+ }
+#else /* ! 0 */
+ /* Instead, apply it only to the frame we're pointing to. */
#ifdef HAVE_X_WINDOWS
-#ifdef MULTI_FRAME
- if (FRAME_X_P (XFRAME (frame))
- && NILP (no_enter))
+ if (track)
{
- Ffocus_frame (frame);
+ Lisp_Object focus, xfocus;
+
+ xfocus = x_get_focus_frame ();
+ if (FRAMEP (xfocus))
+ {
+ focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
+ if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
+ Fredirect_frame_focus (xfocus, frame);
+ }
}
-#endif
-#endif
+#endif /* HAVE_X_WINDOWS */
+#endif /* ! 0 */
+
+ selected_frame = XFRAME (frame);
+ if (! FRAME_MINIBUF_ONLY_P (selected_frame))
+ last_nonminibuf_frame = selected_frame;
+
+ Fselect_window (XFRAME (frame)->selected_window);
choose_minibuf_frame ();
+ /* We want to make sure that the next event generates a frame-switch
+ event to the appropriate frame. This seems kludgy to me, but
+ before you take it out, make sure that evaluating something like
+ (select-window (frame-root-window (new-frame))) doesn't end up
+ with your typing being interpreted in the new frame instead of
+ the one you're actually typing in. */
+ internal_last_event_frame = Qnil;
+
return frame;
}
+DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
+ "Select the frame FRAME.\n\
+Subsequent editing commands apply to its selected window.\n\
+The selection of FRAME lasts until the next time the user does\n\
+something to select a different frame, or until the next time this\n\
+function is called.")
+ (frame, no_enter)
+ Lisp_Object frame, no_enter;
+{
+ return do_switch_frame (frame, no_enter, 1);
+}
+
+
+DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
+ "Handle a switch-frame event EVENT.\n\
+Switch-frame events are usually bound to this function.\n\
+A switch-frame event tells Emacs that the window manager has requested\n\
+that the user's events be directed to the frame mentioned in the event.\n\
+This function selects the selected window of the frame of EVENT.\n\
+\n\
+If EVENT is frame object, handle it as if it were a switch-frame event\n\
+to that frame.")
+ (frame, no_enter)
+ Lisp_Object frame, no_enter;
+{
+ return do_switch_frame (frame, no_enter, 0);
+}
+
+
DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
"Return the frame that is now selected.")
()
{
Lisp_Object tem;
- XSET (tem, Lisp_Frame, selected_frame);
+ XSETFRAME (tem, selected_frame);
return tem;
}
-
+\f
DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
"Return the frame object that window WINDOW is on.")
(window)
return XWINDOW (window)->frame;
}
+DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
+ "Returns the topmost, leftmost window of FRAME.\n\
+If omitted, FRAME defaults to the currently selected frame.")
+ (frame)
+ Lisp_Object frame;
+{
+ Lisp_Object w;
+
+ if (NILP (frame))
+ w = selected_frame->root_window;
+ else
+ {
+ CHECK_LIVE_FRAME (frame, 0);
+ w = XFRAME (frame)->root_window;
+ }
+ while (NILP (XWINDOW (w)->buffer))
+ {
+ if (! NILP (XWINDOW (w)->hchild))
+ w = XWINDOW (w)->hchild;
+ else if (! NILP (XWINDOW (w)->vchild))
+ w = XWINDOW (w)->vchild;
+ else
+ abort ();
+ }
+ return w;
+}
+
DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
"Returns the root-window of FRAME.\n\
If omitted, FRAME defaults to the currently selected frame.")
Lisp_Object frame;
{
if (NILP (frame))
- XSET (frame, Lisp_Frame, selected_frame);
+ XSETFRAME (frame, selected_frame);
else
CHECK_LIVE_FRAME (frame, 0);
Lisp_Object frame;
{
if (NILP (frame))
- XSET (frame, Lisp_Frame, selected_frame);
+ XSETFRAME (frame, selected_frame);
else
CHECK_LIVE_FRAME (frame, 0);
return XFRAME (frame)->selected_window;
}
+DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
+ Sset_frame_selected_window, 2, 2, 0,
+ "Set the selected window of frame object FRAME to WINDOW.\n\
+If FRAME is nil, the selected frame is used.\n\
+If FRAME is the selected frame, this makes WINDOW the selected window.")
+ (frame, window)
+ Lisp_Object frame, window;
+{
+ if (NILP (frame))
+ XSETFRAME (frame, selected_frame);
+ else
+ CHECK_LIVE_FRAME (frame, 0);
+
+ CHECK_LIVE_WINDOW (window, 1);
+
+ if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
+ error ("In `set-frame-selected-window', WINDOW is not on FRAME");
+
+ if (XFRAME (frame) == selected_frame)
+ return Fselect_window (window);
+
+ return XFRAME (frame)->selected_window = window;
+}
+\f
DEFUN ("frame-list", Fframe_list, Sframe_list,
0, 0, 0,
"Return a list of all frames.")
return Fcopy_sequence (Vframe_list);
}
-#ifdef MULTI_FRAME
-
/* Return the next frame in the frame list after FRAME.
If MINIBUF is nil, exclude minibuffer-only frames.
- If MINIBUF is a window, include only frames using that window for
- their minibuffer.
- If MINIBUF is non-nil, and not a window, include all frames. */
+ If MINIBUF is a window, include only its own frame
+ and any frame now using that window as the minibuffer.
+ If MINIBUF is `visible', include all visible frames.
+ If MINIBUF is 0, include all visible and iconified frames.
+ Otherwise, include all frames. */
+
Lisp_Object
next_frame (frame, minibuf)
Lisp_Object frame;
if (! CONSP (Vframe_list))
abort ();
+ /* If this frame is dead, it won't be in Vframe_list, and we'll loop
+ forever. Forestall that. */
+ CHECK_LIVE_FRAME (frame, 0);
+
while (1)
for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
{
- Lisp_Object f = XCONS (tail)->car;
+ Lisp_Object f;
+ f = XCONS (tail)->car;
if (passed)
{
/* Decide whether this frame is eligible to be returned. */
if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
return f;
}
- else if (XTYPE (minibuf) == Lisp_Window)
+ else if (EQ (minibuf, Qvisible))
+ {
+ FRAME_SAMPLE_VISIBILITY (XFRAME (f));
+ if (FRAME_VISIBLE_P (XFRAME (f)))
+ return f;
+ }
+ else if (XFASTINT (minibuf) == 0)
+ {
+ FRAME_SAMPLE_VISIBILITY (XFRAME (f));
+ if (FRAME_VISIBLE_P (XFRAME (f))
+ || FRAME_ICONIFIED_P (XFRAME (f)))
+ return f;
+ }
+ else if (WINDOWP (minibuf))
{
- if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
+ if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
+ /* Check that F either is, or has forwarded its focus to,
+ MINIBUF's frame. */
+ && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
+ || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
+ FRAME_FOCUS_FRAME (XFRAME (f)))))
return f;
}
else
}
}
-#if 0
-/* Nobody seems to be using this code right now. */
-
/* Return the previous frame in the frame list before FRAME.
If MINIBUF is nil, exclude minibuffer-only frames.
- If MINIBUF is a window, include only frames using that window for
- their minibuffer.
- If MINIBUF is non-nil and not a window, include all frames. */
+ If MINIBUF is a window, include only its own frame
+ and any frame now using that window as the minibuffer.
+ If MINIBUF is `visible', include all visible frames.
+ If MINIBUF is 0, include all visible and iconified frames.
+ Otherwise, include all frames. */
+
Lisp_Object
prev_frame (frame, minibuf)
Lisp_Object frame;
prev = Qnil;
for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
{
- Lisp_Object f = XCONS (tail)->car;
+ Lisp_Object f;
- if (XTYPE (f) != Lisp_Frame)
+ f = XCONS (tail)->car;
+ if (!FRAMEP (f))
abort ();
if (EQ (frame, f) && !NILP (prev))
if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
prev = f;
}
- else if (XTYPE (minibuf) == Lisp_Window)
+ else if (WINDOWP (minibuf))
+ {
+ if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
+ /* Check that F either is, or has forwarded its focus to,
+ MINIBUF's frame. */
+ && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
+ || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
+ FRAME_FOCUS_FRAME (XFRAME (f)))))
+ prev = f;
+ }
+ else if (EQ (minibuf, Qvisible))
{
- if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
+ FRAME_SAMPLE_VISIBILITY (XFRAME (f));
+ if (FRAME_VISIBLE_P (XFRAME (f)))
+ prev = f;
+ }
+ else if (XFASTINT (minibuf) == 0)
+ {
+ FRAME_SAMPLE_VISIBILITY (XFRAME (f));
+ if (FRAME_VISIBLE_P (XFRAME (f))
+ || FRAME_ICONIFIED_P (XFRAME (f)))
prev = f;
}
else
acceptable frame in the list, return it. */
return prev;
}
-#endif
+
DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
"Return the next frame in the frame list after FRAME.\n\
-By default, skip minibuffer-only frames.
+By default, skip minibuffer-only frames.\n\
If omitted, FRAME defaults to the selected frame.\n\
-If optional argument MINIFRAME is non-nil, include minibuffer-only frames.\n\
-If MINIFRAME is a window, include only frames using that window for their\n\
-minibuffer.\n\
-If MINIFRAME is non-nil and not a window, include all frames.")
+If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
+If MINIBUF is a window, include only its own frame\n\
+and any frame now using that window as the minibuffer.\n\
+If MINIFRAME is `visible', include all visible frames.\n\
+If MINIBUF is 0, include all visible and iconified frames.\n\
+Otherwise, include all frames.")
(frame, miniframe)
Lisp_Object frame, miniframe;
{
Lisp_Object tail;
if (NILP (frame))
- XSET (frame, Lisp_Frame, selected_frame);
+ XSETFRAME (frame, selected_frame);
else
CHECK_LIVE_FRAME (frame, 0);
return next_frame (frame, miniframe);
}
-#endif /* MULTI_FRAME */
+
+DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
+ "Return the previous frame in the frame list before FRAME.\n\
+By default, skip minibuffer-only frames.\n\
+If omitted, FRAME defaults to the selected frame.\n\
+If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
+If MINIBUF is a window, include only its own frame\n\
+and any frame now using that window as the minibuffer.\n\
+If MINIFRAME is `visible', include all visible frames.\n\
+If MINIBUF is 0, include all visible and iconified frames.\n\
+Otherwise, include all frames.")
+ (frame, miniframe)
+ Lisp_Object frame, miniframe;
+{
+ Lisp_Object tail;
+
+ if (NILP (frame))
+ XSETFRAME (frame, selected_frame);
+ else
+ CHECK_LIVE_FRAME (frame, 0);
+
+ return prev_frame (frame, miniframe);
+}
\f
-DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
+/* 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.) */
+
+int
+other_visible_frames (f)
+ FRAME_PTR f;
+{
+ /* We know the selected frame is visible,
+ so if F is some other frame, it can't be the sole visible one. */
+ if (f == selected_frame)
+ {
+ Lisp_Object frames;
+ int count = 0;
+
+ for (frames = Vframe_list;
+ CONSP (frames);
+ frames = XCONS (frames)->cdr)
+ {
+ Lisp_Object this;
+
+ this = XCONS (frames)->car;
+ /* Verify that the frame's window still exists
+ and we can still talk to it. And note any recent change
+ in visibility. */
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (XFRAME (this)))
+ {
+ x_sync (this);
+ FRAME_SAMPLE_VISIBILITY (XFRAME (this));
+ }
+#endif
+
+ if (FRAME_VISIBLE_P (XFRAME (this))
+ || FRAME_ICONIFIED_P (XFRAME (this))
+ /* Allow deleting the terminal frame when at least
+ one X frame exists! */
+ || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
+ count++;
+ }
+ return count > 1;
+ }
+ return 1;
+}
+
+DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
"Delete FRAME, permanently eliminating it from use.\n\
If omitted, FRAME defaults to the selected frame.\n\
-A frame may not be deleted if its minibuffer is used by other frames.")
- (frame)
- Lisp_Object frame;
+A frame may not be deleted if its minibuffer is used by other frames.\n\
+Normally, you may not delete a frame if all other frames are invisible,\n\
+but if the second optional argument FORCE is non-nil, you may do so.")
+ (frame, force)
+ Lisp_Object frame, force;
{
struct frame *f;
- union display displ;
if (EQ (frame, Qnil))
{
f = selected_frame;
- XSET (frame, Lisp_Frame, f);
+ XSETFRAME (frame, f);
}
else
{
}
if (! FRAME_LIVE_P (f))
- return;
+ return Qnil;
- /* Are there any other frames besides this one? */
- if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
- error ("Attempt to delete the only frame");
+ if (NILP (force) && !other_visible_frames (f))
+ error ("Attempt to delete the sole visible or iconified frame");
/* Does this frame have a minibuffer, and is it the surrogate
minibuffer for any other frame? */
CONSP (frames);
frames = XCONS (frames)->cdr)
{
- Lisp_Object this = XCONS (frames)->car;
+ Lisp_Object this;
+ this = XCONS (frames)->car;
if (! EQ (this, frame)
&& EQ (frame,
- (WINDOW_FRAME
- (XWINDOW
- (FRAME_MINIBUF_WINDOW
- (XFRAME (this)))))))
+ WINDOW_FRAME (XWINDOW
+ (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
error ("Attempt to delete a surrogate minibuffer frame");
}
}
/* Don't let the frame remain selected. */
if (f == selected_frame)
- Fselect_frame (next_frame (frame, Qt), Qnil);
+ Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
/* Don't allow minibuf_window to remain on a deleted frame. */
if (EQ (f->minibuffer_window, minibuf_window))
minibuf_window = selected_frame->minibuffer_window;
}
- Vframe_list = Fdelq (frame, Vframe_list);
- f->visible = 0;
- displ = f->display;
- f->display.nothing = 0;
+ /* Clear any X selections for this frame. */
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (f))
+ x_clear_frame_selections (f);
+#endif
+
+ /* Mark all the windows that used to be on FRAME as deleted, and then
+ remove the reference to them. */
+ delete_all_subwindows (XWINDOW (f->root_window));
+ f->root_window = Qnil;
+ Vframe_list = Fdelq (frame, Vframe_list);
+ FRAME_SET_VISIBLE (f, 0);
+
+ if (FRAME_CURRENT_GLYPHS (f))
+ free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
+ if (FRAME_DESIRED_GLYPHS (f))
+ free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
+ if (FRAME_TEMP_GLYPHS (f))
+ free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
+ if (FRAME_INSERT_COST (f))
+ free (FRAME_INSERT_COST (f));
+ if (FRAME_DELETEN_COST (f))
+ free (FRAME_DELETEN_COST (f));
+ if (FRAME_INSERTN_COST (f))
+ free (FRAME_INSERTN_COST (f));
+ if (FRAME_DELETE_COST (f))
+ free (FRAME_DELETE_COST (f));
+
+ /* Since some events are handled at the interrupt level, we may get
+ an event for f at any time; if we zero out the frame's display
+ now, then we may trip up the event-handling code. Instead, we'll
+ promise that the display of the frame must be valid until we have
+ called the window-system-dependent frame destruction routine. */
+
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
- x_destroy_window (f, displ);
+ x_destroy_window (f);
#endif
+ f->display.nothing = 0;
+
/* If we've deleted the last_nonminibuf_frame, then try to find
another one. */
if (f == last_nonminibuf_frame)
Lisp_Object frames;
/* The last frame we saw with a minibuffer, minibuffer-only or not. */
- Lisp_Object frame_with_minibuf = Qnil;
+ Lisp_Object frame_with_minibuf;
+ frame_with_minibuf = Qnil;
for (frames = Vframe_list;
CONSP (frames);
frames = XCONS (frames)->cdr)
{
- Lisp_Object this = XCONS (frames)->car;
+ Lisp_Object this;
- if (XTYPE (this) != Lisp_Frame)
+ this = XCONS (frames)->car;
+ if (!FRAMEP (this))
abort ();
f = XFRAME (this);
DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
"Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
+The position is given in character cells, where (0, 0) is the\n\
+upper-left corner.\n\
If Emacs is running on a mouseless terminal or hasn't been programmed\n\
to read the mouse position, it returns the selected frame for FRAME\n\
and nil for X and Y.")
()
{
- Lisp_Object x, y, dummy;
FRAME_PTR f;
+ Lisp_Object lispy_dummy;
+ enum scroll_bar_part party_dummy;
+ Lisp_Object x, y;
+ int col, row;
+ unsigned long long_dummy;
+
+ f = selected_frame;
+ x = y = Qnil;
+ /* It's okay for the hook to refrain from storing anything. */
if (mouse_position_hook)
- (*mouse_position_hook) (&f, &x, &y, &dummy);
- else
+ (*mouse_position_hook) (&f,
+ &lispy_dummy, &party_dummy,
+ &x, &y,
+ &long_dummy);
+ if (! NILP (x))
{
- f = selected_frame;
- x = y = Qnil;
+ col = XINT (x);
+ row = XINT (y);
+ pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
+ XSETINT (x, col);
+ XSETINT (y, row);
}
+ XSETFRAME (lispy_dummy, f);
+ return Fcons (lispy_dummy, Fcons (x, y));
+}
- XSET (dummy, Lisp_Frame, f);
- return Fcons (dummy, Fcons (make_number (x), make_number (y)));
+DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
+ Smouse_pixel_position, 0, 0, 0,
+ "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
+The position is given in pixel units, where (0, 0) is the\n\
+upper-left corner.\n\
+If Emacs is running on a mouseless terminal or hasn't been programmed\n\
+to read the mouse position, it returns the selected frame for FRAME\n\
+and nil for X and Y.")
+ ()
+{
+ FRAME_PTR f;
+ Lisp_Object lispy_dummy;
+ enum scroll_bar_part party_dummy;
+ Lisp_Object x, y;
+ int col, row;
+ unsigned long long_dummy;
+
+ f = selected_frame;
+ x = y = Qnil;
+
+ /* It's okay for the hook to refrain from storing anything. */
+ if (mouse_position_hook)
+ (*mouse_position_hook) (&f,
+ &lispy_dummy, &party_dummy,
+ &x, &y,
+ &long_dummy);
+ XSETFRAME (lispy_dummy, f);
+ return Fcons (lispy_dummy, Fcons (x, y));
}
DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
- "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
-WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
+ "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
+WARNING: If you use this under X windows,\n\
+you should call `unfocus-frame' afterwards.")
(frame, x, y)
Lisp_Object frame, x, y;
{
CHECK_NUMBER (x, 2);
CHECK_NUMBER (y, 1);
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (XFRAME (frame)))
/* Warping the mouse will cause enternotify and focus events. */
return Qnil;
}
-\f
-#if 0
-/* ??? Can this be replaced with a Lisp function?
- It is used in minibuf.c. Can we get rid of that?
- Yes. All uses in minibuf.c are gone, and parallels to these
- functions have been defined in frame.el. */
-DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
- 0, 0, 0,
- "Return object describing current frame configuration.\n\
-The frame configuration is the current mouse position and selected frame.\n\
-This object can be given to `restore-frame-configuration'\n\
-to restore this frame configuration.")
- ()
-{
- Lisp_Object c, time;
-
- c = Fmake_vector (make_number(4), Qnil);
- XVECTOR (c)->contents[0] = Fselected_frame();
- if (mouse_position_hook)
- (*mouse_position_hook) (&XVECTOR (c)->contents[1]
- &XVECTOR (c)->contents[2],
- &XVECTOR (c)->contents[3],
- &time);
- return c;
-}
-
-DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
- Srestore_frame_configuration,
- 1, 1, 0,
- "Restores frame configuration CONFIGURATION.")
- (config)
- Lisp_Object config;
+DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
+ Sset_mouse_pixel_position, 3, 3, 0,
+ "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
+WARNING: If you use this under X windows,\n\
+you should call `unfocus-frame' afterwards.")
+ (frame, x, y)
+ Lisp_Object frame, x, y;
{
- Lisp_Object x_pos, y_pos, frame;
-
- CHECK_VECTOR (config, 0);
- if (XVECTOR (config)->size != 3)
- {
- error ("Wrong size vector passed to restore-frame-configuration");
- }
- frame = XVECTOR (config)->contents[0];
CHECK_LIVE_FRAME (frame, 0);
+ CHECK_NUMBER (x, 2);
+ CHECK_NUMBER (y, 1);
- Fselect_frame (frame, Qnil);
-
-#if 0
- /* This seems to interfere with the frame selection mechanism. jla */
- x_pos = XVECTOR (config)->contents[2];
- y_pos = XVECTOR (config)->contents[3];
- set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
+ /* I think this should be done with a hook. */
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (XFRAME (frame)))
+ /* Warping the mouse will cause enternotify and focus events. */
+ x_set_mouse_pixel_position (XFRAME (frame), x, y);
#endif
- return frame;
-}
-#endif
+ return Qnil;
+}
\f
DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
- 0, 1, 0,
+ 0, 1, "",
"Make the frame FRAME visible (assuming it is an X-window).\n\
-Also raises the frame so that nothing obscures it.\n\
If omitted, FRAME defaults to the currently selected frame.")
(frame)
Lisp_Object frame;
{
if (NILP (frame))
- XSET (frame, Lisp_Frame, selected_frame);
+ XSETFRAME (frame, selected_frame);
CHECK_LIVE_FRAME (frame, 0);
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (XFRAME (frame)))
- x_make_frame_visible (XFRAME (frame));
+ {
+ FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
+ x_make_frame_visible (XFRAME (frame));
+ }
#endif
+ /* Make menu bar update for the Buffers and Frams menus. */
+ windows_or_buffers_changed++;
+
return frame;
}
DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
- 0, 1, "",
+ 0, 2, "",
"Make the frame FRAME invisible (assuming it is an X-window).\n\
-If omitted, FRAME defaults to the currently selected frame.")
- (frame)
- Lisp_Object frame;
+If omitted, FRAME defaults to the currently selected frame.\n\
+Normally you may not make FRAME invisible if all other frames are invisible,\n\
+but if the second optional argument FORCE is non-nil, you may do so.")
+ (frame, force)
+ Lisp_Object frame, force;
{
if (NILP (frame))
- XSET (frame, Lisp_Frame, selected_frame);
+ XSETFRAME (frame, selected_frame);
CHECK_LIVE_FRAME (frame, 0);
+ if (NILP (force) && !other_visible_frames (XFRAME (frame)))
+ error ("Attempt to make invisible the sole visible or iconified frame");
+
+#if 0 /* This isn't logically necessary, and it can do GC. */
+ /* Don't let the frame remain selected. */
+ if (XFRAME (frame) == selected_frame)
+ Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+#endif
+
+ /* Don't allow minibuf_window to remain on a deleted frame. */
+ if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
+ {
+ Fset_window_buffer (selected_frame->minibuffer_window,
+ XWINDOW (minibuf_window)->buffer);
+ minibuf_window = selected_frame->minibuffer_window;
+ }
+
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (XFRAME (frame)))
x_make_frame_invisible (XFRAME (frame));
#endif
+ /* Make menu bar update for the Buffers and Frams menus. */
+ windows_or_buffers_changed++;
+
return Qnil;
}
Lisp_Object frame;
{
if (NILP (frame))
- XSET (frame, Lisp_Frame, selected_frame);
+ XSETFRAME (frame, selected_frame);
CHECK_LIVE_FRAME (frame, 0);
+#if 0 /* This isn't logically necessary, and it can do GC. */
+ /* Don't let the frame remain selected. */
+ if (XFRAME (frame) == selected_frame)
+ Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
+#endif
+
+ /* Don't allow minibuf_window to remain on a deleted frame. */
+ if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
+ {
+ Fset_window_buffer (selected_frame->minibuffer_window,
+ XWINDOW (minibuf_window)->buffer);
+ minibuf_window = selected_frame->minibuffer_window;
+ }
+
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (XFRAME (frame)))
x_iconify_frame (XFRAME (frame));
#endif
+ /* Make menu bar update for the Buffers and Frams menus. */
+ windows_or_buffers_changed++;
+
return Qnil;
}
{
CHECK_LIVE_FRAME (frame, 0);
- if (XFRAME (frame)->visible)
+ FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
+
+ if (FRAME_VISIBLE_P (XFRAME (frame)))
return Qt;
- if (XFRAME (frame)->iconified)
+ if (FRAME_ICONIFIED_P (XFRAME (frame)))
return Qicon;
return Qnil;
}
for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
{
frame = XCONS (tail)->car;
- if (XTYPE (frame) != Lisp_Frame)
+ if (!FRAMEP (frame))
continue;
f = XFRAME (frame);
- if (f->visible)
+ if (FRAME_VISIBLE_P (f))
value = Fcons (frame, value);
}
return value;
}
+DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
+ "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
+If FRAME is invisible, make it visible.\n\
+If Emacs is displaying on an ordinary terminal or some other device which\n\
+doesn't support multiple overlapping frames, this function does nothing.")
+ (frame)
+ Lisp_Object frame;
+{
+ CHECK_LIVE_FRAME (frame, 0);
+
+ /* Do like the documentation says. */
+ Fmake_frame_visible (frame);
+
+ if (frame_raise_lower_hook)
+ (*frame_raise_lower_hook) (XFRAME (frame), 1);
+
+ return Qnil;
+}
+
+/* Should we have a corresponding function called Flower_Power? */
+DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
+ "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
+If Emacs is displaying on an ordinary terminal or some other device which\n\
+doesn't support multiple overlapping frames, this function does nothing.")
+ (frame)
+ Lisp_Object frame;
+{
+ CHECK_LIVE_FRAME (frame, 0);
+
+ if (frame_raise_lower_hook)
+ (*frame_raise_lower_hook) (XFRAME (frame), 0);
+
+ return Qnil;
+}
+
\f
DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
1, 2, 0,
"Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
-This means that, after reading a keystroke typed at FRAME,\n\
-`last-event-frame' will be FOCUS-FRAME.\n\
+In other words, switch-frame events caused by events in FRAME will\n\
+request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
+FOCUS-FRAME after reading an event typed at FRAME.\n\
\n\
-If FOCUS-FRAME is omitted or eq to FRAME, any existing redirection is\n\
+If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
cancelled, and the frame again receives its own keystrokes.\n\
\n\
-The redirection lasts until the next call to `redirect-frame-focus'\n\
-or `select-frame'.\n\
+Focus redirection is useful for temporarily redirecting keystrokes to\n\
+a surrogate minibuffer frame when a frame doesn't have its own\n\
+minibuffer window.\n\
+\n\
+A frame's focus redirection can be changed by select-frame. If frame\n\
+FOO is selected, and then a different frame BAR is selected, any\n\
+frames redirecting their focus to FOO are shifted to redirect their\n\
+focus to BAR. This allows focus redirection to work properly when the\n\
+user switches from one frame to another using `select-window'.\n\
\n\
-This is useful for temporarily redirecting keystrokes to the minibuffer\n\
-window when a frame doesn't have its own minibuffer.")
+This means that a frame whose focus is redirected to itself is treated\n\
+differently from a frame whose focus is redirected to nil; the former\n\
+is affected by select-frame, while the latter is not.\n\
+\n\
+The redirection lasts until `redirect-frame-focus' is called to change it.")
(frame, focus_frame)
Lisp_Object frame, focus_frame;
{
- CHECK_LIVE_FRAME (frame, 0);
+ /* Note that we don't check for a live frame here. It's reasonable
+ to redirect the focus of a frame you're about to delete, if you
+ know what other frame should receive those keystrokes. */
+ CHECK_FRAME (frame, 0);
- if (NILP (focus_frame))
- focus_frame = frame;
- else
+ if (! NILP (focus_frame))
CHECK_LIVE_FRAME (focus_frame, 1);
XFRAME (frame)->focus_frame = focus_frame;
+ /* I think this should be done with a hook. */
+#ifdef HAVE_X_WINDOWS
+ if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
+ && FRAME_X_P (XFRAME (focus_frame)))
+ Ffocus_frame (focus_frame);
+#endif
+
if (frame_rehighlight_hook)
(*frame_rehighlight_hook) ();
DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
"Return the frame to which FRAME's keystrokes are currently being sent.\n\
+This returns nil if FRAME's focus is not redirected.\n\
See `redirect-frame-focus'.")
(frame)
Lisp_Object frame;
{
CHECK_LIVE_FRAME (frame, 0);
+
return FRAME_FOCUS_FRAME (XFRAME (frame));
}
else
Fsetcdr (tem, val);
- if (EQ (prop, Qminibuffer)
- && XTYPE (val) == Lisp_Window)
+ if (EQ (prop, Qminibuffer) && WINDOWP (val))
{
if (! MINI_WINDOW_P (XWINDOW (val)))
error ("Surrogate minibuffer windows must be minibuffer windows.");
if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
- error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
+ error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
/* Install the chosen minibuffer window, with proper buffer. */
f->minibuffer_window = val;
Lisp_Object frame;
{
Lisp_Object alist;
- struct frame *f;
+ FRAME_PTR f;
if (EQ (frame, Qnil))
f = selected_frame;
f = XFRAME (frame);
}
- if (f->display.nothing == 0)
+ if (!FRAME_LIVE_P (f))
return Qnil;
alist = Fcopy_alist (f->param_alist);
store_in_alist (&alist, Qname, f->name);
- store_in_alist (&alist, Qheight, make_number (f->height));
- store_in_alist (&alist, Qwidth, make_number (f->width));
- store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
+ store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
+ store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
+ store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
store_in_alist (&alist, Qminibuffer,
- (! FRAME_HAS_MINIBUF_P (f) ? Qnone
- : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
- : FRAME_MINIBUF_WINDOW (f))));
- store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
+ (! FRAME_HAS_MINIBUF_P (f) ? Qnil
+ : FRAME_MINIBUF_ONLY_P (f) ? Qonly
+ : FRAME_MINIBUF_WINDOW (f)));
+ store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
x_report_frame_params (f, &alist);
+ else
#endif
+ {
+ /* This ought to be correct in f->param_alist for an X frame. */
+ Lisp_Object lines;
+ XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
+ store_in_alist (&alist, Qmenu_bar_lines, lines);
+ }
return alist;
}
f = XFRAME (frame);
}
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
#if 1
return Qnil;
}
\f
-
-#if 0
-/* This function isn't useful enough by itself to include; we need to
- add functions to allow the user to find the size of a font before
- this is actually useful. */
-
-DEFUN ("frame-pixel-size", Fframe_pixel_size,
- Sframe_pixel_size, 1, 1, 0,
- "Return a cons (width . height) of FRAME's size in pixels.")
+DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
+ 0, 1, 0,
+ "Height in pixels of a line in the font in frame FRAME.\n\
+If FRAME is omitted, the selected frame is used.\n\
+For a terminal frame, the value is always 1.")
(frame)
Lisp_Object frame;
{
- register struct frame *f;
- int width, height;
+ struct frame *f;
- CHECK_LIVE_FRAME (frame, 0);
- f = XFRAME (frame);
-
- return Fcons (make_number (x_pixel_width (f)),
- make_number (x_pixel_height (f)));
-}
+ if (NILP (frame))
+ f = selected_frame;
+ else
+ {
+ CHECK_FRAME (frame, 0);
+ f = XFRAME (frame);
+ }
+
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (f))
+ return make_number (x_char_height (f));
+ else
#endif
+ return make_number (1);
+}
-#if 0
-/* These functions have no C callers, and can be written nicely in lisp. */
-DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
- "Return number of lines available for display on selected frame.")
- ()
+DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
+ 0, 1, 0,
+ "Width in pixels of characters in the font in frame FRAME.\n\
+If FRAME is omitted, the selected frame is used.\n\
+The width is the same for all characters, because\n\
+currently Emacs supports only fixed-width fonts.\n\
+For a terminal screen, the value is always 1.")
+ (frame)
+ Lisp_Object frame;
{
- return make_number (FRAME_HEIGHT (selected_frame));
+ struct frame *f;
+
+ if (NILP (frame))
+ f = selected_frame;
+ else
+ {
+ CHECK_FRAME (frame, 0);
+ f = XFRAME (frame);
+ }
+
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (f))
+ return make_number (x_char_width (f));
+ else
+#endif
+ return make_number (1);
}
-DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
- "Return number of columns available for display on selected frame.")
- ()
+DEFUN ("frame-pixel-height", Fframe_pixel_height,
+ Sframe_pixel_height, 0, 1, 0,
+ "Return a FRAME's height in pixels.\n\
+For a terminal frame, the result really gives the height in characters.\n\
+If FRAME is omitted, the selected frame is used.")
+ (frame)
+ Lisp_Object frame;
{
- return make_number (FRAME_WIDTH (selected_frame));
-}
+ struct frame *f;
+
+ if (NILP (frame))
+ f = selected_frame;
+ else
+ {
+ CHECK_FRAME (frame, 0);
+ f = XFRAME (frame);
+ }
+
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (f))
+ return make_number (x_pixel_height (f));
+ else
#endif
+ return make_number (FRAME_HEIGHT (f));
+}
+
+DEFUN ("frame-pixel-width", Fframe_pixel_width,
+ Sframe_pixel_width, 0, 1, 0,
+ "Return FRAME's width in pixels.\n\
+For a terminal frame, the result really gives the width in characters.\n\
+If FRAME is omitted, the selected frame is used.")
+ (frame)
+ Lisp_Object frame;
+{
+ struct frame *f;
+ if (NILP (frame))
+ f = selected_frame;
+ else
+ {
+ CHECK_FRAME (frame, 0);
+ f = XFRAME (frame);
+ }
+
+#ifdef HAVE_X_WINDOWS
+ if (FRAME_X_P (f))
+ return make_number (x_pixel_width (f));
+ else
+#endif
+ return make_number (FRAME_WIDTH (f));
+}
+\f
DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
"Specify that the frame FRAME has LINES lines.\n\
Optional third arg non-nil means that redisplay should use LINES lines\n\
f = XFRAME (frame);
}
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
{
if (XINT (rows) != f->width)
- x_set_window_size (f, f->width, XINT (rows));
+ x_set_window_size (f, 1, f->width, XINT (rows));
}
else
#endif
f = XFRAME (frame);
}
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
{
if (XINT (cols) != f->width)
- x_set_window_size (f, XINT (cols), f->height);
+ x_set_window_size (f, 1, XINT (cols), f->height);
}
else
#endif
CHECK_NUMBER (rows, 1);
f = XFRAME (frame);
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
{
if (XINT (rows) != f->height || XINT (cols) != f->width)
- x_set_window_size (f, XINT (cols), XINT (rows));
+ x_set_window_size (f, 1, XINT (cols), XINT (rows));
}
else
#endif
DEFUN ("set-frame-position", Fset_frame_position,
Sset_frame_position, 3, 3, 0,
"Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
-If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
-the leftmost or bottommost position FRAME could occupy without going\n\
-off the screen.")
+This is actually the position of the upper left corner of the frame.\n\
+Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
+the rightmost or bottommost possible position (that stays within the screen).")
(frame, xoffset, yoffset)
Lisp_Object frame, xoffset, yoffset;
{
CHECK_NUMBER (yoffset, 2);
f = XFRAME (frame);
+ /* I think this should be done with a hook. */
#ifdef HAVE_X_WINDOWS
if (FRAME_X_P (f))
- x_set_offset (f, XINT (xoffset), XINT (yoffset));
+ x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
#endif
return Qt;
}
-\f
-#ifndef HAVE_X11
-DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
- 3, 3, "",
- "Ask user to specify a window position and size on FRAME with the mouse.\n\
-Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
-the purpose of this rectangle. GEO is an X-windows size spec that can\n\
-specify defaults for some sizes/positions. If GEO specifies everything,\n\
-the mouse is not used.\n\
-Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
- (frame, name, geo)
- Lisp_Object frame;
- Lisp_Object name;
- Lisp_Object geo;
-{
- int vals[4];
- Lisp_Object nums[4];
- int i;
-
- CHECK_FRAME (frame, 0);
- CHECK_STRING (name, 1);
- CHECK_STRING (geo, 2);
-
- switch (XFRAME (frame)->output_method)
- {
- case output_x_window:
- x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
- XSTRING (geo)->data, XSTRING (name)->data);
- break;
-
- default:
- return Qnil;
- }
-
- for (i = 0; i < 4; i++)
- XFASTINT (nums[i]) = vals[i];
- return Fcons (frame, Flist (4, nums));
- return Qnil;
-}
-#endif /* not HAVE_X11 */
\f
choose_minibuf_frame ()
{
/*&&& init symbols here &&&*/
Qframep = intern ("framep");
staticpro (&Qframep);
- Qlive_frame_p = intern ("live-frame-p");
- staticpro (&Qlive_frame_p);
+ Qframe_live_p = intern ("frame-live-p");
+ staticpro (&Qframe_live_p);
Qheight = intern ("height");
staticpro (&Qheight);
Qicon = intern ("icon");
staticpro (&Qmodeline);
Qname = intern ("name");
staticpro (&Qname);
- Qnone = intern ("none");
- staticpro (&Qnone);
Qonly = intern ("only");
staticpro (&Qonly);
Qunsplittable = intern ("unsplittable");
staticpro (&Qunsplittable);
+ Qmenu_bar_lines = intern ("menu-bar-lines");
+ staticpro (&Qmenu_bar_lines);
Qwidth = intern ("width");
staticpro (&Qwidth);
Qx = intern ("x");
staticpro (&Qx);
+ Qvisible = intern ("visible");
+ staticpro (&Qvisible);
staticpro (&Vframe_list);
Vdefault_frame_alist = Qnil;
defsubr (&Sframep);
- defsubr (&Slive_frame_p);
+ defsubr (&Sframe_live_p);
+ 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);
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);
-#if 0
- defsubr (&Sframe_pixel_size);
- defsubr (&Sframe_height);
- defsubr (&Sframe_width);
-#endif
+ 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);
-#ifndef HAVE_X11
- defsubr (&Srubber_band_rectangle);
-#endif /* HAVE_X11 */
}
keys_of_frame ()
{
- initial_define_lispy_key (global_map, "switch-frame", "select-frame");
+ initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
+ initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
}
-
+\f
#else /* not MULTI_FRAME */
/* If we're not using multi-frame stuff, we still need to provide some
support functions. */
+Lisp_Object Qheight;
+Lisp_Object Qminibuffer;
+Lisp_Object Qmodeline;
+Lisp_Object Qname;
+Lisp_Object Qunsplittable;
+Lisp_Object Qmenu_bar_lines;
+Lisp_Object Qwidth;
+
+Lisp_Object Vterminal_frame;
+
/* Unless this function is defined, providing set-frame-height and
set-frame-width doesn't help compatibility any, since they both
want this as their first argument. */
DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
- "Return the frame that is now selected.")
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
()
{
Lisp_Object tem;
- XFASTINT (tem) = 0;
+ XSETFASTINT (tem, 0);
return tem;
}
+DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ Lisp_Object w;
+
+ w = FRAME_ROOT_WINDOW (selected_frame);
+
+ while (NILP (XWINDOW (w)->buffer))
+ {
+ if (! NILP (XWINDOW (w)->hchild))
+ w = XWINDOW (w)->hchild;
+ else if (! NILP (XWINDOW (w)->vchild))
+ w = XWINDOW (w)->vchild;
+ else
+ abort ();
+ }
+ return w;
+}
+
+DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (object)
+ Lisp_Object object;
+{
+ return Qnil;
+}
+
DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
- "Specify that the frame FRAME has LINES lines.\n\
-Optional third arg non-nil means that redisplay should use LINES lines\n\
-but that the idea of the actual height of the frame should not be changed.")
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
(frame, rows, pretend)
Lisp_Object frame, rows, pretend;
{
}
DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
- "Specify that the frame FRAME has COLS columns.\n\
-Optional third arg non-nil means that redisplay should use COLS columns\n\
-but that the idea of the actual width of the frame should not be changed.")
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
(frame, cols, pretend)
Lisp_Object frame, cols, pretend;
{
}
DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
- "Sets size of FRAME to COLS by ROWS, measured in characters.")
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
(frame, cols, rows)
Lisp_Object frame, cols, rows;
{
return Qnil;
}
-
-DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
- "Return number of lines available for display on selected frame.")
- ()
+\f
+DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
+ "Return number of lines available for display on FRAME.\n\
+If FRAME is omitted, describe the currently selected frame.")
+ (frame)
+ Lisp_Object frame;
{
return make_number (FRAME_HEIGHT (selected_frame));
}
-DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
- "Return number of columns available for display on selected frame.")
- ()
+DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
+ "Return number of columns available for display on FRAME.\n\
+If FRAME is omitted, describe the currently selected frame.")
+ (frame)
+ Lisp_Object frame;
{
return make_number (FRAME_WIDTH (selected_frame));
}
+DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
+ 0, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ return make_number (1);
+}
+
+
+DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
+ 0, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ return make_number (1);
+}
+
+DEFUN ("frame-pixel-height", Fframe_pixel_height,
+ Sframe_pixel_height, 0, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ return make_number (FRAME_HEIGHT (f));
+}
+
+DEFUN ("frame-pixel-width", Fframe_pixel_width,
+ Sframe_pixel_width, 0, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ return make_number (FRAME_WIDTH (f));
+}
+
/* These are for backward compatibility with Emacs 18. */
DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
return Qnil;
}
+DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ ()
+{
+ return Fcons (Qnil, Fcons (Qnil, Qnil));
+}
+\f
+void
+store_in_alist (alistptr, prop, val)
+ Lisp_Object *alistptr, val;
+ Lisp_Object prop;
+{
+ register Lisp_Object tem;
+
+ tem = Fassq (prop, *alistptr);
+ if (EQ (tem, Qnil))
+ *alistptr = Fcons (Fcons (prop, val), *alistptr);
+ else
+ Fsetcdr (tem, val);
+}
+
+DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ Lisp_Object alist;
+ FRAME_PTR f;
+
+ if (EQ (frame, Qnil))
+ f = selected_frame;
+ else
+ {
+ CHECK_FRAME (frame, 0);
+ f = XFRAME (frame);
+ }
+
+ if (!FRAME_LIVE_P (f))
+ return Qnil;
+
+ alist = Qnil;
+ store_in_alist (&alist, Qname, build_string ("emacs"));
+ store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
+ store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
+ store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
+ store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
+ store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
+ store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
+
+ return alist;
+}
+
+DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
+ Smodify_frame_parameters, 2, 2, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame, alist)
+ Lisp_Object frame, alist;
+{
+ return Qnil;
+}
+
+DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
+ /* Don't confuse make-docfile by having two doc strings for this function.
+ make-docfile does not pay attention to #if, for good reason! */
+ 0)
+ (frame)
+ Lisp_Object frame;
+{
+ return Qt;
+}
+
syms_of_frame ()
{
+ Qheight = intern ("height");
+ staticpro (&Qheight);
+ Qminibuffer = intern ("minibuffer");
+ staticpro (&Qminibuffer);
+ Qmodeline = intern ("modeline");
+ staticpro (&Qmodeline);
+ Qname = intern ("name");
+ staticpro (&Qname);
+ Qunsplittable = intern ("unsplittable");
+ staticpro (&Qunsplittable);
+ Qmenu_bar_lines = intern ("menu-bar-lines");
+ staticpro (&Qmenu_bar_lines);
+ Qwidth = intern ("width");
+ staticpro (&Qwidth);
+
+ DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
+ "The initial frame-object, which represents Emacs's stdout.");
+ XSETFASTINT (Vterminal_frame, 0);
+
+ defsubr (&Sselected_frame);
+ defsubr (&Sframe_first_window);
+ defsubr (&Sframep);
+ 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);
Ffset (intern ("screen-height"), intern ("frame-height"));
defsubr (&Sframe_width);
Ffset (intern ("screen-width"), intern ("frame-width"));
+ defsubr (&Smouse_position);
+ defsubr (&Sframe_parameters);
+ defsubr (&Smodify_frame_parameters);
+ defsubr (&Sframe_live_p);
}
keys_of_frame ()
}
#endif /* not MULTI_FRAME */
-
-
-
-