comparison src/frame.c @ 286:8a40ab4a424f

Initial revision
author Jim Blandy <jimb@redhat.com>
date Sat, 25 May 1991 06:46:10 +0000
parents
children 33aa13a3f279
comparison
equal deleted inserted replaced
285:adb31fcccc2b 286:8a40ab4a424f
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 "config.h"
21 #include "lisp.h"
22 #include "screen.h"
23 #include "window.h"
24
25 Lisp_Object Vemacs_iconified;
26 Lisp_Object Qscreenp;
27 Lisp_Object Vscreen_list;
28 Lisp_Object Vterminal_screen;
29 Lisp_Object Vglobal_minibuffer_screen;
30
31 extern Lisp_Object Vminibuffer_list;
32 extern Lisp_Object get_minibuffer ();
33
34 DEFUN ("screenp", Fscreenp, Sscreenp, 1, 1, 0,
35 "Return non-nil if OBJECT is a screen.\n\
36 Value is t for a termcap screen (a character-only terminal),\n\
37 `x' for an Emacs screen that is really an X window.")
38 (screen)
39 Lisp_Object screen;
40 {
41 if (XTYPE (screen) != Lisp_Screen)
42 return Qnil;
43 switch (XSCREEN (screen)->output_method)
44 {
45 case output_termcap:
46 return Qt;
47 case output_x_window:
48 return intern ("x");
49 default:
50 abort ();
51 }
52 }
53
54 struct screen *
55 make_screen (mini_p)
56 int mini_p;
57 {
58 Lisp_Object screen;
59 register struct screen *s;
60 register Lisp_Object root_window;
61 register Lisp_Object mini_window;
62
63 screen = Fmake_vector (sizeof (struct screen) - sizeof (Lisp_Vector) + 1,
64 make_number (0));
65 XSETTYPE (screen, Lisp_Screen);
66 s = XSCREEN (screen);
67
68 s->cursor_x = 0;
69 s->cursor_y = 0;
70 s->current_glyphs = 0;
71 s->desired_glyphs = 0;
72 s->visible = 0;
73 s->display.nothing = 0;
74 s->iconified = 0;
75 s->wants_modeline = 1;
76 s->auto_raise = 0;
77 s->auto_lower = 0;
78 s->no_split = 0;
79 s->garbaged = 0;
80 s->has_minibuffer = mini_p;
81
82 s->param_alist = Qnil;
83
84 root_window = make_window (0);
85 if (mini_p)
86 {
87 mini_window = make_window (0);
88 XWINDOW (root_window)->next = mini_window;
89 XWINDOW (mini_window)->prev = root_window;
90 XWINDOW (mini_window)->mini_p = Qt;
91 XWINDOW (mini_window)->screen = screen;
92 s->minibuffer_window = mini_window;
93 }
94 else
95 {
96 mini_window = Qnil;
97 XWINDOW (root_window)->next = Qnil;
98 s->minibuffer_window = Qnil;
99 }
100
101 XWINDOW (root_window)->screen = screen;
102
103 /* 10 is arbitrary,
104 just so that there is "something there."
105 Correct size will be set up later with change_screen_size. */
106
107 s->width = 10;
108 s->height = 10;
109
110 XFASTINT (XWINDOW (root_window)->width) = 10;
111 XFASTINT (XWINDOW (root_window)->height) = (mini_p ? 9 : 10);
112
113 if (mini_p)
114 {
115 XFASTINT (XWINDOW (mini_window)->width) = 10;
116 XFASTINT (XWINDOW (mini_window)->top) = 9;
117 XFASTINT (XWINDOW (mini_window)->height) = 1;
118 }
119
120 XWINDOW (root_window)->buffer = Qt;
121 Fset_window_buffer (root_window, Fcurrent_buffer ());
122 if (mini_p)
123 {
124 XWINDOW (mini_window)->buffer = Qt;
125 Fset_window_buffer (mini_window,
126 (NULL (Vminibuffer_list)
127 ? get_minibuffer (0)
128 : Fcar (Vminibuffer_list)));
129 }
130
131 s->selected_window = root_window;
132 s->root_window = root_window;
133
134 Vscreen_list = Fcons (screen, Vscreen_list);
135
136 return s;
137 }
138
139 /* Make a screen using a separate minibuffer window on another screen.
140 MINI_WINDOW is the minibuffer window to use. nil means use the
141 default (the global minibuffer). */
142
143 struct screen *
144 make_screen_without_minibuffer (mini_window)
145 register Lisp_Object mini_window;
146 {
147 register struct screen *s;
148
149 /* Choose the minibuffer window to use. */
150 if (NULL (mini_window))
151 {
152 CHECK_SCREEN (Vglobal_minibuffer_screen, 0);
153 mini_window = XSCREEN (Vglobal_minibuffer_screen)->minibuffer_window;
154 }
155 else
156 {
157 CHECK_WINDOW (mini_window, 0);
158 }
159
160 /* Make a screen containing just a root window. */
161 s = make_screen (0);
162
163 /* Install the chosen minibuffer window, with proper buffer. */
164 s->minibuffer_window = mini_window;
165 Fset_window_buffer (mini_window,
166 (NULL (Vminibuffer_list)
167 ? get_minibuffer (0)
168 : Fcar (Vminibuffer_list)));
169 return s;
170 }
171
172 /* Make a screen containing only a minibuffer window. */
173
174 struct screen *
175 make_minibuffer_screen ()
176 {
177 /* First make a screen containing just a root window, no minibuffer. */
178
179 register struct screen *s = make_screen (0);
180 register Lisp_Object mini_window;
181 register Lisp_Object screen;
182
183 XSET (screen, Lisp_Screen, s);
184
185 /* ??? Perhaps leave it to the user program to set auto_raise. */
186 s->auto_raise = 1;
187 s->auto_lower = 0;
188 s->no_split = 1;
189 s->wants_modeline = 0;
190 /* Note we leave has_minibuffer as 0. This is a little strange. */
191
192 /* Now label the root window as also being the minibuffer.
193 Avoid infinite looping on the window chain by marking next pointer
194 as nil. */
195
196 mini_window = s->minibuffer_window = s->root_window;
197 XWINDOW (mini_window)->mini_p = Qt;
198 XWINDOW (mini_window)->next = Qnil;
199 XWINDOW (mini_window)->prev = mini_window;
200 XWINDOW (mini_window)->screen = screen;
201
202 /* Put the proper buffer in that window. */
203
204 Fset_window_buffer (mini_window,
205 (NULL (Vminibuffer_list)
206 ? get_minibuffer (0)
207 : Fcar (Vminibuffer_list)));
208 return s;
209 }
210
211 /* Construct a screen that refers to the terminal (stdin and stdout). */
212
213 struct screen *
214 make_terminal_screen ()
215 {
216 register struct screen *s;
217
218 Vscreen_list = Qnil;
219 s = make_screen (1);
220 s->name = build_string ("terminal");
221 s->visible = 1;
222 s->display.nothing = 1; /* Nonzero means screen isn't deleted. */
223 XSET (Vterminal_screen, Lisp_Screen, s);
224 return s;
225 }
226
227 DEFUN ("select-screen", Fselect_screen, Sselect_screen, 1, 2, 0,
228 "Select the screen S. S's selected window becomes \"the\"\n\
229 selected window. If the optional parameter NO-ENTER is non-nil, don't
230 focus on that screen.")
231 (screen, no_enter)
232 Lisp_Object screen, no_enter;
233 {
234 CHECK_SCREEN (screen, 0);
235
236 if (selected_screen == XSCREEN (screen))
237 return screen;
238
239 selected_screen = XSCREEN (screen);
240 Fselect_window (XSCREEN (screen)->selected_window);
241
242 #ifdef HAVE_X_WINDOWS
243 #ifdef MULTI_SCREEN
244 if (XSCREEN (screen)->output_method == output_x_window
245 && NULL (no_enter))
246 {
247 Ffocus_screen (screen);
248 }
249 #endif
250 #endif
251 choose_minibuf_screen ();
252
253 return screen;
254 }
255
256 DEFUN ("selected-screen", Fselected_screen, Sselected_screen, 0, 0, 0,
257 "Return the screen that is now selected.")
258 ()
259 {
260 Lisp_Object tem;
261 XSET (tem, Lisp_Screen, selected_screen);
262 return tem;
263 }
264
265 DEFUN ("window-screen", Fwindow_screen, Swindow_screen, 1, 1, 0,
266 "Return the screen object that window WINDOW is on.")
267 (window)
268 Lisp_Object window;
269 {
270 CHECK_WINDOW (window, 0);
271 return XWINDOW (window)->screen;
272 }
273
274 DEFUN ("screen-root-window", Fscreen_root_window, Sscreen_root_window, 0, 1, 0,
275 "Returns the root-window of SCREEN.")
276 (screen)
277 Lisp_Object screen;
278 {
279 if (NULL (screen))
280 XSET (screen, Lisp_Screen, selected_screen);
281 CHECK_SCREEN (screen, 0);
282
283 return XSCREEN (screen)->root_window;
284 }
285
286 DEFUN ("screen-selected-window", Fscreen_selected_window,
287 Sscreen_selected_window, 0, 1, 0,
288 "Return the selected window of screen object SCREEN.")
289 (screen)
290 Lisp_Object screen;
291 {
292 if (NULL (screen))
293 XSET (screen, Lisp_Screen, selected_screen);
294 CHECK_SCREEN (screen, 0);
295
296 return XSCREEN (screen)->selected_window;
297 }
298
299 DEFUN ("screen-list", Fscreen_list, Sscreen_list,
300 0, 0, 0,
301 "Return a list of all screens.")
302 ()
303 {
304 return Fcopy_sequence (Vscreen_list);
305 }
306
307 #ifdef MULTI_SCREEN
308 Lisp_Object
309 next_screen (screen, mini_screen)
310 Lisp_Object screen;
311 int mini_screen;
312 {
313 Lisp_Object tail;
314 int passed = 0;
315
316 while (1)
317 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
318 {
319 if (passed)
320 if (!mini_screen
321 && EQ (XCONS (tail)->car, Vglobal_minibuffer_screen))
322 continue;
323 else
324 return XCONS (tail)->car;
325
326 if (EQ (screen, XCONS (tail)->car))
327 passed++;
328 }
329 }
330
331 Lisp_Object
332 prev_screen (screen, mini_screen)
333 Lisp_Object screen;
334 int mini_screen;
335 {
336 Lisp_Object tail;
337 Lisp_Object prev;
338
339 prev = Qnil;
340 while (1)
341 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
342 {
343 if (EQ (screen, XCONS (tail)->car))
344 {
345 if (!NULL (prev) && (mini_screen
346 || !EQ (XCONS (tail)->car,
347 Vglobal_minibuffer_screen)))
348 return prev;
349 }
350 prev = XCONS (tail)->car;
351 }
352 }
353
354 DEFUN ("next-screen", Fnext_screen, Snext_screen,
355 0, 2, 0,
356 "Return the next screen in the screen list after SCREEN.\n\
357 If MINISCREEN is non-nil, include the global-minibuffer-screen if it\n\
358 has its own screen.")
359 (screen, miniscreen)
360 Lisp_Object screen, miniscreen;
361 {
362 Lisp_Object tail;
363
364 if (NULL (screen))
365 XSET (screen, Lisp_Screen, selected_screen);
366 CHECK_SCREEN (screen, 0);
367
368 return next_screen (screen, (NULL (miniscreen) ? 0 : 1));
369 }
370 #endif /* MULTI_SCREEN */
371
372 DEFUN ("delete-screen", Fdelete_screen, Sdelete_screen,
373 0, 1, "",
374 "Delete SCREEN, permanently eliminating it from use.\n\
375 Default is current screen.")
376 (screen)
377 Lisp_Object screen;
378 {
379 struct screen *s;
380 union display displ;
381
382 if (EQ (screen, Qnil))
383 {
384 s = selected_screen;
385 XSET (screen, Lisp_Screen, s);
386 }
387 else
388 {
389 CHECK_SCREEN (screen, 0);
390 s = XSCREEN (screen);
391 }
392
393 /* Don't allow deleted screen to remain selected. */
394 if (s == selected_screen)
395 {
396 Lisp_Object next;
397
398 next = next_screen (screen, 0);
399 if (EQ (next, screen))
400 error ("Attempt to delete the only screen");
401 Fselect_screen (next, Qnil);
402 }
403
404 /* Don't allow the global minibuffer screen to be deleted */
405 if (s == XSCREEN (Vglobal_minibuffer_screen))
406 error ("Attempt to delete the global minibuffer screen");
407
408 /* Don't allow minibuf_window to remain on a deleted screen. */
409 if (EQ (s->minibuffer_window, minibuf_window))
410 {
411 Fset_window_buffer (selected_screen->minibuffer_window,
412 XWINDOW (minibuf_window)->buffer);
413 minibuf_window = selected_screen->minibuffer_window;
414 }
415
416 Vscreen_list = Fdelq (screen, Vscreen_list);
417 s->visible = 0;
418 displ = s->display;
419 s->display.nothing = 0;
420
421 if (s->output_method == output_x_window)
422 x_destroy_window (s, displ);
423
424 return Qnil;
425 }
426
427 /* Return mouse position in character cell units. */
428
429 static
430 read_mouse_position (screen, x, y)
431 Lisp_Object screen;
432 int *x, *y;
433 {
434 CHECK_SCREEN (screen, 0);
435
436 *x = 1;
437 *y = 1;
438
439 #ifdef HAVE_X_WINDOWS
440 if (XSCREEN (screen)->output_method == output_x_window)
441 x_read_mouse_position (XSCREEN (screen), x, y);
442 #endif
443 }
444
445 DEFUN ("read-mouse-position", Fread_mouse_position, Sread_mouse_position, 1, 1, 0,
446 "Return a cons (x . y) which represents the position of the mouse.")
447 (screen)
448 Lisp_Object screen;
449 {
450 int x, y;
451 struct screen *s;
452
453 CHECK_SCREEN (screen, 0);
454
455 read_mouse_position (screen, &x, &y);
456 return Fcons (make_number (x), make_number (y));
457 }
458
459 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
460 "Move the mouse pointer to the center of cell (X,Y) in SCREEN.\n\
461 WARNING: If you use this under X, you should do unfocus-screen afterwards.")
462 (screen, x, y)
463 Lisp_Object screen, x, y;
464 {
465 CHECK_SCREEN (screen, 0);
466 CHECK_NUMBER (x, 2);
467 CHECK_NUMBER (y, 1);
468
469 #ifdef HAVE_X_WINDOWS
470 if (XSCREEN (screen)->output_method == output_x_window)
471 /* Warping the mouse will cause enternotify and focus events. */
472 x_set_mouse_position (XSCREEN (screen), x, y);
473 #endif
474
475 return Qnil;
476 }
477
478 #if 0
479 /* ??? Can this be replaced with a Lisp function?
480 It is used in minibuf.c. Can we get rid of that? */
481
482 DEFUN ("screen-configuration", Fscreen_configuration, Sscreen_configuration,
483 0, 0, 0,
484 "Return object describing current screen configuration.\n\
485 The screen configuration is the current mouse position and selected screen.\n\
486 This object can be given to `restore-screen-configuration'\n\
487 to restore this screen configuration.")
488 ()
489 {
490 int x, y;
491 Lisp_Object c, screen;
492 struct screen *s;
493
494 c = Fmake_vector (make_number(3), Qnil);
495 XVECTOR (c)->contents[0] = screen = Fselected_screen();
496 read_mouse_position (screen, &x, &y);
497 XVECTOR (c)->contents[1] = make_number (x);
498 XVECTOR (c)->contents[2] = make_number (y);
499
500 return c;
501 }
502
503 DEFUN ("restore-screen-configuration", Frestore_screen_configuration,
504 Srestore_screen_configuration,
505 1, 1, 0,
506 "Restores screen configuration CONFIGURATION.")
507 (config)
508 Lisp_Object config;
509 {
510 Lisp_Object x_pos, y_pos, screen;
511
512 CHECK_VECTOR (config, 0);
513 if (XVECTOR (config)->size != 3)
514 {
515 error ("Wrong size vector passed to restore-screen-configuration");
516 }
517 screen = XVECTOR (config)->contents[0];
518 CHECK_SCREEN (screen, 0);
519
520 Fselect_screen (screen, Qnil);
521
522 #if 0
523 /* This seems to interfere with the screen selection mechanism. jla */
524 x_pos = XVECTOR (config)->contents[1];
525 y_pos = XVECTOR (config)->contents[2];
526 set_mouse_position (screen, XINT (x_pos), XINT (y_pos));
527 #endif
528
529 return screen;
530 }
531 #endif
532
533 DEFUN ("make-screen-visible", Fmake_screen_visible, Smake_screen_visible,
534 1, 1, 0,
535 "Make the screen SCREEN visible (assuming it is an X-window).\n\
536 Also raises the screen so that nothing obscures it.")
537 (screen)
538 Lisp_Object screen;
539 {
540 CHECK_SCREEN (screen, 0);
541
542 if (XSCREEN (screen)->display.nothing == 0)
543 error ("Cannot make a dead screen object visible");
544
545 if (XSCREEN (screen)->output_method == output_x_window)
546 x_make_screen_visible (XSCREEN (screen));
547
548 return screen;
549 }
550
551 DEFUN ("make-screen-invisible", Fmake_screen_invisible, Smake_screen_invisible,
552 1, 1, 0,
553 "Make the screen SCREEN invisible (assuming it is an X-window).")
554 (screen)
555 Lisp_Object screen;
556 {
557 CHECK_SCREEN (screen, 0);
558
559 if (XSCREEN (screen)->output_method == output_x_window)
560 x_make_screen_invisible (XSCREEN (screen));
561
562 return Qnil;
563 }
564
565 DEFUN ("iconify-screen", Ficonify_screen, Siconify_screen,
566 1, 1, 0,
567 "Make the screen SCREEN into an icon.")
568 (screen)
569 Lisp_Object screen;
570 {
571 CHECK_SCREEN (screen, 0);
572
573 if (XSCREEN (screen)->display.nothing == 0)
574 error ("Cannot make a dead screen object iconified.");
575
576 if (XSCREEN (screen)->output_method == output_x_window)
577 x_iconify_screen (XSCREEN (screen));
578
579 return Qnil;
580 }
581
582 DEFUN ("deiconify-screen", Fdeiconify_screen, Sdeiconify_screen,
583 1, 1, 0,
584 "Open (de-iconify) the iconified screen SCREEN.")
585 (screen)
586 Lisp_Object screen;
587 {
588 CHECK_SCREEN (screen, 0);
589
590 if (XSCREEN (screen)->display.nothing == 0)
591 error ("Cannot deiconify a dead screen object.");
592
593 if (XSCREEN (screen)->output_method == output_x_window)
594 x_make_screen_visible (XSCREEN (screen));
595
596 return screen;
597 }
598
599 DEFUN ("screen-visible-p", Fscreen_visible_p, Sscreen_visible_p,
600 1, 1, 0,
601 "Return t if SCREEN is now \"visible\" (actually in use for display).\n\
602 A screen that is not \"visible\" is not updated and, if it works through\n\
603 a window system, it may not show at all.\n\
604 Return the symbol `icon' if window is visible only as an icon.")
605 (screen)
606 Lisp_Object screen;
607 {
608 CHECK_SCREEN (screen, 0);
609
610 if (XSCREEN (screen)->visible)
611 return Qt;
612 if (XSCREEN (screen)->iconified)
613 return intern ("icon");
614 return Qnil;
615 }
616
617 DEFUN ("visible-screen-list", Fvisible_screen_list, Svisible_screen_list,
618 0, 0, 0,
619 "Return a list of all screens now \"visible\" (being updated).")
620 ()
621 {
622 Lisp_Object tail, screen;
623 struct screen *s;
624 Lisp_Object value;
625
626 value = Qnil;
627 for (tail = Vscreen_list; CONSP (tail); tail = XCONS (tail)->cdr)
628 {
629 screen = XCONS (tail)->car;
630 if (XTYPE (screen) != Lisp_Screen)
631 continue;
632 s = XSCREEN (screen);
633 if (s->visible)
634 value = Fcons (screen, value);
635 }
636 return value;
637 }
638
639 Lisp_Object
640 get_screen_param (screen, prop)
641 register struct screen *screen;
642 Lisp_Object prop;
643 {
644 register Lisp_Object tem;
645
646 tem = Fassq (prop, screen->param_alist);
647 if (EQ (tem, Qnil))
648 return tem;
649 return Fcdr (tem);
650 }
651
652 void
653 store_in_alist (alistptr, propname, val)
654 Lisp_Object *alistptr, val;
655 char *propname;
656 {
657 register Lisp_Object tem;
658 register Lisp_Object prop;
659
660 prop = intern (propname);
661 tem = Fassq (prop, *alistptr);
662 if (EQ (tem, Qnil))
663 *alistptr = Fcons (Fcons (prop, val), *alistptr);
664 else
665 Fsetcdr (tem, val);
666 }
667
668 void
669 store_screen_param (s, prop, val)
670 struct screen *s;
671 Lisp_Object prop, val;
672 {
673 register Lisp_Object tem;
674
675 tem = Fassq (prop, s->param_alist);
676 if (EQ (tem, Qnil))
677 s->param_alist = Fcons (Fcons (prop, val), s->param_alist);
678 else
679 Fsetcdr (tem, val);
680 }
681
682 DEFUN ("screen-parameters", Fscreen_parameters, Sscreen_parameters, 0, 1, 0,
683 "Return the parameters-alist of screen SCREEN.\n\
684 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.\n\
685 The meaningful PARMs depend on the kind of screen.")
686 (screen)
687 Lisp_Object screen;
688 {
689 Lisp_Object alist;
690 struct screen *s;
691
692 if (EQ (screen, Qnil))
693 s = selected_screen;
694 else
695 {
696 CHECK_SCREEN (screen, 0);
697 s = XSCREEN (screen);
698 }
699
700 if (s->display.nothing == 0)
701 return Qnil;
702
703 alist = Fcopy_alist (s->param_alist);
704 store_in_alist (&alist, "name", s->name);
705 store_in_alist (&alist, "height", make_number (s->height));
706 store_in_alist (&alist, "width", make_number (s->width));
707 store_in_alist (&alist, "modeline", (s->wants_modeline ? Qt : Qnil));
708 store_in_alist (&alist, "minibuffer", (s->has_minibuffer ? Qt : Qnil));
709 store_in_alist (&alist, "unsplittable", (s->no_split ? Qt : Qnil));
710
711 if (s->output_method == output_x_window)
712 x_report_screen_params (s, &alist);
713 return alist;
714 }
715
716 DEFUN ("modify-screen-parameters", Fmodify_screen_parameters,
717 Smodify_screen_parameters, 2, 2, 0,
718 "Modify the parameters of screen SCREEN according to ALIST.\n\
719 ALIST is an alist of parameters to change and their new values.\n\
720 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.\n\
721 The meaningful PARMs depend on the kind of screen; undefined PARMs are ignored.")
722 (screen, alist)
723 Lisp_Object screen, alist;
724 {
725 register struct screen *s;
726 register Lisp_Object tail, elt, prop, val;
727
728 if (EQ (screen, Qnil))
729 s = selected_screen;
730 else
731 {
732 CHECK_SCREEN (screen, 0);
733 s = XSCREEN (screen);
734 }
735
736 if (s->display.nothing == 0)
737 error ("Cannot modify parameters of a deleted screen");
738
739 if (s->output_method == output_x_window)
740 for (tail = alist; !EQ (tail, Qnil); tail = Fcdr (tail))
741 {
742 elt = Fcar (tail);
743 prop = Fcar (elt);
744 val = Fcdr (elt);
745 x_set_screen_param (s, prop, val,
746 get_screen_param (s, prop));
747 store_screen_param (s, prop, val);
748 }
749
750 return Qnil;
751 }
752
753
754 DEFUN ("screen-pixel-size", Fscreen_pixel_size,
755 Sscreen_pixel_size, 1, 1, 0,
756 "Return a cons (width . height) of screen SCREEN's dimensions.")
757 (screen)
758 Lisp_Object screen;
759 {
760 register struct screen *s;
761 int width, height;
762
763 CHECK_SCREEN (screen, 0);
764 s = XSCREEN (screen);
765
766 return Fcons (make_number (x_pixel_width (s)),
767 make_number (x_pixel_height (s)));
768 }
769
770 DEFUN ("screen-height", Fscreen_height, Sscreen_height, 0, 0, 0,
771 "Return number of lines available for display on selected screen.")
772 ()
773 {
774 return make_number (SCREEN_HEIGHT (selected_screen));
775 }
776
777 DEFUN ("screen-width", Fscreen_width, Sscreen_width, 0, 0, 0,
778 "Return number of columns available for display on selected screen.")
779 ()
780 {
781 return make_number (SCREEN_WIDTH (selected_screen));
782 }
783
784 DEFUN ("set-screen-height", Fset_screen_height, Sset_screen_height, 2, 3, 0,
785 "Specify that the screen SCREEN has LINES lines.\n\
786 Optional third arg non-nil means that redisplay should use LINES lines\n\
787 but that the idea of the actual height of the screen should not be changed.")
788 (screen, rows, pretend)
789 Lisp_Object rows, pretend;
790 {
791 register struct screen *s;
792
793 CHECK_NUMBER (rows, 0);
794 if (NULL (screen))
795 s = selected_screen;
796 else
797 {
798 CHECK_SCREEN (screen, 0);
799 s = XSCREEN (screen);
800 }
801
802 if (s->output_method == output_x_window)
803 {
804 if (XINT (rows) != s->width)
805 x_set_window_size (s, s->width, XINT (rows));
806 }
807 else
808 change_screen_size (s, XINT (rows), 0, !NULL (pretend));
809 return Qnil;
810 }
811
812 DEFUN ("set-screen-width", Fset_screen_width, Sset_screen_width, 2, 3, 0,
813 "Specify that the screen SCREEN has COLS columns.\n\
814 Optional third arg non-nil means that redisplay should use COLS columns\n\
815 but that the idea of the actual width of the screen should not be changed.")
816 (screen, cols, pretend)
817 Lisp_Object cols, pretend;
818 {
819 register struct screen *s;
820 CHECK_NUMBER (cols, 0);
821 if (NULL (screen))
822 s = selected_screen;
823 else
824 {
825 CHECK_SCREEN (screen, 0);
826 s = XSCREEN (screen);
827 }
828
829 if (s->output_method == output_x_window)
830 {
831 if (XINT (cols) != s->width)
832 x_set_window_size (s, XINT (cols), s->height);
833 }
834 else
835 change_screen_size (selected_screen, 0, XINT (cols), !NULL (pretend));
836 return Qnil;
837 }
838
839 DEFUN ("set-screen-size", Fset_screen_size,
840 Sset_screen_size, 3, 3, 0,
841 "Sets size of SCREEN to COLS by ROWS, measured in characters.")
842 (screen, cols, rows)
843 Lisp_Object screen, cols, rows;
844 {
845 register struct screen *s;
846 int mask;
847
848 CHECK_SCREEN (screen, 0);
849 CHECK_NUMBER (cols, 2);
850 CHECK_NUMBER (rows, 1);
851 s = XSCREEN (screen);
852
853 if (s->output_method == output_x_window)
854 {
855 if (XINT (rows) != s->height || XINT (cols) != s->width)
856 x_set_window_size (s, XINT (cols), XINT (rows));
857 }
858 else
859 change_screen_size (s, XINT (rows), XINT (cols), 0);
860
861 return Qnil;
862 }
863
864 DEFUN ("set-screen-position", Fset_screen_position,
865 Sset_screen_position, 3, 3, 0,
866 "Sets size of SCREEN in pixels to XOFFSET by YOFFSET.")
867 (screen, xoffset, yoffset)
868 Lisp_Object screen, xoffset, yoffset;
869 {
870 register struct screen *s;
871 int mask;
872
873 CHECK_SCREEN (screen, 0);
874 CHECK_NUMBER (xoffset, 1);
875 CHECK_NUMBER (yoffset, 2);
876 s = XSCREEN (screen);
877
878 if (s->output_method == output_x_window)
879 x_set_offset (s, XINT (xoffset), XINT (yoffset));
880
881 return Qt;
882 }
883
884 /* Test if column *x, row *y is within window *w. If they are not,
885 return 0; if they are on the window's modeline, return -1; if
886 they are in the window's text area (the only other alternative)
887 set *x and *y to their locations relative to the upper left
888 corner of the window, and return 1. */
889 int
890 coordinates_in_window (w, x, y)
891 register struct window *w;
892 register int *x, *y;
893 {
894 register int left = XINT (w->left);
895 register int width = XINT (w->width);
896 register int screen_height = XINT ((XSCREEN (w->screen)->height));
897 register int window_height = XINT (w->height);
898 register int top = XFASTINT (w->top);
899
900 if (*x < left || *x >= left + width
901 || *y == screen_height || *y < top || *y > top + window_height - 1)
902 return 0;
903
904 if (*y == top + window_height - 1
905 && window_height > 1) /* 1 line => minibuffer */
906 /* in modeline */
907 return -1;
908
909 *x -= left;
910 *y -= top;
911 return 1;
912 }
913
914 DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
915 Scoordinates_in_window_p, 2, 2, 0,
916 "Return non-nil if COORDINATES are in WINDOW.\n\
917 COORDINATES is a cons of the form (X Y), X and Y being screen-relative.\n\
918 If COORDINATES are in the text portion of WINDOW, the coordinates relative\n\
919 to the window are returned. If they are in the modeline of WINDOW, t is\n\
920 returned.")
921 (coordinates, window)
922 register Lisp_Object coordinates, window;
923 {
924 int x, y;
925
926 CHECK_WINDOW (window, 0);
927 CHECK_CONS (coordinates, 1);
928 x = XINT (Fcar (coordinates));
929 y = XINT (Fcar (Fcdr (coordinates)));
930
931 switch (coordinates_in_window (XWINDOW (window), &x, &y))
932 {
933 case -1: /* In modeline of window. */
934 return Qt;
935
936 case 0: /* NOT in window at all. */
937 return Qnil;
938
939 case 1: /* In text part of window. */
940 return Fcons (x, Fcons (y, Qnil));
941
942 default:
943 abort ();
944 }
945 }
946
947 #ifndef HAVE_X11
948 DEFUN ("rubber-band-rectangle", Frubber_band_rectangle, Srubber_band_rectangle,
949 3, 3, "",
950 "Ask user to specify a window position and size on SCREEN with the mouse.\n\
951 Arguments are SCREEN, NAME and GEO. NAME is a name to be displayed as\n\
952 the purpose of this rectangle. GEO is an X-windows size spec that can\n\
953 specify defaults for some sizes/positions. If GEO specifies everything,\n\
954 the mouse is not used.\n\
955 Returns a list of five values: (SCREEN LEFT TOP WIDTH HEIGHT).")
956 (screen, name, geo)
957 Lisp_Object screen;
958 Lisp_Object name;
959 Lisp_Object geo;
960 {
961 int vals[4];
962 Lisp_Object nums[4];
963 int i;
964
965 CHECK_SCREEN (screen, 0);
966 CHECK_STRING (name, 1);
967 CHECK_STRING (geo, 2);
968
969 switch (XSCREEN (screen)->output_method)
970 {
971 case output_x_window:
972 x_rubber_band (XSCREEN (screen), &vals[0], &vals[1], &vals[2], &vals[3],
973 XSTRING (geo)->data, XSTRING (name)->data);
974 break;
975
976 default:
977 return Qnil;
978 }
979
980 for (i = 0; i < 4; i++)
981 XFASTINT (nums[i]) = vals[i];
982 return Fcons (screen, Flist (4, nums));
983 return Qnil;
984 }
985 #endif /* not HAVE_X11 */
986
987 choose_minibuf_screen ()
988 {
989 /* For lowest-level minibuf, put it on currently selected screen
990 if screen has a minibuffer. */
991 if (minibuf_level == 0
992 && selected_screen != 0
993 && !EQ (minibuf_window, selected_screen->minibuffer_window)
994 && !EQ (Qnil, selected_screen->minibuffer_window))
995 {
996 Fset_window_buffer (selected_screen->minibuffer_window,
997 XWINDOW (minibuf_window)->buffer);
998 minibuf_window = selected_screen->minibuffer_window;
999 }
1000 }
1001
1002 syms_of_screen ()
1003 {
1004 Qscreenp = intern ("screenp");
1005
1006 staticpro (&Vscreen_list);
1007
1008 DEFVAR_LISP ("terminal-screen", &Vterminal_screen,
1009 "The initial screen-object, which represents Emacs's stdout.");
1010
1011 DEFVAR_LISP ("emacs-iconified", &Vemacs_iconified,
1012 "Non-nil if all of emacs is iconified and not screen updates are needed.");
1013 Vemacs_iconified = Qnil;
1014
1015 DEFVAR_LISP ("global-minibuffer-screen", &Vglobal_minibuffer_screen,
1016 "A screen whose minibuffer is used by minibufferless screens.\n\
1017 When you create a minibufferless screen, by default it will use the\n\
1018 minibuffer of this screen. It is up to you to create a suitable screen\n\
1019 and store it in this variable.");
1020 Vglobal_minibuffer_screen = Qnil;
1021
1022 defsubr (&Sscreenp);
1023 defsubr (&Sselect_screen);
1024 defsubr (&Sselected_screen);
1025 defsubr (&Swindow_screen);
1026 defsubr (&Sscreen_root_window);
1027 defsubr (&Sscreen_selected_window);
1028 defsubr (&Sscreen_list);
1029 defsubr (&Snext_screen);
1030 defsubr (&Sdelete_screen);
1031 defsubr (&Sread_mouse_position);
1032 defsubr (&Sset_mouse_position);
1033 #if 0
1034 defsubr (&Sscreen_configuration);
1035 defsubr (&Srestore_screen_configuration);
1036 #endif
1037 defsubr (&Smake_screen_visible);
1038 defsubr (&Smake_screen_invisible);
1039 defsubr (&Siconify_screen);
1040 defsubr (&Sdeiconify_screen);
1041 defsubr (&Sscreen_visible_p);
1042 defsubr (&Svisible_screen_list);
1043 defsubr (&Sscreen_parameters);
1044 defsubr (&Smodify_screen_parameters);
1045 defsubr (&Sscreen_pixel_size);
1046 defsubr (&Sscreen_height);
1047 defsubr (&Sscreen_width);
1048 defsubr (&Sset_screen_height);
1049 defsubr (&Sset_screen_width);
1050 defsubr (&Sset_screen_size);
1051 defsubr (&Sset_screen_position);
1052 defsubr (&Scoordinates_in_window_p);
1053 #ifndef HAVE_X11
1054 defsubr (&Srubber_band_rectangle);
1055 #endif /* HAVE_X11 */
1056 }