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