XEmacs 21.2.20 "Yoko".
[chise/xemacs-chise.git.1] / src / frame.c
1 /* Generic frame functions.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3    Copyright (C) 1995, 1996 Ben Wing.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: FSF 19.30. */
24
25 /* This file has been Mule-ized. */
26
27 #include <config.h>
28 #include "lisp.h"
29
30 #include "buffer.h"             /* for Vbuffer_alist */
31 #include "console.h"
32 #include "events.h"
33 #include "extents.h"
34 #include "faces.h"
35 #include "frame.h"
36 #include "glyphs.h"
37 #include "gutter.h"
38 #include "menubar.h"
39 #include "redisplay.h"
40 #include "scrollbar.h"
41 #include "window.h"
42
43 Lisp_Object Vselect_frame_hook, Qselect_frame_hook;
44 Lisp_Object Vdeselect_frame_hook, Qdeselect_frame_hook;
45 Lisp_Object Vcreate_frame_hook, Qcreate_frame_hook;
46 Lisp_Object Vdelete_frame_hook, Qdelete_frame_hook;
47 Lisp_Object Vmouse_enter_frame_hook, Qmouse_enter_frame_hook;
48 Lisp_Object Vmouse_leave_frame_hook, Qmouse_leave_frame_hook;
49 Lisp_Object Vmap_frame_hook, Qmap_frame_hook;
50 Lisp_Object Vunmap_frame_hook, Qunmap_frame_hook;
51 int  allow_deletion_of_last_visible_frame;
52 Lisp_Object Vadjust_frame_function;
53 Lisp_Object Vmouse_motion_handler;
54 Lisp_Object Vsynchronize_minibuffers;
55 Lisp_Object Qsynchronize_minibuffers;
56 Lisp_Object Qbuffer_predicate;
57 Lisp_Object Qmake_initial_minibuffer_frame;
58 Lisp_Object Qcustom_initialize_frame;
59
60 /* We declare all these frame properties here even though many of them
61    are currently only used in frame-x.c, because we should generalize
62    them. */
63
64 Lisp_Object Qminibuffer;
65 Lisp_Object Qunsplittable;
66 Lisp_Object Qinternal_border_width;
67 Lisp_Object Qtop_toolbar_shadow_color;
68 Lisp_Object Qbottom_toolbar_shadow_color;
69 Lisp_Object Qbackground_toolbar_color;
70 Lisp_Object Qtop_toolbar_shadow_pixmap;
71 Lisp_Object Qbottom_toolbar_shadow_pixmap;
72 Lisp_Object Qtoolbar_shadow_thickness;
73 Lisp_Object Qscrollbar_placement;
74 Lisp_Object Qinter_line_space;
75 Lisp_Object Qvisual_bell;
76 Lisp_Object Qbell_volume;
77 Lisp_Object Qpointer_background;
78 Lisp_Object Qpointer_color;
79 Lisp_Object Qtext_pointer;
80 Lisp_Object Qspace_pointer;
81 Lisp_Object Qmodeline_pointer;
82 Lisp_Object Qgc_pointer;
83 Lisp_Object Qinitially_unmapped;
84 Lisp_Object Quse_backing_store;
85 Lisp_Object Qborder_color;
86 Lisp_Object Qborder_width;
87
88 Lisp_Object Qframep, Qframe_live_p;
89 Lisp_Object Qdelete_frame;
90
91 Lisp_Object Qframe_title_format, Vframe_title_format;
92 Lisp_Object Qframe_icon_title_format, Vframe_icon_title_format;
93
94 Lisp_Object Vdefault_frame_name;
95 Lisp_Object Vdefault_frame_plist;
96
97 Lisp_Object Vframe_icon_glyph;
98
99 Lisp_Object Qhidden;
100
101 Lisp_Object Qvisible, Qiconic, Qinvisible, Qvisible_iconic, Qinvisible_iconic;
102 Lisp_Object Qnomini, Qvisible_nomini, Qiconic_nomini, Qinvisible_nomini;
103 Lisp_Object Qvisible_iconic_nomini, Qinvisible_iconic_nomini;
104
105 Lisp_Object Qset_specifier, Qset_glyph_image, Qset_face_property;
106 Lisp_Object Qface_property_instance;
107
108 Lisp_Object Qframe_property_alias;
109
110 /* If this is non-nil, it is the frame that make-frame is currently
111    creating.  We can't set the current frame to this in case the
112    debugger goes off because it would try and display to it.  However,
113    there are some places which need to reference it which have no
114    other way of getting it if it isn't the selected frame. */
115 Lisp_Object Vframe_being_created;
116 Lisp_Object Qframe_being_created;
117
118 static void store_minibuf_frame_prop (struct frame *f, Lisp_Object val);
119
120 EXFUN (Fset_frame_properties, 2);
121
122 \f
123 static Lisp_Object
124 mark_frame (Lisp_Object obj)
125 {
126   struct frame *f = XFRAME (obj);
127
128 #define MARKED_SLOT(x) mark_object (f->x)
129 #include "frameslots.h"
130
131   mark_subwindow_cachels (f->subwindow_cachels);
132
133   if (FRAME_LIVE_P (f)) /* device is nil for a dead frame */
134     MAYBE_FRAMEMETH (f, mark_frame, (f));
135
136   return Qnil;
137 }
138
139 static void
140 print_frame (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
141 {
142   struct frame *frm = XFRAME (obj);
143   char buf[200];
144
145   if (print_readably)
146     error ("printing unreadable object #<frame %s 0x%x>",
147            XSTRING_DATA (frm->name), frm->header.uid);
148
149   sprintf (buf, "#<%s-frame ", !FRAME_LIVE_P (frm) ? "dead" :
150            FRAME_TYPE_NAME (frm));
151   write_c_string (buf, printcharfun);
152   print_internal (frm->name, printcharfun, 1);
153   sprintf (buf, " 0x%x>", frm->header.uid);
154   write_c_string (buf, printcharfun);
155 }
156
157 DEFINE_LRECORD_IMPLEMENTATION ("frame", frame,
158                                mark_frame, print_frame, 0, 0, 0, 0,
159                                struct frame);
160 \f
161 static void
162 nuke_all_frame_slots (struct frame *f)
163 {
164 #define MARKED_SLOT(x)  f->x = Qnil
165 #include "frameslots.h"
166 }
167
168 /* Allocate a new frame object and set all its fields to reasonable
169    values.  The root window is created but the minibuffer will be done
170    later. */
171
172 static struct frame *
173 allocate_frame_core (Lisp_Object device)
174 {
175   /* This function can GC */
176   Lisp_Object frame;
177   Lisp_Object root_window;
178   struct frame *f = alloc_lcrecord_type (struct frame, &lrecord_frame);
179
180   zero_lcrecord (f);
181   nuke_all_frame_slots (f);
182   XSETFRAME (frame, f);
183
184   f->device = device;
185   f->framemeths = XDEVICE (device)->devmeths;
186   f->buffer_alist = Fcopy_sequence (Vbuffer_alist);
187
188   root_window = allocate_window ();
189   XWINDOW (root_window)->frame = frame;
190
191   /* 10 is arbitrary,
192      Just so that there is "something there."
193      Correct size will be set up later with change_frame_size.  */
194
195   f->width  = 10;
196   f->height = 10;
197
198   XWINDOW (root_window)->pixel_width = 10;
199   XWINDOW (root_window)->pixel_height = 9;
200
201   /* The size of the minibuffer window is now set in x_create_frame
202      in xfns.c. */
203
204   f->root_window = root_window;
205   f->selected_window = root_window;
206   f->last_nonminibuf_window = root_window;
207
208   /* cache of subwindows visible on frame */
209   f->subwindow_cachels    = Dynarr_new (subwindow_cachel);
210
211   /* associated exposure ignore list */
212   f->subwindow_exposures = 0;
213   f->subwindow_exposures_tail = 0;
214
215   /* Choose a buffer for the frame's root window.  */
216   XWINDOW (root_window)->buffer = Qt;
217   {
218     Lisp_Object buf;
219
220     buf = Fcurrent_buffer ();
221     /* If buf is a 'hidden' buffer (i.e. one whose name starts with
222        a space), try to find another one.  */
223     if (string_char (XSTRING (Fbuffer_name (buf)), 0) == ' ')
224       buf = Fother_buffer (buf, Qnil, Qnil);
225     Fset_window_buffer (root_window, buf);
226   }
227
228   return f;
229 }
230
231 static void
232 setup_normal_frame (struct frame *f)
233 {
234   Lisp_Object mini_window;
235   Lisp_Object frame;
236
237   XSETFRAME (frame, f);
238
239   mini_window = allocate_window ();
240   XWINDOW (f->root_window)->next = mini_window;
241   XWINDOW (mini_window)->prev = f->root_window;
242   XWINDOW (mini_window)->mini_p = Qt;
243   XWINDOW (mini_window)->frame = frame;
244   f->minibuffer_window = mini_window;
245   f->has_minibuffer = 1;
246
247   XWINDOW (mini_window)->buffer = Qt;
248   Fset_window_buffer (mini_window, Vminibuffer_zero);
249 }
250
251 /* Make a frame using a separate minibuffer window on another frame.
252    MINI_WINDOW is the minibuffer window to use.  nil means use the
253    default-minibuffer-frame.  */
254
255 static void
256 setup_frame_without_minibuffer (struct frame *f, Lisp_Object mini_window)
257 {
258   /* This function can GC */
259   Lisp_Object device = f->device;
260
261   if (!NILP (mini_window))
262     CHECK_LIVE_WINDOW (mini_window);
263
264   if (!NILP (mini_window)
265       && !EQ (DEVICE_CONSOLE (XDEVICE (device)),
266               FRAME_CONSOLE (XFRAME (XWINDOW (mini_window)->frame))))
267     error ("frame and minibuffer must be on the same console");
268
269   if (NILP (mini_window))
270     {
271       struct console *con = XCONSOLE (FRAME_CONSOLE (f));
272       /* Use default-minibuffer-frame if possible.  */
273       if (!FRAMEP (con->default_minibuffer_frame)
274           || ! FRAME_LIVE_P (XFRAME (con->default_minibuffer_frame)))
275         {
276           /* If there's no minibuffer frame to use, create one.  */
277           con->default_minibuffer_frame
278             = call1 (Qmake_initial_minibuffer_frame, device);
279         }
280       mini_window = XFRAME (con->default_minibuffer_frame)->minibuffer_window;
281     }
282
283   /* Install the chosen minibuffer window, with proper buffer.  */
284   store_minibuf_frame_prop (f, mini_window);
285   Fset_window_buffer (mini_window, Vminibuffer_zero);
286 }
287
288 /* Make a frame containing only a minibuffer window.  */
289
290 static void
291 setup_minibuffer_frame (struct frame *f)
292 {
293   /* This function can GC */
294   /* First make a frame containing just a root window, no minibuffer.  */
295   Lisp_Object mini_window;
296   Lisp_Object frame;
297
298   XSETFRAME (frame, f);
299
300   f->no_split = 1;
301   f->has_minibuffer = 1;
302
303   /* Now label the root window as also being the minibuffer.
304      Avoid infinite looping on the window chain by marking next pointer
305      as nil. */
306
307   mini_window = f->minibuffer_window = f->root_window;
308   XWINDOW (mini_window)->mini_p = Qt;
309   XWINDOW (mini_window)->next   = Qnil;
310   XWINDOW (mini_window)->prev   = Qnil;
311   XWINDOW (mini_window)->frame  = frame;
312
313   /* Put the proper buffer in that window.  */
314
315   Fset_window_buffer (mini_window, Vminibuffer_zero);
316 }
317
318 static Lisp_Object
319 make_sure_its_a_fresh_plist (Lisp_Object foolist)
320 {
321   if (CONSP (Fcar (foolist)))
322     {
323       /* looks like an alist to me. */
324       foolist = Fcopy_alist (foolist);
325       foolist = Fdestructive_alist_to_plist (foolist);
326     }
327   else
328     foolist = Fcopy_sequence (foolist);
329
330   return foolist;
331 }
332
333 DEFUN ("make-frame", Fmake_frame, 0, 2, "", /*
334 Create and return a new frame, displaying the current buffer.
335 Runs the functions listed in `create-frame-hook' after frame creation.
336
337 Optional argument PROPS is a property list (a list of alternating
338 keyword-value specifications) of properties for the new frame.
339 \(An alist is accepted for backward compatibility but should not
340 be passed in.)
341
342 See `set-frame-properties', `default-x-frame-plist', and
343 `default-tty-frame-plist' for the specially-recognized properties.
344 */
345        (props, device))
346 {
347   struct frame *f;
348   struct device *d;
349   Lisp_Object frame = Qnil, name = Qnil, minibuf;
350   struct gcpro gcpro1, gcpro2, gcpro3;
351   int speccount = specpdl_depth ();
352   int first_frame_on_device = 0;
353   int first_frame_on_console = 0;
354
355   d = decode_device (device);
356   XSETDEVICE (device, d);
357
358   /* PROPS and NAME may be freshly-created, so make sure to GCPRO. */
359   GCPRO3 (frame, props, name);
360
361   props = make_sure_its_a_fresh_plist (props);
362   if (DEVICE_SPECIFIC_FRAME_PROPS (d))
363     /* Put the device-specific props before the more general ones so
364        that they override them. */
365     props = nconc2 (props,
366                     make_sure_its_a_fresh_plist
367                     (*DEVICE_SPECIFIC_FRAME_PROPS (d)));
368   props = nconc2 (props, make_sure_its_a_fresh_plist (Vdefault_frame_plist));
369   Fcanonicalize_lax_plist (props, Qnil);
370
371   name = Flax_plist_get (props, Qname, Qnil);
372   if (!NILP (name))
373     CHECK_STRING (name);
374   else if (STRINGP (Vdefault_frame_name))
375     name = Vdefault_frame_name;
376   else
377     name = build_string ("emacs");
378
379   if (!NILP (Fstring_match (make_string ((CONST Bufbyte *) "\\.", 2), name,
380                             Qnil, Qnil)))
381     signal_simple_error (". not allowed in frame names", name);
382
383   f = allocate_frame_core (device);
384   XSETFRAME (frame, f);
385
386   specbind (Qframe_being_created, name);
387   f->name = name;
388
389   FRAMEMETH (f, init_frame_1, (f, props));
390
391   minibuf = Flax_plist_get (props, Qminibuffer, Qunbound);
392   if (UNBOUNDP (minibuf))
393     {
394       /* If minibuf is unspecified, then look for a minibuffer X resource. */
395       /* #### Not implemented any more.  We need to fix things up so
396          that we search out all X resources and append them to the end of
397          props, above.  This is the only way in general to assure
398          coherent behavior for all frame properties/resources/etc. */
399     }
400   else
401     props = Flax_plist_remprop (props, Qminibuffer);
402
403   if (EQ (minibuf, Qnone) || NILP (minibuf))
404     setup_frame_without_minibuffer (f, Qnil);
405   else if (EQ (minibuf, Qonly))
406     setup_minibuffer_frame (f);
407   else if (WINDOWP (minibuf))
408     setup_frame_without_minibuffer (f, minibuf);
409   else if (EQ (minibuf, Qt) || UNBOUNDP (minibuf))
410     setup_normal_frame (f);
411   else
412     signal_simple_error ("Invalid value for `minibuffer'", minibuf);
413
414   update_frame_window_mirror (f);
415
416   if (initialized && !DEVICE_STREAM_P (d))
417     {
418       if (!NILP (f->minibuffer_window))
419         reset_face_cachels (XWINDOW (f->minibuffer_window));
420       reset_face_cachels (XWINDOW (f->root_window));
421     }
422
423   /* If no frames on this device formerly existed, say this is the
424      first frame.  It kind of assumes that frameless devices don't
425      exist, but it shouldn't be too harmful.  */
426   if (NILP (DEVICE_FRAME_LIST (d)))
427     first_frame_on_device = 1;
428
429   /* This *must* go before the init_*() methods.  Those functions
430      call Lisp code, and if any of them causes a warning to be displayed
431      and the *Warnings* buffer to be created, it won't get added to
432      the frame-specific version of the buffer-alist unless the frame
433      is accessible from the device. */
434
435 #if 0
436   DEVICE_FRAME_LIST (d) = nconc2 (DEVICE_FRAME_LIST (d), Fcons (frame, Qnil));
437 #endif
438   DEVICE_FRAME_LIST (d) = Fcons (frame, DEVICE_FRAME_LIST (d));
439   RESET_CHANGED_SET_FLAGS;
440
441   /* Now make sure that the initial cached values are set correctly.
442      Do this after the init_frame method is called because that may
443      do things (e.g. create widgets) that are necessary for the
444      specifier value-changed methods to work OK. */
445   recompute_all_cached_specifiers_in_frame (f);
446
447   if (!DEVICE_STREAM_P (d))
448     {
449       init_frame_faces (f);
450
451 #ifdef HAVE_SCROLLBARS
452       /* Finish up resourcing the scrollbars. */
453       init_frame_scrollbars (f);
454 #endif
455
456 #ifdef HAVE_TOOLBARS
457       /* Create the initial toolbars.  We have to do this after the frame
458          methods are called because it may potentially call some things itself
459          which depend on the normal frame methods having initialized
460          things. */
461       init_frame_toolbars (f);
462 #endif
463       reset_face_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f)));
464       reset_glyph_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f)));
465       reset_subwindow_cachels (f);
466       change_frame_size (f, f->height, f->width, 0);
467
468     }
469
470   MAYBE_FRAMEMETH (f, init_frame_2, (f, props));
471   Fset_frame_properties (frame, props);
472   MAYBE_FRAMEMETH (f, init_frame_3, (f));
473
474   /* now initialise the gutters, this won't change the frame size
475      so is ok here. */
476   if (!DEVICE_STREAM_P (d))
477     init_frame_gutters (f);
478
479   /* Hallelujah, praise the lord. */
480   f->init_finished = 1;
481
482   /* If this is the first frame on the device, make it the selected one. */
483   if (first_frame_on_device && NILP (DEVICE_SELECTED_FRAME (d)))
484     set_device_selected_frame (d, frame);
485
486   /* If at startup or if the current console is a stream console
487      (usually also at startup), make this console the selected one
488      so that messages show up on it. */
489   if (NILP (Fselected_console ()) ||
490       CONSOLE_STREAM_P (XCONSOLE (Fselected_console ())))
491     Fselect_console (DEVICE_CONSOLE (d));
492
493   first_frame_on_console =
494     (first_frame_on_device &&
495      XINT (Flength (CONSOLE_DEVICE_LIST (XCONSOLE (DEVICE_CONSOLE (d)))))
496      == 1);
497
498   /* #### all this calling of frame methods at various odd times
499      is somewhat of a mess.  It's necessary to do it this way due
500      to strange console-type-specific things that need to be done. */
501   MAYBE_FRAMEMETH (f, after_init_frame, (f, first_frame_on_device,
502                                          first_frame_on_console));
503
504   if (first_frame_on_device)
505     {
506       if (first_frame_on_console)
507         va_run_hook_with_args (Qcreate_console_hook, 1, DEVICE_CONSOLE (d));
508       va_run_hook_with_args (Qcreate_device_hook, 1, device);
509     }
510   va_run_hook_with_args (Qcreate_frame_hook, 1, frame);
511
512   /* Initialize custom-specific stuff. */
513   if (!UNBOUNDP (symbol_function (XSYMBOL (Qcustom_initialize_frame))))
514     call1 (Qcustom_initialize_frame, frame);
515
516   unbind_to (speccount, Qnil);
517
518   UNGCPRO;
519   return frame;
520 }
521
522 \f
523 /* this function should be used in most cases when a Lisp function is passed
524    a FRAME argument.  Use this unless you don't accept nil == current frame
525    (in which case, do a CHECK_LIVE_FRAME() and then an XFRAME()) or you
526    allow dead frames.  Note that very few functions should accept dead
527    frames.  It could be argued that functions should just do nothing when
528    given a dead frame, but the presence of a dead frame usually indicates
529    an oversight in the Lisp code that could potentially lead to strange
530    results and so it is better to catch the error early.
531
532    If you only accept X frames, use decode_x_frame(), which does what this
533    function does but also makes sure the frame is an X frame. */
534
535 struct frame *
536 decode_frame (Lisp_Object frame)
537 {
538   if (NILP (frame))
539     return selected_frame ();
540
541   CHECK_LIVE_FRAME (frame);
542   return XFRAME (frame);
543 }
544
545 struct frame *
546 decode_frame_or_selected (Lisp_Object cdf)
547 {
548   if (CONSOLEP (cdf))
549     cdf = CONSOLE_SELECTED_DEVICE (decode_console (cdf));
550   if (DEVICEP (cdf))
551     cdf = DEVICE_SELECTED_FRAME (decode_device (cdf));
552   return decode_frame (cdf);
553 }
554
555 Lisp_Object
556 make_frame (struct frame *f)
557 {
558   Lisp_Object frame;
559   XSETFRAME (frame, f);
560   return frame;
561 }
562
563 \f
564 /*
565  * window size changes are held up during critical regions.  Afterwards,
566  * we want to deal with any delayed changes.
567  */
568 void
569 hold_frame_size_changes (void)
570 {
571   in_display = 1;
572 }
573
574 void
575 unhold_one_frame_size_changes (struct frame *f)
576 {
577   in_display = 0;
578
579   if (f->size_change_pending)
580     change_frame_size (f, f->new_height, f->new_width, 0);
581 }
582
583 void
584 unhold_frame_size_changes (void)
585 {
586   Lisp_Object frmcons, devcons, concons;
587
588   FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
589     unhold_one_frame_size_changes (XFRAME (XCAR (frmcons)));
590 }
591
592 void
593 invalidate_vertical_divider_cache_in_frame (struct frame *f)
594 {
595   /* Invalidate cached value of needs_vertical_divider_p in
596      every and all windows */
597   map_windows (f, invalidate_vertical_divider_cache_in_window, 0);
598 }
599 \f
600 /*
601  * Frame size may change due to changes in scrollbars, toolbars,
602  * default font etc. These changes are applied early in redisplay
603  * frame.
604  */
605 void
606 adjust_frame_size (struct frame *f)
607 {
608   int keep_char_size = 0;
609   Lisp_Object frame;
610   XSETFRAME (frame, f);
611
612   if (!f->size_slipped)
613     return;
614
615   /* Don't adjust tty frames. #### May break when TTY have menubars.
616      Then, write an Vadjust_frame_function which will return t for TTY
617      frames. Another solution is frame_size_fixed_p method for TTYs,
618      which always returned yes it's fixed.
619   */
620   if (!FRAME_WIN_P (f))
621     {
622       CLEAR_FRAME_SIZE_SLIPPED (f);
623       return;
624     }
625
626   /* frame_size_fixed_p tells that frame size cannot currently
627      be changed change due to external conditions */
628   if (!FRAMEMETH_OR_GIVEN (f, frame_size_fixed_p, (f), 0))
629     {
630       if (NILP (Vadjust_frame_function))
631         keep_char_size = 1;
632       else if (EQ (Vadjust_frame_function, Qt))
633         keep_char_size = 0;
634       else
635         keep_char_size =
636           NILP (call1_trapping_errors ("Error in adjust-frame-function",
637                                        Vadjust_frame_function, frame));
638
639       if (keep_char_size)
640         Fset_frame_size (frame, make_int (FRAME_CHARWIDTH(f)),
641                          make_int (FRAME_CHARHEIGHT(f)), Qnil);
642     }
643
644   if (!keep_char_size)
645     {
646       int height, width;
647       pixel_to_char_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f),
648                           &width, &height);
649       change_frame_size (f, height, width, 0);
650       CLEAR_FRAME_SIZE_SLIPPED (f);
651     }
652 }
653
654 /*
655  * This is a "specifier changed in frame" handler for various specifiers
656  * changing which causes frame size adjustment
657  */
658 void
659 frame_size_slipped (Lisp_Object specifier, struct frame *f,
660                     Lisp_Object oldval)
661 {
662   MARK_FRAME_SIZE_SLIPPED(f);
663 }
664 \f
665 DEFUN ("framep", Fframep, 1, 1, 0, /*
666 Return non-nil if OBJECT is a frame.
667 Also see `frame-live-p'.
668 Note that FSF Emacs kludgily returns a value indicating what type of
669 frame this is.  Use the cleaner function `frame-type' for that.
670 */
671        (object))
672 {
673   return FRAMEP (object) ? Qt : Qnil;
674 }
675
676 DEFUN ("frame-live-p", Fframe_live_p, 1, 1, 0, /*
677 Return non-nil if OBJECT is a frame which has not been deleted.
678 */
679        (object))
680 {
681   return FRAMEP (object) && FRAME_LIVE_P (XFRAME (object)) ? Qt : Qnil;
682 }
683
684 \f
685 DEFUN ("focus-frame", Ffocus_frame, 1, 1, 0, /*
686 Select FRAME and give it the window system focus.
687 This function is not affected by the value of `focus-follows-mouse'.
688 */
689        (frame))
690 {
691   CHECK_LIVE_FRAME (frame);
692
693   MAYBE_DEVMETH (XDEVICE (FRAME_DEVICE (XFRAME (frame))), focus_on_frame,
694                  (XFRAME (frame)));
695   /* FRAME will be selected by the time we receive the next event.
696      However, it is better to select it explicitly now, in case the
697      Lisp code depends on frame being selected.  */
698   Fselect_frame (frame);
699   return Qnil;
700 }
701
702 /* Called from Fselect_window() */
703 void
704 select_frame_1 (Lisp_Object frame)
705 {
706   struct frame *f = XFRAME (frame);
707   Lisp_Object old_selected_frame = Fselected_frame (Qnil);
708
709   if (EQ (frame, old_selected_frame))
710     return;
711
712   /* now select the frame's device */
713   set_device_selected_frame (XDEVICE (FRAME_DEVICE (f)), frame);
714   select_device_1 (FRAME_DEVICE (f));
715
716   update_frame_window_mirror (f);
717 }
718
719 DEFUN ("select-frame", Fselect_frame, 1, 1, 0, /*
720 Select the frame FRAME.
721 Subsequent editing commands apply to its selected window.
722 The selection of FRAME lasts until the next time the user does
723 something to select a different frame, or until the next time this
724 function is called.
725
726 Note that this does not actually cause the window-system focus to be
727 set to this frame, or the `select-frame-hook' or `deselect-frame-hook'
728 to be run, until the next time that XEmacs is waiting for an event.
729
730 Also note that when focus-follows-mouse is non-nil, the frame
731 selection is temporary and is reverted when the current command
732 terminates, much like the buffer selected by `set-buffer'.  In order
733 to effect a permanent focus change, use `focus-frame'.
734 */
735        (frame))
736 {
737   CHECK_LIVE_FRAME (frame);
738
739   /* select the frame's selected window.  This will call
740      selected_frame_1(). */
741   Fselect_window (FRAME_SELECTED_WINDOW (XFRAME (frame)), Qnil);
742
743   /* Nothing should be depending on the return value of this function.
744      But, of course, there is stuff out there which is. */
745   return frame;
746 }
747
748 /* use this to retrieve the currently selected frame.  You should use
749    this in preference to Fselected_frame (Qnil) unless you are prepared
750    to handle the possibility of there being no selected frame (this
751    happens at some points during startup). */
752
753 struct frame *
754 selected_frame (void)
755 {
756   Lisp_Object device = Fselected_device (Qnil);
757   Lisp_Object frame = DEVICE_SELECTED_FRAME (XDEVICE (device));
758   if (NILP (frame))
759     signal_simple_error ("No frames exist on device", device);
760   return XFRAME (frame);
761 }
762
763 /* use this instead of XFRAME (DEVICE_SELECTED_FRAME (d)) to catch
764    the possibility of there being no frames on the device (just created).
765    There is no point doing this inside of redisplay because errors
766    cause an abort(), indicating a flaw in the logic, and error_check_frame()
767    will catch this just as well. */
768
769 struct frame *
770 device_selected_frame (struct device *d)
771 {
772   Lisp_Object frame = DEVICE_SELECTED_FRAME (d);
773   if (NILP (frame))
774     {
775       Lisp_Object device;
776       XSETDEVICE (device, d);
777       signal_simple_error ("No frames exist on device", device);
778     }
779   return XFRAME (frame);
780 }
781
782 #if 0 /* FSFmacs */
783
784 xxDEFUN ("handle-switch-frame", Fhandle_switch_frame, 1, 2, "e", /*
785 Handle a switch-frame event EVENT.
786 Switch-frame events are usually bound to this function.
787 A switch-frame event tells Emacs that the window manager has requested
788 that the user's events be directed to the frame mentioned in the event.
789 This function selects the selected window of the frame of EVENT.
790
791 If EVENT is frame object, handle it as if it were a switch-frame event
792 to that frame.
793 */
794          (frame, no_enter))
795 {
796   /* Preserve prefix arg that the command loop just cleared.  */
797   XCONSOLE (Vselected_console)->prefix_arg = Vcurrent_prefix_arg;
798 #if 0 /* unclean! */
799   run_hook (Qmouse_leave_buffer_hook);
800 #endif
801   return do_switch_frame (frame, no_enter, 0);
802 }
803
804 /* A load of garbage. */
805 xxDEFUN ("ignore-event", Fignore_event, 0, 0, "", /*
806 Do nothing, but preserve any prefix argument already specified.
807 This is a suitable binding for iconify-frame and make-frame-visible.
808 */
809          ())
810 {
811   struct console *c = XCONSOLE (Vselected_console);
812
813   c->prefix_arg = Vcurrent_prefix_arg;
814   return Qnil;
815 }
816
817 #endif /* 0 */
818
819 DEFUN ("selected-frame", Fselected_frame, 0, 1, 0, /*
820 Return the frame that is now selected on device DEVICE.
821 If DEVICE is not specified, the selected device will be used.
822 If no frames exist on the device, nil is returned.
823 */
824        (device))
825 {
826   if (NILP (device) && NILP (Fselected_device (Qnil)))
827     return Qnil; /* happens early in temacs */
828   return DEVICE_SELECTED_FRAME (decode_device (device));
829 }
830
831 Lisp_Object
832 frame_first_window (struct frame *f)
833 {
834   Lisp_Object w = f->root_window;
835
836   while (1)
837     {
838       if (! NILP (XWINDOW (w)->hchild))
839         w = XWINDOW (w)->hchild;
840       else if (! NILP (XWINDOW (w)->vchild))
841         w = XWINDOW (w)->vchild;
842       else
843         break;
844     }
845
846   return w;
847 }
848
849 DEFUN ("active-minibuffer-window", Factive_minibuffer_window, 0, 0, 0, /*
850 Return the currently active minibuffer window, or nil if none.
851 */
852        ())
853 {
854   return minibuf_level ? minibuf_window : Qnil;
855 }
856
857 DEFUN ("last-nonminibuf-frame", Flast_nonminibuf_frame, 0, 1, 0, /*
858 Return the most-recently-selected non-minibuffer-only frame on CONSOLE.
859 This will always be the same as (selected-frame device) unless the
860 selected frame is a minibuffer-only frame.
861 CONSOLE defaults to the selected console if omitted.
862 */
863        (console))
864 {
865   Lisp_Object result;
866
867   XSETCONSOLE (console, decode_console (console));
868   /* Just in case the machinations in delete_frame_internal() resulted
869      in the last-nonminibuf-frame getting out of sync, make sure and
870      return the selected frame if it's acceptable. */
871   result = Fselected_frame (CONSOLE_SELECTED_DEVICE (XCONSOLE (console)));
872   if (!NILP (result) && !FRAME_MINIBUF_ONLY_P (XFRAME (result)))
873     return result;
874   return CONSOLE_LAST_NONMINIBUF_FRAME (XCONSOLE (console));
875 }
876
877 DEFUN ("frame-root-window", Fframe_root_window, 0, 1, 0, /*
878 Return the root-window of FRAME.
879 If omitted, FRAME defaults to the currently selected frame.
880 */
881        (frame))
882 {
883   struct frame *f = decode_frame (frame);
884   return FRAME_ROOT_WINDOW (f);
885 }
886
887 DEFUN ("frame-selected-window", Fframe_selected_window, 0, 1, 0, /*
888 Return the selected window of frame object FRAME.
889 If omitted, FRAME defaults to the currently selected frame.
890 */
891        (frame))
892 {
893   struct frame *f = decode_frame (frame);
894   return FRAME_SELECTED_WINDOW (f);
895 }
896
897 void
898 set_frame_selected_window (struct frame *f, Lisp_Object window)
899 {
900   assert (XFRAME (WINDOW_FRAME (XWINDOW (window))) == f);
901   f->selected_window = window;
902   if (!MINI_WINDOW_P (XWINDOW (window)) || FRAME_MINIBUF_ONLY_P (f))
903     {
904 #ifdef HAVE_TOOLBARS
905       if (!EQ (f->last_nonminibuf_window, window))
906         {
907           MARK_TOOLBAR_CHANGED;
908           MARK_GUTTER_CHANGED;
909         }
910 #endif
911       f->last_nonminibuf_window = window;
912     }
913 }
914
915 DEFUN ("set-frame-selected-window", Fset_frame_selected_window, 2, 2, 0, /*
916 Set the selected window of frame object FRAME to WINDOW.
917 If FRAME is nil, the selected frame is used.
918 If FRAME is the selected frame, this makes WINDOW the selected window.
919 */
920        (frame, window))
921 {
922   XSETFRAME (frame, decode_frame (frame));
923   CHECK_LIVE_WINDOW (window);
924
925   if (! EQ (frame, WINDOW_FRAME (XWINDOW (window))))
926     error ("In `set-frame-selected-window', WINDOW is not on FRAME");
927
928   if (XFRAME (frame) == selected_frame ())
929     return Fselect_window (window, Qnil);
930
931   set_frame_selected_window (XFRAME (frame), window);
932   return window;
933 }
934
935 \f
936 DEFUN ("frame-device", Fframe_device, 0, 1, 0, /*
937 Return the device that FRAME is on.
938 If omitted, FRAME defaults to the currently selected frame.
939 */
940        (frame))
941 {
942   return FRAME_DEVICE (decode_frame (frame));
943 }
944
945 int
946 is_surrogate_for_selected_frame (struct frame *f)
947 {
948   struct device *d = XDEVICE (f->device);
949   struct frame *dsf = device_selected_frame (d);
950
951   /* Can't be a surrogate for ourselves. */
952   if (f == dsf)
953     return 0;
954
955   if (!FRAME_HAS_MINIBUF_P (dsf) &&
956       f == XFRAME (WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (dsf)))))
957     return 1;
958   else
959     return 0;
960 }
961
962 static int
963 frame_matches_frametype (Lisp_Object frame, Lisp_Object type)
964 {
965   struct frame *f = XFRAME (frame);
966
967   if (WINDOWP (type))
968     {
969       CHECK_LIVE_WINDOW (type);
970
971       if (EQ (FRAME_MINIBUF_WINDOW (f), type)
972           /* Check that F either is, or has forwarded
973              its focus to, TYPE's frame.  */
974           && (EQ (WINDOW_FRAME (XWINDOW (type)), frame)
975               || EQ (WINDOW_FRAME (XWINDOW (type)),
976                      FRAME_FOCUS_FRAME (f))))
977         return 1;
978       else
979         return 0;
980     }
981
982 #if 0 /* FSFmacs */
983   if (EQ (type, Qvisible) || EQ (type, Qiconic) || EQ (type, Qvisible_iconic)
984       || EQ (type, Qvisible_nomini) || EQ (type, Qiconic_nomini)
985       || EQ (type, Qvisible_iconic_nomini))
986     FRAME_SAMPLE_VISIBILITY (f);
987 #endif
988
989   if (NILP (type))
990     type = Qnomini;
991   if (ZEROP (type))
992     type = Qvisible_iconic;
993
994   if (EQ (type, Qvisible))
995     return FRAME_VISIBLE_P (f);
996   if (EQ (type, Qiconic))
997     return FRAME_ICONIFIED_P (f);
998   if (EQ (type, Qinvisible))
999     return !FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f);
1000   if (EQ (type, Qvisible_iconic))
1001     return FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f);
1002   if (EQ (type, Qinvisible_iconic))
1003     return !FRAME_VISIBLE_P (f);
1004
1005   if (EQ (type, Qnomini))
1006     return !FRAME_MINIBUF_ONLY_P (f);
1007   if (EQ (type, Qvisible_nomini))
1008     return FRAME_VISIBLE_P (f) && !FRAME_MINIBUF_ONLY_P (f);
1009   if (EQ (type, Qiconic_nomini))
1010     return FRAME_ICONIFIED_P (f) && !FRAME_MINIBUF_ONLY_P (f);
1011   if (EQ (type, Qinvisible_nomini))
1012     return !FRAME_VISIBLE_P (f) && !FRAME_ICONIFIED_P (f) &&
1013       !FRAME_MINIBUF_ONLY_P (f);
1014   if (EQ (type, Qvisible_iconic_nomini))
1015     return ((FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
1016             && !FRAME_MINIBUF_ONLY_P (f));
1017   if (EQ (type, Qinvisible_iconic_nomini))
1018     return !FRAME_VISIBLE_P (f) && !FRAME_MINIBUF_ONLY_P (f);
1019
1020   return 1;
1021 }
1022
1023 int
1024 device_matches_console_spec (Lisp_Object frame, Lisp_Object device,
1025                              Lisp_Object console)
1026 {
1027   if (EQ (console, Qwindow_system))
1028     return DEVICE_WIN_P (XDEVICE (device));
1029   if (NILP (console))
1030     console = (DEVICE_CONSOLE (XDEVICE (FRAME_DEVICE (XFRAME (frame)))));
1031   if (DEVICEP (console))
1032     return EQ (device, console);
1033   if (CONSOLEP (console))
1034     return EQ (DEVICE_CONSOLE (XDEVICE (device)), console);
1035   if (valid_console_type_p (console))
1036     return EQ (DEVICE_TYPE (XDEVICE (device)), console);
1037   return 1;
1038 }
1039
1040 /* Return the next frame in the frame list after FRAME.
1041    FRAMETYPE and CONSOLE control which frames and devices
1042    are considered; see `next-frame'. */
1043
1044 static Lisp_Object
1045 next_frame_internal (Lisp_Object frame, Lisp_Object frametype,
1046                      Lisp_Object console, int called_from_delete_device)
1047 {
1048   int passed = 0;
1049   int started_over = 0;
1050
1051   /* If this frame is dead, it won't be in frame_list, and we'll loop
1052      forever.  Forestall that.  */
1053   CHECK_LIVE_FRAME (frame);
1054
1055   while (1)
1056     {
1057       Lisp_Object devcons, concons;
1058
1059       DEVICE_LOOP_NO_BREAK (devcons, concons)
1060         {
1061           Lisp_Object device = XCAR (devcons);
1062           Lisp_Object frmcons;
1063
1064           if (!device_matches_console_spec (frame, device, console))
1065             continue;
1066
1067           DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
1068             {
1069               Lisp_Object f = XCAR (frmcons);
1070               if (passed)
1071                 {
1072                   /* #### Doing this here is bad and is now
1073                      unnecessary.  The real bug was that f->iconified
1074                      was never, ever updated unless a user explicitly
1075                      called frame-iconified-p.  That has now been
1076                      fixed.  With this change removed all of the other
1077                      changes made to support this routine having the
1078                      called_from_delete_device arg could be removed.
1079                      But it is too close to release to do that now. */
1080 #if 0
1081                   /* Make sure the visibility and iconified flags are
1082                      up-to-date unless we're being deleted. */
1083                   if (!called_from_delete_device)
1084                     {
1085                       Fframe_iconified_p (f);
1086                       Fframe_visible_p (f);
1087                     }
1088 #endif
1089
1090                   /* Decide whether this frame is eligible to be returned.  */
1091
1092                   /* If we've looped all the way around without finding any
1093                      eligible frames, return the original frame.  */
1094                   if (EQ (f, frame))
1095                     return f;
1096
1097                   if (frame_matches_frametype (f, frametype))
1098                     return f;
1099                 }
1100
1101               if (EQ (frame, f))
1102                 passed++;
1103             }
1104         }
1105       /* We hit the end of the list, and need to start over again. */
1106       if (started_over)
1107         return Qnil;
1108       started_over++;
1109     }
1110 }
1111
1112 Lisp_Object
1113 next_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
1114 {
1115   return next_frame_internal (frame, frametype, console, 0);
1116 }
1117
1118 /* Return the previous frame in the frame list before FRAME.
1119    FRAMETYPE and CONSOLE control which frames and devices
1120    are considered; see `next-frame'. */
1121
1122 Lisp_Object
1123 prev_frame (Lisp_Object frame, Lisp_Object frametype, Lisp_Object console)
1124 {
1125   Lisp_Object devcons, concons;
1126   Lisp_Object prev;
1127
1128   /* If this frame is dead, it won't be in frame_list, and we'll loop
1129      forever.  Forestall that.  */
1130   CHECK_LIVE_FRAME (frame);
1131
1132   prev = Qnil;
1133   DEVICE_LOOP_NO_BREAK (devcons, concons)
1134     {
1135       Lisp_Object device = XCAR (devcons);
1136       Lisp_Object frmcons;
1137
1138       if (!device_matches_console_spec (frame, device, console))
1139         continue;
1140
1141       DEVICE_FRAME_LOOP (frmcons, XDEVICE (device))
1142         {
1143           Lisp_Object f = XCAR (frmcons);
1144
1145           if (EQ (frame, f) && !NILP (prev))
1146             return prev;
1147
1148           /* Decide whether this frame is eligible to be returned,
1149              according to frametype.  */
1150
1151           if (frame_matches_frametype (f, frametype))
1152             prev = f;
1153
1154         }
1155     }
1156
1157   /* We've scanned the entire list.  */
1158   if (NILP (prev))
1159     /* We went through the whole frame list without finding a single
1160        acceptable frame.  Return the original frame.  */
1161     return frame;
1162   else
1163     /* There were no acceptable frames in the list before FRAME; otherwise,
1164        we would have returned directly from the loop.  Since PREV is the last
1165        acceptable frame in the list, return it.  */
1166     return prev;
1167 }
1168
1169 DEFUN ("next-frame", Fnext_frame, 0, 3, 0, /*
1170 Return the next frame of the right type in the frame list after FRAME.
1171 FRAMETYPE controls which frames are eligible to be returned; all
1172 others will be skipped.  Note that if there is only one eligible
1173 frame, then `next-frame' called repeatedly will always return
1174 the same frame, and if there is no eligible frame, then FRAME is
1175 returned.
1176
1177 Possible values for FRAMETYPE are
1178
1179 'visible                 Consider only frames that are visible.
1180 'iconic                  Consider only frames that are iconic.
1181 'invisible               Consider only frames that are invisible
1182                          (this is different from iconic).
1183 'visible-iconic          Consider frames that are visible or iconic.
1184 'invisible-iconic        Consider frames that are invisible or iconic.
1185 'nomini                  Consider all frames except minibuffer-only ones.
1186 'visible-nomini          Like `visible' but omits minibuffer-only frames.
1187 'iconic-nomini           Like `iconic' but omits minibuffer-only frames.
1188 'invisible-nomini        Like `invisible' but omits minibuffer-only frames.
1189 'visible-iconic-nomini   Like `visible-iconic' but omits minibuffer-only
1190                          frames.
1191 'invisible-iconic-nomini Like `invisible-iconic' but omits minibuffer-only
1192                          frames.
1193 any other value          Consider all frames.
1194
1195 If FRAMETYPE is omitted, 'nomini is used.  A FRAMETYPE of 0 (a number)
1196 is treated like 'iconic, for backwards compatibility.
1197
1198 If FRAMETYPE is a window, include only its own frame and any frame now
1199 using that window as the minibuffer.
1200
1201 Optional third argument CONSOLE controls which consoles or devices the
1202 returned frame may be on.  If CONSOLE is a console, return frames only
1203 on that console.  If CONSOLE is a device, return frames only on that
1204 device.  If CONSOLE is a console type, return frames only on consoles
1205 of that type.  If CONSOLE is 'window-system, return any frames on any
1206 window-system consoles.  If CONSOLE is nil or omitted, return frames only
1207 on the FRAME's console.  Otherwise, all frames are considered.
1208 */
1209        (frame, frametype, console))
1210 {
1211   XSETFRAME (frame, decode_frame (frame));
1212
1213   return next_frame (frame, frametype, console);
1214 }
1215
1216 DEFUN ("previous-frame", Fprevious_frame, 0, 3, 0, /*
1217 Return the next frame of the right type in the frame list after FRAME.
1218 FRAMETYPE controls which frames are eligible to be returned; all
1219 others will be skipped.  Note that if there is only one eligible
1220 frame, then `previous-frame' called repeatedly will always return
1221 the same frame, and if there is no eligible frame, then FRAME is
1222 returned.
1223
1224 See `next-frame' for an explanation of the FRAMETYPE and CONSOLE
1225 arguments.
1226 */
1227        (frame, frametype, console))
1228 {
1229   XSETFRAME (frame, decode_frame (frame));
1230
1231   return prev_frame (frame, frametype, console);
1232 }
1233
1234 /* Return any frame for which PREDICATE is non-zero, or return Qnil
1235    if there aren't any. */
1236
1237 Lisp_Object
1238 find_some_frame (int (*predicate) (Lisp_Object, void *),
1239                  void *closure)
1240 {
1241   Lisp_Object framecons, devcons, concons;
1242
1243   FRAME_LOOP_NO_BREAK (framecons, devcons, concons)
1244     {
1245       Lisp_Object frame = XCAR (framecons);
1246
1247       if ((predicate) (frame, closure))
1248         return frame;
1249     }
1250
1251   return Qnil;
1252 }
1253
1254 \f
1255
1256 /* extern void free_line_insertion_deletion_costs (struct frame *f); */
1257
1258 /* Return 1 if it is ok to delete frame F;
1259    0 if all frames aside from F are invisible.
1260    (Exception: if F is a stream frame, it's OK to delete if
1261    any other frames exist.) */
1262
1263 static int
1264 other_visible_frames_internal (struct frame *f, int called_from_delete_device)
1265 {
1266   Lisp_Object frame;
1267
1268   XSETFRAME (frame, f);
1269   if (FRAME_STREAM_P (f))
1270     return !EQ (frame, next_frame_internal (frame, Qt, Qt,
1271                                             called_from_delete_device));
1272   return !EQ (frame, next_frame_internal (frame, Qvisible_iconic_nomini, Qt,
1273                                           called_from_delete_device));
1274 }
1275
1276 int
1277 other_visible_frames (struct frame *f)
1278 {
1279   return other_visible_frames_internal (f, 0);
1280 }
1281
1282 /* Delete frame F.
1283
1284    If FORCE is non-zero, allow deletion of the only frame.
1285
1286    If CALLED_FROM_DELETE_DEVICE is non-zero, then, if
1287    deleting the last frame on a device, just delete it,
1288    instead of calling `delete-device'.
1289
1290    If FROM_IO_ERROR is non-zero, then the frame is gone due
1291    to an I/O error.  This affects what happens if we exit
1292    (we do an emergency exit instead of `save-buffers-kill-emacs'.)
1293 */
1294
1295 void
1296 delete_frame_internal (struct frame *f, int force,
1297                        int called_from_delete_device,
1298                        int from_io_error)
1299 {
1300   /* This function can GC */
1301   int minibuffer_selected;
1302   struct device *d;
1303   struct console *con;
1304   Lisp_Object frame;
1305   Lisp_Object device;
1306   Lisp_Object console;
1307   struct gcpro gcpro1;
1308
1309   /* OK to delete an already deleted frame. */
1310   if (! FRAME_LIVE_P (f))
1311     return;
1312
1313   XSETFRAME (frame, f);
1314   GCPRO1 (frame);
1315
1316   device = FRAME_DEVICE (f);
1317   d = XDEVICE (device);
1318   console = DEVICE_CONSOLE (d);
1319   con = XCONSOLE (console);
1320
1321   if (!called_from_delete_device)
1322     {
1323       /* If we're deleting the only non-minibuffer frame on the
1324          device, delete the device. */
1325       if (EQ (frame, next_frame (frame, Qnomini, FRAME_DEVICE (f))))
1326         {
1327           delete_device_internal (d, force, 0, from_io_error);
1328           UNGCPRO;
1329           return;
1330         }
1331     }
1332
1333   /* In FSF, delete-frame will not normally allow you to delete the
1334      last visible frame.  This was too annoying, so we changed it to the
1335      only frame.  However, this would let people shoot themselves by
1336      deleting all frames which were either visible or iconified and thus
1337      losing any way of communicating with the still running XEmacs process.
1338      So we put it back.  */
1339   if (!force && !allow_deletion_of_last_visible_frame &&
1340       !other_visible_frames_internal (f, called_from_delete_device))
1341     error ("Attempt to delete the sole visible or iconified frame");
1342
1343   /* Does this frame have a minibuffer, and is it the surrogate
1344      minibuffer for any other frame?  */
1345   if (FRAME_HAS_MINIBUF_P (f))
1346     {
1347       Lisp_Object frmcons, devcons, concons;
1348
1349       FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
1350         {
1351           Lisp_Object this = XCAR (frmcons);
1352
1353           if (! EQ (this, frame)
1354               && EQ (frame, (WINDOW_FRAME
1355                              (XWINDOW
1356                               (FRAME_MINIBUF_WINDOW (XFRAME (this)))))))
1357             {
1358               /* We've found another frame whose minibuffer is on
1359                  this frame. */
1360               signal_simple_error
1361                 ("Attempt to delete a surrogate minibuffer frame", frame);
1362             }
1363         }
1364     }
1365
1366   /* Test for popup frames hanging around. */
1367   /* Deletion of a parent frame with popups is deadly. */
1368   {
1369     Lisp_Object frmcons, devcons, concons;
1370
1371     FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
1372       {
1373         Lisp_Object this = XCAR (frmcons);
1374
1375
1376         if (! EQ (this, frame))
1377           {
1378             struct device *devcons_d = XDEVICE (XCAR (devcons));
1379             if (EQ (frame, DEVMETH_OR_GIVEN (devcons_d, get_frame_parent,
1380                                              (XFRAME (this)),
1381                                              Qnil)))
1382               /* We've found a popup frame whose parent is this frame. */
1383               signal_simple_error
1384                 ("Attempt to delete a frame with live popups", frame);
1385           }
1386       }
1387   }
1388
1389   /* Before here, we haven't made any dangerous changes (just checked for
1390      error conditions).  Now run the delete-frame-hook.  Remember that
1391      user code there could do any number of dangerous things, including
1392      signalling an error. */
1393
1394   va_run_hook_with_args (Qdelete_frame_hook, 1, frame);
1395
1396   if (!FRAME_LIVE_P (f)) /* Make sure the delete-frame-hook didn't */
1397     {                    /* go ahead and delete anything. */
1398       UNGCPRO;
1399       return;
1400     }
1401
1402   /* Call the delete-device-hook and delete-console-hook now if
1403      appropriate, before we do any dangerous things -- they too could
1404      signal an error. */
1405   if (XINT (Flength (DEVICE_FRAME_LIST (d))) == 1)
1406     {
1407       va_run_hook_with_args (Qdelete_device_hook, 1, device);
1408       if (!FRAME_LIVE_P (f)) /* Make sure the delete-device-hook didn't */
1409         {                    /* go ahead and delete anything. */
1410           UNGCPRO;
1411           return;
1412         }
1413
1414       if (XINT (Flength (CONSOLE_DEVICE_LIST (con))) == 1)
1415         {
1416           va_run_hook_with_args (Qdelete_console_hook, 1, console);
1417           if (!FRAME_LIVE_P (f)) /* Make sure the delete-console-hook didn't */
1418             {                    /* go ahead and delete anything. */
1419               UNGCPRO;
1420               return;
1421             }
1422         }
1423     }
1424
1425   minibuffer_selected = EQ (minibuf_window, Fselected_window (Qnil));
1426
1427   /* If we were focused on this frame, then we're not any more.
1428      Assume that we lost the focus; that way, the call to
1429      Fselect_frame() below won't end up making us explicitly
1430      focus on another frame, which is generally undesirable in
1431      a point-to-type world.  If our mouse ends up sitting over
1432      another frame, we will receive a FocusIn event and end up
1433      making that frame the selected frame.
1434
1435      #### This may not be an ideal solution in a click-to-type
1436      world (in that case, we might want to explicitly choose
1437      another frame to have the focus, rather than relying on
1438      the WM, which might focus on a frame in a different app
1439      or focus on nothing at all).  But there's no easy way
1440      to detect which focus model we're running on, and the
1441      alternative is more heinous. */
1442
1443   if (EQ (frame, DEVICE_FRAME_WITH_FOCUS_REAL (d)))
1444     DEVICE_FRAME_WITH_FOCUS_REAL (d) = Qnil;
1445   if (EQ (frame, DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d)))
1446     DEVICE_FRAME_WITH_FOCUS_FOR_HOOKS (d) = Qnil;
1447   if (EQ (frame, DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d)))
1448     DEVICE_FRAME_THAT_OUGHT_TO_HAVE_FOCUS (d) = Qnil;
1449
1450   /* Don't allow the deleted frame to remain selected.
1451      Note that in the former scheme of things, this would
1452      have caused us to regain the focus.  This no longer
1453      applies (see above); I think the new behavior is more
1454      logical.  If someone disagrees, it can always be
1455      changed (or a new user variable can be introduced, ugh.) */
1456   if (EQ (frame, DEVICE_SELECTED_FRAME (d)))
1457     {
1458       Lisp_Object next;
1459
1460       /* If this is a popup frame, select its parent if possible.
1461          Otherwise, find another visible frame; if none, just take any frame.
1462          First try the same device, then the same console. */
1463
1464       next = DEVMETH_OR_GIVEN (d, get_frame_parent, (f), Qnil);
1465       if (NILP (next) || EQ (next, frame) || ! FRAME_LIVE_P (XFRAME (next)))
1466         next = next_frame_internal (frame, Qvisible, device,
1467                                     called_from_delete_device);
1468       if (NILP (next) || EQ (next, frame))
1469         next = next_frame_internal (frame, Qvisible, console,
1470                                     called_from_delete_device);
1471       if (NILP (next) || EQ (next, frame))
1472         next = next_frame_internal (frame, Qvisible, Qt,
1473                                     called_from_delete_device);
1474       if (NILP (next) || EQ (next, frame))
1475         next = next_frame_internal (frame, Qt, device,
1476                                     called_from_delete_device);
1477       if (NILP (next) || EQ (next, frame))
1478         next = next_frame_internal (frame, Qt, console,
1479                                     called_from_delete_device);
1480       if (NILP (next) || EQ (next, frame))
1481         next = next_frame_internal (frame, Qt, Qt, called_from_delete_device);
1482
1483       /* if we haven't found another frame at this point
1484          then there aren't any. */
1485       if (NILP (next) || EQ (next, frame))
1486         ;
1487       else
1488         {
1489           int did_select = 0;
1490           /* if this is the global selected frame, select another one. */
1491           if (EQ (frame, Fselected_frame (Qnil)))
1492             {
1493                 Fselect_frame (next);
1494                 did_select = 1;
1495             }
1496           /*
1497            * If the new frame we just selected is on a different
1498            * device then we still need to change DEVICE_SELECTED_FRAME(d)
1499            * to a live frame, if there are any left on this device.
1500            */
1501           if (!EQ (device, FRAME_DEVICE(XFRAME(next))))
1502             {
1503                 Lisp_Object next_f =
1504                     next_frame_internal (frame, Qt, device,
1505                                          called_from_delete_device);
1506                 if (NILP (next_f) || EQ (next_f, frame))
1507                   ;
1508                 else
1509                   set_device_selected_frame (d, next_f);
1510             }
1511           else if (! did_select)
1512             set_device_selected_frame (d, next);
1513
1514         }
1515     }
1516
1517   /* Don't allow minibuf_window to remain on a deleted frame.  */
1518   if (EQ (f->minibuffer_window, minibuf_window))
1519     {
1520       struct frame *sel_frame = selected_frame ();
1521       Fset_window_buffer (sel_frame->minibuffer_window,
1522                           XWINDOW (minibuf_window)->buffer);
1523       minibuf_window = sel_frame->minibuffer_window;
1524
1525       /* If the dying minibuffer window was selected,
1526          select the new one.  */
1527       if (minibuffer_selected)
1528         Fselect_window (minibuf_window, Qnil);
1529     }
1530
1531   /* After this point, no errors must be allowed to occur. */
1532
1533 #ifdef HAVE_MENUBARS
1534   free_frame_menubars (f);
1535 #endif
1536 #ifdef HAVE_SCROLLBARS
1537   free_frame_scrollbars (f);
1538 #endif
1539 #ifdef HAVE_TOOLBARS
1540   free_frame_toolbars (f);
1541 #endif
1542   free_frame_gutters (f);
1543
1544   /* This must be done before the window and window_mirror structures
1545      are freed.  The scrollbar information is attached to them. */
1546   MAYBE_FRAMEMETH (f, delete_frame, (f));
1547
1548   /* Mark all the windows that used to be on FRAME as deleted, and then
1549      remove the reference to them.  */
1550   delete_all_subwindows (XWINDOW (f->root_window));
1551   f->root_window = Qnil;
1552
1553   /* clear out the cached glyph information */
1554   if (f->subwindow_cachels)
1555     {
1556       Dynarr_free (f->subwindow_cachels);
1557       f->subwindow_cachels = 0;
1558     }
1559
1560   /* Remove the frame now from the list.  This way, any events generated
1561      on this frame by the maneuvers below will disperse themselves. */
1562
1563   /* This used to be Fdelq(), but that will cause a seg fault if the
1564      QUIT checker happens to get invoked, because the frame list is in
1565      an inconsistent state. */
1566   d->frame_list = delq_no_quit (frame, d->frame_list);
1567   RESET_CHANGED_SET_FLAGS;
1568
1569   f->dead = 1;
1570   f->visible = 0;
1571
1572   free_window_mirror (f->root_mirror);
1573 /*  free_line_insertion_deletion_costs (f); */
1574
1575   /* If we've deleted the last non-minibuf frame, then try to find
1576      another one.  */
1577   if (EQ (frame, CONSOLE_LAST_NONMINIBUF_FRAME (con)))
1578     {
1579       Lisp_Object frmcons, devcons;
1580
1581       set_console_last_nonminibuf_frame (con, Qnil);
1582
1583       CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, con)
1584         {
1585           Lisp_Object ecran = XCAR (frmcons);
1586           if (!FRAME_MINIBUF_ONLY_P (XFRAME (ecran)))
1587             {
1588               set_console_last_nonminibuf_frame (con, ecran);
1589               goto double_break_1;
1590             }
1591         }
1592     }
1593  double_break_1:
1594
1595 #if 0
1596   /* The following test is degenerate FALSE */
1597   if (called_from_delete_device < 0)
1598     /* then we're being called from delete-console, and we shouldn't
1599        try to find another default-minibuffer frame for the console.
1600        */
1601     con->default_minibuffer_frame = Qnil;
1602 #endif
1603
1604   /* If we've deleted this console's default_minibuffer_frame, try to
1605      find another one.  Prefer minibuffer-only frames, but also notice
1606      frames with other windows.  */
1607   if (EQ (frame, con->default_minibuffer_frame))
1608     {
1609       Lisp_Object frmcons, devcons;
1610       /* The last frame we saw with a minibuffer, minibuffer-only or not.  */
1611       Lisp_Object frame_with_minibuf;
1612       /* Some frame we found on the same console, or nil if there are none. */
1613       Lisp_Object frame_on_same_console;
1614
1615       frame_on_same_console = Qnil;
1616       frame_with_minibuf = Qnil;
1617
1618       set_console_last_nonminibuf_frame (con, Qnil);
1619
1620       CONSOLE_FRAME_LOOP_NO_BREAK (frmcons, devcons, con)
1621         {
1622           Lisp_Object this;
1623           struct frame *f1;
1624
1625           this = XCAR (frmcons);
1626           f1 = XFRAME (this);
1627
1628           /* Consider only frames on the same console
1629              and only those with minibuffers.  */
1630           if (FRAME_HAS_MINIBUF_P (f1))
1631             {
1632               frame_with_minibuf = this;
1633               if (FRAME_MINIBUF_ONLY_P (f1))
1634                 goto double_break_2;
1635             }
1636
1637           frame_on_same_console = this;
1638         }
1639     double_break_2:
1640
1641       if (!NILP (frame_on_same_console))
1642         {
1643           /* We know that there must be some frame with a minibuffer out
1644              there.  If this were not true, all of the frames present
1645              would have to be minibuffer-less, which implies that at some
1646              point their minibuffer frames must have been deleted, but
1647              that is prohibited at the top; you can't delete surrogate
1648              minibuffer frames.  */
1649           if (NILP (frame_with_minibuf))
1650             abort ();
1651
1652           con->default_minibuffer_frame = frame_with_minibuf;
1653         }
1654       else
1655         /* No frames left on this console--say no minibuffer either.  */
1656         con->default_minibuffer_frame = Qnil;
1657     }
1658
1659   nuke_all_frame_slots (f); /* nobody should be accessing the device
1660                                or anything else any more, and making
1661                                them Qnil allows for better GC'ing
1662                                in case a pointer to the dead frame
1663                                continues to hang around. */
1664   f->framemeths = dead_console_methods;
1665   UNGCPRO;
1666 }
1667
1668 void
1669 io_error_delete_frame (Lisp_Object frame)
1670 {
1671   delete_frame_internal (XFRAME (frame), 1, 0, 1);
1672 }
1673
1674 DEFUN ("delete-frame", Fdelete_frame, 0, 2, "", /*
1675 Delete FRAME, permanently eliminating it from use.
1676 If omitted, FRAME defaults to the selected frame.
1677 A frame may not be deleted if its minibuffer is used by other frames.
1678 Normally, you cannot delete the last non-minibuffer-only frame (you must
1679 use `save-buffers-kill-emacs' or `kill-emacs').  However, if optional
1680 second argument FORCE is non-nil, you can delete the last frame. (This
1681 will automatically call `save-buffers-kill-emacs'.)
1682 */
1683        (frame, force))
1684 {
1685   /* This function can GC */
1686   struct frame *f;
1687
1688   if (NILP (frame))
1689     {
1690       f = selected_frame ();
1691       XSETFRAME (frame, f);
1692     }
1693   else
1694     {
1695       CHECK_FRAME (frame);
1696       f = XFRAME (frame);
1697     }
1698
1699   delete_frame_internal (f, !NILP (force), 0, 0);
1700   return Qnil;
1701 }
1702
1703 \f
1704 /* Return mouse position in character cell units.  */
1705
1706 static int
1707 mouse_pixel_position_1 (struct device *d, Lisp_Object *frame,
1708                         int *x, int *y)
1709 {
1710   switch (DEVMETH_OR_GIVEN (d, get_mouse_position, (d, frame, x, y), -1))
1711     {
1712     case 1:
1713       return 1;
1714
1715     case 0:
1716       *frame = Qnil;
1717       break;
1718
1719     case -1:
1720       *frame = DEVICE_SELECTED_FRAME (d);
1721       break;
1722
1723     default:
1724       abort (); /* method is incorrectly written */
1725     }
1726
1727   return 0;
1728 }
1729
1730 DEFUN ("mouse-pixel-position", Fmouse_pixel_position, 0, 1, 0, /*
1731 Return a list (WINDOW X . Y) giving the current mouse window and position.
1732 The position is given in pixel units, where (0, 0) is the upper-left corner.
1733
1734 When the cursor is not over a window, the return value is a list (nil nil).
1735
1736 DEVICE specifies the device on which to read the mouse position, and
1737 defaults to the selected device.  If the device is a mouseless terminal
1738 or Emacs hasn't been programmed to read its mouse position, it returns
1739 the device's selected window for WINDOW and nil for X and Y.
1740 */
1741        (device))
1742 {
1743   struct device *d = decode_device (device);
1744   Lisp_Object frame;
1745   Lisp_Object window = Qnil;
1746   Lisp_Object x = Qnil;
1747   Lisp_Object y = Qnil;
1748   int intx, inty;
1749
1750   if (mouse_pixel_position_1 (d, &frame, &intx, &inty) > 0)
1751     {
1752       struct window *w =
1753         find_window_by_pixel_pos (intx, inty, XFRAME (frame)->root_window);
1754       if (w)
1755         {
1756           XSETWINDOW (window, w);
1757
1758           /* Adjust the position to be relative to the window. */
1759           intx -= w->pixel_left;
1760           inty -= w->pixel_top;
1761           XSETINT (x, intx);
1762           XSETINT (y, inty);
1763         }
1764     }
1765   else if (FRAMEP (frame))
1766     window = FRAME_SELECTED_WINDOW (XFRAME (frame));
1767
1768   return Fcons (window, Fcons (x, y));
1769 }
1770
1771 DEFUN ("mouse-position", Fmouse_position, 0, 1, 0, /*
1772 Return a list (WINDOW X . Y) giving the current mouse window and position.
1773 The position is of a character under cursor, where (0, 0) is the upper-left
1774 corner of the window.
1775
1776 When the cursor is not over a character, or not over a window, the return
1777 value is a list (nil nil).
1778
1779 DEVICE specifies the device on which to read the mouse position, and
1780 defaults to the selected device.  If the device is a mouseless terminal
1781 or Emacs hasn't been programmed to read its mouse position, it returns
1782 the device's selected window for WINDOW and nil for X and Y.
1783 */
1784        (device))
1785 {
1786   struct device *d = decode_device (device);
1787   struct window *w;
1788   Lisp_Object frame, window = Qnil, lisp_x = Qnil, lisp_y = Qnil;
1789   int x, y, obj_x, obj_y;
1790   Bufpos bufpos, closest;
1791   Charcount modeline_closest;
1792   Lisp_Object obj1, obj2;
1793
1794   if (mouse_pixel_position_1 (d, &frame, &x, &y) > 0)
1795     {
1796       int res = pixel_to_glyph_translation (XFRAME (frame), x, y, &x, &y,
1797                                             &obj_x, &obj_y, &w, &bufpos,
1798                                             &closest, &modeline_closest,
1799                                             &obj1, &obj2);
1800       if (res == OVER_TEXT)
1801         {
1802           lisp_x = make_int (x);
1803           lisp_y = make_int (y);
1804           XSETWINDOW (window, w);
1805         }
1806     }
1807   else if (FRAMEP (frame))
1808     window = FRAME_SELECTED_WINDOW (XFRAME (frame));
1809
1810   return Fcons (window, Fcons (lisp_x, lisp_y));
1811 }
1812
1813 DEFUN ("mouse-position-as-motion-event", Fmouse_position_as_motion_event, 0, 1, 0, /*
1814 Return the current mouse position as a motion event.
1815 This allows you to call the standard event functions such as
1816 `event-over-toolbar-p' to determine where the mouse is.
1817
1818 DEVICE specifies the device on which to read the mouse position, and
1819 defaults to the selected device.  If the mouse position can't be determined
1820 \(e.g. DEVICE is a TTY device), nil is returned instead of an event.
1821 */
1822        (device))
1823 {
1824   struct device *d = decode_device (device);
1825   Lisp_Object frame;
1826   int intx, inty;
1827
1828   if (mouse_pixel_position_1 (d, &frame, &intx, &inty))
1829     {
1830       Lisp_Object event = Fmake_event (Qnil, Qnil);
1831       XEVENT (event)->event_type = pointer_motion_event;
1832       XEVENT (event)->channel = frame;
1833       XEVENT (event)->event.motion.x = intx;
1834       XEVENT (event)->event.motion.y = inty;
1835       return event;
1836     }
1837   else
1838     return Qnil;
1839 }
1840
1841 DEFUN ("set-mouse-position", Fset_mouse_position, 3, 3, 0, /*
1842 Move the mouse pointer to the center of character cell (X,Y) in WINDOW.
1843 Note, this is a no-op for an X frame that is not visible.
1844 If you have just created a frame, you must wait for it to become visible
1845 before calling this function on it, like this.
1846   (while (not (frame-visible-p frame)) (sleep-for .5))
1847 Note also: Warping the mouse is contrary to the ICCCM, so be very sure
1848  that the behavior won't end up being obnoxious!
1849 */
1850        (window, x, y))
1851 {
1852   struct window *w;
1853   int pix_x, pix_y;
1854
1855   CHECK_LIVE_WINDOW (window);
1856   CHECK_INT (x);
1857   CHECK_INT (y);
1858
1859   /* Warping the mouse will cause EnterNotify and Focus events under X. */
1860   w = XWINDOW (window);
1861   glyph_to_pixel_translation (w, XINT (x), XINT (y), &pix_x, &pix_y);
1862
1863   MAYBE_FRAMEMETH (XFRAME (w->frame), set_mouse_position, (w, pix_x, pix_y));
1864
1865   return Qnil;
1866 }
1867
1868 DEFUN ("set-mouse-pixel-position", Fset_mouse_pixel_position, 3, 3, 0, /*
1869 Move the mouse pointer to pixel position (X,Y) in WINDOW.
1870 Note, this is a no-op for an X frame that is not visible.
1871 If you have just created a frame, you must wait for it to become visible
1872 before calling this function on it, like this.
1873   (while (not (frame-visible-p frame)) (sleep-for .5))
1874 */
1875        (window, x, y))
1876 {
1877   struct window *w;
1878
1879   CHECK_LIVE_WINDOW (window);
1880   CHECK_INT (x);
1881   CHECK_INT (y);
1882
1883   /* Warping the mouse will cause EnterNotify and Focus events under X. */
1884   w = XWINDOW (window);
1885   FRAMEMETH (XFRAME (w->frame), set_mouse_position, (w, XINT (x), XINT (y)));
1886
1887   return Qnil;
1888 }
1889 \f
1890 DEFUN ("make-frame-visible", Fmake_frame_visible, 0, 1, 0, /*
1891 Make the frame FRAME visible (assuming it is an X-window).
1892 If omitted, FRAME defaults to the currently selected frame.
1893 Also raises the frame so that nothing obscures it.
1894 */
1895        (frame))
1896 {
1897   struct frame *f = decode_frame (frame);
1898
1899   MAYBE_FRAMEMETH (f, make_frame_visible, (f));
1900   return frame;
1901 }
1902
1903 DEFUN ("make-frame-invisible", Fmake_frame_invisible, 0, 2, 0, /*
1904 Unconditionally removes frame from the display (assuming it is an X-window).
1905 If omitted, FRAME defaults to the currently selected frame.
1906 If what you want to do is iconify the frame (if the window manager uses
1907 icons) then you should call `iconify-frame' instead.
1908 Normally you may not make FRAME invisible if all other frames are invisible
1909 and uniconified, but if the second optional argument FORCE is non-nil,
1910 you may do so.
1911 */
1912        (frame, force))
1913 {
1914   struct frame *f, *sel_frame;
1915   struct device *d;
1916
1917   f = decode_frame (frame);
1918   d = XDEVICE (FRAME_DEVICE (f));
1919   sel_frame = XFRAME (DEVICE_SELECTED_FRAME (d));
1920
1921   if (NILP (force) && !other_visible_frames (f))
1922     error ("Attempt to make invisible the sole visible or iconified frame");
1923
1924   /* Don't allow minibuf_window to remain on a deleted frame.  */
1925   if (EQ (f->minibuffer_window, minibuf_window))
1926     {
1927       Fset_window_buffer (sel_frame->minibuffer_window,
1928                           XWINDOW (minibuf_window)->buffer);
1929       minibuf_window = sel_frame->minibuffer_window;
1930     }
1931
1932   MAYBE_FRAMEMETH (f, make_frame_invisible, (f));
1933
1934   return Qnil;
1935 }
1936
1937 DEFUN ("iconify-frame", Ficonify_frame, 0, 1, "", /*
1938 Make the frame FRAME into an icon, if the window manager supports icons.
1939 If omitted, FRAME defaults to the currently selected frame.
1940 */
1941        (frame))
1942 {
1943   struct frame *f, *sel_frame;
1944   struct device *d;
1945
1946   f = decode_frame (frame);
1947   d = XDEVICE (FRAME_DEVICE (f));
1948   sel_frame = XFRAME (DEVICE_SELECTED_FRAME (d));
1949
1950   /* Don't allow minibuf_window to remain on a deleted frame.  */
1951   if (EQ (f->minibuffer_window, minibuf_window))
1952     {
1953       Fset_window_buffer (sel_frame->minibuffer_window,
1954                           XWINDOW (minibuf_window)->buffer);
1955       minibuf_window = sel_frame->minibuffer_window;
1956     }
1957
1958   MAYBE_FRAMEMETH (f, iconify_frame, (f));
1959
1960   return Qnil;
1961 }
1962
1963 DEFUN ("deiconify-frame", Fdeiconify_frame, 0, 1, 0, /*
1964 Open (de-iconify) the iconified frame FRAME.
1965 Under X, this is currently the same as `make-frame-visible'.
1966 If omitted, FRAME defaults to the currently selected frame.
1967 Also raises the frame so that nothing obscures it.
1968 */
1969        (frame))
1970 {
1971   return Fmake_frame_visible (frame);
1972 }
1973
1974 /* FSF returns 'icon for iconized frames.  What a crock! */
1975
1976 DEFUN ("frame-visible-p", Fframe_visible_p, 0, 1, 0, /*
1977 Return non NIL if FRAME is now "visible" (actually in use for display).
1978 A frame that is not visible is not updated, and, if it works through a
1979 window system, may not show at all.
1980 N.B. Under X "visible" means Mapped. It the window is mapped but not
1981 actually visible on screen then frame_visible returns 'hidden.
1982 */
1983        (frame))
1984 {
1985   struct frame *f = decode_frame (frame);
1986   int visible = FRAMEMETH_OR_GIVEN (f, frame_visible_p, (f), f->visible);
1987   return visible ? ( visible > 0 ? Qt : Qhidden ) : Qnil;
1988 }
1989
1990 DEFUN ("frame-totally-visible-p", Fframe_totally_visible_p, 0, 1, 0, /*
1991 Return t if frame is not obscured by any other window system windows.
1992 Always returns t for tty frames.
1993 */
1994        (frame))
1995 {
1996   struct frame *f = decode_frame (frame);
1997   return (FRAMEMETH_OR_GIVEN (f, frame_totally_visible_p, (f), f->visible)
1998           ? Qt : Qnil);
1999 }
2000
2001 DEFUN ("frame-iconified-p", Fframe_iconified_p, 0, 1, 0, /*
2002 Return t if FRAME is iconified.
2003 Not all window managers use icons; some merely unmap the window, so this
2004 function is not the inverse of `frame-visible-p'.  It is possible for a
2005 frame to not be visible and not be iconified either.  However, if the
2006 frame is iconified, it will not be visible.
2007 */
2008        (frame))
2009 {
2010   struct frame *f = decode_frame (frame);
2011   if (f->visible)
2012     return Qnil;
2013   f->iconified = FRAMEMETH_OR_GIVEN (f, frame_iconified_p, (f), 0);
2014   return f->iconified ? Qt : Qnil;
2015 }
2016
2017 DEFUN ("visible-frame-list", Fvisible_frame_list, 0, 1, 0, /*
2018 Return a list of all frames now "visible" (being updated).
2019 If DEVICE is specified only frames on that device will be returned.
2020 Note that under virtual window managers not all these frame are necessarily
2021 really updated.
2022 */
2023        (device))
2024 {
2025   Lisp_Object devcons, concons;
2026   struct frame *f;
2027   Lisp_Object value;
2028
2029   value = Qnil;
2030
2031   DEVICE_LOOP_NO_BREAK (devcons, concons)
2032     {
2033       assert (DEVICEP (XCAR (devcons)));
2034
2035       if (NILP (device) || EQ (device, XCAR (devcons)))
2036         {
2037           Lisp_Object frmcons;
2038
2039           DEVICE_FRAME_LOOP (frmcons, XDEVICE (XCAR (devcons)))
2040             {
2041               Lisp_Object frame = XCAR (frmcons);
2042               f = XFRAME (frame);
2043               if (FRAME_VISIBLE_P(f))
2044                 value = Fcons (frame, value);
2045             }
2046         }
2047     }
2048
2049   return value;
2050 }
2051
2052 \f
2053 DEFUN ("raise-frame", Fraise_frame, 0, 1, "", /*
2054 Bring FRAME to the front, so it occludes any frames it overlaps.
2055 If omitted, FRAME defaults to the currently selected frame.
2056 If FRAME is invisible, make it visible.
2057 If Emacs is displaying on an ordinary terminal or some other device which
2058 doesn't support multiple overlapping frames, this function does nothing.
2059 */
2060        (frame))
2061 {
2062   struct frame *f = decode_frame (frame);
2063
2064   /* Do like the documentation says. */
2065   Fmake_frame_visible (frame);
2066   MAYBE_FRAMEMETH (f, raise_frame, (f));
2067   return Qnil;
2068 }
2069
2070 DEFUN ("lower-frame", Flower_frame, 0, 1, "", /*
2071 Send FRAME to the back, so it is occluded by any frames that overlap it.
2072 If omitted, FRAME defaults to the currently selected frame.
2073 If Emacs is displaying on an ordinary terminal or some other device which
2074 doesn't support multiple overlapping frames, this function does nothing.
2075 */
2076        (frame))
2077 {
2078   struct frame *f = decode_frame (frame);
2079
2080   MAYBE_FRAMEMETH (f, lower_frame, (f));
2081   return Qnil;
2082 }
2083
2084 /* Ben thinks there is no need for `redirect-frame-focus' or `frame-focus',
2085    crockish FSFmacs functions.  See summary on focus in event-stream.c. */
2086
2087 \f
2088 /***************************************************************************/
2089 /*                           frame properties                              */
2090 /***************************************************************************/
2091
2092 static void internal_set_frame_size (struct frame *f, int cols, int rows,
2093                                      int pretend);
2094
2095 static void
2096 store_minibuf_frame_prop (struct frame *f, Lisp_Object val)
2097 {
2098   Lisp_Object frame;
2099   XSETFRAME (frame, f);
2100
2101   if (WINDOWP (val))
2102     {
2103       if (! MINI_WINDOW_P (XWINDOW (val)))
2104         signal_simple_error
2105           ("Surrogate minibuffer windows must be minibuffer windows",
2106            val);
2107
2108       if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2109         signal_simple_error
2110           ("Can't change the surrogate minibuffer of a frame with its own minibuffer", frame);
2111
2112       /* Install the chosen minibuffer window, with proper buffer.  */
2113       f->minibuffer_window = val;
2114     }
2115   else if (EQ (val, Qt))
2116     {
2117       if (FRAME_HAS_MINIBUF_P (f) || FRAME_MINIBUF_ONLY_P (f))
2118         signal_simple_error
2119           ("Frame already has its own minibuffer", frame);
2120       else
2121         {
2122           setup_normal_frame (f);
2123           f->mirror_dirty = 1;
2124
2125           update_frame_window_mirror (f);
2126           internal_set_frame_size (f, f->width, f->height, 1);
2127         }
2128     }
2129 }
2130
2131 #if 0
2132
2133 /* possible code if you want to have symbols such as `default-background'
2134    map to setting the background of `default', etc. */
2135
2136 static int
2137 dissect_as_face_setting (Lisp_Object sym, Lisp_Object *face_out,
2138                          Lisp_Object *face_prop_out)
2139 {
2140   Lisp_Object list = Vbuilt_in_face_specifiers;
2141   struct Lisp_String *s;
2142
2143   if (!SYMBOLP (sym))
2144     return 0;
2145
2146   s = symbol_name (XSYMBOL (sym));
2147
2148   while (!NILP (list))
2149     {
2150       Lisp_Object prop = Fcar (list);
2151       struct Lisp_String *prop_name;
2152
2153       if (!SYMBOLP (prop))
2154         continue;
2155       prop_name = symbol_name (XSYMBOL (prop));
2156       if (string_length (s) > string_length (prop_name) + 1
2157           && !memcmp (string_data (prop_name),
2158                       string_data (s) + string_length (s)
2159                       - string_length (prop_name),
2160                       string_length (prop_name))
2161           && string_data (s)[string_length (s) - string_length (prop_name)
2162                              - 1] == '-')
2163         {
2164           Lisp_Object face =
2165             Ffind_face (make_string (string_data (s),
2166                                      string_length (s)
2167                                      - string_length (prop_name)
2168                                      - 1));
2169           if (!NILP (face))
2170             {
2171               *face_out = face;
2172               *face_prop_out = prop;
2173               return 1;
2174             }
2175         }
2176
2177       list = Fcdr (list);
2178     }
2179
2180   return 0;
2181 }
2182
2183 #endif /* 0 */
2184
2185 static Lisp_Object
2186 get_property_alias (Lisp_Object prop)
2187 {
2188   while (1)
2189     {
2190       Lisp_Object alias = Qnil;
2191
2192       if (SYMBOLP (prop))
2193         alias = Fget (prop, Qframe_property_alias, Qnil);
2194       if (NILP (alias))
2195         break;
2196       prop = alias;
2197       QUIT;
2198     }
2199
2200   return prop;
2201 }
2202
2203 /* #### Using this to modify the internal border width has no effect
2204    because the change isn't propagated to the windows.  Are there
2205    other properties which this claims to handle, but doesn't?
2206
2207    But of course.  This stuff needs more work, but it's a lot closer
2208    to sanity now than before with the horrible frame-params stuff. */
2209
2210 DEFUN ("set-frame-properties", Fset_frame_properties, 2, 2, 0, /*
2211 Change some properties of a frame.
2212 PLIST is a property list.
2213 You can also change frame properties individually using `set-frame-property',
2214 but it may be more efficient to change many properties at once.
2215
2216 Frame properties can be retrieved using `frame-property' or `frame-properties'.
2217
2218 The following symbols etc. have predefined meanings:
2219
2220  name           Name of the frame.  Used with X resources.
2221                 Unchangeable after creation.
2222
2223  height         Height of the frame, in lines.
2224
2225  width          Width of the frame, in characters.
2226
2227  minibuffer     Gives the minibuffer behavior for this frame.  Either
2228                 t (frame has its own minibuffer), `only' (frame is
2229                 a minibuffer-only frame), or a window (frame uses that
2230                 window, which is on another frame, as the minibuffer).
2231
2232  unsplittable   If non-nil, frame cannot be split by `display-buffer'.
2233
2234  current-display-table, menubar-visible-p, left-margin-width,
2235  right-margin-width, minimum-line-ascent, minimum-line-descent,
2236  use-left-overflow, use-right-overflow, scrollbar-width, scrollbar-height,
2237  default-toolbar, top-toolbar, bottom-toolbar, left-toolbar, right-toolbar,
2238  default-toolbar-height, default-toolbar-width, top-toolbar-height,
2239  bottom-toolbar-height, left-toolbar-width, right-toolbar-width,
2240  default-toolbar-visible-p, top-toolbar-visible-p, bottom-toolbar-visible-p,
2241  left-toolbar-visible-p, right-toolbar-visible-p, toolbar-buttons-captioned-p,
2242  top-toolbar-border-width, bottom-toolbar-border-width,
2243  left-toolbar-border-width, right-toolbar-border-width,
2244  modeline-shadow-thickness, has-modeline-p
2245                 [Giving the name of any built-in specifier variable is
2246                 equivalent to calling `set-specifier' on the specifier,
2247                 with a locale of FRAME.  Giving the name to `frame-property'
2248                 calls `specifier-instance' on the specifier.]
2249
2250  text-pointer-glyph, nontext-pointer-glyph, modeline-pointer-glyph,
2251  selection-pointer-glyph, busy-pointer-glyph, toolbar-pointer-glyph,
2252  menubar-pointer-glyph, scrollbar-pointer-glyph, gc-pointer-glyph,
2253  octal-escape-glyph, control-arrow-glyph, invisible-text-glyph,
2254  hscroll-glyph, truncation-glyph, continuation-glyph
2255                 [Giving the name of any glyph variable is equivalent to
2256                 calling `set-glyph-image' on the glyph, with a locale
2257                 of FRAME.  Giving the name to `frame-property' calls
2258                 `glyph-image-instance' on the glyph.]
2259
2260  [default foreground], [default background], [default font],
2261  [modeline foreground], [modeline background], [modeline font],
2262  etc.
2263                 [Giving a vector of a face and a property is equivalent
2264                 to calling `set-face-property' on the face and property,
2265                 with a locale of FRAME.  Giving the vector to
2266                 `frame-property' calls `face-property-instance' on the
2267                 face and property.]
2268
2269 Finally, if a frame property symbol has the property `frame-property-alias'
2270 on it, then the value will be used in place of that symbol when looking
2271 up and setting frame property values.  This allows you to alias one
2272 frame property name to another.
2273
2274 See the variables `default-x-frame-plist', `default-tty-frame-plist'
2275 and `default-mswindows-frame-plist' for a description of the properties
2276 recognized for particular types of frames.
2277 */
2278        (frame, plist))
2279 {
2280   struct frame *f = decode_frame (frame);
2281   Lisp_Object tail;
2282   Lisp_Object *tailp;
2283   struct gcpro gcpro1, gcpro2;
2284
2285   XSETFRAME (frame, f);
2286   GCPRO2 (frame, plist);
2287   Fcheck_valid_plist (plist);
2288   plist = Fcopy_sequence (plist);
2289   Fcanonicalize_lax_plist (plist, Qnil);
2290   for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
2291     {
2292       Lisp_Object prop = Fcar (tail);
2293       Lisp_Object val = Fcar (Fcdr (tail));
2294
2295       prop = get_property_alias (prop);
2296
2297 #if 0
2298       /* mly wants this, but it's not reasonable to change the name of a
2299          frame after it has been created, because the old name was used
2300          for resource lookup. */
2301       if (EQ (prop, Qname))
2302         {
2303           CHECK_STRING (val);
2304           f->name = val;
2305         }
2306 #endif /* 0 */
2307       if (EQ (prop, Qminibuffer))
2308         store_minibuf_frame_prop (f, val);
2309       if (EQ (prop, Qunsplittable))
2310         f->no_split = !NILP (val);
2311       if (EQ (prop, Qbuffer_predicate))
2312         f->buffer_predicate = val;
2313       if (SYMBOLP (prop) && EQ (Fbuilt_in_variable_type (prop),
2314                                 Qconst_specifier))
2315         call3 (Qset_specifier, Fsymbol_value (prop), val, frame);
2316       if (SYMBOLP (prop) && !NILP (Fget (prop, Qconst_glyph_variable, Qnil)))
2317         call3 (Qset_glyph_image, Fsymbol_value (prop), val, frame);
2318       if (VECTORP (prop) && XVECTOR_LENGTH (prop) == 2)
2319         {
2320           Lisp_Object face_prop = XVECTOR_DATA (prop)[1];
2321           CHECK_SYMBOL (face_prop);
2322           call4 (Qset_face_property,
2323                  Fget_face (XVECTOR_DATA (prop)[0]),
2324                  face_prop, val, frame);
2325         }
2326     }
2327
2328   MAYBE_FRAMEMETH (f, set_frame_properties, (f, plist));
2329   for (tailp = &plist; !NILP (*tailp);)
2330     {
2331       Lisp_Object *next_tailp;
2332       Lisp_Object next;
2333       Lisp_Object prop;
2334
2335       next = Fcdr (*tailp);
2336       CHECK_CONS (next);
2337       next_tailp = &XCDR (next);
2338       prop = Fcar (*tailp);
2339
2340       prop = get_property_alias (prop);
2341
2342       if (EQ (prop, Qminibuffer)
2343           || EQ (prop, Qunsplittable)
2344           || EQ (prop, Qbuffer_predicate)
2345           || EQ (prop, Qheight)
2346           || EQ (prop, Qwidth)
2347           || (SYMBOLP (prop) && EQ (Fbuilt_in_variable_type (prop),
2348                                     Qconst_specifier))
2349           || (SYMBOLP (prop) && !NILP (Fget (prop, Qconst_glyph_variable,
2350                                              Qnil)))
2351           || (VECTORP (prop) && XVECTOR_LENGTH (prop) == 2)
2352           || FRAMEMETH_OR_GIVEN (f, internal_frame_property_p, (f, prop), 0))
2353         *tailp = *next_tailp;
2354       tailp = next_tailp;
2355     }
2356
2357   f->plist = nconc2 (plist, f->plist);
2358   Fcanonicalize_lax_plist (f->plist, Qnil);
2359   UNGCPRO;
2360   return Qnil;
2361 }
2362
2363 DEFUN ("frame-property", Fframe_property, 2, 3, 0, /*
2364 Return FRAME's value for property PROPERTY.
2365 See `set-frame-properties' for the built-in property names.
2366 */
2367        (frame, property, default_))
2368 {
2369   struct frame *f = decode_frame (frame);
2370   Lisp_Object value;
2371
2372   XSETFRAME (frame, f);
2373
2374   property = get_property_alias (property);
2375
2376   if (EQ (Qname, property)) return f->name;
2377
2378   if (EQ (Qheight, property) || EQ (Qwidth, property))
2379     {
2380       if (window_system_pixelated_geometry (frame))
2381         {
2382           int width, height;
2383           pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2384                                    &width, &height);
2385           return make_int (EQ (Qheight, property) ? height: width);
2386         }
2387       else
2388         return make_int (EQ (Qheight, property) ?
2389                          FRAME_HEIGHT (f) :
2390                          FRAME_WIDTH  (f));
2391     }
2392
2393   /* NOTE: FSF returns Qnil instead of Qt for FRAME_HAS_MINIBUF_P.
2394      This is over-the-top bogosity, because it's inconsistent with
2395      the semantics of `minibuffer' when passed to `make-frame'.
2396      Returning Qt makes things consistent. */
2397   if (EQ (Qminibuffer, property))
2398     return (FRAME_MINIBUF_ONLY_P (f) ? Qonly :
2399             FRAME_HAS_MINIBUF_P  (f) ? Qt    :
2400             FRAME_MINIBUF_WINDOW (f));
2401   if (EQ (Qunsplittable, property))
2402     return FRAME_NO_SPLIT_P (f) ? Qt : Qnil;
2403   if (EQ (Qbuffer_predicate, property))
2404     return f->buffer_predicate;
2405
2406   if (SYMBOLP (property))
2407     {
2408       if (EQ (Fbuilt_in_variable_type (property), Qconst_specifier))
2409         return Fspecifier_instance (Fsymbol_value (property),
2410                                     frame, default_, Qnil);
2411       if (!NILP (Fget (property, Qconst_glyph_variable, Qnil)))
2412         {
2413           Lisp_Object glyph = Fsymbol_value (property);
2414           CHECK_GLYPH (glyph);
2415           return Fspecifier_instance (XGLYPH_IMAGE (glyph),
2416                                       frame, default_, Qnil);
2417         }
2418     }
2419
2420   if (VECTORP (property) && XVECTOR_LENGTH (property) == 2)
2421     {
2422       Lisp_Object face_prop = XVECTOR_DATA (property)[1];
2423       CHECK_SYMBOL (face_prop);
2424       return call3 (Qface_property_instance,
2425                     Fget_face (XVECTOR_DATA (property)[0]),
2426                     face_prop, frame);
2427     }
2428
2429   if (HAS_FRAMEMETH_P (f, frame_property))
2430     if (!UNBOUNDP (value = FRAMEMETH (f, frame_property, (f, property))))
2431       return value;
2432
2433   if (!UNBOUNDP (value = external_plist_get (&f->plist, property, 1, ERROR_ME)))
2434     return value;
2435
2436   return default_;
2437 }
2438
2439 DEFUN ("frame-properties", Fframe_properties, 0, 1, 0, /*
2440 Return a property list of the properties of FRAME.
2441 Do not modify this list; use `set-frame-property' instead.
2442 */
2443        (frame))
2444 {
2445   struct frame *f = decode_frame (frame);
2446   Lisp_Object result = Qnil;
2447   struct gcpro gcpro1;
2448
2449   GCPRO1 (result);
2450
2451   XSETFRAME (frame, f);
2452
2453   /* #### for the moment (since old code uses `frame-parameters'),
2454      we call `copy-sequence' on f->plist.  That allows frame-parameters
2455      to destructively convert the plist into an alist, which is more
2456      efficient than doing it non-destructively.  At some point we
2457      should remove the call to copy-sequence. */
2458   result = Fcopy_sequence (f->plist);
2459
2460   /* #### should we be adding all the specifiers and glyphs?
2461      That would entail having a list of them all. */
2462   if (HAS_FRAMEMETH_P (f, frame_properties))
2463     result = nconc2 (FRAMEMETH (f, frame_properties, (f)), result);
2464
2465   if (!NILP (f->buffer_predicate))
2466     result = cons3 (Qbuffer_predicate, f->buffer_predicate, result);
2467
2468   if (FRAME_NO_SPLIT_P (f))
2469     result = cons3 (Qunsplittable, Qt, result);
2470
2471   /* NOTE: FSF returns Qnil instead of Qt for FRAME_HAS_MINIBUF_P.
2472      This is over-the-top bogosity, because it's inconsistent with
2473      the semantics of `minibuffer' when passed to `make-frame'.
2474      Returning Qt makes things consistent. */
2475   result = cons3 (Qminibuffer,
2476                   (FRAME_MINIBUF_ONLY_P (f) ? Qonly :
2477                    FRAME_HAS_MINIBUF_P  (f) ? Qt    :
2478                    FRAME_MINIBUF_WINDOW (f)),
2479                   result);
2480   {
2481     int width, height;
2482
2483     if (window_system_pixelated_geometry (frame))
2484       {
2485         pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2486                                  &width, &height);
2487       }
2488     else
2489       {
2490         height = FRAME_HEIGHT (f);
2491         width = FRAME_WIDTH (f);
2492       }
2493     result = cons3 (Qwidth , make_int (width),  result);
2494     result = cons3 (Qheight, make_int (height), result);
2495   }
2496
2497   result = cons3 (Qname, f->name, result);
2498
2499   UNGCPRO;
2500   return result;
2501 }
2502
2503 \f
2504 DEFUN ("frame-pixel-height", Fframe_pixel_height, 0, 1, 0, /*
2505 Return the height in pixels of FRAME.
2506 */
2507        (frame))
2508 {
2509   return make_int (decode_frame (frame)->pixheight);
2510 }
2511
2512 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /*
2513 Return the width in pixels of FRAME.
2514 */
2515        (frame))
2516 {
2517   return make_int (decode_frame (frame)->pixwidth);
2518 }
2519
2520 DEFUN ("frame-name", Fframe_name, 0, 1, 0, /*
2521 Return the name of FRAME (defaulting to the selected frame).
2522 This is not the same as the `title' of the frame.
2523 */
2524        (frame))
2525 {
2526   return decode_frame (frame)->name;
2527 }
2528
2529 DEFUN ("frame-modified-tick", Fframe_modified_tick, 0, 1, 0, /*
2530 Return FRAME's tick counter, incremented for each change to the frame.
2531 Each frame has a tick counter which is incremented each time the frame
2532 is resized, a window is resized, added, or deleted, a face is changed,
2533 `set-window-buffer' or `select-window' is called on a window in the
2534 frame, the window-start of a window in the frame has changed, or
2535 anything else interesting has happened.  It wraps around occasionally.
2536 No argument or nil as argument means use selected frame as FRAME.
2537 */
2538        (frame))
2539 {
2540   return make_int (decode_frame (frame)->modiff);
2541 }
2542
2543 static void
2544 internal_set_frame_size (struct frame *f, int cols, int rows, int pretend)
2545 {
2546   /* An explicit size change cancels any pending frame size adjustment */
2547   CLEAR_FRAME_SIZE_SLIPPED(f);
2548
2549   if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size))
2550     change_frame_size (f, rows, cols, 0);
2551   else
2552     FRAMEMETH (f, set_frame_size, (f, cols, rows));
2553 }
2554
2555 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /*
2556 Specify that the frame FRAME has LINES lines.
2557 Optional third arg non-nil means that redisplay should use LINES lines
2558 but that the idea of the actual height of the frame should not be changed.
2559 */
2560        (frame, rows, pretend))
2561 {
2562   struct frame *f = decode_frame (frame);
2563   int height, width;
2564   XSETFRAME (frame, f);
2565   CHECK_INT (rows);
2566
2567   if (window_system_pixelated_geometry (frame))
2568     {
2569       char_to_real_pixel_size (f, 0, XINT (rows), 0, &height);
2570       width = FRAME_PIXWIDTH (f);
2571     }
2572   else
2573     {
2574       height = XINT (rows);
2575       width = FRAME_WIDTH (f);
2576     }
2577
2578   internal_set_frame_size (f, width, height, !NILP (pretend));
2579   return frame;
2580 }
2581
2582 DEFUN ("set-frame-width", Fset_frame_width, 2, 3, 0, /*
2583 Specify that the frame FRAME has COLS columns.
2584 Optional third arg non-nil means that redisplay should use COLS columns
2585 but that the idea of the actual width of the frame should not be changed.
2586 */
2587        (frame, cols, pretend))
2588 {
2589   struct frame *f = decode_frame (frame);
2590   int width, height;
2591   XSETFRAME (frame, f);
2592   CHECK_INT (cols);
2593
2594   if (window_system_pixelated_geometry (frame))
2595     {
2596       char_to_real_pixel_size (f, XINT (cols), 0, &width, 0);
2597       height = FRAME_PIXHEIGHT (f);
2598     }
2599   else
2600     {
2601       width = XINT (cols);
2602       height = FRAME_HEIGHT (f);
2603     }
2604
2605   internal_set_frame_size (f, width, height, !NILP (pretend));
2606   return frame;
2607 }
2608
2609 DEFUN ("set-frame-size", Fset_frame_size, 3, 4, 0, /*
2610 Set the size of FRAME to COLS by ROWS.
2611 Optional fourth arg non-nil means that redisplay should use COLS by ROWS
2612 but that the idea of the actual size of the frame should not be changed.
2613 */
2614        (frame, cols, rows, pretend))
2615 {
2616   struct frame *f = decode_frame (frame);
2617   int height, width;
2618   XSETFRAME (frame, f);
2619   CHECK_INT (cols);
2620   CHECK_INT (rows);
2621
2622   if (window_system_pixelated_geometry (frame))
2623     char_to_real_pixel_size (f, XINT (cols), XINT (rows), &width, &height);
2624   else
2625     {
2626       height = XINT (rows);
2627       width = XINT (cols);
2628     }
2629
2630   internal_set_frame_size (f, width, height, !NILP (pretend));
2631   return frame;
2632 }
2633
2634 DEFUN ("set-frame-position", Fset_frame_position, 3, 3, 0, /*
2635 Set position of FRAME in pixels to XOFFSET by YOFFSET.
2636 This is actually the position of the upper left corner of the frame.
2637 Negative values for XOFFSET or YOFFSET are interpreted relative to
2638 the rightmost or bottommost possible position (that stays within the screen).
2639 */
2640        (frame, xoffset, yoffset))
2641 {
2642   struct frame *f = decode_frame (frame);
2643   CHECK_INT (xoffset);
2644   CHECK_INT (yoffset);
2645
2646   MAYBE_FRAMEMETH (f, set_frame_position, (f, XINT (xoffset), XINT (yoffset)));
2647
2648   return Qt;
2649 }
2650
2651 \f
2652
2653 /* Frame size conversion functions moved here from EmacsFrame.c
2654    because they're generic and really don't belong in that file.
2655    Function get_default_char_pixel_size() removed because it's
2656    exactly the same as default_face_height_and_width(). */
2657 static void
2658 frame_conversion_internal (struct frame *f, int pixel_to_char,
2659                            int *pixel_width, int *pixel_height,
2660                            int *char_width, int *char_height,
2661                            int real_face)
2662 {
2663   int cpw;
2664   int cph;
2665   int egw;
2666   int obw, obh, bdr;
2667   Lisp_Object frame, window;
2668
2669   XSETFRAME (frame, f);
2670   if (real_face)
2671     default_face_height_and_width (frame, &cph, &cpw);
2672   else
2673     default_face_height_and_width_1 (frame, &cph, &cpw);
2674
2675   window = FRAME_SELECTED_WINDOW (f);
2676
2677   egw = max (glyph_width (Vcontinuation_glyph, Vdefault_face, 0, window),
2678              glyph_width (Vtruncation_glyph, Vdefault_face, 0, window));
2679   egw = max (egw, cpw);
2680   bdr = 2 * f->internal_border_width;
2681   obw = FRAME_SCROLLBAR_WIDTH (f) + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f) +
2682     FRAME_THEORETICAL_RIGHT_TOOLBAR_WIDTH (f) +
2683     2 * FRAME_THEORETICAL_LEFT_TOOLBAR_BORDER_WIDTH (f) +
2684     2 * FRAME_THEORETICAL_RIGHT_TOOLBAR_BORDER_WIDTH (f);
2685   obh = FRAME_SCROLLBAR_HEIGHT (f) + FRAME_THEORETICAL_TOP_TOOLBAR_HEIGHT (f) +
2686     FRAME_THEORETICAL_BOTTOM_TOOLBAR_HEIGHT (f) +
2687     2 * FRAME_THEORETICAL_TOP_TOOLBAR_BORDER_WIDTH (f) +
2688     2 * FRAME_THEORETICAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f);
2689
2690   if (pixel_to_char)
2691     {
2692       if (char_width)
2693         *char_width = 1 + ((*pixel_width - egw) - bdr - obw) / cpw;
2694       if (char_height)
2695         *char_height = (*pixel_height - bdr - obh) / cph;
2696     }
2697   else
2698     {
2699       if (pixel_width)
2700         *pixel_width = (*char_width - 1) * cpw + egw + bdr + obw;
2701       if (pixel_height)
2702         *pixel_height = *char_height * cph + bdr + obh;
2703     }
2704 }
2705
2706 /* This takes the size in pixels of the text area, and returns the number
2707    of characters that will fit there, taking into account the internal
2708    border width, and the pixel width of the line terminator glyphs (which
2709    always count as one "character" wide, even if they are not the same size
2710    as the default character size of the default font).  The frame scrollbar
2711    width and left and right toolbar widths are also subtracted out of the
2712    available width.  The frame scrollbar height and top and bottom toolbar
2713    heights are subtracted out of the available height.
2714
2715    Therefore the result is not necessarily a multiple of anything in
2716    particular.  */
2717 void
2718 pixel_to_char_size (struct frame *f, int pixel_width, int pixel_height,
2719                     int *char_width, int *char_height)
2720 {
2721   frame_conversion_internal (f, 1, &pixel_width, &pixel_height, char_width,
2722                              char_height, 0);
2723 }
2724
2725 /* Given a character size, this returns the minimum number of pixels
2726    necessary to display that many characters, taking into account the
2727    internal border width, scrollbar height and width, toolbar heights and
2728    widths and the size of the line terminator glyphs (assuming the line
2729    terminators take up exactly one character position).
2730
2731    Therefore the result is not necessarily a multiple of anything in
2732    particular.  */
2733 void
2734 char_to_pixel_size (struct frame *f, int char_width, int char_height,
2735                     int *pixel_width, int *pixel_height)
2736 {
2737   frame_conversion_internal (f, 0, pixel_width, pixel_height, &char_width,
2738                              &char_height, 0);
2739 }
2740
2741 /* Given a pixel size, rounds DOWN to the smallest size in pixels necessary
2742    to display the same number of characters as are displayable now.
2743  */
2744 void
2745 round_size_to_char (struct frame *f, int in_width, int in_height,
2746                     int *out_width, int *out_height)
2747 {
2748   int char_width;
2749   int char_height;
2750   pixel_to_char_size (f, in_width, in_height, &char_width, &char_height);
2751   char_to_pixel_size (f, char_width, char_height, out_width, out_height);
2752 }
2753
2754 /* Versions of the above which always account for real font metrics.
2755  */
2756 void
2757 pixel_to_real_char_size (struct frame *f, int pixel_width, int pixel_height,
2758                          int *char_width, int *char_height)
2759 {
2760   frame_conversion_internal (f, 1, &pixel_width, &pixel_height, char_width,
2761                              char_height, 1);
2762 }
2763
2764 void
2765 char_to_real_pixel_size (struct frame *f, int char_width, int char_height,
2766                          int *pixel_width, int *pixel_height)
2767 {
2768   frame_conversion_internal (f, 0, pixel_width, pixel_height, &char_width,
2769                              &char_height, 1);
2770 }
2771
2772 void
2773 round_size_to_real_char (struct frame *f, int in_width, int in_height,
2774                          int *out_width, int *out_height)
2775 {
2776   int char_width;
2777   int char_height;
2778   pixel_to_real_char_size (f, in_width, in_height, &char_width, &char_height);
2779   char_to_real_pixel_size (f, char_width, char_height, out_width, out_height);
2780 }
2781
2782 /* Change the frame height and/or width.  Values may be given as zero to
2783    indicate no change is to take place. */
2784 static void
2785 change_frame_size_1 (struct frame *f, int newheight, int newwidth)
2786 {
2787   Lisp_Object frame;
2788   int new_pixheight, new_pixwidth;
2789   int font_height, real_font_height, font_width;
2790
2791   /* #### Chuck -- shouldn't we be checking to see if the frame
2792      is being "changed" to its existing size, and do nothing if so? */
2793   /* No, because it would hose toolbar updates.  The toolbar
2794      update code relies on this function to cause window `top' and
2795      `left' coordinates to be recomputed even though no frame size
2796      change occurs. --kyle */
2797   if (in_display)
2798     abort ();
2799
2800   XSETFRAME (frame, f);
2801
2802   default_face_height_and_width (frame, &real_font_height, 0);
2803   default_face_height_and_width_1 (frame, &font_height, &font_width);
2804
2805   /* This size-change overrides any pending one for this frame.  */
2806   FRAME_NEW_HEIGHT (f) = 0;
2807   FRAME_NEW_WIDTH (f) = 0;
2808
2809   new_pixheight = newheight * font_height;
2810   new_pixwidth = (newwidth - 1) * font_width;
2811
2812   /* #### dependency on FRAME_WIN_P should be removed. */
2813   if (FRAME_WIN_P (f))
2814     {
2815       new_pixheight += FRAME_SCROLLBAR_HEIGHT (f);
2816       new_pixwidth += FRAME_SCROLLBAR_WIDTH (f);
2817     }
2818
2819   /* when frame_conversion_internal() calculated the number of rows/cols
2820      in the frame, the theoretical toolbar sizes were subtracted out.
2821      The calculations below adjust for real toolbar height/width in
2822      frame, which may be different from frame spec, taking the above
2823      fact into account */
2824   new_pixheight +=
2825     + FRAME_THEORETICAL_TOP_TOOLBAR_HEIGHT (f)
2826     + 2 * FRAME_THEORETICAL_TOP_TOOLBAR_BORDER_WIDTH (f)
2827     - FRAME_REAL_TOP_TOOLBAR_HEIGHT (f)
2828     - 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f);
2829
2830   new_pixheight +=
2831     + FRAME_THEORETICAL_BOTTOM_TOOLBAR_HEIGHT (f)
2832     + 2 * FRAME_THEORETICAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f)
2833     - FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f)
2834     - 2 * FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f);
2835
2836   new_pixwidth +=
2837     + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f)
2838     + 2 * FRAME_THEORETICAL_LEFT_TOOLBAR_BORDER_WIDTH (f)
2839     - FRAME_REAL_LEFT_TOOLBAR_WIDTH (f)
2840     - 2 * FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH (f);
2841
2842   new_pixwidth +=
2843     + FRAME_THEORETICAL_RIGHT_TOOLBAR_WIDTH (f)
2844     + 2 * FRAME_THEORETICAL_RIGHT_TOOLBAR_BORDER_WIDTH (f)
2845     - FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f)
2846     - 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f);
2847
2848   /* Adjust the width for the end glyph which may be a different width
2849      than the default character width. */
2850   {
2851     int adjustment, trunc_width, cont_width;
2852
2853     trunc_width = glyph_width (Vtruncation_glyph, Vdefault_face, 0,
2854                                FRAME_SELECTED_WINDOW (f));
2855     cont_width = glyph_width (Vcontinuation_glyph, Vdefault_face, 0,
2856                               FRAME_SELECTED_WINDOW (f));
2857     adjustment = max (trunc_width, cont_width);
2858     adjustment = max (adjustment, font_width);
2859
2860     new_pixwidth += adjustment;
2861   }
2862
2863   /* If we don't have valid values, exit. */
2864   if (!new_pixheight && !new_pixwidth)
2865     return;
2866
2867   if (new_pixheight)
2868     {
2869       XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top = FRAME_TOP_BORDER_END (f);
2870
2871       if (FRAME_HAS_MINIBUF_P (f)
2872           && ! FRAME_MINIBUF_ONLY_P (f))
2873         /* Frame has both root and minibuffer.  */
2874         {
2875           /*
2876            * Leave the minibuffer height the same if the frame has
2877            * been initialized, and the minibuffer height is tall
2878            * enough to display at least one line of text in the default
2879            * font, and the old minibuffer height is a multiple of the
2880            * default font height.  This should cause the minibuffer
2881            * height to be recomputed on font changes but not for
2882            * other frame size changes, which seems reasonable.
2883            */
2884           int old_minibuf_height =
2885             XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
2886           int minibuf_height =
2887             f->init_finished && (old_minibuf_height % real_font_height) == 0 ?
2888             max(old_minibuf_height, real_font_height) :
2889             real_font_height;
2890           set_window_pixheight (FRAME_ROOT_WINDOW (f),
2891                                 /* - font_height for minibuffer */
2892                                 new_pixheight - minibuf_height, 0);
2893
2894           XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top =
2895             new_pixheight - minibuf_height + FRAME_TOP_BORDER_END (f);
2896
2897           set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0);
2898         }
2899       else
2900         /* Frame has just one top-level window.  */
2901         set_window_pixheight (FRAME_ROOT_WINDOW (f), new_pixheight, 0);
2902
2903       FRAME_HEIGHT (f) = newheight;
2904       if (FRAME_TTY_P (f))
2905         f->pixheight = newheight;
2906     }
2907
2908   if (new_pixwidth)
2909     {
2910       XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left = FRAME_LEFT_BORDER_END (f);
2911       set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0);
2912
2913       if (FRAME_HAS_MINIBUF_P (f))
2914         {
2915           XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left =
2916             FRAME_LEFT_BORDER_END (f);
2917           set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0);
2918         }
2919
2920       FRAME_WIDTH (f) = newwidth;
2921       if (FRAME_TTY_P (f))
2922         f->pixwidth = newwidth;
2923     }
2924
2925   if (window_system_pixelated_geometry (frame))
2926     pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2927                              &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
2928   else
2929     {
2930       FRAME_CHARWIDTH (f) = FRAME_WIDTH (f);
2931       FRAME_CHARHEIGHT (f) = FRAME_HEIGHT (f);
2932     }
2933
2934   MARK_FRAME_TOOLBARS_CHANGED (f);
2935   MARK_FRAME_CHANGED (f);
2936   f->echo_area_garbaged = 1;
2937 }
2938
2939 void
2940 change_frame_size (struct frame *f, int newheight, int newwidth, int delay)
2941 {
2942   /* sometimes we get passed a size that's too small (esp. when a
2943      client widget gets resized, since we have no control over this).
2944      So deal. */
2945   check_frame_size (f, &newheight, &newwidth);
2946
2947   if (delay || in_display || gc_in_progress)
2948     {
2949       MARK_FRAME_SIZE_CHANGED (f);
2950       f->new_width = newwidth;
2951       f->new_height = newheight;
2952       return;
2953     }
2954
2955   f->size_change_pending = 0;
2956   /* For TTY frames, it's like one, like all ...
2957      Can't have two TTY frames of different sizes on the same device. */
2958   if (FRAME_TTY_P (f))
2959     {
2960       Lisp_Object frmcons;
2961
2962       DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f)))
2963         change_frame_size_1 (XFRAME (XCAR (frmcons)), newheight, newwidth);
2964     }
2965   else
2966     change_frame_size_1 (f, newheight, newwidth);
2967 }
2968
2969 \f
2970 void
2971 update_frame_title (struct frame *f)
2972 {
2973   struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
2974   Lisp_Object title_format;
2975   Lisp_Object icon_format;
2976   Bufbyte *title;
2977
2978   /* We don't change the title for the minibuffer unless the frame
2979      only has a minibuffer. */
2980   if (MINI_WINDOW_P (w) && !FRAME_MINIBUF_ONLY_P (f))
2981     return;
2982
2983   /* And we don't want dead buffers to blow up on us. */
2984   if (!BUFFER_LIVE_P (XBUFFER (w->buffer)))
2985     return;
2986
2987   title = NULL;
2988   title_format = symbol_value_in_buffer (Qframe_title_format,      w->buffer);
2989   icon_format  = symbol_value_in_buffer (Qframe_icon_title_format, w->buffer);
2990
2991   if (HAS_FRAMEMETH_P (f, set_title_from_bufbyte))
2992     {
2993       title = generate_formatted_string (w, title_format, Qnil,
2994                                          DEFAULT_INDEX, CURRENT_DISP);
2995       FRAMEMETH (f, set_title_from_bufbyte, (f, title));
2996     }
2997
2998   if (HAS_FRAMEMETH_P (f, set_icon_name_from_bufbyte))
2999     {
3000       if (!EQ (icon_format, title_format) || !title)
3001         {
3002           if (title)
3003             xfree (title);
3004
3005           title = generate_formatted_string (w, icon_format, Qnil,
3006                                              DEFAULT_INDEX, CURRENT_DISP);
3007         }
3008       FRAMEMETH (f, set_icon_name_from_bufbyte, (f, title));
3009     }
3010
3011   if (title)
3012     xfree (title);
3013 }
3014
3015 \f
3016 DEFUN ("set-frame-pointer", Fset_frame_pointer, 2, 2, 0, /*
3017 Set the mouse pointer of FRAME to the given pointer image instance.
3018 You should not call this function directly.  Instead, set one of
3019 the variables `text-pointer-glyph', `nontext-pointer-glyph',
3020 `modeline-pointer-glyph', `selection-pointer-glyph',
3021 `busy-pointer-glyph', or `toolbar-pointer-glyph'.
3022 */
3023        (frame, image_instance))
3024 {
3025   struct frame *f = decode_frame (frame);
3026   CHECK_POINTER_IMAGE_INSTANCE (image_instance);
3027   if (!EQ (f->pointer, image_instance))
3028     {
3029       f->pointer = image_instance;
3030       MAYBE_FRAMEMETH (f, set_frame_pointer, (f));
3031     }
3032   return Qnil;
3033 }
3034
3035 \f
3036 void
3037 update_frame_icon (struct frame *f)
3038 {
3039   if (f->icon_changed || f->windows_changed)
3040     {
3041       Lisp_Object frame;
3042       Lisp_Object new_icon;
3043
3044       XSETFRAME (frame, f);
3045       new_icon = glyph_image_instance (Vframe_icon_glyph, frame,
3046                                        ERROR_ME_WARN, 0);
3047       if (!EQ (new_icon, f->icon))
3048         {
3049           f->icon = new_icon;
3050           MAYBE_FRAMEMETH (f, set_frame_icon, (f));
3051         }
3052     }
3053
3054   f->icon_changed = 0;
3055 }
3056
3057 static void
3058 icon_glyph_changed (Lisp_Object glyph, Lisp_Object property,
3059                     Lisp_Object locale)
3060 {
3061   MARK_ICON_CHANGED;
3062 }
3063
3064 \f
3065 void
3066 syms_of_frame (void)
3067 {
3068   defsymbol (&Qdelete_frame_hook, "delete-frame-hook");
3069   defsymbol (&Qselect_frame_hook, "select-frame-hook");
3070   defsymbol (&Qdeselect_frame_hook, "deselect-frame-hook");
3071   defsymbol (&Qcreate_frame_hook, "create-frame-hook");
3072   defsymbol (&Qcustom_initialize_frame, "custom-initialize-frame");
3073   defsymbol (&Qmouse_enter_frame_hook, "mouse-enter-frame-hook");
3074   defsymbol (&Qmouse_leave_frame_hook, "mouse-leave-frame-hook");
3075   defsymbol (&Qmap_frame_hook, "map-frame-hook");
3076   defsymbol (&Qunmap_frame_hook, "unmap-frame-hook");
3077
3078   defsymbol (&Qframep, "framep");
3079   defsymbol (&Qframe_live_p, "frame-live-p");
3080   defsymbol (&Qdelete_frame, "delete-frame");
3081   defsymbol (&Qsynchronize_minibuffers, "synchronize-minibuffers");
3082   defsymbol (&Qbuffer_predicate, "buffer-predicate");
3083   defsymbol (&Qframe_being_created, "frame-being-created");
3084   defsymbol (&Qmake_initial_minibuffer_frame, "make-initial-minibuffer-frame");
3085
3086   defsymbol (&Qframe_title_format, "frame-title-format");
3087   defsymbol (&Qframe_icon_title_format, "frame-icon-title-format");
3088
3089   defsymbol (&Qhidden, "hidden");
3090   defsymbol (&Qvisible, "visible");
3091   defsymbol (&Qiconic, "iconic");
3092   defsymbol (&Qinvisible, "invisible");
3093   defsymbol (&Qvisible_iconic, "visible-iconic");
3094   defsymbol (&Qinvisible_iconic, "invisible-iconic");
3095   defsymbol (&Qnomini, "nomini");
3096   defsymbol (&Qvisible_nomini, "visible-nomini");
3097   defsymbol (&Qiconic_nomini, "iconic-nomini");
3098   defsymbol (&Qinvisible_nomini, "invisible-nomini");
3099   defsymbol (&Qvisible_iconic_nomini, "visible-iconic-nomini");
3100   defsymbol (&Qinvisible_iconic_nomini, "invisible-iconic-nomini");
3101
3102   defsymbol (&Qminibuffer, "minibuffer");
3103   defsymbol (&Qunsplittable, "unsplittable");
3104   defsymbol (&Qinternal_border_width, "internal-border-width");
3105   defsymbol (&Qtop_toolbar_shadow_color, "top-toolbar-shadow-color");
3106   defsymbol (&Qbottom_toolbar_shadow_color, "bottom-toolbar-shadow-color");
3107   defsymbol (&Qbackground_toolbar_color, "background-toolbar-color");
3108   defsymbol (&Qtop_toolbar_shadow_pixmap, "top-toolbar-shadow-pixmap");
3109   defsymbol (&Qbottom_toolbar_shadow_pixmap, "bottom-toolbar-shadow-pixmap");
3110   defsymbol (&Qtoolbar_shadow_thickness, "toolbar-shadow-thickness");
3111   defsymbol (&Qscrollbar_placement, "scrollbar-placement");
3112   defsymbol (&Qinter_line_space, "inter-line-space");
3113   /* Qiconic already in this function. */
3114   defsymbol (&Qvisual_bell, "visual-bell");
3115   defsymbol (&Qbell_volume, "bell-volume");
3116   defsymbol (&Qpointer_background, "pointer-background");
3117   defsymbol (&Qpointer_color, "pointer-color");
3118   defsymbol (&Qtext_pointer, "text-pointer");
3119   defsymbol (&Qspace_pointer, "space-pointer");
3120   defsymbol (&Qmodeline_pointer, "modeline-pointer");
3121   defsymbol (&Qgc_pointer, "gc-pointer");
3122   defsymbol (&Qinitially_unmapped, "initially-unmapped");
3123   defsymbol (&Quse_backing_store, "use-backing-store");
3124   defsymbol (&Qborder_color, "border-color");
3125   defsymbol (&Qborder_width, "border-width");
3126   /* Qwidth, Qheight, Qleft, Qtop in general.c */
3127   defsymbol (&Qset_specifier, "set-specifier");
3128   defsymbol (&Qset_glyph_image, "set-glyph-image");
3129   defsymbol (&Qset_face_property, "set-face-property");
3130   defsymbol (&Qface_property_instance, "face-property-instance");
3131   defsymbol (&Qframe_property_alias, "frame-property-alias");
3132
3133   DEFSUBR (Fmake_frame);
3134   DEFSUBR (Fframep);
3135   DEFSUBR (Fframe_live_p);
3136 #if 0 /* FSFmacs */
3137   DEFSUBR (Fignore_event);
3138 #endif
3139   DEFSUBR (Ffocus_frame);
3140   DEFSUBR (Fselect_frame);
3141   DEFSUBR (Fselected_frame);
3142   DEFSUBR (Factive_minibuffer_window);
3143   DEFSUBR (Flast_nonminibuf_frame);
3144   DEFSUBR (Fframe_root_window);
3145   DEFSUBR (Fframe_selected_window);
3146   DEFSUBR (Fset_frame_selected_window);
3147   DEFSUBR (Fframe_device);
3148   DEFSUBR (Fnext_frame);
3149   DEFSUBR (Fprevious_frame);
3150   DEFSUBR (Fdelete_frame);
3151   DEFSUBR (Fmouse_position);
3152   DEFSUBR (Fmouse_pixel_position);
3153   DEFSUBR (Fmouse_position_as_motion_event);
3154   DEFSUBR (Fset_mouse_position);
3155   DEFSUBR (Fset_mouse_pixel_position);
3156   DEFSUBR (Fmake_frame_visible);
3157   DEFSUBR (Fmake_frame_invisible);
3158   DEFSUBR (Ficonify_frame);
3159   DEFSUBR (Fdeiconify_frame);
3160   DEFSUBR (Fframe_visible_p);
3161   DEFSUBR (Fframe_totally_visible_p);
3162   DEFSUBR (Fframe_iconified_p);
3163   DEFSUBR (Fvisible_frame_list);
3164   DEFSUBR (Fraise_frame);
3165   DEFSUBR (Flower_frame);
3166   DEFSUBR (Fframe_property);
3167   DEFSUBR (Fframe_properties);
3168   DEFSUBR (Fset_frame_properties);
3169   DEFSUBR (Fframe_pixel_height);
3170   DEFSUBR (Fframe_pixel_width);
3171   DEFSUBR (Fframe_name);
3172   DEFSUBR (Fframe_modified_tick);
3173   DEFSUBR (Fset_frame_height);
3174   DEFSUBR (Fset_frame_width);
3175   DEFSUBR (Fset_frame_size);
3176   DEFSUBR (Fset_frame_position);
3177   DEFSUBR (Fset_frame_pointer);
3178 }
3179
3180 void
3181 vars_of_frame (void)
3182 {
3183   /* */
3184   Vframe_being_created = Qnil;
3185   staticpro (&Vframe_being_created);
3186
3187 #ifdef HAVE_CDE
3188   Fprovide (intern ("cde"));
3189 #endif
3190
3191 #ifdef HAVE_OFFIX_DND
3192   Fprovide (intern ("offix"));
3193 #endif
3194
3195 #if 0 /* FSFmacs stupidity */
3196   xxDEFVAR_LISP ("emacs-iconified", &Vemacs_iconified /*
3197 Non-nil if all of emacs is iconified and frame updates are not needed.
3198 */ );
3199   Vemacs_iconified = Qnil;
3200 #endif
3201
3202   DEFVAR_LISP ("select-frame-hook", &Vselect_frame_hook /*
3203 Function or functions to run just after a new frame is given the focus.
3204 Note that calling `select-frame' does not necessarily set the focus:
3205 The actual window-system focus will not be changed until the next time
3206 that XEmacs is waiting for an event, and even then, the window manager
3207 may refuse the focus-change request.
3208 */ );
3209   Vselect_frame_hook = Qnil;
3210
3211   DEFVAR_LISP ("deselect-frame-hook", &Vdeselect_frame_hook /*
3212 Function or functions to run just before a frame loses the focus.
3213 See `select-frame-hook'.
3214 */ );
3215   Vdeselect_frame_hook = Qnil;
3216
3217   DEFVAR_LISP ("delete-frame-hook", &Vdelete_frame_hook /*
3218 Function or functions to call when a frame is deleted.
3219 One argument, the about-to-be-deleted frame.
3220 */ );
3221   Vdelete_frame_hook = Qnil;
3222
3223   DEFVAR_LISP ("create-frame-hook", &Vcreate_frame_hook /*
3224 Function or functions to call when a frame is created.
3225 One argument, the newly-created frame.
3226 */ );
3227   Vcreate_frame_hook = Qnil;
3228
3229   DEFVAR_LISP ("mouse-enter-frame-hook", &Vmouse_enter_frame_hook /*
3230 Function or functions to call when the mouse enters a frame.
3231 One argument, the frame.
3232 Be careful not to make assumptions about the window manager's focus model.
3233 In most cases, the `deselect-frame-hook' is more appropriate.
3234 */ );
3235   Vmouse_enter_frame_hook = Qnil;
3236
3237   DEFVAR_LISP ("mouse-leave-frame-hook", &Vmouse_leave_frame_hook /*
3238 Function or functions to call when the mouse leaves a frame.
3239 One argument, the frame.
3240 Be careful not to make assumptions about the window manager's focus model.
3241 In most cases, the `select-frame-hook' is more appropriate.
3242 */ );
3243   Vmouse_leave_frame_hook = Qnil;
3244
3245   DEFVAR_LISP ("map-frame-hook", &Vmap_frame_hook /*
3246 Function or functions to call when a frame is mapped.
3247 One argument, the frame.
3248 */ );
3249   Vmap_frame_hook = Qnil;
3250
3251   DEFVAR_LISP ("unmap-frame-hook", &Vunmap_frame_hook /*
3252 Function or functions to call when a frame is unmapped.
3253 One argument, the frame.
3254 */ );
3255   Vunmap_frame_hook = Qnil;
3256
3257   DEFVAR_BOOL ("allow-deletion-of-last-visible-frame",
3258                &allow_deletion_of_last_visible_frame /*
3259 *Non-nil means to assume the force option to delete-frame.
3260 */ );
3261   allow_deletion_of_last_visible_frame = 0;
3262
3263   DEFVAR_LISP ("adjust-frame-function", &Vadjust_frame_function /*
3264 Function or constant controlling adjustment of frame.
3265 When scrollbars, toolbars, default font etc. change in frame, the frame
3266 needs to be adjusted. The adjustment is controlled by this variable.
3267 Legal values are:
3268   nil to keep character frame size unchanged when possible (resize)
3269   t   to keep pixel size unchanged (never resize)
3270   function symbol or lambda form. This function must return boolean
3271       value which is treated as above. Function is passed one parameter,
3272       the frame being adjusted. It function should not modify or delete
3273       the frame.
3274 */ );
3275   Vadjust_frame_function = Qnil;
3276
3277   DEFVAR_LISP ("mouse-motion-handler", &Vmouse_motion_handler /*
3278 Handler for motion events.  One arg, the event.
3279 For most applications, you should use `mode-motion-hook' instead of this.
3280 */ );
3281   Vmouse_motion_handler = Qnil;
3282
3283   DEFVAR_LISP ("synchronize-minibuffers",&Vsynchronize_minibuffers /*
3284 Set to t if all minibuffer windows are to be synchronized.
3285 This will cause echo area messages to appear in the minibuffers of all
3286 visible frames.
3287 */ );
3288   Vsynchronize_minibuffers = Qnil;
3289
3290   DEFVAR_LISP ("frame-title-format", &Vframe_title_format /*
3291 Controls the title of the X window corresponding to the selected frame.
3292 This is the same format as `modeline-format' with the exception that
3293 %- is ignored.
3294 */ );
3295   Vframe_title_format = build_string ("%S: %b");
3296
3297   DEFVAR_LISP ("frame-icon-title-format", &Vframe_icon_title_format /*
3298 Controls the title of the icon corresponding to the selected frame.
3299 See also the variable `frame-title-format'.
3300 */ );
3301   Vframe_icon_title_format = build_string ("%b");
3302
3303   DEFVAR_LISP ("default-frame-name", &Vdefault_frame_name /*
3304 The default name to assign to newly-created frames.
3305 This can be overridden by arguments to `make-frame'.
3306 This must be a string.
3307 */ );
3308 #ifndef INFODOCK
3309   Vdefault_frame_name = build_string ("emacs");
3310 #else
3311   Vdefault_frame_name = build_string ("InfoDock");
3312 #endif
3313
3314   DEFVAR_LISP ("default-frame-plist", &Vdefault_frame_plist /*
3315 Plist of default values for frame creation, other than the first one.
3316 These may be set in your init file, like this:
3317
3318   \(setq default-frame-plist '(width 80 height 55))
3319
3320 The properties may be in alist format for backward compatibility
3321 but you should not rely on this behavior.
3322
3323 These override values given in window system configuration data,
3324  including X Windows' defaults database.
3325
3326 Since the first X frame is created before loading your .emacs file,
3327 you must use the X resource database for that.
3328
3329 For values specific to the first Emacs frame, see `initial-frame-plist'.
3330 For values specific to the separate minibuffer frame, see
3331  `minibuffer-frame-plist'.
3332
3333 See also the variables `default-x-frame-plist' and
3334 `default-tty-frame-plist', which are like `default-frame-plist'
3335 except that they apply only to X or tty frames, respectively
3336 \(whereas `default-frame-plist' applies to all types of frames).
3337 */ );
3338   Vdefault_frame_plist = Qnil;
3339
3340   DEFVAR_LISP ("frame-icon-glyph", &Vframe_icon_glyph /*
3341 Icon glyph used to iconify a frame.
3342 */ );
3343 }
3344
3345 void
3346 complex_vars_of_frame (void)
3347 {
3348   Vframe_icon_glyph = allocate_glyph (GLYPH_ICON, icon_glyph_changed);
3349 }