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