*** empty log message ***
[bpt/emacs.git] / src / frame.c
CommitLineData
dc6d9681 1
ff11dfa1 2/* Generic frame functions.
1113d9db 3 Copyright (C) 1989, 1992 Free Software Foundation.
dc6f92b8
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
1113d9db 9the Free Software Foundation; either version 2, or (at your option)
dc6f92b8
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
d5e7c279
JB
21#include <stdio.h>
22
dc6f92b8 23#include "config.h"
e5d77022 24
ff11dfa1 25#ifdef MULTI_FRAME
e5d77022 26
dc6f92b8 27#include "lisp.h"
ff11dfa1 28#include "frame.h"
dc6f92b8 29#include "window.h"
d5e7c279 30#include "termhooks.h"
dc6f92b8
JB
31
32Lisp_Object Vemacs_iconified;
ff11dfa1
JB
33Lisp_Object Qframep;
34Lisp_Object Qlive_frame_p;
35Lisp_Object Vframe_list;
36Lisp_Object Vterminal_frame;
37Lisp_Object Vdefault_minibuffer_frame;
38Lisp_Object Vdefault_frame_alist;
bc93c097 39Lisp_Object Qminibuffer;
dc6f92b8
JB
40
41extern Lisp_Object Vminibuffer_list;
42extern Lisp_Object get_minibuffer ();
43\f
ff11dfa1
JB
44DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
45 "Return non-nil if OBJECT is a frame.\n\
46Value is t for a termcap frame (a character-only terminal),\n\
47`x' for an Emacs frame that is really an X window.\n\
48Also see `live-frame-p'.")
f9898cc6
JB
49 (object)
50 Lisp_Object object;
dc6f92b8 51{
ff11dfa1 52 if (XTYPE (object) != Lisp_Frame)
dc6f92b8 53 return Qnil;
ff11dfa1 54 switch (XFRAME (object)->output_method)
dc6f92b8
JB
55 {
56 case output_termcap:
57 return Qt;
58 case output_x_window:
59 return intern ("x");
60 default:
61 abort ();
62 }
63}
64
ff11dfa1
JB
65DEFUN ("live-frame-p", Flive_frame_p, Slive_frame_p, 1, 1, 0,
66 "Return non-nil if OBJECT is a frame which has not been deleted.\n\
67Value is nil if OBJECT is not a live frame. If object is a live\n\
68frame, the return value indicates what sort of output device it is\n\
69displayed on. Value is t for a termcap frame (a character-only\n\
70terminal), `x' for an Emacs frame being displayed in an X window.")
f9898cc6
JB
71 (object)
72 Lisp_Object object;
73{
ff11dfa1
JB
74 return ((FRAMEP (object)
75 && FRAME_LIVE_P (XFRAME (object)))
76 ? Fframep (object)
f9898cc6
JB
77 : Qnil);
78}
79
ff11dfa1
JB
80struct frame *
81make_frame (mini_p)
dc6f92b8
JB
82 int mini_p;
83{
ff11dfa1
JB
84 Lisp_Object frame;
85 register struct frame *f;
dc6f92b8
JB
86 register Lisp_Object root_window;
87 register Lisp_Object mini_window;
88
ff11dfa1 89 frame = Fmake_vector (((sizeof (struct frame) - (sizeof (Lisp_Vector)
d5e7c279
JB
90 - sizeof (Lisp_Object)))
91 / sizeof (Lisp_Object)),
dc6f92b8 92 make_number (0));
ff11dfa1
JB
93 XSETTYPE (frame, Lisp_Frame);
94 f = XFRAME (frame);
95
96 f->cursor_x = 0;
97 f->cursor_y = 0;
98 f->current_glyphs = 0;
99 f->desired_glyphs = 0;
100 f->visible = 0;
101 f->display.nothing = 0;
102 f->iconified = 0;
103 f->wants_modeline = 1;
104 f->auto_raise = 0;
105 f->auto_lower = 0;
106 f->no_split = 0;
107 f->garbaged = 0;
108 f->has_minibuffer = mini_p;
109 f->focus_frame = frame;
110
111 f->param_alist = Qnil;
dc6f92b8
JB
112
113 root_window = make_window (0);
114 if (mini_p)
115 {
116 mini_window = make_window (0);
117 XWINDOW (root_window)->next = mini_window;
118 XWINDOW (mini_window)->prev = root_window;
119 XWINDOW (mini_window)->mini_p = Qt;
ff11dfa1
JB
120 XWINDOW (mini_window)->frame = frame;
121 f->minibuffer_window = mini_window;
dc6f92b8
JB
122 }
123 else
124 {
125 mini_window = Qnil;
126 XWINDOW (root_window)->next = Qnil;
ff11dfa1 127 f->minibuffer_window = Qnil;
dc6f92b8
JB
128 }
129
ff11dfa1 130 XWINDOW (root_window)->frame = frame;
dc6f92b8
JB
131
132 /* 10 is arbitrary,
133 just so that there is "something there."
ff11dfa1 134 Correct size will be set up later with change_frame_size. */
dc6f92b8 135
ff11dfa1
JB
136 f->width = 10;
137 f->height = 10;
dc6f92b8
JB
138
139 XFASTINT (XWINDOW (root_window)->width) = 10;
140 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
141
142 if (mini_p)
143 {
144 XFASTINT (XWINDOW (mini_window)->width) = 10;
145 XFASTINT (XWINDOW (mini_window)->top) = 9;
146 XFASTINT (XWINDOW (mini_window)->height) = 1;
147 }
148
ff11dfa1 149 /* Choose a buffer for the frame's root window. */
5bce042c
JB
150 {
151 Lisp_Object buf;
152
153 XWINDOW (root_window)->buffer = Qt;
154 buf = Fcurrent_buffer ();
155 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
156 a space), try to find another one. */
157 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
158 buf = Fother_buffer (buf);
159 Fset_window_buffer (root_window, buf);
160 }
161
dc6f92b8
JB
162 if (mini_p)
163 {
164 XWINDOW (mini_window)->buffer = Qt;
165 Fset_window_buffer (mini_window,
265a9e55 166 (NILP (Vminibuffer_list)
dc6f92b8
JB
167 ? get_minibuffer (0)
168 : Fcar (Vminibuffer_list)));
169 }
170
ff11dfa1
JB
171 f->root_window = root_window;
172 f->selected_window = root_window;
d5e7c279
JB
173 /* Make sure this window seems more recently used than
174 a newly-created, never-selected window. */
ff11dfa1 175 XFASTINT (XWINDOW (f->selected_window)->use_time) = ++window_select_count;
dc6f92b8 176
ff11dfa1 177 Vframe_list = Fcons (frame, Vframe_list);
dc6f92b8 178
ff11dfa1 179 return f;
dc6f92b8
JB
180}
181\f
ff11dfa1 182/* Make a frame using a separate minibuffer window on another frame.
dc6f92b8
JB
183 MINI_WINDOW is the minibuffer window to use. nil means use the
184 default (the global minibuffer). */
185
ff11dfa1
JB
186struct frame *
187make_frame_without_minibuffer (mini_window)
dc6f92b8
JB
188 register Lisp_Object mini_window;
189{
ff11dfa1 190 register struct frame *f;
dc6f92b8
JB
191
192 /* Choose the minibuffer window to use. */
265a9e55 193 if (NILP (mini_window))
dc6f92b8 194 {
ff11dfa1
JB
195 if (XTYPE (Vdefault_minibuffer_frame) != Lisp_Frame)
196 error ("default-minibuffer-frame must be set when creating minibufferless frames");
197 if (! FRAME_LIVE_P (XFRAME (Vdefault_minibuffer_frame)))
198 error ("default-minibuffer-frame must be a live frame");
199 mini_window = XFRAME (Vdefault_minibuffer_frame)->minibuffer_window;
dc6f92b8
JB
200 }
201 else
202 {
203 CHECK_WINDOW (mini_window, 0);
204 }
205
ff11dfa1
JB
206 /* Make a frame containing just a root window. */
207 f = make_frame (0);
dc6f92b8
JB
208
209 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 210 f->minibuffer_window = mini_window;
dc6f92b8 211 Fset_window_buffer (mini_window,
265a9e55 212 (NILP (Vminibuffer_list)
dc6f92b8
JB
213 ? get_minibuffer (0)
214 : Fcar (Vminibuffer_list)));
ff11dfa1 215 return f;
dc6f92b8
JB
216}
217
ff11dfa1 218/* Make a frame containing only a minibuffer window. */
dc6f92b8 219
ff11dfa1
JB
220struct frame *
221make_minibuffer_frame ()
dc6f92b8 222{
ff11dfa1 223 /* First make a frame containing just a root window, no minibuffer. */
dc6f92b8 224
ff11dfa1 225 register struct frame *f = make_frame (0);
dc6f92b8 226 register Lisp_Object mini_window;
ff11dfa1 227 register Lisp_Object frame;
dc6f92b8 228
ff11dfa1 229 XSET (frame, Lisp_Frame, f);
dc6f92b8
JB
230
231 /* ??? Perhaps leave it to the user program to set auto_raise. */
ff11dfa1
JB
232 f->auto_raise = 1;
233 f->auto_lower = 0;
234 f->no_split = 1;
235 f->wants_modeline = 0;
236 f->has_minibuffer = 1;
dc6f92b8
JB
237
238 /* Now label the root window as also being the minibuffer.
239 Avoid infinite looping on the window chain by marking next pointer
240 as nil. */
241
ff11dfa1 242 mini_window = f->minibuffer_window = f->root_window;
dc6f92b8
JB
243 XWINDOW (mini_window)->mini_p = Qt;
244 XWINDOW (mini_window)->next = Qnil;
245 XWINDOW (mini_window)->prev = mini_window;
ff11dfa1 246 XWINDOW (mini_window)->frame = frame;
dc6f92b8
JB
247
248 /* Put the proper buffer in that window. */
249
250 Fset_window_buffer (mini_window,
265a9e55 251 (NILP (Vminibuffer_list)
dc6f92b8
JB
252 ? get_minibuffer (0)
253 : Fcar (Vminibuffer_list)));
ff11dfa1 254 return f;
dc6f92b8
JB
255}
256\f
ff11dfa1 257/* Construct a frame that refers to the terminal (stdin and stdout). */
dc6f92b8 258
ff11dfa1
JB
259struct frame *
260make_terminal_frame ()
dc6f92b8 261{
ff11dfa1
JB
262 register struct frame *f;
263
264 Vframe_list = Qnil;
265 f = make_frame (1);
266 f->name = build_string ("terminal");
267 f->visible = 1;
268 f->display.nothing = 1; /* Nonzero means frame isn't deleted. */
269 XSET (Vterminal_frame, Lisp_Frame, f);
270 return f;
dc6f92b8
JB
271}
272\f
ff11dfa1
JB
273DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, 0,
274 "Select the frame FRAME. FRAMES's selected window becomes \"the\"\n\
d5e7c279 275selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
ff11dfa1
JB
276focus on that frame.")
277 (frame, no_enter)
278 Lisp_Object frame, no_enter;
dc6f92b8 279{
ff11dfa1 280 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 281
ff11dfa1
JB
282 if (selected_frame == XFRAME (frame))
283 return frame;
dc6f92b8 284
ff11dfa1
JB
285 selected_frame = XFRAME (frame);
286 if (! FRAME_MINIBUF_ONLY_P (selected_frame))
287 last_nonminibuf_frame = selected_frame;
d5e7c279 288
ff11dfa1 289 Fselect_window (XFRAME (frame)->selected_window);
dc6f92b8
JB
290
291#ifdef HAVE_X_WINDOWS
ff11dfa1
JB
292#ifdef MULTI_FRAME
293 if (FRAME_IS_X (XFRAME (frame))
265a9e55 294 && NILP (no_enter))
dc6f92b8 295 {
ff11dfa1 296 Ffocus_frame (frame);
dc6f92b8
JB
297 }
298#endif
299#endif
ff11dfa1 300 choose_minibuf_frame ();
dc6f92b8 301
ff11dfa1 302 return frame;
dc6f92b8
JB
303}
304
ff11dfa1
JB
305DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
306 "Return the frame that is now selected.")
dc6f92b8
JB
307 ()
308{
309 Lisp_Object tem;
ff11dfa1 310 XSET (tem, Lisp_Frame, selected_frame);
dc6f92b8
JB
311 return tem;
312}
313
ff11dfa1
JB
314DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
315 "Return the frame object that window WINDOW is on.")
dc6f92b8
JB
316 (window)
317 Lisp_Object window;
318{
319 CHECK_WINDOW (window, 0);
ff11dfa1 320 return XWINDOW (window)->frame;
dc6f92b8
JB
321}
322
ff11dfa1
JB
323DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
324 "Returns the root-window of FRAME.")
325 (frame)
326 Lisp_Object frame;
dc6f92b8 327{
ff11dfa1
JB
328 if (NILP (frame))
329 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 330 else
ff11dfa1 331 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 332
ff11dfa1 333 return XFRAME (frame)->root_window;
dc6f92b8
JB
334}
335
ff11dfa1
JB
336DEFUN ("frame-selected-window", Fframe_selected_window,
337 Sframe_selected_window, 0, 1, 0,
338 "Return the selected window of frame object FRAME.")
339 (frame)
340 Lisp_Object frame;
dc6f92b8 341{
ff11dfa1
JB
342 if (NILP (frame))
343 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 344 else
ff11dfa1 345 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 346
ff11dfa1 347 return XFRAME (frame)->selected_window;
dc6f92b8
JB
348}
349
ff11dfa1 350DEFUN ("frame-list", Fframe_list, Sframe_list,
dc6f92b8 351 0, 0, 0,
ff11dfa1 352 "Return a list of all frames.")
dc6f92b8
JB
353 ()
354{
ff11dfa1 355 return Fcopy_sequence (Vframe_list);
dc6f92b8
JB
356}
357
ff11dfa1 358#ifdef MULTI_FRAME
f9898cc6 359
ff11dfa1
JB
360/* Return the next frame in the frame list after FRAME.
361 If MINIBUF is non-nil, include all frames.
362 If MINIBUF is nil, exclude minibuffer-only frames.
363 If MINIBUF is a window, include only frames using that window for
f9898cc6 364 their minibuffer. */
dc6f92b8 365Lisp_Object
ff11dfa1
JB
366next_frame (frame, minibuf)
367 Lisp_Object frame;
f9898cc6 368 Lisp_Object minibuf;
dc6f92b8
JB
369{
370 Lisp_Object tail;
371 int passed = 0;
372
ff11dfa1
JB
373 /* There must always be at least one frame in Vframe_list. */
374 if (! CONSP (Vframe_list))
f9898cc6
JB
375 abort ();
376
dc6f92b8 377 while (1)
ff11dfa1 378 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8
JB
379 {
380 if (passed)
d5e7c279 381 {
ff11dfa1 382 Lisp_Object f = XCONS (tail)->car;
f9898cc6 383
ff11dfa1 384 /* Decide whether this frame is eligible to be returned,
f9898cc6 385 according to minibuf. */
ff11dfa1 386 if ((NILP (minibuf) && ! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
f9898cc6 387 || XTYPE (minibuf) != Lisp_Window
ff11dfa1
JB
388 || EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
389 || EQ (f, frame))
390 return f;
d5e7c279 391 }
dc6f92b8 392
ff11dfa1 393 if (EQ (frame, XCONS (tail)->car))
dc6f92b8
JB
394 passed++;
395 }
396}
397
ff11dfa1
JB
398/* Return the previous frame in the frame list before FRAME.
399 If MINIBUF is non-nil, include all frames.
400 If MINIBUF is nil, exclude minibuffer-only frames.
401 If MINIBUF is a window, include only frames using that window for
f9898cc6 402 their minibuffer. */
dc6f92b8 403Lisp_Object
ff11dfa1
JB
404prev_frame (frame, minibuf)
405 Lisp_Object frame;
f9898cc6 406 Lisp_Object minibuf;
dc6f92b8
JB
407{
408 Lisp_Object tail;
409 Lisp_Object prev;
410
ff11dfa1
JB
411 /* There must always be at least one frame in Vframe_list. */
412 if (! CONSP (Vframe_list))
f9898cc6
JB
413 abort ();
414
dc6f92b8
JB
415 prev = Qnil;
416 while (1)
f9898cc6 417 {
ff11dfa1 418 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
f9898cc6
JB
419 {
420 Lisp_Object scr = XCONS (tail)->car;
421
ff11dfa1 422 if (XTYPE (scr) != Lisp_Frame)
f9898cc6
JB
423 abort ();
424
ff11dfa1 425 if (EQ (frame, scr) && !NILP (prev))
f9898cc6
JB
426 return prev;
427
ff11dfa1 428 /* Decide whether this frame is eligible to be returned,
f9898cc6 429 according to minibuf. */
ff11dfa1 430 if ((NILP (minibuf) && ! FRAME_MINIBUF_ONLY_P (XFRAME (scr)))
f9898cc6 431 || XTYPE (minibuf) != Lisp_Window
ff11dfa1 432 || EQ (FRAME_MINIBUF_WINDOW (XFRAME (scr)), minibuf))
f9898cc6
JB
433 prev = scr;
434 }
435
265a9e55 436 if (NILP (prev))
ff11dfa1
JB
437 /* We went through the whole frame list without finding a single
438 acceptable frame. Return the original frame. */
439 prev = frame;
f9898cc6
JB
440 }
441
dc6f92b8
JB
442}
443
ff11dfa1
JB
444DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
445 "Return the next frame in the frame list after FRAME.\n\
446If optional argument MINIBUF is non-nil, include all frames. If\n\
447MINIBUF is nil or omitted, exclude minibuffer-only frames. If\n\
448MINIBUF is a window, include only frames using that window for their\n\
f9898cc6 449minibuffer.")
ff11dfa1
JB
450 (frame, miniframe)
451Lisp_Object frame, miniframe;
dc6f92b8
JB
452{
453 Lisp_Object tail;
454
ff11dfa1
JB
455 if (NILP (frame))
456 XSET (frame, Lisp_Frame, selected_frame);
f9898cc6 457 else
ff11dfa1 458 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 459
ff11dfa1 460 return next_frame (frame, miniframe);
dc6f92b8 461}
ff11dfa1 462#endif /* MULTI_FRAME */
dc6f92b8 463\f
ff11dfa1
JB
464DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 1, "",
465 "Delete FRAME, permanently eliminating it from use.\n\
466If omitted, FRAME defaults to the selected frame.\n\
467A frame may not be deleted if its minibuffer is used by other frames.")
468 (frame)
469 Lisp_Object frame;
dc6f92b8 470{
ff11dfa1 471 struct frame *f;
dc6f92b8
JB
472 union display displ;
473
ff11dfa1 474 if (EQ (frame, Qnil))
dc6f92b8 475 {
ff11dfa1
JB
476 f = selected_frame;
477 XSET (frame, Lisp_Frame, f);
dc6f92b8
JB
478 }
479 else
480 {
ff11dfa1
JB
481 CHECK_FRAME (frame, 0);
482 f = XFRAME (frame);
dc6f92b8
JB
483 }
484
ff11dfa1 485 if (! FRAME_LIVE_P (f))
f9898cc6
JB
486 return;
487
ff11dfa1
JB
488 /* Are there any other frames besides this one? */
489 if (f == selected_frame && EQ (next_frame (frame, Qt), frame))
490 error ("Attempt to delete the only frame");
d5e7c279 491
ff11dfa1
JB
492 /* Does this frame have a minibuffer, and is it the surrogate
493 minibuffer for any other frame? */
494 if (FRAME_HAS_MINIBUF (XFRAME (frame)))
dc6f92b8 495 {
ff11dfa1 496 Lisp_Object frames;
1113d9db 497
ff11dfa1
JB
498 for (frames = Vframe_list;
499 CONSP (frames);
500 frames = XCONS (frames)->cdr)
1113d9db 501 {
ff11dfa1 502 Lisp_Object this = XCONS (frames)->car;
1113d9db 503
ff11dfa1
JB
504 if (! EQ (this, frame)
505 && EQ (frame,
506 (WINDOW_FRAME
1113d9db 507 (XWINDOW
ff11dfa1
JB
508 (FRAME_MINIBUF_WINDOW
509 (XFRAME (this)))))))
510 error ("Attempt to delete a surrogate minibuffer frame");
1113d9db 511 }
dc6f92b8
JB
512 }
513
ff11dfa1
JB
514 /* Don't let the frame remain selected. */
515 if (f == selected_frame)
516 Fselect_frame (next_frame (frame, Qt));
dc6f92b8 517
ff11dfa1
JB
518 /* Don't allow minibuf_window to remain on a deleted frame. */
519 if (EQ (f->minibuffer_window, minibuf_window))
dc6f92b8 520 {
ff11dfa1 521 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 522 XWINDOW (minibuf_window)->buffer);
ff11dfa1 523 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
524 }
525
ff11dfa1
JB
526 Vframe_list = Fdelq (frame, Vframe_list);
527 f->visible = 0;
528 displ = f->display;
529 f->display.nothing = 0;
dc6f92b8 530
d5e7c279 531#ifdef HAVE_X_WINDOWS
ff11dfa1
JB
532 if (FRAME_IS_X (f))
533 x_destroy_window (f, displ);
d5e7c279
JB
534#endif
535
ff11dfa1 536 /* If we've deleted the last_nonminibuf_frame, then try to find
d5e7c279 537 another one. */
ff11dfa1 538 if (f == last_nonminibuf_frame)
d5e7c279 539 {
ff11dfa1 540 Lisp_Object frames;
1113d9db 541
ff11dfa1 542 last_nonminibuf_frame = 0;
d5e7c279 543
ff11dfa1
JB
544 for (frames = Vframe_list;
545 CONSP (frames);
546 frames = XCONS (frames)->cdr)
d5e7c279 547 {
ff11dfa1
JB
548 f = XFRAME (XCONS (frames)->car);
549 if (!FRAME_MINIBUF_ONLY_P (f))
d5e7c279 550 {
ff11dfa1 551 last_nonminibuf_frame = f;
d5e7c279
JB
552 break;
553 }
554 }
555 }
dc6f92b8 556
ff11dfa1
JB
557 /* If we've deleted Vdefault_minibuffer_frame, try to find another
558 one. Prefer minibuffer-only frames, but also notice frames
1113d9db 559 with other windows. */
ff11dfa1 560 if (EQ (frame, Vdefault_minibuffer_frame))
1113d9db 561 {
ff11dfa1 562 Lisp_Object frames;
1113d9db 563
ff11dfa1
JB
564 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
565 Lisp_Object frame_with_minibuf = Qnil;
1113d9db 566
ff11dfa1
JB
567 for (frames = Vframe_list;
568 CONSP (frames);
569 frames = XCONS (frames)->cdr)
1113d9db 570 {
ff11dfa1 571 Lisp_Object this = XCONS (frames)->car;
1113d9db 572
ff11dfa1 573 if (XTYPE (this) != Lisp_Frame)
1113d9db 574 abort ();
ff11dfa1 575 f = XFRAME (this);
1113d9db 576
ff11dfa1 577 if (FRAME_HAS_MINIBUF (f))
1113d9db 578 {
ff11dfa1
JB
579 frame_with_minibuf = this;
580 if (FRAME_MINIBUF_ONLY_P (f))
1113d9db
JB
581 break;
582 }
583 }
584
ff11dfa1
JB
585 /* We know that there must be some frame with a minibuffer out
586 there. If this were not true, all of the frames present
1113d9db 587 would have to be minibufferless, which implies that at some
ff11dfa1 588 point their minibuffer frames must have been deleted, but
1113d9db 589 that is prohibited at the top; you can't delete surrogate
ff11dfa1
JB
590 minibuffer frames. */
591 if (NILP (frame_with_minibuf))
1113d9db
JB
592 abort ();
593
ff11dfa1 594 Vdefault_minibuffer_frame = frame_with_minibuf;
1113d9db
JB
595 }
596
dc6f92b8
JB
597 return Qnil;
598}
599\f
600/* Return mouse position in character cell units. */
601
f9898cc6 602DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
ff11dfa1 603 "Return a list (FRAME X . Y) giving the current mouse frame and position.\n\
f9898cc6 604If Emacs is running on a mouseless terminal or hasn't been programmed\n\
ff11dfa1 605to read the mouse position, it returns the selected frame for FRAME\n\
f9898cc6
JB
606and nil for X and Y.")
607 ()
dc6f92b8 608{
f9898cc6 609 Lisp_Object x, y, dummy;
ff11dfa1 610 FRAME_PTR f;
dc6f92b8 611
f9898cc6 612 if (mouse_position_hook)
ff11dfa1 613 (*mouse_position_hook) (&f, &x, &y, &dummy);
f9898cc6
JB
614 else
615 {
ff11dfa1 616 f = selected_frame;
f9898cc6
JB
617 x = y = Qnil;
618 }
dc6f92b8 619
ff11dfa1 620 XSET (dummy, Lisp_Frame, f);
f9898cc6 621 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
dc6f92b8
JB
622}
623
624DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
ff11dfa1
JB
625 "Move the mouse pointer to the center of cell (X,Y) in FRAME.\n\
626WARNING: If you use this under X, you should do `unfocus-frame' afterwards.")
627 (frame, x, y)
628 Lisp_Object frame, x, y;
dc6f92b8 629{
ff11dfa1 630 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
631 CHECK_NUMBER (x, 2);
632 CHECK_NUMBER (y, 1);
633
634#ifdef HAVE_X_WINDOWS
ff11dfa1 635 if (FRAME_IS_X (XFRAME (frame)))
dc6f92b8 636 /* Warping the mouse will cause enternotify and focus events. */
ff11dfa1 637 x_set_mouse_position (XFRAME (frame), x, y);
dc6f92b8
JB
638#endif
639
640 return Qnil;
641}
642\f
643#if 0
644/* ??? Can this be replaced with a Lisp function?
06b1a5ef
JB
645 It is used in minibuf.c. Can we get rid of that?
646 Yes. All uses in minibuf.c are gone, and parallels to these
ff11dfa1 647 functions have been defined in frame.el. */
dc6f92b8 648
ff11dfa1 649DEFUN ("frame-configuration", Fframe_configuration, Sframe_configuration,
dc6f92b8 650 0, 0, 0,
ff11dfa1
JB
651 "Return object describing current frame configuration.\n\
652The frame configuration is the current mouse position and selected frame.\n\
653This object can be given to `restore-frame-configuration'\n\
654to restore this frame configuration.")
dc6f92b8
JB
655 ()
656{
f9898cc6 657 Lisp_Object c, time;
dc6f92b8 658
f9898cc6 659 c = Fmake_vector (make_number(4), Qnil);
ff11dfa1 660 XVECTOR (c)->contents[0] = Fselected_frame();
f9898cc6
JB
661 if (mouse_position_hook)
662 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
663 &XVECTOR (c)->contents[2],
664 &XVECTOR (c)->contents[3],
665 &time);
dc6f92b8
JB
666 return c;
667}
668
ff11dfa1
JB
669DEFUN ("restore-frame-configuration", Frestore_frame_configuration,
670 Srestore_frame_configuration,
dc6f92b8 671 1, 1, 0,
ff11dfa1 672 "Restores frame configuration CONFIGURATION.")
dc6f92b8
JB
673 (config)
674 Lisp_Object config;
675{
ff11dfa1 676 Lisp_Object x_pos, y_pos, frame;
dc6f92b8
JB
677
678 CHECK_VECTOR (config, 0);
679 if (XVECTOR (config)->size != 3)
680 {
ff11dfa1 681 error ("Wrong size vector passed to restore-frame-configuration");
dc6f92b8 682 }
ff11dfa1
JB
683 frame = XVECTOR (config)->contents[0];
684 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 685
ff11dfa1 686 Fselect_frame (frame, Qnil);
dc6f92b8
JB
687
688#if 0
ff11dfa1 689 /* This seems to interfere with the frame selection mechanism. jla */
f9898cc6
JB
690 x_pos = XVECTOR (config)->contents[2];
691 y_pos = XVECTOR (config)->contents[3];
ff11dfa1 692 set_mouse_position (frame, XINT (x_pos), XINT (y_pos));
dc6f92b8
JB
693#endif
694
ff11dfa1 695 return frame;
dc6f92b8
JB
696}
697#endif
698\f
ff11dfa1 699DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1aa66088 700 0, 1, 0,
ff11dfa1
JB
701 "Make the frame FRAME visible (assuming it is an X-window).\n\
702Also raises the frame so that nothing obscures it.")
703 (frame)
704 Lisp_Object frame;
dc6f92b8 705{
1aa66088
JB
706 if (NILP (frame))
707 frame = selected_frame;
708
ff11dfa1 709 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 710
ff11dfa1
JB
711 if (FRAME_IS_X (XFRAME (frame)))
712 x_make_frame_visible (XFRAME (frame));
dc6f92b8 713
ff11dfa1 714 return frame;
dc6f92b8
JB
715}
716
ff11dfa1 717DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1aa66088 718 0, 1, "",
ff11dfa1
JB
719 "Make the frame FRAME invisible (assuming it is an X-window).")
720 (frame)
721 Lisp_Object frame;
dc6f92b8 722{
1aa66088
JB
723 if (NILP (frame))
724 frame = selected_frame;
725
ff11dfa1 726 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 727
ff11dfa1
JB
728 if (FRAME_IS_X (XFRAME (frame)))
729 x_make_frame_invisible (XFRAME (frame));
dc6f92b8
JB
730
731 return Qnil;
732}
733
ff11dfa1 734DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1aa66088 735 0, 1, "",
ff11dfa1
JB
736 "Make the frame FRAME into an icon.")
737 (frame)
738 Lisp_Object frame;
dc6f92b8 739{
1aa66088
JB
740 if (NILP (frame))
741 frame = selected_frame;
742
ff11dfa1 743 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 744
ff11dfa1
JB
745 if (FRAME_IS_X (XFRAME (frame)))
746 x_iconify_frame (XFRAME (frame));
dc6f92b8
JB
747
748 return Qnil;
749}
750
ff11dfa1 751DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
dc6f92b8 752 1, 1, 0,
ff11dfa1
JB
753 "Return t if FRAME is now \"visible\" (actually in use for display).\n\
754A frame that is not \"visible\" is not updated and, if it works through\n\
dc6f92b8
JB
755a window system, it may not show at all.\n\
756Return the symbol `icon' if window is visible only as an icon.")
ff11dfa1
JB
757 (frame)
758 Lisp_Object frame;
dc6f92b8 759{
ff11dfa1 760 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8 761
ff11dfa1 762 if (XFRAME (frame)->visible)
dc6f92b8 763 return Qt;
ff11dfa1 764 if (XFRAME (frame)->iconified)
dc6f92b8
JB
765 return intern ("icon");
766 return Qnil;
767}
768
ff11dfa1 769DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
dc6f92b8 770 0, 0, 0,
ff11dfa1 771 "Return a list of all frames now \"visible\" (being updated).")
dc6f92b8
JB
772 ()
773{
ff11dfa1
JB
774 Lisp_Object tail, frame;
775 struct frame *f;
dc6f92b8
JB
776 Lisp_Object value;
777
778 value = Qnil;
ff11dfa1 779 for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
dc6f92b8 780 {
ff11dfa1
JB
781 frame = XCONS (tail)->car;
782 if (XTYPE (frame) != Lisp_Frame)
dc6f92b8 783 continue;
ff11dfa1
JB
784 f = XFRAME (frame);
785 if (f->visible)
786 value = Fcons (frame, value);
dc6f92b8
JB
787 }
788 return value;
789}
d5e7c279
JB
790
791
792\f
ff11dfa1 793DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
d5e7c279 794 1, 2, 0,
ff11dfa1
JB
795 "Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.\n\
796This means that, after reading a keystroke typed at FRAME,\n\
797`last-event-frame' will be FOCUS-FRAME.\n\
d5e7c279 798\n\
ff11dfa1
JB
799If FOCUS-FRAME is omitted or eq to FRAME, any existing redirection is\n\
800cancelled, and the frame again receives its own keystrokes.\n\
d5e7c279 801\n\
ff11dfa1
JB
802The redirection lasts until the next call to `redirect-frame-focus'\n\
803or `select-frame'.\n\
d5e7c279
JB
804\n\
805This is useful for temporarily redirecting keystrokes to the minibuffer\n\
ff11dfa1
JB
806window when a frame doesn't have its own minibuffer.")
807 (frame, focus_frame)
808 Lisp_Object frame, focus_frame;
d5e7c279 809{
ff11dfa1 810 CHECK_LIVE_FRAME (frame, 0);
f9898cc6 811
ff11dfa1
JB
812 if (NILP (focus_frame))
813 focus_frame = frame;
d5e7c279 814 else
ff11dfa1 815 CHECK_LIVE_FRAME (focus_frame, 1);
d5e7c279 816
ff11dfa1 817 XFRAME (frame)->focus_frame = focus_frame;
d5e7c279 818
ff11dfa1
JB
819 if (frame_rehighlight_hook)
820 (*frame_rehighlight_hook) ();
d5e7c279
JB
821
822 return Qnil;
823}
824
825
ff11dfa1
JB
826DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
827 "Return the frame to which FRAME's keystrokes are currently being sent.\n\
828See `redirect-frame-focus'.")
829 (frame)
830 Lisp_Object frame;
d5e7c279 831{
ff11dfa1
JB
832 CHECK_LIVE_FRAME (frame, 0);
833 return FRAME_FOCUS_FRAME (XFRAME (frame));
d5e7c279
JB
834}
835
836
dc6f92b8
JB
837\f
838Lisp_Object
ff11dfa1
JB
839get_frame_param (frame, prop)
840 register struct frame *frame;
dc6f92b8
JB
841 Lisp_Object prop;
842{
843 register Lisp_Object tem;
844
ff11dfa1 845 tem = Fassq (prop, frame->param_alist);
dc6f92b8
JB
846 if (EQ (tem, Qnil))
847 return tem;
848 return Fcdr (tem);
849}
850
851void
852store_in_alist (alistptr, propname, val)
853 Lisp_Object *alistptr, val;
854 char *propname;
855{
856 register Lisp_Object tem;
857 register Lisp_Object prop;
858
859 prop = intern (propname);
860 tem = Fassq (prop, *alistptr);
861 if (EQ (tem, Qnil))
862 *alistptr = Fcons (Fcons (prop, val), *alistptr);
863 else
864 Fsetcdr (tem, val);
865}
866
867void
ff11dfa1
JB
868store_frame_param (f, prop, val)
869 struct frame *f;
dc6f92b8
JB
870 Lisp_Object prop, val;
871{
872 register Lisp_Object tem;
873
ff11dfa1 874 tem = Fassq (prop, f->param_alist);
dc6f92b8 875 if (EQ (tem, Qnil))
ff11dfa1 876 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
dc6f92b8
JB
877 else
878 Fsetcdr (tem, val);
bc93c097
JB
879
880 if (EQ (prop, Qminibuffer)
881 && XTYPE (val) == Lisp_Window)
882 {
883 if (! MINI_WINDOW_P (XWINDOW (val)))
884 error ("Surrogate minibuffer windows must be minibuffer windows.");
885
ff11dfa1
JB
886 if (FRAME_HAS_MINIBUF (f) || FRAME_MINIBUF_ONLY_P (f))
887 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer.");
bc93c097
JB
888
889 /* Install the chosen minibuffer window, with proper buffer. */
ff11dfa1 890 f->minibuffer_window = val;
bc93c097 891 }
dc6f92b8
JB
892}
893
ff11dfa1
JB
894DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
895 "Return the parameters-alist of frame FRAME.\n\
dc6f92b8 896It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
dc6d9681
JB
897The meaningful PARMs depend on the kind of frame.\n\
898If FRAME is omitted, return information on the currently selected frame.")
ff11dfa1
JB
899 (frame)
900 Lisp_Object frame;
dc6f92b8
JB
901{
902 Lisp_Object alist;
ff11dfa1 903 struct frame *f;
dc6f92b8 904
ff11dfa1
JB
905 if (EQ (frame, Qnil))
906 f = selected_frame;
dc6f92b8
JB
907 else
908 {
ff11dfa1
JB
909 CHECK_FRAME (frame, 0);
910 f = XFRAME (frame);
dc6f92b8
JB
911 }
912
ff11dfa1 913 if (f->display.nothing == 0)
dc6f92b8
JB
914 return Qnil;
915
ff11dfa1
JB
916 alist = Fcopy_alist (f->param_alist);
917 store_in_alist (&alist, "name", f->name);
918 store_in_alist (&alist, "height", make_number (f->height));
919 store_in_alist (&alist, "width", make_number (f->width));
920 store_in_alist (&alist, "modeline", (f->wants_modeline ? Qt : Qnil));
f9898cc6 921 store_in_alist (&alist, "minibuffer",
ff11dfa1
JB
922 (FRAME_HAS_MINIBUF (f)
923 ? (FRAME_MINIBUF_ONLY_P (f) ? intern ("only") : Qt)
924 : FRAME_MINIBUF_WINDOW (f)));
925 store_in_alist (&alist, "unsplittable", (f->no_split ? Qt : Qnil));
dc6f92b8 926
ff11dfa1
JB
927 if (FRAME_IS_X (f))
928 x_report_frame_params (f, &alist);
dc6f92b8
JB
929 return alist;
930}
931
ff11dfa1
JB
932DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
933 Smodify_frame_parameters, 2, 2, 0,
934 "Modify the parameters of frame FRAME according to ALIST.\n\
dc6f92b8
JB
935ALIST is an alist of parameters to change and their new values.\n\
936Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
ff11dfa1
JB
937The meaningful PARMs depend on the kind of frame; undefined PARMs are ignored.")
938 (frame, alist)
939 Lisp_Object frame, alist;
dc6f92b8 940{
ff11dfa1 941 register struct frame *f;
dc6f92b8
JB
942 register Lisp_Object tail, elt, prop, val;
943
ff11dfa1
JB
944 if (EQ (frame, Qnil))
945 f = selected_frame;
dc6f92b8
JB
946 else
947 {
ff11dfa1
JB
948 CHECK_LIVE_FRAME (frame, 0);
949 f = XFRAME (frame);
dc6f92b8
JB
950 }
951
ff11dfa1 952 if (FRAME_IS_X (f))
dc6f92b8
JB
953 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
954 {
955 elt = Fcar (tail);
956 prop = Fcar (elt);
957 val = Fcdr (elt);
ff11dfa1
JB
958 x_set_frame_param (f, prop, val,
959 get_frame_param (f, prop));
960 store_frame_param (f, prop, val);
dc6f92b8
JB
961 }
962
963 return Qnil;
964}
965\f
966
dc6d9681
JB
967#if 0
968/* This function isn't useful enough by itself to include; we need to
969 add functions to allow the user to find the size of a font before
970 this is actually useful. */
971
ff11dfa1
JB
972DEFUN ("frame-pixel-size", Fframe_pixel_size,
973 Sframe_pixel_size, 1, 1, 0,
974 "Return a cons (width . height) of FRAME's size in pixels.")
975 (frame)
976 Lisp_Object frame;
dc6f92b8 977{
ff11dfa1 978 register struct frame *f;
dc6f92b8
JB
979 int width, height;
980
ff11dfa1
JB
981 CHECK_LIVE_FRAME (frame, 0);
982 f = XFRAME (frame);
dc6f92b8 983
ff11dfa1
JB
984 return Fcons (make_number (x_pixel_width (f)),
985 make_number (x_pixel_height (f)));
dc6f92b8 986}
dc6d9681
JB
987#endif
988
989#if 0
990/* These functions have no C callers, and can be written nicely in lisp. */
dc6f92b8 991
ff11dfa1
JB
992DEFUN ("frame-height", Fframe_height, Sframe_height, 0, 0, 0,
993 "Return number of lines available for display on selected frame.")
dc6f92b8
JB
994 ()
995{
ff11dfa1 996 return make_number (FRAME_HEIGHT (selected_frame));
dc6f92b8
JB
997}
998
ff11dfa1
JB
999DEFUN ("frame-width", Fframe_width, Sframe_width, 0, 0, 0,
1000 "Return number of columns available for display on selected frame.")
dc6f92b8
JB
1001 ()
1002{
ff11dfa1 1003 return make_number (FRAME_WIDTH (selected_frame));
dc6f92b8 1004}
dc6d9681 1005#endif
dc6f92b8 1006
ff11dfa1
JB
1007DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
1008 "Specify that the frame FRAME has LINES lines.\n\
dc6f92b8 1009Optional third arg non-nil means that redisplay should use LINES lines\n\
ff11dfa1
JB
1010but that the idea of the actual height of the frame should not be changed.")
1011 (frame, rows, pretend)
dc6f92b8
JB
1012 Lisp_Object rows, pretend;
1013{
ff11dfa1 1014 register struct frame *f;
dc6f92b8
JB
1015
1016 CHECK_NUMBER (rows, 0);
ff11dfa1
JB
1017 if (NILP (frame))
1018 f = selected_frame;
dc6f92b8
JB
1019 else
1020 {
ff11dfa1
JB
1021 CHECK_LIVE_FRAME (frame, 0);
1022 f = XFRAME (frame);
dc6f92b8
JB
1023 }
1024
ff11dfa1 1025 if (FRAME_IS_X (f))
dc6f92b8 1026 {
ff11dfa1
JB
1027 if (XINT (rows) != f->width)
1028 x_set_window_size (f, f->width, XINT (rows));
dc6f92b8
JB
1029 }
1030 else
ff11dfa1 1031 change_frame_size (f, XINT (rows), 0, !NILP (pretend));
dc6f92b8
JB
1032 return Qnil;
1033}
1034
ff11dfa1
JB
1035DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
1036 "Specify that the frame FRAME has COLS columns.\n\
dc6f92b8 1037Optional third arg non-nil means that redisplay should use COLS columns\n\
ff11dfa1
JB
1038but that the idea of the actual width of the frame should not be changed.")
1039 (frame, cols, pretend)
dc6f92b8
JB
1040 Lisp_Object cols, pretend;
1041{
ff11dfa1 1042 register struct frame *f;
dc6f92b8 1043 CHECK_NUMBER (cols, 0);
ff11dfa1
JB
1044 if (NILP (frame))
1045 f = selected_frame;
dc6f92b8
JB
1046 else
1047 {
ff11dfa1
JB
1048 CHECK_LIVE_FRAME (frame, 0);
1049 f = XFRAME (frame);
dc6f92b8
JB
1050 }
1051
ff11dfa1 1052 if (FRAME_IS_X (f))
dc6f92b8 1053 {
ff11dfa1
JB
1054 if (XINT (cols) != f->width)
1055 x_set_window_size (f, XINT (cols), f->height);
dc6f92b8
JB
1056 }
1057 else
ff11dfa1 1058 change_frame_size (selected_frame, 0, XINT (cols), !NILP (pretend));
dc6f92b8
JB
1059 return Qnil;
1060}
1061
ff11dfa1
JB
1062DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
1063 "Sets size of FRAME to COLS by ROWS, measured in characters.")
1064 (frame, cols, rows)
1065 Lisp_Object frame, cols, rows;
dc6f92b8 1066{
ff11dfa1 1067 register struct frame *f;
dc6f92b8
JB
1068 int mask;
1069
ff11dfa1 1070 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1071 CHECK_NUMBER (cols, 2);
1072 CHECK_NUMBER (rows, 1);
ff11dfa1 1073 f = XFRAME (frame);
dc6f92b8 1074
ff11dfa1 1075 if (FRAME_IS_X (f))
dc6f92b8 1076 {
ff11dfa1
JB
1077 if (XINT (rows) != f->height || XINT (cols) != f->width)
1078 x_set_window_size (f, XINT (cols), XINT (rows));
dc6f92b8
JB
1079 }
1080 else
ff11dfa1 1081 change_frame_size (f, XINT (rows), XINT (cols), 0);
dc6f92b8
JB
1082
1083 return Qnil;
1084}
1085
ff11dfa1
JB
1086DEFUN ("set-frame-position", Fset_frame_position,
1087 Sset_frame_position, 3, 3, 0,
1088 "Sets position of FRAME in pixels to XOFFSET by YOFFSET.\n\
f9898cc6 1089If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
ff11dfa1
JB
1090the leftmost or bottommost position FRAME could occupy without going\n\
1091off the frame.")
1092 (frame, xoffset, yoffset)
1093 Lisp_Object frame, xoffset, yoffset;
dc6f92b8 1094{
ff11dfa1 1095 register struct frame *f;
dc6f92b8
JB
1096 int mask;
1097
ff11dfa1 1098 CHECK_LIVE_FRAME (frame, 0);
dc6f92b8
JB
1099 CHECK_NUMBER (xoffset, 1);
1100 CHECK_NUMBER (yoffset, 2);
ff11dfa1 1101 f = XFRAME (frame);
dc6f92b8 1102
ff11dfa1
JB
1103 if (FRAME_IS_X (f))
1104 x_set_offset (f, XINT (xoffset), XINT (yoffset));
dc6f92b8
JB
1105
1106 return Qt;
1107}
dc6d9681 1108
dc6f92b8 1109\f
dc6f92b8
JB
1110#ifndef HAVE_X11
1111DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1112 3, 3, "",
ff11dfa1
JB
1113 "Ask user to specify a window position and size on FRAME with the mouse.\n\
1114Arguments are FRAME, NAME and GEO. NAME is a name to be displayed as\n\
dc6f92b8
JB
1115the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1116specify defaults for some sizes/positions. If GEO specifies everything,\n\
1117the mouse is not used.\n\
ff11dfa1
JB
1118Returns a list of five values: (FRAME LEFT TOP WIDTH HEIGHT).")
1119 (frame, name, geo)
1120 Lisp_Object frame;
dc6f92b8
JB
1121 Lisp_Object name;
1122 Lisp_Object geo;
1123{
1124 int vals[4];
1125 Lisp_Object nums[4];
1126 int i;
1127
ff11dfa1 1128 CHECK_FRAME (frame, 0);
dc6f92b8
JB
1129 CHECK_STRING (name, 1);
1130 CHECK_STRING (geo, 2);
1131
ff11dfa1 1132 switch (XFRAME (frame)->output_method)
dc6f92b8
JB
1133 {
1134 case output_x_window:
ff11dfa1 1135 x_rubber_band (XFRAME (frame), &vals[0], &vals[1], &vals[2], &vals[3],
dc6f92b8
JB
1136 XSTRING (geo)->data, XSTRING (name)->data);
1137 break;
1138
1139 default:
1140 return Qnil;
1141 }
1142
1143 for (i = 0; i < 4; i++)
1144 XFASTINT (nums[i]) = vals[i];
ff11dfa1 1145 return Fcons (frame, Flist (4, nums));
dc6f92b8
JB
1146 return Qnil;
1147}
1148#endif /* not HAVE_X11 */
1149\f
ff11dfa1 1150choose_minibuf_frame ()
dc6f92b8 1151{
ff11dfa1
JB
1152 /* For lowest-level minibuf, put it on currently selected frame
1153 if frame has a minibuffer. */
dc6f92b8 1154 if (minibuf_level == 0
ff11dfa1
JB
1155 && selected_frame != 0
1156 && !EQ (minibuf_window, selected_frame->minibuffer_window)
1157 && !EQ (Qnil, selected_frame->minibuffer_window))
dc6f92b8 1158 {
ff11dfa1 1159 Fset_window_buffer (selected_frame->minibuffer_window,
dc6f92b8 1160 XWINDOW (minibuf_window)->buffer);
ff11dfa1 1161 minibuf_window = selected_frame->minibuffer_window;
dc6f92b8
JB
1162 }
1163}
1164\f
ff11dfa1 1165syms_of_frame ()
dc6f92b8 1166{
ff11dfa1
JB
1167 Qframep = intern ("framep");
1168 Qlive_frame_p = intern ("live_frame_p");
bc93c097 1169 Qminibuffer = intern ("minibuffer");
f9898cc6 1170
ff11dfa1
JB
1171 staticpro (&Qframep);
1172 staticpro (&Qlive_frame_p);
bc93c097 1173 staticpro (&Qminibuffer);
dc6f92b8 1174
ff11dfa1 1175 staticpro (&Vframe_list);
dc6f92b8 1176
ff11dfa1
JB
1177 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
1178 "The initial frame-object, which represents Emacs's stdout.");
dc6f92b8
JB
1179
1180 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
ff11dfa1 1181 "Non-nil if all of emacs is iconified and frame updates are not needed.");
dc6f92b8
JB
1182 Vemacs_iconified = Qnil;
1183
ff11dfa1
JB
1184 DEFVAR_LISP ("default-minibuffer-frame", &Vdefault_minibuffer_frame,
1185 "Minibufferless frames use this frame's minibuffer.\n\
f9898cc6 1186\n\
ff11dfa1 1187Emacs cannot create minibufferless frames unless this is set to an\n\
f9898cc6
JB
1188appropriate surrogate.\n\
1189\n\
1190Emacs consults this variable only when creating minibufferless\n\
ff11dfa1 1191frames; once the frame is created, it sticks with its assigned\n\
f9898cc6
JB
1192minibuffer, no matter what this variable is set to. This means that\n\
1193this variable doesn't necessarily say anything meaningful about the\n\
ff11dfa1 1194current set of frames, or where the minibuffer is currently being\n\
f9898cc6 1195displayed.");
ff11dfa1 1196 Vdefault_minibuffer_frame = Qnil;
dc6f92b8 1197
ff11dfa1
JB
1198 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
1199 "Alist of default values for frame creation.\n\
5bce042c 1200These may be set in your init file, like this:\n\
ff11dfa1 1201 (setq default-frame-alist '((width . 80) (height . 55)))\n\
5bce042c
JB
1202These override values given in window system configuration data, like\n\
1203X Windows' defaults database.\n\
ff11dfa1
JB
1204For values specific to the first Emacs frame, see `initial-frame-alist'.\n\
1205For values specific to the separate minibuffer frame, see\n\
1206`minibuffer-frame-alist'.");
1207 Vdefault_frame_alist = Qnil;
1208
1209 defsubr (&Sframep);
1210 defsubr (&Slive_frame_p);
1211 defsubr (&Sselect_frame);
1212 defsubr (&Sselected_frame);
1213 defsubr (&Swindow_frame);
1214 defsubr (&Sframe_root_window);
1215 defsubr (&Sframe_selected_window);
1216 defsubr (&Sframe_list);
1217 defsubr (&Snext_frame);
1218 defsubr (&Sdelete_frame);
f9898cc6 1219 defsubr (&Smouse_position);
dc6f92b8
JB
1220 defsubr (&Sset_mouse_position);
1221#if 0
ff11dfa1
JB
1222 defsubr (&Sframe_configuration);
1223 defsubr (&Srestore_frame_configuration);
dc6f92b8 1224#endif
ff11dfa1
JB
1225 defsubr (&Smake_frame_visible);
1226 defsubr (&Smake_frame_invisible);
1227 defsubr (&Siconify_frame);
1228 defsubr (&Sframe_visible_p);
1229 defsubr (&Svisible_frame_list);
1230 defsubr (&Sredirect_frame_focus);
1231 defsubr (&Sframe_focus);
1232 defsubr (&Sframe_parameters);
1233 defsubr (&Smodify_frame_parameters);
1265558a 1234#if 0
ff11dfa1
JB
1235 defsubr (&Sframe_pixel_size);
1236 defsubr (&Sframe_height);
1237 defsubr (&Sframe_width);
1265558a 1238#endif
ff11dfa1
JB
1239 defsubr (&Sset_frame_height);
1240 defsubr (&Sset_frame_width);
1241 defsubr (&Sset_frame_size);
1242 defsubr (&Sset_frame_position);
dc6f92b8
JB
1243#ifndef HAVE_X11
1244 defsubr (&Srubber_band_rectangle);
1245#endif /* HAVE_X11 */
1246}
e5d77022
JB
1247
1248#endif