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