*** empty log message ***
[bpt/emacs.git] / src / frame.c
CommitLineData
dc6f92b8
JB
1/* Generic screen functions.
2 Copyright (C) 1989 Free Software Foundation.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
d5e7c279
JB
20#include <stdio.h>
21
dc6f92b8
JB
22#include "config.h"
23#include "lisp.h"
24#include "screen.h"
25#include "window.h"
d5e7c279 26#include "termhooks.h"
dc6f92b8
JB
27
28Lisp_Object Vemacs_iconified;
29Lisp_Object Qscreenp;
f9898cc6 30Lisp_Object Qlive_screen_p;
dc6f92b8
JB
31Lisp_Object Vscreen_list;
32Lisp_Object Vterminal_screen;
f9898cc6 33Lisp_Object Vdefault_minibuffer_screen;
5bce042c 34Lisp_Object Vdefault_screen_alist;
dc6f92b8 35
d5e7c279
JB
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. */
39struct screen *last_nonminibuf_screen;
40
dc6f92b8
JB
41extern Lisp_Object Vminibuffer_list;
42extern Lisp_Object get_minibuffer ();
43\f
44DEFUN ("screenp", Fscreenp, Sscreenp, 1, 1, 0,
45 "Return non-nil if OBJECT is a screen.\n\
46Value is t for a termcap screen (a character-only terminal),\n\
f9898cc6
JB
47`x' for an Emacs screen that is really an X window.\n\
48Also see live-screen-p.")
49 (object)
50 Lisp_Object object;
dc6f92b8 51{
f9898cc6 52 if (XTYPE (object) != Lisp_Screen)
dc6f92b8 53 return Qnil;
f9898cc6 54 switch (XSCREEN (object)->output_method)
dc6f92b8
JB
55 {
56 case output_termcap:
57 return Qt;
58 case output_x_window:
59 return intern ("x");
60 default:
61 abort ();
62 }
63}
64
f9898cc6
JB
65DEFUN ("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\
67Value is nil if OBJECT is not a live screen. If object is a live\n\
68screen, the return value indicates what sort of output device it is\n\
69displayed on. Value is t for a termcap screen (a character-only\n\
70terminal), `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
dc6f92b8
JB
80struct screen *
81make_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
d5e7c279
JB
89 screen = Fmake_vector (((sizeof (struct screen) - (sizeof (Lisp_Vector)
90 - sizeof (Lisp_Object)))
91 / sizeof (Lisp_Object)),
dc6f92b8
JB
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;
d5e7c279 109 s->focus_screen = screen;
dc6f92b8
JB
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
5bce042c
JB
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
dc6f92b8
JB
162 if (mini_p)
163 {
164 XWINDOW (mini_window)->buffer = Qt;
165 Fset_window_buffer (mini_window,
265a9e55 166 (NILP (Vminibuffer_list)
dc6f92b8
JB
167 ? get_minibuffer (0)
168 : Fcar (Vminibuffer_list)));
169 }
170
dc6f92b8 171 s->root_window = root_window;
d5e7c279
JB
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;
dc6f92b8
JB
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
186struct screen *
187make_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. */
265a9e55 193 if (NILP (mini_window))
dc6f92b8 194 {
f9898cc6
JB
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;
dc6f92b8
JB
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,
265a9e55 210 (NILP (Vminibuffer_list)
dc6f92b8
JB
211 ? get_minibuffer (0)
212 : Fcar (Vminibuffer_list)));
213 return s;
214}
215
216/* Make a screen containing only a minibuffer window. */
217
218struct screen *
219make_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;
f9898cc6 234 s->has_minibuffer = 1;
dc6f92b8
JB
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,
265a9e55 249 (NILP (Vminibuffer_list)
dc6f92b8
JB
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
257struct screen *
258make_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
271DEFUN ("select-screen", Fselect_screen, Sselect_screen, 1, 2, 0,
272 "Select the screen S. S's selected window becomes \"the\"\n\
d5e7c279 273selected window. If the optional parameter NO-ENTER is non-nil, don't\n\
dc6f92b8
JB
274focus on that screen.")
275 (screen, no_enter)
276 Lisp_Object screen, no_enter;
277{
f9898cc6 278 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
279
280 if (selected_screen == XSCREEN (screen))
281 return screen;
282
283 selected_screen = XSCREEN (screen);
f9898cc6 284 if (! SCREEN_MINIBUF_ONLY_P (selected_screen))
d5e7c279
JB
285 last_nonminibuf_screen = selected_screen;
286
dc6f92b8
JB
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
265a9e55 292 && NILP (no_enter))
dc6f92b8
JB
293 {
294 Ffocus_screen (screen);
295 }
296#endif
297#endif
298 choose_minibuf_screen ();
299
300 return screen;
301}
302
303DEFUN ("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
312DEFUN ("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
321DEFUN ("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{
265a9e55 326 if (NILP (screen))
dc6f92b8 327 XSET (screen, Lisp_Screen, selected_screen);
f9898cc6
JB
328 else
329 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
330
331 return XSCREEN (screen)->root_window;
332}
333
334DEFUN ("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{
265a9e55 340 if (NILP (screen))
dc6f92b8 341 XSET (screen, Lisp_Screen, selected_screen);
f9898cc6
JB
342 else
343 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
344
345 return XSCREEN (screen)->selected_window;
346}
347
348DEFUN ("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
f9898cc6
JB
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. */
dc6f92b8 363Lisp_Object
f9898cc6 364next_screen (screen, minibuf)
dc6f92b8 365 Lisp_Object screen;
f9898cc6 366 Lisp_Object minibuf;
dc6f92b8
JB
367{
368 Lisp_Object tail;
369 int passed = 0;
370
f9898cc6
JB
371 /* There must always be at least one screen in Vscreen_list. */
372 if (! CONSP (Vscreen_list))
373 abort ();
374
dc6f92b8
JB
375 while (1)
376 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
377 {
378 if (passed)
d5e7c279 379 {
f9898cc6
JB
380 Lisp_Object s = XCONS (tail)->car;
381
382 /* Decide whether this screen is eligible to be returned,
383 according to minibuf. */
265a9e55 384 if ((NILP (minibuf) && ! SCREEN_MINIBUF_ONLY_P (XSCREEN (s)))
f9898cc6
JB
385 || XTYPE (minibuf) != Lisp_Window
386 || EQ (SCREEN_MINIBUF_WINDOW (XSCREEN (s)), minibuf)
387 || EQ (s, screen))
388 return s;
d5e7c279 389 }
dc6f92b8
JB
390
391 if (EQ (screen, XCONS (tail)->car))
392 passed++;
393 }
394}
395
f9898cc6
JB
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. */
dc6f92b8 401Lisp_Object
f9898cc6 402prev_screen (screen, minibuf)
dc6f92b8 403 Lisp_Object screen;
f9898cc6 404 Lisp_Object minibuf;
dc6f92b8
JB
405{
406 Lisp_Object tail;
407 Lisp_Object prev;
408
f9898cc6
JB
409 /* There must always be at least one screen in Vscreen_list. */
410 if (! CONSP (Vscreen_list))
411 abort ();
412
dc6f92b8
JB
413 prev = Qnil;
414 while (1)
f9898cc6
JB
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
265a9e55 423 if (EQ (screen, scr) && !NILP (prev))
f9898cc6
JB
424 return prev;
425
426 /* Decide whether this screen is eligible to be returned,
427 according to minibuf. */
265a9e55 428 if ((NILP (minibuf) && ! SCREEN_MINIBUF_ONLY_P (XSCREEN (scr)))
f9898cc6
JB
429 || XTYPE (minibuf) != Lisp_Window
430 || EQ (SCREEN_MINIBUF_WINDOW (XSCREEN (scr)), minibuf))
431 prev = scr;
432 }
433
265a9e55 434 if (NILP (prev))
f9898cc6
JB
435 /* We went through the whole screen list without finding a single
436 acceptable screen. Return the original screen. */
437 prev = screen;
438 }
439
dc6f92b8
JB
440}
441
f9898cc6
JB
442DEFUN ("next-screen", Fnext_screen, Snext_screen, 0, 2, 0,
443 "Return the next screen in the screen list after SCREEN.\n\
444If optional argument MINIBUF is non-nil, include all screens. If\n\
445MINIBUF is nil or omitted, exclude minibuffer-only screens. If\n\
446MINIBUF is a window, include only screens using that window for their\n\
447minibuffer.")
dc6f92b8
JB
448 (screen, miniscreen)
449Lisp_Object screen, miniscreen;
450{
451 Lisp_Object tail;
452
265a9e55 453 if (NILP (screen))
dc6f92b8 454 XSET (screen, Lisp_Screen, selected_screen);
f9898cc6
JB
455 else
456 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8 457
f9898cc6 458 return next_screen (screen, miniscreen);
dc6f92b8
JB
459}
460#endif /* MULTI_SCREEN */
461\f
f9898cc6
JB
462DEFUN ("delete-screen", Fdelete_screen, Sdelete_screen, 0, 1, "",
463 "Delete SCREEN, permanently eliminating it from use.\n\
464If omitted, SCREEN defaults to the selected screen.\n\
465A screen may not be deleted if its minibuffer is used by other screens.")
dc6f92b8
JB
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
f9898cc6
JB
483 if (! SCREEN_LIVE_P (s))
484 return;
485
d5e7c279 486 /* Are there any other screens besides this one? */
f9898cc6 487 if (s == selected_screen && EQ (next_screen (screen, Qt), screen))
d5e7c279
JB
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? */
f9898cc6 492 if (SCREEN_HAS_MINIBUF (XSCREEN (screen)))
dc6f92b8 493 {
d5e7c279 494 Lisp_Object screen2;
dc6f92b8 495
d5e7c279
JB
496 for (screen2 = Vscreen_list; CONSP (2); screen2 = XCONS (screen2)->cdr)
497 if (! EQ (screen2, screen)
498 && EQ (screen,
f9898cc6
JB
499 (WINDOW_SCREEN
500 (XWINDOW
501 (SCREEN_MINIBUF_WINDOW
502 (XSCREEN (screen2)))))))
d5e7c279 503 error ("Attempt to delete a surrogate minibuffer screen");
dc6f92b8
JB
504 }
505
d5e7c279
JB
506 /* Don't let the screen remain selected. */
507 if (s == selected_screen)
f9898cc6 508 Fselect_screen (next_screen (screen, Qt));
dc6f92b8
JB
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
d5e7c279 523#ifdef HAVE_X_WINDOWS
dc6f92b8
JB
524 if (s->output_method == output_x_window)
525 x_destroy_window (s, displ);
d5e7c279
JB
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 {
f9898cc6
JB
536 s = XSCREEN (XCONS (screen)->car);
537 if (!SCREEN_MINIBUF_ONLY_P (s))
d5e7c279
JB
538 {
539 last_nonminibuf_screen = s;
540 break;
541 }
542 }
543 }
dc6f92b8
JB
544
545 return Qnil;
546}
547\f
548/* Return mouse position in character cell units. */
549
f9898cc6
JB
550DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
551 "Return a list (SCREEN X . Y) giving the current mouse screen and position.\n\
552If Emacs is running on a mouseless terminal or hasn't been programmed\n\
553to read the mouse position, it returns the selected screen for SCREEN\n\
554and nil for X and Y.")
555 ()
dc6f92b8 556{
f9898cc6
JB
557 Lisp_Object x, y, dummy;
558 SCREEN_PTR s;
dc6f92b8 559
f9898cc6
JB
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 }
dc6f92b8 567
f9898cc6
JB
568 XSET (dummy, Lisp_Screen, s);
569 return Fcons (dummy, Fcons (make_number (x), make_number (y)));
dc6f92b8
JB
570}
571
572DEFUN ("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\
574WARNING: If you use this under X, you should do unfocus-screen afterwards.")
575 (screen, x, y)
576 Lisp_Object screen, x, y;
577{
f9898cc6 578 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
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
595DEFUN ("screen-configuration", Fscreen_configuration, Sscreen_configuration,
596 0, 0, 0,
597 "Return object describing current screen configuration.\n\
598The screen configuration is the current mouse position and selected screen.\n\
599This object can be given to `restore-screen-configuration'\n\
600to restore this screen configuration.")
601 ()
602{
f9898cc6 603 Lisp_Object c, time;
dc6f92b8 604
f9898cc6
JB
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);
dc6f92b8
JB
612 return c;
613}
614
615DEFUN ("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];
f9898cc6 630 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
631
632 Fselect_screen (screen, Qnil);
633
634#if 0
635 /* This seems to interfere with the screen selection mechanism. jla */
f9898cc6
JB
636 x_pos = XVECTOR (config)->contents[2];
637 y_pos = XVECTOR (config)->contents[3];
dc6f92b8
JB
638 set_mouse_position (screen, XINT (x_pos), XINT (y_pos));
639#endif
640
641 return screen;
642}
643#endif
644\f
645DEFUN ("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\
648Also raises the screen so that nothing obscures it.")
649 (screen)
650 Lisp_Object screen;
651{
f9898cc6 652 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
653
654 if (XSCREEN (screen)->output_method == output_x_window)
655 x_make_screen_visible (XSCREEN (screen));
656
657 return screen;
658}
659
660DEFUN ("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{
f9898cc6 666 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
667
668 if (XSCREEN (screen)->output_method == output_x_window)
669 x_make_screen_invisible (XSCREEN (screen));
670
671 return Qnil;
672}
673
674DEFUN ("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{
f9898cc6 680 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
681
682 if (XSCREEN (screen)->output_method == output_x_window)
683 x_iconify_screen (XSCREEN (screen));
684
685 return Qnil;
686}
687
688DEFUN ("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{
f9898cc6 694 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
695
696 if (XSCREEN (screen)->output_method == output_x_window)
697 x_make_screen_visible (XSCREEN (screen));
698
699 return screen;
700}
701
702DEFUN ("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\
705A screen that is not \"visible\" is not updated and, if it works through\n\
706a window system, it may not show at all.\n\
707Return the symbol `icon' if window is visible only as an icon.")
708 (screen)
709 Lisp_Object screen;
710{
f9898cc6 711 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
712
713 if (XSCREEN (screen)->visible)
714 return Qt;
715 if (XSCREEN (screen)->iconified)
716 return intern ("icon");
717 return Qnil;
718}
719
720DEFUN ("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}
d5e7c279
JB
741
742
743\f
744DEFUN ("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\
747This means that, after reading a keystroke typed at SCREEN,\n\
748last-event-screen will be FOCUS-SCREEN.\n\
749\n\
750If FOCUS-SCREEN is omitted or eq to SCREEN, any existing redirection is\n\
751cancelled, and the screen again receives its own keystrokes.\n\
752\n\
753The redirection lasts until the next call to redirect-screen-focus\n\
754or select-screen.\n\
755\n\
756This is useful for temporarily redirecting keystrokes to the minibuffer\n\
757window when a screen doesn't have its own minibuffer.")
758 (screen, focus_screen)
759 Lisp_Object screen, focus_screen;
760{
f9898cc6
JB
761 CHECK_LIVE_SCREEN (screen, 0);
762
265a9e55 763 if (NILP (focus_screen))
d5e7c279
JB
764 focus_screen = screen;
765 else
f9898cc6 766 CHECK_LIVE_SCREEN (focus_screen, 1);
d5e7c279
JB
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
777DEFUN ("screen-focus", Fscreen_focus, Sscreen_focus, 1, 1, 0,
778 "Return the screen to which SCREEN's keystrokes are currently being sent.\n\
779See redirect-screen-focus.")
780 (screen)
781 Lisp_Object screen;
782{
f9898cc6 783 CHECK_LIVE_SCREEN (screen, 0);
d5e7c279
JB
784 return SCREEN_FOCUS_SCREEN (XSCREEN (screen));
785}
786
787
dc6f92b8
JB
788\f
789Lisp_Object
790get_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
802void
803store_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
818void
819store_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
832DEFUN ("screen-parameters", Fscreen_parameters, Sscreen_parameters, 0, 1, 0,
833 "Return the parameters-alist of screen SCREEN.\n\
834It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
835The 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));
f9898cc6
JB
858 store_in_alist (&alist, "minibuffer",
859 (SCREEN_HAS_MINIBUF (s)
860 ? (SCREEN_MINIBUF_ONLY_P (s) ? intern ("only") : Qt)
861 : Qnil));
dc6f92b8
JB
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
869DEFUN ("modify-screen-parameters", Fmodify_screen_parameters,
870 Smodify_screen_parameters, 2, 2, 0,
871 "Modify the parameters of screen SCREEN according to ALIST.\n\
872ALIST is an alist of parameters to change and their new values.\n\
873Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
874The 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 {
f9898cc6 885 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
886 s = XSCREEN (screen);
887 }
888
dc6f92b8
JB
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
904DEFUN ("screen-pixel-size", Fscreen_pixel_size,
905 Sscreen_pixel_size, 1, 1, 0,
f9898cc6 906 "Return a cons (width . height) of SCREEN's size in pixels.")
dc6f92b8
JB
907 (screen)
908 Lisp_Object screen;
909{
910 register struct screen *s;
911 int width, height;
912
f9898cc6 913 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
914 s = XSCREEN (screen);
915
916 return Fcons (make_number (x_pixel_width (s)),
917 make_number (x_pixel_height (s)));
918}
919
920DEFUN ("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
927DEFUN ("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
934DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 2, 3, 0,
935 "Specify that the screen SCREEN has LINES lines.\n\
936Optional third arg non-nil means that redisplay should use LINES lines\n\
937but 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);
265a9e55 944 if (NILP (screen))
dc6f92b8
JB
945 s = selected_screen;
946 else
947 {
f9898cc6 948 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
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
265a9e55 958 change_screen_size (s, XINT (rows), 0, !NILP (pretend));
dc6f92b8
JB
959 return Qnil;
960}
961
962DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 2, 3, 0,
963 "Specify that the screen SCREEN has COLS columns.\n\
964Optional third arg non-nil means that redisplay should use COLS columns\n\
965but 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);
265a9e55 971 if (NILP (screen))
dc6f92b8
JB
972 s = selected_screen;
973 else
974 {
f9898cc6 975 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
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
265a9e55 985 change_screen_size (selected_screen, 0, XINT (cols), !NILP (pretend));
dc6f92b8
JB
986 return Qnil;
987}
988
f9898cc6 989DEFUN ("set-screen-size", Fset_screen_size, Sset_screen_size, 3, 3, 0,
dc6f92b8
JB
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
f9898cc6 997 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
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
1013DEFUN ("set-screen-position", Fset_screen_position,
1014 Sset_screen_position, 3, 3, 0,
f9898cc6
JB
1015 "Sets position of SCREEN in pixels to XOFFSET by YOFFSET.\n\
1016If XOFFSET or YOFFSET are negative, they are interpreted relative to\n\
1017the leftmost or bottommost position SCREEN could occupy without going\n\
1018off the screen.")
dc6f92b8
JB
1019 (screen, xoffset, yoffset)
1020 Lisp_Object screen, xoffset, yoffset;
1021{
1022 register struct screen *s;
1023 int mask;
1024
f9898cc6 1025 CHECK_LIVE_SCREEN (screen, 0);
dc6f92b8
JB
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
dc6f92b8
JB
1036#ifndef HAVE_X11
1037DEFUN ("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\
1040Arguments are SCREEN, NAME and GEO. NAME is a name to be displayed as\n\
1041the purpose of this rectangle. GEO is an X-windows size spec that can\n\
1042specify defaults for some sizes/positions. If GEO specifies everything,\n\
1043the mouse is not used.\n\
1044Returns 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
1076choose_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
1091syms_of_screen ()
1092{
1093 Qscreenp = intern ("screenp");
f9898cc6
JB
1094 Qlive_screen_p = intern ("live_screen_p");
1095
1096 staticpro (&Qscreenp);
1097 staticpro (&Qlive_screen_p);
dc6f92b8
JB
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,
f9898cc6 1105 "Non-nil if all of emacs is iconified and screen updates are not needed.");
dc6f92b8
JB
1106 Vemacs_iconified = Qnil;
1107
f9898cc6
JB
1108 DEFVAR_LISP ("default-minibuffer-screen", &Vdefault_minibuffer_screen,
1109 "Minibufferless screens use this screen's minibuffer.\n\
1110\n\
1111Emacs cannot create minibufferless screens unless this is set to an\n\
1112appropriate surrogate.\n\
1113\n\
1114Emacs consults this variable only when creating minibufferless\n\
1115screens; once the screen is created, it sticks with its assigned\n\
1116minibuffer, no matter what this variable is set to. This means that\n\
1117this variable doesn't necessarily say anything meaningful about the\n\
1118current set of screens, or where the minibuffer is currently being\n\
1119displayed.");
1120 Vdefault_minibuffer_screen = Qnil;
dc6f92b8 1121
5bce042c
JB
1122 DEFVAR_LISP ("default-screen-alist", &Vdefault_screen_alist,
1123 "Alist of default values for screen creation.\n\
1124These may be set in your init file, like this:\n\
1125 (setq default-screen-alist '((width . 80) (height . 55)))\n\
1126These override values given in window system configuration data, like\n\
1127X Windows' defaults database.\n\
1128For values specific to the first emacs screen, see initial-screen-alist.\n\
1129For values specific to the separate minibuffer screen, see\n\
1130minibuffer-screen-alist.");
1131 Vdefault_screen_alist = Qnil;
1132
dc6f92b8 1133 defsubr (&Sscreenp);
f9898cc6 1134 defsubr (&Slive_screen_p);
dc6f92b8
JB
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);
f9898cc6 1143 defsubr (&Smouse_position);
dc6f92b8
JB
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);
d5e7c279
JB
1155 defsubr (&Sredirect_screen_focus);
1156 defsubr (&Sscreen_focus);
dc6f92b8
JB
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);
dc6f92b8
JB
1166#ifndef HAVE_X11
1167 defsubr (&Srubber_band_rectangle);
1168#endif /* HAVE_X11 */
1169}