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