*** empty log message ***
[emacs.git] / src / frame.c
blob67c739505057b73948e14c4f90f1a691ce183fc2
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;
36 /* A screen which is not just a minibuffer, or 0 if there are no
37 such screens. This is usually the most recent such screen that
38 was selected. */
39 struct screen *last_nonminibuf_screen;
41 extern Lisp_Object Vminibuffer_list;
42 extern Lisp_Object get_minibuffer ();
44 DEFUN ("screenp", Fscreenp, Sscreenp, 1, 1, 0,
45 "Return non-nil if OBJECT is a screen.\n\
46 Value is t for a termcap screen (a character-only terminal),\n\
47 `x' for an Emacs screen that is really an X window.\n\
48 Also see live-screen-p.")
49 (object)
50 Lisp_Object object;
52 if (XTYPE (object) != Lisp_Screen)
53 return Qnil;
54 switch (XSCREEN (object)->output_method)
56 case output_termcap:
57 return Qt;
58 case output_x_window:
59 return intern ("x");
60 default:
61 abort ();
65 DEFUN ("live-screen-p", Flive_screen_p, Slive_screen_p, 1, 1, 0,
66 "Return non-nil if OBJECT is a screen which has not been deleted.\n\
67 Value is nil if OBJECT is not a live screen. If object is a live\n\
68 screen, the return value indicates what sort of output device it is\n\
69 displayed on. Value is t for a termcap screen (a character-only\n\
70 terminal), `x' for an Emacs screen being displayed in an X window.")
71 (object)
72 Lisp_Object object;
74 return ((SCREENP (object)
75 && SCREEN_LIVE_P (XSCREEN (object)))
76 ? Fscreenp (object)
77 : Qnil);
80 struct screen *
81 make_screen (mini_p)
82 int mini_p;
84 Lisp_Object screen;
85 register struct screen *s;
86 register Lisp_Object root_window;
87 register Lisp_Object mini_window;
89 screen = Fmake_vector (((sizeof (struct screen) - (sizeof (Lisp_Vector)
90 - sizeof (Lisp_Object)))
91 / sizeof (Lisp_Object)),
92 make_number (0));
93 XSETTYPE (screen, Lisp_Screen);
94 s = XSCREEN (screen);
96 s->cursor_x = 0;
97 s->cursor_y = 0;
98 s->current_glyphs = 0;
99 s->desired_glyphs = 0;
100 s->visible = 0;
101 s->display.nothing = 0;
102 s->iconified = 0;
103 s->wants_modeline = 1;
104 s->auto_raise = 0;
105 s->auto_lower = 0;
106 s->no_split = 0;
107 s->garbaged = 0;
108 s->has_minibuffer = mini_p;
109 s->focus_screen = screen;
111 s->param_alist = Qnil;
113 root_window = make_window (0);
114 if (mini_p)
116 mini_window = make_window (0);
117 XWINDOW (root_window)->next = mini_window;
118 XWINDOW (mini_window)->prev = root_window;
119 XWINDOW (mini_window)->mini_p = Qt;
120 XWINDOW (mini_window)->screen = screen;
121 s->minibuffer_window = mini_window;
123 else
125 mini_window = Qnil;
126 XWINDOW (root_window)->next = Qnil;
127 s->minibuffer_window = Qnil;
130 XWINDOW (root_window)->screen = screen;
132 /* 10 is arbitrary,
133 just so that there is "something there."
134 Correct size will be set up later with change_screen_size. */
136 s->width = 10;
137 s->height = 10;
139 XFASTINT (XWINDOW (root_window)->width) = 10;
140 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
142 if (mini_p)
144 XFASTINT (XWINDOW (mini_window)->width) = 10;
145 XFASTINT (XWINDOW (mini_window)->top) = 9;
146 XFASTINT (XWINDOW (mini_window)->height) = 1;
149 /* Choose a buffer for the screen's root window. */
151 Lisp_Object buf;
153 XWINDOW (root_window)->buffer = Qt;
154 buf = Fcurrent_buffer ();
155 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
156 a space), try to find another one. */
157 if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')
158 buf = Fother_buffer (buf);
159 Fset_window_buffer (root_window, buf);
162 if (mini_p)
164 XWINDOW (mini_window)->buffer = Qt;
165 Fset_window_buffer (mini_window,
166 (NILP (Vminibuffer_list)
167 ? get_minibuffer (0)
168 : Fcar (Vminibuffer_list)));
171 s->root_window = root_window;
172 s->selected_window = root_window;
173 /* Make sure this window seems more recently used than
174 a newly-created, never-selected window. */
175 XFASTINT (XWINDOW (s->selected_window)->use_time) = ++window_select_count;
177 Vscreen_list = Fcons (screen, Vscreen_list);
179 return s;
182 /* Make a screen using a separate minibuffer window on another screen.
183 MINI_WINDOW is the minibuffer window to use. nil means use the
184 default (the global minibuffer). */
186 struct screen *
187 make_screen_without_minibuffer (mini_window)
188 register Lisp_Object mini_window;
190 register struct screen *s;
192 /* Choose the minibuffer window to use. */
193 if (NILP (mini_window))
195 if (XTYPE (Vdefault_minibuffer_screen) != Lisp_Screen)
196 error ("default-minibuffer-screen must be set when creating minibufferless screens.");
197 mini_window = XSCREEN (Vdefault_minibuffer_screen)->minibuffer_window;
199 else
201 CHECK_WINDOW (mini_window, 0);
204 /* Make a screen containing just a root window. */
205 s = make_screen (0);
207 /* Install the chosen minibuffer window, with proper buffer. */
208 s->minibuffer_window = mini_window;
209 Fset_window_buffer (mini_window,
210 (NILP (Vminibuffer_list)
211 ? get_minibuffer (0)
212 : Fcar (Vminibuffer_list)));
213 return s;
216 /* Make a screen containing only a minibuffer window. */
218 struct screen *
219 make_minibuffer_screen ()
221 /* First make a screen containing just a root window, no minibuffer. */
223 register struct screen *s = make_screen (0);
224 register Lisp_Object mini_window;
225 register Lisp_Object screen;
227 XSET (screen, Lisp_Screen, s);
229 /* ??? Perhaps leave it to the user program to set auto_raise. */
230 s->auto_raise = 1;
231 s->auto_lower = 0;
232 s->no_split = 1;
233 s->wants_modeline = 0;
234 s->has_minibuffer = 1;
236 /* Now label the root window as also being the minibuffer.
237 Avoid infinite looping on the window chain by marking next pointer
238 as nil. */
240 mini_window = s->minibuffer_window = s->root_window;
241 XWINDOW (mini_window)->mini_p = Qt;
242 XWINDOW (mini_window)->next = Qnil;
243 XWINDOW (mini_window)->prev = mini_window;
244 XWINDOW (mini_window)->screen = screen;
246 /* Put the proper buffer in that window. */
248 Fset_window_buffer (mini_window,
249 (NILP (Vminibuffer_list)
250 ? get_minibuffer (0)
251 : Fcar (Vminibuffer_list)));
252 return s;
255 /* Construct a screen that refers to the terminal (stdin and stdout). */
257 struct screen *
258 make_terminal_screen ()
260 register struct screen *s;
262 Vscreen_list = Qnil;
263 s = make_screen (1);
264 s->name = build_string ("terminal");
265 s->visible = 1;
266 s->display.nothing = 1; /* Nonzero means screen isn't deleted. */
267 XSET (Vterminal_screen, Lisp_Screen, s);
268 return s;
271 DEFUN ("select-screen", Fselect_screen, Sselect_screen, 1, 2, 0,
272 "Select the screen S. S's selected window becomes \"the\"\n\
273 selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
274 focus on that screen.")
275 (screen, no_enter)
276 Lisp_Object screen, no_enter;
278 CHECK_LIVE_SCREEN (screen, 0);
280 if (selected_screen == XSCREEN (screen))
281 return screen;
283 selected_screen = XSCREEN (screen);
284 if (! SCREEN_MINIBUF_ONLY_P (selected_screen))
285 last_nonminibuf_screen = selected_screen;
287 Fselect_window (XSCREEN (screen)->selected_window);
289 #ifdef HAVE_X_WINDOWS
290 #ifdef MULTI_SCREEN
291 if (XSCREEN (screen)->output_method == output_x_window
292 && NILP (no_enter))
294 Ffocus_screen (screen);
296 #endif
297 #endif
298 choose_minibuf_screen ();
300 return screen;
303 DEFUN ("selected-screen", Fselected_screen, Sselected_screen, 0, 0, 0,
304 "Return the screen that is now selected.")
307 Lisp_Object tem;
308 XSET (tem, Lisp_Screen, selected_screen);
309 return tem;
312 DEFUN ("window-screen", Fwindow_screen, Swindow_screen, 1, 1, 0,
313 "Return the screen object that window WINDOW is on.")
314 (window)
315 Lisp_Object window;
317 CHECK_WINDOW (window, 0);
318 return XWINDOW (window)->screen;
321 DEFUN ("screen-root-window", Fscreen_root_window, Sscreen_root_window, 0, 1, 0,
322 "Returns the root-window of SCREEN.")
323 (screen)
324 Lisp_Object screen;
326 if (NILP (screen))
327 XSET (screen, Lisp_Screen, selected_screen);
328 else
329 CHECK_LIVE_SCREEN (screen, 0);
331 return XSCREEN (screen)->root_window;
334 DEFUN ("screen-selected-window", Fscreen_selected_window,
335 Sscreen_selected_window, 0, 1, 0,
336 "Return the selected window of screen object SCREEN.")
337 (screen)
338 Lisp_Object screen;
340 if (NILP (screen))
341 XSET (screen, Lisp_Screen, selected_screen);
342 else
343 CHECK_LIVE_SCREEN (screen, 0);
345 return XSCREEN (screen)->selected_window;
348 DEFUN ("screen-list", Fscreen_list, Sscreen_list,
349 0, 0, 0,
350 "Return a list of all screens.")
353 return Fcopy_sequence (Vscreen_list);
356 #ifdef MULTI_SCREEN
358 /* Return the next screen in the screen list after SCREEN.
359 If MINIBUF is non-nil, include all screens.
360 If MINIBUF is nil, exclude minibuffer-only screens.
361 If MINIBUF is a window, include only screens using that window for
362 their minibuffer. */
363 Lisp_Object
364 next_screen (screen, minibuf)
365 Lisp_Object screen;
366 Lisp_Object minibuf;
368 Lisp_Object tail;
369 int passed = 0;
371 /* There must always be at least one screen in Vscreen_list. */
372 if (! CONSP (Vscreen_list))
373 abort ();
375 while (1)
376 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
378 if (passed)
380 Lisp_Object s = XCONS (tail)->car;
382 /* Decide whether this screen is eligible to be returned,
383 according to minibuf. */
384 if ((NILP (minibuf) && ! SCREEN_MINIBUF_ONLY_P (XSCREEN (s)))
385 || XTYPE (minibuf) != Lisp_Window
386 || EQ (SCREEN_MINIBUF_WINDOW (XSCREEN (s)), minibuf)
387 || EQ (s, screen))
388 return s;
391 if (EQ (screen, XCONS (tail)->car))
392 passed++;
396 /* Return the previous screen in the screen list before SCREEN.
397 If MINIBUF is non-nil, include all screens.
398 If MINIBUF is nil, exclude minibuffer-only screens.
399 If MINIBUF is a window, include only screens using that window for
400 their minibuffer. */
401 Lisp_Object
402 prev_screen (screen, minibuf)
403 Lisp_Object screen;
404 Lisp_Object minibuf;
406 Lisp_Object tail;
407 Lisp_Object prev;
409 /* There must always be at least one screen in Vscreen_list. */
410 if (! CONSP (Vscreen_list))
411 abort ();
413 prev = Qnil;
414 while (1)
416 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
418 Lisp_Object scr = XCONS (tail)->car;
420 if (XTYPE (scr) != Lisp_Screen)
421 abort ();
423 if (EQ (screen, scr) && !NILP (prev))
424 return prev;
426 /* Decide whether this screen is eligible to be returned,
427 according to minibuf. */
428 if ((NILP (minibuf) && ! SCREEN_MINIBUF_ONLY_P (XSCREEN (scr)))
429 || XTYPE (minibuf) != Lisp_Window
430 || EQ (SCREEN_MINIBUF_WINDOW (XSCREEN (scr)), minibuf))
431 prev = scr;
434 if (NILP (prev))
435 /* We went through the whole screen list without finding a single
436 acceptable screen. Return the original screen. */
437 prev = screen;
442 DEFUN ("next-screen", Fnext_screen, Snext_screen, 0, 2, 0,
443 "Return the next screen in the screen list after SCREEN.\n\
444 If optional argument MINIBUF is non-nil, include all screens. If\n\
445 MINIBUF is nil or omitted, exclude minibuffer-only screens. If\n\
446 MINIBUF is a window, include only screens using that window for their\n\
447 minibuffer.")
448 (screen, miniscreen)
449 Lisp_Object screen, miniscreen;
451 Lisp_Object tail;
453 if (NILP (screen))
454 XSET (screen, Lisp_Screen, selected_screen);
455 else
456 CHECK_LIVE_SCREEN (screen, 0);
458 return next_screen (screen, miniscreen);
460 #endif /* MULTI_SCREEN */
462 DEFUN ("delete-screen", Fdelete_screen, Sdelete_screen, 0, 1, "",
463 "Delete SCREEN, permanently eliminating it from use.\n\
464 If omitted, SCREEN defaults to the selected screen.\n\
465 A screen may not be deleted if its minibuffer is used by other screens.")
466 (screen)
467 Lisp_Object screen;
469 struct screen *s;
470 union display displ;
472 if (EQ (screen, Qnil))
474 s = selected_screen;
475 XSET (screen, Lisp_Screen, s);
477 else
479 CHECK_SCREEN (screen, 0);
480 s = XSCREEN (screen);
483 if (! SCREEN_LIVE_P (s))
484 return;
486 /* Are there any other screens besides this one? */
487 if (s == selected_screen && EQ (next_screen (screen, Qt), screen))
488 error ("Attempt to delete the only screen");
490 /* Does this screen have a minibuffer, and is it the surrogate
491 minibuffer for any other screen? */
492 if (SCREEN_HAS_MINIBUF (XSCREEN (screen)))
494 Lisp_Object screen2;
496 for (screen2 = Vscreen_list; CONSP (2); screen2 = XCONS (screen2)->cdr)
497 if (! EQ (screen2, screen)
498 && EQ (screen,
499 (WINDOW_SCREEN
500 (XWINDOW
501 (SCREEN_MINIBUF_WINDOW
502 (XSCREEN (screen2)))))))
503 error ("Attempt to delete a surrogate minibuffer screen");
506 /* Don't let the screen remain selected. */
507 if (s == selected_screen)
508 Fselect_screen (next_screen (screen, Qt));
510 /* Don't allow minibuf_window to remain on a deleted screen. */
511 if (EQ (s->minibuffer_window, minibuf_window))
513 Fset_window_buffer (selected_screen->minibuffer_window,
514 XWINDOW (minibuf_window)->buffer);
515 minibuf_window = selected_screen->minibuffer_window;
518 Vscreen_list = Fdelq (screen, Vscreen_list);
519 s->visible = 0;
520 displ = s->display;
521 s->display.nothing = 0;
523 #ifdef HAVE_X_WINDOWS
524 if (s->output_method == output_x_window)
525 x_destroy_window (s, displ);
526 #endif
528 /* If we've deleted the last_nonminibuf_screen, then try to find
529 another one. */
530 if (s == last_nonminibuf_screen)
532 last_nonminibuf_screen = 0;
534 for (screen = Vscreen_list; CONSP (screen); screen = XCONS (screen)->cdr)
536 s = XSCREEN (XCONS (screen)->car);
537 if (!SCREEN_MINIBUF_ONLY_P (s))
539 last_nonminibuf_screen = s;
540 break;
545 return Qnil;
548 /* Return mouse position in character cell units. */
550 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
551 "Return a list (SCREEN X . Y) giving the current mouse screen and position.\n\
552 If Emacs is running on a mouseless terminal or hasn't been programmed\n\
553 to read the mouse position, it returns the selected screen for SCREEN\n\
554 and nil for X and Y.")
557 Lisp_Object x, y, dummy;
558 SCREEN_PTR s;
560 if (mouse_position_hook)
561 (*mouse_position_hook) (&s, &x, &y, &dummy);
562 else
564 s = selected_screen;
565 x = y = Qnil;
568 XSET (dummy, Lisp_Screen, s);
569 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
572 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
573 "Move the mouse pointer to the center of cell (X,Y) in SCREEN.\n\
574 WARNING: If you use this under X, you should do unfocus-screen afterwards.")
575 (screen, x, y)
576 Lisp_Object screen, x, y;
578 CHECK_LIVE_SCREEN (screen, 0);
579 CHECK_NUMBER (x, 2);
580 CHECK_NUMBER (y, 1);
582 #ifdef HAVE_X_WINDOWS
583 if (XSCREEN (screen)->output_method == output_x_window)
584 /* Warping the mouse will cause enternotify and focus events. */
585 x_set_mouse_position (XSCREEN (screen), x, y);
586 #endif
588 return Qnil;
591 #if 0
592 /* ??? Can this be replaced with a Lisp function?
593 It is used in minibuf.c. Can we get rid of that? */
595 DEFUN ("screen-configuration", Fscreen_configuration, Sscreen_configuration,
596 0, 0, 0,
597 "Return object describing current screen configuration.\n\
598 The screen configuration is the current mouse position and selected screen.\n\
599 This object can be given to `restore-screen-configuration'\n\
600 to restore this screen configuration.")
603 Lisp_Object c, time;
605 c = Fmake_vector (make_number(4), Qnil);
606 XVECTOR (c)->contents[0] = Fselected_screen();
607 if (mouse_position_hook)
608 (*mouse_position_hook) (&XVECTOR (c)->contents[1]
609 &XVECTOR (c)->contents[2],
610 &XVECTOR (c)->contents[3],
611 &time);
612 return c;
615 DEFUN ("restore-screen-configuration", Frestore_screen_configuration,
616 Srestore_screen_configuration,
617 1, 1, 0,
618 "Restores screen configuration CONFIGURATION.")
619 (config)
620 Lisp_Object config;
622 Lisp_Object x_pos, y_pos, screen;
624 CHECK_VECTOR (config, 0);
625 if (XVECTOR (config)->size != 3)
627 error ("Wrong size vector passed to restore-screen-configuration");
629 screen = XVECTOR (config)->contents[0];
630 CHECK_LIVE_SCREEN (screen, 0);
632 Fselect_screen (screen, Qnil);
634 #if 0
635 /* This seems to interfere with the screen selection mechanism. jla */
636 x_pos = XVECTOR (config)->contents[2];
637 y_pos = XVECTOR (config)->contents[3];
638 set_mouse_position (screen, XINT (x_pos), XINT (y_pos));
639 #endif
641 return screen;
643 #endif
645 DEFUN ("make-screen-visible", Fmake_screen_visible, Smake_screen_visible,
646 1, 1, 0,
647 "Make the screen SCREEN visible (assuming it is an X-window).\n\
648 Also raises the screen so that nothing obscures it.")
649 (screen)
650 Lisp_Object screen;
652 CHECK_LIVE_SCREEN (screen, 0);
654 if (XSCREEN (screen)->output_method == output_x_window)
655 x_make_screen_visible (XSCREEN (screen));
657 return screen;
660 DEFUN ("make-screen-invisible", Fmake_screen_invisible, Smake_screen_invisible,
661 1, 1, 0,
662 "Make the screen SCREEN invisible (assuming it is an X-window).")
663 (screen)
664 Lisp_Object screen;
666 CHECK_LIVE_SCREEN (screen, 0);
668 if (XSCREEN (screen)->output_method == output_x_window)
669 x_make_screen_invisible (XSCREEN (screen));
671 return Qnil;
674 DEFUN ("iconify-screen", Ficonify_screen, Siconify_screen,
675 1, 1, 0,
676 "Make the screen SCREEN into an icon.")
677 (screen)
678 Lisp_Object screen;
680 CHECK_LIVE_SCREEN (screen, 0);
682 if (XSCREEN (screen)->output_method == output_x_window)
683 x_iconify_screen (XSCREEN (screen));
685 return Qnil;
688 DEFUN ("deiconify-screen", Fdeiconify_screen, Sdeiconify_screen,
689 1, 1, 0,
690 "Open (de-iconify) the iconified screen SCREEN.")
691 (screen)
692 Lisp_Object screen;
694 CHECK_LIVE_SCREEN (screen, 0);
696 if (XSCREEN (screen)->output_method == output_x_window)
697 x_make_screen_visible (XSCREEN (screen));
699 return screen;
702 DEFUN ("screen-visible-p", Fscreen_visible_p, Sscreen_visible_p,
703 1, 1, 0,
704 "Return t if SCREEN is now \"visible\" (actually in use for display).\n\
705 A screen that is not \"visible\" is not updated and, if it works through\n\
706 a window system, it may not show at all.\n\
707 Return the symbol `icon' if window is visible only as an icon.")
708 (screen)
709 Lisp_Object screen;
711 CHECK_LIVE_SCREEN (screen, 0);
713 if (XSCREEN (screen)->visible)
714 return Qt;
715 if (XSCREEN (screen)->iconified)
716 return intern ("icon");
717 return Qnil;
720 DEFUN ("visible-screen-list", Fvisible_screen_list, Svisible_screen_list,
721 0, 0, 0,
722 "Return a list of all screens now \"visible\" (being updated).")
725 Lisp_Object tail, screen;
726 struct screen *s;
727 Lisp_Object value;
729 value = Qnil;
730 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
732 screen = XCONS (tail)->car;
733 if (XTYPE (screen) != Lisp_Screen)
734 continue;
735 s = XSCREEN (screen);
736 if (s->visible)
737 value = Fcons (screen, value);
739 return value;
744 DEFUN ("redirect-screen-focus", Fredirect_screen_focus, Sredirect_screen_focus,
745 1, 2, 0,
746 "Arrange for keystrokes typed at SCREEN to be sent to FOCUS-SCREEN.\n\
747 This means that, after reading a keystroke typed at SCREEN,\n\
748 last-event-screen will be FOCUS-SCREEN.\n\
750 If FOCUS-SCREEN is omitted or eq to SCREEN, any existing redirection is\n\
751 cancelled, and the screen again receives its own keystrokes.\n\
753 The redirection lasts until the next call to redirect-screen-focus\n\
754 or select-screen.\n\
756 This is useful for temporarily redirecting keystrokes to the minibuffer\n\
757 window when a screen doesn't have its own minibuffer.")
758 (screen, focus_screen)
759 Lisp_Object screen, focus_screen;
761 CHECK_LIVE_SCREEN (screen, 0);
763 if (NILP (focus_screen))
764 focus_screen = screen;
765 else
766 CHECK_LIVE_SCREEN (focus_screen, 1);
768 XSCREEN (screen)->focus_screen = focus_screen;
770 if (screen_rehighlight_hook)
771 (*screen_rehighlight_hook) ();
773 return Qnil;
777 DEFUN ("screen-focus", Fscreen_focus, Sscreen_focus, 1, 1, 0,
778 "Return the screen to which SCREEN's keystrokes are currently being sent.\n\
779 See redirect-screen-focus.")
780 (screen)
781 Lisp_Object screen;
783 CHECK_LIVE_SCREEN (screen, 0);
784 return SCREEN_FOCUS_SCREEN (XSCREEN (screen));
789 Lisp_Object
790 get_screen_param (screen, prop)
791 register struct screen *screen;
792 Lisp_Object prop;
794 register Lisp_Object tem;
796 tem = Fassq (prop, screen->param_alist);
797 if (EQ (tem, Qnil))
798 return tem;
799 return Fcdr (tem);
802 void
803 store_in_alist (alistptr, propname, val)
804 Lisp_Object *alistptr, val;
805 char *propname;
807 register Lisp_Object tem;
808 register Lisp_Object prop;
810 prop = intern (propname);
811 tem = Fassq (prop, *alistptr);
812 if (EQ (tem, Qnil))
813 *alistptr = Fcons (Fcons (prop, val), *alistptr);
814 else
815 Fsetcdr (tem, val);
818 void
819 store_screen_param (s, prop, val)
820 struct screen *s;
821 Lisp_Object prop, val;
823 register Lisp_Object tem;
825 tem = Fassq (prop, s->param_alist);
826 if (EQ (tem, Qnil))
827 s->param_alist = Fcons (Fcons (prop, val), s->param_alist);
828 else
829 Fsetcdr (tem, val);
832 DEFUN ("screen-parameters", Fscreen_parameters, Sscreen_parameters, 0, 1, 0,
833 "Return the parameters-alist of screen SCREEN.\n\
834 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
835 The meaningful PARMs depend on the kind of screen.")
836 (screen)
837 Lisp_Object screen;
839 Lisp_Object alist;
840 struct screen *s;
842 if (EQ (screen, Qnil))
843 s = selected_screen;
844 else
846 CHECK_SCREEN (screen, 0);
847 s = XSCREEN (screen);
850 if (s->display.nothing == 0)
851 return Qnil;
853 alist = Fcopy_alist (s->param_alist);
854 store_in_alist (&alist, "name", s->name);
855 store_in_alist (&alist, "height", make_number (s->height));
856 store_in_alist (&alist, "width", make_number (s->width));
857 store_in_alist (&alist, "modeline", (s->wants_modeline ? Qt : Qnil));
858 store_in_alist (&alist, "minibuffer",
859 (SCREEN_HAS_MINIBUF (s)
860 ? (SCREEN_MINIBUF_ONLY_P (s) ? intern ("only") : Qt)
861 : Qnil));
862 store_in_alist (&alist, "unsplittable", (s->no_split ? Qt : Qnil));
864 if (s->output_method == output_x_window)
865 x_report_screen_params (s, &alist);
866 return alist;
869 DEFUN ("modify-screen-parameters", Fmodify_screen_parameters,
870 Smodify_screen_parameters, 2, 2, 0,
871 "Modify the parameters of screen SCREEN according to ALIST.\n\
872 ALIST is an alist of parameters to change and their new values.\n\
873 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
874 The meaningful PARMs depend on the kind of screen; undefined PARMs are ignored.")
875 (screen, alist)
876 Lisp_Object screen, alist;
878 register struct screen *s;
879 register Lisp_Object tail, elt, prop, val;
881 if (EQ (screen, Qnil))
882 s = selected_screen;
883 else
885 CHECK_LIVE_SCREEN (screen, 0);
886 s = XSCREEN (screen);
889 if (s->output_method == output_x_window)
890 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
892 elt = Fcar (tail);
893 prop = Fcar (elt);
894 val = Fcdr (elt);
895 x_set_screen_param (s, prop, val,
896 get_screen_param (s, prop));
897 store_screen_param (s, prop, val);
900 return Qnil;
904 DEFUN ("screen-pixel-size", Fscreen_pixel_size,
905 Sscreen_pixel_size, 1, 1, 0,
906 "Return a cons (width . height) of SCREEN's size in pixels.")
907 (screen)
908 Lisp_Object screen;
910 register struct screen *s;
911 int width, height;
913 CHECK_LIVE_SCREEN (screen, 0);
914 s = XSCREEN (screen);
916 return Fcons (make_number (x_pixel_width (s)),
917 make_number (x_pixel_height (s)));
920 DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0,
921 "Return number of lines available for display on selected screen.")
924 return make_number (SCREEN_HEIGHT (selected_screen));
927 DEFUN ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0,
928 "Return number of columns available for display on selected screen.")
931 return make_number (SCREEN_WIDTH (selected_screen));
934 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 2, 3, 0,
935 "Specify that the screen SCREEN has LINES lines.\n\
936 Optional third arg non-nil means that redisplay should use LINES lines\n\
937 but that the idea of the actual height of the screen should not be changed.")
938 (screen, rows, pretend)
939 Lisp_Object rows, pretend;
941 register struct screen *s;
943 CHECK_NUMBER (rows, 0);
944 if (NILP (screen))
945 s = selected_screen;
946 else
948 CHECK_LIVE_SCREEN (screen, 0);
949 s = XSCREEN (screen);
952 if (s->output_method == output_x_window)
954 if (XINT (rows) != s->width)
955 x_set_window_size (s, s->width, XINT (rows));
957 else
958 change_screen_size (s, XINT (rows), 0, !NILP (pretend));
959 return Qnil;
962 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 2, 3, 0,
963 "Specify that the screen SCREEN has COLS columns.\n\
964 Optional third arg non-nil means that redisplay should use COLS columns\n\
965 but that the idea of the actual width of the screen should not be changed.")
966 (screen, cols, pretend)
967 Lisp_Object cols, pretend;
969 register struct screen *s;
970 CHECK_NUMBER (cols, 0);
971 if (NILP (screen))
972 s = selected_screen;
973 else
975 CHECK_LIVE_SCREEN (screen, 0);
976 s = XSCREEN (screen);
979 if (s->output_method == output_x_window)
981 if (XINT (cols) != s->width)
982 x_set_window_size (s, XINT (cols), s->height);
984 else
985 change_screen_size (selected_screen, 0, XINT (cols), !NILP (pretend));
986 return Qnil;
989 DEFUN ("set-screen-size", Fset_screen_size, Sset_screen_size, 3, 3, 0,
990 "Sets size of SCREEN to COLS by ROWS, measured in characters.")
991 (screen, cols, rows)
992 Lisp_Object screen, cols, rows;
994 register struct screen *s;
995 int mask;
997 CHECK_LIVE_SCREEN (screen, 0);
998 CHECK_NUMBER (cols, 2);
999 CHECK_NUMBER (rows, 1);
1000 s = XSCREEN (screen);
1002 if (s->output_method == output_x_window)
1004 if (XINT (rows) != s->height || XINT (cols) != s->width)
1005 x_set_window_size (s, XINT (cols), XINT (rows));
1007 else
1008 change_screen_size (s, XINT (rows), XINT (cols), 0);
1010 return Qnil;
1013 DEFUN ("set-screen-position", Fset_screen_position,
1014 Sset_screen_position, 3, 3, 0,
1015 "Sets position of SCREEN in pixels to XOFFSET by YOFFSET.\n\
1016 If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1017 the leftmost or bottommost position SCREEN could occupy without going\n\
1018 off the screen.")
1019 (screen, xoffset, yoffset)
1020 Lisp_Object screen, xoffset, yoffset;
1022 register struct screen *s;
1023 int mask;
1025 CHECK_LIVE_SCREEN (screen, 0);
1026 CHECK_NUMBER (xoffset, 1);
1027 CHECK_NUMBER (yoffset, 2);
1028 s = XSCREEN (screen);
1030 if (s->output_method == output_x_window)
1031 x_set_offset (s, XINT (xoffset), XINT (yoffset));
1033 return Qt;
1036 #ifndef HAVE_X11
1037 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
1038 3, 3, "",
1039 "Ask user to specify a window position and size on SCREEN with the mouse.\n\
1040 Arguments are SCREEN, NAME and GEO. NAME is a name to be displayed as\n\
1041 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1042 specify defaults for some sizes/positions. If GEO specifies everything,\n\
1043 the mouse is not used.\n\
1044 Returns a list of five values: (SCREEN LEFT TOP WIDTH HEIGHT).")
1045 (screen, name, geo)
1046 Lisp_Object screen;
1047 Lisp_Object name;
1048 Lisp_Object geo;
1050 int vals[4];
1051 Lisp_Object nums[4];
1052 int i;
1054 CHECK_SCREEN (screen, 0);
1055 CHECK_STRING (name, 1);
1056 CHECK_STRING (geo, 2);
1058 switch (XSCREEN (screen)->output_method)
1060 case output_x_window:
1061 x_rubber_band (XSCREEN (screen), &vals[0], &vals[1], &vals[2], &vals[3],
1062 XSTRING (geo)->data, XSTRING (name)->data);
1063 break;
1065 default:
1066 return Qnil;
1069 for (i = 0; i < 4; i++)
1070 XFASTINT (nums[i]) = vals[i];
1071 return Fcons (screen, Flist (4, nums));
1072 return Qnil;
1074 #endif /* not HAVE_X11 */
1076 choose_minibuf_screen ()
1078 /* For lowest-level minibuf, put it on currently selected screen
1079 if screen has a minibuffer. */
1080 if (minibuf_level == 0
1081 && selected_screen != 0
1082 && !EQ (minibuf_window, selected_screen->minibuffer_window)
1083 && !EQ (Qnil, selected_screen->minibuffer_window))
1085 Fset_window_buffer (selected_screen->minibuffer_window,
1086 XWINDOW (minibuf_window)->buffer);
1087 minibuf_window = selected_screen->minibuffer_window;
1091 syms_of_screen ()
1093 Qscreenp = intern ("screenp");
1094 Qlive_screen_p = intern ("live_screen_p");
1096 staticpro (&Qscreenp);
1097 staticpro (&Qlive_screen_p);
1099 staticpro (&Vscreen_list);
1101 DEFVAR_LISP ("terminal-screen", &Vterminal_screen,
1102 "The initial screen-object, which represents Emacs's stdout.");
1104 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1105 "Non-nil if all of emacs is iconified and screen updates are not needed.");
1106 Vemacs_iconified = Qnil;
1108 DEFVAR_LISP ("default-minibuffer-screen", &Vdefault_minibuffer_screen,
1109 "Minibufferless screens use this screen's minibuffer.\n\
1111 Emacs cannot create minibufferless screens unless this is set to an\n\
1112 appropriate surrogate.\n\
1114 Emacs consults this variable only when creating minibufferless\n\
1115 screens; once the screen is created, it sticks with its assigned\n\
1116 minibuffer, no matter what this variable is set to. This means that\n\
1117 this variable doesn't necessarily say anything meaningful about the\n\
1118 current set of screens, or where the minibuffer is currently being\n\
1119 displayed.");
1120 Vdefault_minibuffer_screen = Qnil;
1122 DEFVAR_LISP ("default-screen-alist", &Vdefault_screen_alist,
1123 "Alist of default values for screen creation.\n\
1124 These may be set in your init file, like this:\n\
1125 (setq default-screen-alist '((width . 80) (height . 55)))\n\
1126 These override values given in window system configuration data, like\n\
1127 X Windows' defaults database.\n\
1128 For values specific to the first emacs screen, see initial-screen-alist.\n\
1129 For values specific to the separate minibuffer screen, see\n\
1130 minibuffer-screen-alist.");
1131 Vdefault_screen_alist = Qnil;
1133 defsubr (&Sscreenp);
1134 defsubr (&Slive_screen_p);
1135 defsubr (&Sselect_screen);
1136 defsubr (&Sselected_screen);
1137 defsubr (&Swindow_screen);
1138 defsubr (&Sscreen_root_window);
1139 defsubr (&Sscreen_selected_window);
1140 defsubr (&Sscreen_list);
1141 defsubr (&Snext_screen);
1142 defsubr (&Sdelete_screen);
1143 defsubr (&Smouse_position);
1144 defsubr (&Sset_mouse_position);
1145 #if 0
1146 defsubr (&Sscreen_configuration);
1147 defsubr (&Srestore_screen_configuration);
1148 #endif
1149 defsubr (&Smake_screen_visible);
1150 defsubr (&Smake_screen_invisible);
1151 defsubr (&Siconify_screen);
1152 defsubr (&Sdeiconify_screen);
1153 defsubr (&Sscreen_visible_p);
1154 defsubr (&Svisible_screen_list);
1155 defsubr (&Sredirect_screen_focus);
1156 defsubr (&Sscreen_focus);
1157 defsubr (&Sscreen_parameters);
1158 defsubr (&Smodify_screen_parameters);
1159 defsubr (&Sscreen_pixel_size);
1160 defsubr (&Sscreen_height);
1161 defsubr (&Sscreen_width);
1162 defsubr (&Sset_screen_height);
1163 defsubr (&Sset_screen_width);
1164 defsubr (&Sset_screen_size);
1165 defsubr (&Sset_screen_position);
1166 #ifndef HAVE_X11
1167 defsubr (&Srubber_band_rectangle);
1168 #endif /* HAVE_X11 */