*** empty log message ***
[emacs.git] / src / frame.c
blob675407ba8ff1da2a51bcdac24e2cb4d48258c1b5
1 /* Generic screen functions.
2 Copyright (C) 1989 Free Software Foundation.
4 This file is part of GNU Emacs.
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 1, or (at your option)
9 any later version.
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.
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. */
20 #include <stdio.h>
22 #include "config.h"
23 #include "lisp.h"
24 #include "screen.h"
25 #include "window.h"
26 #include "termhooks.h"
28 Lisp_Object Vemacs_iconified;
29 Lisp_Object Qscreenp;
30 Lisp_Object Qlive_screen_p;
31 Lisp_Object Vscreen_list;
32 Lisp_Object Vterminal_screen;
33 Lisp_Object Vdefault_minibuffer_screen;
34 Lisp_Object Vdefault_screen_alist;
35 Lisp_Object Qminibuffer;
37 /* A screen which is not just a minibuffer, or 0 if there are no
38 such screens. This is usually the most recent such screen that
39 was selected. */
40 struct screen *last_nonminibuf_screen;
42 extern Lisp_Object Vminibuffer_list;
43 extern Lisp_Object get_minibuffer ();
45 DEFUN ("screenp", Fscreenp, Sscreenp, 1, 1, 0,
46 "Return non-nil if OBJECT is a screen.\n\
47 Value is t for a termcap screen (a character-only terminal),\n\
48 `x' for an Emacs screen that is really an X window.\n\
49 Also see live-screen-p.")
50 (object)
51 Lisp_Object object;
53 if (XTYPE (object) != Lisp_Screen)
54 return Qnil;
55 switch (XSCREEN (object)->output_method)
57 case output_termcap:
58 return Qt;
59 case output_x_window:
60 return intern ("x");
61 default:
62 abort ();
66 DEFUN ("live-screen-p", Flive_screen_p, Slive_screen_p, 1, 1, 0,
67 "Return non-nil if OBJECT is a screen which has not been deleted.\n\
68 Value is nil if OBJECT is not a live screen. If object is a live\n\
69 screen, the return value indicates what sort of output device it is\n\
70 displayed on. Value is t for a termcap screen (a character-only\n\
71 terminal), `x' for an Emacs screen being displayed in an X window.")
72 (object)
73 Lisp_Object object;
75 return ((SCREENP (object)
76 && SCREEN_LIVE_P (XSCREEN (object)))
77 ? Fscreenp (object)
78 : Qnil);
81 struct screen *
82 make_screen (mini_p)
83 int mini_p;
85 Lisp_Object screen;
86 register struct screen *s;
87 register Lisp_Object root_window;
88 register Lisp_Object mini_window;
90 screen = Fmake_vector (((sizeof (struct screen) - (sizeof (Lisp_Vector)
91 - sizeof (Lisp_Object)))
92 / sizeof (Lisp_Object)),
93 make_number (0));
94 XSETTYPE (screen, Lisp_Screen);
95 s = XSCREEN (screen);
97 s->cursor_x = 0;
98 s->cursor_y = 0;
99 s->current_glyphs = 0;
100 s->desired_glyphs = 0;
101 s->visible = 0;
102 s->display.nothing = 0;
103 s->iconified = 0;
104 s->wants_modeline = 1;
105 s->auto_raise = 0;
106 s->auto_lower = 0;
107 s->no_split = 0;
108 s->garbaged = 0;
109 s->has_minibuffer = mini_p;
110 s->focus_screen = screen;
112 s->param_alist = Qnil;
114 root_window = make_window (0);
115 if (mini_p)
117 mini_window = make_window (0);
118 XWINDOW (root_window)->next = mini_window;
119 XWINDOW (mini_window)->prev = root_window;
120 XWINDOW (mini_window)->mini_p = Qt;
121 XWINDOW (mini_window)->screen = screen;
122 s->minibuffer_window = mini_window;
124 else
126 mini_window = Qnil;
127 XWINDOW (root_window)->next = Qnil;
128 s->minibuffer_window = Qnil;
131 XWINDOW (root_window)->screen = screen;
133 /* 10 is arbitrary,
134 just so that there is "something there."
135 Correct size will be set up later with change_screen_size. */
137 s->width = 10;
138 s->height = 10;
140 XFASTINT (XWINDOW (root_window)->width) = 10;
141 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
143 if (mini_p)
145 XFASTINT (XWINDOW (mini_window)->width) = 10;
146 XFASTINT (XWINDOW (mini_window)->top) = 9;
147 XFASTINT (XWINDOW (mini_window)->height) = 1;
150 /* Choose a buffer for the screen's root window. */
152 Lisp_Object buf;
154 XWINDOW (root_window)->buffer = Qt;
155 buf = Fcurrent_buffer ();
156 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
157 a space), try to find another one. */
158 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
159 buf = Fother_buffer (buf);
160 Fset_window_buffer (root_window, buf);
163 if (mini_p)
165 XWINDOW (mini_window)->buffer = Qt;
166 Fset_window_buffer (mini_window,
167 (NILP (Vminibuffer_list)
168 ? get_minibuffer (0)
169 : Fcar (Vminibuffer_list)));
172 s->root_window = root_window;
173 s->selected_window = root_window;
174 /* Make sure this window seems more recently used than
175 a newly-created, never-selected window. */
176 XFASTINT (XWINDOW (s->selected_window)->use_time) = ++window_select_count;
178 Vscreen_list = Fcons (screen, Vscreen_list);
180 return s;
183 /* Make a screen using a separate minibuffer window on another screen.
184 MINI_WINDOW is the minibuffer window to use. nil means use the
185 default (the global minibuffer). */
187 struct screen *
188 make_screen_without_minibuffer (mini_window)
189 register Lisp_Object mini_window;
191 register struct screen *s;
193 /* Choose the minibuffer window to use. */
194 if (NILP (mini_window))
196 if (XTYPE (Vdefault_minibuffer_screen) != Lisp_Screen)
197 error ("default-minibuffer-screen must be set when creating minibufferless screens.");
198 mini_window = XSCREEN (Vdefault_minibuffer_screen)->minibuffer_window;
200 else
202 CHECK_WINDOW (mini_window, 0);
205 /* Make a screen containing just a root window. */
206 s = make_screen (0);
208 /* Install the chosen minibuffer window, with proper buffer. */
209 s->minibuffer_window = mini_window;
210 Fset_window_buffer (mini_window,
211 (NILP (Vminibuffer_list)
212 ? get_minibuffer (0)
213 : Fcar (Vminibuffer_list)));
214 return s;
217 /* Make a screen containing only a minibuffer window. */
219 struct screen *
220 make_minibuffer_screen ()
222 /* First make a screen containing just a root window, no minibuffer. */
224 register struct screen *s = make_screen (0);
225 register Lisp_Object mini_window;
226 register Lisp_Object screen;
228 XSET (screen, Lisp_Screen, s);
230 /* ??? Perhaps leave it to the user program to set auto_raise. */
231 s->auto_raise = 1;
232 s->auto_lower = 0;
233 s->no_split = 1;
234 s->wants_modeline = 0;
235 s->has_minibuffer = 1;
237 /* Now label the root window as also being the minibuffer.
238 Avoid infinite looping on the window chain by marking next pointer
239 as nil. */
241 mini_window = s->minibuffer_window = s->root_window;
242 XWINDOW (mini_window)->mini_p = Qt;
243 XWINDOW (mini_window)->next = Qnil;
244 XWINDOW (mini_window)->prev = mini_window;
245 XWINDOW (mini_window)->screen = screen;
247 /* Put the proper buffer in that window. */
249 Fset_window_buffer (mini_window,
250 (NILP (Vminibuffer_list)
251 ? get_minibuffer (0)
252 : Fcar (Vminibuffer_list)));
253 return s;
256 /* Construct a screen that refers to the terminal (stdin and stdout). */
258 struct screen *
259 make_terminal_screen ()
261 register struct screen *s;
263 Vscreen_list = Qnil;
264 s = make_screen (1);
265 s->name = build_string ("terminal");
266 s->visible = 1;
267 s->display.nothing = 1; /* Nonzero means screen isn't deleted. */
268 XSET (Vterminal_screen, Lisp_Screen, s);
269 return s;
272 DEFUN ("select-screen", Fselect_screen, Sselect_screen, 1, 2, 0,
273 "Select the screen S. S's selected window becomes \"the\"\n\
274 selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
275 focus on that screen.")
276 (screen, no_enter)
277 Lisp_Object screen, no_enter;
279 CHECK_LIVE_SCREEN (screen, 0);
281 if (selected_screen == XSCREEN (screen))
282 return screen;
284 selected_screen = XSCREEN (screen);
285 if (! SCREEN_MINIBUF_ONLY_P (selected_screen))
286 last_nonminibuf_screen = selected_screen;
288 Fselect_window (XSCREEN (screen)->selected_window);
290 #ifdef HAVE_X_WINDOWS
291 #ifdef MULTI_SCREEN
292 if (SCREEN_IS_X (XSCREEN (screen))
293 && NILP (no_enter))
295 Ffocus_screen (screen);
297 #endif
298 #endif
299 choose_minibuf_screen ();
301 return screen;
304 DEFUN ("selected-screen", Fselected_screen, Sselected_screen, 0, 0, 0,
305 "Return the screen that is now selected.")
308 Lisp_Object tem;
309 XSET (tem, Lisp_Screen, selected_screen);
310 return tem;
313 DEFUN ("window-screen", Fwindow_screen, Swindow_screen, 1, 1, 0,
314 "Return the screen object that window WINDOW is on.")
315 (window)
316 Lisp_Object window;
318 CHECK_WINDOW (window, 0);
319 return XWINDOW (window)->screen;
322 DEFUN ("screen-root-window", Fscreen_root_window, Sscreen_root_window, 0, 1, 0,
323 "Returns the root-window of SCREEN.")
324 (screen)
325 Lisp_Object screen;
327 if (NILP (screen))
328 XSET (screen, Lisp_Screen, selected_screen);
329 else
330 CHECK_LIVE_SCREEN (screen, 0);
332 return XSCREEN (screen)->root_window;
335 DEFUN ("screen-selected-window", Fscreen_selected_window,
336 Sscreen_selected_window, 0, 1, 0,
337 "Return the selected window of screen object SCREEN.")
338 (screen)
339 Lisp_Object screen;
341 if (NILP (screen))
342 XSET (screen, Lisp_Screen, selected_screen);
343 else
344 CHECK_LIVE_SCREEN (screen, 0);
346 return XSCREEN (screen)->selected_window;
349 DEFUN ("screen-list", Fscreen_list, Sscreen_list,
350 0, 0, 0,
351 "Return a list of all screens.")
354 return Fcopy_sequence (Vscreen_list);
357 #ifdef MULTI_SCREEN
359 /* Return the next screen in the screen list after SCREEN.
360 If MINIBUF is non-nil, include all screens.
361 If MINIBUF is nil, exclude minibuffer-only screens.
362 If MINIBUF is a window, include only screens using that window for
363 their minibuffer. */
364 Lisp_Object
365 next_screen (screen, minibuf)
366 Lisp_Object screen;
367 Lisp_Object minibuf;
369 Lisp_Object tail;
370 int passed = 0;
372 /* There must always be at least one screen in Vscreen_list. */
373 if (! CONSP (Vscreen_list))
374 abort ();
376 while (1)
377 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
379 if (passed)
381 Lisp_Object s = XCONS (tail)->car;
383 /* Decide whether this screen is eligible to be returned,
384 according to minibuf. */
385 if ((NILP (minibuf) && ! SCREEN_MINIBUF_ONLY_P (XSCREEN (s)))
386 || XTYPE (minibuf) != Lisp_Window
387 || EQ (SCREEN_MINIBUF_WINDOW (XSCREEN (s)), minibuf)
388 || EQ (s, screen))
389 return s;
392 if (EQ (screen, XCONS (tail)->car))
393 passed++;
397 /* Return the previous screen in the screen list before SCREEN.
398 If MINIBUF is non-nil, include all screens.
399 If MINIBUF is nil, exclude minibuffer-only screens.
400 If MINIBUF is a window, include only screens using that window for
401 their minibuffer. */
402 Lisp_Object
403 prev_screen (screen, minibuf)
404 Lisp_Object screen;
405 Lisp_Object minibuf;
407 Lisp_Object tail;
408 Lisp_Object prev;
410 /* There must always be at least one screen in Vscreen_list. */
411 if (! CONSP (Vscreen_list))
412 abort ();
414 prev = Qnil;
415 while (1)
417 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
419 Lisp_Object scr = XCONS (tail)->car;
421 if (XTYPE (scr) != Lisp_Screen)
422 abort ();
424 if (EQ (screen, scr) && !NILP (prev))
425 return prev;
427 /* Decide whether this screen is eligible to be returned,
428 according to minibuf. */
429 if ((NILP (minibuf) && ! SCREEN_MINIBUF_ONLY_P (XSCREEN (scr)))
430 || XTYPE (minibuf) != Lisp_Window
431 || EQ (SCREEN_MINIBUF_WINDOW (XSCREEN (scr)), minibuf))
432 prev = scr;
435 if (NILP (prev))
436 /* We went through the whole screen list without finding a single
437 acceptable screen. Return the original screen. */
438 prev = screen;
443 DEFUN ("next-screen", Fnext_screen, Snext_screen, 0, 2, 0,
444 "Return the next screen in the screen list after SCREEN.\n\
445 If optional argument MINIBUF is non-nil, include all screens. If\n\
446 MINIBUF is nil or omitted, exclude minibuffer-only screens. If\n\
447 MINIBUF is a window, include only screens using that window for their\n\
448 minibuffer.")
449 (screen, miniscreen)
450 Lisp_Object screen, miniscreen;
452 Lisp_Object tail;
454 if (NILP (screen))
455 XSET (screen, Lisp_Screen, selected_screen);
456 else
457 CHECK_LIVE_SCREEN (screen, 0);
459 return next_screen (screen, miniscreen);
461 #endif /* MULTI_SCREEN */
463 DEFUN ("delete-screen", Fdelete_screen, Sdelete_screen, 0, 1, "",
464 "Delete SCREEN, permanently eliminating it from use.\n\
465 If omitted, SCREEN defaults to the selected screen.\n\
466 A screen may not be deleted if its minibuffer is used by other screens.")
467 (screen)
468 Lisp_Object screen;
470 struct screen *s;
471 union display displ;
473 if (EQ (screen, Qnil))
475 s = selected_screen;
476 XSET (screen, Lisp_Screen, s);
478 else
480 CHECK_SCREEN (screen, 0);
481 s = XSCREEN (screen);
484 if (! SCREEN_LIVE_P (s))
485 return;
487 /* Are there any other screens besides this one? */
488 if (s == selected_screen && EQ (next_screen (screen, Qt), screen))
489 error ("Attempt to delete the only screen");
491 /* Does this screen have a minibuffer, and is it the surrogate
492 minibuffer for any other screen? */
493 if (SCREEN_HAS_MINIBUF (XSCREEN (screen)))
495 Lisp_Object screen2;
497 for (screen2 = Vscreen_list; CONSP (2); screen2 = XCONS (screen2)->cdr)
498 if (! EQ (screen2, screen)
499 && EQ (screen,
500 (WINDOW_SCREEN
501 (XWINDOW
502 (SCREEN_MINIBUF_WINDOW
503 (XSCREEN (screen2)))))))
504 error ("Attempt to delete a surrogate minibuffer screen");
507 /* Don't let the screen remain selected. */
508 if (s == selected_screen)
509 Fselect_screen (next_screen (screen, Qt));
511 /* Don't allow minibuf_window to remain on a deleted screen. */
512 if (EQ (s->minibuffer_window, minibuf_window))
514 Fset_window_buffer (selected_screen->minibuffer_window,
515 XWINDOW (minibuf_window)->buffer);
516 minibuf_window = selected_screen->minibuffer_window;
519 Vscreen_list = Fdelq (screen, Vscreen_list);
520 s->visible = 0;
521 displ = s->display;
522 s->display.nothing = 0;
524 #ifdef HAVE_X_WINDOWS
525 if (SCREEN_IS_X (s))
526 x_destroy_window (s, displ);
527 #endif
529 /* If we've deleted the last_nonminibuf_screen, then try to find
530 another one. */
531 if (s == last_nonminibuf_screen)
533 last_nonminibuf_screen = 0;
535 for (screen = Vscreen_list; CONSP (screen); screen = XCONS (screen)->cdr)
537 s = XSCREEN (XCONS (screen)->car);
538 if (!SCREEN_MINIBUF_ONLY_P (s))
540 last_nonminibuf_screen = s;
541 break;
546 return Qnil;
549 /* Return mouse position in character cell units. */
551 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
552 "Return a list (SCREEN X . Y) giving the current mouse screen and position.\n\
553 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
554 to read the mouse position, it returns the selected screen for SCREEN\n\
555 and nil for X and Y.")
558 Lisp_Object x, y, dummy;
559 SCREEN_PTR s;
561 if (mouse_position_hook)
562 (*mouse_position_hook) (&s, &x, &y, &dummy);
563 else
565 s = selected_screen;
566 x = y = Qnil;
569 XSET (dummy, Lisp_Screen, s);
570 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
573 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
574 "Move the mouse pointer to the center of cell (X,Y) in SCREEN.\n\
575 WARNING: If you use this under X, you should do unfocus-screen afterwards.")
576 (screen, x, y)
577 Lisp_Object screen, x, y;
579 CHECK_LIVE_SCREEN (screen, 0);
580 CHECK_NUMBER (x, 2);
581 CHECK_NUMBER (y, 1);
583 #ifdef HAVE_X_WINDOWS
584 if (SCREEN_IS_X (XSCREEN (screen)))
585 /* Warping the mouse will cause enternotify and focus events. */
586 x_set_mouse_position (XSCREEN (screen), x, y);
587 #endif
589 return Qnil;
592 #if 0
593 /* ??? Can this be replaced with a Lisp function?
594 It is used in minibuf.c. Can we get rid of that? */
596 DEFUN ("screen-configuration", Fscreen_configuration, Sscreen_configuration,
597 0, 0, 0,
598 "Return object describing current screen configuration.\n\
599 The screen configuration is the current mouse position and selected screen.\n\
600 This object can be given to `restore-screen-configuration'\n\
601 to restore this screen configuration.")
604 Lisp_Object c, time;
606 c = Fmake_vector (make_number(4), Qnil);
607 XVECTOR (c)->contents[0] = Fselected_screen();
608 if (mouse_position_hook)
609 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
610 &XVECTOR (c)->contents[2],
611 &XVECTOR (c)->contents[3],
612 &time);
613 return c;
616 DEFUN ("restore-screen-configuration", Frestore_screen_configuration,
617 Srestore_screen_configuration,
618 1, 1, 0,
619 "Restores screen configuration CONFIGURATION.")
620 (config)
621 Lisp_Object config;
623 Lisp_Object x_pos, y_pos, screen;
625 CHECK_VECTOR (config, 0);
626 if (XVECTOR (config)->size != 3)
628 error ("Wrong size vector passed to restore-screen-configuration");
630 screen = XVECTOR (config)->contents[0];
631 CHECK_LIVE_SCREEN (screen, 0);
633 Fselect_screen (screen, Qnil);
635 #if 0
636 /* This seems to interfere with the screen selection mechanism. jla */
637 x_pos = XVECTOR (config)->contents[2];
638 y_pos = XVECTOR (config)->contents[3];
639 set_mouse_position (screen, XINT (x_pos), XINT (y_pos));
640 #endif
642 return screen;
644 #endif
646 DEFUN ("make-screen-visible", Fmake_screen_visible, Smake_screen_visible,
647 1, 1, 0,
648 "Make the screen SCREEN visible (assuming it is an X-window).\n\
649 Also raises the screen so that nothing obscures it.")
650 (screen)
651 Lisp_Object screen;
653 CHECK_LIVE_SCREEN (screen, 0);
655 if (SCREEN_IS_X (XSCREEN (screen)))
656 x_make_screen_visible (XSCREEN (screen));
658 return screen;
661 DEFUN ("make-screen-invisible", Fmake_screen_invisible, Smake_screen_invisible,
662 1, 1, 0,
663 "Make the screen SCREEN invisible (assuming it is an X-window).")
664 (screen)
665 Lisp_Object screen;
667 CHECK_LIVE_SCREEN (screen, 0);
669 if (SCREEN_IS_X (XSCREEN (screen)))
670 x_make_screen_invisible (XSCREEN (screen));
672 return Qnil;
675 DEFUN ("iconify-screen", Ficonify_screen, Siconify_screen,
676 1, 1, 0,
677 "Make the screen SCREEN into an icon.")
678 (screen)
679 Lisp_Object screen;
681 CHECK_LIVE_SCREEN (screen, 0);
683 if (SCREEN_IS_X (XSCREEN (screen)))
684 x_iconify_screen (XSCREEN (screen));
686 return Qnil;
689 DEFUN ("deiconify-screen", Fdeiconify_screen, Sdeiconify_screen,
690 1, 1, 0,
691 "Open (de-iconify) the iconified screen SCREEN.")
692 (screen)
693 Lisp_Object screen;
695 CHECK_LIVE_SCREEN (screen, 0);
697 if (SCREEN_IS_X (XSCREEN (screen)))
698 x_make_screen_visible (XSCREEN (screen));
700 return screen;
703 DEFUN ("screen-visible-p", Fscreen_visible_p, Sscreen_visible_p,
704 1, 1, 0,
705 "Return t if SCREEN is now \"visible\" (actually in use for display).\n\
706 A screen that is not \"visible\" is not updated and, if it works through\n\
707 a window system, it may not show at all.\n\
708 Return the symbol `icon' if window is visible only as an icon.")
709 (screen)
710 Lisp_Object screen;
712 CHECK_LIVE_SCREEN (screen, 0);
714 if (XSCREEN (screen)->visible)
715 return Qt;
716 if (XSCREEN (screen)->iconified)
717 return intern ("icon");
718 return Qnil;
721 DEFUN ("visible-screen-list", Fvisible_screen_list, Svisible_screen_list,
722 0, 0, 0,
723 "Return a list of all screens now \"visible\" (being updated).")
726 Lisp_Object tail, screen;
727 struct screen *s;
728 Lisp_Object value;
730 value = Qnil;
731 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
733 screen = XCONS (tail)->car;
734 if (XTYPE (screen) != Lisp_Screen)
735 continue;
736 s = XSCREEN (screen);
737 if (s->visible)
738 value = Fcons (screen, value);
740 return value;
745 DEFUN ("redirect-screen-focus", Fredirect_screen_focus, Sredirect_screen_focus,
746 1, 2, 0,
747 "Arrange for keystrokes typed at SCREEN to be sent to FOCUS-SCREEN.\n\
748 This means that, after reading a keystroke typed at SCREEN,\n\
749 last-event-screen will be FOCUS-SCREEN.\n\
751 If FOCUS-SCREEN is omitted or eq to SCREEN, any existing redirection is\n\
752 cancelled, and the screen again receives its own keystrokes.\n\
754 The redirection lasts until the next call to redirect-screen-focus\n\
755 or select-screen.\n\
757 This is useful for temporarily redirecting keystrokes to the minibuffer\n\
758 window when a screen doesn't have its own minibuffer.")
759 (screen, focus_screen)
760 Lisp_Object screen, focus_screen;
762 CHECK_LIVE_SCREEN (screen, 0);
764 if (NILP (focus_screen))
765 focus_screen = screen;
766 else
767 CHECK_LIVE_SCREEN (focus_screen, 1);
769 XSCREEN (screen)->focus_screen = focus_screen;
771 if (screen_rehighlight_hook)
772 (*screen_rehighlight_hook) ();
774 return Qnil;
778 DEFUN ("screen-focus", Fscreen_focus, Sscreen_focus, 1, 1, 0,
779 "Return the screen to which SCREEN's keystrokes are currently being sent.\n\
780 See redirect-screen-focus.")
781 (screen)
782 Lisp_Object screen;
784 CHECK_LIVE_SCREEN (screen, 0);
785 return SCREEN_FOCUS_SCREEN (XSCREEN (screen));
790 Lisp_Object
791 get_screen_param (screen, prop)
792 register struct screen *screen;
793 Lisp_Object prop;
795 register Lisp_Object tem;
797 tem = Fassq (prop, screen->param_alist);
798 if (EQ (tem, Qnil))
799 return tem;
800 return Fcdr (tem);
803 void
804 store_in_alist (alistptr, propname, val)
805 Lisp_Object *alistptr, val;
806 char *propname;
808 register Lisp_Object tem;
809 register Lisp_Object prop;
811 prop = intern (propname);
812 tem = Fassq (prop, *alistptr);
813 if (EQ (tem, Qnil))
814 *alistptr = Fcons (Fcons (prop, val), *alistptr);
815 else
816 Fsetcdr (tem, val);
819 void
820 store_screen_param (s, prop, val)
821 struct screen *s;
822 Lisp_Object prop, val;
824 register Lisp_Object tem;
826 tem = Fassq (prop, s->param_alist);
827 if (EQ (tem, Qnil))
828 s->param_alist = Fcons (Fcons (prop, val), s->param_alist);
829 else
830 Fsetcdr (tem, val);
832 if (EQ (prop, Qminibuffer)
833 && XTYPE (val) == Lisp_Window)
835 if (! MINI_WINDOW_P (XWINDOW (val)))
836 error ("Surrogate minibuffer windows must be minibuffer windows.");
838 if (SCREEN_HAS_MINIBUF (s) || SCREEN_MINIBUF_ONLY_P (s))
839 error ("Can't change surrogate minibuffer on screens with their own minibuffers.");
841 /* Install the chosen minibuffer window, with proper buffer. */
842 s->minibuffer_window = val;
846 DEFUN ("screen-parameters", Fscreen_parameters, Sscreen_parameters, 0, 1, 0,
847 "Return the parameters-alist of screen SCREEN.\n\
848 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
849 The meaningful PARMs depend on the kind of screen.")
850 (screen)
851 Lisp_Object screen;
853 Lisp_Object alist;
854 struct screen *s;
856 if (EQ (screen, Qnil))
857 s = selected_screen;
858 else
860 CHECK_SCREEN (screen, 0);
861 s = XSCREEN (screen);
864 if (s->display.nothing == 0)
865 return Qnil;
867 alist = Fcopy_alist (s->param_alist);
868 store_in_alist (&alist, "name", s->name);
869 store_in_alist (&alist, "height", make_number (s->height));
870 store_in_alist (&alist, "width", make_number (s->width));
871 store_in_alist (&alist, "modeline", (s->wants_modeline ? Qt : Qnil));
872 store_in_alist (&alist, "minibuffer",
873 (SCREEN_HAS_MINIBUF (s)
874 ? (SCREEN_MINIBUF_ONLY_P (s) ? intern ("only") : Qt)
875 : SCREEN_MINIBUF_WINDOW (s)));
876 store_in_alist (&alist, "unsplittable", (s->no_split ? Qt : Qnil));
878 if (SCREEN_IS_X (s))
879 x_report_screen_params (s, &alist);
880 return alist;
883 DEFUN ("modify-screen-parameters", Fmodify_screen_parameters,
884 Smodify_screen_parameters, 2, 2, 0,
885 "Modify the parameters of screen SCREEN according to ALIST.\n\
886 ALIST is an alist of parameters to change and their new values.\n\
887 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
888 The meaningful PARMs depend on the kind of screen; undefined PARMs are ignored.")
889 (screen, alist)
890 Lisp_Object screen, alist;
892 register struct screen *s;
893 register Lisp_Object tail, elt, prop, val;
895 if (EQ (screen, Qnil))
896 s = selected_screen;
897 else
899 CHECK_LIVE_SCREEN (screen, 0);
900 s = XSCREEN (screen);
903 if (SCREEN_IS_X (s))
904 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
906 elt = Fcar (tail);
907 prop = Fcar (elt);
908 val = Fcdr (elt);
909 x_set_screen_param (s, prop, val,
910 get_screen_param (s, prop));
911 store_screen_param (s, prop, val);
914 return Qnil;
918 DEFUN ("screen-pixel-size", Fscreen_pixel_size,
919 Sscreen_pixel_size, 1, 1, 0,
920 "Return a cons (width . height) of SCREEN's size in pixels.")
921 (screen)
922 Lisp_Object screen;
924 register struct screen *s;
925 int width, height;
927 CHECK_LIVE_SCREEN (screen, 0);
928 s = XSCREEN (screen);
930 return Fcons (make_number (x_pixel_width (s)),
931 make_number (x_pixel_height (s)));
934 DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0,
935 "Return number of lines available for display on selected screen.")
938 return make_number (SCREEN_HEIGHT (selected_screen));
941 DEFUN ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0,
942 "Return number of columns available for display on selected screen.")
945 return make_number (SCREEN_WIDTH (selected_screen));
948 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 2, 3, 0,
949 "Specify that the screen SCREEN has LINES lines.\n\
950 Optional third arg non-nil means that redisplay should use LINES lines\n\
951 but that the idea of the actual height of the screen should not be changed.")
952 (screen, rows, pretend)
953 Lisp_Object rows, pretend;
955 register struct screen *s;
957 CHECK_NUMBER (rows, 0);
958 if (NILP (screen))
959 s = selected_screen;
960 else
962 CHECK_LIVE_SCREEN (screen, 0);
963 s = XSCREEN (screen);
966 if (SCREEN_IS_X (s))
968 if (XINT (rows) != s->width)
969 x_set_window_size (s, s->width, XINT (rows));
971 else
972 change_screen_size (s, XINT (rows), 0, !NILP (pretend));
973 return Qnil;
976 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 2, 3, 0,
977 "Specify that the screen SCREEN has COLS columns.\n\
978 Optional third arg non-nil means that redisplay should use COLS columns\n\
979 but that the idea of the actual width of the screen should not be changed.")
980 (screen, cols, pretend)
981 Lisp_Object cols, pretend;
983 register struct screen *s;
984 CHECK_NUMBER (cols, 0);
985 if (NILP (screen))
986 s = selected_screen;
987 else
989 CHECK_LIVE_SCREEN (screen, 0);
990 s = XSCREEN (screen);
993 if (SCREEN_IS_X (s))
995 if (XINT (cols) != s->width)
996 x_set_window_size (s, XINT (cols), s->height);
998 else
999 change_screen_size (selected_screen, 0, XINT (cols), !NILP (pretend));
1000 return Qnil;
1003 DEFUN ("set-screen-size", Fset_screen_size, Sset_screen_size, 3, 3, 0,
1004 "Sets size of SCREEN to COLS by ROWS, measured in characters.")
1005 (screen, cols, rows)
1006 Lisp_Object screen, cols, rows;
1008 register struct screen *s;
1009 int mask;
1011 CHECK_LIVE_SCREEN (screen, 0);
1012 CHECK_NUMBER (cols, 2);
1013 CHECK_NUMBER (rows, 1);
1014 s = XSCREEN (screen);
1016 if (SCREEN_IS_X (s))
1018 if (XINT (rows) != s->height || XINT (cols) != s->width)
1019 x_set_window_size (s, XINT (cols), XINT (rows));
1021 else
1022 change_screen_size (s, XINT (rows), XINT (cols), 0);
1024 return Qnil;
1027 DEFUN ("set-screen-position", Fset_screen_position,
1028 Sset_screen_position, 3, 3, 0,
1029 "Sets position of SCREEN in pixels to XOFFSET by YOFFSET.\n\
1030 If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1031 the leftmost or bottommost position SCREEN could occupy without going\n\
1032 off the screen.")
1033 (screen, xoffset, yoffset)
1034 Lisp_Object screen, xoffset, yoffset;
1036 register struct screen *s;
1037 int mask;
1039 CHECK_LIVE_SCREEN (screen, 0);
1040 CHECK_NUMBER (xoffset, 1);
1041 CHECK_NUMBER (yoffset, 2);
1042 s = XSCREEN (screen);
1044 if (SCREEN_IS_X (s))
1045 x_set_offset (s, XINT (xoffset), XINT (yoffset));
1047 return Qt;
1050 #ifndef HAVE_X11
1051 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1052 3, 3, "",
1053 "Ask user to specify a window position and size on SCREEN with the mouse.\n\
1054 Arguments are SCREEN, NAME and GEO. NAME is a name to be displayed as\n\
1055 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1056 specify defaults for some sizes/positions. If GEO specifies everything,\n\
1057 the mouse is not used.\n\
1058 Returns a list of five values: (SCREEN LEFT TOP WIDTH HEIGHT).")
1059 (screen, name, geo)
1060 Lisp_Object screen;
1061 Lisp_Object name;
1062 Lisp_Object geo;
1064 int vals[4];
1065 Lisp_Object nums[4];
1066 int i;
1068 CHECK_SCREEN (screen, 0);
1069 CHECK_STRING (name, 1);
1070 CHECK_STRING (geo, 2);
1072 switch (XSCREEN (screen)->output_method)
1074 case output_x_window:
1075 x_rubber_band (XSCREEN (screen), &vals[0], &vals[1], &vals[2], &vals[3],
1076 XSTRING (geo)->data, XSTRING (name)->data);
1077 break;
1079 default:
1080 return Qnil;
1083 for (i = 0; i < 4; i++)
1084 XFASTINT (nums[i]) = vals[i];
1085 return Fcons (screen, Flist (4, nums));
1086 return Qnil;
1088 #endif /* not HAVE_X11 */
1090 choose_minibuf_screen ()
1092 /* For lowest-level minibuf, put it on currently selected screen
1093 if screen has a minibuffer. */
1094 if (minibuf_level == 0
1095 && selected_screen != 0
1096 && !EQ (minibuf_window, selected_screen->minibuffer_window)
1097 && !EQ (Qnil, selected_screen->minibuffer_window))
1099 Fset_window_buffer (selected_screen->minibuffer_window,
1100 XWINDOW (minibuf_window)->buffer);
1101 minibuf_window = selected_screen->minibuffer_window;
1105 syms_of_screen ()
1107 Qscreenp = intern ("screenp");
1108 Qlive_screen_p = intern ("live_screen_p");
1109 Qminibuffer = intern ("minibuffer");
1111 staticpro (&Qscreenp);
1112 staticpro (&Qlive_screen_p);
1113 staticpro (&Qminibuffer);
1115 staticpro (&Vscreen_list);
1117 DEFVAR_LISP ("terminal-screen", &Vterminal_screen,
1118 "The initial screen-object, which represents Emacs's stdout.");
1120 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1121 "Non-nil if all of emacs is iconified and screen updates are not needed.");
1122 Vemacs_iconified = Qnil;
1124 DEFVAR_LISP ("default-minibuffer-screen", &Vdefault_minibuffer_screen,
1125 "Minibufferless screens use this screen's minibuffer.\n\
1127 Emacs cannot create minibufferless screens unless this is set to an\n\
1128 appropriate surrogate.\n\
1130 Emacs consults this variable only when creating minibufferless\n\
1131 screens; once the screen is created, it sticks with its assigned\n\
1132 minibuffer, no matter what this variable is set to. This means that\n\
1133 this variable doesn't necessarily say anything meaningful about the\n\
1134 current set of screens, or where the minibuffer is currently being\n\
1135 displayed.");
1136 Vdefault_minibuffer_screen = Qnil;
1138 DEFVAR_LISP ("default-screen-alist", &Vdefault_screen_alist,
1139 "Alist of default values for screen creation.\n\
1140 These may be set in your init file, like this:\n\
1141 (setq default-screen-alist '((width . 80) (height . 55)))\n\
1142 These override values given in window system configuration data, like\n\
1143 X Windows' defaults database.\n\
1144 For values specific to the first emacs screen, see initial-screen-alist.\n\
1145 For values specific to the separate minibuffer screen, see\n\
1146 minibuffer-screen-alist.");
1147 Vdefault_screen_alist = Qnil;
1149 defsubr (&Sscreenp);
1150 defsubr (&Slive_screen_p);
1151 defsubr (&Sselect_screen);
1152 defsubr (&Sselected_screen);
1153 defsubr (&Swindow_screen);
1154 defsubr (&Sscreen_root_window);
1155 defsubr (&Sscreen_selected_window);
1156 defsubr (&Sscreen_list);
1157 defsubr (&Snext_screen);
1158 defsubr (&Sdelete_screen);
1159 defsubr (&Smouse_position);
1160 defsubr (&Sset_mouse_position);
1161 #if 0
1162 defsubr (&Sscreen_configuration);
1163 defsubr (&Srestore_screen_configuration);
1164 #endif
1165 defsubr (&Smake_screen_visible);
1166 defsubr (&Smake_screen_invisible);
1167 defsubr (&Siconify_screen);
1168 defsubr (&Sdeiconify_screen);
1169 defsubr (&Sscreen_visible_p);
1170 defsubr (&Svisible_screen_list);
1171 defsubr (&Sredirect_screen_focus);
1172 defsubr (&Sscreen_focus);
1173 defsubr (&Sscreen_parameters);
1174 defsubr (&Smodify_screen_parameters);
1175 defsubr (&Sscreen_pixel_size);
1176 defsubr (&Sscreen_height);
1177 defsubr (&Sscreen_width);
1178 defsubr (&Sset_screen_height);
1179 defsubr (&Sset_screen_width);
1180 defsubr (&Sset_screen_size);
1181 defsubr (&Sset_screen_position);
1182 #ifndef HAVE_X11
1183 defsubr (&Srubber_band_rectangle);
1184 #endif /* HAVE_X11 */