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