(make_frame): Initialize f->namebuf.
[bpt/emacs.git] / src / frame.c
CommitLineData
ff11dfa1 1/* Generic frame functions.
5add3885 2 Copyright (C) 1993, 1994, 1995 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
18160b98 20#include <config.h>
565620a5
RS
21
22#include <stdio.h>
cc38027b
JB
23#include "lisp.h"
24#include "frame.h"
bc1ed486 25#include "termhooks.h"
f769f1b2 26#include "window.h"
87485d6f
MW
27#ifdef MSDOS
28#include "msdos.h"
29#endif
e5d77022 30
ff11dfa1 31#ifdef MULTI_FRAME
e5d77022 32
bff19c8d 33#include "buffer.h"
dc6f92b8 34
2f0b07e0
JB
35/* These help us bind and responding to switch-frame events. */
36#include "commands.h"
37#include "keyboard.h"
38
dc6f92b8 39Lisp_Object Vemacs_iconified;
ff11dfa1
JB
40Lisp_Object Vframe_list;
41Lisp_Object Vterminal_frame;
42Lisp_Object Vdefault_minibuffer_frame;
43Lisp_Object Vdefault_frame_alist;
fd0c2bd1
JB
44
45/* Evaluate this expression to rebuild the section of syms_of_frame
46 that initializes and staticpros the symbols declared below. Note
47 that Emacs 18 has a bug that keeps C-x C-e from being able to
48 evaluate this expression.
49
50(progn
51 ;; Accumulate a list of the symbols we want to initialize from the
52 ;; declarations at the top of the file.
53 (goto-char (point-min))
54 (search-forward "/\*&&& symbols declared here &&&*\/\n")
55 (let (symbol-list)
56 (while (looking-at "Lisp_Object \\(Q[a-z_]+\\)")
57 (setq symbol-list
58 (cons (buffer-substring (match-beginning 1) (match-end 1))
59 symbol-list))
60 (forward-line 1))
61 (setq symbol-list (nreverse symbol-list))
62 ;; Delete the section of syms_of_... where we initialize the symbols.
63 (search-forward "\n /\*&&& init symbols here &&&*\/\n")
64 (let ((start (point)))
65 (while (looking-at "^ Q")
66 (forward-line 2))
67 (kill-region start (point)))
68 ;; Write a new symbol initialization section.
69 (while symbol-list
70 (insert (format " %s = intern (\"" (car symbol-list)))
71 (let ((start (point)))
72 (insert (substring (car symbol-list) 1))
73 (subst-char-in-region start (point) ?_ ?-))
74 (insert (format "\");\n staticpro (&%s);\n" (car symbol-list)))
75 (setq symbol-list (cdr symbol-list)))))
76 */
77
78/*&&& symbols declared here &&&*/
79Lisp_Object Qframep;
dbc4e1c1 80Lisp_Object Qframe_live_p;
fd0c2bd1
JB
81Lisp_Object Qheight;
82Lisp_Object Qicon;
bc93c097 83Lisp_Object Qminibuffer;
fd0c2bd1
JB
84Lisp_Object Qmodeline;
85Lisp_Object Qname;
fd0c2bd1
JB
86Lisp_Object Qonly;
87Lisp_Object Qunsplittable;
fa8fdbf9 88Lisp_Object Qmenu_bar_lines;
fd0c2bd1
JB
89Lisp_Object Qwidth;
90Lisp_Object Qx;
f7af3f7b 91Lisp_Object Qvisible;
329ca574 92Lisp_Object Qbuffer_predicate;
dc6f92b8
JB
93
94extern Lisp_Object Vminibuffer_list;
95extern Lisp_Object get_minibuffer ();
84386599
RS
96extern Lisp_Object Fhandle_switch_frame ();
97extern Lisp_Object Fredirect_frame_focus ();
dc6f92b8 98\f
ff11dfa1
JB
99DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
100 "Return non-nil if OBJECT is a frame.\n\
101Value is t for a termcap frame (a character-only terminal),\n\
87485d6f
MW
102`x' for an Emacs frame that is really an X window,\n\
103`pc' for a direct-write MS-DOS frame.\n\
e6b27a8f 104See also `frame-live-p'.")
f9898cc6
JB
105 (object)
106 Lisp_Object object;
dc6f92b8 107{
e35d291d 108 if (!FRAMEP (object))
dc6f92b8 109 return Qnil;
ff11dfa1 110 switch (XFRAME (object)->output_method)
dc6f92b8
JB
111 {
112 case output_termcap:
113 return Qt;
114 case output_x_window:
fd0c2bd1 115 return Qx;
87485d6f 116 /* The `pc' case is in the Fframep below. */
dc6f92b8
JB
117 default:
118 abort ();
119 }
120}
121
dbc4e1c1 122DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
ff11dfa1
JB
123 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
124Value is nil if OBJECT is not a live frame. If object is a live\n\
125frame, the return value indicates what sort of output device it is\n\
126displayed on. Value is t for a termcap frame (a character-only\n\
127terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
128 (object)
129 Lisp_Object object;
130{
ff11dfa1
JB
131 return ((FRAMEP (object)
132 && FRAME_LIVE_P (XFRAME (object)))
133 ? Fframep (object)
f9898cc6
JB
134 : Qnil);
135}
136
ff11dfa1
JB
137struct frame *
138make_frame (mini_p)
dc6f92b8
JB
139 int mini_p;
140{
ff11dfa1
JB
141 Lisp_Object frame;
142 register struct frame *f;
dc6f92b8
JB
143 register Lisp_Object root_window;
144 register Lisp_Object mini_window;
36af7d69
KH
145 register struct Lisp_Vector *vec;
146 int i;
147
148 vec = allocate_vectorlike ((EMACS_INT) VECSIZE (struct frame));
149 for (i = 0; i < VECSIZE (struct frame); i++)
150 XSETFASTINT (vec->contents[i], 0);
151 vec->size = VECSIZE (struct frame);
152 f = (struct frame *)vec;
153 XSETFRAME (frame, f);
ff11dfa1
JB
154
155 f->cursor_x = 0;
156 f->cursor_y = 0;
157 f->current_glyphs = 0;
158 f->desired_glyphs = 0;
159 f->visible = 0;
323405de 160 f->async_visible = 0;
ff11dfa1
JB
161 f->display.nothing = 0;
162 f->iconified = 0;
323405de 163 f->async_iconified = 0;
ff11dfa1
JB
164 f->wants_modeline = 1;
165 f->auto_raise = 0;
166 f->auto_lower = 0;
167 f->no_split = 0;
168 f->garbaged = 0;
169 f->has_minibuffer = mini_p;
a42e9724 170 f->focus_frame = Qnil;
804518aa 171 f->explicit_name = 0;
fd2777e0
JB
172 f->can_have_scroll_bars = 0;
173 f->has_vertical_scroll_bars = 0;
ff11dfa1 174 f->param_alist = Qnil;
fd2777e0
JB
175 f->scroll_bars = Qnil;
176 f->condemned_scroll_bars = Qnil;
306cc902 177 f->face_alist = Qnil;
9dd935ee 178 f->menu_bar_items = Qnil;
c8b8e7e3
RS
179 f->menu_bar_vector = Qnil;
180 f->menu_bar_items_used = 0;
329ca574 181 f->buffer_predicate = Qnil;
b4f0ee5d
KH
182#ifdef MULTI_KBOARD
183 f->kboard = initial_kboard;
184#endif
aec6e486 185 f->namebuf = 0;
dc6f92b8 186
cc38027b 187 root_window = make_window ();
dc6f92b8
JB
188 if (mini_p)
189 {
cc38027b 190 mini_window = make_window ();
dc6f92b8
JB
191 XWINDOW (root_window)->next = mini_window;
192 XWINDOW (mini_window)->prev = root_window;
193 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
194 XWINDOW (mini_window)->frame = frame;
195 f->minibuffer_window = mini_window;
dc6f92b8
JB
196 }
197 else
198 {
199 mini_window = Qnil;
200 XWINDOW (root_window)->next = Qnil;
ff11dfa1 201 f->minibuffer_window = Qnil;
dc6f92b8
JB
202 }
203
ff11dfa1 204 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
205
206 /* 10 is arbitrary,
207 just so that there is "something there."
ff11dfa1 208 Correct size will be set up later with change_frame_size. */
dc6f92b8 209
ff11dfa1
JB
210 f->width = 10;
211 f->height = 10;
dc6f92b8 212
f4e93c40
KH
213 XSETFASTINT (XWINDOW (root_window)->width, 10);
214 XSETFASTINT (XWINDOW (root_window)->height, (mini_p ? 9 : 10));
dc6f92b8
JB
215
216 if (mini_p)
217 {
f4e93c40
KH
218 XSETFASTINT (XWINDOW (mini_window)->width, 10);
219 XSETFASTINT (XWINDOW (mini_window)->top, 9);
220 XSETFASTINT (XWINDOW (mini_window)->height, 1);
dc6f92b8
JB
221 }
222
ff11dfa1 223 /* Choose a buffer for the frame's root window. */
5bce042c
JB
224 {
225 Lisp_Object buf;
226
227 XWINDOW (root_window)->buffer = Qt;
228 buf = Fcurrent_buffer ();
229 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
230 a space), try to find another one. */
231 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
c3c73481 232 buf = Fother_buffer (buf, Qnil);
5bce042c
JB
233 Fset_window_buffer (root_window, buf);
234 }
235
dc6f92b8
JB
236 if (mini_p)
237 {
238 XWINDOW (mini_window)->buffer = Qt;
239 Fset_window_buffer (mini_window,
265a9e55 240 (NILP (Vminibuffer_list)
dc6f92b8
JB
241 ? get_minibuffer (0)
242 : Fcar (Vminibuffer_list)));
243 }
244
ff11dfa1
JB
245 f->root_window = root_window;
246 f->selected_window = root_window;
d5e7c279
JB
247 /* Make sure this window seems more recently used than
248 a newly-created, never-selected window. */
f4e93c40 249 XSETFASTINT (XWINDOW (f->selected_window)->use_time, ++window_select_count);
dc6f92b8 250
ff11dfa1 251 return f;
dc6f92b8
JB
252}
253\f
ff11dfa1 254/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
255 MINI_WINDOW is the minibuffer window to use. nil means use the
256 default (the global minibuffer). */
257
ff11dfa1
JB
258struct frame *
259make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
260 register Lisp_Object mini_window;
261{
ff11dfa1 262 register struct frame *f;
dc6f92b8
JB
263
264 /* Choose the minibuffer window to use. */
265a9e55 265 if (NILP (mini_window))
dc6f92b8 266 {
e35d291d 267 if (!FRAMEP (Vdefault_minibuffer_frame))
ff11dfa1
JB
268 error ("default-minibuffer-frame must be set when creating minibufferless frames");
269 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
270 error ("default-minibuffer-frame must be a live frame");
271 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
272 }
273 else
274 {
774910eb 275 CHECK_LIVE_WINDOW (mini_window, 0);
dc6f92b8
JB
276 }
277
ff11dfa1
JB
278 /* Make a frame containing just a root window. */
279 f = make_frame (0);
dc6f92b8
JB
280
281 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 282 f->minibuffer_window = mini_window;
dc6f92b8 283 Fset_window_buffer (mini_window,
265a9e55 284 (NILP (Vminibuffer_list)
dc6f92b8
JB
285 ? get_minibuffer (0)
286 : Fcar (Vminibuffer_list)));
ff11dfa1 287 return f;
dc6f92b8
JB
288}
289
ff11dfa1 290/* Make a frame containing only a minibuffer window. */
dc6f92b8 291
ff11dfa1
JB
292struct frame *
293make_minibuffer_frame ()
dc6f92b8 294{
ff11dfa1 295 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 296
ff11dfa1 297 register struct frame *f = make_frame (0);
dc6f92b8 298 register Lisp_Object mini_window;
ff11dfa1 299 register Lisp_Object frame;
dc6f92b8 300
2d80a27a 301 XSETFRAME (frame, f);
dc6f92b8 302
804518aa 303 f->auto_raise = 0;
ff11dfa1
JB
304 f->auto_lower = 0;
305 f->no_split = 1;
306 f->wants_modeline = 0;
307 f->has_minibuffer = 1;
dc6f92b8
JB
308
309 /* Now label the root window as also being the minibuffer.
310 Avoid infinite looping on the window chain by marking next pointer
311 as nil. */
312
ff11dfa1 313 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
314 XWINDOW (mini_window)->mini_p = Qt;
315 XWINDOW (mini_window)->next = Qnil;
804518aa 316 XWINDOW (mini_window)->prev = Qnil;
ff11dfa1 317 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
318
319 /* Put the proper buffer in that window. */
320
321 Fset_window_buffer (mini_window,
265a9e55 322 (NILP (Vminibuffer_list)
dc6f92b8
JB
323 ? get_minibuffer (0)
324 : Fcar (Vminibuffer_list)));
ff11dfa1 325 return f;
dc6f92b8
JB
326}
327\f
ff11dfa1 328/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 329
bb1513c9
RS
330static int terminal_frame_count;
331
ff11dfa1
JB
332struct frame *
333make_terminal_frame ()
dc6f92b8 334{
ff11dfa1 335 register struct frame *f;
d063751a 336 Lisp_Object frame;
bb1513c9
RS
337 char name[20];
338
b4f0ee5d
KH
339#ifdef MULTI_KBOARD
340 if (!initial_kboard)
341 {
342 initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
343 init_kboard (initial_kboard);
a1b658dd
KH
344 initial_kboard->next_kboard = all_kboards;
345 all_kboards = initial_kboard;
b4f0ee5d
KH
346 }
347#endif
348
bb1513c9
RS
349 /* The first call must initialize Vframe_list. */
350 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
351 Vframe_list = Qnil;
ff11dfa1 352
ff11dfa1 353 f = make_frame (1);
d063751a 354
2d80a27a 355 XSETFRAME (frame, f);
d063751a
RS
356 Vframe_list = Fcons (frame, Vframe_list);
357
bb1513c9 358 terminal_frame_count++;
3f005256
RS
359 if (terminal_frame_count == 1)
360 {
361 f->name = build_string ("Emacs");
362 }
363 else
364 {
365 sprintf (name, "Emacs-%d", terminal_frame_count);
366 f->name = build_string (name);
367 }
bb1513c9 368
bb1513c9
RS
369 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
370 f->async_visible = 1; /* Don't let visible be cleared later. */
371 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
2d80a27a 372 XSETFRAME (Vterminal_frame, f);
ff11dfa1 373 return f;
dc6f92b8 374}
bb1513c9
RS
375
376DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
4bc7e3ad
RS
377 1, 1, 0, "Create an additional terminal frame.\n\
378You can create multiple frames on a text-only terminal in this way.\n\
379Only the selected terminal frame is actually displayed.\n\
380This function takes one argument, an alist specifying frame parameters.\n\
381In practice, generally you don't need to specify any parameters.\n\
382Note that changing the size of one terminal frame automatically affects all.")
bb1513c9
RS
383 (parms)
384 Lisp_Object parms;
385{
386 struct frame *f;
387 Lisp_Object frame;
388
389 if (selected_frame->output_method != output_termcap)
390 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
391
392 f = make_terminal_frame ();
393 change_frame_size (f, FRAME_HEIGHT (selected_frame),
394 FRAME_WIDTH (selected_frame), 0, 0);
395 remake_frame_glyphs (f);
396 calculate_costs (f);
397 XSETFRAME (frame, f);
398 Fmodify_frame_parameters (frame, parms);
399 return frame;
400}
dc6f92b8 401\f
0aed85f4
KH
402static Lisp_Object
403do_switch_frame (frame, no_enter, track)
ff11dfa1 404 Lisp_Object frame, no_enter;
0aed85f4 405 int track;
dc6f92b8 406{
2f0b07e0
JB
407 /* If FRAME is a switch-frame event, extract the frame we should
408 switch to. */
409 if (CONSP (frame)
410 && EQ (XCONS (frame)->car, Qswitch_frame)
411 && CONSP (XCONS (frame)->cdr))
412 frame = XCONS (XCONS (frame)->cdr)->car;
413
09907c3a
KH
414 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
415 a switch-frame event to arrive after a frame is no longer live,
416 especially when deleting the initial frame during startup. */
417 CHECK_FRAME (frame, 0);
418 if (! FRAME_LIVE_P (XFRAME (frame)))
419 return Qnil;
dc6f92b8 420
ff11dfa1
JB
421 if (selected_frame == XFRAME (frame))
422 return frame;
dc6f92b8 423
0aed85f4
KH
424 /* This is too greedy; it causes inappropriate focus redirection
425 that's hard to get rid of. */
426#if 0
a42e9724
JB
427 /* If a frame's focus has been redirected toward the currently
428 selected frame, we should change the redirection to point to the
429 newly selected frame. This means that if the focus is redirected
430 from a minibufferless frame to a surrogate minibuffer frame, we
431 can use `other-window' to switch between all the frames using
432 that minibuffer frame, and the focus redirection will follow us
433 around. */
0aed85f4
KH
434 if (track)
435 {
436 Lisp_Object tail;
a42e9724 437
0aed85f4
KH
438 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
439 {
440 Lisp_Object focus;
a42e9724 441
e35d291d 442 if (!FRAMEP (XCONS (tail)->car))
0aed85f4 443 abort ();
a42e9724 444
0aed85f4 445 focus = FRAME_FOCUS_FRAME (XFRAME (XCONS (tail)->car));
a42e9724 446
e35d291d 447 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
0aed85f4
KH
448 Fredirect_frame_focus (XCONS (tail)->car, frame);
449 }
450 }
451#else /* ! 0 */
452 /* Instead, apply it only to the frame we're pointing to. */
453#ifdef HAVE_X_WINDOWS
454 if (track)
455 {
456 Lisp_Object focus, xfocus;
457
458 xfocus = x_get_focus_frame ();
459 if (FRAMEP (xfocus))
460 {
461 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
462 if (FRAMEP (focus) && XFRAME (focus) == selected_frame)
463 Fredirect_frame_focus (xfocus, frame);
464 }
465 }
466#endif /* HAVE_X_WINDOWS */
467#endif /* ! 0 */
a42e9724 468
bb1513c9
RS
469 if (FRAME_TERMCAP_P (XFRAME (frame)))
470 {
471 /* Since frames on an ASCII terminal share the same display area,
472 switching means we must redisplay the whole thing. */
473 windows_or_buffers_changed++;
474 SET_FRAME_GARBAGED (XFRAME (frame));
475 }
476
ff11dfa1
JB
477 selected_frame = XFRAME (frame);
478 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
479 last_nonminibuf_frame = selected_frame;
d5e7c279 480
ff11dfa1 481 Fselect_window (XFRAME (frame)->selected_window);
ff11dfa1 482 choose_minibuf_frame ();
dc6f92b8 483
074577b8 484 /* We want to make sure that the next event generates a frame-switch
eb8c3be9 485 event to the appropriate frame. This seems kludgy to me, but
074577b8
JB
486 before you take it out, make sure that evaluating something like
487 (select-window (frame-root-window (new-frame))) doesn't end up
488 with your typing being interpreted in the new frame instead of
489 the one you're actually typing in. */
ef352596 490 internal_last_event_frame = Qnil;
074577b8 491
ff11dfa1 492 return frame;
dc6f92b8
JB
493}
494
0aed85f4
KH
495DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
496 "Select the frame FRAME.\n\
497Subsequent editing commands apply to its selected window.\n\
498The selection of FRAME lasts until the next time the user does\n\
499something to select a different frame, or until the next time this\n\
500function is called.")
501 (frame, no_enter)
502 Lisp_Object frame, no_enter;
503{
504 return do_switch_frame (frame, no_enter, 1);
505}
506
507
508DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 2, "e",
509 "Handle a switch-frame event EVENT.\n\
510Switch-frame events are usually bound to this function.\n\
511A switch-frame event tells Emacs that the window manager has requested\n\
512that the user's events be directed to the frame mentioned in the event.\n\
513This function selects the selected window of the frame of EVENT.\n\
514\n\
515If EVENT is frame object, handle it as if it were a switch-frame event\n\
516to that frame.")
517 (frame, no_enter)
518 Lisp_Object frame, no_enter;
519{
520 return do_switch_frame (frame, no_enter, 0);
521}
522
523
ff11dfa1
JB
524DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
525 "Return the frame that is now selected.")
dc6f92b8
JB
526 ()
527{
528 Lisp_Object tem;
2d80a27a 529 XSETFRAME (tem, selected_frame);
dc6f92b8
JB
530 return tem;
531}
4a7cfafc 532\f
ff11dfa1
JB
533DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
534 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
535 (window)
536 Lisp_Object window;
537{
774910eb 538 CHECK_LIVE_WINDOW (window, 0);
ff11dfa1 539 return XWINDOW (window)->frame;
dc6f92b8
JB
540}
541
ba32f2db
KH
542DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
543 "Returns the topmost, leftmost window of FRAME.\n\
544If omitted, FRAME defaults to the currently selected frame.")
545 (frame)
546 Lisp_Object frame;
547{
548 Lisp_Object w;
549
550 if (NILP (frame))
551 w = selected_frame->root_window;
552 else
553 {
554 CHECK_LIVE_FRAME (frame, 0);
555 w = XFRAME (frame)->root_window;
556 }
557 while (NILP (XWINDOW (w)->buffer))
558 {
559 if (! NILP (XWINDOW (w)->hchild))
560 w = XWINDOW (w)->hchild;
561 else if (! NILP (XWINDOW (w)->vchild))
562 w = XWINDOW (w)->vchild;
563 else
564 abort ();
565 }
566 return w;
567}
568
5add3885
RS
569DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
570 Sactive_minibuffer_window, 0, 0, 0,
571 "Return the currently active minibuffer window, or nil if none.")
572 ()
573{
574 return minibuf_level ? minibuf_window : Qnil;
575}
576
ff11dfa1 577DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
8693ca83
JB
578 "Returns the root-window of FRAME.\n\
579If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
580 (frame)
581 Lisp_Object frame;
dc6f92b8 582{
ff11dfa1 583 if (NILP (frame))
2d80a27a 584 XSETFRAME (frame, selected_frame);
f9898cc6 585 else
ff11dfa1 586 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 587
ff11dfa1 588 return XFRAME (frame)->root_window;
dc6f92b8
JB
589}
590
ff11dfa1
JB
591DEFUN ("frame-selected-window", Fframe_selected_window,
592 Sframe_selected_window, 0, 1, 0,
8693ca83
JB
593 "Return the selected window of frame object FRAME.\n\
594If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
595 (frame)
596 Lisp_Object frame;
dc6f92b8 597{
ff11dfa1 598 if (NILP (frame))
2d80a27a 599 XSETFRAME (frame, selected_frame);
f9898cc6 600 else
ff11dfa1 601 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 602
ff11dfa1 603 return XFRAME (frame)->selected_window;
dc6f92b8
JB
604}
605
4a7cfafc
RS
606DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
607 Sset_frame_selected_window, 2, 2, 0,
608 "Set the selected window of frame object FRAME to WINDOW.\n\
609If FRAME is nil, the selected frame is used.\n\
610If FRAME is the selected frame, this makes WINDOW the selected window.")
611 (frame, window)
612 Lisp_Object frame, window;
613{
614 if (NILP (frame))
2d80a27a 615 XSETFRAME (frame, selected_frame);
4a7cfafc
RS
616 else
617 CHECK_LIVE_FRAME (frame, 0);
618
619 CHECK_LIVE_WINDOW (window, 1);
620
621 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
622 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
623
624 if (XFRAME (frame) == selected_frame)
625 return Fselect_window (window);
626
627 return XFRAME (frame)->selected_window = window;
628}
629\f
ff11dfa1 630DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 631 0, 0, 0,
ff11dfa1 632 "Return a list of all frames.")
dc6f92b8
JB
633 ()
634{
ff11dfa1 635 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
636}
637
ff11dfa1 638/* Return the next frame in the frame list after FRAME.
ff11dfa1 639 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
640 If MINIBUF is a window, include only its own frame
641 and any frame now using that window as the minibuffer.
f7af3f7b 642 If MINIBUF is `visible', include all visible frames.
a9986780 643 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
644 Otherwise, include all frames. */
645
dc6f92b8 646Lisp_Object
ff11dfa1
JB
647next_frame (frame, minibuf)
648 Lisp_Object frame;
f9898cc6 649 Lisp_Object minibuf;
dc6f92b8
JB
650{
651 Lisp_Object tail;
652 int passed = 0;
653
ff11dfa1
JB
654 /* There must always be at least one frame in Vframe_list. */
655 if (! CONSP (Vframe_list))
f9898cc6
JB
656 abort ();
657
dbc4e1c1
JB
658 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
659 forever. Forestall that. */
660 CHECK_LIVE_FRAME (frame, 0);
661
dc6f92b8 662 while (1)
ff11dfa1 663 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 664 {
ab9f008d 665 Lisp_Object f;
d06a8a56 666
ab9f008d 667 f = XCONS (tail)->car;
dc6f92b8 668 if (passed)
d5e7c279 669 {
d06a8a56
JB
670 /* Decide whether this frame is eligible to be returned. */
671
672 /* If we've looped all the way around without finding any
673 eligible frames, return the original frame. */
674 if (EQ (f, frame))
675 return f;
676
677 /* Let minibuf decide if this frame is acceptable. */
678 if (NILP (minibuf))
679 {
680 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
681 return f;
682 }
f7af3f7b
RS
683 else if (EQ (minibuf, Qvisible))
684 {
685 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
686 if (FRAME_VISIBLE_P (XFRAME (f)))
687 return f;
688 }
a9986780
RS
689 else if (XFASTINT (minibuf) == 0)
690 {
691 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
692 if (FRAME_VISIBLE_P (XFRAME (f))
693 || FRAME_ICONIFIED_P (XFRAME (f)))
694 return f;
695 }
f7af3f7b 696 else if (WINDOWP (minibuf))
d06a8a56 697 {
a9986780
RS
698 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
699 /* Check that F either is, or has forwarded its focus to,
700 MINIBUF's frame. */
701 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
702 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
703 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
704 return f;
705 }
706 else
ff11dfa1 707 return f;
d5e7c279 708 }
dc6f92b8 709
d06a8a56 710 if (EQ (frame, f))
dc6f92b8
JB
711 passed++;
712 }
713}
714
ff11dfa1 715/* Return the previous frame in the frame list before FRAME.
ff11dfa1 716 If MINIBUF is nil, exclude minibuffer-only frames.
a9986780
RS
717 If MINIBUF is a window, include only its own frame
718 and any frame now using that window as the minibuffer.
f7af3f7b 719 If MINIBUF is `visible', include all visible frames.
a9986780 720 If MINIBUF is 0, include all visible and iconified frames.
f7af3f7b
RS
721 Otherwise, include all frames. */
722
dc6f92b8 723Lisp_Object
ff11dfa1
JB
724prev_frame (frame, minibuf)
725 Lisp_Object frame;
f9898cc6 726 Lisp_Object minibuf;
dc6f92b8
JB
727{
728 Lisp_Object tail;
729 Lisp_Object prev;
730
ff11dfa1
JB
731 /* There must always be at least one frame in Vframe_list. */
732 if (! CONSP (Vframe_list))
f9898cc6
JB
733 abort ();
734
dc6f92b8 735 prev = Qnil;
d06a8a56 736 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6 737 {
ab9f008d 738 Lisp_Object f;
f9898cc6 739
ab9f008d 740 f = XCONS (tail)->car;
e35d291d 741 if (!FRAMEP (f))
d06a8a56 742 abort ();
f9898cc6 743
d06a8a56
JB
744 if (EQ (frame, f) && !NILP (prev))
745 return prev;
f9898cc6 746
d06a8a56
JB
747 /* Decide whether this frame is eligible to be returned,
748 according to minibuf. */
749 if (NILP (minibuf))
750 {
751 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
752 prev = f;
f9898cc6 753 }
aea9f59e 754 else if (WINDOWP (minibuf))
d06a8a56 755 {
a9986780
RS
756 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
757 /* Check that F either is, or has forwarded its focus to,
758 MINIBUF's frame. */
759 && (EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
760 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
761 FRAME_FOCUS_FRAME (XFRAME (f)))))
d06a8a56
JB
762 prev = f;
763 }
f7af3f7b
RS
764 else if (EQ (minibuf, Qvisible))
765 {
766 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
767 if (FRAME_VISIBLE_P (XFRAME (f)))
768 prev = f;
769 }
aea9f59e 770 else if (XFASTINT (minibuf) == 0)
a9986780
RS
771 {
772 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
773 if (FRAME_VISIBLE_P (XFRAME (f))
774 || FRAME_ICONIFIED_P (XFRAME (f)))
775 prev = f;
776 }
d06a8a56
JB
777 else
778 prev = f;
f9898cc6 779 }
d06a8a56
JB
780
781 /* We've scanned the entire list. */
782 if (NILP (prev))
783 /* We went through the whole frame list without finding a single
784 acceptable frame. Return the original frame. */
785 return frame;
786 else
787 /* There were no acceptable frames in the list before FRAME; otherwise,
788 we would have returned directly from the loop. Since PREV is the last
789 acceptable frame in the list, return it. */
790 return prev;
dc6f92b8
JB
791}
792
ef2c57ac 793
ff11dfa1
JB
794DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
795 "Return the next frame in the frame list after FRAME.\n\
a42e9724 796By default, skip minibuffer-only frames.\n\
d06a8a56 797If omitted, FRAME defaults to the selected frame.\n\
c08c95c7 798If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
a9986780
RS
799If MINIBUF is a window, include only its own frame\n\
800and any frame now using that window as the minibuffer.\n\
f7af3f7b 801If MINIFRAME is `visible', include all visible frames.\n\
a9986780 802If MINIBUF is 0, include all visible and iconified frames.\n\
f7af3f7b 803Otherwise, include all frames.")
ff11dfa1 804 (frame, miniframe)
8693ca83 805 Lisp_Object frame, miniframe;
dc6f92b8
JB
806{
807 Lisp_Object tail;
808
ff11dfa1 809 if (NILP (frame))
2d80a27a 810 XSETFRAME (frame, selected_frame);
f9898cc6 811 else
ff11dfa1 812 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 813
ff11dfa1 814 return next_frame (frame, miniframe);
dc6f92b8 815}
dbc4e1c1 816
ef2c57ac
RM
817DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
818 "Return the previous frame in the frame list before FRAME.\n\
819By default, skip minibuffer-only frames.\n\
820If omitted, FRAME defaults to the selected frame.\n\
821If optional argument MINIFRAME is nil, exclude minibuffer-only frames.\n\
a9986780
RS
822If MINIBUF is a window, include only its own frame\n\
823and any frame now using that window as the minibuffer.\n\
f7af3f7b 824If MINIFRAME is `visible', include all visible frames.\n\
a9986780 825If MINIBUF is 0, include all visible and iconified frames.\n\
f7af3f7b 826Otherwise, include all frames.")
ef2c57ac
RM
827 (frame, miniframe)
828 Lisp_Object frame, miniframe;
829{
830 Lisp_Object tail;
831
832 if (NILP (frame))
2d80a27a 833 XSETFRAME (frame, selected_frame);
ef2c57ac
RM
834 else
835 CHECK_LIVE_FRAME (frame, 0);
836
837 return prev_frame (frame, miniframe);
838}
dc6f92b8 839\f
808c0f20
RS
840/* Return 1 if it is ok to delete frame F;
841 0 if all frames aside from F are invisible.
842 (Exception: if F is the terminal frame, and we are using X, return 1.) */
dc6f92b8 843
d56b45eb 844int
808c0f20
RS
845other_visible_frames (f)
846 FRAME_PTR f;
847{
848 /* We know the selected frame is visible,
849 so if F is some other frame, it can't be the sole visible one. */
850 if (f == selected_frame)
c08c95c7
RS
851 {
852 Lisp_Object frames;
853 int count = 0;
854
855 for (frames = Vframe_list;
856 CONSP (frames);
857 frames = XCONS (frames)->cdr)
858 {
ab9f008d 859 Lisp_Object this;
c08c95c7 860
ab9f008d 861 this = XCONS (frames)->car;
808c0f20
RS
862 /* Verify that the frame's window still exists
863 and we can still talk to it. And note any recent change
864 in visibility. */
5e7b7c5b
RS
865#ifdef HAVE_X_WINDOWS
866 if (FRAME_X_P (XFRAME (this)))
867 {
b0509a40 868 x_sync (XFRAME (this));
5e7b7c5b
RS
869 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
870 }
871#endif
872
c08c95c7
RS
873 if (FRAME_VISIBLE_P (XFRAME (this))
874 || FRAME_ICONIFIED_P (XFRAME (this))
875 /* Allow deleting the terminal frame when at least
876 one X frame exists! */
9fbb139c 877 || (FRAME_X_P (XFRAME (this)) && !FRAME_X_P (f)))
c08c95c7
RS
878 count++;
879 }
808c0f20 880 return count > 1;
c08c95c7 881 }
808c0f20
RS
882 return 1;
883}
884
885DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
886 "Delete FRAME, permanently eliminating it from use.\n\
887If omitted, FRAME defaults to the selected frame.\n\
888A frame may not be deleted if its minibuffer is used by other frames.\n\
889Normally, you may not delete a frame if all other frames are invisible,\n\
890but if the second optional argument FORCE is non-nil, you may do so.")
891 (frame, force)
892 Lisp_Object frame, force;
893{
894 struct frame *f;
895
896 if (EQ (frame, Qnil))
897 {
898 f = selected_frame;
2d80a27a 899 XSETFRAME (frame, f);
808c0f20
RS
900 }
901 else
902 {
903 CHECK_FRAME (frame, 0);
904 f = XFRAME (frame);
905 }
906
907 if (! FRAME_LIVE_P (f))
908 return Qnil;
909
910 if (NILP (force) && !other_visible_frames (f))
911 error ("Attempt to delete the sole visible or iconified frame");
d5e7c279 912
ff11dfa1
JB
913 /* Does this frame have a minibuffer, and is it the surrogate
914 minibuffer for any other frame? */
fd0c2bd1 915 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
dc6f92b8 916 {
ff11dfa1 917 Lisp_Object frames;
1113d9db 918
ff11dfa1
JB
919 for (frames = Vframe_list;
920 CONSP (frames);
921 frames = XCONS (frames)->cdr)
1113d9db 922 {
7a8cc307
RS
923 Lisp_Object this;
924 this = XCONS (frames)->car;
1113d9db 925
ff11dfa1
JB
926 if (! EQ (this, frame)
927 && EQ (frame,
7a8cc307
RS
928 WINDOW_FRAME (XWINDOW
929 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
ff11dfa1 930 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 931 }
dc6f92b8
JB
932 }
933
ff11dfa1
JB
934 /* Don't let the frame remain selected. */
935 if (f == selected_frame)
0f85737c 936 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
dc6f92b8 937
ff11dfa1
JB
938 /* Don't allow minibuf_window to remain on a deleted frame. */
939 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 940 {
ff11dfa1 941 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 942 XWINDOW (minibuf_window)->buffer);
ff11dfa1 943 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
944 }
945
bb2a0a65
RS
946 /* Clear any X selections for this frame. */
947#ifdef HAVE_X_WINDOWS
948 if (FRAME_X_P (f))
949 x_clear_frame_selections (f);
950#endif
951
4a88b3b0
JB
952 /* Mark all the windows that used to be on FRAME as deleted, and then
953 remove the reference to them. */
954 delete_all_subwindows (XWINDOW (f->root_window));
955 f->root_window = Qnil;
956
ff11dfa1 957 Vframe_list = Fdelq (frame, Vframe_list);
a42e9724 958 FRAME_SET_VISIBLE (f, 0);
dc6f92b8 959
d2bee99e
RS
960 if (FRAME_CURRENT_GLYPHS (f))
961 free_frame_glyphs (f, FRAME_CURRENT_GLYPHS (f));
962 if (FRAME_DESIRED_GLYPHS (f))
963 free_frame_glyphs (f, FRAME_DESIRED_GLYPHS (f));
964 if (FRAME_TEMP_GLYPHS (f))
965 free_frame_glyphs (f, FRAME_TEMP_GLYPHS (f));
966 if (FRAME_INSERT_COST (f))
967 free (FRAME_INSERT_COST (f));
968 if (FRAME_DELETEN_COST (f))
09d1d7e2 969 free (FRAME_DELETEN_COST (f));
d2bee99e 970 if (FRAME_INSERTN_COST (f))
09d1d7e2 971 free (FRAME_INSERTN_COST (f));
d2bee99e 972 if (FRAME_DELETE_COST (f))
09d1d7e2 973 free (FRAME_DELETE_COST (f));
d2bee99e 974
8678b9cc
JB
975 /* Since some events are handled at the interrupt level, we may get
976 an event for f at any time; if we zero out the frame's display
977 now, then we may trip up the event-handling code. Instead, we'll
978 promise that the display of the frame must be valid until we have
979 called the window-system-dependent frame destruction routine. */
dbc4e1c1
JB
980
981 /* I think this should be done with a hook. */
d5e7c279 982#ifdef HAVE_X_WINDOWS
fd0c2bd1 983 if (FRAME_X_P (f))
8678b9cc 984 x_destroy_window (f);
d5e7c279
JB
985#endif
986
8678b9cc
JB
987 f->display.nothing = 0;
988
ff11dfa1 989 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 990 another one. */
ff11dfa1 991 if (f == last_nonminibuf_frame)
d5e7c279 992 {
ff11dfa1 993 Lisp_Object frames;
1113d9db 994
ff11dfa1 995 last_nonminibuf_frame = 0;
d5e7c279 996
ff11dfa1
JB
997 for (frames = Vframe_list;
998 CONSP (frames);
999 frames = XCONS (frames)->cdr)
d5e7c279 1000 {
ff11dfa1
JB
1001 f = XFRAME (XCONS (frames)->car);
1002 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 1003 {
ff11dfa1 1004 last_nonminibuf_frame = f;
d5e7c279
JB
1005 break;
1006 }
1007 }
1008 }
dc6f92b8 1009
ff11dfa1
JB
1010 /* If we've deleted Vdefault_minibuffer_frame, try to find another
1011 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 1012 with other windows. */
ff11dfa1 1013 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 1014 {
ff11dfa1 1015 Lisp_Object frames;
1113d9db 1016
ff11dfa1 1017 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
ab9f008d 1018 Lisp_Object frame_with_minibuf;
1113d9db 1019
ab9f008d 1020 frame_with_minibuf = Qnil;
ff11dfa1
JB
1021 for (frames = Vframe_list;
1022 CONSP (frames);
1023 frames = XCONS (frames)->cdr)
1113d9db 1024 {
ab9f008d 1025 Lisp_Object this;
1113d9db 1026
ab9f008d 1027 this = XCONS (frames)->car;
e35d291d 1028 if (!FRAMEP (this))
1113d9db 1029 abort ();
ff11dfa1 1030 f = XFRAME (this);
1113d9db 1031
fd0c2bd1 1032 if (FRAME_HAS_MINIBUF_P (f))
1113d9db 1033 {
ff11dfa1
JB
1034 frame_with_minibuf = this;
1035 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
1036 break;
1037 }
1038 }
1039
ff11dfa1
JB
1040 /* We know that there must be some frame with a minibuffer out
1041 there. If this were not true, all of the frames present
1113d9db 1042 would have to be minibufferless, which implies that at some
ff11dfa1 1043 point their minibuffer frames must have been deleted, but
1113d9db 1044 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
1045 minibuffer frames. */
1046 if (NILP (frame_with_minibuf))
1113d9db
JB
1047 abort ();
1048
ff11dfa1 1049 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
1050 }
1051
dc6f92b8
JB
1052 return Qnil;
1053}
1054\f
1055/* Return mouse position in character cell units. */
1056
f9898cc6 1057DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 1058 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
4f90516b
JB
1059The position is given in character cells, where (0, 0) is the\n\
1060upper-left corner.\n\
f9898cc6 1061If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 1062to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
1063and nil for X and Y.")
1064 ()
dc6f92b8 1065{
ff11dfa1 1066 FRAME_PTR f;
dbc4e1c1 1067 Lisp_Object lispy_dummy;
fd2777e0 1068 enum scroll_bar_part party_dummy;
dbc4e1c1 1069 Lisp_Object x, y;
5384466a 1070 int col, row;
dbc4e1c1 1071 unsigned long long_dummy;
dc6f92b8 1072
c5074d8c
RS
1073 f = selected_frame;
1074 x = y = Qnil;
1075
f443c170 1076#ifdef HAVE_MOUSE
c5074d8c 1077 /* It's okay for the hook to refrain from storing anything. */
f9898cc6 1078 if (mouse_position_hook)
0c5c1cf7 1079 (*mouse_position_hook) (&f, 0,
dbc4e1c1
JB
1080 &lispy_dummy, &party_dummy,
1081 &x, &y,
1082 &long_dummy);
76db7eb4
KH
1083 if (! NILP (x))
1084 {
1085 col = XINT (x);
1086 row = XINT (y);
6a6d921c 1087 pixel_to_glyph_coords (f, col, row, &col, &row, 0, 1);
76db7eb4
KH
1088 XSETINT (x, col);
1089 XSETINT (y, row);
1090 }
f443c170 1091#endif
2d80a27a 1092 XSETFRAME (lispy_dummy, f);
c5074d8c 1093 return Fcons (lispy_dummy, Fcons (x, y));
dc6f92b8
JB
1094}
1095
152e6c70
RS
1096DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1097 Smouse_pixel_position, 0, 0, 0,
1098 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
1099The position is given in pixel units, where (0, 0) is the\n\
1100upper-left corner.\n\
1101If Emacs is running on a mouseless terminal or hasn't been programmed\n\
1102to read the mouse position, it returns the selected frame for FRAME\n\
1103and nil for X and Y.")
1104 ()
1105{
1106 FRAME_PTR f;
1107 Lisp_Object lispy_dummy;
1108 enum scroll_bar_part party_dummy;
1109 Lisp_Object x, y;
1110 int col, row;
1111 unsigned long long_dummy;
1112
1113 f = selected_frame;
1114 x = y = Qnil;
1115
0c5c1cf7 1116#ifdef HAVE_MOUSE
152e6c70
RS
1117 /* It's okay for the hook to refrain from storing anything. */
1118 if (mouse_position_hook)
0c5c1cf7 1119 (*mouse_position_hook) (&f, 0,
152e6c70
RS
1120 &lispy_dummy, &party_dummy,
1121 &x, &y,
1122 &long_dummy);
0c5c1cf7 1123#endif
2d80a27a 1124 XSETFRAME (lispy_dummy, f);
152e6c70
RS
1125 return Fcons (lispy_dummy, Fcons (x, y));
1126}
1127
dc6f92b8 1128DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1d7cc616 1129 "Move the mouse pointer to the center of character cell (X,Y) in FRAME.\n\
152e6c70
RS
1130WARNING: If you use this under X windows,\n\
1131you should call `unfocus-frame' afterwards.")
ff11dfa1
JB
1132 (frame, x, y)
1133 Lisp_Object frame, x, y;
dc6f92b8 1134{
ff11dfa1 1135 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1136 CHECK_NUMBER (x, 2);
1137 CHECK_NUMBER (y, 1);
1138
dbc4e1c1 1139 /* I think this should be done with a hook. */
dc6f92b8 1140#ifdef HAVE_X_WINDOWS
fd0c2bd1 1141 if (FRAME_X_P (XFRAME (frame)))
dc6f92b8 1142 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 1143 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
1144#endif
1145
1146 return Qnil;
1147}
152e6c70
RS
1148
1149DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1150 Sset_mouse_pixel_position, 3, 3, 0,
1151 "Move the mouse pointer to pixel position (X,Y) in FRAME.\n\
1152WARNING: If you use this under X windows,\n\
1153you should call `unfocus-frame' afterwards.")
1154 (frame, x, y)
1155 Lisp_Object frame, x, y;
1156{
1157 CHECK_LIVE_FRAME (frame, 0);
1158 CHECK_NUMBER (x, 2);
1159 CHECK_NUMBER (y, 1);
1160
1161 /* I think this should be done with a hook. */
1162#ifdef HAVE_X_WINDOWS
1163 if (FRAME_X_P (XFRAME (frame)))
1164 /* Warping the mouse will cause enternotify and focus events. */
1165 x_set_mouse_pixel_position (XFRAME (frame), x, y);
1166#endif
1167
1168 return Qnil;
1169}
dc6f92b8 1170\f
ff11dfa1 1171DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
fc25d15d 1172 0, 1, "",
ff11dfa1 1173 "Make the frame FRAME visible (assuming it is an X-window).\n\
8693ca83 1174If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1175 (frame)
1176 Lisp_Object frame;
dc6f92b8 1177{
1aa66088 1178 if (NILP (frame))
2d80a27a 1179 XSETFRAME (frame, selected_frame);
1aa66088 1180
ff11dfa1 1181 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1182
dbc4e1c1 1183 /* I think this should be done with a hook. */
fd0c2bd1
JB
1184#ifdef HAVE_X_WINDOWS
1185 if (FRAME_X_P (XFRAME (frame)))
02ff9dd5
RS
1186 {
1187 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1188 x_make_frame_visible (XFRAME (frame));
1189 }
fd0c2bd1 1190#endif
dc6f92b8 1191
565620a5
RS
1192 /* Make menu bar update for the Buffers and Frams menus. */
1193 windows_or_buffers_changed++;
1194
ff11dfa1 1195 return frame;
dc6f92b8
JB
1196}
1197
ff11dfa1 1198DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
808c0f20 1199 0, 2, "",
8693ca83 1200 "Make the frame FRAME invisible (assuming it is an X-window).\n\
808c0f20
RS
1201If omitted, FRAME defaults to the currently selected frame.\n\
1202Normally you may not make FRAME invisible if all other frames are invisible,\n\
1203but if the second optional argument FORCE is non-nil, you may do so.")
1204 (frame, force)
1205 Lisp_Object frame, force;
dc6f92b8 1206{
1aa66088 1207 if (NILP (frame))
2d80a27a 1208 XSETFRAME (frame, selected_frame);
1aa66088 1209
ff11dfa1 1210 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1211
808c0f20
RS
1212 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1213 error ("Attempt to make invisible the sole visible or iconified frame");
1214
3d378fdf 1215#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1216 /* Don't let the frame remain selected. */
1217 if (XFRAME (frame) == selected_frame)
1218 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1219#endif
9c394f17
RS
1220
1221 /* Don't allow minibuf_window to remain on a deleted frame. */
1222 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1223 {
1224 Fset_window_buffer (selected_frame->minibuffer_window,
1225 XWINDOW (minibuf_window)->buffer);
1226 minibuf_window = selected_frame->minibuffer_window;
1227 }
1228
dbc4e1c1 1229 /* I think this should be done with a hook. */
fd0c2bd1
JB
1230#ifdef HAVE_X_WINDOWS
1231 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 1232 x_make_frame_invisible (XFRAME (frame));
fd0c2bd1 1233#endif
dc6f92b8 1234
565620a5
RS
1235 /* Make menu bar update for the Buffers and Frams menus. */
1236 windows_or_buffers_changed++;
1237
dc6f92b8
JB
1238 return Qnil;
1239}
1240
ff11dfa1 1241DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 1242 0, 1, "",
8693ca83
JB
1243 "Make the frame FRAME into an icon.\n\
1244If omitted, FRAME defaults to the currently selected frame.")
ff11dfa1
JB
1245 (frame)
1246 Lisp_Object frame;
dc6f92b8 1247{
1aa66088 1248 if (NILP (frame))
2d80a27a 1249 XSETFRAME (frame, selected_frame);
1aa66088 1250
ff11dfa1 1251 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1252
3d378fdf 1253#if 0 /* This isn't logically necessary, and it can do GC. */
9c394f17
RS
1254 /* Don't let the frame remain selected. */
1255 if (XFRAME (frame) == selected_frame)
1256 Fhandle_switch_frame (next_frame (frame, Qt), Qnil);
3d378fdf 1257#endif
9c394f17
RS
1258
1259 /* Don't allow minibuf_window to remain on a deleted frame. */
1260 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1261 {
1262 Fset_window_buffer (selected_frame->minibuffer_window,
1263 XWINDOW (minibuf_window)->buffer);
1264 minibuf_window = selected_frame->minibuffer_window;
1265 }
1266
dbc4e1c1 1267 /* I think this should be done with a hook. */
fd0c2bd1
JB
1268#ifdef HAVE_X_WINDOWS
1269 if (FRAME_X_P (XFRAME (frame)))
ff11dfa1 1270 x_iconify_frame (XFRAME (frame));
fd0c2bd1 1271#endif
dc6f92b8 1272
565620a5
RS
1273 /* Make menu bar update for the Buffers and Frams menus. */
1274 windows_or_buffers_changed++;
1275
dc6f92b8
JB
1276 return Qnil;
1277}
1278
ff11dfa1 1279DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 1280 1, 1, 0,
ff11dfa1
JB
1281 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
1282A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8 1283a window system, it may not show at all.\n\
fd0c2bd1 1284Return the symbol `icon' if frame is visible only as an icon.")
ff11dfa1
JB
1285 (frame)
1286 Lisp_Object frame;
dc6f92b8 1287{
ff11dfa1 1288 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 1289
5c044f55
RS
1290 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1291
a42e9724 1292 if (FRAME_VISIBLE_P (XFRAME (frame)))
dc6f92b8 1293 return Qt;
a42e9724 1294 if (FRAME_ICONIFIED_P (XFRAME (frame)))
fd0c2bd1 1295 return Qicon;
dc6f92b8
JB
1296 return Qnil;
1297}
1298
ff11dfa1 1299DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 1300 0, 0, 0,
ff11dfa1 1301 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
1302 ()
1303{
ff11dfa1
JB
1304 Lisp_Object tail, frame;
1305 struct frame *f;
dc6f92b8
JB
1306 Lisp_Object value;
1307
1308 value = Qnil;
ff11dfa1 1309 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 1310 {
ff11dfa1 1311 frame = XCONS (tail)->car;
e35d291d 1312 if (!FRAMEP (frame))
dc6f92b8 1313 continue;
ff11dfa1 1314 f = XFRAME (frame);
a42e9724 1315 if (FRAME_VISIBLE_P (f))
ff11dfa1 1316 value = Fcons (frame, value);
dc6f92b8
JB
1317 }
1318 return value;
1319}
d5e7c279
JB
1320
1321
828ac693 1322DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 1, 1, "",
dbc4e1c1
JB
1323 "Bring FRAME to the front, so it occludes any frames it overlaps.\n\
1324If FRAME is invisible, make it visible.\n\
828ac693 1325If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1326If Emacs is displaying on an ordinary terminal or some other device which\n\
1327doesn't support multiple overlapping frames, this function does nothing.")
1328 (frame)
1329 Lisp_Object frame;
1330{
828ac693
RS
1331 if (NILP (frame))
1332 XSETFRAME (frame, selected_frame);
1333
dbc4e1c1 1334 CHECK_LIVE_FRAME (frame, 0);
8a981af5
RS
1335
1336 /* Do like the documentation says. */
1337 Fmake_frame_visible (frame);
1338
dbc4e1c1
JB
1339 if (frame_raise_lower_hook)
1340 (*frame_raise_lower_hook) (XFRAME (frame), 1);
1341
1342 return Qnil;
1343}
1344
b49f5578 1345/* Should we have a corresponding function called Flower_Power? */
828ac693 1346DEFUN ("lower-frame", Flower_frame, Slower_frame, 1, 1, "",
dbc4e1c1 1347 "Send FRAME to the back, so it is occluded by any frames that overlap it.\n\
828ac693 1348If you don't specify a frame, the selected frame is used.\n\
dbc4e1c1
JB
1349If Emacs is displaying on an ordinary terminal or some other device which\n\
1350doesn't support multiple overlapping frames, this function does nothing.")
1351 (frame)
1352 Lisp_Object frame;
1353{
828ac693
RS
1354 if (NILP (frame))
1355 XSETFRAME (frame, selected_frame);
1356
dbc4e1c1
JB
1357 CHECK_LIVE_FRAME (frame, 0);
1358
1359 if (frame_raise_lower_hook)
1360 (*frame_raise_lower_hook) (XFRAME (frame), 0);
1361
1362 return Qnil;
1363}
1364
d5e7c279 1365\f
ff11dfa1 1366DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 1367 1, 2, 0,
ff11dfa1 1368 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
a42e9724
JB
1369In other words, switch-frame events caused by events in FRAME will\n\
1370request a switch to FOCUS-FRAME, and `last-event-frame' will be\n\
1371FOCUS-FRAME after reading an event typed at FRAME.\n\
d5e7c279 1372\n\
a42e9724 1373If FOCUS-FRAME is omitted or nil, any existing redirection is\n\
ff11dfa1 1374cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 1375\n\
a42e9724
JB
1376Focus redirection is useful for temporarily redirecting keystrokes to\n\
1377a surrogate minibuffer frame when a frame doesn't have its own\n\
1378minibuffer window.\n\
d5e7c279 1379\n\
a42e9724
JB
1380A frame's focus redirection can be changed by select-frame. If frame\n\
1381FOO is selected, and then a different frame BAR is selected, any\n\
1382frames redirecting their focus to FOO are shifted to redirect their\n\
1383focus to BAR. This allows focus redirection to work properly when the\n\
1384user switches from one frame to another using `select-window'.\n\
1385\n\
1386This means that a frame whose focus is redirected to itself is treated\n\
1387differently from a frame whose focus is redirected to nil; the former\n\
1388is affected by select-frame, while the latter is not.\n\
1389\n\
1390The redirection lasts until `redirect-frame-focus' is called to change it.")
ff11dfa1
JB
1391 (frame, focus_frame)
1392 Lisp_Object frame, focus_frame;
d5e7c279 1393{
13144095
JB
1394 /* Note that we don't check for a live frame here. It's reasonable
1395 to redirect the focus of a frame you're about to delete, if you
1396 know what other frame should receive those keystrokes. */
1397 CHECK_FRAME (frame, 0);
f9898cc6 1398
a42e9724 1399 if (! NILP (focus_frame))
ff11dfa1 1400 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 1401
ff11dfa1 1402 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 1403
9c394f17
RS
1404 /* I think this should be done with a hook. */
1405#ifdef HAVE_X_WINDOWS
1406 if (!NILP (focus_frame) && ! EQ (focus_frame, frame)
1407 && FRAME_X_P (XFRAME (focus_frame)))
1408 Ffocus_frame (focus_frame);
1409#endif
1410
ff11dfa1
JB
1411 if (frame_rehighlight_hook)
1412 (*frame_rehighlight_hook) ();
d5e7c279
JB
1413
1414 return Qnil;
1415}
1416
1417
ff11dfa1
JB
1418DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
1419 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
a42e9724 1420This returns nil if FRAME's focus is not redirected.\n\
ff11dfa1
JB
1421See `redirect-frame-focus'.")
1422 (frame)
1423 Lisp_Object frame;
d5e7c279 1424{
ff11dfa1 1425 CHECK_LIVE_FRAME (frame, 0);
a42e9724 1426
ff11dfa1 1427 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
1428}
1429
1430
dc6f92b8 1431\f
329ca574
RS
1432/* Return the value of frame parameter PROP in frame FRAME. */
1433
dc6f92b8 1434Lisp_Object
ff11dfa1
JB
1435get_frame_param (frame, prop)
1436 register struct frame *frame;
dc6f92b8
JB
1437 Lisp_Object prop;
1438{
1439 register Lisp_Object tem;
1440
ff11dfa1 1441 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
1442 if (EQ (tem, Qnil))
1443 return tem;
1444 return Fcdr (tem);
1445}
1446
329ca574
RS
1447/* Return the buffer-predicate of the selected frame. */
1448
1449Lisp_Object
1450frame_buffer_predicate ()
1451{
1452 return selected_frame->buffer_predicate;
1453}
1454
1455/* Modify the alist in *ALISTPTR to associate PROP with VAL.
1456 If the alist already has an element for PROP, we change it. */
1457
dc6f92b8 1458void
fd0c2bd1 1459store_in_alist (alistptr, prop, val)
dc6f92b8 1460 Lisp_Object *alistptr, val;
fd0c2bd1 1461 Lisp_Object prop;
dc6f92b8
JB
1462{
1463 register Lisp_Object tem;
dc6f92b8 1464
dc6f92b8
JB
1465 tem = Fassq (prop, *alistptr);
1466 if (EQ (tem, Qnil))
1467 *alistptr = Fcons (Fcons (prop, val), *alistptr);
1468 else
1469 Fsetcdr (tem, val);
1470}
1471
1472void
ff11dfa1
JB
1473store_frame_param (f, prop, val)
1474 struct frame *f;
dc6f92b8
JB
1475 Lisp_Object prop, val;
1476{
1477 register Lisp_Object tem;
1478
ff11dfa1 1479 tem = Fassq (prop, f->param_alist);
dc6f92b8 1480 if (EQ (tem, Qnil))
ff11dfa1 1481 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
1482 else
1483 Fsetcdr (tem, val);
bc93c097 1484
329ca574
RS
1485 if (EQ (prop, Qbuffer_predicate))
1486 f->buffer_predicate = val;
1487
e35d291d 1488 if (EQ (prop, Qminibuffer) && WINDOWP (val))
bc93c097
JB
1489 {
1490 if (! MINI_WINDOW_P (XWINDOW (val)))
1491 error ("Surrogate minibuffer windows must be minibuffer windows.");
1492
fd0c2bd1 1493 if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
1fb2d074 1494 error ("can't change the surrogate minibuffer of a frame with its own minibuffer");
bc93c097
JB
1495
1496 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 1497 f->minibuffer_window = val;
bc93c097 1498 }
dc6f92b8
JB
1499}
1500
ff11dfa1
JB
1501DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
1502 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 1503It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
1504The meaningful PARMs depend on the kind of frame.\n\
1505If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
1506 (frame)
1507 Lisp_Object frame;
dc6f92b8
JB
1508{
1509 Lisp_Object alist;
f769f1b2 1510 FRAME_PTR f;
dc6f92b8 1511
ff11dfa1
JB
1512 if (EQ (frame, Qnil))
1513 f = selected_frame;
dc6f92b8
JB
1514 else
1515 {
ff11dfa1
JB
1516 CHECK_FRAME (frame, 0);
1517 f = XFRAME (frame);
dc6f92b8
JB
1518 }
1519
f769f1b2 1520 if (!FRAME_LIVE_P (f))
dc6f92b8
JB
1521 return Qnil;
1522
ff11dfa1 1523 alist = Fcopy_alist (f->param_alist);
fd0c2bd1 1524 store_in_alist (&alist, Qname, f->name);
f769f1b2
KH
1525 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
1526 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
1527 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
fd0c2bd1 1528 store_in_alist (&alist, Qminibuffer,
39acc701 1529 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
f769f1b2
KH
1530 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
1531 : FRAME_MINIBUF_WINDOW (f)));
1532 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
fd0c2bd1 1533
dbc4e1c1 1534 /* I think this should be done with a hook. */
fd0c2bd1
JB
1535#ifdef HAVE_X_WINDOWS
1536 if (FRAME_X_P (f))
ff11dfa1 1537 x_report_frame_params (f, &alist);
b6dd20ed 1538 else
fd0c2bd1 1539#endif
16a3738c
KH
1540 {
1541 /* This ought to be correct in f->param_alist for an X frame. */
1542 Lisp_Object lines;
f4e93c40 1543 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
16a3738c
KH
1544 store_in_alist (&alist, Qmenu_bar_lines, lines);
1545 }
dc6f92b8
JB
1546 return alist;
1547}
1548
ff11dfa1
JB
1549DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
1550 Smodify_frame_parameters, 2, 2, 0,
1551 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
1552ALIST is an alist of parameters to change and their new values.\n\
1553Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
1554The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
1555 (frame, alist)
1556 Lisp_Object frame, alist;
dc6f92b8 1557{
fd0c2bd1 1558 FRAME_PTR f;
dc6f92b8
JB
1559 register Lisp_Object tail, elt, prop, val;
1560
ff11dfa1
JB
1561 if (EQ (frame, Qnil))
1562 f = selected_frame;
dc6f92b8
JB
1563 else
1564 {
ff11dfa1
JB
1565 CHECK_LIVE_FRAME (frame, 0);
1566 f = XFRAME (frame);
dc6f92b8
JB
1567 }
1568
dbc4e1c1 1569 /* I think this should be done with a hook. */
fd0c2bd1
JB
1570#ifdef HAVE_X_WINDOWS
1571 if (FRAME_X_P (f))
fd0c2bd1 1572 x_set_frame_parameters (f, alist);
329ca574
RS
1573 else
1574#endif
dc6f92b8
JB
1575 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
1576 {
1577 elt = Fcar (tail);
1578 prop = Fcar (elt);
1579 val = Fcdr (elt);
ff11dfa1 1580 store_frame_param (f, prop, val);
dc6f92b8
JB
1581 }
1582
1583 return Qnil;
1584}
1585\f
a26a1f95
RS
1586DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
1587 0, 1, 0,
1588 "Height in pixels of a line in the font in frame FRAME.\n\
1589If FRAME is omitted, the selected frame is used.\n\
1590For a terminal frame, the value is always 1.")
ff11dfa1
JB
1591 (frame)
1592 Lisp_Object frame;
dc6f92b8 1593{
a26a1f95 1594 struct frame *f;
dc6f92b8 1595
a26a1f95
RS
1596 if (NILP (frame))
1597 f = selected_frame;
1598 else
1599 {
1600 CHECK_FRAME (frame, 0);
1601 f = XFRAME (frame);
1602 }
1603
1604#ifdef HAVE_X_WINDOWS
1605 if (FRAME_X_P (f))
1606 return make_number (x_char_height (f));
1607 else
dc6d9681 1608#endif
a26a1f95
RS
1609 return make_number (1);
1610}
dc6d9681 1611
dc6f92b8 1612
a26a1f95
RS
1613DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
1614 0, 1, 0,
1615 "Width in pixels of characters in the font in frame FRAME.\n\
1616If FRAME is omitted, the selected frame is used.\n\
1617The width is the same for all characters, because\n\
1618currently Emacs supports only fixed-width fonts.\n\
1619For a terminal screen, the value is always 1.")
1620 (frame)
1621 Lisp_Object frame;
dc6f92b8 1622{
a26a1f95
RS
1623 struct frame *f;
1624
1625 if (NILP (frame))
1626 f = selected_frame;
1627 else
1628 {
1629 CHECK_FRAME (frame, 0);
1630 f = XFRAME (frame);
1631 }
1632
1633#ifdef HAVE_X_WINDOWS
1634 if (FRAME_X_P (f))
1635 return make_number (x_char_width (f));
1636 else
1637#endif
1638 return make_number (1);
dc6f92b8
JB
1639}
1640
a26a1f95
RS
1641DEFUN ("frame-pixel-height", Fframe_pixel_height,
1642 Sframe_pixel_height, 0, 1, 0,
164a14ef
RS
1643 "Return a FRAME's height in pixels.\n\
1644For a terminal frame, the result really gives the height in characters.\n\
a26a1f95
RS
1645If FRAME is omitted, the selected frame is used.")
1646 (frame)
1647 Lisp_Object frame;
dc6f92b8 1648{
a26a1f95
RS
1649 struct frame *f;
1650
1651 if (NILP (frame))
1652 f = selected_frame;
1653 else
1654 {
1655 CHECK_FRAME (frame, 0);
1656 f = XFRAME (frame);
1657 }
1658
1659#ifdef HAVE_X_WINDOWS
1660 if (FRAME_X_P (f))
1661 return make_number (x_pixel_height (f));
1662 else
dc6d9681 1663#endif
a26a1f95
RS
1664 return make_number (FRAME_HEIGHT (f));
1665}
1666
1667DEFUN ("frame-pixel-width", Fframe_pixel_width,
1668 Sframe_pixel_width, 0, 1, 0,
1669 "Return FRAME's width in pixels.\n\
164a14ef 1670For a terminal frame, the result really gives the width in characters.\n\
a26a1f95
RS
1671If FRAME is omitted, the selected frame is used.")
1672 (frame)
1673 Lisp_Object frame;
1674{
1675 struct frame *f;
1676
1677 if (NILP (frame))
1678 f = selected_frame;
1679 else
1680 {
1681 CHECK_FRAME (frame, 0);
1682 f = XFRAME (frame);
1683 }
dc6f92b8 1684
a26a1f95
RS
1685#ifdef HAVE_X_WINDOWS
1686 if (FRAME_X_P (f))
1687 return make_number (x_pixel_width (f));
1688 else
1689#endif
1690 return make_number (FRAME_WIDTH (f));
1691}
1692\f
ff11dfa1
JB
1693DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1694 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1695Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1696but that the idea of the actual height of the frame should not be changed.")
1697 (frame, rows, pretend)
fd0c2bd1 1698 Lisp_Object frame, rows, pretend;
dc6f92b8 1699{
ff11dfa1 1700 register struct frame *f;
dc6f92b8
JB
1701
1702 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1703 if (NILP (frame))
1704 f = selected_frame;
dc6f92b8
JB
1705 else
1706 {
ff11dfa1
JB
1707 CHECK_LIVE_FRAME (frame, 0);
1708 f = XFRAME (frame);
dc6f92b8
JB
1709 }
1710
dbc4e1c1 1711 /* I think this should be done with a hook. */
fd0c2bd1
JB
1712#ifdef HAVE_X_WINDOWS
1713 if (FRAME_X_P (f))
dc6f92b8 1714 {
3558db6f 1715 if (XINT (rows) != f->height)
808c0f20 1716 x_set_window_size (f, 1, f->width, XINT (rows));
dc6f92b8
JB
1717 }
1718 else
fd0c2bd1
JB
1719#endif
1720 change_frame_size (f, XINT (rows), 0, !NILP (pretend), 0);
dc6f92b8
JB
1721 return Qnil;
1722}
1723
ff11dfa1
JB
1724DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1725 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1726Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1727but that the idea of the actual width of the frame should not be changed.")
1728 (frame, cols, pretend)
fd0c2bd1 1729 Lisp_Object frame, cols, pretend;
dc6f92b8 1730{
ff11dfa1 1731 register struct frame *f;
dc6f92b8 1732 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1733 if (NILP (frame))
1734 f = selected_frame;
dc6f92b8
JB
1735 else
1736 {
ff11dfa1
JB
1737 CHECK_LIVE_FRAME (frame, 0);
1738 f = XFRAME (frame);
dc6f92b8
JB
1739 }
1740
dbc4e1c1 1741 /* I think this should be done with a hook. */
fd0c2bd1
JB
1742#ifdef HAVE_X_WINDOWS
1743 if (FRAME_X_P (f))
dc6f92b8 1744 {
ff11dfa1 1745 if (XINT (cols) != f->width)
808c0f20 1746 x_set_window_size (f, 1, XINT (cols), f->height);
dc6f92b8
JB
1747 }
1748 else
fd0c2bd1
JB
1749#endif
1750 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0);
dc6f92b8
JB
1751 return Qnil;
1752}
1753
ff11dfa1
JB
1754DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1755 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1756 (frame, cols, rows)
1757 Lisp_Object frame, cols, rows;
dc6f92b8 1758{
ff11dfa1 1759 register struct frame *f;
dc6f92b8
JB
1760 int mask;
1761
ff11dfa1 1762 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1763 CHECK_NUMBER (cols, 2);
1764 CHECK_NUMBER (rows, 1);
ff11dfa1 1765 f = XFRAME (frame);
dc6f92b8 1766
dbc4e1c1 1767 /* I think this should be done with a hook. */
fd0c2bd1
JB
1768#ifdef HAVE_X_WINDOWS
1769 if (FRAME_X_P (f))
dc6f92b8 1770 {
ff11dfa1 1771 if (XINT (rows) != f->height || XINT (cols) != f->width)
808c0f20 1772 x_set_window_size (f, 1, XINT (cols), XINT (rows));
dc6f92b8
JB
1773 }
1774 else
fd0c2bd1
JB
1775#endif
1776 change_frame_size (f, XINT (rows), XINT (cols), 0, 0);
dc6f92b8
JB
1777
1778 return Qnil;
1779}
1780
ff11dfa1
JB
1781DEFUN ("set-frame-position", Fset_frame_position,
1782 Sset_frame_position, 3, 3, 0,
1783 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
60bf8ee4
RS
1784This is actually the position of the upper left corner of the frame.\n\
1785Negative values for XOFFSET or YOFFSET are interpreted relative to\n\
4524cb1c 1786the rightmost or bottommost possible position (that stays within the screen).")
ff11dfa1
JB
1787 (frame, xoffset, yoffset)
1788 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1789{
ff11dfa1 1790 register struct frame *f;
dc6f92b8
JB
1791 int mask;
1792
ff11dfa1 1793 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1794 CHECK_NUMBER (xoffset, 1);
1795 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1796 f = XFRAME (frame);
dc6f92b8 1797
dbc4e1c1 1798 /* I think this should be done with a hook. */
fd0c2bd1
JB
1799#ifdef HAVE_X_WINDOWS
1800 if (FRAME_X_P (f))
c7c70761 1801 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
fd0c2bd1 1802#endif
dc6f92b8
JB
1803
1804 return Qt;
1805}
dc6d9681 1806
dc6f92b8 1807\f
ff11dfa1 1808choose_minibuf_frame ()
dc6f92b8 1809{
ff11dfa1
JB
1810 /* For lowest-level minibuf, put it on currently selected frame
1811 if frame has a minibuffer. */
d06a8a56 1812
dc6f92b8 1813 if (minibuf_level == 0
ff11dfa1 1814 && selected_frame != 0
d06a8a56 1815 && !EQ (minibuf_window, selected_frame->minibuffer_window))
dc6f92b8 1816 {
d06a8a56
JB
1817 /* I don't think that any frames may validly have a null minibuffer
1818 window anymore. */
1819 if (NILP (selected_frame->minibuffer_window))
1820 abort ();
1821
ff11dfa1 1822 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1823 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1824 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1825 }
1826}
1827\f
ff11dfa1 1828syms_of_frame ()
dc6f92b8 1829{
fd0c2bd1 1830 /*&&& init symbols here &&&*/
ff11dfa1 1831 Qframep = intern ("framep");
ff11dfa1 1832 staticpro (&Qframep);
dbc4e1c1
JB
1833 Qframe_live_p = intern ("frame-live-p");
1834 staticpro (&Qframe_live_p);
fd0c2bd1
JB
1835 Qheight = intern ("height");
1836 staticpro (&Qheight);
1837 Qicon = intern ("icon");
1838 staticpro (&Qicon);
1839 Qminibuffer = intern ("minibuffer");
bc93c097 1840 staticpro (&Qminibuffer);
fd0c2bd1
JB
1841 Qmodeline = intern ("modeline");
1842 staticpro (&Qmodeline);
1843 Qname = intern ("name");
1844 staticpro (&Qname);
fd0c2bd1
JB
1845 Qonly = intern ("only");
1846 staticpro (&Qonly);
1847 Qunsplittable = intern ("unsplittable");
1848 staticpro (&Qunsplittable);
f7af3f7b
RS
1849 Qmenu_bar_lines = intern ("menu-bar-lines");
1850 staticpro (&Qmenu_bar_lines);
fd0c2bd1
JB
1851 Qwidth = intern ("width");
1852 staticpro (&Qwidth);
1853 Qx = intern ("x");
1854 staticpro (&Qx);
f7af3f7b
RS
1855 Qvisible = intern ("visible");
1856 staticpro (&Qvisible);
329ca574
RS
1857 Qbuffer_predicate = intern ("buffer-predicate");
1858 staticpro (&Qbuffer_predicate);
dc6f92b8 1859
ff11dfa1 1860 staticpro (&Vframe_list);
dc6f92b8 1861
ff11dfa1
JB
1862 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1863 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1864
1865 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1866 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1867 Vemacs_iconified = Qnil;
1868
ff11dfa1
JB
1869 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1870 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1871\n\
ff11dfa1 1872Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1873appropriate surrogate.\n\
1874\n\
1875Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1876frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1877minibuffer, no matter what this variable is set to. This means that\n\
1878this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1879current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1880displayed.");
ff11dfa1 1881 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1882
ff11dfa1
JB
1883 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1884 "Alist of default values for frame creation.\n\
5bce042c 1885These may be set in your init file, like this:\n\
1855c8dd
RS
1886 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1))\n\
1887These override values given in window system configuration data,\n\
1888 including X Windows' defaults database.\n\
ff11dfa1
JB
1889For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1890For values specific to the separate minibuffer frame, see\n\
1855c8dd
RS
1891 `minibuffer-frame-alist'.\n\
1892The `menu-bar-lines' element of the list controls whether new frames\n\
169e69a3 1893 have menu bars; `menu-bar-mode' works by altering this element.");
ff11dfa1
JB
1894 Vdefault_frame_alist = Qnil;
1895
5add3885 1896 defsubr (&Sactive_minibuffer_window);
ff11dfa1 1897 defsubr (&Sframep);
dbc4e1c1 1898 defsubr (&Sframe_live_p);
bb1513c9 1899 defsubr (&Smake_terminal_frame);
0f85737c 1900 defsubr (&Shandle_switch_frame);
ff11dfa1
JB
1901 defsubr (&Sselect_frame);
1902 defsubr (&Sselected_frame);
1903 defsubr (&Swindow_frame);
1904 defsubr (&Sframe_root_window);
d446a856 1905 defsubr (&Sframe_first_window);
ff11dfa1 1906 defsubr (&Sframe_selected_window);
4a7cfafc 1907 defsubr (&Sset_frame_selected_window);
ff11dfa1
JB
1908 defsubr (&Sframe_list);
1909 defsubr (&Snext_frame);
ef2c57ac 1910 defsubr (&Sprevious_frame);
ff11dfa1 1911 defsubr (&Sdelete_frame);
f9898cc6 1912 defsubr (&Smouse_position);
152e6c70 1913 defsubr (&Smouse_pixel_position);
dc6f92b8 1914 defsubr (&Sset_mouse_position);
152e6c70 1915 defsubr (&Sset_mouse_pixel_position);
dc6f92b8 1916#if 0
ff11dfa1
JB
1917 defsubr (&Sframe_configuration);
1918 defsubr (&Srestore_frame_configuration);
dc6f92b8 1919#endif
ff11dfa1
JB
1920 defsubr (&Smake_frame_visible);
1921 defsubr (&Smake_frame_invisible);
1922 defsubr (&Siconify_frame);
1923 defsubr (&Sframe_visible_p);
1924 defsubr (&Svisible_frame_list);
b49f5578
JB
1925 defsubr (&Sraise_frame);
1926 defsubr (&Slower_frame);
ff11dfa1
JB
1927 defsubr (&Sredirect_frame_focus);
1928 defsubr (&Sframe_focus);
1929 defsubr (&Sframe_parameters);
1930 defsubr (&Smodify_frame_parameters);
a26a1f95
RS
1931 defsubr (&Sframe_char_height);
1932 defsubr (&Sframe_char_width);
1933 defsubr (&Sframe_pixel_height);
1934 defsubr (&Sframe_pixel_width);
ff11dfa1
JB
1935 defsubr (&Sset_frame_height);
1936 defsubr (&Sset_frame_width);
1937 defsubr (&Sset_frame_size);
1938 defsubr (&Sset_frame_position);
dc6f92b8 1939}
e5d77022 1940
2f0b07e0
JB
1941keys_of_frame ()
1942{
0f85737c 1943 initial_define_lispy_key (global_map, "switch-frame", "handle-switch-frame");
d134b17b 1944 initial_define_lispy_key (global_map, "delete-frame", "handle-delete-frame");
8af6db06
KH
1945 initial_define_lispy_key (global_map, "iconify-frame", "ignore");
1946 initial_define_lispy_key (global_map, "make-frame-visible", "ignore");
2f0b07e0 1947}
a26a1f95 1948\f
d06a8a56 1949#else /* not MULTI_FRAME */
fd0c2bd1 1950
cc38027b
JB
1951/* If we're not using multi-frame stuff, we still need to provide some
1952 support functions. */
1953
f769f1b2
KH
1954Lisp_Object Qheight;
1955Lisp_Object Qminibuffer;
1956Lisp_Object Qmodeline;
1957Lisp_Object Qname;
1958Lisp_Object Qunsplittable;
1959Lisp_Object Qmenu_bar_lines;
1960Lisp_Object Qwidth;
1961
91f5a8d7
KH
1962Lisp_Object Vterminal_frame;
1963
cc38027b
JB
1964/* Unless this function is defined, providing set-frame-height and
1965 set-frame-width doesn't help compatibility any, since they both
1966 want this as their first argument. */
1967DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
9597f4b8
KH
1968 /* Don't confuse make-docfile by having two doc strings for this function.
1969 make-docfile does not pay attention to #if, for good reason! */
1970 0)
cc38027b
JB
1971 ()
1972{
87485d6f
MW
1973 /* For your possible information, this code is unfolded into the
1974 second WINDOW_FRAME in frame.h. */
cc38027b 1975 Lisp_Object tem;
f4e93c40 1976 XSETFASTINT (tem, 0);
cc38027b
JB
1977 return tem;
1978}
888f3d05 1979
6e18b6c2
RS
1980DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
1981 /* Don't confuse make-docfile by having two doc strings for this function.
1982 make-docfile does not pay attention to #if, for good reason! */
1983 0)
1984 (window)
1985 Lisp_Object window;
1986{
1987 /* For your possible information, this code is unfolded into the
1988 second WINDOW_FRAME in frame.h. */
1989 Lisp_Object tem;
1990 XSETFASTINT (tem, 0);
1991 return tem;
1992}
1993
888f3d05
RS
1994DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
1995 0)
1996 (frame)
1997 Lisp_Object frame;
1998{
1999 Lisp_Object w;
2000
2001 w = FRAME_ROOT_WINDOW (selected_frame);
2002
2003 while (NILP (XWINDOW (w)->buffer))
2004 {
2005 if (! NILP (XWINDOW (w)->hchild))
2006 w = XWINDOW (w)->hchild;
2007 else if (! NILP (XWINDOW (w)->vchild))
2008 w = XWINDOW (w)->vchild;
2009 else
2010 abort ();
2011 }
2012 return w;
2013}
2014
704a9b45 2015DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
9597f4b8
KH
2016 /* Don't confuse make-docfile by having two doc strings for this function.
2017 make-docfile does not pay attention to #if, for good reason! */
2018 0)
704a9b45
RS
2019 (object)
2020 Lisp_Object object;
2021{
87485d6f
MW
2022#ifdef MSDOS
2023 if (FRAME_X_P (object))
2024 return intern ("pc");
2025#endif
704a9b45
RS
2026 return Qnil;
2027}
fd0c2bd1
JB
2028
2029DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
9597f4b8
KH
2030 /* Don't confuse make-docfile by having two doc strings for this function.
2031 make-docfile does not pay attention to #if, for good reason! */
2032 0)
fd0c2bd1
JB
2033 (frame, rows, pretend)
2034 Lisp_Object frame, rows, pretend;
2035{
2036 CHECK_NUMBER (rows, 0);
2037
2038 change_frame_size (0, XINT (rows), 0, !NILP (pretend), 0);
2039 return Qnil;
2040}
2041
2042DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
9597f4b8
KH
2043 /* Don't confuse make-docfile by having two doc strings for this function.
2044 make-docfile does not pay attention to #if, for good reason! */
2045 0)
fd0c2bd1
JB
2046 (frame, cols, pretend)
2047 Lisp_Object frame, cols, pretend;
2048{
2049 CHECK_NUMBER (cols, 0);
2050
2051 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2052 return Qnil;
2053}
2054
2055DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
9597f4b8
KH
2056 /* Don't confuse make-docfile by having two doc strings for this function.
2057 make-docfile does not pay attention to #if, for good reason! */
2058 0)
fd0c2bd1
JB
2059 (frame, cols, rows)
2060 Lisp_Object frame, cols, rows;
2061{
2062 CHECK_NUMBER (cols, 2);
2063 CHECK_NUMBER (rows, 1);
2064
2065 change_frame_size (0, XINT (rows), XINT (cols), 0, 0);
2066
2067 return Qnil;
2068}
b6d8a44f 2069\f
48c9d487
JB
2070DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 1, 0,
2071 "Return number of lines available for display on FRAME.\n\
2072If FRAME is omitted, describe the currently selected frame.")
2073 (frame)
2074 Lisp_Object frame;
cc38027b
JB
2075{
2076 return make_number (FRAME_HEIGHT (selected_frame));
2077}
2078
48c9d487
JB
2079DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 1, 0,
2080 "Return number of columns available for display on FRAME.\n\
2081If FRAME is omitted, describe the currently selected frame.")
2082 (frame)
2083 Lisp_Object frame;
cc38027b
JB
2084{
2085 return make_number (FRAME_WIDTH (selected_frame));
2086}
2087
a26a1f95
RS
2088DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2089 0, 1, 0,
9597f4b8
KH
2090 /* Don't confuse make-docfile by having two doc strings for this function.
2091 make-docfile does not pay attention to #if, for good reason! */
2092 0)
a26a1f95
RS
2093 (frame)
2094 Lisp_Object frame;
2095{
2096 return make_number (1);
2097}
2098
2099
2100DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2101 0, 1, 0,
9597f4b8
KH
2102 /* Don't confuse make-docfile by having two doc strings for this function.
2103 make-docfile does not pay attention to #if, for good reason! */
2104 0)
a26a1f95
RS
2105 (frame)
2106 Lisp_Object frame;
2107{
2108 return make_number (1);
2109}
2110
2111DEFUN ("frame-pixel-height", Fframe_pixel_height,
2112 Sframe_pixel_height, 0, 1, 0,
9597f4b8
KH
2113 /* Don't confuse make-docfile by having two doc strings for this function.
2114 make-docfile does not pay attention to #if, for good reason! */
2115 0)
a26a1f95
RS
2116 (frame)
2117 Lisp_Object frame;
2118{
2119 return make_number (FRAME_HEIGHT (f));
2120}
2121
2122DEFUN ("frame-pixel-width", Fframe_pixel_width,
2123 Sframe_pixel_width, 0, 1, 0,
9597f4b8
KH
2124 /* Don't confuse make-docfile by having two doc strings for this function.
2125 make-docfile does not pay attention to #if, for good reason! */
2126 0)
a26a1f95
RS
2127 (frame)
2128 Lisp_Object frame;
2129{
2130 return make_number (FRAME_WIDTH (f));
2131}
2132
cc38027b
JB
2133/* These are for backward compatibility with Emacs 18. */
2134
fd0c2bd1
JB
2135DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 1, 2, 0,
2136 "Tell redisplay that the screen has LINES lines.\n\
2137Optional second arg non-nil means that redisplay should use LINES lines\n\
2138but that the idea of the actual height of the screen should not be changed.")
2139 (lines, pretend)
2140 Lisp_Object lines, pretend;
2141{
2142 CHECK_NUMBER (lines, 0);
2143
2144 change_frame_size (0, XINT (lines), 0, !NILP (pretend), 0);
2145 return Qnil;
2146}
2147
2148DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 1, 2, 0,
2149 "Tell redisplay that the screen has COLS columns.\n\
2150Optional second arg non-nil means that redisplay should use COLS columns\n\
2151but that the idea of the actual width of the screen should not be changed.")
2152 (cols, pretend)
2153 Lisp_Object cols, pretend;
2154{
2155 CHECK_NUMBER (cols, 0);
2156
2157 change_frame_size (0, 0, XINT (cols), !NILP (pretend), 0);
2158 return Qnil;
2159}
2160
bc1ed486 2161DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
76db7eb4
KH
2162 /* Don't confuse make-docfile by having two doc strings for this function.
2163 make-docfile does not pay attention to #if, for good reason! */
2164 0)
bc1ed486
RS
2165 ()
2166{
87485d6f
MW
2167#ifdef HAVE_MOUSE
2168 if (mouse_position_hook)
2169 {
2170 FRAME_PTR f;
2171 Lisp_Object lispy_dummy;
2172 enum scroll_bar_part party_dummy;
2173 Lisp_Object x, y;
2174 unsigned long long_dummy;
2175
0c5c1cf7 2176 (*mouse_position_hook) (&f, 0,
87485d6f
MW
2177 &lispy_dummy, &party_dummy,
2178 &x, &y,
2179 &long_dummy);
2180 return Fcons (Fselected_frame (), Fcons (x, y));
2181 }
2182#endif
76db7eb4 2183 return Fcons (Qnil, Fcons (Qnil, Qnil));
bc1ed486 2184}
b6d8a44f 2185\f
f769f1b2
KH
2186void
2187store_in_alist (alistptr, prop, val)
2188 Lisp_Object *alistptr, val;
2189 Lisp_Object prop;
2190{
2191 register Lisp_Object tem;
2192
2193 tem = Fassq (prop, *alistptr);
2194 if (EQ (tem, Qnil))
2195 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2196 else
2197 Fsetcdr (tem, val);
2198}
2199
b6d8a44f 2200DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
42652599
KH
2201 /* Don't confuse make-docfile by having two doc strings for this function.
2202 make-docfile does not pay attention to #if, for good reason! */
2203 0)
b6d8a44f
RS
2204 (frame)
2205 Lisp_Object frame;
2206{
f769f1b2
KH
2207 Lisp_Object alist;
2208 FRAME_PTR f;
2209
2210 if (EQ (frame, Qnil))
2211 f = selected_frame;
2212 else
2213 {
2214 CHECK_FRAME (frame, 0);
2215 f = XFRAME (frame);
2216 }
2217
2218 if (!FRAME_LIVE_P (f))
2219 return Qnil;
2220
2221 alist = Qnil;
87485d6f
MW
2222#ifdef MSDOS
2223 if (FRAME_X_P (f))
2224 {
2225 static char *colornames[16] =
2226 {
2227 "black", "blue", "green", "cyan", "red", "magenta", "brown",
2228 "lightgray", "darkgray", "lightblue", "lightgreen", "lightcyan",
2229 "lightred", "lightmagenta", "yellow", "white"
2230 };
2231 store_in_alist (&alist, intern ("foreground-color"),
2232 build_string (colornames[FRAME_FOREGROUND_PIXEL (f)]));
2233 store_in_alist (&alist, intern ("background-color"),
2234 build_string (colornames[FRAME_BACKGROUND_PIXEL (f)]));
2235 }
2236#endif
2237 store_in_alist (&alist, intern ("font"), build_string ("default"));
f769f1b2
KH
2238 store_in_alist (&alist, Qname, build_string ("emacs"));
2239 store_in_alist (&alist, Qheight, make_number (FRAME_HEIGHT (f)));
2240 store_in_alist (&alist, Qwidth, make_number (FRAME_WIDTH (f)));
2241 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2242 store_in_alist (&alist, Qminibuffer, FRAME_MINIBUF_WINDOW (f));
2243 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2244 store_in_alist (&alist, Qmenu_bar_lines, (FRAME_MENU_BAR_LINES (f)));
2245
2246 return alist;
b6d8a44f
RS
2247}
2248
2249DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2250 Smodify_frame_parameters, 2, 2, 0,
42652599
KH
2251 /* Don't confuse make-docfile by having two doc strings for this function.
2252 make-docfile does not pay attention to #if, for good reason! */
2253 0)
b6d8a44f
RS
2254 (frame, alist)
2255 Lisp_Object frame, alist;
2256{
87485d6f
MW
2257#ifdef MSDOS
2258 if (FRAME_X_P (frame))
2259 IT_set_frame_parameters (XFRAME (frame), alist);
2260#endif
b6d8a44f
RS
2261 return Qnil;
2262}
bc1ed486 2263
52ed2dad
RS
2264DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
2265 /* Don't confuse make-docfile by having two doc strings for this function.
2266 make-docfile does not pay attention to #if, for good reason! */
2267 0)
2268 (frame)
2269 Lisp_Object frame;
2270{
2271 return Qt;
2272}
2273
87485d6f
MW
2274DEFUN ("frame-list", Fframe_list, Sframe_list, 0, 0, 0,
2275 /* Don't confuse make-docfile by having two doc strings for this function.
2276 make-docfile does not pay attention to #if, for good reason! */
2277 0)
2278 ()
2279{
2280 return Fcons (Fselected_frame (), Qnil);
2281}
2282
fd0c2bd1
JB
2283syms_of_frame ()
2284{
f769f1b2
KH
2285 Qheight = intern ("height");
2286 staticpro (&Qheight);
2287 Qminibuffer = intern ("minibuffer");
2288 staticpro (&Qminibuffer);
2289 Qmodeline = intern ("modeline");
2290 staticpro (&Qmodeline);
2291 Qname = intern ("name");
2292 staticpro (&Qname);
2293 Qunsplittable = intern ("unsplittable");
2294 staticpro (&Qunsplittable);
2295 Qmenu_bar_lines = intern ("menu-bar-lines");
2296 staticpro (&Qmenu_bar_lines);
2297 Qwidth = intern ("width");
2298 staticpro (&Qwidth);
2299
91f5a8d7
KH
2300 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
2301 "The initial frame-object, which represents Emacs's stdout.");
f4e93c40 2302 XSETFASTINT (Vterminal_frame, 0);
91f5a8d7 2303
a26a1f95 2304 defsubr (&Sselected_frame);
6e18b6c2 2305 defsubr (&Swindow_frame);
888f3d05 2306 defsubr (&Sframe_first_window);
704a9b45 2307 defsubr (&Sframep);
a26a1f95
RS
2308 defsubr (&Sframe_char_height);
2309 defsubr (&Sframe_char_width);
2310 defsubr (&Sframe_pixel_height);
2311 defsubr (&Sframe_pixel_width);
fd0c2bd1
JB
2312 defsubr (&Sset_frame_height);
2313 defsubr (&Sset_frame_width);
2314 defsubr (&Sset_frame_size);
2315 defsubr (&Sset_screen_height);
2316 defsubr (&Sset_screen_width);
2317 defsubr (&Sframe_height);
2318 Ffset (intern ("screen-height"), intern ("frame-height"));
2319 defsubr (&Sframe_width);
2320 Ffset (intern ("screen-width"), intern ("frame-width"));
bc1ed486 2321 defsubr (&Smouse_position);
b6d8a44f
RS
2322 defsubr (&Sframe_parameters);
2323 defsubr (&Smodify_frame_parameters);
52ed2dad 2324 defsubr (&Sframe_live_p);
87485d6f
MW
2325 defsubr (&Sframe_list);
2326
2327#ifdef MSDOS
2328 /* A comment in dispnew.c says the_only_frame is not protected. */
2329 the_only_frame.face_alist = Qnil;
2330 staticpro (&the_only_frame.face_alist);
2331 the_only_frame.menu_bar_items = Qnil;
2332 staticpro (&the_only_frame.menu_bar_items);
2333 the_only_frame.menu_bar_vector = Qnil;
2334 staticpro (&the_only_frame.menu_bar_vector);
2335 the_only_frame.menu_bar_items = menu_bar_items (Qnil);
2336#endif
fd0c2bd1
JB
2337}
2338
2f0b07e0
JB
2339keys_of_frame ()
2340{
2341}
2342
fd0c2bd1 2343#endif /* not MULTI_FRAME */