(Vemacs_iconified): Remove.
[bpt/emacs.git] / src / frame.c
1 /* Generic frame functions.
2 Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include <config.h>
21
22 #include <stdio.h>
23 #include <ctype.h>
24 #include "lisp.h"
25 #include "character.h"
26 #ifdef HAVE_X_WINDOWS
27 #include "xterm.h"
28 #endif
29 #ifdef WINDOWSNT
30 #include "w32term.h"
31 #endif
32 #ifdef HAVE_NS
33 #include "nsterm.h"
34 #endif
35 #include "buffer.h"
36 /* These help us bind and responding to switch-frame events. */
37 #include "commands.h"
38 #include "keyboard.h"
39 #include "frame.h"
40 #include "blockinput.h"
41 #include "termchar.h"
42 #include "termhooks.h"
43 #include "dispextern.h"
44 #include "window.h"
45 #ifdef HAVE_WINDOW_SYSTEM
46 #include "font.h"
47 #include "fontset.h"
48 #endif
49 #ifdef MSDOS
50 #include "msdos.h"
51 #include "dosfns.h"
52 #endif
53
54
55 #ifdef HAVE_WINDOW_SYSTEM
56
57 /* The name we're using in resource queries. Most often "emacs". */
58
59 Lisp_Object Vx_resource_name;
60
61 /* The application class we're using in resource queries.
62 Normally "Emacs". */
63
64 Lisp_Object Vx_resource_class;
65
66 /* Lower limit value of the frame opacity (alpha transparency). */
67
68 Lisp_Object Vframe_alpha_lower_limit;
69
70 #endif
71
72 #ifdef HAVE_NS
73 Lisp_Object Qns_parse_geometry;
74 #endif
75
76 Lisp_Object Qframep, Qframe_live_p;
77 Lisp_Object Qicon, Qmodeline;
78 Lisp_Object Qonly;
79 Lisp_Object Qx, Qw32, Qmac, Qpc, Qns;
80 Lisp_Object Qvisible;
81 Lisp_Object Qdisplay_type;
82 Lisp_Object Qbackground_mode;
83 Lisp_Object Qnoelisp;
84
85 Lisp_Object Qx_frame_parameter;
86 Lisp_Object Qx_resource_name;
87 Lisp_Object Qterminal;
88 Lisp_Object Qterminal_live_p;
89
90 /* Frame parameters (set or reported). */
91
92 Lisp_Object Qauto_raise, Qauto_lower;
93 Lisp_Object Qborder_color, Qborder_width;
94 Lisp_Object Qcursor_color, Qcursor_type;
95 Lisp_Object Qgeometry; /* Not used */
96 Lisp_Object Qheight, Qwidth;
97 Lisp_Object Qleft, Qright;
98 Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
99 Lisp_Object Qinternal_border_width;
100 Lisp_Object Qmouse_color;
101 Lisp_Object Qminibuffer;
102 Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
103 Lisp_Object Qvisibility;
104 Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
105 Lisp_Object Qscreen_gamma;
106 Lisp_Object Qline_spacing;
107 Lisp_Object Quser_position, Quser_size;
108 Lisp_Object Qwait_for_wm;
109 Lisp_Object Qwindow_id;
110 #ifdef HAVE_X_WINDOWS
111 Lisp_Object Qouter_window_id;
112 #endif
113 Lisp_Object Qparent_id;
114 Lisp_Object Qtitle, Qname;
115 Lisp_Object Qexplicit_name;
116 Lisp_Object Qunsplittable;
117 Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
118 Lisp_Object Qleft_fringe, Qright_fringe;
119 Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
120 Lisp_Object Qtty_color_mode;
121 Lisp_Object Qtty, Qtty_type;
122
123 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
124 Lisp_Object Qfont_backend;
125 Lisp_Object Qalpha;
126
127 Lisp_Object Qface_set_after_frame_default;
128
129 Lisp_Object Vterminal_frame;
130 Lisp_Object Vdefault_frame_alist;
131 Lisp_Object Vdefault_frame_scroll_bars;
132 Lisp_Object Vmouse_position_function;
133 Lisp_Object Vmouse_highlight;
134 static Lisp_Object Vdelete_frame_functions, Qdelete_frame_functions;
135
136 int focus_follows_mouse;
137 \f
138 static void
139 set_menu_bar_lines_1 (window, n)
140 Lisp_Object window;
141 int n;
142 {
143 struct window *w = XWINDOW (window);
144
145 XSETFASTINT (w->last_modified, 0);
146 XSETFASTINT (w->top_line, XFASTINT (w->top_line) + n);
147 XSETFASTINT (w->total_lines, XFASTINT (w->total_lines) - n);
148
149 if (INTEGERP (w->orig_top_line))
150 XSETFASTINT (w->orig_top_line, XFASTINT (w->orig_top_line) + n);
151 if (INTEGERP (w->orig_total_lines))
152 XSETFASTINT (w->orig_total_lines, XFASTINT (w->orig_total_lines) - n);
153
154 /* Handle just the top child in a vertical split. */
155 if (!NILP (w->vchild))
156 set_menu_bar_lines_1 (w->vchild, n);
157
158 /* Adjust all children in a horizontal split. */
159 for (window = w->hchild; !NILP (window); window = w->next)
160 {
161 w = XWINDOW (window);
162 set_menu_bar_lines_1 (window, n);
163 }
164 }
165
166 void
167 set_menu_bar_lines (f, value, oldval)
168 struct frame *f;
169 Lisp_Object value, oldval;
170 {
171 int nlines;
172 int olines = FRAME_MENU_BAR_LINES (f);
173
174 /* Right now, menu bars don't work properly in minibuf-only frames;
175 most of the commands try to apply themselves to the minibuffer
176 frame itself, and get an error because you can't switch buffers
177 in or split the minibuffer window. */
178 if (FRAME_MINIBUF_ONLY_P (f))
179 return;
180
181 if (INTEGERP (value))
182 nlines = XINT (value);
183 else
184 nlines = 0;
185
186 if (nlines != olines)
187 {
188 windows_or_buffers_changed++;
189 FRAME_WINDOW_SIZES_CHANGED (f) = 1;
190 FRAME_MENU_BAR_LINES (f) = nlines;
191 set_menu_bar_lines_1 (f->root_window, nlines - olines);
192 adjust_glyphs (f);
193 }
194 }
195 \f
196 Lisp_Object Vframe_list;
197
198 extern Lisp_Object Vminibuffer_list;
199 extern Lisp_Object get_minibuffer ();
200 extern Lisp_Object Fhandle_switch_frame ();
201 extern Lisp_Object Fredirect_frame_focus ();
202 extern Lisp_Object x_get_focus_frame ();
203 \f
204 DEFUN ("framep", Fframep, Sframep, 1, 1, 0,
205 doc: /* Return non-nil if OBJECT is a frame.
206 Value is t for a termcap frame (a character-only terminal),
207 `x' for an Emacs frame that is really an X window,
208 `w32' for an Emacs frame that is a window on MS-Windows display,
209 `ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
210 `pc' for a direct-write MS-DOS frame.
211 See also `frame-live-p'. */)
212 (object)
213 Lisp_Object object;
214 {
215 if (!FRAMEP (object))
216 return Qnil;
217 switch (XFRAME (object)->output_method)
218 {
219 case output_initial: /* The initial frame is like a termcap frame. */
220 case output_termcap:
221 return Qt;
222 case output_x_window:
223 return Qx;
224 case output_w32:
225 return Qw32;
226 case output_msdos_raw:
227 return Qpc;
228 case output_mac:
229 return Qmac;
230 case output_ns:
231 return Qns;
232 default:
233 abort ();
234 }
235 }
236
237 DEFUN ("frame-live-p", Fframe_live_p, Sframe_live_p, 1, 1, 0,
238 doc: /* Return non-nil if OBJECT is a frame which has not been deleted.
239 Value is nil if OBJECT is not a live frame. If object is a live
240 frame, the return value indicates what sort of terminal device it is
241 displayed on. See the documentation of `framep' for possible
242 return values. */)
243 (object)
244 Lisp_Object object;
245 {
246 return ((FRAMEP (object)
247 && FRAME_LIVE_P (XFRAME (object)))
248 ? Fframep (object)
249 : Qnil);
250 }
251
252 DEFUN ("window-system", Fwindow_system, Swindow_system, 0, 1, 0,
253 doc: /* The name of the window system that FRAME is displaying through.
254 The value is a symbol---for instance, 'x' for X windows.
255 The value is nil if Emacs is using a text-only terminal.
256
257 FRAME defaults to the currently selected frame. */)
258 (frame)
259 Lisp_Object frame;
260 {
261 Lisp_Object type;
262 if (NILP (frame))
263 frame = selected_frame;
264
265 type = Fframep (frame);
266
267 if (NILP (type))
268 wrong_type_argument (Qframep, frame);
269
270 if (EQ (type, Qt))
271 return Qnil;
272 else
273 return type;
274 }
275
276 struct frame *
277 make_frame (mini_p)
278 int mini_p;
279 {
280 Lisp_Object frame;
281 register struct frame *f;
282 register Lisp_Object root_window;
283 register Lisp_Object mini_window;
284
285 f = allocate_frame ();
286 XSETFRAME (frame, f);
287
288 f->desired_matrix = 0;
289 f->current_matrix = 0;
290 f->desired_pool = 0;
291 f->current_pool = 0;
292 f->glyphs_initialized_p = 0;
293 f->decode_mode_spec_buffer = 0;
294 f->visible = 0;
295 f->async_visible = 0;
296 f->output_data.nothing = 0;
297 f->iconified = 0;
298 f->async_iconified = 0;
299 f->wants_modeline = 1;
300 f->auto_raise = 0;
301 f->auto_lower = 0;
302 f->no_split = 0;
303 f->garbaged = 1;
304 f->has_minibuffer = mini_p;
305 f->focus_frame = Qnil;
306 f->explicit_name = 0;
307 f->can_have_scroll_bars = 0;
308 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
309 f->param_alist = Qnil;
310 f->scroll_bars = Qnil;
311 f->condemned_scroll_bars = Qnil;
312 f->face_alist = Qnil;
313 f->face_cache = NULL;
314 f->menu_bar_items = Qnil;
315 f->menu_bar_vector = Qnil;
316 f->menu_bar_items_used = 0;
317 f->buffer_predicate = Qnil;
318 f->buffer_list = Qnil;
319 f->buried_buffer_list = Qnil;
320 f->namebuf = 0;
321 f->title = Qnil;
322 f->menu_bar_window = Qnil;
323 f->tool_bar_window = Qnil;
324 f->tool_bar_items = Qnil;
325 f->desired_tool_bar_string = f->current_tool_bar_string = Qnil;
326 f->n_tool_bar_items = 0;
327 f->left_fringe_width = f->right_fringe_width = 0;
328 f->fringe_cols = 0;
329 f->scroll_bar_actual_width = 0;
330 f->border_width = 0;
331 f->internal_border_width = 0;
332 f->column_width = 1; /* !FRAME_WINDOW_P value */
333 f->line_height = 1; /* !FRAME_WINDOW_P value */
334 f->x_pixels_diff = f->y_pixels_diff = 0;
335 #ifdef HAVE_WINDOW_SYSTEM
336 f->want_fullscreen = FULLSCREEN_NONE;
337 #endif
338 f->size_hint_flags = 0;
339 f->win_gravity = 0;
340 f->font_driver_list = NULL;
341 f->font_data_list = NULL;
342
343 root_window = make_window ();
344 if (mini_p)
345 {
346 mini_window = make_window ();
347 XWINDOW (root_window)->next = mini_window;
348 XWINDOW (mini_window)->prev = root_window;
349 XWINDOW (mini_window)->mini_p = Qt;
350 XWINDOW (mini_window)->frame = frame;
351 f->minibuffer_window = mini_window;
352 }
353 else
354 {
355 mini_window = Qnil;
356 XWINDOW (root_window)->next = Qnil;
357 f->minibuffer_window = Qnil;
358 }
359
360 XWINDOW (root_window)->frame = frame;
361
362 /* 10 is arbitrary,
363 just so that there is "something there."
364 Correct size will be set up later with change_frame_size. */
365
366 SET_FRAME_COLS (f, 10);
367 FRAME_LINES (f) = 10;
368
369 XSETFASTINT (XWINDOW (root_window)->total_cols, 10);
370 XSETFASTINT (XWINDOW (root_window)->total_lines, (mini_p ? 9 : 10));
371
372 if (mini_p)
373 {
374 XSETFASTINT (XWINDOW (mini_window)->total_cols, 10);
375 XSETFASTINT (XWINDOW (mini_window)->top_line, 9);
376 XSETFASTINT (XWINDOW (mini_window)->total_lines, 1);
377 }
378
379 /* Choose a buffer for the frame's root window. */
380 {
381 Lisp_Object buf;
382
383 XWINDOW (root_window)->buffer = Qt;
384 buf = Fcurrent_buffer ();
385 /* If buf is a 'hidden' buffer (i.e. one whose name starts with
386 a space), try to find another one. */
387 if (SREF (Fbuffer_name (buf), 0) == ' ')
388 buf = Fother_buffer (buf, Qnil, Qnil);
389
390 /* Use set_window_buffer, not Fset_window_buffer, and don't let
391 hooks be run by it. The reason is that the whole frame/window
392 arrangement is not yet fully intialized at this point. Windows
393 don't have the right size, glyph matrices aren't initialized
394 etc. Running Lisp functions at this point surely ends in a
395 SEGV. */
396 set_window_buffer (root_window, buf, 0, 0);
397 f->buffer_list = Fcons (buf, Qnil);
398 }
399
400 if (mini_p)
401 {
402 XWINDOW (mini_window)->buffer = Qt;
403 set_window_buffer (mini_window,
404 (NILP (Vminibuffer_list)
405 ? get_minibuffer (0)
406 : Fcar (Vminibuffer_list)),
407 0, 0);
408 }
409
410 f->root_window = root_window;
411 f->selected_window = root_window;
412 /* Make sure this window seems more recently used than
413 a newly-created, never-selected window. */
414 ++window_select_count;
415 XSETFASTINT (XWINDOW (f->selected_window)->use_time, window_select_count);
416
417 f->default_face_done_p = 0;
418
419 return f;
420 }
421 \f
422 #ifdef HAVE_WINDOW_SYSTEM
423 /* Make a frame using a separate minibuffer window on another frame.
424 MINI_WINDOW is the minibuffer window to use. nil means use the
425 default (the global minibuffer). */
426
427 struct frame *
428 make_frame_without_minibuffer (mini_window, kb, display)
429 register Lisp_Object mini_window;
430 KBOARD *kb;
431 Lisp_Object display;
432 {
433 register struct frame *f;
434 struct gcpro gcpro1;
435
436 if (!NILP (mini_window))
437 CHECK_LIVE_WINDOW (mini_window);
438
439 if (!NILP (mini_window)
440 && FRAME_KBOARD (XFRAME (XWINDOW (mini_window)->frame)) != kb)
441 error ("Frame and minibuffer must be on the same terminal");
442
443 /* Make a frame containing just a root window. */
444 f = make_frame (0);
445
446 if (NILP (mini_window))
447 {
448 /* Use default-minibuffer-frame if possible. */
449 if (!FRAMEP (kb->Vdefault_minibuffer_frame)
450 || ! FRAME_LIVE_P (XFRAME (kb->Vdefault_minibuffer_frame)))
451 {
452 Lisp_Object frame_dummy;
453
454 XSETFRAME (frame_dummy, f);
455 GCPRO1 (frame_dummy);
456 /* If there's no minibuffer frame to use, create one. */
457 kb->Vdefault_minibuffer_frame =
458 call1 (intern ("make-initial-minibuffer-frame"), display);
459 UNGCPRO;
460 }
461
462 mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
463 }
464
465 f->minibuffer_window = mini_window;
466
467 /* Make the chosen minibuffer window display the proper minibuffer,
468 unless it is already showing a minibuffer. */
469 if (NILP (Fmemq (XWINDOW (mini_window)->buffer, Vminibuffer_list)))
470 Fset_window_buffer (mini_window,
471 (NILP (Vminibuffer_list)
472 ? get_minibuffer (0)
473 : Fcar (Vminibuffer_list)), Qnil);
474 return f;
475 }
476
477 /* Make a frame containing only a minibuffer window. */
478
479 struct frame *
480 make_minibuffer_frame ()
481 {
482 /* First make a frame containing just a root window, no minibuffer. */
483
484 register struct frame *f = make_frame (0);
485 register Lisp_Object mini_window;
486 register Lisp_Object frame;
487
488 XSETFRAME (frame, f);
489
490 f->auto_raise = 0;
491 f->auto_lower = 0;
492 f->no_split = 1;
493 f->wants_modeline = 0;
494 f->has_minibuffer = 1;
495
496 /* Now label the root window as also being the minibuffer.
497 Avoid infinite looping on the window chain by marking next pointer
498 as nil. */
499
500 mini_window = f->minibuffer_window = f->root_window;
501 XWINDOW (mini_window)->mini_p = Qt;
502 XWINDOW (mini_window)->next = Qnil;
503 XWINDOW (mini_window)->prev = Qnil;
504 XWINDOW (mini_window)->frame = frame;
505
506 /* Put the proper buffer in that window. */
507
508 Fset_window_buffer (mini_window,
509 (NILP (Vminibuffer_list)
510 ? get_minibuffer (0)
511 : Fcar (Vminibuffer_list)), Qnil);
512 return f;
513 }
514 #endif /* HAVE_WINDOW_SYSTEM */
515 \f
516 /* Construct a frame that refers to a terminal. */
517
518 static int tty_frame_count;
519
520 struct frame *
521 make_initial_frame (void)
522 {
523 struct frame *f;
524 struct terminal *terminal;
525 Lisp_Object frame;
526
527 eassert (initial_kboard);
528
529 /* The first call must initialize Vframe_list. */
530 if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
531 Vframe_list = Qnil;
532
533 terminal = init_initial_terminal ();
534
535 f = make_frame (1);
536 XSETFRAME (frame, f);
537
538 Vframe_list = Fcons (frame, Vframe_list);
539
540 tty_frame_count = 1;
541 f->name = build_string ("F1");
542
543 f->visible = 1;
544 f->async_visible = 1;
545
546 f->output_method = terminal->type;
547 f->terminal = terminal;
548 f->terminal->reference_count++;
549 f->output_data.nothing = 0;
550
551 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
552 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
553
554 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
555 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
556
557 #ifdef CANNOT_DUMP
558 if (!noninteractive)
559 init_frame_faces (f);
560 #endif
561
562 return f;
563 }
564
565
566 struct frame *
567 make_terminal_frame (struct terminal *terminal)
568 {
569 register struct frame *f;
570 Lisp_Object frame;
571 char name[20];
572
573 if (!terminal->name)
574 error ("Terminal is not live, can't create new frames on it");
575
576 f = make_frame (1);
577
578 XSETFRAME (frame, f);
579 Vframe_list = Fcons (frame, Vframe_list);
580
581 tty_frame_count++;
582 sprintf (name, "F%d", tty_frame_count);
583 f->name = build_string (name);
584
585 f->visible = 1; /* FRAME_SET_VISIBLE wd set frame_garbaged. */
586 f->async_visible = 1; /* Don't let visible be cleared later. */
587 f->terminal = terminal;
588 f->terminal->reference_count++;
589 #ifdef MSDOS
590 f->output_data.tty->display_info = &the_only_display_info;
591 if (!inhibit_window_system
592 && (!FRAMEP (selected_frame) || !FRAME_LIVE_P (XFRAME (selected_frame))
593 || XFRAME (selected_frame)->output_method == output_msdos_raw))
594 f->output_method = output_msdos_raw;
595 else
596 f->output_method = output_termcap;
597 #else
598 {
599 f->output_method = output_termcap;
600 create_tty_output (f);
601
602 FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
603 FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
604 }
605
606 #ifdef CANNOT_DUMP
607 FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
608 FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
609 #endif
610 #endif /* MSDOS */
611
612 FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
613 FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
614
615 /* Set the top frame to the newly created frame. */
616 if (FRAMEP (FRAME_TTY (f)->top_frame)
617 && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
618 XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
619
620 FRAME_TTY (f)->top_frame = frame;
621
622 if (!noninteractive)
623 init_frame_faces (f);
624
625 return f;
626 }
627
628 /* Get a suitable value for frame parameter PARAMETER for a newly
629 created frame, based on (1) the user-supplied frame parameter
630 alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
631 fails, (3) Vdefault_frame_alist. */
632
633 static Lisp_Object
634 get_future_frame_param (Lisp_Object parameter,
635 Lisp_Object supplied_parms,
636 char *current_value)
637 {
638 Lisp_Object result;
639
640 result = Fassq (parameter, supplied_parms);
641 if (NILP (result))
642 result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
643 if (NILP (result) && current_value != NULL)
644 result = build_string (current_value);
645 if (NILP (result))
646 result = Fassq (parameter, Vdefault_frame_alist);
647 if (!NILP (result) && !STRINGP (result))
648 result = XCDR (result);
649 if (NILP (result) || !STRINGP (result))
650 result = Qnil;
651
652 return result;
653 }
654
655 DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
656 1, 1, 0,
657 doc: /* Create an additional terminal frame, possibly on another terminal.
658 This function takes one argument, an alist specifying frame parameters.
659
660 You can create multiple frames on a single text-only terminal, but
661 only one of them (the selected terminal frame) is actually displayed.
662
663 In practice, generally you don't need to specify any parameters,
664 except when you want to create a new frame on another terminal.
665 In that case, the `tty' parameter specifies the device file to open,
666 and the `tty-type' parameter specifies the terminal type. Example:
667
668 (make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
669
670 Note that changing the size of one terminal frame automatically
671 affects all frames on the same terminal device. */)
672 (parms)
673 Lisp_Object parms;
674 {
675 struct frame *f;
676 struct terminal *t = NULL;
677 Lisp_Object frame, tem;
678 struct frame *sf = SELECTED_FRAME ();
679
680 #ifdef MSDOS
681 if (sf->output_method != output_msdos_raw
682 && sf->output_method != output_termcap)
683 abort ();
684 #else /* not MSDOS */
685
686 #ifdef WINDOWSNT /* This should work now! */
687 if (sf->output_method != output_termcap)
688 error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
689 #endif
690 #endif /* not MSDOS */
691
692 {
693 Lisp_Object terminal;
694
695 terminal = Fassq (Qterminal, parms);
696 if (!NILP (terminal))
697 {
698 terminal = XCDR (terminal);
699 t = get_terminal (terminal, 1);
700 }
701 #ifdef MSDOS
702 if (t && t != the_only_display_info.terminal)
703 /* msdos.c assumes a single tty_display_info object. */
704 error ("Multiple terminals are not supported on this platform");
705 if (!t)
706 t = the_only_display_info.terminal;
707 #endif
708 }
709
710 if (!t)
711 {
712 char *name = 0, *type = 0;
713 Lisp_Object tty, tty_type;
714
715 tty = get_future_frame_param
716 (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
717 ? FRAME_TTY (XFRAME (selected_frame))->name
718 : NULL));
719 if (!NILP (tty))
720 {
721 name = (char *) alloca (SBYTES (tty) + 1);
722 strncpy (name, SDATA (tty), SBYTES (tty));
723 name[SBYTES (tty)] = 0;
724 }
725
726 tty_type = get_future_frame_param
727 (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
728 ? FRAME_TTY (XFRAME (selected_frame))->type
729 : NULL));
730 if (!NILP (tty_type))
731 {
732 type = (char *) alloca (SBYTES (tty_type) + 1);
733 strncpy (type, SDATA (tty_type), SBYTES (tty_type));
734 type[SBYTES (tty_type)] = 0;
735 }
736
737 t = init_tty (name, type, 0); /* Errors are not fatal. */
738 }
739
740 f = make_terminal_frame (t);
741
742 {
743 int width, height;
744 get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
745 change_frame_size (f, height, width, 0, 0, 0);
746 }
747
748 adjust_glyphs (f);
749 calculate_costs (f);
750 XSETFRAME (frame, f);
751 Fmodify_frame_parameters (frame, Vdefault_frame_alist);
752 Fmodify_frame_parameters (frame, parms);
753 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
754 build_string (t->display_info.tty->type)),
755 Qnil));
756 if (t->display_info.tty->name != NULL)
757 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
758 build_string (t->display_info.tty->name)),
759 Qnil));
760 else
761 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
762
763 /* Make the frame face alist be frame-specific, so that each
764 frame could change its face definitions independently. */
765 f->face_alist = Fcopy_alist (sf->face_alist);
766 /* Simple Fcopy_alist isn't enough, because we need the contents of
767 the vectors which are the CDRs of associations in face_alist to
768 be copied as well. */
769 for (tem = f->face_alist; CONSP (tem); tem = XCDR (tem))
770 XSETCDR (XCAR (tem), Fcopy_sequence (XCDR (XCAR (tem))));
771 return frame;
772 }
773
774 \f
775 /* Perform the switch to frame FRAME.
776
777 If FRAME is a switch-frame event `(switch-frame FRAME1)', use
778 FRAME1 as frame.
779
780 If TRACK is non-zero and the frame that currently has the focus
781 redirects its focus to the selected frame, redirect that focused
782 frame's focus to FRAME instead.
783
784 FOR_DELETION non-zero means that the selected frame is being
785 deleted, which includes the possibility that the frame's terminal
786 is dead.
787
788 The value of NORECORD is passed as argument to Fselect_window. */
789
790 Lisp_Object
791 do_switch_frame (frame, track, for_deletion, norecord)
792 Lisp_Object frame, norecord;
793 int track, for_deletion;
794 {
795 struct frame *sf = SELECTED_FRAME ();
796
797 /* If FRAME is a switch-frame event, extract the frame we should
798 switch to. */
799 if (CONSP (frame)
800 && EQ (XCAR (frame), Qswitch_frame)
801 && CONSP (XCDR (frame)))
802 frame = XCAR (XCDR (frame));
803
804 /* This used to say CHECK_LIVE_FRAME, but apparently it's possible for
805 a switch-frame event to arrive after a frame is no longer live,
806 especially when deleting the initial frame during startup. */
807 CHECK_FRAME (frame);
808 if (! FRAME_LIVE_P (XFRAME (frame)))
809 return Qnil;
810
811 if (sf == XFRAME (frame))
812 return frame;
813
814 /* This is too greedy; it causes inappropriate focus redirection
815 that's hard to get rid of. */
816 #if 0
817 /* If a frame's focus has been redirected toward the currently
818 selected frame, we should change the redirection to point to the
819 newly selected frame. This means that if the focus is redirected
820 from a minibufferless frame to a surrogate minibuffer frame, we
821 can use `other-window' to switch between all the frames using
822 that minibuffer frame, and the focus redirection will follow us
823 around. */
824 if (track)
825 {
826 Lisp_Object tail;
827
828 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
829 {
830 Lisp_Object focus;
831
832 if (!FRAMEP (XCAR (tail)))
833 abort ();
834
835 focus = FRAME_FOCUS_FRAME (XFRAME (XCAR (tail)));
836
837 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
838 Fredirect_frame_focus (XCAR (tail), frame);
839 }
840 }
841 #else /* ! 0 */
842 /* Instead, apply it only to the frame we're pointing to. */
843 #ifdef HAVE_WINDOW_SYSTEM
844 if (track && FRAME_WINDOW_P (XFRAME (frame)))
845 {
846 Lisp_Object focus, xfocus;
847
848 xfocus = x_get_focus_frame (XFRAME (frame));
849 if (FRAMEP (xfocus))
850 {
851 focus = FRAME_FOCUS_FRAME (XFRAME (xfocus));
852 if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
853 Fredirect_frame_focus (xfocus, frame);
854 }
855 }
856 #endif /* HAVE_X_WINDOWS */
857 #endif /* ! 0 */
858
859 if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
860 resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
861
862 if (FRAME_TERMCAP_P (XFRAME (frame)) || FRAME_MSDOS_P (XFRAME (frame)))
863 {
864 if (FRAMEP (FRAME_TTY (XFRAME (frame))->top_frame))
865 /* Mark previously displayed frame as now obscured. */
866 XFRAME (FRAME_TTY (XFRAME (frame))->top_frame)->async_visible = 2;
867 XFRAME (frame)->async_visible = 1;
868 FRAME_TTY (XFRAME (frame))->top_frame = frame;
869 }
870
871 selected_frame = frame;
872 if (! FRAME_MINIBUF_ONLY_P (XFRAME (selected_frame)))
873 last_nonminibuf_frame = XFRAME (selected_frame);
874
875 Fselect_window (XFRAME (frame)->selected_window, norecord);
876
877 #ifdef NS_IMPL_COCOA
878 /* term gets no other notification of this */
879 if (for_deletion)
880 Fraise_frame(Qnil);
881 #endif
882
883 /* We want to make sure that the next event generates a frame-switch
884 event to the appropriate frame. This seems kludgy to me, but
885 before you take it out, make sure that evaluating something like
886 (select-window (frame-root-window (new-frame))) doesn't end up
887 with your typing being interpreted in the new frame instead of
888 the one you're actually typing in. */
889 internal_last_event_frame = Qnil;
890
891 return frame;
892 }
893
894 DEFUN ("select-frame", Fselect_frame, Sselect_frame, 1, 2, "e",
895 doc: /* Select FRAME.
896 Subsequent editing commands apply to its selected window.
897 Optional argument NORECORD means to neither change the order of
898 recently selected windows nor the buffer list.
899
900 The selection of FRAME lasts until the next time the user does
901 something to select a different frame, or until the next time
902 this function is called. If you are using a window system, the
903 previously selected frame may be restored as the selected frame
904 after return to the command loop, because it still may have the
905 window system's input focus. On a text-only terminal, the next
906 redisplay will display FRAME.
907
908 This function returns FRAME, or nil if FRAME has been deleted. */)
909 (frame, norecord)
910 Lisp_Object frame, norecord;
911 {
912 return do_switch_frame (frame, 1, 0, norecord);
913 }
914
915
916 DEFUN ("handle-switch-frame", Fhandle_switch_frame, Shandle_switch_frame, 1, 1, "e",
917 doc: /* Handle a switch-frame event EVENT.
918 Switch-frame events are usually bound to this function.
919 A switch-frame event tells Emacs that the window manager has requested
920 that the user's events be directed to the frame mentioned in the event.
921 This function selects the selected window of the frame of EVENT.
922
923 If EVENT is frame object, handle it as if it were a switch-frame event
924 to that frame. */)
925 (event)
926 Lisp_Object event;
927 {
928 /* Preserve prefix arg that the command loop just cleared. */
929 current_kboard->Vprefix_arg = Vcurrent_prefix_arg;
930 call1 (Vrun_hooks, Qmouse_leave_buffer_hook);
931 return do_switch_frame (event, 0, 0, Qnil);
932 }
933
934 DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
935 doc: /* Return the frame that is now selected. */)
936 ()
937 {
938 return selected_frame;
939 }
940 \f
941 DEFUN ("window-frame", Fwindow_frame, Swindow_frame, 1, 1, 0,
942 doc: /* Return the frame object that window WINDOW is on. */)
943 (window)
944 Lisp_Object window;
945 {
946 CHECK_LIVE_WINDOW (window);
947 return XWINDOW (window)->frame;
948 }
949
950 DEFUN ("frame-first-window", Fframe_first_window, Sframe_first_window, 0, 1, 0,
951 doc: /* Returns the topmost, leftmost window of FRAME.
952 If omitted, FRAME defaults to the currently selected frame. */)
953 (frame)
954 Lisp_Object frame;
955 {
956 Lisp_Object w;
957
958 if (NILP (frame))
959 w = SELECTED_FRAME ()->root_window;
960 else
961 {
962 CHECK_LIVE_FRAME (frame);
963 w = XFRAME (frame)->root_window;
964 }
965 while (NILP (XWINDOW (w)->buffer))
966 {
967 if (! NILP (XWINDOW (w)->hchild))
968 w = XWINDOW (w)->hchild;
969 else if (! NILP (XWINDOW (w)->vchild))
970 w = XWINDOW (w)->vchild;
971 else
972 abort ();
973 }
974 return w;
975 }
976
977 DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
978 Sactive_minibuffer_window, 0, 0, 0,
979 doc: /* Return the currently active minibuffer window, or nil if none. */)
980 ()
981 {
982 return minibuf_level ? minibuf_window : Qnil;
983 }
984
985 DEFUN ("frame-root-window", Fframe_root_window, Sframe_root_window, 0, 1, 0,
986 doc: /* Returns the root-window of FRAME.
987 If omitted, FRAME defaults to the currently selected frame. */)
988 (frame)
989 Lisp_Object frame;
990 {
991 Lisp_Object window;
992
993 if (NILP (frame))
994 window = SELECTED_FRAME ()->root_window;
995 else
996 {
997 CHECK_LIVE_FRAME (frame);
998 window = XFRAME (frame)->root_window;
999 }
1000
1001 return window;
1002 }
1003
1004 DEFUN ("frame-selected-window", Fframe_selected_window,
1005 Sframe_selected_window, 0, 1, 0,
1006 doc: /* Return the selected window of FRAME.
1007 FRAME defaults to the currently selected frame. */)
1008 (frame)
1009 Lisp_Object frame;
1010 {
1011 Lisp_Object window;
1012
1013 if (NILP (frame))
1014 window = SELECTED_FRAME ()->selected_window;
1015 else
1016 {
1017 CHECK_LIVE_FRAME (frame);
1018 window = XFRAME (frame)->selected_window;
1019 }
1020
1021 return window;
1022 }
1023
1024 DEFUN ("set-frame-selected-window", Fset_frame_selected_window,
1025 Sset_frame_selected_window, 2, 3, 0,
1026 doc: /* Set selected window of FRAME to WINDOW.
1027 If FRAME is nil, use the selected frame. If FRAME is the
1028 selected frame, this makes WINDOW the selected window.
1029 Optional argument NORECORD non-nil means to neither change the
1030 order of recently selected windows nor the buffer list.
1031 Return WINDOW. */)
1032 (frame, window, norecord)
1033 Lisp_Object frame, window, norecord;
1034 {
1035 if (NILP (frame))
1036 frame = selected_frame;
1037
1038 CHECK_LIVE_FRAME (frame);
1039 CHECK_LIVE_WINDOW (window);
1040
1041 if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
1042 error ("In `set-frame-selected-window', WINDOW is not on FRAME");
1043
1044 if (EQ (frame, selected_frame))
1045 return Fselect_window (window, norecord);
1046
1047 return XFRAME (frame)->selected_window = window;
1048 }
1049
1050 \f
1051 DEFUN ("frame-list", Fframe_list, Sframe_list,
1052 0, 0, 0,
1053 doc: /* Return a list of all frames. */)
1054 ()
1055 {
1056 Lisp_Object frames;
1057 frames = Fcopy_sequence (Vframe_list);
1058 #ifdef HAVE_WINDOW_SYSTEM
1059 if (FRAMEP (tip_frame))
1060 frames = Fdelq (tip_frame, frames);
1061 #endif
1062 return frames;
1063 }
1064
1065 /* Return the next frame in the frame list after FRAME.
1066 If MINIBUF is nil, exclude minibuffer-only frames.
1067 If MINIBUF is a window, include only its own frame
1068 and any frame now using that window as the minibuffer.
1069 If MINIBUF is `visible', include all visible frames.
1070 If MINIBUF is 0, include all visible and iconified frames.
1071 Otherwise, include all frames. */
1072
1073 static Lisp_Object
1074 next_frame (frame, minibuf)
1075 Lisp_Object frame;
1076 Lisp_Object minibuf;
1077 {
1078 Lisp_Object tail;
1079 int passed = 0;
1080
1081 /* There must always be at least one frame in Vframe_list. */
1082 if (! CONSP (Vframe_list))
1083 abort ();
1084
1085 /* If this frame is dead, it won't be in Vframe_list, and we'll loop
1086 forever. Forestall that. */
1087 CHECK_LIVE_FRAME (frame);
1088
1089 while (1)
1090 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1091 {
1092 Lisp_Object f;
1093
1094 f = XCAR (tail);
1095
1096 if (passed
1097 && ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1098 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1099 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1100 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame)))))
1101 {
1102 /* Decide whether this frame is eligible to be returned. */
1103
1104 /* If we've looped all the way around without finding any
1105 eligible frames, return the original frame. */
1106 if (EQ (f, frame))
1107 return f;
1108
1109 /* Let minibuf decide if this frame is acceptable. */
1110 if (NILP (minibuf))
1111 {
1112 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1113 return f;
1114 }
1115 else if (EQ (minibuf, Qvisible))
1116 {
1117 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1118 if (FRAME_VISIBLE_P (XFRAME (f)))
1119 return f;
1120 }
1121 else if (INTEGERP (minibuf) && XINT (minibuf) == 0)
1122 {
1123 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1124 if (FRAME_VISIBLE_P (XFRAME (f))
1125 || FRAME_ICONIFIED_P (XFRAME (f)))
1126 return f;
1127 }
1128 else if (WINDOWP (minibuf))
1129 {
1130 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1131 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1132 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1133 FRAME_FOCUS_FRAME (XFRAME (f))))
1134 return f;
1135 }
1136 else
1137 return f;
1138 }
1139
1140 if (EQ (frame, f))
1141 passed++;
1142 }
1143 }
1144
1145 /* Return the previous frame in the frame list before FRAME.
1146 If MINIBUF is nil, exclude minibuffer-only frames.
1147 If MINIBUF is a window, include only its own frame
1148 and any frame now using that window as the minibuffer.
1149 If MINIBUF is `visible', include all visible frames.
1150 If MINIBUF is 0, include all visible and iconified frames.
1151 Otherwise, include all frames. */
1152
1153 static Lisp_Object
1154 prev_frame (frame, minibuf)
1155 Lisp_Object frame;
1156 Lisp_Object minibuf;
1157 {
1158 Lisp_Object tail;
1159 Lisp_Object prev;
1160
1161 /* There must always be at least one frame in Vframe_list. */
1162 if (! CONSP (Vframe_list))
1163 abort ();
1164
1165 prev = Qnil;
1166 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1167 {
1168 Lisp_Object f;
1169
1170 f = XCAR (tail);
1171 if (!FRAMEP (f))
1172 abort ();
1173
1174 if (EQ (frame, f) && !NILP (prev))
1175 return prev;
1176
1177 if ((!FRAME_TERMCAP_P (XFRAME (f)) && !FRAME_TERMCAP_P (XFRAME (frame))
1178 && FRAME_KBOARD (XFRAME (f)) == FRAME_KBOARD (XFRAME (frame)))
1179 || (FRAME_TERMCAP_P (XFRAME (f)) && FRAME_TERMCAP_P (XFRAME (frame))
1180 && FRAME_TTY (XFRAME (f)) == FRAME_TTY (XFRAME (frame))))
1181 {
1182 /* Decide whether this frame is eligible to be returned,
1183 according to minibuf. */
1184 if (NILP (minibuf))
1185 {
1186 if (! FRAME_MINIBUF_ONLY_P (XFRAME (f)))
1187 prev = f;
1188 }
1189 else if (WINDOWP (minibuf))
1190 {
1191 if (EQ (FRAME_MINIBUF_WINDOW (XFRAME (f)), minibuf)
1192 || EQ (WINDOW_FRAME (XWINDOW (minibuf)), f)
1193 || EQ (WINDOW_FRAME (XWINDOW (minibuf)),
1194 FRAME_FOCUS_FRAME (XFRAME (f))))
1195 prev = f;
1196 }
1197 else if (EQ (minibuf, Qvisible))
1198 {
1199 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1200 if (FRAME_VISIBLE_P (XFRAME (f)))
1201 prev = f;
1202 }
1203 else if (XFASTINT (minibuf) == 0)
1204 {
1205 FRAME_SAMPLE_VISIBILITY (XFRAME (f));
1206 if (FRAME_VISIBLE_P (XFRAME (f))
1207 || FRAME_ICONIFIED_P (XFRAME (f)))
1208 prev = f;
1209 }
1210 else
1211 prev = f;
1212 }
1213 }
1214
1215 /* We've scanned the entire list. */
1216 if (NILP (prev))
1217 /* We went through the whole frame list without finding a single
1218 acceptable frame. Return the original frame. */
1219 return frame;
1220 else
1221 /* There were no acceptable frames in the list before FRAME; otherwise,
1222 we would have returned directly from the loop. Since PREV is the last
1223 acceptable frame in the list, return it. */
1224 return prev;
1225 }
1226
1227
1228 DEFUN ("next-frame", Fnext_frame, Snext_frame, 0, 2, 0,
1229 doc: /* Return the next frame in the frame list after FRAME.
1230 It considers only frames on the same terminal as FRAME.
1231 By default, skip minibuffer-only frames.
1232 If omitted, FRAME defaults to the selected frame.
1233 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1234 If MINIFRAME is a window, include only its own frame
1235 and any frame now using that window as the minibuffer.
1236 If MINIFRAME is `visible', include all visible frames.
1237 If MINIFRAME is 0, include all visible and iconified frames.
1238 Otherwise, include all frames. */)
1239 (frame, miniframe)
1240 Lisp_Object frame, miniframe;
1241 {
1242 if (NILP (frame))
1243 frame = selected_frame;
1244
1245 CHECK_LIVE_FRAME (frame);
1246 return next_frame (frame, miniframe);
1247 }
1248
1249 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
1250 doc: /* Return the previous frame in the frame list before FRAME.
1251 It considers only frames on the same terminal as FRAME.
1252 By default, skip minibuffer-only frames.
1253 If omitted, FRAME defaults to the selected frame.
1254 If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
1255 If MINIFRAME is a window, include only its own frame
1256 and any frame now using that window as the minibuffer.
1257 If MINIFRAME is `visible', include all visible frames.
1258 If MINIFRAME is 0, include all visible and iconified frames.
1259 Otherwise, include all frames. */)
1260 (frame, miniframe)
1261 Lisp_Object frame, miniframe;
1262 {
1263 if (NILP (frame))
1264 frame = selected_frame;
1265 CHECK_LIVE_FRAME (frame);
1266 return prev_frame (frame, miniframe);
1267 }
1268 \f
1269 /* Return 1 if it is ok to delete frame F;
1270 0 if all frames aside from F are invisible.
1271 (Exception: if F is the terminal frame, and we are using X, return 1.) */
1272
1273 int
1274 other_visible_frames (f)
1275 FRAME_PTR f;
1276 {
1277 /* We know the selected frame is visible,
1278 so if F is some other frame, it can't be the sole visible one. */
1279 if (f == SELECTED_FRAME ())
1280 {
1281 Lisp_Object frames;
1282 int count = 0;
1283
1284 for (frames = Vframe_list;
1285 CONSP (frames);
1286 frames = XCDR (frames))
1287 {
1288 Lisp_Object this;
1289
1290 this = XCAR (frames);
1291 /* Verify that the frame's window still exists
1292 and we can still talk to it. And note any recent change
1293 in visibility. */
1294 #ifdef HAVE_WINDOW_SYSTEM
1295 if (FRAME_WINDOW_P (XFRAME (this)))
1296 {
1297 x_sync (XFRAME (this));
1298 FRAME_SAMPLE_VISIBILITY (XFRAME (this));
1299 }
1300 #endif
1301
1302 if (FRAME_VISIBLE_P (XFRAME (this))
1303 || FRAME_ICONIFIED_P (XFRAME (this))
1304 /* Allow deleting the terminal frame when at least
1305 one X frame exists! */
1306 || (FRAME_WINDOW_P (XFRAME (this)) && !FRAME_WINDOW_P (f)))
1307 count++;
1308 }
1309 return count > 1;
1310 }
1311 return 1;
1312 }
1313
1314 /* Error handler for `delete-frame-functions'. */
1315 static Lisp_Object
1316 delete_frame_handler (Lisp_Object arg)
1317 {
1318 add_to_log ("Error during `delete-frame': %s", arg, Qnil);
1319 return Qnil;
1320 }
1321
1322 extern Lisp_Object Qrun_hook_with_args;
1323
1324 /* Delete FRAME. When FORCE equals Qnoelisp, delete FRAME
1325 unconditionally. x_connection_closed and delete_terminal use
1326 this. Any other value of FORCE implements the semantics
1327 described for Fdelete_frame. */
1328 Lisp_Object
1329 delete_frame (frame, force)
1330 register Lisp_Object frame, force;
1331 {
1332 struct frame *f;
1333 struct frame *sf = SELECTED_FRAME ();
1334 struct kboard *kb;
1335
1336 int minibuffer_selected;
1337
1338 if (EQ (frame, Qnil))
1339 {
1340 f = sf;
1341 XSETFRAME (frame, f);
1342 }
1343 else
1344 {
1345 CHECK_FRAME (frame);
1346 f = XFRAME (frame);
1347 }
1348
1349 if (! FRAME_LIVE_P (f))
1350 return Qnil;
1351
1352 if (NILP (force) && !other_visible_frames (f))
1353 error ("Attempt to delete the sole visible or iconified frame");
1354
1355 /* x_connection_closed must have set FORCE to `noelisp' in order
1356 to delete the last frame, if it is gone. */
1357 if (NILP (XCDR (Vframe_list)) && !EQ (force, Qnoelisp))
1358 error ("Attempt to delete the only frame");
1359
1360 /* Does this frame have a minibuffer, and is it the surrogate
1361 minibuffer for any other frame? */
1362 if (FRAME_HAS_MINIBUF_P (XFRAME (frame)))
1363 {
1364 Lisp_Object frames;
1365
1366 for (frames = Vframe_list;
1367 CONSP (frames);
1368 frames = XCDR (frames))
1369 {
1370 Lisp_Object this;
1371 this = XCAR (frames);
1372
1373 if (! EQ (this, frame)
1374 && EQ (frame,
1375 WINDOW_FRAME (XWINDOW
1376 (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
1377 {
1378 /* If we MUST delete this frame, delete the other first.
1379 But do this only if FORCE equals `noelisp'. */
1380 if (EQ (force, Qnoelisp))
1381 delete_frame (this, Qnoelisp);
1382 else
1383 error ("Attempt to delete a surrogate minibuffer frame");
1384 }
1385 }
1386 }
1387
1388 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1389 frame is a tooltip. FORCE is set to `noelisp' when handling
1390 a disconnect from the terminal, so we don't dare call Lisp
1391 code. */
1392 if (NILP (Vrun_hooks) || !NILP (Fframe_parameter (frame, intern ("tooltip"))))
1393 ;
1394 if (EQ (force, Qnoelisp))
1395 pending_funcalls
1396 = Fcons (list3 (Qrun_hook_with_args, Qdelete_frame_functions, frame),
1397 pending_funcalls);
1398 else
1399 safe_call2 (Qrun_hook_with_args, Qdelete_frame_functions, frame);
1400
1401 /* The hook may sometimes (indirectly) cause the frame to be deleted. */
1402 if (! FRAME_LIVE_P (f))
1403 return Qnil;
1404
1405 /* At this point, we are committed to deleting the frame.
1406 There is no more chance for errors to prevent it. */
1407
1408 minibuffer_selected = EQ (minibuf_window, selected_window);
1409
1410 /* Don't let the frame remain selected. */
1411 if (f == sf)
1412 {
1413 Lisp_Object tail, frame1;
1414
1415 /* Look for another visible frame on the same terminal. */
1416 frame1 = next_frame (frame, Qvisible);
1417
1418 /* If there is none, find *some* other frame. */
1419 if (NILP (frame1) || EQ (frame1, frame))
1420 {
1421 FOR_EACH_FRAME (tail, frame1)
1422 {
1423 if (! EQ (frame, frame1) && FRAME_LIVE_P (XFRAME (frame1)))
1424 break;
1425 }
1426 }
1427
1428 do_switch_frame (frame1, 0, 1, Qnil);
1429 sf = SELECTED_FRAME ();
1430 }
1431
1432 /* Don't allow minibuf_window to remain on a deleted frame. */
1433 if (EQ (f->minibuffer_window, minibuf_window))
1434 {
1435 Fset_window_buffer (sf->minibuffer_window,
1436 XWINDOW (minibuf_window)->buffer, Qnil);
1437 minibuf_window = sf->minibuffer_window;
1438
1439 /* If the dying minibuffer window was selected,
1440 select the new one. */
1441 if (minibuffer_selected)
1442 Fselect_window (minibuf_window, Qnil);
1443 }
1444
1445 /* Don't let echo_area_window to remain on a deleted frame. */
1446 if (EQ (f->minibuffer_window, echo_area_window))
1447 echo_area_window = sf->minibuffer_window;
1448
1449 /* Clear any X selections for this frame. */
1450 #ifdef HAVE_X_WINDOWS
1451 if (FRAME_X_P (f))
1452 x_clear_frame_selections (f);
1453 #endif
1454
1455 /* Free glyphs.
1456 This function must be called before the window tree of the
1457 frame is deleted because windows contain dynamically allocated
1458 memory. */
1459 free_glyphs (f);
1460
1461 #ifdef HAVE_WINDOW_SYSTEM
1462 /* Give chance to each font driver to free a frame specific data. */
1463 font_update_drivers (f, Qnil);
1464 #endif
1465
1466 /* Mark all the windows that used to be on FRAME as deleted, and then
1467 remove the reference to them. */
1468 delete_all_subwindows (XWINDOW (f->root_window));
1469 f->root_window = Qnil;
1470
1471 Vframe_list = Fdelq (frame, Vframe_list);
1472 FRAME_SET_VISIBLE (f, 0);
1473
1474 /* Allow the vector of menu bar contents to be freed in the next
1475 garbage collection. The frame object itself may not be garbage
1476 collected until much later, because recent_keys and other data
1477 structures can still refer to it. */
1478 f->menu_bar_vector = Qnil;
1479
1480 free_font_driver_list (f);
1481 xfree (f->namebuf);
1482 xfree (f->decode_mode_spec_buffer);
1483 xfree (FRAME_INSERT_COST (f));
1484 xfree (FRAME_DELETEN_COST (f));
1485 xfree (FRAME_INSERTN_COST (f));
1486 xfree (FRAME_DELETE_COST (f));
1487 xfree (FRAME_MESSAGE_BUF (f));
1488
1489 /* Since some events are handled at the interrupt level, we may get
1490 an event for f at any time; if we zero out the frame's terminal
1491 now, then we may trip up the event-handling code. Instead, we'll
1492 promise that the terminal of the frame must be valid until we
1493 have called the window-system-dependent frame destruction
1494 routine. */
1495
1496 if (FRAME_TERMINAL (f)->delete_frame_hook)
1497 (*FRAME_TERMINAL (f)->delete_frame_hook) (f);
1498
1499 {
1500 struct terminal *terminal = FRAME_TERMINAL (f);
1501 f->output_data.nothing = 0;
1502 f->terminal = 0; /* Now the frame is dead. */
1503
1504 /* If needed, delete the terminal that this frame was on.
1505 (This must be done after the frame is killed.) */
1506 terminal->reference_count--;
1507 if (terminal->reference_count == 0)
1508 {
1509 Lisp_Object tmp;
1510 XSETTERMINAL (tmp, terminal);
1511
1512 kb = NULL;
1513 Fdelete_terminal (tmp, NILP (force) ? Qt : force);
1514 }
1515 else
1516 kb = terminal->kboard;
1517 }
1518
1519 /* If we've deleted the last_nonminibuf_frame, then try to find
1520 another one. */
1521 if (f == last_nonminibuf_frame)
1522 {
1523 Lisp_Object frames;
1524
1525 last_nonminibuf_frame = 0;
1526
1527 for (frames = Vframe_list;
1528 CONSP (frames);
1529 frames = XCDR (frames))
1530 {
1531 f = XFRAME (XCAR (frames));
1532 if (!FRAME_MINIBUF_ONLY_P (f))
1533 {
1534 last_nonminibuf_frame = f;
1535 break;
1536 }
1537 }
1538 }
1539
1540 /* If there's no other frame on the same kboard, get out of
1541 single-kboard state if we're in it for this kboard. */
1542 if (kb != NULL)
1543 {
1544 Lisp_Object frames;
1545 /* Some frame we found on the same kboard, or nil if there are none. */
1546 Lisp_Object frame_on_same_kboard;
1547
1548 frame_on_same_kboard = Qnil;
1549
1550 for (frames = Vframe_list;
1551 CONSP (frames);
1552 frames = XCDR (frames))
1553 {
1554 Lisp_Object this;
1555 struct frame *f1;
1556
1557 this = XCAR (frames);
1558 if (!FRAMEP (this))
1559 abort ();
1560 f1 = XFRAME (this);
1561
1562 if (kb == FRAME_KBOARD (f1))
1563 frame_on_same_kboard = this;
1564 }
1565
1566 if (NILP (frame_on_same_kboard))
1567 not_single_kboard_state (kb);
1568 }
1569
1570
1571 /* If we've deleted this keyboard's default_minibuffer_frame, try to
1572 find another one. Prefer minibuffer-only frames, but also notice
1573 frames with other windows. */
1574 if (kb != NULL && EQ (frame, kb->Vdefault_minibuffer_frame))
1575 {
1576 Lisp_Object frames;
1577
1578 /* The last frame we saw with a minibuffer, minibuffer-only or not. */
1579 Lisp_Object frame_with_minibuf;
1580 /* Some frame we found on the same kboard, or nil if there are none. */
1581 Lisp_Object frame_on_same_kboard;
1582
1583 frame_on_same_kboard = Qnil;
1584 frame_with_minibuf = Qnil;
1585
1586 for (frames = Vframe_list;
1587 CONSP (frames);
1588 frames = XCDR (frames))
1589 {
1590 Lisp_Object this;
1591 struct frame *f1;
1592
1593 this = XCAR (frames);
1594 if (!FRAMEP (this))
1595 abort ();
1596 f1 = XFRAME (this);
1597
1598 /* Consider only frames on the same kboard
1599 and only those with minibuffers. */
1600 if (kb == FRAME_KBOARD (f1)
1601 && FRAME_HAS_MINIBUF_P (f1))
1602 {
1603 frame_with_minibuf = this;
1604 if (FRAME_MINIBUF_ONLY_P (f1))
1605 break;
1606 }
1607
1608 if (kb == FRAME_KBOARD (f1))
1609 frame_on_same_kboard = this;
1610 }
1611
1612 if (!NILP (frame_on_same_kboard))
1613 {
1614 /* We know that there must be some frame with a minibuffer out
1615 there. If this were not true, all of the frames present
1616 would have to be minibufferless, which implies that at some
1617 point their minibuffer frames must have been deleted, but
1618 that is prohibited at the top; you can't delete surrogate
1619 minibuffer frames. */
1620 if (NILP (frame_with_minibuf))
1621 abort ();
1622
1623 kb->Vdefault_minibuffer_frame = frame_with_minibuf;
1624 }
1625 else
1626 /* No frames left on this kboard--say no minibuffer either. */
1627 kb->Vdefault_minibuffer_frame = Qnil;
1628 }
1629
1630 /* Cause frame titles to update--necessary if we now have just one frame. */
1631 update_mode_lines = 1;
1632
1633 return Qnil;
1634 }
1635
1636 DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
1637 doc: /* Delete FRAME, permanently eliminating it from use.
1638 FRAME defaults to the selected frame.
1639
1640 A frame may not be deleted if its minibuffer is used by other frames.
1641 Normally, you may not delete a frame if all other frames are invisible,
1642 but if the second optional argument FORCE is non-nil, you may do so.
1643
1644 This function runs `delete-frame-functions' before actually
1645 deleting the frame, unless the frame is a tooltip.
1646 The functions are run with one argument, the frame to be deleted. */)
1647 (frame, force)
1648 Lisp_Object frame, force;
1649 {
1650 return delete_frame (frame, !NILP (force) ? Qt : Qnil);
1651 }
1652
1653 \f
1654 /* Return mouse position in character cell units. */
1655
1656 DEFUN ("mouse-position", Fmouse_position, Smouse_position, 0, 0, 0,
1657 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1658 The position is given in character cells, where (0, 0) is the
1659 upper-left corner of the frame, X is the horizontal offset, and Y is
1660 the vertical offset.
1661 If Emacs is running on a mouseless terminal or hasn't been programmed
1662 to read the mouse position, it returns the selected frame for FRAME
1663 and nil for X and Y.
1664 If `mouse-position-function' is non-nil, `mouse-position' calls it,
1665 passing the normal return value to that function as an argument,
1666 and returns whatever that function returns. */)
1667 ()
1668 {
1669 FRAME_PTR f;
1670 Lisp_Object lispy_dummy;
1671 enum scroll_bar_part party_dummy;
1672 Lisp_Object x, y, retval;
1673 int col, row;
1674 unsigned long long_dummy;
1675 struct gcpro gcpro1;
1676
1677 f = SELECTED_FRAME ();
1678 x = y = Qnil;
1679
1680 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1681 /* It's okay for the hook to refrain from storing anything. */
1682 if (FRAME_TERMINAL (f)->mouse_position_hook)
1683 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1684 &lispy_dummy, &party_dummy,
1685 &x, &y,
1686 &long_dummy);
1687 if (! NILP (x))
1688 {
1689 col = XINT (x);
1690 row = XINT (y);
1691 pixel_to_glyph_coords (f, col, row, &col, &row, NULL, 1);
1692 XSETINT (x, col);
1693 XSETINT (y, row);
1694 }
1695 #endif
1696 XSETFRAME (lispy_dummy, f);
1697 retval = Fcons (lispy_dummy, Fcons (x, y));
1698 GCPRO1 (retval);
1699 if (!NILP (Vmouse_position_function))
1700 retval = call1 (Vmouse_position_function, retval);
1701 RETURN_UNGCPRO (retval);
1702 }
1703
1704 DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
1705 Smouse_pixel_position, 0, 0, 0,
1706 doc: /* Return a list (FRAME X . Y) giving the current mouse frame and position.
1707 The position is given in pixel units, where (0, 0) is the
1708 upper-left corner of the frame, X is the horizontal offset, and Y is
1709 the vertical offset.
1710 If Emacs is running on a mouseless terminal or hasn't been programmed
1711 to read the mouse position, it returns the selected frame for FRAME
1712 and nil for X and Y. */)
1713 ()
1714 {
1715 FRAME_PTR f;
1716 Lisp_Object lispy_dummy;
1717 enum scroll_bar_part party_dummy;
1718 Lisp_Object x, y;
1719 unsigned long long_dummy;
1720
1721 f = SELECTED_FRAME ();
1722 x = y = Qnil;
1723
1724 #if defined (HAVE_MOUSE) || defined (HAVE_GPM)
1725 /* It's okay for the hook to refrain from storing anything. */
1726 if (FRAME_TERMINAL (f)->mouse_position_hook)
1727 (*FRAME_TERMINAL (f)->mouse_position_hook) (&f, -1,
1728 &lispy_dummy, &party_dummy,
1729 &x, &y,
1730 &long_dummy);
1731 #endif
1732 XSETFRAME (lispy_dummy, f);
1733 return Fcons (lispy_dummy, Fcons (x, y));
1734 }
1735
1736 DEFUN ("set-mouse-position", Fset_mouse_position, Sset_mouse_position, 3, 3, 0,
1737 doc: /* Move the mouse pointer to the center of character cell (X,Y) in FRAME.
1738 Coordinates are relative to the frame, not a window,
1739 so the coordinates of the top left character in the frame
1740 may be nonzero due to left-hand scroll bars or the menu bar.
1741
1742 The position is given in character cells, where (0, 0) is the
1743 upper-left corner of the frame, X is the horizontal offset, and Y is
1744 the vertical offset.
1745
1746 This function is a no-op for an X frame that is not visible.
1747 If you have just created a frame, you must wait for it to become visible
1748 before calling this function on it, like this.
1749 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1750 (frame, x, y)
1751 Lisp_Object frame, x, y;
1752 {
1753 CHECK_LIVE_FRAME (frame);
1754 CHECK_NUMBER (x);
1755 CHECK_NUMBER (y);
1756
1757 /* I think this should be done with a hook. */
1758 #ifdef HAVE_WINDOW_SYSTEM
1759 if (FRAME_WINDOW_P (XFRAME (frame)))
1760 /* Warping the mouse will cause enternotify and focus events. */
1761 x_set_mouse_position (XFRAME (frame), XINT (x), XINT (y));
1762 #else
1763 #if defined (MSDOS) && defined (HAVE_MOUSE)
1764 if (FRAME_MSDOS_P (XFRAME (frame)))
1765 {
1766 Fselect_frame (frame, Qnil);
1767 mouse_moveto (XINT (x), XINT (y));
1768 }
1769 #else
1770 #ifdef HAVE_GPM
1771 {
1772 Fselect_frame (frame, Qnil);
1773 term_mouse_moveto (XINT (x), XINT (y));
1774 }
1775 #endif
1776 #endif
1777 #endif
1778
1779 return Qnil;
1780 }
1781
1782 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position,
1783 Sset_mouse_pixel_position, 3, 3, 0,
1784 doc: /* Move the mouse pointer to pixel position (X,Y) in FRAME.
1785 The position is given in pixels, where (0, 0) is the upper-left corner
1786 of the frame, X is the horizontal offset, and Y is the vertical offset.
1787
1788 Note, this is a no-op for an X frame that is not visible.
1789 If you have just created a frame, you must wait for it to become visible
1790 before calling this function on it, like this.
1791 (while (not (frame-visible-p frame)) (sleep-for .5)) */)
1792 (frame, x, y)
1793 Lisp_Object frame, x, y;
1794 {
1795 CHECK_LIVE_FRAME (frame);
1796 CHECK_NUMBER (x);
1797 CHECK_NUMBER (y);
1798
1799 /* I think this should be done with a hook. */
1800 #ifdef HAVE_WINDOW_SYSTEM
1801 if (FRAME_WINDOW_P (XFRAME (frame)))
1802 /* Warping the mouse will cause enternotify and focus events. */
1803 x_set_mouse_pixel_position (XFRAME (frame), XINT (x), XINT (y));
1804 #else
1805 #if defined (MSDOS) && defined (HAVE_MOUSE)
1806 if (FRAME_MSDOS_P (XFRAME (frame)))
1807 {
1808 Fselect_frame (frame, Qnil);
1809 mouse_moveto (XINT (x), XINT (y));
1810 }
1811 #else
1812 #ifdef HAVE_GPM
1813 {
1814 Fselect_frame (frame, Qnil);
1815 term_mouse_moveto (XINT (x), XINT (y));
1816 }
1817 #endif
1818 #endif
1819 #endif
1820
1821 return Qnil;
1822 }
1823 \f
1824 static void make_frame_visible_1 P_ ((Lisp_Object));
1825
1826 DEFUN ("make-frame-visible", Fmake_frame_visible, Smake_frame_visible,
1827 0, 1, "",
1828 doc: /* Make the frame FRAME visible (assuming it is an X window).
1829 If omitted, FRAME defaults to the currently selected frame. */)
1830 (frame)
1831 Lisp_Object frame;
1832 {
1833 if (NILP (frame))
1834 frame = selected_frame;
1835
1836 CHECK_LIVE_FRAME (frame);
1837
1838 /* I think this should be done with a hook. */
1839 #ifdef HAVE_WINDOW_SYSTEM
1840 if (FRAME_WINDOW_P (XFRAME (frame)))
1841 {
1842 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1843 x_make_frame_visible (XFRAME (frame));
1844 }
1845 #endif
1846
1847 make_frame_visible_1 (XFRAME (frame)->root_window);
1848
1849 /* Make menu bar update for the Buffers and Frames menus. */
1850 windows_or_buffers_changed++;
1851
1852 return frame;
1853 }
1854
1855 /* Update the display_time slot of the buffers shown in WINDOW
1856 and all its descendents. */
1857
1858 static void
1859 make_frame_visible_1 (window)
1860 Lisp_Object window;
1861 {
1862 struct window *w;
1863
1864 for (;!NILP (window); window = w->next)
1865 {
1866 w = XWINDOW (window);
1867
1868 if (!NILP (w->buffer))
1869 XBUFFER (w->buffer)->display_time = Fcurrent_time ();
1870
1871 if (!NILP (w->vchild))
1872 make_frame_visible_1 (w->vchild);
1873 if (!NILP (w->hchild))
1874 make_frame_visible_1 (w->hchild);
1875 }
1876 }
1877
1878 DEFUN ("make-frame-invisible", Fmake_frame_invisible, Smake_frame_invisible,
1879 0, 2, "",
1880 doc: /* Make the frame FRAME invisible (assuming it is an X window).
1881 If omitted, FRAME defaults to the currently selected frame.
1882 Normally you may not make FRAME invisible if all other frames are invisible,
1883 but if the second optional argument FORCE is non-nil, you may do so. */)
1884 (frame, force)
1885 Lisp_Object frame, force;
1886 {
1887 if (NILP (frame))
1888 frame = selected_frame;
1889
1890 CHECK_LIVE_FRAME (frame);
1891
1892 if (NILP (force) && !other_visible_frames (XFRAME (frame)))
1893 error ("Attempt to make invisible the sole visible or iconified frame");
1894
1895 #if 0 /* This isn't logically necessary, and it can do GC. */
1896 /* Don't let the frame remain selected. */
1897 if (EQ (frame, selected_frame))
1898 do_switch_frame (next_frame (frame, Qt), 0, 0, Qnil)
1899 #endif
1900
1901 /* Don't allow minibuf_window to remain on a deleted frame. */
1902 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1903 {
1904 struct frame *sf = XFRAME (selected_frame);
1905 Fset_window_buffer (sf->minibuffer_window,
1906 XWINDOW (minibuf_window)->buffer, Qnil);
1907 minibuf_window = sf->minibuffer_window;
1908 }
1909
1910 /* I think this should be done with a hook. */
1911 #ifdef HAVE_WINDOW_SYSTEM
1912 if (FRAME_WINDOW_P (XFRAME (frame)))
1913 x_make_frame_invisible (XFRAME (frame));
1914 #endif
1915
1916 /* Make menu bar update for the Buffers and Frames menus. */
1917 windows_or_buffers_changed++;
1918
1919 return Qnil;
1920 }
1921
1922 DEFUN ("iconify-frame", Ficonify_frame, Siconify_frame,
1923 0, 1, "",
1924 doc: /* Make the frame FRAME into an icon.
1925 If omitted, FRAME defaults to the currently selected frame. */)
1926 (frame)
1927 Lisp_Object frame;
1928 {
1929 if (NILP (frame))
1930 frame = selected_frame;
1931
1932 CHECK_LIVE_FRAME (frame);
1933
1934 #if 0 /* This isn't logically necessary, and it can do GC. */
1935 /* Don't let the frame remain selected. */
1936 if (EQ (frame, selected_frame))
1937 Fhandle_switch_frame (next_frame (frame, Qt));
1938 #endif
1939
1940 /* Don't allow minibuf_window to remain on a deleted frame. */
1941 if (EQ (XFRAME (frame)->minibuffer_window, minibuf_window))
1942 {
1943 struct frame *sf = XFRAME (selected_frame);
1944 Fset_window_buffer (sf->minibuffer_window,
1945 XWINDOW (minibuf_window)->buffer, Qnil);
1946 minibuf_window = sf->minibuffer_window;
1947 }
1948
1949 /* I think this should be done with a hook. */
1950 #ifdef HAVE_WINDOW_SYSTEM
1951 if (FRAME_WINDOW_P (XFRAME (frame)))
1952 x_iconify_frame (XFRAME (frame));
1953 #endif
1954
1955 /* Make menu bar update for the Buffers and Frames menus. */
1956 windows_or_buffers_changed++;
1957
1958 return Qnil;
1959 }
1960
1961 DEFUN ("frame-visible-p", Fframe_visible_p, Sframe_visible_p,
1962 1, 1, 0,
1963 doc: /* Return t if FRAME is now \"visible\" (actually in use for display).
1964 A frame that is not \"visible\" is not updated and, if it works through
1965 a window system, it may not show at all.
1966 Return the symbol `icon' if frame is visible only as an icon.
1967
1968 On a text-only terminal, all frames are considered visible, whether
1969 they are currently being displayed or not, and this function returns t
1970 for all frames. */)
1971 (frame)
1972 Lisp_Object frame;
1973 {
1974 CHECK_LIVE_FRAME (frame);
1975
1976 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
1977
1978 if (FRAME_VISIBLE_P (XFRAME (frame)))
1979 return Qt;
1980 if (FRAME_ICONIFIED_P (XFRAME (frame)))
1981 return Qicon;
1982 return Qnil;
1983 }
1984
1985 DEFUN ("visible-frame-list", Fvisible_frame_list, Svisible_frame_list,
1986 0, 0, 0,
1987 doc: /* Return a list of all frames now \"visible\" (being updated). */)
1988 ()
1989 {
1990 Lisp_Object tail, frame;
1991 struct frame *f;
1992 Lisp_Object value;
1993
1994 value = Qnil;
1995 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
1996 {
1997 frame = XCAR (tail);
1998 if (!FRAMEP (frame))
1999 continue;
2000 f = XFRAME (frame);
2001 if (FRAME_VISIBLE_P (f))
2002 value = Fcons (frame, value);
2003 }
2004 return value;
2005 }
2006
2007
2008 DEFUN ("raise-frame", Fraise_frame, Sraise_frame, 0, 1, "",
2009 doc: /* Bring FRAME to the front, so it occludes any frames it overlaps.
2010 If FRAME is invisible or iconified, make it visible.
2011 If you don't specify a frame, the selected frame is used.
2012 If Emacs is displaying on an ordinary terminal or some other device which
2013 doesn't support multiple overlapping frames, this function selects FRAME. */)
2014 (frame)
2015 Lisp_Object frame;
2016 {
2017 struct frame *f;
2018 if (NILP (frame))
2019 frame = selected_frame;
2020
2021 CHECK_LIVE_FRAME (frame);
2022
2023 f = XFRAME (frame);
2024
2025 if (FRAME_TERMCAP_P (f))
2026 /* On a text-only terminal select FRAME. */
2027 Fselect_frame (frame, Qnil);
2028 else
2029 /* Do like the documentation says. */
2030 Fmake_frame_visible (frame);
2031
2032 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2033 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 1);
2034
2035 return Qnil;
2036 }
2037
2038 /* Should we have a corresponding function called Flower_Power? */
2039 DEFUN ("lower-frame", Flower_frame, Slower_frame, 0, 1, "",
2040 doc: /* Send FRAME to the back, so it is occluded by any frames that overlap it.
2041 If you don't specify a frame, the selected frame is used.
2042 If Emacs is displaying on an ordinary terminal or some other device which
2043 doesn't support multiple overlapping frames, this function does nothing. */)
2044 (frame)
2045 Lisp_Object frame;
2046 {
2047 struct frame *f;
2048
2049 if (NILP (frame))
2050 frame = selected_frame;
2051
2052 CHECK_LIVE_FRAME (frame);
2053
2054 f = XFRAME (frame);
2055
2056 if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
2057 (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
2058
2059 return Qnil;
2060 }
2061
2062 \f
2063 DEFUN ("redirect-frame-focus", Fredirect_frame_focus, Sredirect_frame_focus,
2064 1, 2, 0,
2065 doc: /* Arrange for keystrokes typed at FRAME to be sent to FOCUS-FRAME.
2066 In other words, switch-frame events caused by events in FRAME will
2067 request a switch to FOCUS-FRAME, and `last-event-frame' will be
2068 FOCUS-FRAME after reading an event typed at FRAME.
2069
2070 If FOCUS-FRAME is omitted or nil, any existing redirection is
2071 cancelled, and the frame again receives its own keystrokes.
2072
2073 Focus redirection is useful for temporarily redirecting keystrokes to
2074 a surrogate minibuffer frame when a frame doesn't have its own
2075 minibuffer window.
2076
2077 A frame's focus redirection can be changed by `select-frame'. If frame
2078 FOO is selected, and then a different frame BAR is selected, any
2079 frames redirecting their focus to FOO are shifted to redirect their
2080 focus to BAR. This allows focus redirection to work properly when the
2081 user switches from one frame to another using `select-window'.
2082
2083 This means that a frame whose focus is redirected to itself is treated
2084 differently from a frame whose focus is redirected to nil; the former
2085 is affected by `select-frame', while the latter is not.
2086
2087 The redirection lasts until `redirect-frame-focus' is called to change it. */)
2088 (frame, focus_frame)
2089 Lisp_Object frame, focus_frame;
2090 {
2091 struct frame *f;
2092
2093 /* Note that we don't check for a live frame here. It's reasonable
2094 to redirect the focus of a frame you're about to delete, if you
2095 know what other frame should receive those keystrokes. */
2096 CHECK_FRAME (frame);
2097
2098 if (! NILP (focus_frame))
2099 CHECK_LIVE_FRAME (focus_frame);
2100
2101 f = XFRAME (frame);
2102
2103 f->focus_frame = focus_frame;
2104
2105 if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
2106 (*FRAME_TERMINAL (f)->frame_rehighlight_hook) (f);
2107
2108 return Qnil;
2109 }
2110
2111
2112 DEFUN ("frame-focus", Fframe_focus, Sframe_focus, 1, 1, 0,
2113 doc: /* Return the frame to which FRAME's keystrokes are currently being sent.
2114 This returns nil if FRAME's focus is not redirected.
2115 See `redirect-frame-focus'. */)
2116 (frame)
2117 Lisp_Object frame;
2118 {
2119 CHECK_LIVE_FRAME (frame);
2120
2121 return FRAME_FOCUS_FRAME (XFRAME (frame));
2122 }
2123
2124
2125 \f
2126 /* Return the value of frame parameter PROP in frame FRAME. */
2127
2128 Lisp_Object
2129 get_frame_param (frame, prop)
2130 register struct frame *frame;
2131 Lisp_Object prop;
2132 {
2133 register Lisp_Object tem;
2134
2135 tem = Fassq (prop, frame->param_alist);
2136 if (EQ (tem, Qnil))
2137 return tem;
2138 return Fcdr (tem);
2139 }
2140
2141 /* Return the buffer-predicate of the selected frame. */
2142
2143 Lisp_Object
2144 frame_buffer_predicate (frame)
2145 Lisp_Object frame;
2146 {
2147 return XFRAME (frame)->buffer_predicate;
2148 }
2149
2150 /* Return the buffer-list of the selected frame. */
2151
2152 Lisp_Object
2153 frame_buffer_list (frame)
2154 Lisp_Object frame;
2155 {
2156 return XFRAME (frame)->buffer_list;
2157 }
2158
2159 /* Set the buffer-list of the selected frame. */
2160
2161 void
2162 set_frame_buffer_list (frame, list)
2163 Lisp_Object frame, list;
2164 {
2165 XFRAME (frame)->buffer_list = list;
2166 }
2167
2168 /* Discard BUFFER from the buffer-list and buried-buffer-list of each frame. */
2169
2170 void
2171 frames_discard_buffer (buffer)
2172 Lisp_Object buffer;
2173 {
2174 Lisp_Object frame, tail;
2175
2176 FOR_EACH_FRAME (tail, frame)
2177 {
2178 XFRAME (frame)->buffer_list
2179 = Fdelq (buffer, XFRAME (frame)->buffer_list);
2180 XFRAME (frame)->buried_buffer_list
2181 = Fdelq (buffer, XFRAME (frame)->buried_buffer_list);
2182 }
2183 }
2184
2185 /* Modify the alist in *ALISTPTR to associate PROP with VAL.
2186 If the alist already has an element for PROP, we change it. */
2187
2188 void
2189 store_in_alist (alistptr, prop, val)
2190 Lisp_Object *alistptr, val;
2191 Lisp_Object prop;
2192 {
2193 register Lisp_Object tem;
2194
2195 tem = Fassq (prop, *alistptr);
2196 if (EQ (tem, Qnil))
2197 *alistptr = Fcons (Fcons (prop, val), *alistptr);
2198 else
2199 Fsetcdr (tem, val);
2200 }
2201
2202 static int
2203 frame_name_fnn_p (str, len)
2204 char *str;
2205 EMACS_INT len;
2206 {
2207 if (len > 1 && str[0] == 'F')
2208 {
2209 char *end_ptr;
2210
2211 strtol (str + 1, &end_ptr, 10);
2212
2213 if (end_ptr == str + len)
2214 return 1;
2215 }
2216 return 0;
2217 }
2218
2219 /* Set the name of the terminal frame. Also used by MSDOS frames.
2220 Modeled after x_set_name which is used for WINDOW frames. */
2221
2222 static void
2223 set_term_frame_name (f, name)
2224 struct frame *f;
2225 Lisp_Object name;
2226 {
2227 f->explicit_name = ! NILP (name);
2228
2229 /* If NAME is nil, set the name to F<num>. */
2230 if (NILP (name))
2231 {
2232 char namebuf[20];
2233
2234 /* Check for no change needed in this very common case
2235 before we do any consing. */
2236 if (frame_name_fnn_p (SDATA (f->name),
2237 SBYTES (f->name)))
2238 return;
2239
2240 tty_frame_count++;
2241 sprintf (namebuf, "F%d", tty_frame_count);
2242 name = build_string (namebuf);
2243 }
2244 else
2245 {
2246 CHECK_STRING (name);
2247
2248 /* Don't change the name if it's already NAME. */
2249 if (! NILP (Fstring_equal (name, f->name)))
2250 return;
2251
2252 /* Don't allow the user to set the frame name to F<num>, so it
2253 doesn't clash with the names we generate for terminal frames. */
2254 if (frame_name_fnn_p (SDATA (name), SBYTES (name)))
2255 error ("Frame names of the form F<num> are usurped by Emacs");
2256 }
2257
2258 f->name = name;
2259 update_mode_lines = 1;
2260 }
2261
2262 void
2263 store_frame_param (f, prop, val)
2264 struct frame *f;
2265 Lisp_Object prop, val;
2266 {
2267 register Lisp_Object old_alist_elt;
2268
2269 /* The buffer-list parameters are stored in a special place and not
2270 in the alist. */
2271 if (EQ (prop, Qbuffer_list))
2272 {
2273 f->buffer_list = val;
2274 return;
2275 }
2276 if (EQ (prop, Qburied_buffer_list))
2277 {
2278 f->buried_buffer_list = val;
2279 return;
2280 }
2281
2282 /* If PROP is a symbol which is supposed to have frame-local values,
2283 and it is set up based on this frame, switch to the global
2284 binding. That way, we can create or alter the frame-local binding
2285 without messing up the symbol's status. */
2286 if (SYMBOLP (prop))
2287 {
2288 Lisp_Object valcontents;
2289 valcontents = SYMBOL_VALUE (prop);
2290 if ((BUFFER_LOCAL_VALUEP (valcontents))
2291 && XBUFFER_LOCAL_VALUE (valcontents)->check_frame
2292 && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame
2293 && XFRAME (XBUFFER_LOCAL_VALUE (valcontents)->frame) == f)
2294 swap_in_global_binding (prop);
2295 }
2296
2297 /* The tty color needed to be set before the frame's parameter
2298 alist was updated with the new value. This is not true any more,
2299 but we still do this test early on. */
2300 if (FRAME_TERMCAP_P (f) && EQ (prop, Qtty_color_mode)
2301 && f == FRAME_TTY (f)->previous_frame)
2302 /* Force redisplay of this tty. */
2303 FRAME_TTY (f)->previous_frame = NULL;
2304
2305 /* Update the frame parameter alist. */
2306 old_alist_elt = Fassq (prop, f->param_alist);
2307 if (EQ (old_alist_elt, Qnil))
2308 f->param_alist = Fcons (Fcons (prop, val), f->param_alist);
2309 else
2310 Fsetcdr (old_alist_elt, val);
2311
2312 /* Update some other special parameters in their special places
2313 in addition to the alist. */
2314
2315 if (EQ (prop, Qbuffer_predicate))
2316 f->buffer_predicate = val;
2317
2318 if (! FRAME_WINDOW_P (f))
2319 {
2320 if (EQ (prop, Qmenu_bar_lines))
2321 set_menu_bar_lines (f, val, make_number (FRAME_MENU_BAR_LINES (f)));
2322 else if (EQ (prop, Qname))
2323 set_term_frame_name (f, val);
2324 }
2325
2326 if (EQ (prop, Qminibuffer) && WINDOWP (val))
2327 {
2328 if (! MINI_WINDOW_P (XWINDOW (val)))
2329 error ("Surrogate minibuffer windows must be minibuffer windows");
2330
2331 if ((FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2332 && !EQ (val, f->minibuffer_window))
2333 error ("Can't change the surrogate minibuffer of a frame with its own minibuffer");
2334
2335 /* Install the chosen minibuffer window, with proper buffer. */
2336 f->minibuffer_window = val;
2337 }
2338 }
2339
2340 DEFUN ("frame-parameters", Fframe_parameters, Sframe_parameters, 0, 1, 0,
2341 doc: /* Return the parameters-alist of frame FRAME.
2342 It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
2343 The meaningful PARMs depend on the kind of frame.
2344 If FRAME is omitted, return information on the currently selected frame. */)
2345 (frame)
2346 Lisp_Object frame;
2347 {
2348 Lisp_Object alist;
2349 FRAME_PTR f;
2350 int height, width;
2351 struct gcpro gcpro1;
2352
2353 if (NILP (frame))
2354 frame = selected_frame;
2355
2356 CHECK_FRAME (frame);
2357 f = XFRAME (frame);
2358
2359 if (!FRAME_LIVE_P (f))
2360 return Qnil;
2361
2362 alist = Fcopy_alist (f->param_alist);
2363 GCPRO1 (alist);
2364
2365 if (!FRAME_WINDOW_P (f))
2366 {
2367 int fg = FRAME_FOREGROUND_PIXEL (f);
2368 int bg = FRAME_BACKGROUND_PIXEL (f);
2369 Lisp_Object elt;
2370
2371 /* If the frame's parameter alist says the colors are
2372 unspecified and reversed, take the frame's background pixel
2373 for foreground and vice versa. */
2374 elt = Fassq (Qforeground_color, alist);
2375 if (CONSP (elt) && STRINGP (XCDR (elt)))
2376 {
2377 if (strncmp (SDATA (XCDR (elt)),
2378 unspecified_bg,
2379 SCHARS (XCDR (elt))) == 0)
2380 store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2381 else if (strncmp (SDATA (XCDR (elt)),
2382 unspecified_fg,
2383 SCHARS (XCDR (elt))) == 0)
2384 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2385 }
2386 else
2387 store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2388 elt = Fassq (Qbackground_color, alist);
2389 if (CONSP (elt) && STRINGP (XCDR (elt)))
2390 {
2391 if (strncmp (SDATA (XCDR (elt)),
2392 unspecified_fg,
2393 SCHARS (XCDR (elt))) == 0)
2394 store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2395 else if (strncmp (SDATA (XCDR (elt)),
2396 unspecified_bg,
2397 SCHARS (XCDR (elt))) == 0)
2398 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2399 }
2400 else
2401 store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2402 store_in_alist (&alist, intern ("font"),
2403 build_string (FRAME_MSDOS_P (f)
2404 ? "ms-dos"
2405 : FRAME_W32_P (f) ? "w32term"
2406 :"tty"));
2407 }
2408 store_in_alist (&alist, Qname, f->name);
2409 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2410 store_in_alist (&alist, Qheight, make_number (height));
2411 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2412 store_in_alist (&alist, Qwidth, make_number (width));
2413 store_in_alist (&alist, Qmodeline, (FRAME_WANTS_MODELINE_P (f) ? Qt : Qnil));
2414 store_in_alist (&alist, Qminibuffer,
2415 (! FRAME_HAS_MINIBUF_P (f) ? Qnil
2416 : FRAME_MINIBUF_ONLY_P (f) ? Qonly
2417 : FRAME_MINIBUF_WINDOW (f)));
2418 store_in_alist (&alist, Qunsplittable, (FRAME_NO_SPLIT_P (f) ? Qt : Qnil));
2419 store_in_alist (&alist, Qbuffer_list, frame_buffer_list (frame));
2420 store_in_alist (&alist, Qburied_buffer_list, XFRAME (frame)->buried_buffer_list);
2421
2422 /* I think this should be done with a hook. */
2423 #ifdef HAVE_WINDOW_SYSTEM
2424 if (FRAME_WINDOW_P (f))
2425 x_report_frame_params (f, &alist);
2426 else
2427 #endif
2428 {
2429 /* This ought to be correct in f->param_alist for an X frame. */
2430 Lisp_Object lines;
2431 XSETFASTINT (lines, FRAME_MENU_BAR_LINES (f));
2432 store_in_alist (&alist, Qmenu_bar_lines, lines);
2433 }
2434
2435 UNGCPRO;
2436 return alist;
2437 }
2438
2439
2440 DEFUN ("frame-parameter", Fframe_parameter, Sframe_parameter, 2, 2, 0,
2441 doc: /* Return FRAME's value for parameter PARAMETER.
2442 If FRAME is nil, describe the currently selected frame. */)
2443 (frame, parameter)
2444 Lisp_Object frame, parameter;
2445 {
2446 struct frame *f;
2447 Lisp_Object value;
2448
2449 if (NILP (frame))
2450 frame = selected_frame;
2451 else
2452 CHECK_FRAME (frame);
2453 CHECK_SYMBOL (parameter);
2454
2455 f = XFRAME (frame);
2456 value = Qnil;
2457
2458 if (FRAME_LIVE_P (f))
2459 {
2460 /* Avoid consing in frequent cases. */
2461 if (EQ (parameter, Qname))
2462 value = f->name;
2463 #ifdef HAVE_X_WINDOWS
2464 else if (EQ (parameter, Qdisplay) && FRAME_X_P (f))
2465 value = XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element);
2466 #endif /* HAVE_X_WINDOWS */
2467 else if (EQ (parameter, Qbackground_color)
2468 || EQ (parameter, Qforeground_color))
2469 {
2470 value = Fassq (parameter, f->param_alist);
2471 if (CONSP (value))
2472 {
2473 value = XCDR (value);
2474 /* Fframe_parameters puts the actual fg/bg color names,
2475 even if f->param_alist says otherwise. This is
2476 important when param_alist's notion of colors is
2477 "unspecified". We need to do the same here. */
2478 if (STRINGP (value) && !FRAME_WINDOW_P (f))
2479 {
2480 const char *color_name;
2481 EMACS_INT csz;
2482
2483 if (EQ (parameter, Qbackground_color))
2484 {
2485 color_name = SDATA (value);
2486 csz = SCHARS (value);
2487 if (strncmp (color_name, unspecified_bg, csz) == 0)
2488 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2489 else if (strncmp (color_name, unspecified_fg, csz) == 0)
2490 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2491 }
2492 else if (EQ (parameter, Qforeground_color))
2493 {
2494 color_name = SDATA (value);
2495 csz = SCHARS (value);
2496 if (strncmp (color_name, unspecified_fg, csz) == 0)
2497 value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2498 else if (strncmp (color_name, unspecified_bg, csz) == 0)
2499 value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2500 }
2501 }
2502 }
2503 else
2504 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2505 }
2506 else if (EQ (parameter, Qdisplay_type)
2507 || EQ (parameter, Qbackground_mode))
2508 value = Fcdr (Fassq (parameter, f->param_alist));
2509 else
2510 value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2511 }
2512
2513 return value;
2514 }
2515
2516
2517 DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2518 Smodify_frame_parameters, 2, 2, 0,
2519 doc: /* Modify the parameters of frame FRAME according to ALIST.
2520 If FRAME is nil, it defaults to the selected frame.
2521 ALIST is an alist of parameters to change and their new values.
2522 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
2523 The meaningful PARMs depend on the kind of frame.
2524 Undefined PARMs are ignored, but stored in the frame's parameter list
2525 so that `frame-parameters' will return them.
2526
2527 The value of frame parameter FOO can also be accessed
2528 as a frame-local binding for the variable FOO, if you have
2529 enabled such bindings for that variable with `make-variable-frame-local'.
2530 Note that this functionality is obsolete as of Emacs 22.2, and its
2531 use is not recommended. Explicitly check for a frame-parameter instead. */)
2532 (frame, alist)
2533 Lisp_Object frame, alist;
2534 {
2535 FRAME_PTR f;
2536 register Lisp_Object tail, prop, val;
2537
2538 if (EQ (frame, Qnil))
2539 frame = selected_frame;
2540 CHECK_LIVE_FRAME (frame);
2541 f = XFRAME (frame);
2542
2543 /* I think this should be done with a hook. */
2544 #ifdef HAVE_WINDOW_SYSTEM
2545 if (FRAME_WINDOW_P (f))
2546 x_set_frame_parameters (f, alist);
2547 else
2548 #endif
2549 #ifdef MSDOS
2550 if (FRAME_MSDOS_P (f))
2551 IT_set_frame_parameters (f, alist);
2552 else
2553 #endif
2554
2555 {
2556 int length = XINT (Flength (alist));
2557 int i;
2558 Lisp_Object *parms
2559 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2560 Lisp_Object *values
2561 = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
2562
2563 /* Extract parm names and values into those vectors. */
2564
2565 i = 0;
2566 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2567 {
2568 Lisp_Object elt;
2569
2570 elt = XCAR (tail);
2571 parms[i] = Fcar (elt);
2572 values[i] = Fcdr (elt);
2573 i++;
2574 }
2575
2576 /* Now process them in reverse of specified order. */
2577 for (i--; i >= 0; i--)
2578 {
2579 prop = parms[i];
2580 val = values[i];
2581 store_frame_param (f, prop, val);
2582
2583 /* Changing the background color might change the background
2584 mode, so that we have to load new defface specs.
2585 Call frame-set-background-mode to do that. */
2586 if (EQ (prop, Qbackground_color))
2587 call1 (Qframe_set_background_mode, frame);
2588 }
2589 }
2590 return Qnil;
2591 }
2592 \f
2593 DEFUN ("frame-char-height", Fframe_char_height, Sframe_char_height,
2594 0, 1, 0,
2595 doc: /* Height in pixels of a line in the font in frame FRAME.
2596 If FRAME is omitted, the selected frame is used.
2597 For a terminal frame, the value is always 1. */)
2598 (frame)
2599 Lisp_Object frame;
2600 {
2601 struct frame *f;
2602
2603 if (NILP (frame))
2604 frame = selected_frame;
2605 CHECK_FRAME (frame);
2606 f = XFRAME (frame);
2607
2608 #ifdef HAVE_WINDOW_SYSTEM
2609 if (FRAME_WINDOW_P (f))
2610 return make_number (x_char_height (f));
2611 else
2612 #endif
2613 return make_number (1);
2614 }
2615
2616
2617 DEFUN ("frame-char-width", Fframe_char_width, Sframe_char_width,
2618 0, 1, 0,
2619 doc: /* Width in pixels of characters in the font in frame FRAME.
2620 If FRAME is omitted, the selected frame is used.
2621 On a graphical screen, the width is the standard width of the default font.
2622 For a terminal screen, the value is always 1. */)
2623 (frame)
2624 Lisp_Object frame;
2625 {
2626 struct frame *f;
2627
2628 if (NILP (frame))
2629 frame = selected_frame;
2630 CHECK_FRAME (frame);
2631 f = XFRAME (frame);
2632
2633 #ifdef HAVE_WINDOW_SYSTEM
2634 if (FRAME_WINDOW_P (f))
2635 return make_number (x_char_width (f));
2636 else
2637 #endif
2638 return make_number (1);
2639 }
2640
2641 DEFUN ("frame-pixel-height", Fframe_pixel_height,
2642 Sframe_pixel_height, 0, 1, 0,
2643 doc: /* Return a FRAME's height in pixels.
2644 This counts only the height available for text lines,
2645 not menu bars on window-system Emacs frames.
2646 For a terminal frame, the result really gives the height in characters.
2647 If FRAME is omitted, the selected frame is used. */)
2648 (frame)
2649 Lisp_Object frame;
2650 {
2651 struct frame *f;
2652
2653 if (NILP (frame))
2654 frame = selected_frame;
2655 CHECK_FRAME (frame);
2656 f = XFRAME (frame);
2657
2658 #ifdef HAVE_WINDOW_SYSTEM
2659 if (FRAME_WINDOW_P (f))
2660 return make_number (x_pixel_height (f));
2661 else
2662 #endif
2663 return make_number (FRAME_LINES (f));
2664 }
2665
2666 DEFUN ("frame-pixel-width", Fframe_pixel_width,
2667 Sframe_pixel_width, 0, 1, 0,
2668 doc: /* Return FRAME's width in pixels.
2669 For a terminal frame, the result really gives the width in characters.
2670 If FRAME is omitted, the selected frame is used. */)
2671 (frame)
2672 Lisp_Object frame;
2673 {
2674 struct frame *f;
2675
2676 if (NILP (frame))
2677 frame = selected_frame;
2678 CHECK_FRAME (frame);
2679 f = XFRAME (frame);
2680
2681 #ifdef HAVE_WINDOW_SYSTEM
2682 if (FRAME_WINDOW_P (f))
2683 return make_number (x_pixel_width (f));
2684 else
2685 #endif
2686 return make_number (FRAME_COLS (f));
2687 }
2688 \f
2689 DEFUN ("set-frame-height", Fset_frame_height, Sset_frame_height, 2, 3, 0,
2690 doc: /* Specify that the frame FRAME has LINES lines.
2691 Optional third arg non-nil means that redisplay should use LINES lines
2692 but that the idea of the actual height of the frame should not be changed. */)
2693 (frame, lines, pretend)
2694 Lisp_Object frame, lines, pretend;
2695 {
2696 register struct frame *f;
2697
2698 CHECK_NUMBER (lines);
2699 if (NILP (frame))
2700 frame = selected_frame;
2701 CHECK_LIVE_FRAME (frame);
2702 f = XFRAME (frame);
2703
2704 /* I think this should be done with a hook. */
2705 #ifdef HAVE_WINDOW_SYSTEM
2706 if (FRAME_WINDOW_P (f))
2707 {
2708 if (XINT (lines) != FRAME_LINES (f))
2709 x_set_window_size (f, 1, FRAME_COLS (f), XINT (lines));
2710 do_pending_window_change (0);
2711 }
2712 else
2713 #endif
2714 change_frame_size (f, XINT (lines), 0, !NILP (pretend), 0, 0);
2715 return Qnil;
2716 }
2717
2718 DEFUN ("set-frame-width", Fset_frame_width, Sset_frame_width, 2, 3, 0,
2719 doc: /* Specify that the frame FRAME has COLS columns.
2720 Optional third arg non-nil means that redisplay should use COLS columns
2721 but that the idea of the actual width of the frame should not be changed. */)
2722 (frame, cols, pretend)
2723 Lisp_Object frame, cols, pretend;
2724 {
2725 register struct frame *f;
2726 CHECK_NUMBER (cols);
2727 if (NILP (frame))
2728 frame = selected_frame;
2729 CHECK_LIVE_FRAME (frame);
2730 f = XFRAME (frame);
2731
2732 /* I think this should be done with a hook. */
2733 #ifdef HAVE_WINDOW_SYSTEM
2734 if (FRAME_WINDOW_P (f))
2735 {
2736 if (XINT (cols) != FRAME_COLS (f))
2737 x_set_window_size (f, 1, XINT (cols), FRAME_LINES (f));
2738 do_pending_window_change (0);
2739 }
2740 else
2741 #endif
2742 change_frame_size (f, 0, XINT (cols), !NILP (pretend), 0, 0);
2743 return Qnil;
2744 }
2745
2746 DEFUN ("set-frame-size", Fset_frame_size, Sset_frame_size, 3, 3, 0,
2747 doc: /* Sets size of FRAME to COLS by ROWS, measured in characters. */)
2748 (frame, cols, rows)
2749 Lisp_Object frame, cols, rows;
2750 {
2751 register struct frame *f;
2752
2753 CHECK_LIVE_FRAME (frame);
2754 CHECK_NUMBER (cols);
2755 CHECK_NUMBER (rows);
2756 f = XFRAME (frame);
2757
2758 /* I think this should be done with a hook. */
2759 #ifdef HAVE_WINDOW_SYSTEM
2760 if (FRAME_WINDOW_P (f))
2761 {
2762 if (XINT (rows) != FRAME_LINES (f)
2763 || XINT (cols) != FRAME_COLS (f)
2764 || f->new_text_lines || f->new_text_cols)
2765 x_set_window_size (f, 1, XINT (cols), XINT (rows));
2766 do_pending_window_change (0);
2767 }
2768 else
2769 #endif
2770 change_frame_size (f, XINT (rows), XINT (cols), 0, 0, 0);
2771
2772 return Qnil;
2773 }
2774
2775 DEFUN ("set-frame-position", Fset_frame_position,
2776 Sset_frame_position, 3, 3, 0,
2777 doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2778 This is actually the position of the upper left corner of the frame.
2779 Negative values for XOFFSET or YOFFSET are interpreted relative to
2780 the rightmost or bottommost possible position (that stays within the screen). */)
2781 (frame, xoffset, yoffset)
2782 Lisp_Object frame, xoffset, yoffset;
2783 {
2784 register struct frame *f;
2785
2786 CHECK_LIVE_FRAME (frame);
2787 CHECK_NUMBER (xoffset);
2788 CHECK_NUMBER (yoffset);
2789 f = XFRAME (frame);
2790
2791 /* I think this should be done with a hook. */
2792 #ifdef HAVE_WINDOW_SYSTEM
2793 if (FRAME_WINDOW_P (f))
2794 x_set_offset (f, XINT (xoffset), XINT (yoffset), 1);
2795 #endif
2796
2797 return Qt;
2798 }
2799
2800 \f
2801 /***********************************************************************
2802 Frame Parameters
2803 ***********************************************************************/
2804
2805 /* Connect the frame-parameter names for X frames
2806 to the ways of passing the parameter values to the window system.
2807
2808 The name of a parameter, as a Lisp symbol,
2809 has an `x-frame-parameter' property which is an integer in Lisp
2810 that is an index in this table. */
2811
2812 struct frame_parm_table {
2813 char *name;
2814 Lisp_Object *variable;
2815 };
2816
2817 static struct frame_parm_table frame_parms[] =
2818 {
2819 {"auto-raise", &Qauto_raise},
2820 {"auto-lower", &Qauto_lower},
2821 {"background-color", 0},
2822 {"border-color", &Qborder_color},
2823 {"border-width", &Qborder_width},
2824 {"cursor-color", &Qcursor_color},
2825 {"cursor-type", &Qcursor_type},
2826 {"font", 0},
2827 {"foreground-color", 0},
2828 {"icon-name", &Qicon_name},
2829 {"icon-type", &Qicon_type},
2830 {"internal-border-width", &Qinternal_border_width},
2831 {"menu-bar-lines", &Qmenu_bar_lines},
2832 {"mouse-color", &Qmouse_color},
2833 {"name", &Qname},
2834 {"scroll-bar-width", &Qscroll_bar_width},
2835 {"title", &Qtitle},
2836 {"unsplittable", &Qunsplittable},
2837 {"vertical-scroll-bars", &Qvertical_scroll_bars},
2838 {"visibility", &Qvisibility},
2839 {"tool-bar-lines", &Qtool_bar_lines},
2840 {"scroll-bar-foreground", &Qscroll_bar_foreground},
2841 {"scroll-bar-background", &Qscroll_bar_background},
2842 {"screen-gamma", &Qscreen_gamma},
2843 {"line-spacing", &Qline_spacing},
2844 {"left-fringe", &Qleft_fringe},
2845 {"right-fringe", &Qright_fringe},
2846 {"wait-for-wm", &Qwait_for_wm},
2847 {"fullscreen", &Qfullscreen},
2848 {"font-backend", &Qfont_backend},
2849 {"alpha", &Qalpha}
2850 };
2851
2852 #ifdef HAVE_WINDOW_SYSTEM
2853
2854 extern Lisp_Object Qbox;
2855 extern Lisp_Object Qtop;
2856
2857 /* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the
2858 wanted positions of the WM window (not Emacs window).
2859 Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2860 window (FRAME_X_WINDOW).
2861 */
2862
2863 void
2864 x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2865 struct frame *f;
2866 int *width;
2867 int *height;
2868 int *top_pos;
2869 int *left_pos;
2870 {
2871 int newwidth = FRAME_COLS (f);
2872 int newheight = FRAME_LINES (f);
2873 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
2874
2875 *top_pos = f->top_pos;
2876 *left_pos = f->left_pos;
2877
2878 if (f->want_fullscreen & FULLSCREEN_HEIGHT)
2879 {
2880 int ph;
2881
2882 ph = x_display_pixel_height (dpyinfo);
2883 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2884 ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff;
2885 newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph);
2886 *top_pos = 0;
2887 }
2888
2889 if (f->want_fullscreen & FULLSCREEN_WIDTH)
2890 {
2891 int pw;
2892
2893 pw = x_display_pixel_width (dpyinfo);
2894 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2895 pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff;
2896 newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw);
2897 *left_pos = 0;
2898 }
2899
2900 *width = newwidth;
2901 *height = newheight;
2902 }
2903
2904
2905 /* Change the parameters of frame F as specified by ALIST.
2906 If a parameter is not specially recognized, do nothing special;
2907 otherwise call the `x_set_...' function for that parameter.
2908 Except for certain geometry properties, always call store_frame_param
2909 to store the new value in the parameter alist. */
2910
2911 void
2912 x_set_frame_parameters (f, alist)
2913 FRAME_PTR f;
2914 Lisp_Object alist;
2915 {
2916 Lisp_Object tail;
2917
2918 /* If both of these parameters are present, it's more efficient to
2919 set them both at once. So we wait until we've looked at the
2920 entire list before we set them. */
2921 int width, height;
2922
2923 /* Same here. */
2924 Lisp_Object left, top;
2925
2926 /* Same with these. */
2927 Lisp_Object icon_left, icon_top;
2928
2929 /* Record in these vectors all the parms specified. */
2930 Lisp_Object *parms;
2931 Lisp_Object *values;
2932 int i, p;
2933 int left_no_change = 0, top_no_change = 0;
2934 int icon_left_no_change = 0, icon_top_no_change = 0;
2935 int fullscreen_is_being_set = 0;
2936
2937 struct gcpro gcpro1, gcpro2;
2938
2939 i = 0;
2940 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2941 i++;
2942
2943 parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2944 values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2945
2946 /* Extract parm names and values into those vectors. */
2947
2948 i = 0;
2949 for (tail = alist; CONSP (tail); tail = XCDR (tail))
2950 {
2951 Lisp_Object elt;
2952
2953 elt = XCAR (tail);
2954 parms[i] = Fcar (elt);
2955 values[i] = Fcdr (elt);
2956 i++;
2957 }
2958 /* TAIL and ALIST are not used again below here. */
2959 alist = tail = Qnil;
2960
2961 GCPRO2 (*parms, *values);
2962 gcpro1.nvars = i;
2963 gcpro2.nvars = i;
2964
2965 /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2966 because their values appear in VALUES and strings are not valid. */
2967 top = left = Qunbound;
2968 icon_left = icon_top = Qunbound;
2969
2970 /* Provide default values for HEIGHT and WIDTH. */
2971 width = (f->new_text_cols ? f->new_text_cols : FRAME_COLS (f));
2972 height = (f->new_text_lines ? f->new_text_lines : FRAME_LINES (f));
2973
2974 /* Process foreground_color and background_color before anything else.
2975 They are independent of other properties, but other properties (e.g.,
2976 cursor_color) are dependent upon them. */
2977 /* Process default font as well, since fringe widths depends on it. */
2978 /* Also, process fullscreen, width and height depend upon that */
2979 for (p = 0; p < i; p++)
2980 {
2981 Lisp_Object prop, val;
2982
2983 prop = parms[p];
2984 val = values[p];
2985 if (EQ (prop, Qforeground_color)
2986 || EQ (prop, Qbackground_color)
2987 || EQ (prop, Qfont)
2988 || EQ (prop, Qfullscreen))
2989 {
2990 register Lisp_Object param_index, old_value;
2991
2992 old_value = get_frame_param (f, prop);
2993 fullscreen_is_being_set |= EQ (prop, Qfullscreen);
2994 if (NILP (Fequal (val, old_value)))
2995 {
2996 store_frame_param (f, prop, val);
2997
2998 param_index = Fget (prop, Qx_frame_parameter);
2999 if (NATNUMP (param_index)
3000 && (XFASTINT (param_index)
3001 < sizeof (frame_parms)/sizeof (frame_parms[0]))
3002 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3003 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
3004 }
3005 }
3006 }
3007
3008 /* Now process them in reverse of specified order. */
3009 for (i--; i >= 0; i--)
3010 {
3011 Lisp_Object prop, val;
3012
3013 prop = parms[i];
3014 val = values[i];
3015
3016 if (EQ (prop, Qwidth) && NATNUMP (val))
3017 width = XFASTINT (val);
3018 else if (EQ (prop, Qheight) && NATNUMP (val))
3019 height = XFASTINT (val);
3020 else if (EQ (prop, Qtop))
3021 top = val;
3022 else if (EQ (prop, Qleft))
3023 left = val;
3024 else if (EQ (prop, Qicon_top))
3025 icon_top = val;
3026 else if (EQ (prop, Qicon_left))
3027 icon_left = val;
3028 else if (EQ (prop, Qforeground_color)
3029 || EQ (prop, Qbackground_color)
3030 || EQ (prop, Qfont)
3031 || EQ (prop, Qfullscreen))
3032 /* Processed above. */
3033 continue;
3034 else
3035 {
3036 register Lisp_Object param_index, old_value;
3037
3038 old_value = get_frame_param (f, prop);
3039
3040 store_frame_param (f, prop, val);
3041
3042 param_index = Fget (prop, Qx_frame_parameter);
3043 if (NATNUMP (param_index)
3044 && (XFASTINT (param_index)
3045 < sizeof (frame_parms)/sizeof (frame_parms[0]))
3046 && FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])
3047 (*(FRAME_RIF (f)->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
3048 }
3049 }
3050
3051 /* Don't die if just one of these was set. */
3052 if (EQ (left, Qunbound))
3053 {
3054 left_no_change = 1;
3055 if (f->left_pos < 0)
3056 left = Fcons (Qplus, Fcons (make_number (f->left_pos), Qnil));
3057 else
3058 XSETINT (left, f->left_pos);
3059 }
3060 if (EQ (top, Qunbound))
3061 {
3062 top_no_change = 1;
3063 if (f->top_pos < 0)
3064 top = Fcons (Qplus, Fcons (make_number (f->top_pos), Qnil));
3065 else
3066 XSETINT (top, f->top_pos);
3067 }
3068
3069 /* If one of the icon positions was not set, preserve or default it. */
3070 if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
3071 {
3072 icon_left_no_change = 1;
3073 icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
3074 if (NILP (icon_left))
3075 XSETINT (icon_left, 0);
3076 }
3077 if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
3078 {
3079 icon_top_no_change = 1;
3080 icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
3081 if (NILP (icon_top))
3082 XSETINT (icon_top, 0);
3083 }
3084
3085 if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
3086 {
3087 /* If the frame is visible already and the fullscreen parameter is
3088 being set, it is too late to set WM manager hints to specify
3089 size and position.
3090 Here we first get the width, height and position that applies to
3091 fullscreen. We then move the frame to the appropriate
3092 position. Resize of the frame is taken care of in the code after
3093 this if-statement. */
3094 int new_left, new_top;
3095
3096 x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
3097 if (new_top != f->top_pos || new_left != f->left_pos)
3098 x_set_offset (f, new_left, new_top, 1);
3099 }
3100
3101 /* Don't set these parameters unless they've been explicitly
3102 specified. The window might be mapped or resized while we're in
3103 this function, and we don't want to override that unless the lisp
3104 code has asked for it.
3105
3106 Don't set these parameters unless they actually differ from the
3107 window's current parameters; the window may not actually exist
3108 yet. */
3109 {
3110 Lisp_Object frame;
3111
3112 check_frame_size (f, &height, &width);
3113
3114 XSETFRAME (frame, f);
3115
3116 if (width != FRAME_COLS (f)
3117 || height != FRAME_LINES (f)
3118 || f->new_text_lines || f->new_text_cols)
3119 Fset_frame_size (frame, make_number (width), make_number (height));
3120
3121 if ((!NILP (left) || !NILP (top))
3122 && ! (left_no_change && top_no_change)
3123 && ! (NUMBERP (left) && XINT (left) == f->left_pos
3124 && NUMBERP (top) && XINT (top) == f->top_pos))
3125 {
3126 int leftpos = 0;
3127 int toppos = 0;
3128
3129 /* Record the signs. */
3130 f->size_hint_flags &= ~ (XNegative | YNegative);
3131 if (EQ (left, Qminus))
3132 f->size_hint_flags |= XNegative;
3133 else if (INTEGERP (left))
3134 {
3135 leftpos = XINT (left);
3136 if (leftpos < 0)
3137 f->size_hint_flags |= XNegative;
3138 }
3139 else if (CONSP (left) && EQ (XCAR (left), Qminus)
3140 && CONSP (XCDR (left))
3141 && INTEGERP (XCAR (XCDR (left))))
3142 {
3143 leftpos = - XINT (XCAR (XCDR (left)));
3144 f->size_hint_flags |= XNegative;
3145 }
3146 else if (CONSP (left) && EQ (XCAR (left), Qplus)
3147 && CONSP (XCDR (left))
3148 && INTEGERP (XCAR (XCDR (left))))
3149 {
3150 leftpos = XINT (XCAR (XCDR (left)));
3151 }
3152
3153 if (EQ (top, Qminus))
3154 f->size_hint_flags |= YNegative;
3155 else if (INTEGERP (top))
3156 {
3157 toppos = XINT (top);
3158 if (toppos < 0)
3159 f->size_hint_flags |= YNegative;
3160 }
3161 else if (CONSP (top) && EQ (XCAR (top), Qminus)
3162 && CONSP (XCDR (top))
3163 && INTEGERP (XCAR (XCDR (top))))
3164 {
3165 toppos = - XINT (XCAR (XCDR (top)));
3166 f->size_hint_flags |= YNegative;
3167 }
3168 else if (CONSP (top) && EQ (XCAR (top), Qplus)
3169 && CONSP (XCDR (top))
3170 && INTEGERP (XCAR (XCDR (top))))
3171 {
3172 toppos = XINT (XCAR (XCDR (top)));
3173 }
3174
3175
3176 /* Store the numeric value of the position. */
3177 f->top_pos = toppos;
3178 f->left_pos = leftpos;
3179
3180 f->win_gravity = NorthWestGravity;
3181
3182 /* Actually set that position, and convert to absolute. */
3183 x_set_offset (f, leftpos, toppos, -1);
3184 }
3185
3186 if ((!NILP (icon_left) || !NILP (icon_top))
3187 && ! (icon_left_no_change && icon_top_no_change))
3188 x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
3189 }
3190
3191 UNGCPRO;
3192 }
3193
3194
3195 /* Insert a description of internally-recorded parameters of frame X
3196 into the parameter alist *ALISTPTR that is to be given to the user.
3197 Only parameters that are specific to the X window system
3198 and whose values are not correctly recorded in the frame's
3199 param_alist need to be considered here. */
3200
3201 void
3202 x_report_frame_params (f, alistptr)
3203 struct frame *f;
3204 Lisp_Object *alistptr;
3205 {
3206 char buf[16];
3207 Lisp_Object tem;
3208
3209 /* Represent negative positions (off the top or left screen edge)
3210 in a way that Fmodify_frame_parameters will understand correctly. */
3211 XSETINT (tem, f->left_pos);
3212 if (f->left_pos >= 0)
3213 store_in_alist (alistptr, Qleft, tem);
3214 else
3215 store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
3216
3217 XSETINT (tem, f->top_pos);
3218 if (f->top_pos >= 0)
3219 store_in_alist (alistptr, Qtop, tem);
3220 else
3221 store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
3222
3223 store_in_alist (alistptr, Qborder_width,
3224 make_number (f->border_width));
3225 store_in_alist (alistptr, Qinternal_border_width,
3226 make_number (FRAME_INTERNAL_BORDER_WIDTH (f)));
3227 store_in_alist (alistptr, Qleft_fringe,
3228 make_number (FRAME_LEFT_FRINGE_WIDTH (f)));
3229 store_in_alist (alistptr, Qright_fringe,
3230 make_number (FRAME_RIGHT_FRINGE_WIDTH (f)));
3231 store_in_alist (alistptr, Qscroll_bar_width,
3232 (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3233 ? make_number (0)
3234 : FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0
3235 ? make_number (FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3236 /* nil means "use default width"
3237 for non-toolkit scroll bar.
3238 ruler-mode.el depends on this. */
3239 : Qnil));
3240 sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
3241 store_in_alist (alistptr, Qwindow_id,
3242 build_string (buf));
3243 #ifdef HAVE_X_WINDOWS
3244 #ifdef USE_X_TOOLKIT
3245 /* Tooltip frame may not have this widget. */
3246 if (FRAME_X_OUTPUT (f)->widget)
3247 #endif
3248 sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
3249 store_in_alist (alistptr, Qouter_window_id,
3250 build_string (buf));
3251 #endif
3252 store_in_alist (alistptr, Qicon_name, f->icon_name);
3253 FRAME_SAMPLE_VISIBILITY (f);
3254 store_in_alist (alistptr, Qvisibility,
3255 (FRAME_VISIBLE_P (f) ? Qt
3256 : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
3257 store_in_alist (alistptr, Qdisplay,
3258 XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
3259
3260 if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
3261 tem = Qnil;
3262 else
3263 XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
3264 store_in_alist (alistptr, Qexplicit_name, (f->explicit_name ? Qt : Qnil));
3265 store_in_alist (alistptr, Qparent_id, tem);
3266 }
3267
3268
3269 /* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is
3270 the previous value of that parameter, NEW_VALUE is the new value. */
3271
3272 void
3273 x_set_fullscreen (f, new_value, old_value)
3274 struct frame *f;
3275 Lisp_Object new_value, old_value;
3276 {
3277 if (NILP (new_value))
3278 f->want_fullscreen = FULLSCREEN_NONE;
3279 else if (EQ (new_value, Qfullboth))
3280 f->want_fullscreen = FULLSCREEN_BOTH;
3281 else if (EQ (new_value, Qfullwidth))
3282 f->want_fullscreen = FULLSCREEN_WIDTH;
3283 else if (EQ (new_value, Qfullheight))
3284 f->want_fullscreen = FULLSCREEN_HEIGHT;
3285
3286 if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
3287 FRAME_TERMINAL (f)->fullscreen_hook (f);
3288 }
3289
3290
3291 /* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is
3292 the previous value of that parameter, NEW_VALUE is the new value. */
3293
3294 void
3295 x_set_line_spacing (f, new_value, old_value)
3296 struct frame *f;
3297 Lisp_Object new_value, old_value;
3298 {
3299 if (NILP (new_value))
3300 f->extra_line_spacing = 0;
3301 else if (NATNUMP (new_value))
3302 f->extra_line_spacing = XFASTINT (new_value);
3303 else
3304 signal_error ("Invalid line-spacing", new_value);
3305 if (FRAME_VISIBLE_P (f))
3306 redraw_frame (f);
3307 }
3308
3309
3310 /* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is
3311 the previous value of that parameter, NEW_VALUE is the new value. */
3312
3313 void
3314 x_set_screen_gamma (f, new_value, old_value)
3315 struct frame *f;
3316 Lisp_Object new_value, old_value;
3317 {
3318 Lisp_Object bgcolor;
3319
3320 if (NILP (new_value))
3321 f->gamma = 0;
3322 else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3323 /* The value 0.4545 is the normal viewing gamma. */
3324 f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3325 else
3326 signal_error ("Invalid screen-gamma", new_value);
3327
3328 /* Apply the new gamma value to the frame background. */
3329 bgcolor = Fassq (Qbackground_color, f->param_alist);
3330 if (CONSP (bgcolor) && (bgcolor = XCDR (bgcolor), STRINGP (bgcolor)))
3331 {
3332 Lisp_Object index = Fget (Qbackground_color, Qx_frame_parameter);
3333 if (NATNUMP (index)
3334 && (XFASTINT (index)
3335 < sizeof (frame_parms)/sizeof (frame_parms[0]))
3336 && FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
3337 (*FRAME_RIF (f)->frame_parm_handlers[XFASTINT (index)])
3338 (f, bgcolor, Qnil);
3339 }
3340
3341 Fclear_face_cache (Qnil);
3342 }
3343
3344
3345 void
3346 x_set_font (f, arg, oldval)
3347 struct frame *f;
3348 Lisp_Object arg, oldval;
3349 {
3350 Lisp_Object frame;
3351 int fontset = -1;
3352 Lisp_Object font_object;
3353
3354 /* Set the frame parameter back to the old value because we may
3355 fail to use ARG as the new parameter value. */
3356 store_frame_param (f, Qfont, oldval);
3357
3358 /* ARG is a fontset name, a font name, or a font object.
3359 In the last case, this function never fail. */
3360 if (STRINGP (arg))
3361 {
3362 fontset = fs_query_fontset (arg, 0);
3363 if (fontset < 0)
3364 {
3365 font_object = font_open_by_name (f, SDATA (arg));
3366 if (NILP (font_object))
3367 error ("Font `%s' is not defined", SDATA (arg));
3368 arg = AREF (font_object, FONT_NAME_INDEX);
3369 }
3370 else if (fontset > 0)
3371 {
3372 Lisp_Object ascii_font = fontset_ascii (fontset);
3373
3374 font_object = font_open_by_name (f, SDATA (ascii_font));
3375 if (NILP (font_object))
3376 error ("Font `%s' is not defined", SDATA (arg));
3377 arg = fontset_name (fontset);
3378 }
3379 else
3380 error ("The default fontset can't be used for a frame font");
3381 }
3382 else if (FONT_OBJECT_P (arg))
3383 {
3384 font_object = arg;
3385 /* This is store the XLFD font name in the frame parameter for
3386 backward compatiblity. We should store the font-object
3387 itself in the future. */
3388 arg = AREF (font_object, FONT_NAME_INDEX);
3389 }
3390 else
3391 signal_error ("Invalid font", arg);
3392
3393 if (! NILP (Fequal (font_object, oldval)))
3394 return;
3395 x_new_font (f, font_object, fontset);
3396 store_frame_param (f, Qfont, arg);
3397 /* Recalculate toolbar height. */
3398 f->n_tool_bar_rows = 0;
3399 /* Ensure we redraw it. */
3400 clear_current_matrices (f);
3401
3402 recompute_basic_faces (f);
3403
3404 do_pending_window_change (0);
3405
3406 /* We used to call face-set-after-frame-default here, but it leads to
3407 recursive calls (since that function can set the `default' face's
3408 font which in turns changes the frame's `font' parameter).
3409 Also I don't know what this call is meant to do, but it seems the
3410 wrong way to do it anyway (it does a lot more work than what seems
3411 reasonable in response to a change to `font'). */
3412 }
3413
3414
3415 void
3416 x_set_font_backend (f, new_value, old_value)
3417 struct frame *f;
3418 Lisp_Object new_value, old_value;
3419 {
3420 if (! NILP (new_value)
3421 && !CONSP (new_value))
3422 {
3423 char *p0, *p1;
3424
3425 CHECK_STRING (new_value);
3426 p0 = p1 = SDATA (new_value);
3427 new_value = Qnil;
3428 while (*p0)
3429 {
3430 while (*p1 && ! isspace (*p1) && *p1 != ',') p1++;
3431 if (p0 < p1)
3432 new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
3433 new_value);
3434 if (*p1)
3435 {
3436 int c;
3437
3438 while ((c = *++p1) && isspace (c));
3439 }
3440 p0 = p1;
3441 }
3442 new_value = Fnreverse (new_value);
3443 }
3444
3445 if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
3446 return;
3447
3448 if (FRAME_FONT (f))
3449 free_all_realized_faces (Qnil);
3450
3451 new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
3452 if (NILP (new_value))
3453 {
3454 if (NILP (old_value))
3455 error ("No font backend available");
3456 font_update_drivers (f, old_value);
3457 error ("None of specified font backends are available");
3458 }
3459 store_frame_param (f, Qfont_backend, new_value);
3460
3461 if (FRAME_FONT (f))
3462 {
3463 Lisp_Object frame;
3464
3465 XSETFRAME (frame, f);
3466 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
3467 ++face_change_count;
3468 ++windows_or_buffers_changed;
3469 }
3470 }
3471
3472
3473 void
3474 x_set_fringe_width (f, new_value, old_value)
3475 struct frame *f;
3476 Lisp_Object new_value, old_value;
3477 {
3478 compute_fringe_widths (f, 1);
3479 }
3480
3481 void
3482 x_set_border_width (f, arg, oldval)
3483 struct frame *f;
3484 Lisp_Object arg, oldval;
3485 {
3486 CHECK_NUMBER (arg);
3487
3488 if (XINT (arg) == f->border_width)
3489 return;
3490
3491 if (FRAME_X_WINDOW (f) != 0)
3492 error ("Cannot change the border width of a frame");
3493
3494 f->border_width = XINT (arg);
3495 }
3496
3497 void
3498 x_set_internal_border_width (f, arg, oldval)
3499 struct frame *f;
3500 Lisp_Object arg, oldval;
3501 {
3502 int old = FRAME_INTERNAL_BORDER_WIDTH (f);
3503
3504 CHECK_NUMBER (arg);
3505 FRAME_INTERNAL_BORDER_WIDTH (f) = XINT (arg);
3506 if (FRAME_INTERNAL_BORDER_WIDTH (f) < 0)
3507 FRAME_INTERNAL_BORDER_WIDTH (f) = 0;
3508
3509 #ifdef USE_X_TOOLKIT
3510 if (FRAME_X_OUTPUT (f)->edit_widget)
3511 widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3512 #endif
3513
3514 if (FRAME_INTERNAL_BORDER_WIDTH (f) == old)
3515 return;
3516
3517 if (FRAME_X_WINDOW (f) != 0)
3518 {
3519 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3520 SET_FRAME_GARBAGED (f);
3521 do_pending_window_change (0);
3522 }
3523 else
3524 SET_FRAME_GARBAGED (f);
3525 }
3526
3527 void
3528 x_set_visibility (f, value, oldval)
3529 struct frame *f;
3530 Lisp_Object value, oldval;
3531 {
3532 Lisp_Object frame;
3533 XSETFRAME (frame, f);
3534
3535 if (NILP (value))
3536 Fmake_frame_invisible (frame, Qt);
3537 else if (EQ (value, Qicon))
3538 Ficonify_frame (frame);
3539 else
3540 Fmake_frame_visible (frame);
3541 }
3542
3543 void
3544 x_set_autoraise (f, arg, oldval)
3545 struct frame *f;
3546 Lisp_Object arg, oldval;
3547 {
3548 f->auto_raise = !EQ (Qnil, arg);
3549 }
3550
3551 void
3552 x_set_autolower (f, arg, oldval)
3553 struct frame *f;
3554 Lisp_Object arg, oldval;
3555 {
3556 f->auto_lower = !EQ (Qnil, arg);
3557 }
3558
3559 void
3560 x_set_unsplittable (f, arg, oldval)
3561 struct frame *f;
3562 Lisp_Object arg, oldval;
3563 {
3564 f->no_split = !NILP (arg);
3565 }
3566
3567 void
3568 x_set_vertical_scroll_bars (f, arg, oldval)
3569 struct frame *f;
3570 Lisp_Object arg, oldval;
3571 {
3572 if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3573 || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3574 || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3575 || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3576 {
3577 FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3578 = (NILP (arg)
3579 ? vertical_scroll_bar_none
3580 : EQ (Qleft, arg)
3581 ? vertical_scroll_bar_left
3582 : EQ (Qright, arg)
3583 ? vertical_scroll_bar_right
3584 : EQ (Qleft, Vdefault_frame_scroll_bars)
3585 ? vertical_scroll_bar_left
3586 : EQ (Qright, Vdefault_frame_scroll_bars)
3587 ? vertical_scroll_bar_right
3588 : vertical_scroll_bar_none);
3589
3590 /* We set this parameter before creating the X window for the
3591 frame, so we can get the geometry right from the start.
3592 However, if the window hasn't been created yet, we shouldn't
3593 call x_set_window_size. */
3594 if (FRAME_X_WINDOW (f))
3595 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3596 do_pending_window_change (0);
3597 }
3598 }
3599
3600 void
3601 x_set_scroll_bar_width (f, arg, oldval)
3602 struct frame *f;
3603 Lisp_Object arg, oldval;
3604 {
3605 int wid = FRAME_COLUMN_WIDTH (f);
3606
3607 if (NILP (arg))
3608 {
3609 x_set_scroll_bar_default_width (f);
3610
3611 if (FRAME_X_WINDOW (f))
3612 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3613 do_pending_window_change (0);
3614 }
3615 else if (INTEGERP (arg) && XINT (arg) > 0
3616 && XFASTINT (arg) != FRAME_CONFIG_SCROLL_BAR_WIDTH (f))
3617 {
3618 if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3619 XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3620
3621 FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = XFASTINT (arg);
3622 FRAME_CONFIG_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3623 if (FRAME_X_WINDOW (f))
3624 x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
3625 do_pending_window_change (0);
3626 }
3627
3628 change_frame_size (f, 0, FRAME_COLS (f), 0, 0, 0);
3629 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3630 XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3631 }
3632
3633
3634
3635 /* Return non-nil if frame F wants a bitmap icon. */
3636
3637 Lisp_Object
3638 x_icon_type (f)
3639 FRAME_PTR f;
3640 {
3641 Lisp_Object tem;
3642
3643 tem = assq_no_quit (Qicon_type, f->param_alist);
3644 if (CONSP (tem))
3645 return XCDR (tem);
3646 else
3647 return Qnil;
3648 }
3649
3650 void
3651 x_set_alpha (f, arg, oldval)
3652 struct frame *f;
3653 Lisp_Object arg, oldval;
3654 {
3655 double alpha = 1.0;
3656 double newval[2];
3657 int i, ialpha;
3658 Lisp_Object item;
3659
3660 for (i = 0; i < 2; i++)
3661 {
3662 newval[i] = 1.0;
3663 if (CONSP (arg))
3664 {
3665 item = CAR (arg);
3666 arg = CDR (arg);
3667 }
3668 else
3669 item = arg;
3670
3671 if (NILP (item))
3672 alpha = - 1.0;
3673 else if (FLOATP (item))
3674 {
3675 alpha = XFLOAT_DATA (item);
3676 if (alpha < 0.0 || 1.0 < alpha)
3677 args_out_of_range (make_float (0.0), make_float (1.0));
3678 }
3679 else if (INTEGERP (item))
3680 {
3681 ialpha = XINT (item);
3682 if (ialpha < 0 || 100 < ialpha)
3683 args_out_of_range (make_number (0), make_number (100));
3684 else
3685 alpha = ialpha / 100.0;
3686 }
3687 else
3688 wrong_type_argument (Qnumberp, item);
3689 newval[i] = alpha;
3690 }
3691
3692 for (i = 0; i < 2; i++)
3693 f->alpha[i] = newval[i];
3694
3695 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) || defined (NS_IMPL_COCOA)
3696 BLOCK_INPUT;
3697 x_set_frame_alpha (f);
3698 UNBLOCK_INPUT;
3699 #endif
3700
3701 return;
3702 }
3703
3704 \f
3705 /* Subroutines of creating an X frame. */
3706
3707 /* Make sure that Vx_resource_name is set to a reasonable value.
3708 Fix it up, or set it to `emacs' if it is too hopeless. */
3709
3710 void
3711 validate_x_resource_name ()
3712 {
3713 int len = 0;
3714 /* Number of valid characters in the resource name. */
3715 int good_count = 0;
3716 /* Number of invalid characters in the resource name. */
3717 int bad_count = 0;
3718 Lisp_Object new;
3719 int i;
3720
3721 if (!STRINGP (Vx_resource_class))
3722 Vx_resource_class = build_string (EMACS_CLASS);
3723
3724 if (STRINGP (Vx_resource_name))
3725 {
3726 unsigned char *p = SDATA (Vx_resource_name);
3727 int i;
3728
3729 len = SBYTES (Vx_resource_name);
3730
3731 /* Only letters, digits, - and _ are valid in resource names.
3732 Count the valid characters and count the invalid ones. */
3733 for (i = 0; i < len; i++)
3734 {
3735 int c = p[i];
3736 if (! ((c >= 'a' && c <= 'z')
3737 || (c >= 'A' && c <= 'Z')
3738 || (c >= '0' && c <= '9')
3739 || c == '-' || c == '_'))
3740 bad_count++;
3741 else
3742 good_count++;
3743 }
3744 }
3745 else
3746 /* Not a string => completely invalid. */
3747 bad_count = 5, good_count = 0;
3748
3749 /* If name is valid already, return. */
3750 if (bad_count == 0)
3751 return;
3752
3753 /* If name is entirely invalid, or nearly so, use `emacs'. */
3754 if (good_count == 0
3755 || (good_count == 1 && bad_count > 0))
3756 {
3757 Vx_resource_name = build_string ("emacs");
3758 return;
3759 }
3760
3761 /* Name is partly valid. Copy it and replace the invalid characters
3762 with underscores. */
3763
3764 Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3765
3766 for (i = 0; i < len; i++)
3767 {
3768 int c = SREF (new, i);
3769 if (! ((c >= 'a' && c <= 'z')
3770 || (c >= 'A' && c <= 'Z')
3771 || (c >= '0' && c <= '9')
3772 || c == '-' || c == '_'))
3773 SSET (new, i, '_');
3774 }
3775 }
3776
3777
3778 extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3779 extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3780
3781
3782 /* Get specified attribute from resource database RDB.
3783 See Fx_get_resource below for other parameters. */
3784
3785 static Lisp_Object
3786 xrdb_get_resource (rdb, attribute, class, component, subclass)
3787 XrmDatabase rdb;
3788 Lisp_Object attribute, class, component, subclass;
3789 {
3790 register char *value;
3791 char *name_key;
3792 char *class_key;
3793
3794 CHECK_STRING (attribute);
3795 CHECK_STRING (class);
3796
3797 if (!NILP (component))
3798 CHECK_STRING (component);
3799 if (!NILP (subclass))
3800 CHECK_STRING (subclass);
3801 if (NILP (component) != NILP (subclass))
3802 error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3803
3804 validate_x_resource_name ();
3805
3806 /* Allocate space for the components, the dots which separate them,
3807 and the final '\0'. Make them big enough for the worst case. */
3808 name_key = (char *) alloca (SBYTES (Vx_resource_name)
3809 + (STRINGP (component)
3810 ? SBYTES (component) : 0)
3811 + SBYTES (attribute)
3812 + 3);
3813
3814 class_key = (char *) alloca (SBYTES (Vx_resource_class)
3815 + SBYTES (class)
3816 + (STRINGP (subclass)
3817 ? SBYTES (subclass) : 0)
3818 + 3);
3819
3820 /* Start with emacs.FRAMENAME for the name (the specific one)
3821 and with `Emacs' for the class key (the general one). */
3822 strcpy (name_key, SDATA (Vx_resource_name));
3823 strcpy (class_key, SDATA (Vx_resource_class));
3824
3825 strcat (class_key, ".");
3826 strcat (class_key, SDATA (class));
3827
3828 if (!NILP (component))
3829 {
3830 strcat (class_key, ".");
3831 strcat (class_key, SDATA (subclass));
3832
3833 strcat (name_key, ".");
3834 strcat (name_key, SDATA (component));
3835 }
3836
3837 strcat (name_key, ".");
3838 strcat (name_key, SDATA (attribute));
3839
3840 value = x_get_string_resource (rdb, name_key, class_key);
3841
3842 if (value != (char *) 0)
3843 return build_string (value);
3844 else
3845 return Qnil;
3846 }
3847
3848
3849 DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3850 doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3851 This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3852 class, where INSTANCE is the name under which Emacs was invoked, or
3853 the name specified by the `-name' or `-rn' command-line arguments.
3854
3855 The optional arguments COMPONENT and SUBCLASS add to the key and the
3856 class, respectively. You must specify both of them or neither.
3857 If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3858 and the class is `Emacs.CLASS.SUBCLASS'. */)
3859 (attribute, class, component, subclass)
3860 Lisp_Object attribute, class, component, subclass;
3861 {
3862 #ifdef HAVE_X_WINDOWS
3863 check_x ();
3864 #endif
3865
3866 return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3867 attribute, class, component, subclass);
3868 }
3869
3870 /* Get an X resource, like Fx_get_resource, but for display DPYINFO. */
3871
3872 Lisp_Object
3873 display_x_get_resource (dpyinfo, attribute, class, component, subclass)
3874 Display_Info *dpyinfo;
3875 Lisp_Object attribute, class, component, subclass;
3876 {
3877 return xrdb_get_resource (dpyinfo->xrdb,
3878 attribute, class, component, subclass);
3879 }
3880
3881 /* Used when C code wants a resource value. */
3882
3883 char *
3884 x_get_resource_string (attribute, class)
3885 char *attribute, *class;
3886 {
3887 char *name_key;
3888 char *class_key;
3889 struct frame *sf = SELECTED_FRAME ();
3890
3891 /* Allocate space for the components, the dots which separate them,
3892 and the final '\0'. */
3893 name_key = (char *) alloca (SBYTES (Vinvocation_name)
3894 + strlen (attribute) + 2);
3895 class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3896 + strlen (class) + 2);
3897
3898 sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3899 sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3900
3901 return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3902 name_key, class_key);
3903 }
3904
3905
3906 /* Return the value of parameter PARAM.
3907
3908 First search ALIST, then Vdefault_frame_alist, then the X defaults
3909 database, using ATTRIBUTE as the attribute name and CLASS as its class.
3910
3911 Convert the resource to the type specified by desired_type.
3912
3913 If no default is specified, return Qunbound. If you call
3914 x_get_arg, make sure you deal with Qunbound in a reasonable way,
3915 and don't let it get stored in any Lisp-visible variables! */
3916
3917 Lisp_Object
3918 x_get_arg (dpyinfo, alist, param, attribute, class, type)
3919 Display_Info *dpyinfo;
3920 Lisp_Object alist, param;
3921 char *attribute;
3922 char *class;
3923 enum resource_types type;
3924 {
3925 register Lisp_Object tem;
3926
3927 tem = Fassq (param, alist);
3928
3929 if (!NILP (tem))
3930 {
3931 /* If we find this parm in ALIST, clear it out
3932 so that it won't be "left over" at the end. */
3933 Lisp_Object tail;
3934 XSETCAR (tem, Qnil);
3935 /* In case the parameter appears more than once in the alist,
3936 clear it out. */
3937 for (tail = alist; CONSP (tail); tail = XCDR (tail))
3938 if (CONSP (XCAR (tail))
3939 && EQ (XCAR (XCAR (tail)), param))
3940 XSETCAR (XCAR (tail), Qnil);
3941 }
3942 else
3943 tem = Fassq (param, Vdefault_frame_alist);
3944
3945 /* If it wasn't specified in ALIST or the Lisp-level defaults,
3946 look in the X resources. */
3947 if (EQ (tem, Qnil))
3948 {
3949 if (attribute)
3950 {
3951 tem = display_x_get_resource (dpyinfo,
3952 build_string (attribute),
3953 build_string (class),
3954 Qnil, Qnil);
3955
3956 if (NILP (tem))
3957 return Qunbound;
3958
3959 switch (type)
3960 {
3961 case RES_TYPE_NUMBER:
3962 return make_number (atoi (SDATA (tem)));
3963
3964 case RES_TYPE_FLOAT:
3965 return make_float (atof (SDATA (tem)));
3966
3967 case RES_TYPE_BOOLEAN:
3968 tem = Fdowncase (tem);
3969 if (!strcmp (SDATA (tem), "on")
3970 #ifdef HAVE_NS
3971 || !strcmp(SDATA(tem), "yes")
3972 #endif
3973 || !strcmp (SDATA (tem), "true"))
3974 return Qt;
3975 else
3976 return Qnil;
3977
3978 case RES_TYPE_STRING:
3979 return tem;
3980
3981 case RES_TYPE_SYMBOL:
3982 /* As a special case, we map the values `true' and `on'
3983 to Qt, and `false' and `off' to Qnil. */
3984 {
3985 Lisp_Object lower;
3986 lower = Fdowncase (tem);
3987 if (!strcmp (SDATA (lower), "on")
3988 #ifdef HAVE_NS
3989 || !strcmp(SDATA(lower), "yes")
3990 #endif
3991 || !strcmp (SDATA (lower), "true"))
3992 return Qt;
3993 else if (!strcmp (SDATA (lower), "off")
3994 #ifdef HAVE_NS
3995 || !strcmp(SDATA(lower), "no")
3996 #endif
3997 || !strcmp (SDATA (lower), "false"))
3998 return Qnil;
3999 else
4000 return Fintern (tem, Qnil);
4001 }
4002
4003 default:
4004 abort ();
4005 }
4006 }
4007 else
4008 return Qunbound;
4009 }
4010 return Fcdr (tem);
4011 }
4012
4013 Lisp_Object
4014 x_frame_get_arg (f, alist, param, attribute, class, type)
4015 struct frame *f;
4016 Lisp_Object alist, param;
4017 char *attribute;
4018 char *class;
4019 enum resource_types type;
4020 {
4021 return x_get_arg (FRAME_X_DISPLAY_INFO (f),
4022 alist, param, attribute, class, type);
4023 }
4024
4025 /* Like x_frame_get_arg, but also record the value in f->param_alist. */
4026
4027 Lisp_Object
4028 x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
4029 struct frame *f;
4030 Lisp_Object alist, param;
4031 char *attribute;
4032 char *class;
4033 enum resource_types type;
4034 {
4035 Lisp_Object value;
4036
4037 value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
4038 attribute, class, type);
4039 if (! NILP (value) && ! EQ (value, Qunbound))
4040 store_frame_param (f, param, value);
4041
4042 return value;
4043 }
4044
4045
4046 /* Record in frame F the specified or default value according to ALIST
4047 of the parameter named PROP (a Lisp symbol).
4048 If no value is specified for PROP, look for an X default for XPROP
4049 on the frame named NAME.
4050 If that is not found either, use the value DEFLT. */
4051
4052 Lisp_Object
4053 x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
4054 struct frame *f;
4055 Lisp_Object alist;
4056 Lisp_Object prop;
4057 Lisp_Object deflt;
4058 char *xprop;
4059 char *xclass;
4060 enum resource_types type;
4061 {
4062 Lisp_Object tem;
4063
4064 tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
4065 if (EQ (tem, Qunbound))
4066 tem = deflt;
4067 x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
4068 return tem;
4069 }
4070
4071
4072
4073 \f
4074 #ifdef HAVE_NS
4075
4076 /* We used to define x-parse-geometry directly in ns-win.el, but that
4077 confused make-docfile: the documentation string in ns-win.el was
4078 used for x-parse-geometry even in non-NS builds.. */
4079
4080 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4081 doc: /* Parse a Nextstep-style geometry string STRING.
4082 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4083 The properties returned may include `top', `left', `height', and `width'.
4084 This works by calling `ns-parse-geometry'. */)
4085 (string)
4086 Lisp_Object string;
4087 {
4088 call1 (Qns_parse_geometry, string);
4089 }
4090
4091 #else /* !HAVE_NS */
4092
4093 DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
4094 doc: /* Parse an X-style geometry string STRING.
4095 Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
4096 The properties returned may include `top', `left', `height', and `width'.
4097 The value of `left' or `top' may be an integer,
4098 or a list (+ N) meaning N pixels relative to top/left corner,
4099 or a list (- N) meaning -N pixels relative to bottom/right corner. */)
4100 (string)
4101 Lisp_Object string;
4102 {
4103 int geometry, x, y;
4104 unsigned int width, height;
4105 Lisp_Object result;
4106
4107 CHECK_STRING (string);
4108
4109 geometry = XParseGeometry ((char *) SDATA (string),
4110 &x, &y, &width, &height);
4111 result = Qnil;
4112 if (geometry & XValue)
4113 {
4114 Lisp_Object element;
4115
4116 if (x >= 0 && (geometry & XNegative))
4117 element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
4118 else if (x < 0 && ! (geometry & XNegative))
4119 element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
4120 else
4121 element = Fcons (Qleft, make_number (x));
4122 result = Fcons (element, result);
4123 }
4124
4125 if (geometry & YValue)
4126 {
4127 Lisp_Object element;
4128
4129 if (y >= 0 && (geometry & YNegative))
4130 element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
4131 else if (y < 0 && ! (geometry & YNegative))
4132 element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
4133 else
4134 element = Fcons (Qtop, make_number (y));
4135 result = Fcons (element, result);
4136 }
4137
4138 if (geometry & WidthValue)
4139 result = Fcons (Fcons (Qwidth, make_number (width)), result);
4140 if (geometry & HeightValue)
4141 result = Fcons (Fcons (Qheight, make_number (height)), result);
4142
4143 return result;
4144 }
4145 #endif /* HAVE_NS */
4146
4147
4148 /* Calculate the desired size and position of frame F.
4149 Return the flags saying which aspects were specified.
4150
4151 Also set the win_gravity and size_hint_flags of F.
4152
4153 Adjust height for toolbar if TOOLBAR_P is 1.
4154
4155 This function does not make the coordinates positive. */
4156
4157 #define DEFAULT_ROWS 40
4158 #define DEFAULT_COLS 80
4159
4160 int
4161 x_figure_window_size (f, parms, toolbar_p)
4162 struct frame *f;
4163 Lisp_Object parms;
4164 int toolbar_p;
4165 {
4166 register Lisp_Object tem0, tem1, tem2;
4167 long window_prompting = 0;
4168 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
4169
4170 /* Default values if we fall through.
4171 Actually, if that happens we should get
4172 window manager prompting. */
4173 SET_FRAME_COLS (f, DEFAULT_COLS);
4174 FRAME_LINES (f) = DEFAULT_ROWS;
4175 /* Window managers expect that if program-specified
4176 positions are not (0,0), they're intentional, not defaults. */
4177 f->top_pos = 0;
4178 f->left_pos = 0;
4179
4180 /* Ensure that old new_text_cols and new_text_lines will not override the
4181 values set here. */
4182 /* ++KFS: This was specific to W32, but seems ok for all platforms */
4183 f->new_text_cols = f->new_text_lines = 0;
4184
4185 tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
4186 tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
4187 tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
4188 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4189 {
4190 if (!EQ (tem0, Qunbound))
4191 {
4192 CHECK_NUMBER (tem0);
4193 FRAME_LINES (f) = XINT (tem0);
4194 }
4195 if (!EQ (tem1, Qunbound))
4196 {
4197 CHECK_NUMBER (tem1);
4198 SET_FRAME_COLS (f, XINT (tem1));
4199 }
4200 if (!NILP (tem2) && !EQ (tem2, Qunbound))
4201 window_prompting |= USSize;
4202 else
4203 window_prompting |= PSize;
4204 }
4205
4206 f->scroll_bar_actual_width
4207 = FRAME_SCROLL_BAR_COLS (f) * FRAME_COLUMN_WIDTH (f);
4208
4209 /* This used to be done _before_ calling x_figure_window_size, but
4210 since the height is reset here, this was really a no-op. I
4211 assume that moving it here does what Gerd intended (although he
4212 no longer can remember what that was... ++KFS, 2003-03-25. */
4213
4214 /* Add the tool-bar height to the initial frame height so that the
4215 user gets a text display area of the size he specified with -g or
4216 via .Xdefaults. Later changes of the tool-bar height don't
4217 change the frame size. This is done so that users can create
4218 tall Emacs frames without having to guess how tall the tool-bar
4219 will get. */
4220 if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
4221 {
4222 int margin, relief, bar_height;
4223
4224 relief = (tool_bar_button_relief >= 0
4225 ? tool_bar_button_relief
4226 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
4227
4228 if (INTEGERP (Vtool_bar_button_margin)
4229 && XINT (Vtool_bar_button_margin) > 0)
4230 margin = XFASTINT (Vtool_bar_button_margin);
4231 else if (CONSP (Vtool_bar_button_margin)
4232 && INTEGERP (XCDR (Vtool_bar_button_margin))
4233 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
4234 margin = XFASTINT (XCDR (Vtool_bar_button_margin));
4235 else
4236 margin = 0;
4237
4238 bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
4239 FRAME_LINES (f) += (bar_height + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
4240 }
4241
4242 compute_fringe_widths (f, 0);
4243
4244 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
4245 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
4246
4247 tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
4248 tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
4249 tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
4250 if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
4251 {
4252 if (EQ (tem0, Qminus))
4253 {
4254 f->top_pos = 0;
4255 window_prompting |= YNegative;
4256 }
4257 else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
4258 && CONSP (XCDR (tem0))
4259 && INTEGERP (XCAR (XCDR (tem0))))
4260 {
4261 f->top_pos = - XINT (XCAR (XCDR (tem0)));
4262 window_prompting |= YNegative;
4263 }
4264 else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
4265 && CONSP (XCDR (tem0))
4266 && INTEGERP (XCAR (XCDR (tem0))))
4267 {
4268 f->top_pos = XINT (XCAR (XCDR (tem0)));
4269 }
4270 else if (EQ (tem0, Qunbound))
4271 f->top_pos = 0;
4272 else
4273 {
4274 CHECK_NUMBER (tem0);
4275 f->top_pos = XINT (tem0);
4276 if (f->top_pos < 0)
4277 window_prompting |= YNegative;
4278 }
4279
4280 if (EQ (tem1, Qminus))
4281 {
4282 f->left_pos = 0;
4283 window_prompting |= XNegative;
4284 }
4285 else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
4286 && CONSP (XCDR (tem1))
4287 && INTEGERP (XCAR (XCDR (tem1))))
4288 {
4289 f->left_pos = - XINT (XCAR (XCDR (tem1)));
4290 window_prompting |= XNegative;
4291 }
4292 else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
4293 && CONSP (XCDR (tem1))
4294 && INTEGERP (XCAR (XCDR (tem1))))
4295 {
4296 f->left_pos = XINT (XCAR (XCDR (tem1)));
4297 }
4298 else if (EQ (tem1, Qunbound))
4299 f->left_pos = 0;
4300 else
4301 {
4302 CHECK_NUMBER (tem1);
4303 f->left_pos = XINT (tem1);
4304 if (f->left_pos < 0)
4305 window_prompting |= XNegative;
4306 }
4307
4308 if (!NILP (tem2) && ! EQ (tem2, Qunbound))
4309 window_prompting |= USPosition;
4310 else
4311 window_prompting |= PPosition;
4312 }
4313
4314 if (f->want_fullscreen != FULLSCREEN_NONE)
4315 {
4316 int left, top;
4317 int width, height;
4318
4319 /* It takes both for some WM:s to place it where we want */
4320 window_prompting |= USPosition | PPosition;
4321 x_fullscreen_adjust (f, &width, &height, &top, &left);
4322 FRAME_COLS (f) = width;
4323 FRAME_LINES (f) = height;
4324 FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
4325 FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
4326 f->left_pos = left;
4327 f->top_pos = top;
4328 }
4329
4330 if (window_prompting & XNegative)
4331 {
4332 if (window_prompting & YNegative)
4333 f->win_gravity = SouthEastGravity;
4334 else
4335 f->win_gravity = NorthEastGravity;
4336 }
4337 else
4338 {
4339 if (window_prompting & YNegative)
4340 f->win_gravity = SouthWestGravity;
4341 else
4342 f->win_gravity = NorthWestGravity;
4343 }
4344
4345 f->size_hint_flags = window_prompting;
4346
4347 return window_prompting;
4348 }
4349
4350
4351
4352 #endif /* HAVE_WINDOW_SYSTEM */
4353
4354
4355 \f
4356 /***********************************************************************
4357 Initialization
4358 ***********************************************************************/
4359
4360 void
4361 syms_of_frame ()
4362 {
4363 Qframep = intern ("framep");
4364 staticpro (&Qframep);
4365 Qframe_live_p = intern ("frame-live-p");
4366 staticpro (&Qframe_live_p);
4367 Qexplicit_name = intern ("explicit-name");
4368 staticpro (&Qexplicit_name);
4369 Qheight = intern ("height");
4370 staticpro (&Qheight);
4371 Qicon = intern ("icon");
4372 staticpro (&Qicon);
4373 Qminibuffer = intern ("minibuffer");
4374 staticpro (&Qminibuffer);
4375 Qmodeline = intern ("modeline");
4376 staticpro (&Qmodeline);
4377 Qonly = intern ("only");
4378 staticpro (&Qonly);
4379 Qwidth = intern ("width");
4380 staticpro (&Qwidth);
4381 Qgeometry = intern ("geometry");
4382 staticpro (&Qgeometry);
4383 Qicon_left = intern ("icon-left");
4384 staticpro (&Qicon_left);
4385 Qicon_top = intern ("icon-top");
4386 staticpro (&Qicon_top);
4387 Qleft = intern ("left");
4388 staticpro (&Qleft);
4389 Qright = intern ("right");
4390 staticpro (&Qright);
4391 Quser_position = intern ("user-position");
4392 staticpro (&Quser_position);
4393 Quser_size = intern ("user-size");
4394 staticpro (&Quser_size);
4395 Qwindow_id = intern ("window-id");
4396 staticpro (&Qwindow_id);
4397 #ifdef HAVE_X_WINDOWS
4398 Qouter_window_id = intern ("outer-window-id");
4399 staticpro (&Qouter_window_id);
4400 #endif
4401 Qparent_id = intern ("parent-id");
4402 staticpro (&Qparent_id);
4403 Qx = intern ("x");
4404 staticpro (&Qx);
4405 Qw32 = intern ("w32");
4406 staticpro (&Qw32);
4407 Qpc = intern ("pc");
4408 staticpro (&Qpc);
4409 Qmac = intern ("mac");
4410 staticpro (&Qmac);
4411 Qns = intern ("ns");
4412 staticpro (&Qns);
4413 Qvisible = intern ("visible");
4414 staticpro (&Qvisible);
4415 Qbuffer_predicate = intern ("buffer-predicate");
4416 staticpro (&Qbuffer_predicate);
4417 Qbuffer_list = intern ("buffer-list");
4418 staticpro (&Qbuffer_list);
4419 Qburied_buffer_list = intern ("buried-buffer-list");
4420 staticpro (&Qburied_buffer_list);
4421 Qdisplay_type = intern ("display-type");
4422 staticpro (&Qdisplay_type);
4423 Qbackground_mode = intern ("background-mode");
4424 staticpro (&Qbackground_mode);
4425 Qnoelisp = intern ("noelisp");
4426 staticpro (&Qnoelisp);
4427 Qtty_color_mode = intern ("tty-color-mode");
4428 staticpro (&Qtty_color_mode);
4429 Qtty = intern ("tty");
4430 staticpro (&Qtty);
4431 Qtty_type = intern ("tty-type");
4432 staticpro (&Qtty_type);
4433
4434 Qface_set_after_frame_default = intern ("face-set-after-frame-default");
4435 staticpro (&Qface_set_after_frame_default);
4436
4437 Qfullwidth = intern ("fullwidth");
4438 staticpro (&Qfullwidth);
4439 Qfullheight = intern ("fullheight");
4440 staticpro (&Qfullheight);
4441 Qfullboth = intern ("fullboth");
4442 staticpro (&Qfullboth);
4443 Qx_resource_name = intern ("x-resource-name");
4444 staticpro (&Qx_resource_name);
4445
4446 Qx_frame_parameter = intern ("x-frame-parameter");
4447 staticpro (&Qx_frame_parameter);
4448
4449 Qterminal = intern ("terminal");
4450 staticpro (&Qterminal);
4451 Qterminal_live_p = intern ("terminal-live-p");
4452 staticpro (&Qterminal_live_p);
4453
4454 #ifdef HAVE_NS
4455 Qns_parse_geometry = intern ("ns-parse-geometry");
4456 staticpro (&Qns_parse_geometry);
4457 #endif
4458
4459 {
4460 int i;
4461
4462 for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
4463 {
4464 Lisp_Object v = intern (frame_parms[i].name);
4465 if (frame_parms[i].variable)
4466 {
4467 *frame_parms[i].variable = v;
4468 staticpro (frame_parms[i].variable);
4469 }
4470 Fput (v, Qx_frame_parameter, make_number (i));
4471 }
4472 }
4473
4474 #ifdef HAVE_WINDOW_SYSTEM
4475 DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
4476 doc: /* The name Emacs uses to look up X resources.
4477 `x-get-resource' uses this as the first component of the instance name
4478 when requesting resource values.
4479 Emacs initially sets `x-resource-name' to the name under which Emacs
4480 was invoked, or to the value specified with the `-name' or `-rn'
4481 switches, if present.
4482
4483 It may be useful to bind this variable locally around a call
4484 to `x-get-resource'. See also the variable `x-resource-class'. */);
4485 Vx_resource_name = Qnil;
4486
4487 DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4488 doc: /* The class Emacs uses to look up X resources.
4489 `x-get-resource' uses this as the first component of the instance class
4490 when requesting resource values.
4491
4492 Emacs initially sets `x-resource-class' to "Emacs".
4493
4494 Setting this variable permanently is not a reasonable thing to do,
4495 but binding this variable locally around a call to `x-get-resource'
4496 is a reasonable practice. See also the variable `x-resource-name'. */);
4497 Vx_resource_class = build_string (EMACS_CLASS);
4498
4499 DEFVAR_LISP ("frame-alpha-lower-limit", &Vframe_alpha_lower_limit,
4500 doc: /* The lower limit of the frame opacity (alpha transparency).
4501 The value should range from 0 (invisible) to 100 (completely opaque).
4502 You can also use a floating number between 0.0 and 1.0.
4503 The default is 20. */);
4504 Vframe_alpha_lower_limit = make_number (20);
4505 #endif
4506
4507 DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
4508 doc: /* Alist of default values for frame creation.
4509 These may be set in your init file, like this:
4510 (setq default-frame-alist '((width . 80) (height . 55) (menu-bar-lines . 1)))
4511 These override values given in window system configuration data,
4512 including X Windows' defaults database.
4513 For values specific to the first Emacs frame, see `initial-frame-alist'.
4514 For window-system specific values, see `window-system-default-frame-alist'.
4515 For values specific to the separate minibuffer frame, see
4516 `minibuffer-frame-alist'.
4517 The `menu-bar-lines' element of the list controls whether new frames
4518 have menu bars; `menu-bar-mode' works by altering this element.
4519 Setting this variable does not affect existing frames, only new ones. */);
4520 Vdefault_frame_alist = Qnil;
4521
4522 DEFVAR_LISP ("default-frame-scroll-bars", &Vdefault_frame_scroll_bars,
4523 doc: /* Default position of scroll bars on this window-system. */);
4524 #ifdef HAVE_WINDOW_SYSTEM
4525 #if defined(HAVE_NTGUI) || defined(NS_IMPL_COCOA)
4526 /* MS-Windows and Mac OS X have scroll bars on the right by default. */
4527 Vdefault_frame_scroll_bars = Qright;
4528 #else
4529 Vdefault_frame_scroll_bars = Qleft;
4530 #endif
4531 #else
4532 Vdefault_frame_scroll_bars = Qnil;
4533 #endif
4534
4535 DEFVAR_LISP ("terminal-frame", &Vterminal_frame,
4536 doc: /* The initial frame-object, which represents Emacs's stdout. */);
4537
4538 DEFVAR_LISP ("mouse-position-function", &Vmouse_position_function,
4539 doc: /* If non-nil, function to transform normal value of `mouse-position'.
4540 `mouse-position' calls this function, passing its usual return value as
4541 argument, and returns whatever this function returns.
4542 This abnormal hook exists for the benefit of packages like `xt-mouse.el'
4543 which need to do mouse handling at the Lisp level. */);
4544 Vmouse_position_function = Qnil;
4545
4546 DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
4547 doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4548 If the value is an integer, highlighting is only shown after moving the
4549 mouse, while keyboard input turns off the highlight even when the mouse
4550 is over the clickable text. However, the mouse shape still indicates
4551 when the mouse is over clickable text. */);
4552 Vmouse_highlight = Qt;
4553
4554 DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
4555 doc: /* Functions to be run before deleting a frame.
4556 The functions are run with one arg, the frame to be deleted.
4557 See `delete-frame'.
4558
4559 Note that functions in this list may be called just before the frame is
4560 actually deleted, or some time later (or even both when an earlier function
4561 in `delete-frame-functions' (indirectly) calls `delete-frame'
4562 recursively). */);
4563 Vdelete_frame_functions = Qnil;
4564 Qdelete_frame_functions = intern ("delete-frame-functions");
4565 staticpro (&Qdelete_frame_functions);
4566
4567 DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4568 doc: /* Minibufferless frames use this frame's minibuffer.
4569
4570 Emacs cannot create minibufferless frames unless this is set to an
4571 appropriate surrogate.
4572
4573 Emacs consults this variable only when creating minibufferless
4574 frames; once the frame is created, it sticks with its assigned
4575 minibuffer, no matter what this variable is set to. This means that
4576 this variable doesn't necessarily say anything meaningful about the
4577 current set of frames, or where the minibuffer is currently being
4578 displayed.
4579
4580 This variable is local to the current terminal and cannot be buffer-local. */);
4581
4582 DEFVAR_BOOL ("focus-follows-mouse", &focus_follows_mouse,
4583 doc: /* Non-nil if window system changes focus when you move the mouse.
4584 You should set this variable to tell Emacs how your window manager
4585 handles focus, since there is no way in general for Emacs to find out
4586 automatically. */);
4587 #ifdef HAVE_WINDOW_SYSTEM
4588 #if defined(HAVE_NTGUI) || defined(HAVE_NS)
4589 focus_follows_mouse = 0;
4590 #else
4591 focus_follows_mouse = 1;
4592 #endif
4593 #else
4594 focus_follows_mouse = 0;
4595 #endif
4596
4597 staticpro (&Vframe_list);
4598
4599 defsubr (&Sactive_minibuffer_window);
4600 defsubr (&Sframep);
4601 defsubr (&Sframe_live_p);
4602 defsubr (&Swindow_system);
4603 defsubr (&Smake_terminal_frame);
4604 defsubr (&Shandle_switch_frame);
4605 defsubr (&Sselect_frame);
4606 defsubr (&Sselected_frame);
4607 defsubr (&Swindow_frame);
4608 defsubr (&Sframe_root_window);
4609 defsubr (&Sframe_first_window);
4610 defsubr (&Sframe_selected_window);
4611 defsubr (&Sset_frame_selected_window);
4612 defsubr (&Sframe_list);
4613 defsubr (&Snext_frame);
4614 defsubr (&Sprevious_frame);
4615 defsubr (&Sdelete_frame);
4616 defsubr (&Smouse_position);
4617 defsubr (&Smouse_pixel_position);
4618 defsubr (&Sset_mouse_position);
4619 defsubr (&Sset_mouse_pixel_position);
4620 #if 0
4621 defsubr (&Sframe_configuration);
4622 defsubr (&Srestore_frame_configuration);
4623 #endif
4624 defsubr (&Smake_frame_visible);
4625 defsubr (&Smake_frame_invisible);
4626 defsubr (&Siconify_frame);
4627 defsubr (&Sframe_visible_p);
4628 defsubr (&Svisible_frame_list);
4629 defsubr (&Sraise_frame);
4630 defsubr (&Slower_frame);
4631 defsubr (&Sredirect_frame_focus);
4632 defsubr (&Sframe_focus);
4633 defsubr (&Sframe_parameters);
4634 defsubr (&Sframe_parameter);
4635 defsubr (&Smodify_frame_parameters);
4636 defsubr (&Sframe_char_height);
4637 defsubr (&Sframe_char_width);
4638 defsubr (&Sframe_pixel_height);
4639 defsubr (&Sframe_pixel_width);
4640 defsubr (&Sset_frame_height);
4641 defsubr (&Sset_frame_width);
4642 defsubr (&Sset_frame_size);
4643 defsubr (&Sset_frame_position);
4644
4645 #ifdef HAVE_WINDOW_SYSTEM
4646 defsubr (&Sx_get_resource);
4647 defsubr (&Sx_parse_geometry);
4648 #endif
4649
4650 }
4651
4652 /* arch-tag: 7dbf2c69-9aad-45f8-8296-db893d6dd039
4653 (do not change this comment) */