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