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