X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/09907c3a85887a5d1ea230e317ee7b5c529946b8..919fa9cbf0b0aabb55af71e54a2050304f4347bf:/src/frame.c diff --git a/src/frame.c b/src/frame.c index 6a422d037a..5c6e44e936 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1,5 +1,5 @@ /* Generic frame functions. - Copyright (C) 1993 Free Software Foundation. + Copyright (C) 1993, 1994 Free Software Foundation. This file is part of GNU Emacs. @@ -17,17 +17,17 @@ You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include - #include + +#include #include "lisp.h" #include "frame.h" #include "termhooks.h" +#include "window.h" #ifdef MULTI_FRAME #include "buffer.h" -#include "window.h" /* These help us bind and responding to switch-frame events. */ #include "commands.h" @@ -100,7 +100,7 @@ Also see `live-frame-p'.") (object) Lisp_Object object; { - if (XTYPE (object) != Lisp_Frame) + if (!FRAMEP (object)) return Qnil; switch (XFRAME (object)->output_method) { @@ -168,6 +168,8 @@ make_frame (mini_p) 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) @@ -195,14 +197,14 @@ make_frame (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. */ @@ -231,7 +233,7 @@ make_frame (mini_p) 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; + XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count); return f; } @@ -249,7 +251,7 @@ make_frame_without_minibuffer (mini_window) /* 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"); @@ -283,7 +285,7 @@ make_minibuffer_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; @@ -321,40 +323,20 @@ make_terminal_frame () Vframe_list = Qnil; f = make_frame (1); - XSET (frame, Lisp_Frame, f); + XSETFRAME (frame, f); Vframe_list = Fcons (frame, Vframe_list); f->name = build_string ("terminal"); 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; } -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 Fhandle_switch_frame (frame, no_enter); -} - - -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) +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. */ @@ -373,6 +355,9 @@ to that frame.") if (selected_frame == 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 @@ -380,23 +365,40 @@ to that frame.") can use `other-window' to switch between all the frames using that minibuffer frame, and the focus redirection will follow us around. */ - { - Lisp_Object tail; + if (track) + { + Lisp_Object tail; - for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) - { - Lisp_Object focus; + for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) + { + Lisp_Object focus; - if (XTYPE (XCONS (tail)->car) != Lisp_Frame) - abort (); + if (!FRAMEP (XCONS (tail)->car)) + abort (); - focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car)); + focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car)); - if (XTYPE (focus) == Lisp_Frame - && XFRAME (focus) == selected_frame) - Fredirect_frame_focus (XCONS (tail)->car, frame); - } - } + 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 + if (track) + { + 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 /* HAVE_X_WINDOWS */ +#endif /* ! 0 */ selected_frame = XFRAME (frame); if (! FRAME_MINIBUF_ONLY_P (selected_frame)) @@ -416,15 +418,44 @@ to that frame.") 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; } - + DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0, "Return the frame object that window WINDOW is on.") (window) @@ -434,6 +465,33 @@ DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0, 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.") @@ -441,7 +499,7 @@ 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); @@ -456,13 +514,37 @@ 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); 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; +} + DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0, "Return a list of all frames.") @@ -473,9 +555,10 @@ DEFUN ("frame-list", Fframe_list, Sframe_list, /* 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 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 @@ -497,8 +580,9 @@ next_frame (frame, minibuf) 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. */ @@ -520,9 +604,21 @@ next_frame (frame, minibuf) 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 @@ -536,9 +632,10 @@ next_frame (frame, minibuf) /* 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 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 @@ -556,9 +653,10 @@ prev_frame (frame, minibuf) 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)) @@ -571,9 +669,14 @@ prev_frame (frame, minibuf) 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)) + 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)) @@ -582,6 +685,13 @@ prev_frame (frame, minibuf) 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 prev = f; } @@ -604,9 +714,10 @@ DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0, 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 MINIFRAME is a window, include only frames using that window for their\n\ -minibuffer.\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; @@ -614,7 +725,7 @@ Otherwise, include all frames.") Lisp_Object tail; if (NILP (frame)) - XSET (frame, Lisp_Frame, selected_frame); + XSETFRAME (frame, selected_frame); else CHECK_LIVE_FRAME (frame, 0); @@ -626,9 +737,10 @@ DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0, 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 MINIFRAME is a window, include only frames using that window for their\n\ -minibuffer.\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; @@ -636,7 +748,7 @@ Otherwise, include all frames.") Lisp_Object tail; if (NILP (frame)) - XSET (frame, Lisp_Frame, selected_frame); + XSETFRAME (frame, selected_frame); else CHECK_LIVE_FRAME (frame, 0); @@ -647,7 +759,7 @@ Otherwise, include all frames.") 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 +int other_visible_frames (f) FRAME_PTR f; { @@ -662,8 +774,9 @@ other_visible_frames (f) CONSP (frames); frames = XCONS (frames)->cdr) { - Lisp_Object this = XCONS (frames)->car; + 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. */ @@ -701,7 +814,7 @@ but if the second optional argument FORCE is non-nil, you may do so.") if (EQ (frame, Qnil)) { f = selected_frame; - XSET (frame, Lisp_Frame, f); + XSETFRAME (frame, f); } else { @@ -748,6 +861,12 @@ but if the second optional argument FORCE is non-nil, you may do so.") minibuf_window = selected_frame->minibuffer_window; } + /* 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)); @@ -756,6 +875,21 @@ but if the second optional argument FORCE is non-nil, you may do so.") 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 @@ -799,15 +933,17 @@ but if the second optional argument FORCE is non-nil, you may do so.") 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); @@ -861,18 +997,52 @@ and nil for X and Y.") &lispy_dummy, &party_dummy, &x, &y, &long_dummy); - col = XINT (x); - row = XINT (y); - glyph_to_pixel_coords (f, col, row, &col, &row); - XSETINT (x, col); - XSETINT (y, row); - XSET (lispy_dummy, Lisp_Frame, f); + if (! NILP (x)) + { + 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)); +} + +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 character cell (X,Y) in FRAME.\n\ -WARNING: If you use this under X, you should do `unfocus-frame' afterwards.") +WARNING: If you use this under X windows,\n\ +you should call `unfocus-frame' afterwards.") (frame, x, y) Lisp_Object frame, x, y; { @@ -889,6 +1059,28 @@ WARNING: If you use this under X, you should do `unfocus-frame' afterwards.") return Qnil; } + +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; +{ + CHECK_LIVE_FRAME (frame, 0); + 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. */ + x_set_mouse_pixel_position (XFRAME (frame), x, y); +#endif + + return Qnil; +} DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible, 0, 1, "", @@ -898,7 +1090,7 @@ 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); CHECK_LIVE_FRAME (frame, 0); @@ -911,6 +1103,9 @@ If omitted, FRAME defaults to the currently selected frame.") } #endif + /* Make menu bar update for the Buffers and Frams menus. */ + windows_or_buffers_changed++; + return frame; } @@ -924,16 +1119,18 @@ but if the second optional argument FORCE is non-nil, you may do so.") 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)) @@ -949,6 +1146,9 @@ but if the second optional argument FORCE is non-nil, you may do so.") x_make_frame_invisible (XFRAME (frame)); #endif + /* Make menu bar update for the Buffers and Frams menus. */ + windows_or_buffers_changed++; + return Qnil; } @@ -960,13 +1160,15 @@ 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); 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)) @@ -982,6 +1184,9 @@ If omitted, FRAME defaults to the currently selected frame.") x_iconify_frame (XFRAME (frame)); #endif + /* Make menu bar update for the Buffers and Frams menus. */ + windows_or_buffers_changed++; + return Qnil; } @@ -1018,7 +1223,7 @@ DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list, 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 (FRAME_VISIBLE_P (f)) @@ -1170,8 +1375,7 @@ store_frame_param (f, prop, val) 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."); @@ -1193,7 +1397,7 @@ If FRAME is omitted, return information on the currently selected frame.") Lisp_Object frame; { Lisp_Object alist; - struct frame *f; + FRAME_PTR f; if (EQ (frame, Qnil)) f = selected_frame; @@ -1203,26 +1407,32 @@ If FRAME is omitted, return information on the currently 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) ? Qnil - : (FRAME_MINIBUF_ONLY_P (f) ? Qonly - : FRAME_MINIBUF_WINDOW (f)))); - store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil)); - store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f))); + : 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; } @@ -1481,7 +1691,7 @@ the rightmost or bottommost possible position (that stays within the screen).") /* 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; @@ -1579,13 +1789,17 @@ For values specific to the separate minibuffer frame, see\n\ 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); @@ -1614,6 +1828,7 @@ For values specific to the separate minibuffer frame, see\n\ keys_of_frame () { initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame"); + initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame"); } #else /* not MULTI_FRAME */ @@ -1621,6 +1836,16 @@ keys_of_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. */ @@ -1631,9 +1856,31 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 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! */ @@ -1684,7 +1931,7 @@ DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, return Qnil; } - + 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.") @@ -1777,42 +2024,105 @@ but that the idea of the actual width of the screen should not be changed.") } 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.") + /* 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)); +} + +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; - Lisp_Object lispy_dummy; - enum scroll_bar_part party_dummy; - Lisp_Object x, y; - unsigned long long_dummy; - f = selected_frame; - x = y = Qnil; + if (EQ (frame, Qnil)) + f = selected_frame; + else + { + CHECK_FRAME (frame, 0); + f = XFRAME (frame); + } - /* 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); + if (!FRAME_LIVE_P (f)) + return Qnil; - col = XINT (x); - row = XINT (y); - glyph_to_pixel_coords (f, col, row, &col, &row); - XSETINT (x, col); - XSETINT (y, row); - /* Always return nil for frame. */ - return Fcons (Qnil, Fcons (x, y)); + 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); @@ -1828,6 +2138,9 @@ syms_of_frame () 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 () @@ -1835,7 +2148,3 @@ keys_of_frame () } #endif /* not MULTI_FRAME */ - - - -