Mercurial > emacs
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 } |