(Fdisplay_buffer): If pop_up_frames != 0,
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
c6c5df7f 2 Copyright (C) 1993 Free Software Foundation.
dc6f92b8
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
1113d9db 8the Free Software Foundation; either version 2, or (at your option)
dc6f92b8
JB
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
d5e7c279
JB
20#include <stdio.h>
21
18160b98 22#include <config.h>
cc38027b
JB
23#include "lisp.h"
24#include "frame.h"
bc1ed486 25#include "termhooks.h"
e5d77022 26
ff11dfa1 27#ifdef MULTI_FRAME
e5d77022 28
bff19c8d 29#include "buffer.h"
dc6f92b8
JB
30#include "window.h"
31
2f0b07e0
JB
32/* These help us bind and responding to switch-frame events. */
33#include "commands.h"
34#include "keyboard.h"
35
dc6f92b8 36Lisp_Object Vemacs_iconified;
ff11dfa1
JB
37Lisp_Object Vframe_list;
38Lisp_Object Vterminal_frame;
39Lisp_Object Vdefault_minibuffer_frame;
40Lisp_Object Vdefault_frame_alist;
fd0c2bd1
JB
41
42/* Evaluate this expression to rebuild the section of syms_of_frame
43 that initializes and staticpros the symbols declared below. Note
44 that Emacs 18 has a bug that keeps C-x C-e from being able to
45 evaluate this expression.
46
47(progn
48 ;; Accumulate a list of the symbols we want to initialize from the
49 ;; declarations at the top of the file.
50 (goto-char (point-min))
51 (search-forward "/\*&&& symbols declared here &&&*\/\n")
52 (let (symbol-list)
53 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
54 (setq symbol-list
55 (cons (buffer-substring (match-beginning 1) (match-end 1))
56 symbol-list))
57 (forward-line 1))
58 (setq symbol-list (nreverse symbol-list))
59 ;; Delete the section of syms_of_... where we initialize the symbols.
60 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
61 (let ((start (point)))
62 (while (looking-at "^ Q")
63 (forward-line 2))
64 (kill-region start (point)))
65 ;; Write a new symbol initialization section.
66 (while symbol-list
67 (insert (format " %s = intern (\"" (car symbol-list)))
68 (let ((start (point)))
69 (insert (substring (car symbol-list) 1))
70 (subst-char-in-region start (point) ?_ ?-))
71 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
72 (setq symbol-list (cdr symbol-list)))))
73 */
74
75/*&&& symbols declared here &&&*/
76Lisp_Object Qframep;
dbc4e1c1 77Lisp_Object Qframe_live_p;
fd0c2bd1
JB
78Lisp_Object Qheight;
79Lisp_Object Qicon;
bc93c097 80Lisp_Object Qminibuffer;
fd0c2bd1
JB
81Lisp_Object Qmodeline;
82Lisp_Object Qname;
fd0c2bd1
JB
83Lisp_Object Qonly;
84Lisp_Object Qunsplittable;
fa8fdbf9 85Lisp_Object Qmenu_bar_lines;
fd0c2bd1
JB
86Lisp_Object Qwidth;
87Lisp_Object Qx;
f7af3f7b 88Lisp_Object Qvisible;
dc6f92b8
JB
89
90extern Lisp_Object Vminibuffer_list;
91extern Lisp_Object get_minibuffer ();
84386599
RS
92extern Lisp_Object Fhandle_switch_frame ();
93extern Lisp_Object Fredirect_frame_focus ();
dc6f92b8 94\f
ff11dfa1
JB
95DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
96 "Return non-nil if OBJECT is a frame.\n\
97Value is t for a termcap frame (a character-only terminal),\n\
98`x' for an Emacs frame that is really an X window.\n\
99Also see `live-frame-p'.")
f9898cc6
JB
100 (object)
101 Lisp_Object object;
dc6f92b8 102{
ff11dfa1 103 if (XTYPE (object) != Lisp_Frame)
dc6f92b8 104 return Qnil;
ff11dfa1 105 switch (XFRAME (object)->output_method)
dc6f92b8
JB
106 {
107 case output_termcap:
108 return Qt;
109 case output_x_window:
fd0c2bd1 110 return Qx;
dc6f92b8
JB
111 default:
112 abort ();
113 }
114}
115
dbc4e1c1 116DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
ff11dfa1
JB
117 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
118Value is nil if OBJECT is not a live frame. If object is a live\n\
119frame, the return value indicates what sort of output device it is\n\
120displayed on. Value is t for a termcap frame (a character-only\n\
121terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
122 (object)
123 Lisp_Object object;
124{
ff11dfa1
JB
125 return ((FRAMEP (object)
126 && FRAME_LIVE_P (XFRAME (object)))
127 ? Fframep (object)
f9898cc6
JB
128 : Qnil);
129}
130
ff11dfa1
JB
131struct frame *
132make_frame (mini_p)
dc6f92b8
JB
133 int mini_p;
134{
ff11dfa1
JB
135 Lisp_Object frame;
136 register struct frame *f;
dc6f92b8
JB
137 register Lisp_Object root_window;
138 register Lisp_Object mini_window;
139
ff11dfa1 140 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
d5e7c279
JB
141 - sizeof (Lisp_Object)))
142 / sizeof (Lisp_Object)),
dc6f92b8 143 make_number (0));
ff11dfa1
JB
144 XSETTYPE (frame, Lisp_Frame);
145 f = XFRAME (frame);
146
147 f->cursor_x = 0;
148 f->cursor_y = 0;
149 f->current_glyphs = 0;
150 f->desired_glyphs = 0;
151 f->visible = 0;
323405de 152 f->async_visible = 0;
ff11dfa1
JB
153 f->display.nothing = 0;
154 f->iconified = 0;
323405de 155 f->async_iconified = 0;
ff11dfa1
JB
156 f->wants_modeline = 1;
157 f->auto_raise = 0;
158 f->auto_lower = 0;
159 f->no_split = 0;
160 f->garbaged = 0;
161 f->has_minibuffer = mini_p;
a42e9724 162 f->focus_frame = Qnil;
804518aa 163 f->explicit_name = 0;
fd2777e0
JB
164 f->can_have_scroll_bars = 0;
165 f->has_vertical_scroll_bars = 0;
ff11dfa1 166 f->param_alist = Qnil;
fd2777e0
JB
167 f->scroll_bars = Qnil;
168 f->condemned_scroll_bars = Qnil;
306cc902 169 f->face_alist = Qnil;
9dd935ee 170 f->menu_bar_items = Qnil;
dc6f92b8 171
cc38027b 172 root_window = make_window ();
dc6f92b8
JB
173 if (mini_p)
174 {
cc38027b 175 mini_window = make_window ();
dc6f92b8
JB
176 XWINDOW (root_window)->next = mini_window;
177 XWINDOW (mini_window)->prev = root_window;
178 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
179 XWINDOW (mini_window)->frame = frame;
180 f->minibuffer_window = mini_window;
dc6f92b8
JB
181 }
182 else
183 {
184 mini_window = Qnil;
185 XWINDOW (root_window)->next = Qnil;
ff11dfa1 186 f->minibuffer_window = Qnil;
dc6f92b8
JB
187 }
188
ff11dfa1 189 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
190
191 /* 10 is arbitrary,
192 just so that there is "something there."
ff11dfa1 193 Correct size will be set up later with change_frame_size. */
dc6f92b8 194
ff11dfa1
JB
195 f->width = 10;
196 f->height = 10;
dc6f92b8
JB
197
198 XFASTINT (XWINDOW (root_window)->width) = 10;
199 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
200
201 if (mini_p)
202 {
203 XFASTINT (XWINDOW (mini_window)->width) = 10;
204 XFASTINT (XWINDOW (mini_window)->top) = 9;
205 XFASTINT (XWINDOW (mini_window)->height) = 1;
206 }
207
ff11dfa1 208 /* Choose a buffer for the frame's root window. */
5bce042c
JB
209 {
210 Lisp_Object buf;
211
212 XWINDOW (root_window)->buffer = Qt;
213 buf = Fcurrent_buffer ();
214 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
215 a space), try to find another one. */
216 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 217 buf = Fother_buffer (buf, Qnil);
5bce042c
JB
218 Fset_window_buffer (root_window, buf);
219 }
220
dc6f92b8
JB
221 if (mini_p)
222 {
223 XWINDOW (mini_window)->buffer = Qt;
224 Fset_window_buffer (mini_window,
265a9e55 225 (NILP (Vminibuffer_list)
dc6f92b8
JB
226 ? get_minibuffer (0)
227 : Fcar (Vminibuffer_list)));
228 }
229
ff11dfa1
JB
230 f->root_window = root_window;
231 f->selected_window = root_window;
d5e7c279
JB
232 /* Make sure this window seems more recently used than
233 a newly-created, never-selected window. */
ff11dfa1 234 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
dc6f92b8 235
ff11dfa1 236 return f;
dc6f92b8
JB
237}
238\f
ff11dfa1 239/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
240 MINI_WINDOW is the minibuffer window to use. nil means use the
241 default (the global minibuffer). */
242
ff11dfa1
JB
243struct frame *
244make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
245 register Lisp_Object mini_window;
246{
ff11dfa1 247 register struct frame *f;
dc6f92b8
JB
248
249 /* Choose the minibuffer window to use. */
265a9e55 250 if (NILP (mini_window))
dc6f92b8 251 {
ff11dfa1
JB
252 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
253 error ("default-minibuffer-frame must be set when creating minibufferless frames");
254 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
255 error ("default-minibuffer-frame must be a live frame");
256 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
257 }
258 else
259 {
774910eb 260 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8
JB
261 }
262
ff11dfa1
JB
263 /* Make a frame containing just a root window. */
264 f = make_frame (0);
dc6f92b8
JB
265
266 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 267 f->minibuffer_window = mini_window;
dc6f92b8 268 Fset_window_buffer (mini_window,
265a9e55 269 (NILP (Vminibuffer_list)
dc6f92b8
JB
270 ? get_minibuffer (0)
271 : Fcar (Vminibuffer_list)));
ff11dfa1 272 return f;
dc6f92b8
JB
273}
274
ff11dfa1 275/* Make a frame containing only a minibuffer window. */
dc6f92b8 276
ff11dfa1
JB
277struct frame *
278make_minibuffer_frame ()
dc6f92b8 279{
ff11dfa1 280 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 281
ff11dfa1 282 register struct frame *f = make_frame (0);
dc6f92b8 283 register Lisp_Object mini_window;
ff11dfa1 284 register Lisp_Object frame;
dc6f92b8 285
ff11dfa1 286 XSET (frame, Lisp_Frame, f);
dc6f92b8 287
804518aa 288 f->auto_raise = 0;
ff11dfa1
JB
289 f->auto_lower = 0;
290 f->no_split = 1;
291 f->wants_modeline = 0;
292 f->has_minibuffer = 1;
dc6f92b8
JB
293
294 /* Now label the root window as also being the minibuffer.
295 Avoid infinite looping on the window chain by marking next pointer
296 as nil. */
297
ff11dfa1 298 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
299 XWINDOW (mini_window)->mini_p = Qt;
300 XWINDOW (mini_window)->next = Qnil;
804518aa 301 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 302 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
303
304 /* Put the proper buffer in that window. */
305
306 Fset_window_buffer (mini_window,
265a9e55 307 (NILP (Vminibuffer_list)
dc6f92b8
JB
308 ? get_minibuffer (0)
309 : Fcar (Vminibuffer_list)));
ff11dfa1 310 return f;
dc6f92b8
JB
311}
312\f
ff11dfa1 313/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 314
ff11dfa1
JB
315struct frame *
316make_terminal_frame ()
dc6f92b8 317{
ff11dfa1 318 register struct frame *f;
d063751a 319 Lisp_Object frame;
ff11dfa1
JB
320
321 Vframe_list = Qnil;
322 f = make_frame (1);
d063751a
RS
323
324 XSET (frame, Lisp_Frame, f);
325 Vframe_list = Fcons (frame, Vframe_list);
326
ff11dfa1 327 f->name = build_string ("terminal");
a42e9724 328 FRAME_SET_VISIBLE (f, 1);
ff11dfa1
JB
329 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
330 XSET (Vterminal_frame, Lisp_Frame, f);
331 return f;
dc6f92b8
JB
332}
333\f
2f0b07e0 334DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
0f85737c 335 "Select the frame FRAME.\n\
eb8c3be9 336Subsequent editing commands apply to its selected window.\n\
0f85737c
JB
337The selection of FRAME lasts until the next time the user does\n\
338something to select a different frame, or until the next time this\n\
339function is called.")
340 (frame, no_enter)
341 Lisp_Object frame, no_enter;
342{
343 return Fhandle_switch_frame (frame, no_enter);
344}
345
346
347DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
348 "Handle a switch-frame event EVENT.\n\
a375dcc0 349Switch-frame events are usually bound to this function.\n\
0f85737c
JB
350A switch-frame event tells Emacs that the window manager has requested\n\
351that the user's events be directed to the frame mentioned in the event.\n\
352This function selects the selected window of the frame of EVENT.\n\
a42e9724 353\n\
0f85737c
JB
354If EVENT is frame object, handle it as if it were a switch-frame event\n\
355to that frame.")
ff11dfa1
JB
356 (frame, no_enter)
357 Lisp_Object frame, no_enter;
dc6f92b8 358{
2f0b07e0
JB
359 /* If FRAME is a switch-frame event, extract the frame we should
360 switch to. */
361 if (CONSP (frame)
362 && EQ (XCONS (frame)->car, Qswitch_frame)
363 && CONSP (XCONS (frame)->cdr))
364 frame = XCONS (XCONS (frame)->cdr)->car;
365
ff11dfa1 366 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 367
ff11dfa1
JB
368 if (selected_frame == XFRAME (frame))
369 return frame;
dc6f92b8 370
a42e9724
JB
371 /* If a frame's focus has been redirected toward the currently
372 selected frame, we should change the redirection to point to the
373 newly selected frame. This means that if the focus is redirected
374 from a minibufferless frame to a surrogate minibuffer frame, we
375 can use `other-window' to switch between all the frames using
376 that minibuffer frame, and the focus redirection will follow us
377 around. */
378 {
379 Lisp_Object tail;
380
381 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
382 {
383 Lisp_Object focus;
384
385 if (XTYPE (XCONS (tail)->car) != Lisp_Frame)
386 abort ();
387
388 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
389
390 if (XTYPE (focus) == Lisp_Frame
391 && XFRAME (focus) == selected_frame)
392 Fredirect_frame_focus (XCONS (tail)->car, frame);
393 }
394 }
395
ff11dfa1
JB
396 selected_frame = XFRAME (frame);
397 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
398 last_nonminibuf_frame = selected_frame;
d5e7c279 399
ff11dfa1 400 Fselect_window (XFRAME (frame)->selected_window);
ff11dfa1 401 choose_minibuf_frame ();
dc6f92b8 402
074577b8 403 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 404 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
405 before you take it out, make sure that evaluating something like
406 (select-window (frame-root-window (new-frame))) doesn't end up
407 with your typing being interpreted in the new frame instead of
408 the one you're actually typing in. */
fd2777e0 409 internal_last_event_frame = Qnil;
074577b8 410
ff11dfa1 411 return frame;
dc6f92b8
JB
412}
413
ff11dfa1
JB
414DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
415 "Return the frame that is now selected.")
dc6f92b8
JB
416 ()
417{
418 Lisp_Object tem;
ff11dfa1 419 XSET (tem, Lisp_Frame, selected_frame);
dc6f92b8
JB
420 return tem;
421}
422
ff11dfa1
JB
423DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
424 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
425 (window)
426 Lisp_Object window;
427{
774910eb 428 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 429 return XWINDOW (window)->frame;
dc6f92b8
JB
430}
431
ff11dfa1 432DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
433 "Returns the root-window of FRAME.\n\
434If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
435 (frame)
436 Lisp_Object frame;
dc6f92b8 437{
ff11dfa1
JB
438 if (NILP (frame))
439 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 440 else
ff11dfa1 441 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 442
ff11dfa1 443 return XFRAME (frame)->root_window;
dc6f92b8
JB
444}
445
ff11dfa1
JB
446DEFUN ("frame-selected-window", Fframe_selected_window,
447 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
448 "Return the selected window of frame object FRAME.\n\
449If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
450 (frame)
451 Lisp_Object frame;
dc6f92b8 452{
ff11dfa1
JB
453 if (NILP (frame))
454 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 455 else
ff11dfa1 456 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 457
ff11dfa1 458 return XFRAME (frame)->selected_window;
dc6f92b8
JB
459}
460
ff11dfa1 461DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 462 0, 0, 0,
ff11dfa1 463 "Return a list of all frames.")
dc6f92b8
JB
464 ()
465{
ff11dfa1 466 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
467}
468
ff11dfa1 469/* Return the next frame in the frame list after FRAME.
ff11dfa1
JB
470 If MINIBUF is nil, exclude minibuffer-only frames.
471 If MINIBUF is a window, include only frames using that window for
d06a8a56 472 their minibuffer.
f7af3f7b
RS
473 If MINIBUF is `visible', include all visible frames.
474 Otherwise, include all frames. */
475
dc6f92b8 476Lisp_Object
ff11dfa1
JB
477next_frame (frame, minibuf)
478 Lisp_Object frame;
f9898cc6 479 Lisp_Object minibuf;
dc6f92b8
JB
480{
481 Lisp_Object tail;
482 int passed = 0;
483
ff11dfa1
JB
484 /* There must always be at least one frame in Vframe_list. */
485 if (! CONSP (Vframe_list))
f9898cc6
JB
486 abort ();
487
dbc4e1c1
JB
488 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
489 forever. Forestall that. */
490 CHECK_LIVE_FRAME (frame, 0);
491
dc6f92b8 492 while (1)
ff11dfa1 493 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 494 {
d06a8a56
JB
495 Lisp_Object f = XCONS (tail)->car;
496
dc6f92b8 497 if (passed)
d5e7c279 498 {
d06a8a56
JB
499 /* Decide whether this frame is eligible to be returned. */
500
501 /* If we've looped all the way around without finding any
502 eligible frames, return the original frame. */
503 if (EQ (f, frame))
504 return f;
505
506 /* Let minibuf decide if this frame is acceptable. */
507 if (NILP (minibuf))
508 {
509 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
510 return f;
511 }
f7af3f7b
RS
512 else if (EQ (minibuf, Qvisible))
513 {
514 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
515 if (FRAME_VISIBLE_P (XFRAME (f)))
516 return f;
517 }
518 else if (WINDOWP (minibuf))
d06a8a56
JB
519 {
520 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
521 return f;
522 }
523 else
ff11dfa1 524 return f;
d5e7c279 525 }
dc6f92b8 526
d06a8a56 527 if (EQ (frame, f))
dc6f92b8
JB
528 passed++;
529 }
530}
531
ff11dfa1 532/* Return the previous frame in the frame list before FRAME.
ff11dfa1
JB
533 If MINIBUF is nil, exclude minibuffer-only frames.
534 If MINIBUF is a window, include only frames using that window for
d06a8a56 535 their minibuffer.
f7af3f7b
RS
536 If MINIBUF is `visible', include all visible frames.
537 Otherwise, include all frames. */
538
dc6f92b8 539Lisp_Object
ff11dfa1
JB
540prev_frame (frame, minibuf)
541 Lisp_Object frame;
f9898cc6 542 Lisp_Object minibuf;
dc6f92b8
JB
543{
544 Lisp_Object tail;
545 Lisp_Object prev;
546
ff11dfa1
JB
547 /* There must always be at least one frame in Vframe_list. */
548 if (! CONSP (Vframe_list))
f9898cc6
JB
549 abort ();
550
dc6f92b8 551 prev = Qnil;
d06a8a56 552 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 553 {
d06a8a56 554 Lisp_Object f = XCONS (tail)->car;
f9898cc6 555
d06a8a56
JB
556 if (XTYPE (f) != Lisp_Frame)
557 abort ();
f9898cc6 558
d06a8a56
JB
559 if (EQ (frame, f) && !NILP (prev))
560 return prev;
f9898cc6 561
d06a8a56
JB
562 /* Decide whether this frame is eligible to be returned,
563 according to minibuf. */
564 if (NILP (minibuf))
565 {
566 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
567 prev = f;
f9898cc6 568 }
d06a8a56
JB
569 else if (XTYPE (minibuf) == Lisp_Window)
570 {
571 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf))
572 prev = f;
573 }
f7af3f7b
RS
574 else if (EQ (minibuf, Qvisible))
575 {
576 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
577 if (FRAME_VISIBLE_P (XFRAME (f)))
578 prev = f;
579 }
d06a8a56
JB
580 else
581 prev = f;
f9898cc6 582 }
d06a8a56
JB
583
584 /* We've scanned the entire list. */
585 if (NILP (prev))
586 /* We went through the whole frame list without finding a single
587 acceptable frame. Return the original frame. */
588 return frame;
589 else
590 /* There were no acceptable frames in the list before FRAME; otherwise,
591 we would have returned directly from the loop. Since PREV is the last
592 acceptable frame in the list, return it. */
593 return prev;
dc6f92b8
JB
594}
595
ef2c57ac 596
ff11dfa1
JB
597DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
598 "Return the next frame in the frame list after FRAME.\n\
a42e9724 599By default, skip minibuffer-only frames.\n\
d06a8a56 600If omitted, FRAME defaults to the selected frame.\n\
c08c95c7 601If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
8693ca83 602If MINIFRAME is a window, include only frames using that window for their\n\
d06a8a56 603minibuffer.\n\
f7af3f7b
RS
604If MINIFRAME is `visible', include all visible frames.\n\
605Otherwise, include all frames.")
ff11dfa1 606 (frame, miniframe)
8693ca83 607 Lisp_Object frame, miniframe;
dc6f92b8
JB
608{
609 Lisp_Object tail;
610
ff11dfa1
JB
611 if (NILP (frame))
612 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 613 else
ff11dfa1 614 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 615
ff11dfa1 616 return next_frame (frame, miniframe);
dc6f92b8 617}
dbc4e1c1 618
ef2c57ac
RM
619DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
620 "Return the previous frame in the frame list before FRAME.\n\
621By default, skip minibuffer-only frames.\n\
622If omitted, FRAME defaults to the selected frame.\n\
623If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
624If MINIFRAME is a window, include only frames using that window for their\n\
625minibuffer.\n\
f7af3f7b
RS
626If MINIFRAME is `visible', include all visible frames.\n\
627Otherwise, include all frames.")
ef2c57ac
RM
628 (frame, miniframe)
629 Lisp_Object frame, miniframe;
630{
631 Lisp_Object tail;
632
633 if (NILP (frame))
634 XSET (frame, Lisp_Frame, selected_frame);
635 else
636 CHECK_LIVE_FRAME (frame, 0);
637
638 return prev_frame (frame, miniframe);
639}
dc6f92b8 640\f
808c0f20
RS
641/* Return 1 if it is ok to delete frame F;
642 0 if all frames aside from F are invisible.
643 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 644
808c0f20
RS
645static int
646other_visible_frames (f)
647 FRAME_PTR f;
648{
649 /* We know the selected frame is visible,
650 so if F is some other frame, it can't be the sole visible one. */
651 if (f == selected_frame)
c08c95c7
RS
652 {
653 Lisp_Object frames;
654 int count = 0;
655
656 for (frames = Vframe_list;
657 CONSP (frames);
658 frames = XCONS (frames)->cdr)
659 {
660 Lisp_Object this = XCONS (frames)->car;
661
808c0f20
RS
662 /* Verify that the frame's window still exists
663 and we can still talk to it. And note any recent change
664 in visibility. */
5e7b7c5b
RS
665#ifdef HAVE_X_WINDOWS
666 if (FRAME_X_P (XFRAME (this)))
667 {
668 x_sync (this);
669 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
670 }
671#endif
672
c08c95c7
RS
673 if (FRAME_VISIBLE_P (XFRAME (this))
674 || FRAME_ICONIFIED_P (XFRAME (this))
675 /* Allow deleting the terminal frame when at least
676 one X frame exists! */
9fbb139c 677 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
c08c95c7
RS
678 count++;
679 }
808c0f20 680 return count > 1;
c08c95c7 681 }
808c0f20
RS
682 return 1;
683}
684
685DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
686 "Delete FRAME, permanently eliminating it from use.\n\
687If omitted, FRAME defaults to the selected frame.\n\
688A frame may not be deleted if its minibuffer is used by other frames.\n\
689Normally, you may not delete a frame if all other frames are invisible,\n\
690but if the second optional argument FORCE is non-nil, you may do so.")
691 (frame, force)
692 Lisp_Object frame, force;
693{
694 struct frame *f;
695
696 if (EQ (frame, Qnil))
697 {
698 f = selected_frame;
699 XSET (frame, Lisp_Frame, f);
700 }
701 else
702 {
703 CHECK_FRAME (frame, 0);
704 f = XFRAME (frame);
705 }
706
707 if (! FRAME_LIVE_P (f))
708 return Qnil;
709
710 if (NILP (force) && !other_visible_frames (f))
711 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 712
ff11dfa1
JB
713 /* Does this frame have a minibuffer, and is it the surrogate
714 minibuffer for any other frame? */
fd0c2bd1 715 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 716 {
ff11dfa1 717 Lisp_Object frames;
1113d9db 718
ff11dfa1
JB
719 for (frames = Vframe_list;
720 CONSP (frames);
721 frames = XCONS (frames)->cdr)
1113d9db 722 {
7a8cc307
RS
723 Lisp_Object this;
724 this = XCONS (frames)->car;
1113d9db 725
ff11dfa1
JB
726 if (! EQ (this, frame)
727 && EQ (frame,
7a8cc307
RS
728 WINDOW_FRAME (XWINDOW
729 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 730 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 731 }
dc6f92b8
JB
732 }
733
ff11dfa1
JB
734 /* Don't let the frame remain selected. */
735 if (f == selected_frame)
0f85737c 736 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
dc6f92b8 737
ff11dfa1
JB
738 /* Don't allow minibuf_window to remain on a deleted frame. */
739 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 740 {
ff11dfa1 741 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 742 XWINDOW (minibuf_window)->buffer);
ff11dfa1 743 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
744 }
745
4a88b3b0
JB
746 /* Mark all the windows that used to be on FRAME as deleted, and then
747 remove the reference to them. */
748 delete_all_subwindows (XWINDOW (f->root_window));
749 f->root_window = Qnil;
750
ff11dfa1 751 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 752 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 753
8678b9cc
JB
754 /* Since some events are handled at the interrupt level, we may get
755 an event for f at any time; if we zero out the frame's display
756 now, then we may trip up the event-handling code. Instead, we'll
757 promise that the display of the frame must be valid until we have
758 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
759
760 /* I think this should be done with a hook. */
d5e7c279 761#ifdef HAVE_X_WINDOWS
fd0c2bd1 762 if (FRAME_X_P (f))
8678b9cc 763 x_destroy_window (f);
d5e7c279
JB
764#endif
765
8678b9cc
JB
766 f->display.nothing = 0;
767
ff11dfa1 768 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 769 another one. */
ff11dfa1 770 if (f == last_nonminibuf_frame)
d5e7c279 771 {
ff11dfa1 772 Lisp_Object frames;
1113d9db 773
ff11dfa1 774 last_nonminibuf_frame = 0;
d5e7c279 775
ff11dfa1
JB
776 for (frames = Vframe_list;
777 CONSP (frames);
778 frames = XCONS (frames)->cdr)
d5e7c279 779 {
ff11dfa1
JB
780 f = XFRAME (XCONS (frames)->car);
781 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 782 {
ff11dfa1 783 last_nonminibuf_frame = f;
d5e7c279
JB
784 break;
785 }
786 }
787 }
dc6f92b8 788
ff11dfa1
JB
789 /* If we've deleted Vdefault_minibuffer_frame, try to find another
790 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 791 with other windows. */
ff11dfa1 792 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 793 {
ff11dfa1 794 Lisp_Object frames;
1113d9db 795
ff11dfa1
JB
796 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
797 Lisp_Object frame_with_minibuf = Qnil;
1113d9db 798
ff11dfa1
JB
799 for (frames = Vframe_list;
800 CONSP (frames);
801 frames = XCONS (frames)->cdr)
1113d9db 802 {
ff11dfa1 803 Lisp_Object this = XCONS (frames)->car;
1113d9db 804
ff11dfa1 805 if (XTYPE (this) != Lisp_Frame)
1113d9db 806 abort ();
ff11dfa1 807 f = XFRAME (this);
1113d9db 808
fd0c2bd1 809 if (FRAME_HAS_MINIBUF_P (f))
1113d9db 810 {
ff11dfa1
JB
811 frame_with_minibuf = this;
812 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
813 break;
814 }
815 }
816
ff11dfa1
JB
817 /* We know that there must be some frame with a minibuffer out
818 there. If this were not true, all of the frames present
1113d9db 819 would have to be minibufferless, which implies that at some
ff11dfa1 820 point their minibuffer frames must have been deleted, but
1113d9db 821 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
822 minibuffer frames. */
823 if (NILP (frame_with_minibuf))
1113d9db
JB
824 abort ();
825
ff11dfa1 826 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
827 }
828
dc6f92b8
JB
829 return Qnil;
830}
831\f
832/* Return mouse position in character cell units. */
833
f9898cc6 834DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 835 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
836The position is given in character cells, where (0, 0) is the\n\
837upper-left corner.\n\
f9898cc6 838If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 839to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
840and nil for X and Y.")
841 ()
dc6f92b8 842{
ff11dfa1 843 FRAME_PTR f;
dbc4e1c1 844 Lisp_Object lispy_dummy;
fd2777e0 845 enum scroll_bar_part party_dummy;
dbc4e1c1 846 Lisp_Object x, y;
5384466a 847 int col, row;
dbc4e1c1 848 unsigned long long_dummy;
dc6f92b8 849
c5074d8c
RS
850 f = selected_frame;
851 x = y = Qnil;
852
853 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 854 if (mouse_position_hook)
dbc4e1c1
JB
855 (*mouse_position_hook) (&f,
856 &lispy_dummy, &party_dummy,
857 &x, &y,
858 &long_dummy);
5384466a
RS
859 col = XINT (x);
860 row = XINT (y);
861 glyph_to_pixel_coords (f, col, row, &col, &row);
862 XSETINT (x, col);
863 XSETINT (y, row);
dbc4e1c1 864 XSET (lispy_dummy, Lisp_Frame, f);
c5074d8c 865 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
866}
867
868DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 869 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
ff11dfa1
JB
870WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
871 (frame, x, y)
872 Lisp_Object frame, x, y;
dc6f92b8 873{
ff11dfa1 874 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
875 CHECK_NUMBER (x, 2);
876 CHECK_NUMBER (y, 1);
877
dbc4e1c1 878 /* I think this should be done with a hook. */
dc6f92b8 879#ifdef HAVE_X_WINDOWS
fd0c2bd1 880 if (FRAME_X_P (XFRAME (frame)))
dc6f92b8 881 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 882 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
883#endif
884
885 return Qnil;
886}
887\f
ff11dfa1 888DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 889 0, 1, "",
ff11dfa1 890 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 891If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
892 (frame)
893 Lisp_Object frame;
dc6f92b8 894{
1aa66088 895 if (NILP (frame))
7500877e 896 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 897
ff11dfa1 898 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 899
dbc4e1c1 900 /* I think this should be done with a hook. */
fd0c2bd1
JB
901#ifdef HAVE_X_WINDOWS
902 if (FRAME_X_P (XFRAME (frame)))
02ff9dd5
RS
903 {
904 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
905 x_make_frame_visible (XFRAME (frame));
906 }
fd0c2bd1 907#endif
dc6f92b8 908
ff11dfa1 909 return frame;
dc6f92b8
JB
910}
911
ff11dfa1 912DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 913 0, 2, "",
8693ca83 914 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
915If omitted, FRAME defaults to the currently selected frame.\n\
916Normally you may not make FRAME invisible if all other frames are invisible,\n\
917but if the second optional argument FORCE is non-nil, you may do so.")
918 (frame, force)
919 Lisp_Object frame, force;
dc6f92b8 920{
1aa66088 921 if (NILP (frame))
7500877e 922 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 923
ff11dfa1 924 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 925
808c0f20
RS
926 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
927 error ("Attempt to make invisible the sole visible or iconified frame");
928
9c394f17
RS
929 /* Don't let the frame remain selected. */
930 if (XFRAME (frame) == selected_frame)
931 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
932
933 /* Don't allow minibuf_window to remain on a deleted frame. */
934 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
935 {
936 Fset_window_buffer (selected_frame->minibuffer_window,
937 XWINDOW (minibuf_window)->buffer);
938 minibuf_window = selected_frame->minibuffer_window;
939 }
940
dbc4e1c1 941 /* I think this should be done with a hook. */
fd0c2bd1
JB
942#ifdef HAVE_X_WINDOWS
943 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 944 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 945#endif
dc6f92b8
JB
946
947 return Qnil;
948}
949
ff11dfa1 950DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 951 0, 1, "",
8693ca83
JB
952 "Make the frame FRAME into an icon.\n\
953If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
954 (frame)
955 Lisp_Object frame;
dc6f92b8 956{
1aa66088 957 if (NILP (frame))
7500877e 958 XSET (frame, Lisp_Frame, selected_frame);
1aa66088 959
ff11dfa1 960 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 961
9c394f17
RS
962 /* Don't let the frame remain selected. */
963 if (XFRAME (frame) == selected_frame)
964 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
965
966 /* Don't allow minibuf_window to remain on a deleted frame. */
967 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
968 {
969 Fset_window_buffer (selected_frame->minibuffer_window,
970 XWINDOW (minibuf_window)->buffer);
971 minibuf_window = selected_frame->minibuffer_window;
972 }
973
dbc4e1c1 974 /* I think this should be done with a hook. */
fd0c2bd1
JB
975#ifdef HAVE_X_WINDOWS
976 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 977 x_iconify_frame (XFRAME (frame));
fd0c2bd1 978#endif
dc6f92b8
JB
979
980 return Qnil;
981}
982
ff11dfa1 983DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 984 1, 1, 0,
ff11dfa1
JB
985 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
986A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 987a window system, it may not show at all.\n\
fd0c2bd1 988Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
989 (frame)
990 Lisp_Object frame;
dc6f92b8 991{
ff11dfa1 992 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 993
5c044f55
RS
994 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
995
a42e9724 996 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 997 return Qt;
a42e9724 998 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 999 return Qicon;
dc6f92b8
JB
1000 return Qnil;
1001}
1002
ff11dfa1 1003DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1004 0, 0, 0,
ff11dfa1 1005 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1006 ()
1007{
ff11dfa1
JB
1008 Lisp_Object tail, frame;
1009 struct frame *f;
dc6f92b8
JB
1010 Lisp_Object value;
1011
1012 value = Qnil;
ff11dfa1 1013 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1014 {
ff11dfa1
JB
1015 frame = XCONS (tail)->car;
1016 if (XTYPE (frame) != Lisp_Frame)
dc6f92b8 1017 continue;
ff11dfa1 1018 f = XFRAME (frame);
a42e9724 1019 if (FRAME_VISIBLE_P (f))
ff11dfa1 1020 value = Fcons (frame, value);
dc6f92b8
JB
1021 }
1022 return value;
1023}
d5e7c279
JB
1024
1025
b49f5578 1026DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, 0,
dbc4e1c1
JB
1027 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1028If FRAME is invisible, make it visible.\n\
1029If Emacs is displaying on an ordinary terminal or some other device which\n\
1030doesn't support multiple overlapping frames, this function does nothing.")
1031 (frame)
1032 Lisp_Object frame;
1033{
1034 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1035
1036 /* Do like the documentation says. */
1037 Fmake_frame_visible (frame);
1038
dbc4e1c1
JB
1039 if (frame_raise_lower_hook)
1040 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1041
1042 return Qnil;
1043}
1044
b49f5578
JB
1045/* Should we have a corresponding function called Flower_Power? */
1046DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, 0,
dbc4e1c1
JB
1047 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
1048If Emacs is displaying on an ordinary terminal or some other device which\n\
1049doesn't support multiple overlapping frames, this function does nothing.")
1050 (frame)
1051 Lisp_Object frame;
1052{
1053 CHECK_LIVE_FRAME (frame, 0);
1054
1055 if (frame_raise_lower_hook)
1056 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1057
1058 return Qnil;
1059}
1060
d5e7c279 1061\f
ff11dfa1 1062DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1063 1, 2, 0,
ff11dfa1 1064 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1065In other words, switch-frame events caused by events in FRAME will\n\
1066request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1067FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1068\n\
a42e9724 1069If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1070cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1071\n\
a42e9724
JB
1072Focus redirection is useful for temporarily redirecting keystrokes to\n\
1073a surrogate minibuffer frame when a frame doesn't have its own\n\
1074minibuffer window.\n\
d5e7c279 1075\n\
a42e9724
JB
1076A frame's focus redirection can be changed by select-frame. If frame\n\
1077FOO is selected, and then a different frame BAR is selected, any\n\
1078frames redirecting their focus to FOO are shifted to redirect their\n\
1079focus to BAR. This allows focus redirection to work properly when the\n\
1080user switches from one frame to another using `select-window'.\n\
1081\n\
1082This means that a frame whose focus is redirected to itself is treated\n\
1083differently from a frame whose focus is redirected to nil; the former\n\
1084is affected by select-frame, while the latter is not.\n\
1085\n\
1086The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1087 (frame, focus_frame)
1088 Lisp_Object frame, focus_frame;
d5e7c279 1089{
13144095
JB
1090 /* Note that we don't check for a live frame here. It's reasonable
1091 to redirect the focus of a frame you're about to delete, if you
1092 know what other frame should receive those keystrokes. */
1093 CHECK_FRAME (frame, 0);
f9898cc6 1094
a42e9724 1095 if (! NILP (focus_frame))
ff11dfa1 1096 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1097
ff11dfa1 1098 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1099
9c394f17
RS
1100 /* I think this should be done with a hook. */
1101#ifdef HAVE_X_WINDOWS
1102 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1103 && FRAME_X_P (XFRAME (focus_frame)))
1104 Ffocus_frame (focus_frame);
1105#endif
1106
ff11dfa1
JB
1107 if (frame_rehighlight_hook)
1108 (*frame_rehighlight_hook) ();
d5e7c279
JB
1109
1110 return Qnil;
1111}
1112
1113
ff11dfa1
JB
1114DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1115 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1116This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1117See `redirect-frame-focus'.")
1118 (frame)
1119 Lisp_Object frame;
d5e7c279 1120{
ff11dfa1 1121 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1122
ff11dfa1 1123 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1124}
1125
1126
dc6f92b8
JB
1127\f
1128Lisp_Object
ff11dfa1
JB
1129get_frame_param (frame, prop)
1130 register struct frame *frame;
dc6f92b8
JB
1131 Lisp_Object prop;
1132{
1133 register Lisp_Object tem;
1134
ff11dfa1 1135 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1136 if (EQ (tem, Qnil))
1137 return tem;
1138 return Fcdr (tem);
1139}
1140
1141void
fd0c2bd1 1142store_in_alist (alistptr, prop, val)
dc6f92b8 1143 Lisp_Object *alistptr, val;
fd0c2bd1 1144 Lisp_Object prop;
dc6f92b8
JB
1145{
1146 register Lisp_Object tem;
dc6f92b8 1147
dc6f92b8
JB
1148 tem = Fassq (prop, *alistptr);
1149 if (EQ (tem, Qnil))
1150 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1151 else
1152 Fsetcdr (tem, val);
1153}
1154
1155void
ff11dfa1
JB
1156store_frame_param (f, prop, val)
1157 struct frame *f;
dc6f92b8
JB
1158 Lisp_Object prop, val;
1159{
1160 register Lisp_Object tem;
1161
ff11dfa1 1162 tem = Fassq (prop, f->param_alist);
dc6f92b8 1163 if (EQ (tem, Qnil))
ff11dfa1 1164 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1165 else
1166 Fsetcdr (tem, val);
bc93c097
JB
1167
1168 if (EQ (prop, Qminibuffer)
1169 && XTYPE (val) == Lisp_Window)
1170 {
1171 if (! MINI_WINDOW_P (XWINDOW (val)))
1172 error ("Surrogate minibuffer windows must be minibuffer windows.");
1173
fd0c2bd1 1174 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1fb2d074 1175 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1176
1177 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1178 f->minibuffer_window = val;
bc93c097 1179 }
dc6f92b8
JB
1180}
1181
ff11dfa1
JB
1182DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1183 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1184It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1185The meaningful PARMs depend on the kind of frame.\n\
1186If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1187 (frame)
1188 Lisp_Object frame;
dc6f92b8
JB
1189{
1190 Lisp_Object alist;
ff11dfa1 1191 struct frame *f;
dc6f92b8 1192
ff11dfa1
JB
1193 if (EQ (frame, Qnil))
1194 f = selected_frame;
dc6f92b8
JB
1195 else
1196 {
ff11dfa1
JB
1197 CHECK_FRAME (frame, 0);
1198 f = XFRAME (frame);
dc6f92b8
JB
1199 }
1200
ff11dfa1 1201 if (f->display.nothing == 0)
dc6f92b8
JB
1202 return Qnil;
1203
ff11dfa1 1204 alist = Fcopy_alist (f->param_alist);
fd0c2bd1
JB
1205 store_in_alist (&alist, Qname, f->name);
1206 store_in_alist (&alist, Qheight, make_number (f->height));
1207 store_in_alist (&alist, Qwidth, make_number (f->width));
1208 store_in_alist (&alist, Qmodeline, (f->wants_modeline ? Qt : Qnil));
1209 store_in_alist (&alist, Qminibuffer,
39acc701 1210 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
fd0c2bd1
JB
1211 : (FRAME_MINIBUF_ONLY_P (f) ? Qonly
1212 : FRAME_MINIBUF_WINDOW (f))));
1213 store_in_alist (&alist, Qunsplittable, (f->no_split ? Qt : Qnil));
fa8fdbf9 1214 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
fd0c2bd1 1215
dbc4e1c1 1216 /* I think this should be done with a hook. */
fd0c2bd1
JB
1217#ifdef HAVE_X_WINDOWS
1218 if (FRAME_X_P (f))
ff11dfa1 1219 x_report_frame_params (f, &alist);
fd0c2bd1 1220#endif
dc6f92b8
JB
1221 return alist;
1222}
1223
ff11dfa1
JB
1224DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1225 Smodify_frame_parameters, 2, 2, 0,
1226 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1227ALIST is an alist of parameters to change and their new values.\n\
1228Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
1229The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1230 (frame, alist)
1231 Lisp_Object frame, alist;
dc6f92b8 1232{
fd0c2bd1 1233 FRAME_PTR f;
dc6f92b8
JB
1234 register Lisp_Object tail, elt, prop, val;
1235
ff11dfa1
JB
1236 if (EQ (frame, Qnil))
1237 f = selected_frame;
dc6f92b8
JB
1238 else
1239 {
ff11dfa1
JB
1240 CHECK_LIVE_FRAME (frame, 0);
1241 f = XFRAME (frame);
dc6f92b8
JB
1242 }
1243
dbc4e1c1 1244 /* I think this should be done with a hook. */
fd0c2bd1
JB
1245#ifdef HAVE_X_WINDOWS
1246 if (FRAME_X_P (f))
1247#if 1
1248 x_set_frame_parameters (f, alist);
1249#else
dc6f92b8
JB
1250 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1251 {
1252 elt = Fcar (tail);
1253 prop = Fcar (elt);
1254 val = Fcdr (elt);
fd0c2bd1 1255 x_set_frame_param (f, prop, val, get_frame_param (f, prop));
ff11dfa1 1256 store_frame_param (f, prop, val);
dc6f92b8 1257 }
fd0c2bd1
JB
1258#endif
1259#endif
dc6f92b8
JB
1260
1261 return Qnil;
1262}
1263\f
a26a1f95
RS
1264DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1265 0, 1, 0,
1266 "Height in pixels of a line in the font in frame FRAME.\n\
1267If FRAME is omitted, the selected frame is used.\n\
1268For a terminal frame, the value is always 1.")
ff11dfa1
JB
1269 (frame)
1270 Lisp_Object frame;
dc6f92b8 1271{
a26a1f95 1272 struct frame *f;
dc6f92b8 1273
a26a1f95
RS
1274 if (NILP (frame))
1275 f = selected_frame;
1276 else
1277 {
1278 CHECK_FRAME (frame, 0);
1279 f = XFRAME (frame);
1280 }
1281
1282#ifdef HAVE_X_WINDOWS
1283 if (FRAME_X_P (f))
1284 return make_number (x_char_height (f));
1285 else
dc6d9681 1286#endif
a26a1f95
RS
1287 return make_number (1);
1288}
dc6d9681 1289
dc6f92b8 1290
a26a1f95
RS
1291DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1292 0, 1, 0,
1293 "Width in pixels of characters in the font in frame FRAME.\n\
1294If FRAME is omitted, the selected frame is used.\n\
1295The width is the same for all characters, because\n\
1296currently Emacs supports only fixed-width fonts.\n\
1297For a terminal screen, the value is always 1.")
1298 (frame)
1299 Lisp_Object frame;
dc6f92b8 1300{
a26a1f95
RS
1301 struct frame *f;
1302
1303 if (NILP (frame))
1304 f = selected_frame;
1305 else
1306 {
1307 CHECK_FRAME (frame, 0);
1308 f = XFRAME (frame);
1309 }
1310
1311#ifdef HAVE_X_WINDOWS
1312 if (FRAME_X_P (f))
1313 return make_number (x_char_width (f));
1314 else
1315#endif
1316 return make_number (1);
dc6f92b8
JB
1317}
1318
a26a1f95
RS
1319DEFUN ("frame-pixel-height", Fframe_pixel_height,
1320 Sframe_pixel_height, 0, 1, 0,
164a14ef
RS
1321 "Return a FRAME's height in pixels.\n\
1322For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
1323If FRAME is omitted, the selected frame is used.")
1324 (frame)
1325 Lisp_Object frame;
dc6f92b8 1326{
a26a1f95
RS
1327 struct frame *f;
1328
1329 if (NILP (frame))
1330 f = selected_frame;
1331 else
1332 {
1333 CHECK_FRAME (frame, 0);
1334 f = XFRAME (frame);
1335 }
1336
1337#ifdef HAVE_X_WINDOWS
1338 if (FRAME_X_P (f))
1339 return make_number (x_pixel_height (f));
1340 else
dc6d9681 1341#endif
a26a1f95
RS
1342 return make_number (FRAME_HEIGHT (f));
1343}
1344
1345DEFUN ("frame-pixel-width", Fframe_pixel_width,
1346 Sframe_pixel_width, 0, 1, 0,
1347 "Return FRAME's width in pixels.\n\
164a14ef 1348For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
1349If FRAME is omitted, the selected frame is used.")
1350 (frame)
1351 Lisp_Object frame;
1352{
1353 struct frame *f;
1354
1355 if (NILP (frame))
1356 f = selected_frame;
1357 else
1358 {
1359 CHECK_FRAME (frame, 0);
1360 f = XFRAME (frame);
1361 }
dc6f92b8 1362
a26a1f95
RS
1363#ifdef HAVE_X_WINDOWS
1364 if (FRAME_X_P (f))
1365 return make_number (x_pixel_width (f));
1366 else
1367#endif
1368 return make_number (FRAME_WIDTH (f));
1369}
1370\f
ff11dfa1
JB
1371DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1372 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1373Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1374but that the idea of the actual height of the frame should not be changed.")
1375 (frame, rows, pretend)
fd0c2bd1 1376 Lisp_Object frame, rows, pretend;
dc6f92b8 1377{
ff11dfa1 1378 register struct frame *f;
dc6f92b8
JB
1379
1380 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1381 if (NILP (frame))
1382 f = selected_frame;
dc6f92b8
JB
1383 else
1384 {
ff11dfa1
JB
1385 CHECK_LIVE_FRAME (frame, 0);
1386 f = XFRAME (frame);
dc6f92b8
JB
1387 }
1388
dbc4e1c1 1389 /* I think this should be done with a hook. */
fd0c2bd1
JB
1390#ifdef HAVE_X_WINDOWS
1391 if (FRAME_X_P (f))
dc6f92b8 1392 {
ff11dfa1 1393 if (XINT (rows) != f->width)
808c0f20 1394 x_set_window_size (f, 1, f->width, XINT (rows));
dc6f92b8
JB
1395 }
1396 else
fd0c2bd1
JB
1397#endif
1398 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
dc6f92b8
JB
1399 return Qnil;
1400}
1401
ff11dfa1
JB
1402DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1403 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1404Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1405but that the idea of the actual width of the frame should not be changed.")
1406 (frame, cols, pretend)
fd0c2bd1 1407 Lisp_Object frame, cols, pretend;
dc6f92b8 1408{
ff11dfa1 1409 register struct frame *f;
dc6f92b8 1410 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1411 if (NILP (frame))
1412 f = selected_frame;
dc6f92b8
JB
1413 else
1414 {
ff11dfa1
JB
1415 CHECK_LIVE_FRAME (frame, 0);
1416 f = XFRAME (frame);
dc6f92b8
JB
1417 }
1418
dbc4e1c1 1419 /* I think this should be done with a hook. */
fd0c2bd1
JB
1420#ifdef HAVE_X_WINDOWS
1421 if (FRAME_X_P (f))
dc6f92b8 1422 {
ff11dfa1 1423 if (XINT (cols) != f->width)
808c0f20 1424 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
1425 }
1426 else
fd0c2bd1
JB
1427#endif
1428 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
1429 return Qnil;
1430}
1431
ff11dfa1
JB
1432DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1433 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1434 (frame, cols, rows)
1435 Lisp_Object frame, cols, rows;
dc6f92b8 1436{
ff11dfa1 1437 register struct frame *f;
dc6f92b8
JB
1438 int mask;
1439
ff11dfa1 1440 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1441 CHECK_NUMBER (cols, 2);
1442 CHECK_NUMBER (rows, 1);
ff11dfa1 1443 f = XFRAME (frame);
dc6f92b8 1444
dbc4e1c1 1445 /* I think this should be done with a hook. */
fd0c2bd1
JB
1446#ifdef HAVE_X_WINDOWS
1447 if (FRAME_X_P (f))
dc6f92b8 1448 {
ff11dfa1 1449 if (XINT (rows) != f->height || XINT (cols) != f->width)
808c0f20 1450 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
1451 }
1452 else
fd0c2bd1
JB
1453#endif
1454 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
1455
1456 return Qnil;
1457}
1458
ff11dfa1
JB
1459DEFUN ("set-frame-position", Fset_frame_position,
1460 Sset_frame_position, 3, 3, 0,
1461 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
1462This is actually the position of the upper left corner of the frame.\n\
1463Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 1464the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
1465 (frame, xoffset, yoffset)
1466 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1467{
ff11dfa1 1468 register struct frame *f;
dc6f92b8
JB
1469 int mask;
1470
ff11dfa1 1471 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1472 CHECK_NUMBER (xoffset, 1);
1473 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1474 f = XFRAME (frame);
dc6f92b8 1475
dbc4e1c1 1476 /* I think this should be done with a hook. */
fd0c2bd1
JB
1477#ifdef HAVE_X_WINDOWS
1478 if (FRAME_X_P (f))
ff11dfa1 1479 x_set_offset (f, XINT (xoffset), XINT (yoffset));
fd0c2bd1 1480#endif
dc6f92b8
JB
1481
1482 return Qt;
1483}
dc6d9681 1484
dc6f92b8 1485\f
ff11dfa1 1486choose_minibuf_frame ()
dc6f92b8 1487{
ff11dfa1
JB
1488 /* For lowest-level minibuf, put it on currently selected frame
1489 if frame has a minibuffer. */
d06a8a56 1490
dc6f92b8 1491 if (minibuf_level == 0
ff11dfa1 1492 && selected_frame != 0
d06a8a56 1493 && !EQ (minibuf_window, selected_frame->minibuffer_window))
dc6f92b8 1494 {
d06a8a56
JB
1495 /* I don't think that any frames may validly have a null minibuffer
1496 window anymore. */
1497 if (NILP (selected_frame->minibuffer_window))
1498 abort ();
1499
ff11dfa1 1500 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1501 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1502 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1503 }
1504}
1505\f
ff11dfa1 1506syms_of_frame ()
dc6f92b8 1507{
fd0c2bd1 1508 /*&&& init symbols here &&&*/
ff11dfa1 1509 Qframep = intern ("framep");
ff11dfa1 1510 staticpro (&Qframep);
dbc4e1c1
JB
1511 Qframe_live_p = intern ("frame-live-p");
1512 staticpro (&Qframe_live_p);
fd0c2bd1
JB
1513 Qheight = intern ("height");
1514 staticpro (&Qheight);
1515 Qicon = intern ("icon");
1516 staticpro (&Qicon);
1517 Qminibuffer = intern ("minibuffer");
bc93c097 1518 staticpro (&Qminibuffer);
fd0c2bd1
JB
1519 Qmodeline = intern ("modeline");
1520 staticpro (&Qmodeline);
1521 Qname = intern ("name");
1522 staticpro (&Qname);
fd0c2bd1
JB
1523 Qonly = intern ("only");
1524 staticpro (&Qonly);
1525 Qunsplittable = intern ("unsplittable");
1526 staticpro (&Qunsplittable);
f7af3f7b
RS
1527 Qmenu_bar_lines = intern ("menu-bar-lines");
1528 staticpro (&Qmenu_bar_lines);
fd0c2bd1
JB
1529 Qwidth = intern ("width");
1530 staticpro (&Qwidth);
1531 Qx = intern ("x");
1532 staticpro (&Qx);
f7af3f7b
RS
1533 Qvisible = intern ("visible");
1534 staticpro (&Qvisible);
dc6f92b8 1535
ff11dfa1 1536 staticpro (&Vframe_list);
dc6f92b8 1537
ff11dfa1
JB
1538 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1539 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1540
1541 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1542 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1543 Vemacs_iconified = Qnil;
1544
ff11dfa1
JB
1545 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1546 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1547\n\
ff11dfa1 1548Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1549appropriate surrogate.\n\
1550\n\
1551Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1552frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1553minibuffer, no matter what this variable is set to. This means that\n\
1554this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1555current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1556displayed.");
ff11dfa1 1557 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1558
ff11dfa1
JB
1559 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1560 "Alist of default values for frame creation.\n\
5bce042c 1561These may be set in your init file, like this:\n\
ff11dfa1 1562 (setq default-frame-alist '((width . 80) (height . 55)))\n\
5bce042c
JB
1563These override values given in window system configuration data, like\n\
1564X Windows' defaults database.\n\
ff11dfa1
JB
1565For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1566For values specific to the separate minibuffer frame, see\n\
1567`minibuffer-frame-alist'.");
1568 Vdefault_frame_alist = Qnil;
1569
1570 defsubr (&Sframep);
dbc4e1c1 1571 defsubr (&Sframe_live_p);
0f85737c 1572 defsubr (&Shandle_switch_frame);
ff11dfa1
JB
1573 defsubr (&Sselect_frame);
1574 defsubr (&Sselected_frame);
1575 defsubr (&Swindow_frame);
1576 defsubr (&Sframe_root_window);
1577 defsubr (&Sframe_selected_window);
1578 defsubr (&Sframe_list);
1579 defsubr (&Snext_frame);
ef2c57ac 1580 defsubr (&Sprevious_frame);
ff11dfa1 1581 defsubr (&Sdelete_frame);
f9898cc6 1582 defsubr (&Smouse_position);
dc6f92b8
JB
1583 defsubr (&Sset_mouse_position);
1584#if 0
ff11dfa1
JB
1585 defsubr (&Sframe_configuration);
1586 defsubr (&Srestore_frame_configuration);
dc6f92b8 1587#endif
ff11dfa1
JB
1588 defsubr (&Smake_frame_visible);
1589 defsubr (&Smake_frame_invisible);
1590 defsubr (&Siconify_frame);
1591 defsubr (&Sframe_visible_p);
1592 defsubr (&Svisible_frame_list);
b49f5578
JB
1593 defsubr (&Sraise_frame);
1594 defsubr (&Slower_frame);
ff11dfa1
JB
1595 defsubr (&Sredirect_frame_focus);
1596 defsubr (&Sframe_focus);
1597 defsubr (&Sframe_parameters);
1598 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
1599 defsubr (&Sframe_char_height);
1600 defsubr (&Sframe_char_width);
1601 defsubr (&Sframe_pixel_height);
1602 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
1603 defsubr (&Sset_frame_height);
1604 defsubr (&Sset_frame_width);
1605 defsubr (&Sset_frame_size);
1606 defsubr (&Sset_frame_position);
dc6f92b8 1607}
e5d77022 1608
2f0b07e0
JB
1609keys_of_frame ()
1610{
0f85737c 1611 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
2f0b07e0 1612}
a26a1f95 1613\f
d06a8a56 1614#else /* not MULTI_FRAME */
fd0c2bd1 1615
cc38027b
JB
1616/* If we're not using multi-frame stuff, we still need to provide some
1617 support functions. */
1618
1619/* Unless this function is defined, providing set-frame-height and
1620 set-frame-width doesn't help compatibility any, since they both
1621 want this as their first argument. */
1622DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1623 "Return the frame that is now selected.")
1624 ()
1625{
1626 Lisp_Object tem;
1627 XFASTINT (tem) = 0;
1628 return tem;
1629}
704a9b45
RS
1630DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
1631 "Return non-nil if OBJECT is a frame.\n\
1632Value is t for a termcap frame (a character-only terminal),\n\
1633`x' for an Emacs frame that is really an X window.\n\
1634Also see `live-frame-p'.")
1635 (object)
1636 Lisp_Object object;
1637{
1638 return Qnil;
1639}
fd0c2bd1
JB
1640
1641DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1642 "Specify that the frame FRAME has LINES lines.\n\
1643Optional third arg non-nil means that redisplay should use LINES lines\n\
1644but that the idea of the actual height of the frame should not be changed.")
1645 (frame, rows, pretend)
1646 Lisp_Object frame, rows, pretend;
1647{
1648 CHECK_NUMBER (rows, 0);
1649
1650 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
1651 return Qnil;
1652}
1653
1654DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1655 "Specify that the frame FRAME has COLS columns.\n\
1656Optional third arg non-nil means that redisplay should use COLS columns\n\
1657but that the idea of the actual width of the frame should not be changed.")
1658 (frame, cols, pretend)
1659 Lisp_Object frame, cols, pretend;
1660{
1661 CHECK_NUMBER (cols, 0);
1662
1663 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1664 return Qnil;
1665}
1666
1667DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1668 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1669 (frame, cols, rows)
1670 Lisp_Object frame, cols, rows;
1671{
1672 CHECK_NUMBER (cols, 2);
1673 CHECK_NUMBER (rows, 1);
1674
1675 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
1676
1677 return Qnil;
1678}
1679
48c9d487
JB
1680DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
1681 "Return number of lines available for display on FRAME.\n\
1682If FRAME is omitted, describe the currently selected frame.")
1683 (frame)
1684 Lisp_Object frame;
cc38027b
JB
1685{
1686 return make_number (FRAME_HEIGHT (selected_frame));
1687}
1688
48c9d487
JB
1689DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
1690 "Return number of columns available for display on FRAME.\n\
1691If FRAME is omitted, describe the currently selected frame.")
1692 (frame)
1693 Lisp_Object frame;
cc38027b
JB
1694{
1695 return make_number (FRAME_WIDTH (selected_frame));
1696}
1697
a26a1f95
RS
1698DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1699 0, 1, 0,
1700 "Height in pixels of a line in the font in frame FRAME.\n\
1701If FRAME is omitted, the selected frame is used.\n\
1702For a terminal frame, the value is always 1.")
1703 (frame)
1704 Lisp_Object frame;
1705{
1706 return make_number (1);
1707}
1708
1709
1710DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1711 0, 1, 0,
1712 "Width in pixels of characters in the font in frame FRAME.\n\
1713If FRAME is omitted, the selected frame is used.\n\
1714The width is the same for all characters, because\n\
1715currently Emacs supports only fixed-width fonts.\n\
1716For a terminal screen, the value is always 1.")
1717 (frame)
1718 Lisp_Object frame;
1719{
1720 return make_number (1);
1721}
1722
1723DEFUN ("frame-pixel-height", Fframe_pixel_height,
1724 Sframe_pixel_height, 0, 1, 0,
1725 "Return FRAME's height in pixels.\n\
1726For a terminal frame, the result really gives the height in characters.\n\
1727If FRAME is omitted, the selected frame is used.")
1728 (frame)
1729 Lisp_Object frame;
1730{
1731 return make_number (FRAME_HEIGHT (f));
1732}
1733
1734DEFUN ("frame-pixel-width", Fframe_pixel_width,
1735 Sframe_pixel_width, 0, 1, 0,
1736 "Return FRAME's width in pixels.\n\
1737For a terminal frame, the result really gives the width in characters.\n\
1738If FRAME is omitted, the selected frame is used.")
1739 (frame)
1740 Lisp_Object frame;
1741{
1742 return make_number (FRAME_WIDTH (f));
1743}
1744
cc38027b
JB
1745/* These are for backward compatibility with Emacs 18. */
1746
fd0c2bd1
JB
1747DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
1748 "Tell redisplay that the screen has LINES lines.\n\
1749Optional second arg non-nil means that redisplay should use LINES lines\n\
1750but that the idea of the actual height of the screen should not be changed.")
1751 (lines, pretend)
1752 Lisp_Object lines, pretend;
1753{
1754 CHECK_NUMBER (lines, 0);
1755
1756 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
1757 return Qnil;
1758}
1759
1760DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
1761 "Tell redisplay that the screen has COLS columns.\n\
1762Optional second arg non-nil means that redisplay should use COLS columns\n\
1763but that the idea of the actual width of the screen should not be changed.")
1764 (cols, pretend)
1765 Lisp_Object cols, pretend;
1766{
1767 CHECK_NUMBER (cols, 0);
1768
1769 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
1770 return Qnil;
1771}
1772
bc1ed486
RS
1773DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1774 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1775The position is given in character cells, where (0, 0) is the\n\
1776upper-left corner.\n\
1777If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1778to read the mouse position, it returns the selected frame for FRAME\n\
1779and nil for X and Y.")
1780 ()
1781{
1782 FRAME_PTR f;
1783 Lisp_Object lispy_dummy;
1784 enum scroll_bar_part party_dummy;
1785 Lisp_Object x, y;
1786 unsigned long long_dummy;
1787
1788 f = selected_frame;
1789 x = y = Qnil;
1790
1791 /* It's okay for the hook to refrain from storing anything. */
1792 if (mouse_position_hook)
1793 (*mouse_position_hook) (&f,
1794 &lispy_dummy, &party_dummy,
1795 &x, &y,
1796 &long_dummy);
1797
5384466a
RS
1798 col = XINT (x);
1799 row = XINT (y);
1800 glyph_to_pixel_coords (f, col, row, &col, &row);
1801 XSETINT (x, col);
1802 XSETINT (y, row);
bc1ed486
RS
1803 /* Always return nil for frame. */
1804 return Fcons (Qnil, Fcons (x, y));
1805}
1806
fd0c2bd1
JB
1807syms_of_frame ()
1808{
a26a1f95 1809 defsubr (&Sselected_frame);
704a9b45 1810 defsubr (&Sframep);
a26a1f95
RS
1811 defsubr (&Sframe_char_height);
1812 defsubr (&Sframe_char_width);
1813 defsubr (&Sframe_pixel_height);
1814 defsubr (&Sframe_pixel_width);
fd0c2bd1
JB
1815 defsubr (&Sset_frame_height);
1816 defsubr (&Sset_frame_width);
1817 defsubr (&Sset_frame_size);
1818 defsubr (&Sset_screen_height);
1819 defsubr (&Sset_screen_width);
1820 defsubr (&Sframe_height);
1821 Ffset (intern ("screen-height"), intern ("frame-height"));
1822 defsubr (&Sframe_width);
1823 Ffset (intern ("screen-width"), intern ("frame-width"));
bc1ed486 1824 defsubr (&Smouse_position);
fd0c2bd1
JB
1825}
1826
2f0b07e0
JB
1827keys_of_frame ()
1828{
1829}
1830
fd0c2bd1
JB
1831#endif /* not MULTI_FRAME */
1832
1833
1834
1835