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