X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/d5e7c279e59c8dbc3175b23aea201a2877738e66..752a043ffa37cb8a652f6913ff94d1e1c8923358:/src/frame.c diff --git a/src/frame.c b/src/frame.c index 0371a0f3e8..e11a90affb 100644 --- a/src/frame.c +++ b/src/frame.c @@ -1,11 +1,11 @@ -/* Generic screen functions. - Copyright (C) 1989 Free Software Foundation. +/* Generic frame functions. + Copyright (C) 1989, 1992, 1993 Free Software Foundation. This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) +the Free Software Foundation; either version 2, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, @@ -21,102 +21,175 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "config.h" #include "lisp.h" -#include "screen.h" +#include "frame.h" + +#ifdef MULTI_FRAME + +#include "buffer.h" #include "window.h" #include "termhooks.h" -Lisp_Object Vemacs_iconified; -Lisp_Object Qscreenp; -Lisp_Object Vscreen_list; -Lisp_Object Vterminal_screen; -Lisp_Object Vglobal_minibuffer_screen; +/* These help us bind and responding to switch-frame events. */ +#include "commands.h" +#include "keyboard.h" -/* A screen which is not just a minibuffer, or 0 if there are no - such screens. This is usually the most recent such screen that - was selected. */ -struct screen *last_nonminibuf_screen; +Lisp_Object Vemacs_iconified; +Lisp_Object Vframe_list; +Lisp_Object Vterminal_frame; +Lisp_Object Vdefault_minibuffer_frame; +Lisp_Object Vdefault_frame_alist; + +/* Evaluate this expression to rebuild the section of syms_of_frame + that initializes and staticpros the symbols declared below. Note + that Emacs 18 has a bug that keeps C-x C-e from being able to + evaluate this expression. + +(progn + ;; Accumulate a list of the symbols we want to initialize from the + ;; declarations at the top of the file. + (goto-char (point-min)) + (search-forward "/\*&&& symbols declared here &&&*\/\n") + (let (symbol-list) + (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)") + (setq symbol-list + (cons (buffer-substring (match-beginning 1) (match-end 1)) + symbol-list)) + (forward-line 1)) + (setq symbol-list (nreverse symbol-list)) + ;; Delete the section of syms_of_... where we initialize the symbols. + (search-forward "\n /\*&&& init symbols here &&&*\/\n") + (let ((start (point))) + (while (looking-at "^ Q") + (forward-line 2)) + (kill-region start (point))) + ;; Write a new symbol initialization section. + (while symbol-list + (insert (format " %s = intern (\"" (car symbol-list))) + (let ((start (point))) + (insert (substring (car symbol-list) 1)) + (subst-char-in-region start (point) ?_ ?-)) + (insert (format "\");\n staticpro (&%s);\n" (car symbol-list))) + (setq symbol-list (cdr symbol-list))))) + */ + +/*&&& symbols declared here &&&*/ +Lisp_Object Qframep; +Lisp_Object Qframe_live_p; +Lisp_Object Qheight; +Lisp_Object Qicon; +Lisp_Object Qminibuffer; +Lisp_Object Qmodeline; +Lisp_Object Qname; +Lisp_Object Qonly; +Lisp_Object Qunsplittable; +Lisp_Object Qmenu_bar_lines; +Lisp_Object Qwidth; +Lisp_Object Qx; extern Lisp_Object Vminibuffer_list; extern Lisp_Object get_minibuffer (); -DEFUN ("screenp", Fscreenp, Sscreenp, 1, 1, 0, - "Return non-nil if OBJECT is a screen.\n\ -Value is t for a termcap screen (a character-only terminal),\n\ -`x' for an Emacs screen that is really an X window.") - (screen) - Lisp_Object screen; +DEFUN ("framep", Fframep, Sframep, 1, 1, 0, + "Return non-nil if OBJECT is a frame.\n\ +Value is t for a termcap frame (a character-only terminal),\n\ +`x' for an Emacs frame that is really an X window.\n\ +Also see `live-frame-p'.") + (object) + Lisp_Object object; { - if (XTYPE (screen) != Lisp_Screen) + if (XTYPE (object) != Lisp_Frame) return Qnil; - switch (XSCREEN (screen)->output_method) + switch (XFRAME (object)->output_method) { case output_termcap: return Qt; case output_x_window: - return intern ("x"); + return Qx; default: abort (); } } -struct screen * -make_screen (mini_p) +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\ +displayed on. Value is t for a termcap frame (a character-only\n\ +terminal), `x' for an Emacs frame being displayed in an X window.") + (object) + Lisp_Object object; +{ + return ((FRAMEP (object) + && FRAME_LIVE_P (XFRAME (object))) + ? Fframep (object) + : Qnil); +} + +struct frame * +make_frame (mini_p) int mini_p; { - Lisp_Object screen; - register struct screen *s; + Lisp_Object frame; + register struct frame *f; register Lisp_Object root_window; register Lisp_Object mini_window; - screen = Fmake_vector (((sizeof (struct screen) - (sizeof (Lisp_Vector) + frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector) - sizeof (Lisp_Object))) / sizeof (Lisp_Object)), make_number (0)); - XSETTYPE (screen, Lisp_Screen); - s = XSCREEN (screen); - - s->cursor_x = 0; - s->cursor_y = 0; - s->current_glyphs = 0; - s->desired_glyphs = 0; - s->visible = 0; - s->display.nothing = 0; - s->iconified = 0; - s->wants_modeline = 1; - s->auto_raise = 0; - s->auto_lower = 0; - s->no_split = 0; - s->garbaged = 0; - s->has_minibuffer = mini_p; - s->focus_screen = screen; - - s->param_alist = Qnil; - - root_window = make_window (0); + XSETTYPE (frame, Lisp_Frame); + f = XFRAME (frame); + + f->cursor_x = 0; + f->cursor_y = 0; + 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 = 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; + + root_window = make_window (); if (mini_p) { - mini_window = make_window (0); + mini_window = make_window (); XWINDOW (root_window)->next = mini_window; XWINDOW (mini_window)->prev = root_window; XWINDOW (mini_window)->mini_p = Qt; - XWINDOW (mini_window)->screen = screen; - s->minibuffer_window = mini_window; + XWINDOW (mini_window)->frame = frame; + f->minibuffer_window = mini_window; } else { mini_window = Qnil; XWINDOW (root_window)->next = Qnil; - s->minibuffer_window = Qnil; + f->minibuffer_window = Qnil; } - XWINDOW (root_window)->screen = screen; + XWINDOW (root_window)->frame = frame; /* 10 is arbitrary, just so that there is "something there." - Correct size will be set up later with change_screen_size. */ + Correct size will be set up later with change_frame_size. */ - s->width = 10; - s->height = 10; + f->width = 10; + f->height = 10; XFASTINT (XWINDOW (root_window)->width) = 10; XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10); @@ -128,639 +201,817 @@ make_screen (mini_p) XFASTINT (XWINDOW (mini_window)->height) = 1; } - XWINDOW (root_window)->buffer = Qt; - Fset_window_buffer (root_window, Fcurrent_buffer ()); + /* Choose a buffer for the frame's root window. */ + { + Lisp_Object buf; + + XWINDOW (root_window)->buffer = Qt; + buf = Fcurrent_buffer (); + /* If buf is a 'hidden' buffer (i.e. one whose name starts with + a space), try to find another one. */ + if (XSTRING (Fbuffer_name (buf))->data[0] == ' ') + buf = Fother_buffer (buf, Qnil); + Fset_window_buffer (root_window, buf); + } + if (mini_p) { XWINDOW (mini_window)->buffer = Qt; Fset_window_buffer (mini_window, - (NULL (Vminibuffer_list) + (NILP (Vminibuffer_list) ? get_minibuffer (0) : Fcar (Vminibuffer_list))); } - s->root_window = root_window; - s->selected_window = root_window; + f->root_window = root_window; + f->selected_window = root_window; /* Make sure this window seems more recently used than a newly-created, never-selected window. */ - XFASTINT (XWINDOW (s->selected_window)->use_time) = ++window_select_count; + XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count; - Vscreen_list = Fcons (screen, Vscreen_list); + Vframe_list = Fcons (frame, Vframe_list); - return s; + return f; } -/* Make a screen using a separate minibuffer window on another screen. +/* Make a frame using a separate minibuffer window on another frame. MINI_WINDOW is the minibuffer window to use. nil means use the default (the global minibuffer). */ -struct screen * -make_screen_without_minibuffer (mini_window) +struct frame * +make_frame_without_minibuffer (mini_window) register Lisp_Object mini_window; { - register struct screen *s; + register struct frame *f; /* Choose the minibuffer window to use. */ - if (NULL (mini_window)) + if (NILP (mini_window)) { - if (XTYPE (Vglobal_minibuffer_screen) != Lisp_Screen) - error ("global-minibuffer-screen must be set to create minibufferless screens."); - mini_window = XSCREEN (Vglobal_minibuffer_screen)->minibuffer_window; + if (XTYPE (Vdefault_minibuffer_frame) != Lisp_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"); + mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window; } else { - CHECK_WINDOW (mini_window, 0); + CHECK_LIVE_WINDOW (mini_window, 0); } - /* Make a screen containing just a root window. */ - s = make_screen (0); + /* Make a frame containing just a root window. */ + f = make_frame (0); /* Install the chosen minibuffer window, with proper buffer. */ - s->minibuffer_window = mini_window; + f->minibuffer_window = mini_window; Fset_window_buffer (mini_window, - (NULL (Vminibuffer_list) + (NILP (Vminibuffer_list) ? get_minibuffer (0) : Fcar (Vminibuffer_list))); - return s; + return f; } -/* Make a screen containing only a minibuffer window. */ +/* Make a frame containing only a minibuffer window. */ -struct screen * -make_minibuffer_screen () +struct frame * +make_minibuffer_frame () { - /* First make a screen containing just a root window, no minibuffer. */ + /* First make a frame containing just a root window, no minibuffer. */ - register struct screen *s = make_screen (0); + register struct frame *f = make_frame (0); register Lisp_Object mini_window; - register Lisp_Object screen; + register Lisp_Object frame; - XSET (screen, Lisp_Screen, s); + XSET (frame, Lisp_Frame, f); - /* ??? Perhaps leave it to the user program to set auto_raise. */ - s->auto_raise = 1; - s->auto_lower = 0; - s->no_split = 1; - s->wants_modeline = 0; - /* Note we leave has_minibuffer as 0. This is a little strange. */ + f->auto_raise = 0; + 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 as nil. */ - mini_window = s->minibuffer_window = s->root_window; + mini_window = f->minibuffer_window = f->root_window; XWINDOW (mini_window)->mini_p = Qt; XWINDOW (mini_window)->next = Qnil; - XWINDOW (mini_window)->prev = mini_window; - XWINDOW (mini_window)->screen = screen; + XWINDOW (mini_window)->prev = Qnil; + XWINDOW (mini_window)->frame = frame; /* Put the proper buffer in that window. */ Fset_window_buffer (mini_window, - (NULL (Vminibuffer_list) + (NILP (Vminibuffer_list) ? get_minibuffer (0) : Fcar (Vminibuffer_list))); - return s; + return f; } -/* Construct a screen that refers to the terminal (stdin and stdout). */ +/* Construct a frame that refers to the terminal (stdin and stdout). */ -struct screen * -make_terminal_screen () +struct frame * +make_terminal_frame () { - register struct screen *s; - - Vscreen_list = Qnil; - s = make_screen (1); - s->name = build_string ("terminal"); - s->visible = 1; - s->display.nothing = 1; /* Nonzero means screen isn't deleted. */ - XSET (Vterminal_screen, Lisp_Screen, s); - return s; + register struct frame *f; + + Vframe_list = Qnil; + f = make_frame (1); + 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); + return f; } -DEFUN ("select-screen", Fselect_screen, Sselect_screen, 1, 2, 0, - "Select the screen S. S's selected window becomes \"the\"\n\ -selected window. If the optional parameter NO-ENTER is non-nil, don't\n\ -focus on that screen.") - (screen, no_enter) - Lisp_Object screen, no_enter; +DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e", + "Select the frame FRAME.\n\ +Subseqent 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; { - CHECK_SCREEN (screen, 0); + return Fhandle_switch_frame (frame, no_enter); +} - if (selected_screen == XSCREEN (screen)) - return screen; - selected_screen = XSCREEN (screen); - if (!EQ (SCREEN_ROOT_WINDOW (selected_screen), - SCREEN_MINIBUF_WINDOW (selected_screen))) - last_nonminibuf_screen = selected_screen; +DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e", + "Handle a switch-frame event EVENT.\n\ +Switch-frame events is 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; +{ + /* If FRAME is a switch-frame event, extract the frame we should + switch to. */ + if (CONSP (frame) + && EQ (XCONS (frame)->car, Qswitch_frame) + && CONSP (XCONS (frame)->cdr)) + frame = XCONS (XCONS (frame)->cdr)->car; + + CHECK_LIVE_FRAME (frame, 0); + + if (selected_frame == XFRAME (frame)) + return frame; + + /* 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. */ + { + Lisp_Object tail; + + for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) + { + Lisp_Object focus; - Fselect_window (XSCREEN (screen)->selected_window); + if (XTYPE (XCONS (tail)->car) != Lisp_Frame) + abort (); + focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car)); + + if (XTYPE (focus) == Lisp_Frame + && XFRAME (focus) == selected_frame) + Fredirect_frame_focus (XCONS (tail)->car, frame); + } + } + + selected_frame = XFRAME (frame); + if (! FRAME_MINIBUF_ONLY_P (selected_frame)) + last_nonminibuf_frame = selected_frame; + + Fselect_window (XFRAME (frame)->selected_window); + + /* I think this should be done with a hook. */ #ifdef HAVE_X_WINDOWS -#ifdef MULTI_SCREEN - if (XSCREEN (screen)->output_method == output_x_window - && NULL (no_enter)) + if (FRAME_X_P (XFRAME (frame)) + && NILP (no_enter)) { - Ffocus_screen (screen); + Ffocus_frame (frame); } #endif -#endif - choose_minibuf_screen (); + choose_minibuf_frame (); - return screen; + /* We want to make sure that the next event generates a frame-switch + event to the appropriate frame. This seems kludgey 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 ("selected-screen", Fselected_screen, Sselected_screen, 0, 0, 0, - "Return the screen that is now selected.") +DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0, + "Return the frame that is now selected.") () { Lisp_Object tem; - XSET (tem, Lisp_Screen, selected_screen); + XSET (tem, Lisp_Frame, selected_frame); return tem; } -DEFUN ("window-screen", Fwindow_screen, Swindow_screen, 1, 1, 0, - "Return the screen object that window WINDOW is on.") +DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0, + "Return the frame object that window WINDOW is on.") (window) Lisp_Object window; { - CHECK_WINDOW (window, 0); - return XWINDOW (window)->screen; + CHECK_LIVE_WINDOW (window, 0); + return XWINDOW (window)->frame; } -DEFUN ("screen-root-window", Fscreen_root_window, Sscreen_root_window, 0, 1, 0, - "Returns the root-window of SCREEN.") - (screen) - Lisp_Object screen; +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.") + (frame) + Lisp_Object frame; { - if (NULL (screen)) - XSET (screen, Lisp_Screen, selected_screen); - CHECK_SCREEN (screen, 0); + if (NILP (frame)) + XSET (frame, Lisp_Frame, selected_frame); + else + CHECK_LIVE_FRAME (frame, 0); - return XSCREEN (screen)->root_window; + return XFRAME (frame)->root_window; } -DEFUN ("screen-selected-window", Fscreen_selected_window, - Sscreen_selected_window, 0, 1, 0, - "Return the selected window of screen object SCREEN.") - (screen) - Lisp_Object screen; +DEFUN ("frame-selected-window", Fframe_selected_window, + Sframe_selected_window, 0, 1, 0, + "Return the selected window of frame object FRAME.\n\ +If omitted, FRAME defaults to the currently selected frame.") + (frame) + Lisp_Object frame; { - if (NULL (screen)) - XSET (screen, Lisp_Screen, selected_screen); - CHECK_SCREEN (screen, 0); + if (NILP (frame)) + XSET (frame, Lisp_Frame, selected_frame); + else + CHECK_LIVE_FRAME (frame, 0); - return XSCREEN (screen)->selected_window; + return XFRAME (frame)->selected_window; } -DEFUN ("screen-list", Fscreen_list, Sscreen_list, +DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0, - "Return a list of all screens.") + "Return a list of all frames.") () { - return Fcopy_sequence (Vscreen_list); + return Fcopy_sequence (Vframe_list); } -#ifdef MULTI_SCREEN +/* 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. */ Lisp_Object -next_screen (screen, mini_screen) - Lisp_Object screen; - int mini_screen; +next_frame (frame, minibuf) + Lisp_Object frame; + Lisp_Object minibuf; { Lisp_Object tail; int passed = 0; + /* There must always be at least one frame in Vframe_list. */ + 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 = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr) + for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) { + Lisp_Object f = XCONS (tail)->car; + if (passed) { - SCREEN_PTR s = XSCREEN (XCONS (tail)->car); - - if (!mini_screen - - /* Is this screen only a minibuffer? */ - && EQ (SCREEN_ROOT_WINDOW (s), - SCREEN_MINIBUF_WINDOW (s)) - - /* If we have wrapped all the way around the list (i.e. - the only screen is an all-minibuffer screen), return - it anyway. */ - && s != XSCREEN (screen)) - continue; + /* Decide whether this frame is eligible to be returned. */ + + /* If we've looped all the way around without finding any + eligible frames, return the original frame. */ + if (EQ (f, frame)) + return f; + + /* Let minibuf decide if this frame is acceptable. */ + if (NILP (minibuf)) + { + if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) + return f; + } + else if (XTYPE (minibuf) == Lisp_Window) + { + if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)) + return f; + } else - return XCONS (tail)->car; + return f; } - if (EQ (screen, XCONS (tail)->car)) + if (EQ (frame, f)) passed++; } } +/* 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. */ Lisp_Object -prev_screen (screen, mini_screen) - Lisp_Object screen; - int mini_screen; +prev_frame (frame, minibuf) + Lisp_Object frame; + Lisp_Object minibuf; { Lisp_Object tail; Lisp_Object prev; + /* There must always be at least one frame in Vframe_list. */ + if (! CONSP (Vframe_list)) + abort (); + prev = Qnil; - while (1) - for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr) - { - if (EQ (screen, XCONS (tail)->car)) - { - if (!NULL (prev) && (mini_screen - || !EQ (XCONS (tail)->car, - Vglobal_minibuffer_screen))) - return prev; - } - prev = XCONS (tail)->car; - } + for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) + { + Lisp_Object f = XCONS (tail)->car; + + if (XTYPE (f) != Lisp_Frame) + abort (); + + if (EQ (frame, f) && !NILP (prev)) + return prev; + + /* Decide whether this frame is eligible to be returned, + according to minibuf. */ + if (NILP (minibuf)) + { + if (! FRAME_MINIBUF_ONLY_P (XFRAME (f))) + prev = f; + } + else if (XTYPE (minibuf) == Lisp_Window) + { + if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)) + prev = f; + } + else + prev = f; + } + + /* We've scanned the entire list. */ + if (NILP (prev)) + /* We went through the whole frame list without finding a single + acceptable frame. Return the original frame. */ + return frame; + else + /* There were no acceptable frames in the list before FRAME; otherwise, + we would have returned directly from the loop. Since PREV is the last + acceptable frame in the list, return it. */ + return prev; } -DEFUN ("next-screen", Fnext_screen, Snext_screen, - 0, 2, 0, - "Return the next screen in the screen list after SCREEN.\n\ -If MINISCREEN is non-nil, include screens whose only window is a minibuffer.\n\ -If MINISCREEN is nil or omitted, these screens are skipped.") - (screen, miniscreen) -Lisp_Object screen, miniscreen; +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.\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.") + (frame, miniframe) + Lisp_Object frame, miniframe; { Lisp_Object tail; - if (NULL (screen)) - XSET (screen, Lisp_Screen, selected_screen); - CHECK_SCREEN (screen, 0); + if (NILP (frame)) + XSET (frame, Lisp_Frame, selected_frame); + else + CHECK_LIVE_FRAME (frame, 0); - return next_screen (screen, (NULL (miniscreen) ? 0 : 1)); + return next_frame (frame, miniframe); } -#endif /* MULTI_SCREEN */ + -DEFUN ("delete-screen", Fdelete_screen, Sdelete_screen, - 0, 1, "", - "Delete SCREEN, permanently eliminating it from use.\n\ -Default is current screen.") - (screen) - Lisp_Object screen; +DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "", + "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; { - struct screen *s; - union display displ; + struct frame *f; - if (EQ (screen, Qnil)) + if (EQ (frame, Qnil)) { - s = selected_screen; - XSET (screen, Lisp_Screen, s); + f = selected_frame; + XSET (frame, Lisp_Frame, f); } else { - CHECK_SCREEN (screen, 0); - s = XSCREEN (screen); + CHECK_FRAME (frame, 0); + f = XFRAME (frame); } - /* Are there any other screens besides this one? */ - if (s == selected_screen && EQ (next_screen (screen, 1), screen)) - error ("Attempt to delete the only screen"); + if (! FRAME_LIVE_P (f)) + return Qnil; - /* Does this screen have a minibuffer, and is it the surrogate - minibuffer for any other screen? */ - if (EQ (screen, - WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (XSCREEN (screen)))))) + /* 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"); + + /* Does this frame have a minibuffer, and is it the surrogate + minibuffer for any other frame? */ + if (FRAME_HAS_MINIBUF_P (XFRAME (frame))) { - Lisp_Object screen2; + Lisp_Object frames; - for (screen2 = Vscreen_list; CONSP (2); screen2 = XCONS (screen2)->cdr) - if (! EQ (screen2, screen) - && EQ (screen, - WINDOW_SCREEN (XWINDOW (SCREEN_MINIBUF_WINDOW (XSCREEN (screen2)))))) - error ("Attempt to delete a surrogate minibuffer screen"); + for (frames = Vframe_list; + CONSP (frames); + frames = XCONS (frames)->cdr) + { + Lisp_Object this = XCONS (frames)->car; + + if (! EQ (this, frame) + && EQ (frame, + (WINDOW_FRAME + (XWINDOW + (FRAME_MINIBUF_WINDOW + (XFRAME (this))))))) + error ("Attempt to delete a surrogate minibuffer frame"); + } } - /* Don't let the screen remain selected. */ - if (s == selected_screen) - Fselect_screen (next_screen (screen, 1)); + /* Don't let the frame remain selected. */ + if (f == selected_frame) + Fhandle_switch_frame (next_frame (frame, Qt), Qnil); - /* Don't allow minibuf_window to remain on a deleted screen. */ - if (EQ (s->minibuffer_window, minibuf_window)) + /* Don't allow minibuf_window to remain on a deleted frame. */ + if (EQ (f->minibuffer_window, minibuf_window)) { - Fset_window_buffer (selected_screen->minibuffer_window, + Fset_window_buffer (selected_frame->minibuffer_window, XWINDOW (minibuf_window)->buffer); - minibuf_window = selected_screen->minibuffer_window; + minibuf_window = selected_frame->minibuffer_window; } - Vscreen_list = Fdelq (screen, Vscreen_list); - s->visible = 0; - displ = s->display; - s->display.nothing = 0; + /* 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); + + /* 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 (s->output_method == output_x_window) - x_destroy_window (s, displ); + if (FRAME_X_P (f)) + x_destroy_window (f); #endif - /* If we've deleted the last_nonminibuf_screen, then try to find + f->display.nothing = 0; + + /* If we've deleted the last_nonminibuf_frame, then try to find another one. */ - if (s == last_nonminibuf_screen) + if (f == last_nonminibuf_frame) { - last_nonminibuf_screen = 0; + Lisp_Object frames; + + last_nonminibuf_frame = 0; - for (screen = Vscreen_list; CONSP (screen); screen = XCONS (screen)->cdr) + for (frames = Vframe_list; + CONSP (frames); + frames = XCONS (frames)->cdr) { - s = XSCREEN (XCONS (screen)->cdr); - if (!EQ (SCREEN_ROOT_WINDOW (s), SCREEN_MINIBUF_WINDOW (s))) + f = XFRAME (XCONS (frames)->car); + if (!FRAME_MINIBUF_ONLY_P (f)) { - last_nonminibuf_screen = s; + last_nonminibuf_frame = f; break; } } } - return Qnil; -} - -/* Return mouse position in character cell units. */ + /* If we've deleted Vdefault_minibuffer_frame, try to find another + one. Prefer minibuffer-only frames, but also notice frames + with other windows. */ + if (EQ (frame, Vdefault_minibuffer_frame)) + { + Lisp_Object frames; -static -read_mouse_position (screen, x, y) - Lisp_Object screen; - int *x, *y; -{ - CHECK_SCREEN (screen, 0); + /* The last frame we saw with a minibuffer, minibuffer-only or not. */ + Lisp_Object frame_with_minibuf = Qnil; - *x = 1; - *y = 1; + for (frames = Vframe_list; + CONSP (frames); + frames = XCONS (frames)->cdr) + { + Lisp_Object this = XCONS (frames)->car; -#ifdef HAVE_X_WINDOWS - if (XSCREEN (screen)->output_method == output_x_window) - x_read_mouse_position (XSCREEN (screen), x, y); -#endif + if (XTYPE (this) != Lisp_Frame) + abort (); + f = XFRAME (this); + + if (FRAME_HAS_MINIBUF_P (f)) + { + frame_with_minibuf = this; + if (FRAME_MINIBUF_ONLY_P (f)) + break; + } + } + + /* We know that there must be some frame with a minibuffer out + there. If this were not true, all of the frames present + would have to be minibufferless, which implies that at some + point their minibuffer frames must have been deleted, but + that is prohibited at the top; you can't delete surrogate + minibuffer frames. */ + if (NILP (frame_with_minibuf)) + abort (); + + Vdefault_minibuffer_frame = frame_with_minibuf; + } + + return Qnil; } + +/* Return mouse position in character cell units. */ -DEFUN ("read-mouse-position", Fread_mouse_position, Sread_mouse_position, 1, 1, 0, - "Return a cons (x . y) which represents the position of the mouse.") - (screen) - Lisp_Object screen; +DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0, + "Return a list (FRAME X . Y) giving the current mouse frame and position.\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.") + () { - int x, y; - struct screen *s; - - CHECK_SCREEN (screen, 0); + FRAME_PTR f; + Lisp_Object lispy_dummy; + enum scroll_bar_part party_dummy; + Lisp_Object x, y; + unsigned long long_dummy; + + if (mouse_position_hook) + (*mouse_position_hook) (&f, + &lispy_dummy, &party_dummy, + &x, &y, + &long_dummy); + else + { + f = selected_frame; + x = y = Qnil; + } - read_mouse_position (screen, &x, &y); - return Fcons (make_number (x), make_number (y)); + XSET (lispy_dummy, Lisp_Frame, f); + return Fcons (lispy_dummy, Fcons (make_number (x), make_number (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 SCREEN.\n\ -WARNING: If you use this under X, you should do unfocus-screen afterwards.") - (screen, x, y) - Lisp_Object screen, x, y; + "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.") + (frame, x, y) + Lisp_Object frame, x, y; { - CHECK_SCREEN (screen, 0); + 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 (XSCREEN (screen)->output_method == output_x_window) + if (FRAME_X_P (XFRAME (frame))) /* Warping the mouse will cause enternotify and focus events. */ - x_set_mouse_position (XSCREEN (screen), x, y); + x_set_mouse_position (XFRAME (frame), x, y); #endif return Qnil; } -#if 0 -/* ??? Can this be replaced with a Lisp function? - It is used in minibuf.c. Can we get rid of that? */ - -DEFUN ("screen-configuration", Fscreen_configuration, Sscreen_configuration, - 0, 0, 0, - "Return object describing current screen configuration.\n\ -The screen configuration is the current mouse position and selected screen.\n\ -This object can be given to `restore-screen-configuration'\n\ -to restore this screen configuration.") - () +DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible, + 0, 1, 0, + "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; { - int x, y; - Lisp_Object c, screen; - struct screen *s; - - c = Fmake_vector (make_number(3), Qnil); - XVECTOR (c)->contents[0] = screen = Fselected_screen(); - read_mouse_position (screen, &x, &y); - XVECTOR (c)->contents[1] = make_number (x); - XVECTOR (c)->contents[2] = make_number (y); + if (NILP (frame)) + XSET (frame, Lisp_Frame, selected_frame); - return c; -} + CHECK_LIVE_FRAME (frame, 0); -DEFUN ("restore-screen-configuration", Frestore_screen_configuration, - Srestore_screen_configuration, - 1, 1, 0, - "Restores screen configuration CONFIGURATION.") - (config) - Lisp_Object config; -{ - Lisp_Object x_pos, y_pos, screen; - - CHECK_VECTOR (config, 0); - if (XVECTOR (config)->size != 3) - { - error ("Wrong size vector passed to restore-screen-configuration"); - } - screen = XVECTOR (config)->contents[0]; - CHECK_SCREEN (screen, 0); - - Fselect_screen (screen, Qnil); - -#if 0 - /* This seems to interfere with the screen selection mechanism. jla */ - x_pos = XVECTOR (config)->contents[1]; - y_pos = XVECTOR (config)->contents[2]; - set_mouse_position (screen, XINT (x_pos), XINT (y_pos)); -#endif - - return screen; -} + /* 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)); #endif - -DEFUN ("make-screen-visible", Fmake_screen_visible, Smake_screen_visible, - 1, 1, 0, - "Make the screen SCREEN visible (assuming it is an X-window).\n\ -Also raises the screen so that nothing obscures it.") - (screen) - Lisp_Object screen; -{ - CHECK_SCREEN (screen, 0); - - if (XSCREEN (screen)->display.nothing == 0) - error ("Cannot make a dead screen object visible"); - - if (XSCREEN (screen)->output_method == output_x_window) - x_make_screen_visible (XSCREEN (screen)); - return screen; + return frame; } -DEFUN ("make-screen-invisible", Fmake_screen_invisible, Smake_screen_invisible, - 1, 1, 0, - "Make the screen SCREEN invisible (assuming it is an X-window).") - (screen) - Lisp_Object screen; -{ - CHECK_SCREEN (screen, 0); - - if (XSCREEN (screen)->output_method == output_x_window) - x_make_screen_invisible (XSCREEN (screen)); - - return Qnil; -} - -DEFUN ("iconify-screen", Ficonify_screen, Siconify_screen, - 1, 1, 0, - "Make the screen SCREEN into an icon.") - (screen) - Lisp_Object screen; +DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible, + 0, 1, "", + "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; { - CHECK_SCREEN (screen, 0); + if (NILP (frame)) + XSET (frame, Lisp_Frame, selected_frame); - if (XSCREEN (screen)->display.nothing == 0) - error ("Cannot make a dead screen object iconified."); + CHECK_LIVE_FRAME (frame, 0); - if (XSCREEN (screen)->output_method == output_x_window) - x_iconify_screen (XSCREEN (screen)); + /* 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 return Qnil; } -DEFUN ("deiconify-screen", Fdeiconify_screen, Sdeiconify_screen, - 1, 1, 0, - "Open (de-iconify) the iconified screen SCREEN.") - (screen) - Lisp_Object screen; +DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame, + 0, 1, "", + "Make the frame FRAME into an icon.\n\ +If omitted, FRAME defaults to the currently selected frame.") + (frame) + Lisp_Object frame; { - CHECK_SCREEN (screen, 0); - - if (XSCREEN (screen)->display.nothing == 0) - error ("Cannot deiconify a dead screen object."); + if (NILP (frame)) + XSET (frame, Lisp_Frame, selected_frame); + + CHECK_LIVE_FRAME (frame, 0); - if (XSCREEN (screen)->output_method == output_x_window) - x_make_screen_visible (XSCREEN (screen)); + /* 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 - return screen; + return Qnil; } -DEFUN ("screen-visible-p", Fscreen_visible_p, Sscreen_visible_p, +DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p, 1, 1, 0, - "Return t if SCREEN is now \"visible\" (actually in use for display).\n\ -A screen that is not \"visible\" is not updated and, if it works through\n\ + "Return t if FRAME is now \"visible\" (actually in use for display).\n\ +A frame that is not \"visible\" is not updated and, if it works through\n\ a window system, it may not show at all.\n\ -Return the symbol `icon' if window is visible only as an icon.") - (screen) - Lisp_Object screen; +Return the symbol `icon' if frame is visible only as an icon.") + (frame) + Lisp_Object frame; { - CHECK_SCREEN (screen, 0); + CHECK_LIVE_FRAME (frame, 0); - if (XSCREEN (screen)->visible) + if (FRAME_VISIBLE_P (XFRAME (frame))) return Qt; - if (XSCREEN (screen)->iconified) - return intern ("icon"); + if (FRAME_ICONIFIED_P (XFRAME (frame))) + return Qicon; return Qnil; } -DEFUN ("visible-screen-list", Fvisible_screen_list, Svisible_screen_list, +DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list, 0, 0, 0, - "Return a list of all screens now \"visible\" (being updated).") + "Return a list of all frames now \"visible\" (being updated).") () { - Lisp_Object tail, screen; - struct screen *s; + Lisp_Object tail, frame; + struct frame *f; Lisp_Object value; value = Qnil; - for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr) + for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr) { - screen = XCONS (tail)->car; - if (XTYPE (screen) != Lisp_Screen) + frame = XCONS (tail)->car; + if (XTYPE (frame) != Lisp_Frame) continue; - s = XSCREEN (screen); - if (s->visible) - value = Fcons (screen, value); + f = XFRAME (frame); + 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); + + 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; +} + -DEFUN ("redirect-screen-focus", Fredirect_screen_focus, Sredirect_screen_focus, +DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus, 1, 2, 0, - "Arrange for keystrokes typed at SCREEN to be sent to FOCUS-SCREEN.\n\ -This means that, after reading a keystroke typed at SCREEN,\n\ -last-event-screen will be FOCUS-SCREEN.\n\ + "Arrange for keystrokes typed at FRAME to be sent to 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 nil, any existing redirection is\n\ +cancelled, and the frame again receives its own keystrokes.\n\ \n\ -If FOCUS-SCREEN is omitted or eq to SCREEN, any existing redirection is\n\ -cancelled, and the screen again receives its own keystrokes.\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\ -The redirection lasts until the next call to redirect-screen-focus\n\ -or select-screen.\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 screen doesn't have its own minibuffer.") - (screen, focus_screen) - Lisp_Object screen, focus_screen; +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_SCREEN (screen, 0); - if (NULL (focus_screen)) - focus_screen = screen; - else - CHECK_SCREEN (focus_screen, 1); + CHECK_LIVE_FRAME (frame, 0); - XSCREEN (screen)->focus_screen = focus_screen; + if (! NILP (focus_frame)) + CHECK_LIVE_FRAME (focus_frame, 1); - if (screen_rehighlight_hook) - (*screen_rehighlight_hook) (); + XFRAME (frame)->focus_frame = focus_frame; + + if (frame_rehighlight_hook) + (*frame_rehighlight_hook) (); return Qnil; } -DEFUN ("screen-focus", Fscreen_focus, Sscreen_focus, 1, 1, 0, - "Return the screen to which SCREEN's keystrokes are currently being sent.\n\ -See redirect-screen-focus.") - (screen) - Lisp_Object screen; +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_SCREEN (screen, 0); - return SCREEN_FOCUS_SCREEN (XSCREEN (screen)); + CHECK_LIVE_FRAME (frame, 0); + + return FRAME_FOCUS_FRAME (XFRAME (frame)); } Lisp_Object -get_screen_param (screen, prop) - register struct screen *screen; +get_frame_param (frame, prop) + register struct frame *frame; Lisp_Object prop; { register Lisp_Object tem; - tem = Fassq (prop, screen->param_alist); + tem = Fassq (prop, frame->param_alist); if (EQ (tem, Qnil)) return tem; return Fcdr (tem); } void -store_in_alist (alistptr, propname, val) +store_in_alist (alistptr, prop, val) Lisp_Object *alistptr, val; - char *propname; + Lisp_Object prop; { register Lisp_Object tem; - register Lisp_Object prop; - prop = intern (propname); tem = Fassq (prop, *alistptr); if (EQ (tem, Qnil)) *alistptr = Fcons (Fcons (prop, val), *alistptr); @@ -769,294 +1020,347 @@ store_in_alist (alistptr, propname, val) } void -store_screen_param (s, prop, val) - struct screen *s; +store_frame_param (f, prop, val) + struct frame *f; Lisp_Object prop, val; { register Lisp_Object tem; - tem = Fassq (prop, s->param_alist); + tem = Fassq (prop, f->param_alist); if (EQ (tem, Qnil)) - s->param_alist = Fcons (Fcons (prop, val), s->param_alist); + f->param_alist = Fcons (Fcons (prop, val), f->param_alist); else Fsetcdr (tem, val); + + if (EQ (prop, Qminibuffer) + && XTYPE (val) == Lisp_Window) + { + 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."); + + /* Install the chosen minibuffer window, with proper buffer. */ + f->minibuffer_window = val; + } } -DEFUN ("screen-parameters", Fscreen_parameters, Sscreen_parameters, 0, 1, 0, - "Return the parameters-alist of screen SCREEN.\n\ +DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0, + "Return the parameters-alist of frame FRAME.\n\ It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\ -The meaningful PARMs depend on the kind of screen.") - (screen) - Lisp_Object screen; +The meaningful PARMs depend on the kind of frame.\n\ +If FRAME is omitted, return information on the currently selected frame.") + (frame) + Lisp_Object frame; { Lisp_Object alist; - struct screen *s; + struct frame *f; - if (EQ (screen, Qnil)) - s = selected_screen; + if (EQ (frame, Qnil)) + f = selected_frame; else { - CHECK_SCREEN (screen, 0); - s = XSCREEN (screen); + CHECK_FRAME (frame, 0); + f = XFRAME (frame); } - if (s->display.nothing == 0) + if (f->display.nothing == 0) return Qnil; - alist = Fcopy_alist (s->param_alist); - store_in_alist (&alist, "name", s->name); - store_in_alist (&alist, "height", make_number (s->height)); - store_in_alist (&alist, "width", make_number (s->width)); - store_in_alist (&alist, "modeline", (s->wants_modeline ? Qt : Qnil)); - store_in_alist (&alist, "minibuffer", (s->has_minibuffer ? Qt : Qnil)); - store_in_alist (&alist, "unsplittable", (s->no_split ? Qt : Qnil)); - - if (s->output_method == output_x_window) - x_report_screen_params (s, &alist); + 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, 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))); + + /* I think this should be done with a hook. */ +#ifdef HAVE_X_WINDOWS + if (FRAME_X_P (f)) + x_report_frame_params (f, &alist); +#endif return alist; } -DEFUN ("modify-screen-parameters", Fmodify_screen_parameters, - Smodify_screen_parameters, 2, 2, 0, - "Modify the parameters of screen SCREEN according to ALIST.\n\ +DEFUN ("modify-frame-parameters", Fmodify_frame_parameters, + Smodify_frame_parameters, 2, 2, 0, + "Modify the parameters of frame FRAME according to ALIST.\n\ ALIST is an alist of parameters to change and their new values.\n\ Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\ -The meaningful PARMs depend on the kind of screen; undefined PARMs are ignored.") - (screen, alist) - Lisp_Object screen, alist; +The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.") + (frame, alist) + Lisp_Object frame, alist; { - register struct screen *s; + FRAME_PTR f; register Lisp_Object tail, elt, prop, val; - if (EQ (screen, Qnil)) - s = selected_screen; + if (EQ (frame, Qnil)) + f = selected_frame; else { - CHECK_SCREEN (screen, 0); - s = XSCREEN (screen); + CHECK_LIVE_FRAME (frame, 0); + f = XFRAME (frame); } - if (s->display.nothing == 0) - error ("Cannot modify parameters of a deleted screen"); - - if (s->output_method == output_x_window) + /* I think this should be done with a hook. */ +#ifdef HAVE_X_WINDOWS + if (FRAME_X_P (f)) +#if 1 + x_set_frame_parameters (f, alist); +#else for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail)) { elt = Fcar (tail); prop = Fcar (elt); val = Fcdr (elt); - x_set_screen_param (s, prop, val, - get_screen_param (s, prop)); - store_screen_param (s, prop, val); + x_set_frame_param (f, prop, val, get_frame_param (f, prop)); + store_frame_param (f, prop, val); } +#endif +#endif return Qnil; } - -DEFUN ("screen-pixel-size", Fscreen_pixel_size, - Sscreen_pixel_size, 1, 1, 0, - "Return a cons (width . height) of screen SCREEN's dimensions.") - (screen) - Lisp_Object screen; +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 screen *s; - int width, height; + struct frame *f; - CHECK_SCREEN (screen, 0); - s = XSCREEN (screen); - - return Fcons (make_number (x_pixel_width (s)), - make_number (x_pixel_height (s))); + 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); } -DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0, - "Return number of lines available for display on selected screen.") - () + +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 (SCREEN_HEIGHT (selected_screen)); + 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 ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0, - "Return number of columns available for display on selected screen.") - () +DEFUN ("frame-pixel-height", Fframe_pixel_height, + Sframe_pixel_height, 0, 1, 0, + "Return a FRAME's heightin pixels.\n\ +For a terminal frame, the result really gives the sizes in characters.\n\ +If FRAME is omitted, the selected frame is used.") + (frame) + Lisp_Object frame; { - return make_number (SCREEN_WIDTH (selected_screen)); + 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 ("set-screen-height", Fset_screen_height, Sset_screen_height, 2, 3, 0, - "Specify that the screen SCREEN has LINES lines.\n\ +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 sizes 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)); +} + +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 screen should not be changed.") - (screen, rows, pretend) - Lisp_Object rows, pretend; +but that the idea of the actual height of the frame should not be changed.") + (frame, rows, pretend) + Lisp_Object frame, rows, pretend; { - register struct screen *s; + register struct frame *f; CHECK_NUMBER (rows, 0); - if (NULL (screen)) - s = selected_screen; + if (NILP (frame)) + f = selected_frame; else { - CHECK_SCREEN (screen, 0); - s = XSCREEN (screen); + CHECK_LIVE_FRAME (frame, 0); + f = XFRAME (frame); } - if (s->output_method == output_x_window) + /* I think this should be done with a hook. */ +#ifdef HAVE_X_WINDOWS + if (FRAME_X_P (f)) { - if (XINT (rows) != s->width) - x_set_window_size (s, s->width, XINT (rows)); + if (XINT (rows) != f->width) + x_set_window_size (f, f->width, XINT (rows)); } else - change_screen_size (s, XINT (rows), 0, !NULL (pretend)); +#endif + change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0); return Qnil; } -DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 2, 3, 0, - "Specify that the screen SCREEN has COLS columns.\n\ +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 screen should not be changed.") - (screen, cols, pretend) - Lisp_Object cols, pretend; +but that the idea of the actual width of the frame should not be changed.") + (frame, cols, pretend) + Lisp_Object frame, cols, pretend; { - register struct screen *s; + register struct frame *f; CHECK_NUMBER (cols, 0); - if (NULL (screen)) - s = selected_screen; + if (NILP (frame)) + f = selected_frame; else { - CHECK_SCREEN (screen, 0); - s = XSCREEN (screen); + CHECK_LIVE_FRAME (frame, 0); + f = XFRAME (frame); } - if (s->output_method == output_x_window) + /* I think this should be done with a hook. */ +#ifdef HAVE_X_WINDOWS + if (FRAME_X_P (f)) { - if (XINT (cols) != s->width) - x_set_window_size (s, XINT (cols), s->height); + if (XINT (cols) != f->width) + x_set_window_size (f, XINT (cols), f->height); } else - change_screen_size (selected_screen, 0, XINT (cols), !NULL (pretend)); +#endif + change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0); return Qnil; } -DEFUN ("set-screen-size", Fset_screen_size, - Sset_screen_size, 3, 3, 0, - "Sets size of SCREEN to COLS by ROWS, measured in characters.") - (screen, cols, rows) - Lisp_Object screen, cols, rows; +DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, + "Sets size of FRAME to COLS by ROWS, measured in characters.") + (frame, cols, rows) + Lisp_Object frame, cols, rows; { - register struct screen *s; + register struct frame *f; int mask; - CHECK_SCREEN (screen, 0); + CHECK_LIVE_FRAME (frame, 0); CHECK_NUMBER (cols, 2); CHECK_NUMBER (rows, 1); - s = XSCREEN (screen); + f = XFRAME (frame); - if (s->output_method == output_x_window) + /* I think this should be done with a hook. */ +#ifdef HAVE_X_WINDOWS + if (FRAME_X_P (f)) { - if (XINT (rows) != s->height || XINT (cols) != s->width) - x_set_window_size (s, XINT (cols), XINT (rows)); + if (XINT (rows) != f->height || XINT (cols) != f->width) + x_set_window_size (f, XINT (cols), XINT (rows)); } else - change_screen_size (s, XINT (rows), XINT (cols), 0); +#endif + change_frame_size (f, XINT (rows), XINT (cols), 0, 0); return Qnil; } -DEFUN ("set-screen-position", Fset_screen_position, - Sset_screen_position, 3, 3, 0, - "Sets size of SCREEN in pixels to XOFFSET by YOFFSET.") - (screen, xoffset, yoffset) - Lisp_Object screen, xoffset, yoffset; +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.") + (frame, xoffset, yoffset) + Lisp_Object frame, xoffset, yoffset; { - register struct screen *s; + register struct frame *f; int mask; - CHECK_SCREEN (screen, 0); + CHECK_LIVE_FRAME (frame, 0); CHECK_NUMBER (xoffset, 1); CHECK_NUMBER (yoffset, 2); - s = XSCREEN (screen); + f = XFRAME (frame); - if (s->output_method == output_x_window) - x_set_offset (s, XINT (xoffset), XINT (yoffset)); + /* 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)); +#endif return Qt; } - -/* Test if column *x, row *y is within window *w. If they are not, - return 0; if they are on the window's modeline, return -1; if - they are in the window's text area (the only other alternative) - set *x and *y to their locations relative to the upper left - corner of the window, and return 1. */ -int -coordinates_in_window (w, x, y) - register struct window *w; - register int *x, *y; -{ - register int left = XINT (w->left); - register int width = XINT (w->width); - register int window_height = XINT (w->height); - register int top = XFASTINT (w->top); - - if (*x < left || *x >= left + width - || *y < top || *y > top + window_height - 1) - return 0; - - if (*y == top + window_height - 1 - && window_height > 1) /* 1 line => minibuffer */ - /* in modeline */ - return -1; - - *x -= left; - *y -= top; - return 1; -} - -DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, - Scoordinates_in_window_p, 2, 2, 0, - "Return non-nil if COORDINATES are in WINDOW.\n\ -COORDINATES is a cons of the form (X Y), X and Y being screen-relative.\n\ -If COORDINATES are in the text portion of WINDOW, the coordinates relative\n\ -to the window are returned. If they are in the modeline of WINDOW, t is\n\ -returned.") - (coordinates, window) - register Lisp_Object coordinates, window; -{ - int x, y; - - CHECK_WINDOW (window, 0); - CHECK_CONS (coordinates, 1); - x = XINT (Fcar (coordinates)); - y = XINT (Fcar (Fcdr (coordinates))); - - switch (coordinates_in_window (XWINDOW (window), &x, &y)) - { - case -1: /* In modeline of window. */ - return Qt; - - case 0: /* NOT in window at all. */ - return Qnil; - - case 1: /* In text part of window. */ - return Fcons (x, Fcons (y, Qnil)); - default: - abort (); - } -} #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 SCREEN with the mouse.\n\ -Arguments are SCREEN, NAME and GEO. NAME is a name to be displayed as\n\ + "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: (SCREEN LEFT TOP WIDTH HEIGHT).") - (screen, name, geo) - Lisp_Object screen; +Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).") + (frame, name, geo) + Lisp_Object frame; Lisp_Object name; Lisp_Object geo; { @@ -1064,14 +1368,14 @@ Returns a list of five values: (SCREEN LEFT TOP WIDTH HEIGHT).") Lisp_Object nums[4]; int i; - CHECK_SCREEN (screen, 0); + CHECK_FRAME (frame, 0); CHECK_STRING (name, 1); CHECK_STRING (geo, 2); - switch (XSCREEN (screen)->output_method) + switch (XFRAME (frame)->output_method) { case output_x_window: - x_rubber_band (XSCREEN (screen), &vals[0], &vals[1], &vals[2], &vals[3], + x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3], XSTRING (geo)->data, XSTRING (name)->data); break; @@ -1081,80 +1385,312 @@ Returns a list of five values: (SCREEN LEFT TOP WIDTH HEIGHT).") for (i = 0; i < 4; i++) XFASTINT (nums[i]) = vals[i]; - return Fcons (screen, Flist (4, nums)); + return Fcons (frame, Flist (4, nums)); return Qnil; } #endif /* not HAVE_X11 */ -choose_minibuf_screen () +choose_minibuf_frame () { - /* For lowest-level minibuf, put it on currently selected screen - if screen has a minibuffer. */ + /* For lowest-level minibuf, put it on currently selected frame + if frame has a minibuffer. */ + if (minibuf_level == 0 - && selected_screen != 0 - && !EQ (minibuf_window, selected_screen->minibuffer_window) - && !EQ (Qnil, selected_screen->minibuffer_window)) + && selected_frame != 0 + && !EQ (minibuf_window, selected_frame->minibuffer_window)) { - Fset_window_buffer (selected_screen->minibuffer_window, + /* I don't think that any frames may validly have a null minibuffer + window anymore. */ + if (NILP (selected_frame->minibuffer_window)) + abort (); + + Fset_window_buffer (selected_frame->minibuffer_window, XWINDOW (minibuf_window)->buffer); - minibuf_window = selected_screen->minibuffer_window; + minibuf_window = selected_frame->minibuffer_window; } } -syms_of_screen () +syms_of_frame () { - Qscreenp = intern ("screenp"); - - staticpro (&Vscreen_list); - - DEFVAR_LISP ("terminal-screen", &Vterminal_screen, - "The initial screen-object, which represents Emacs's stdout."); + /*&&& init symbols here &&&*/ + Qframep = intern ("framep"); + staticpro (&Qframep); + Qframe_live_p = intern ("frame-live-p"); + staticpro (&Qframe_live_p); + Qheight = intern ("height"); + staticpro (&Qheight); + Qicon = intern ("icon"); + staticpro (&Qicon); + Qminibuffer = intern ("minibuffer"); + staticpro (&Qminibuffer); + Qmodeline = intern ("modeline"); + staticpro (&Qmodeline); + Qname = intern ("name"); + staticpro (&Qname); + Qonly = intern ("only"); + staticpro (&Qonly); + Qunsplittable = intern ("unsplittable"); + staticpro (&Qunsplittable); + Qwidth = intern ("width"); + staticpro (&Qwidth); + Qx = intern ("x"); + staticpro (&Qx); + Qmenu_bar_lines = intern ("menu-bar-lines"); + staticpro (&Qmenu_bar_lines); + + staticpro (&Vframe_list); + + DEFVAR_LISP ("terminal-frame", &Vterminal_frame, + "The initial frame-object, which represents Emacs's stdout."); DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified, - "Non-nil if all of emacs is iconified and not screen updates are needed."); + "Non-nil if all of emacs is iconified and frame updates are not needed."); Vemacs_iconified = Qnil; - DEFVAR_LISP ("global-minibuffer-screen", &Vglobal_minibuffer_screen, - "A screen whose minibuffer is used by minibufferless screens.\n\ -When you create a minibufferless screen, by default it will use the\n\ -minibuffer of this screen. It is up to you to create a suitable screen\n\ -and store it in this variable."); - Vglobal_minibuffer_screen = Qnil; - - defsubr (&Sscreenp); - defsubr (&Sselect_screen); - defsubr (&Sselected_screen); - defsubr (&Swindow_screen); - defsubr (&Sscreen_root_window); - defsubr (&Sscreen_selected_window); - defsubr (&Sscreen_list); - defsubr (&Snext_screen); - defsubr (&Sdelete_screen); - defsubr (&Sread_mouse_position); + DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame, + "Minibufferless frames use this frame's minibuffer.\n\ +\n\ +Emacs cannot create minibufferless frames unless this is set to an\n\ +appropriate surrogate.\n\ +\n\ +Emacs consults this variable only when creating minibufferless\n\ +frames; once the frame is created, it sticks with its assigned\n\ +minibuffer, no matter what this variable is set to. This means that\n\ +this variable doesn't necessarily say anything meaningful about the\n\ +current set of frames, or where the minibuffer is currently being\n\ +displayed."); + Vdefault_minibuffer_frame = Qnil; + + DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist, + "Alist of default values for frame creation.\n\ +These may be set in your init file, like this:\n\ + (setq default-frame-alist '((width . 80) (height . 55)))\n\ +These override values given in window system configuration data, like\n\ +X Windows' defaults database.\n\ +For values specific to the first Emacs frame, see `initial-frame-alist'.\n\ +For values specific to the separate minibuffer frame, see\n\ +`minibuffer-frame-alist'."); + Vdefault_frame_alist = Qnil; + + defsubr (&Sframep); + defsubr (&Sframe_live_p); + defsubr (&Shandle_switch_frame); + defsubr (&Sselect_frame); + defsubr (&Sselected_frame); + defsubr (&Swindow_frame); + defsubr (&Sframe_root_window); + defsubr (&Sframe_selected_window); + defsubr (&Sframe_list); + defsubr (&Snext_frame); + defsubr (&Sdelete_frame); + defsubr (&Smouse_position); defsubr (&Sset_mouse_position); #if 0 - defsubr (&Sscreen_configuration); - defsubr (&Srestore_screen_configuration); + defsubr (&Sframe_configuration); + defsubr (&Srestore_frame_configuration); #endif - defsubr (&Smake_screen_visible); - defsubr (&Smake_screen_invisible); - defsubr (&Siconify_screen); - defsubr (&Sdeiconify_screen); - defsubr (&Sscreen_visible_p); - defsubr (&Svisible_screen_list); - defsubr (&Sredirect_screen_focus); - defsubr (&Sscreen_focus); - defsubr (&Sscreen_parameters); - defsubr (&Smodify_screen_parameters); - defsubr (&Sscreen_pixel_size); - defsubr (&Sscreen_height); - defsubr (&Sscreen_width); - defsubr (&Sset_screen_height); - defsubr (&Sset_screen_width); - defsubr (&Sset_screen_size); - defsubr (&Sset_screen_position); - defsubr (&Scoordinates_in_window_p); + defsubr (&Smake_frame_visible); + defsubr (&Smake_frame_invisible); + defsubr (&Siconify_frame); + defsubr (&Sframe_visible_p); + defsubr (&Svisible_frame_list); + defsubr (&Sraise_frame); + defsubr (&Slower_frame); + defsubr (&Sredirect_frame_focus); + defsubr (&Sframe_focus); + defsubr (&Sframe_parameters); + defsubr (&Smodify_frame_parameters); + defsubr (&Sframe_char_height); + defsubr (&Sframe_char_width); + defsubr (&Sframe_pixel_height); + defsubr (&Sframe_pixel_width); + defsubr (&Sset_frame_height); + defsubr (&Sset_frame_width); + defsubr (&Sset_frame_size); + defsubr (&Sset_frame_position); #ifndef HAVE_X11 defsubr (&Srubber_band_rectangle); #endif /* HAVE_X11 */ } + +keys_of_frame () +{ + initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame"); +} + +#else /* not MULTI_FRAME */ + +/* If we're not using multi-frame stuff, we still need to provide some + support functions. */ + +/* 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.") + () +{ + Lisp_Object tem; + XFASTINT (tem) = 0; + return tem; +} + +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.") + (frame, rows, pretend) + Lisp_Object frame, rows, pretend; +{ + CHECK_NUMBER (rows, 0); + + change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0); + return Qnil; +} + +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.") + (frame, cols, pretend) + Lisp_Object frame, cols, pretend; +{ + CHECK_NUMBER (cols, 0); + + change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0); + return Qnil; +} + +DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0, + "Sets size of FRAME to COLS by ROWS, measured in characters.") + (frame, cols, rows) + Lisp_Object frame, cols, rows; +{ + CHECK_NUMBER (cols, 2); + CHECK_NUMBER (rows, 1); + + change_frame_size (0, XINT (rows), XINT (cols), 0, 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.") + (frame) + Lisp_Object frame; +{ + return make_number (FRAME_HEIGHT (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, + "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; +{ + return make_number (1); +} + + +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 (1); +} + +DEFUN ("frame-pixel-height", Fframe_pixel_height, + Sframe_pixel_height, 0, 1, 0, + "Return 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_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; +{ + 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, + "Tell redisplay that the screen has LINES lines.\n\ +Optional second arg non-nil means that redisplay should use LINES lines\n\ +but that the idea of the actual height of the screen should not be changed.") + (lines, pretend) + Lisp_Object lines, pretend; +{ + CHECK_NUMBER (lines, 0); + + change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0); + return Qnil; +} + +DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0, + "Tell redisplay that the screen has COLS columns.\n\ +Optional second arg non-nil means that redisplay should use COLS columns\n\ +but that the idea of the actual width of the screen should not be changed.") + (cols, pretend) + Lisp_Object cols, pretend; +{ + CHECK_NUMBER (cols, 0); + + change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0); + return Qnil; +} + +syms_of_frame () +{ + defsubr (&Sselected_frame); + 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_screen_height); + defsubr (&Sset_screen_width); + defsubr (&Sframe_height); + Ffset (intern ("screen-height"), intern ("frame-height")); + defsubr (&Sframe_width); + Ffset (intern ("screen-width"), intern ("frame-width")); +} + +keys_of_frame () +{ +} + +#endif /* not MULTI_FRAME */ + + + +