*** empty log message ***
[bpt/emacs.git] / src / frame.c
1 /* Generic screen functions.
2 Copyright (C) 1989 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 1, 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 <stdio.h>
21
22 #include "config.h"
23 #include "lisp.h"
24 #include "screen.h"
25 #include "window.h"
26 #include "termhooks.h"
27
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;
36
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;
41
42 extern Lisp_Object Vminibuffer_list;
43 extern Lisp_Object get_minibuffer ();
44 \f
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;
52 {
53 if (XTYPE (object) != Lisp_Screen)
54 return Qnil;
55 switch (XSCREEN (object)->output_method)
56 {
57 case output_termcap:
58 return Qt;
59 case output_x_window:
60 return intern ("x");
61 default:
62 abort ();
63 }
64 }
65
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;
74 {
75 return ((SCREENP (object)
76 && SCREEN_LIVE_P (XSCREEN (object)))
77 ? Fscreenp (object)
78 : Qnil);
79 }
80
81 struct screen *
82 make_screen (mini_p)
83 int mini_p;
84 {
85 Lisp_Object screen;
86 register struct screen *s;
87 register Lisp_Object root_window;
88 register Lisp_Object mini_window;
89
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);
96
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;
111
112 s->param_alist = Qnil;
113
114 root_window = make_window (0);
115 if (mini_p)
116 {
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;
123 }
124 else
125 {
126 mini_window = Qnil;
127 XWINDOW (root_window)->next = Qnil;
128 s->minibuffer_window = Qnil;
129 }
130
131 XWINDOW (root_window)->screen = screen;
132
133 /* 10 is arbitrary,
134 just so that there is "something there."
135 Correct size will be set up later with change_screen_size. */
136
137 s->width = 10;
138 s->height = 10;
139
140 XFASTINT (XWINDOW (root_window)->width) = 10;
141 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
142
143 if (mini_p)
144 {
145 XFASTINT (XWINDOW (mini_window)->width) = 10;
146 XFASTINT (XWINDOW (mini_window)->top) = 9;
147 XFASTINT (XWINDOW (mini_window)->height) = 1;
148 }
149
150 /* Choose a buffer for the screen's root window. */
151 {
152 Lisp_Object buf;
153
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);
161 }
162
163 if (mini_p)
164 {
165 XWINDOW (mini_window)->buffer = Qt;
166 Fset_window_buffer (mini_window,
167 (NILP (Vminibuffer_list)
168 ? get_minibuffer (0)
169 : Fcar (Vminibuffer_list)));
170 }
171
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;
177
178 Vscreen_list = Fcons (screen, Vscreen_list);
179
180 return s;
181 }
182 \f
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). */
186
187 struct screen *
188 make_screen_without_minibuffer (mini_window)
189 register Lisp_Object mini_window;
190 {
191 register struct screen *s;
192
193 /* Choose the minibuffer window to use. */
194 if (NILP (mini_window))
195 {
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;
199 }
200 else
201 {
202 CHECK_WINDOW (mini_window, 0);
203 }
204
205 /* Make a screen containing just a root window. */
206 s = make_screen (0);
207
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;
215 }
216
217 /* Make a screen containing only a minibuffer window. */
218
219 struct screen *
220 make_minibuffer_screen ()
221 {
222 /* First make a screen containing just a root window, no minibuffer. */
223
224 register struct screen *s = make_screen (0);
225 register Lisp_Object mini_window;
226 register Lisp_Object screen;
227
228 XSET (screen, Lisp_Screen, s);
229
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;
236
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. */
240
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;
246
247 /* Put the proper buffer in that window. */
248
249 Fset_window_buffer (mini_window,
250 (NILP (Vminibuffer_list)
251 ? get_minibuffer (0)
252 : Fcar (Vminibuffer_list)));
253 return s;
254 }
255 \f
256 /* Construct a screen that refers to the terminal (stdin and stdout). */
257
258 struct screen *
259 make_terminal_screen ()
260 {
261 register struct screen *s;
262
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;
270 }
271 \f
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;
278 {
279 CHECK_LIVE_SCREEN (screen, 0);
280
281 if (selected_screen == XSCREEN (screen))
282 return screen;
283
284 selected_screen = XSCREEN (screen);
285 if (! SCREEN_MINIBUF_ONLY_P (selected_screen))
286 last_nonminibuf_screen = selected_screen;
287
288 Fselect_window (XSCREEN (screen)->selected_window);
289
290 #ifdef HAVE_X_WINDOWS
291 #ifdef MULTI_SCREEN
292 if (SCREEN_IS_X (XSCREEN (screen))
293 && NILP (no_enter))
294 {
295 Ffocus_screen (screen);
296 }
297 #endif
298 #endif
299 choose_minibuf_screen ();
300
301 return screen;
302 }
303
304 DEFUN ("selected-screen", Fselected_screen, Sselected_screen, 0, 0, 0,
305 "Return the screen that is now selected.")
306 ()
307 {
308 Lisp_Object tem;
309 XSET (tem, Lisp_Screen, selected_screen);
310 return tem;
311 }
312
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;
317 {
318 CHECK_WINDOW (window, 0);
319 return XWINDOW (window)->screen;
320 }
321
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;
326 {
327 if (NILP (screen))
328 XSET (screen, Lisp_Screen, selected_screen);
329 else
330 CHECK_LIVE_SCREEN (screen, 0);
331
332 return XSCREEN (screen)->root_window;
333 }
334
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;
340 {
341 if (NILP (screen))
342 XSET (screen, Lisp_Screen, selected_screen);
343 else
344 CHECK_LIVE_SCREEN (screen, 0);
345
346 return XSCREEN (screen)->selected_window;
347 }
348
349 DEFUN ("screen-list", Fscreen_list, Sscreen_list,
350 0, 0, 0,
351 "Return a list of all screens.")
352 ()
353 {
354 return Fcopy_sequence (Vscreen_list);
355 }
356
357 #ifdef MULTI_SCREEN
358
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;
368 {
369 Lisp_Object tail;
370 int passed = 0;
371
372 /* There must always be at least one screen in Vscreen_list. */
373 if (! CONSP (Vscreen_list))
374 abort ();
375
376 while (1)
377 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
378 {
379 if (passed)
380 {
381 Lisp_Object s = XCONS (tail)->car;
382
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;
390 }
391
392 if (EQ (screen, XCONS (tail)->car))
393 passed++;
394 }
395 }
396
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;
406 {
407 Lisp_Object tail;
408 Lisp_Object prev;
409
410 /* There must always be at least one screen in Vscreen_list. */
411 if (! CONSP (Vscreen_list))
412 abort ();
413
414 prev = Qnil;
415 while (1)
416 {
417 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
418 {
419 Lisp_Object scr = XCONS (tail)->car;
420
421 if (XTYPE (scr) != Lisp_Screen)
422 abort ();
423
424 if (EQ (screen, scr) && !NILP (prev))
425 return prev;
426
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;
433 }
434
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;
439 }
440
441 }
442
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;
451 {
452 Lisp_Object tail;
453
454 if (NILP (screen))
455 XSET (screen, Lisp_Screen, selected_screen);
456 else
457 CHECK_LIVE_SCREEN (screen, 0);
458
459 return next_screen (screen, miniscreen);
460 }
461 #endif /* MULTI_SCREEN */
462 \f
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;
469 {
470 struct screen *s;
471 union display displ;
472
473 if (EQ (screen, Qnil))
474 {
475 s = selected_screen;
476 XSET (screen, Lisp_Screen, s);
477 }
478 else
479 {
480 CHECK_SCREEN (screen, 0);
481 s = XSCREEN (screen);
482 }
483
484 if (! SCREEN_LIVE_P (s))
485 return;
486
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");
490
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)))
494 {
495 Lisp_Object screen2;
496
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");
505 }
506
507 /* Don't let the screen remain selected. */
508 if (s == selected_screen)
509 Fselect_screen (next_screen (screen, Qt));
510
511 /* Don't allow minibuf_window to remain on a deleted screen. */
512 if (EQ (s->minibuffer_window, minibuf_window))
513 {
514 Fset_window_buffer (selected_screen->minibuffer_window,
515 XWINDOW (minibuf_window)->buffer);
516 minibuf_window = selected_screen->minibuffer_window;
517 }
518
519 Vscreen_list = Fdelq (screen, Vscreen_list);
520 s->visible = 0;
521 displ = s->display;
522 s->display.nothing = 0;
523
524 #ifdef HAVE_X_WINDOWS
525 if (SCREEN_IS_X (s))
526 x_destroy_window (s, displ);
527 #endif
528
529 /* If we've deleted the last_nonminibuf_screen, then try to find
530 another one. */
531 if (s == last_nonminibuf_screen)
532 {
533 last_nonminibuf_screen = 0;
534
535 for (screen = Vscreen_list; CONSP (screen); screen = XCONS (screen)->cdr)
536 {
537 s = XSCREEN (XCONS (screen)->car);
538 if (!SCREEN_MINIBUF_ONLY_P (s))
539 {
540 last_nonminibuf_screen = s;
541 break;
542 }
543 }
544 }
545
546 return Qnil;
547 }
548 \f
549 /* Return mouse position in character cell units. */
550
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.")
556 ()
557 {
558 Lisp_Object x, y, dummy;
559 SCREEN_PTR s;
560
561 if (mouse_position_hook)
562 (*mouse_position_hook) (&s, &x, &y, &dummy);
563 else
564 {
565 s = selected_screen;
566 x = y = Qnil;
567 }
568
569 XSET (dummy, Lisp_Screen, s);
570 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
571 }
572
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;
578 {
579 CHECK_LIVE_SCREEN (screen, 0);
580 CHECK_NUMBER (x, 2);
581 CHECK_NUMBER (y, 1);
582
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
588
589 return Qnil;
590 }
591 \f
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? */
595
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.")
602 ()
603 {
604 Lisp_Object c, time;
605
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;
614 }
615
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;
622 {
623 Lisp_Object x_pos, y_pos, screen;
624
625 CHECK_VECTOR (config, 0);
626 if (XVECTOR (config)->size != 3)
627 {
628 error ("Wrong size vector passed to restore-screen-configuration");
629 }
630 screen = XVECTOR (config)->contents[0];
631 CHECK_LIVE_SCREEN (screen, 0);
632
633 Fselect_screen (screen, Qnil);
634
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
641
642 return screen;
643 }
644 #endif
645 \f
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;
652 {
653 CHECK_LIVE_SCREEN (screen, 0);
654
655 if (SCREEN_IS_X (XSCREEN (screen)))
656 x_make_screen_visible (XSCREEN (screen));
657
658 return screen;
659 }
660
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;
666 {
667 CHECK_LIVE_SCREEN (screen, 0);
668
669 if (SCREEN_IS_X (XSCREEN (screen)))
670 x_make_screen_invisible (XSCREEN (screen));
671
672 return Qnil;
673 }
674
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;
680 {
681 CHECK_LIVE_SCREEN (screen, 0);
682
683 if (SCREEN_IS_X (XSCREEN (screen)))
684 x_iconify_screen (XSCREEN (screen));
685
686 return Qnil;
687 }
688
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;
694 {
695 CHECK_LIVE_SCREEN (screen, 0);
696
697 if (SCREEN_IS_X (XSCREEN (screen)))
698 x_make_screen_visible (XSCREEN (screen));
699
700 return screen;
701 }
702
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;
711 {
712 CHECK_LIVE_SCREEN (screen, 0);
713
714 if (XSCREEN (screen)->visible)
715 return Qt;
716 if (XSCREEN (screen)->iconified)
717 return intern ("icon");
718 return Qnil;
719 }
720
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).")
724 ()
725 {
726 Lisp_Object tail, screen;
727 struct screen *s;
728 Lisp_Object value;
729
730 value = Qnil;
731 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
732 {
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);
739 }
740 return value;
741 }
742
743
744 \f
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\
750 \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\
753 \n\
754 The redirection lasts until the next call to redirect-screen-focus\n\
755 or select-screen.\n\
756 \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;
761 {
762 CHECK_LIVE_SCREEN (screen, 0);
763
764 if (NILP (focus_screen))
765 focus_screen = screen;
766 else
767 CHECK_LIVE_SCREEN (focus_screen, 1);
768
769 XSCREEN (screen)->focus_screen = focus_screen;
770
771 if (screen_rehighlight_hook)
772 (*screen_rehighlight_hook) ();
773
774 return Qnil;
775 }
776
777
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;
783 {
784 CHECK_LIVE_SCREEN (screen, 0);
785 return SCREEN_FOCUS_SCREEN (XSCREEN (screen));
786 }
787
788
789 \f
790 Lisp_Object
791 get_screen_param (screen, prop)
792 register struct screen *screen;
793 Lisp_Object prop;
794 {
795 register Lisp_Object tem;
796
797 tem = Fassq (prop, screen->param_alist);
798 if (EQ (tem, Qnil))
799 return tem;
800 return Fcdr (tem);
801 }
802
803 void
804 store_in_alist (alistptr, propname, val)
805 Lisp_Object *alistptr, val;
806 char *propname;
807 {
808 register Lisp_Object tem;
809 register Lisp_Object prop;
810
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);
817 }
818
819 void
820 store_screen_param (s, prop, val)
821 struct screen *s;
822 Lisp_Object prop, val;
823 {
824 register Lisp_Object tem;
825
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);
831
832 if (EQ (prop, Qminibuffer)
833 && XTYPE (val) == Lisp_Window)
834 {
835 if (! MINI_WINDOW_P (XWINDOW (val)))
836 error ("Surrogate minibuffer windows must be minibuffer windows.");
837
838 if (SCREEN_HAS_MINIBUF (s) || SCREEN_MINIBUF_ONLY_P (s))
839 error ("Can't change surrogate minibuffer on screens with their own minibuffers.");
840
841 /* Install the chosen minibuffer window, with proper buffer. */
842 s->minibuffer_window = val;
843 }
844 }
845
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;
852 {
853 Lisp_Object alist;
854 struct screen *s;
855
856 if (EQ (screen, Qnil))
857 s = selected_screen;
858 else
859 {
860 CHECK_SCREEN (screen, 0);
861 s = XSCREEN (screen);
862 }
863
864 if (s->display.nothing == 0)
865 return Qnil;
866
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));
877
878 if (SCREEN_IS_X (s))
879 x_report_screen_params (s, &alist);
880 return alist;
881 }
882
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;
891 {
892 register struct screen *s;
893 register Lisp_Object tail, elt, prop, val;
894
895 if (EQ (screen, Qnil))
896 s = selected_screen;
897 else
898 {
899 CHECK_LIVE_SCREEN (screen, 0);
900 s = XSCREEN (screen);
901 }
902
903 if (SCREEN_IS_X (s))
904 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
905 {
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);
912 }
913
914 return Qnil;
915 }
916 \f
917
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;
923 {
924 register struct screen *s;
925 int width, height;
926
927 CHECK_LIVE_SCREEN (screen, 0);
928 s = XSCREEN (screen);
929
930 return Fcons (make_number (x_pixel_width (s)),
931 make_number (x_pixel_height (s)));
932 }
933
934 DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0,
935 "Return number of lines available for display on selected screen.")
936 ()
937 {
938 return make_number (SCREEN_HEIGHT (selected_screen));
939 }
940
941 DEFUN ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0,
942 "Return number of columns available for display on selected screen.")
943 ()
944 {
945 return make_number (SCREEN_WIDTH (selected_screen));
946 }
947
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;
954 {
955 register struct screen *s;
956
957 CHECK_NUMBER (rows, 0);
958 if (NILP (screen))
959 s = selected_screen;
960 else
961 {
962 CHECK_LIVE_SCREEN (screen, 0);
963 s = XSCREEN (screen);
964 }
965
966 if (SCREEN_IS_X (s))
967 {
968 if (XINT (rows) != s->width)
969 x_set_window_size (s, s->width, XINT (rows));
970 }
971 else
972 change_screen_size (s, XINT (rows), 0, !NILP (pretend));
973 return Qnil;
974 }
975
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;
982 {
983 register struct screen *s;
984 CHECK_NUMBER (cols, 0);
985 if (NILP (screen))
986 s = selected_screen;
987 else
988 {
989 CHECK_LIVE_SCREEN (screen, 0);
990 s = XSCREEN (screen);
991 }
992
993 if (SCREEN_IS_X (s))
994 {
995 if (XINT (cols) != s->width)
996 x_set_window_size (s, XINT (cols), s->height);
997 }
998 else
999 change_screen_size (selected_screen, 0, XINT (cols), !NILP (pretend));
1000 return Qnil;
1001 }
1002
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;
1007 {
1008 register struct screen *s;
1009 int mask;
1010
1011 CHECK_LIVE_SCREEN (screen, 0);
1012 CHECK_NUMBER (cols, 2);
1013 CHECK_NUMBER (rows, 1);
1014 s = XSCREEN (screen);
1015
1016 if (SCREEN_IS_X (s))
1017 {
1018 if (XINT (rows) != s->height || XINT (cols) != s->width)
1019 x_set_window_size (s, XINT (cols), XINT (rows));
1020 }
1021 else
1022 change_screen_size (s, XINT (rows), XINT (cols), 0);
1023
1024 return Qnil;
1025 }
1026
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;
1035 {
1036 register struct screen *s;
1037 int mask;
1038
1039 CHECK_LIVE_SCREEN (screen, 0);
1040 CHECK_NUMBER (xoffset, 1);
1041 CHECK_NUMBER (yoffset, 2);
1042 s = XSCREEN (screen);
1043
1044 if (SCREEN_IS_X (s))
1045 x_set_offset (s, XINT (xoffset), XINT (yoffset));
1046
1047 return Qt;
1048 }
1049 \f
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;
1063 {
1064 int vals[4];
1065 Lisp_Object nums[4];
1066 int i;
1067
1068 CHECK_SCREEN (screen, 0);
1069 CHECK_STRING (name, 1);
1070 CHECK_STRING (geo, 2);
1071
1072 switch (XSCREEN (screen)->output_method)
1073 {
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;
1078
1079 default:
1080 return Qnil;
1081 }
1082
1083 for (i = 0; i < 4; i++)
1084 XFASTINT (nums[i]) = vals[i];
1085 return Fcons (screen, Flist (4, nums));
1086 return Qnil;
1087 }
1088 #endif /* not HAVE_X11 */
1089 \f
1090 choose_minibuf_screen ()
1091 {
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))
1098 {
1099 Fset_window_buffer (selected_screen->minibuffer_window,
1100 XWINDOW (minibuf_window)->buffer);
1101 minibuf_window = selected_screen->minibuffer_window;
1102 }
1103 }
1104 \f
1105 syms_of_screen ()
1106 {
1107 Qscreenp = intern ("screenp");
1108 Qlive_screen_p = intern ("live_screen_p");
1109 Qminibuffer = intern ("minibuffer");
1110
1111 staticpro (&Qscreenp);
1112 staticpro (&Qlive_screen_p);
1113 staticpro (&Qminibuffer);
1114
1115 staticpro (&Vscreen_list);
1116
1117 DEFVAR_LISP ("terminal-screen", &Vterminal_screen,
1118 "The initial screen-object, which represents Emacs's stdout.");
1119
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;
1123
1124 DEFVAR_LISP ("default-minibuffer-screen", &Vdefault_minibuffer_screen,
1125 "Minibufferless screens use this screen's minibuffer.\n\
1126 \n\
1127 Emacs cannot create minibufferless screens unless this is set to an\n\
1128 appropriate surrogate.\n\
1129 \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;
1137
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;
1148
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 */
1185 }