*** 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
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;
40
41 extern Lisp_Object Vminibuffer_list;
42 extern Lisp_Object get_minibuffer ();
43 \f
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;
51 {
52 if (XTYPE (object) != Lisp_Screen)
53 return Qnil;
54 switch (XSCREEN (object)->output_method)
55 {
56 case output_termcap:
57 return Qt;
58 case output_x_window:
59 return intern ("x");
60 default:
61 abort ();
62 }
63 }
64
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;
73 {
74 return ((SCREENP (object)
75 && SCREEN_LIVE_P (XSCREEN (object)))
76 ? Fscreenp (object)
77 : Qnil);
78 }
79
80 struct screen *
81 make_screen (mini_p)
82 int mini_p;
83 {
84 Lisp_Object screen;
85 register struct screen *s;
86 register Lisp_Object root_window;
87 register Lisp_Object mini_window;
88
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);
95
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;
110
111 s->param_alist = Qnil;
112
113 root_window = make_window (0);
114 if (mini_p)
115 {
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;
122 }
123 else
124 {
125 mini_window = Qnil;
126 XWINDOW (root_window)->next = Qnil;
127 s->minibuffer_window = Qnil;
128 }
129
130 XWINDOW (root_window)->screen = screen;
131
132 /* 10 is arbitrary,
133 just so that there is "something there."
134 Correct size will be set up later with change_screen_size. */
135
136 s->width = 10;
137 s->height = 10;
138
139 XFASTINT (XWINDOW (root_window)->width) = 10;
140 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
141
142 if (mini_p)
143 {
144 XFASTINT (XWINDOW (mini_window)->width) = 10;
145 XFASTINT (XWINDOW (mini_window)->top) = 9;
146 XFASTINT (XWINDOW (mini_window)->height) = 1;
147 }
148
149 /* Choose a buffer for the screen's root window. */
150 {
151 Lisp_Object buf;
152
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);
160 }
161
162 if (mini_p)
163 {
164 XWINDOW (mini_window)->buffer = Qt;
165 Fset_window_buffer (mini_window,
166 (NILP (Vminibuffer_list)
167 ? get_minibuffer (0)
168 : Fcar (Vminibuffer_list)));
169 }
170
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;
176
177 Vscreen_list = Fcons (screen, Vscreen_list);
178
179 return s;
180 }
181 \f
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). */
185
186 struct screen *
187 make_screen_without_minibuffer (mini_window)
188 register Lisp_Object mini_window;
189 {
190 register struct screen *s;
191
192 /* Choose the minibuffer window to use. */
193 if (NILP (mini_window))
194 {
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;
198 }
199 else
200 {
201 CHECK_WINDOW (mini_window, 0);
202 }
203
204 /* Make a screen containing just a root window. */
205 s = make_screen (0);
206
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;
214 }
215
216 /* Make a screen containing only a minibuffer window. */
217
218 struct screen *
219 make_minibuffer_screen ()
220 {
221 /* First make a screen containing just a root window, no minibuffer. */
222
223 register struct screen *s = make_screen (0);
224 register Lisp_Object mini_window;
225 register Lisp_Object screen;
226
227 XSET (screen, Lisp_Screen, s);
228
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;
235
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. */
239
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;
245
246 /* Put the proper buffer in that window. */
247
248 Fset_window_buffer (mini_window,
249 (NILP (Vminibuffer_list)
250 ? get_minibuffer (0)
251 : Fcar (Vminibuffer_list)));
252 return s;
253 }
254 \f
255 /* Construct a screen that refers to the terminal (stdin and stdout). */
256
257 struct screen *
258 make_terminal_screen ()
259 {
260 register struct screen *s;
261
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;
269 }
270 \f
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;
277 {
278 CHECK_LIVE_SCREEN (screen, 0);
279
280 if (selected_screen == XSCREEN (screen))
281 return screen;
282
283 selected_screen = XSCREEN (screen);
284 if (! SCREEN_MINIBUF_ONLY_P (selected_screen))
285 last_nonminibuf_screen = selected_screen;
286
287 Fselect_window (XSCREEN (screen)->selected_window);
288
289 #ifdef HAVE_X_WINDOWS
290 #ifdef MULTI_SCREEN
291 if (XSCREEN (screen)->output_method == output_x_window
292 && NILP (no_enter))
293 {
294 Ffocus_screen (screen);
295 }
296 #endif
297 #endif
298 choose_minibuf_screen ();
299
300 return screen;
301 }
302
303 DEFUN ("selected-screen", Fselected_screen, Sselected_screen, 0, 0, 0,
304 "Return the screen that is now selected.")
305 ()
306 {
307 Lisp_Object tem;
308 XSET (tem, Lisp_Screen, selected_screen);
309 return tem;
310 }
311
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;
316 {
317 CHECK_WINDOW (window, 0);
318 return XWINDOW (window)->screen;
319 }
320
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;
325 {
326 if (NILP (screen))
327 XSET (screen, Lisp_Screen, selected_screen);
328 else
329 CHECK_LIVE_SCREEN (screen, 0);
330
331 return XSCREEN (screen)->root_window;
332 }
333
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;
339 {
340 if (NILP (screen))
341 XSET (screen, Lisp_Screen, selected_screen);
342 else
343 CHECK_LIVE_SCREEN (screen, 0);
344
345 return XSCREEN (screen)->selected_window;
346 }
347
348 DEFUN ("screen-list", Fscreen_list, Sscreen_list,
349 0, 0, 0,
350 "Return a list of all screens.")
351 ()
352 {
353 return Fcopy_sequence (Vscreen_list);
354 }
355
356 #ifdef MULTI_SCREEN
357
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;
367 {
368 Lisp_Object tail;
369 int passed = 0;
370
371 /* There must always be at least one screen in Vscreen_list. */
372 if (! CONSP (Vscreen_list))
373 abort ();
374
375 while (1)
376 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
377 {
378 if (passed)
379 {
380 Lisp_Object s = XCONS (tail)->car;
381
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;
389 }
390
391 if (EQ (screen, XCONS (tail)->car))
392 passed++;
393 }
394 }
395
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;
405 {
406 Lisp_Object tail;
407 Lisp_Object prev;
408
409 /* There must always be at least one screen in Vscreen_list. */
410 if (! CONSP (Vscreen_list))
411 abort ();
412
413 prev = Qnil;
414 while (1)
415 {
416 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
417 {
418 Lisp_Object scr = XCONS (tail)->car;
419
420 if (XTYPE (scr) != Lisp_Screen)
421 abort ();
422
423 if (EQ (screen, scr) && !NILP (prev))
424 return prev;
425
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;
432 }
433
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;
438 }
439
440 }
441
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;
450 {
451 Lisp_Object tail;
452
453 if (NILP (screen))
454 XSET (screen, Lisp_Screen, selected_screen);
455 else
456 CHECK_LIVE_SCREEN (screen, 0);
457
458 return next_screen (screen, miniscreen);
459 }
460 #endif /* MULTI_SCREEN */
461 \f
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;
468 {
469 struct screen *s;
470 union display displ;
471
472 if (EQ (screen, Qnil))
473 {
474 s = selected_screen;
475 XSET (screen, Lisp_Screen, s);
476 }
477 else
478 {
479 CHECK_SCREEN (screen, 0);
480 s = XSCREEN (screen);
481 }
482
483 if (! SCREEN_LIVE_P (s))
484 return;
485
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");
489
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)))
493 {
494 Lisp_Object screen2;
495
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");
504 }
505
506 /* Don't let the screen remain selected. */
507 if (s == selected_screen)
508 Fselect_screen (next_screen (screen, Qt));
509
510 /* Don't allow minibuf_window to remain on a deleted screen. */
511 if (EQ (s->minibuffer_window, minibuf_window))
512 {
513 Fset_window_buffer (selected_screen->minibuffer_window,
514 XWINDOW (minibuf_window)->buffer);
515 minibuf_window = selected_screen->minibuffer_window;
516 }
517
518 Vscreen_list = Fdelq (screen, Vscreen_list);
519 s->visible = 0;
520 displ = s->display;
521 s->display.nothing = 0;
522
523 #ifdef HAVE_X_WINDOWS
524 if (s->output_method == output_x_window)
525 x_destroy_window (s, displ);
526 #endif
527
528 /* If we've deleted the last_nonminibuf_screen, then try to find
529 another one. */
530 if (s == last_nonminibuf_screen)
531 {
532 last_nonminibuf_screen = 0;
533
534 for (screen = Vscreen_list; CONSP (screen); screen = XCONS (screen)->cdr)
535 {
536 s = XSCREEN (XCONS (screen)->car);
537 if (!SCREEN_MINIBUF_ONLY_P (s))
538 {
539 last_nonminibuf_screen = s;
540 break;
541 }
542 }
543 }
544
545 return Qnil;
546 }
547 \f
548 /* Return mouse position in character cell units. */
549
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.")
555 ()
556 {
557 Lisp_Object x, y, dummy;
558 SCREEN_PTR s;
559
560 if (mouse_position_hook)
561 (*mouse_position_hook) (&s, &x, &y, &dummy);
562 else
563 {
564 s = selected_screen;
565 x = y = Qnil;
566 }
567
568 XSET (dummy, Lisp_Screen, s);
569 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
570 }
571
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;
577 {
578 CHECK_LIVE_SCREEN (screen, 0);
579 CHECK_NUMBER (x, 2);
580 CHECK_NUMBER (y, 1);
581
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
587
588 return Qnil;
589 }
590 \f
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? */
594
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.")
601 ()
602 {
603 Lisp_Object c, time;
604
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;
613 }
614
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;
621 {
622 Lisp_Object x_pos, y_pos, screen;
623
624 CHECK_VECTOR (config, 0);
625 if (XVECTOR (config)->size != 3)
626 {
627 error ("Wrong size vector passed to restore-screen-configuration");
628 }
629 screen = XVECTOR (config)->contents[0];
630 CHECK_LIVE_SCREEN (screen, 0);
631
632 Fselect_screen (screen, Qnil);
633
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
640
641 return screen;
642 }
643 #endif
644 \f
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;
651 {
652 CHECK_LIVE_SCREEN (screen, 0);
653
654 if (XSCREEN (screen)->output_method == output_x_window)
655 x_make_screen_visible (XSCREEN (screen));
656
657 return screen;
658 }
659
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;
665 {
666 CHECK_LIVE_SCREEN (screen, 0);
667
668 if (XSCREEN (screen)->output_method == output_x_window)
669 x_make_screen_invisible (XSCREEN (screen));
670
671 return Qnil;
672 }
673
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;
679 {
680 CHECK_LIVE_SCREEN (screen, 0);
681
682 if (XSCREEN (screen)->output_method == output_x_window)
683 x_iconify_screen (XSCREEN (screen));
684
685 return Qnil;
686 }
687
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;
693 {
694 CHECK_LIVE_SCREEN (screen, 0);
695
696 if (XSCREEN (screen)->output_method == output_x_window)
697 x_make_screen_visible (XSCREEN (screen));
698
699 return screen;
700 }
701
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;
710 {
711 CHECK_LIVE_SCREEN (screen, 0);
712
713 if (XSCREEN (screen)->visible)
714 return Qt;
715 if (XSCREEN (screen)->iconified)
716 return intern ("icon");
717 return Qnil;
718 }
719
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).")
723 ()
724 {
725 Lisp_Object tail, screen;
726 struct screen *s;
727 Lisp_Object value;
728
729 value = Qnil;
730 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
731 {
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);
738 }
739 return value;
740 }
741
742
743 \f
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\
749 \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\
752 \n\
753 The redirection lasts until the next call to redirect-screen-focus\n\
754 or select-screen.\n\
755 \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;
760 {
761 CHECK_LIVE_SCREEN (screen, 0);
762
763 if (NILP (focus_screen))
764 focus_screen = screen;
765 else
766 CHECK_LIVE_SCREEN (focus_screen, 1);
767
768 XSCREEN (screen)->focus_screen = focus_screen;
769
770 if (screen_rehighlight_hook)
771 (*screen_rehighlight_hook) ();
772
773 return Qnil;
774 }
775
776
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;
782 {
783 CHECK_LIVE_SCREEN (screen, 0);
784 return SCREEN_FOCUS_SCREEN (XSCREEN (screen));
785 }
786
787
788 \f
789 Lisp_Object
790 get_screen_param (screen, prop)
791 register struct screen *screen;
792 Lisp_Object prop;
793 {
794 register Lisp_Object tem;
795
796 tem = Fassq (prop, screen->param_alist);
797 if (EQ (tem, Qnil))
798 return tem;
799 return Fcdr (tem);
800 }
801
802 void
803 store_in_alist (alistptr, propname, val)
804 Lisp_Object *alistptr, val;
805 char *propname;
806 {
807 register Lisp_Object tem;
808 register Lisp_Object prop;
809
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);
816 }
817
818 void
819 store_screen_param (s, prop, val)
820 struct screen *s;
821 Lisp_Object prop, val;
822 {
823 register Lisp_Object tem;
824
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);
830 }
831
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;
838 {
839 Lisp_Object alist;
840 struct screen *s;
841
842 if (EQ (screen, Qnil))
843 s = selected_screen;
844 else
845 {
846 CHECK_SCREEN (screen, 0);
847 s = XSCREEN (screen);
848 }
849
850 if (s->display.nothing == 0)
851 return Qnil;
852
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));
863
864 if (s->output_method == output_x_window)
865 x_report_screen_params (s, &alist);
866 return alist;
867 }
868
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;
877 {
878 register struct screen *s;
879 register Lisp_Object tail, elt, prop, val;
880
881 if (EQ (screen, Qnil))
882 s = selected_screen;
883 else
884 {
885 CHECK_LIVE_SCREEN (screen, 0);
886 s = XSCREEN (screen);
887 }
888
889 if (s->output_method == output_x_window)
890 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
891 {
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);
898 }
899
900 return Qnil;
901 }
902 \f
903
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;
909 {
910 register struct screen *s;
911 int width, height;
912
913 CHECK_LIVE_SCREEN (screen, 0);
914 s = XSCREEN (screen);
915
916 return Fcons (make_number (x_pixel_width (s)),
917 make_number (x_pixel_height (s)));
918 }
919
920 DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0,
921 "Return number of lines available for display on selected screen.")
922 ()
923 {
924 return make_number (SCREEN_HEIGHT (selected_screen));
925 }
926
927 DEFUN ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0,
928 "Return number of columns available for display on selected screen.")
929 ()
930 {
931 return make_number (SCREEN_WIDTH (selected_screen));
932 }
933
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;
940 {
941 register struct screen *s;
942
943 CHECK_NUMBER (rows, 0);
944 if (NILP (screen))
945 s = selected_screen;
946 else
947 {
948 CHECK_LIVE_SCREEN (screen, 0);
949 s = XSCREEN (screen);
950 }
951
952 if (s->output_method == output_x_window)
953 {
954 if (XINT (rows) != s->width)
955 x_set_window_size (s, s->width, XINT (rows));
956 }
957 else
958 change_screen_size (s, XINT (rows), 0, !NILP (pretend));
959 return Qnil;
960 }
961
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;
968 {
969 register struct screen *s;
970 CHECK_NUMBER (cols, 0);
971 if (NILP (screen))
972 s = selected_screen;
973 else
974 {
975 CHECK_LIVE_SCREEN (screen, 0);
976 s = XSCREEN (screen);
977 }
978
979 if (s->output_method == output_x_window)
980 {
981 if (XINT (cols) != s->width)
982 x_set_window_size (s, XINT (cols), s->height);
983 }
984 else
985 change_screen_size (selected_screen, 0, XINT (cols), !NILP (pretend));
986 return Qnil;
987 }
988
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;
993 {
994 register struct screen *s;
995 int mask;
996
997 CHECK_LIVE_SCREEN (screen, 0);
998 CHECK_NUMBER (cols, 2);
999 CHECK_NUMBER (rows, 1);
1000 s = XSCREEN (screen);
1001
1002 if (s->output_method == output_x_window)
1003 {
1004 if (XINT (rows) != s->height || XINT (cols) != s->width)
1005 x_set_window_size (s, XINT (cols), XINT (rows));
1006 }
1007 else
1008 change_screen_size (s, XINT (rows), XINT (cols), 0);
1009
1010 return Qnil;
1011 }
1012
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;
1021 {
1022 register struct screen *s;
1023 int mask;
1024
1025 CHECK_LIVE_SCREEN (screen, 0);
1026 CHECK_NUMBER (xoffset, 1);
1027 CHECK_NUMBER (yoffset, 2);
1028 s = XSCREEN (screen);
1029
1030 if (s->output_method == output_x_window)
1031 x_set_offset (s, XINT (xoffset), XINT (yoffset));
1032
1033 return Qt;
1034 }
1035 \f
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;
1049 {
1050 int vals[4];
1051 Lisp_Object nums[4];
1052 int i;
1053
1054 CHECK_SCREEN (screen, 0);
1055 CHECK_STRING (name, 1);
1056 CHECK_STRING (geo, 2);
1057
1058 switch (XSCREEN (screen)->output_method)
1059 {
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;
1064
1065 default:
1066 return Qnil;
1067 }
1068
1069 for (i = 0; i < 4; i++)
1070 XFASTINT (nums[i]) = vals[i];
1071 return Fcons (screen, Flist (4, nums));
1072 return Qnil;
1073 }
1074 #endif /* not HAVE_X11 */
1075 \f
1076 choose_minibuf_screen ()
1077 {
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))
1084 {
1085 Fset_window_buffer (selected_screen->minibuffer_window,
1086 XWINDOW (minibuf_window)->buffer);
1087 minibuf_window = selected_screen->minibuffer_window;
1088 }
1089 }
1090 \f
1091 syms_of_screen ()
1092 {
1093 Qscreenp = intern ("screenp");
1094 Qlive_screen_p = intern ("live_screen_p");
1095
1096 staticpro (&Qscreenp);
1097 staticpro (&Qlive_screen_p);
1098
1099 staticpro (&Vscreen_list);
1100
1101 DEFVAR_LISP ("terminal-screen", &Vterminal_screen,
1102 "The initial screen-object, which represents Emacs's stdout.");
1103
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;
1107
1108 DEFVAR_LISP ("default-minibuffer-screen", &Vdefault_minibuffer_screen,
1109 "Minibufferless screens use this screen's minibuffer.\n\
1110 \n\
1111 Emacs cannot create minibufferless screens unless this is set to an\n\
1112 appropriate surrogate.\n\
1113 \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;
1121
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;
1132
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 */
1169 }