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