/[emacs]/emacs/src/frame.c
ViewVC logotype

Diff of /emacs/src/frame.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.284 by akochoi, Fri Apr 26 23:39:05 2002 UTC revision 1.284.2.1 by miles, Fri Apr 4 06:20:58 2003 UTC
# Line 41  Boston, MA 02111-1307, USA.  */ Line 41  Boston, MA 02111-1307, USA.  */
41  #ifdef HAVE_WINDOW_SYSTEM  #ifdef HAVE_WINDOW_SYSTEM
42  #include "fontset.h"  #include "fontset.h"
43  #endif  #endif
44    #include "blockinput.h"
45  #include "termhooks.h"  #include "termhooks.h"
46  #include "dispextern.h"  #include "dispextern.h"
47  #include "window.h"  #include "window.h"
# Line 49  Boston, MA 02111-1307, USA.  */ Line 50  Boston, MA 02111-1307, USA.  */
50  #include "dosfns.h"  #include "dosfns.h"
51  #endif  #endif
52    
53  Lisp_Object Qframep;  
54  Lisp_Object Qframe_live_p;  #ifdef HAVE_WINDOW_SYSTEM
55  Lisp_Object Qheight;  
56  Lisp_Object Qicon;  /* The name we're using in resource queries.  Most often "emacs".  */
57  Lisp_Object Qminibuffer;  
58  Lisp_Object Qmodeline;  Lisp_Object Vx_resource_name;
59  Lisp_Object Qname;  
60    /* The application class we're using in resource queries.
61       Normally "Emacs".  */
62    
63    Lisp_Object Vx_resource_class;
64    
65    #endif
66    
67    Lisp_Object Qframep, Qframe_live_p;
68    Lisp_Object Qicon, Qmodeline;
69  Lisp_Object Qonly;  Lisp_Object Qonly;
70  Lisp_Object Qunsplittable;  Lisp_Object Qx, Qw32, Qmac, Qpc;
 Lisp_Object Qmenu_bar_lines;  
 Lisp_Object Qtool_bar_lines;  
 Lisp_Object Qwidth;  
 Lisp_Object Qx;  
 Lisp_Object Qw32;  
 Lisp_Object Qpc;  
 Lisp_Object Qmac;  
71  Lisp_Object Qvisible;  Lisp_Object Qvisible;
 Lisp_Object Qbuffer_predicate;  
 Lisp_Object Qbuffer_list;  
 Lisp_Object Qtitle;  
72  Lisp_Object Qdisplay_type;  Lisp_Object Qdisplay_type;
73  Lisp_Object Qbackground_mode;  Lisp_Object Qbackground_mode;
74  Lisp_Object Qinhibit_default_face_x_resources;  Lisp_Object Qinhibit_default_face_x_resources;
75  Lisp_Object Qleft_fringe;  
76  Lisp_Object Qright_fringe;  Lisp_Object Qx_frame_parameter;
77    Lisp_Object Qx_resource_name;
78    
79    /* Frame parameters (set or reported).  */
80    
81    Lisp_Object Qauto_raise, Qauto_lower;
82    Lisp_Object Qborder_color, Qborder_width;
83    Lisp_Object Qcursor_color, Qcursor_type;
84    Lisp_Object Qgeometry;  /* Not used */
85    Lisp_Object Qheight, Qwidth;
86    Lisp_Object Qleft, Qright;
87    Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
88    Lisp_Object Qinternal_border_width;
89    Lisp_Object Qmouse_color;
90    Lisp_Object Qminibuffer;
91    Lisp_Object Qscroll_bar_width, Qvertical_scroll_bars;
92    Lisp_Object Qvisibility;
93    Lisp_Object Qscroll_bar_foreground, Qscroll_bar_background;
94    Lisp_Object Qscreen_gamma;
95    Lisp_Object Qline_spacing;
96    Lisp_Object Quser_position, Quser_size;
97    Lisp_Object Qwait_for_wm;
98    Lisp_Object Qwindow_id;
99    #ifdef HAVE_X_WINDOWS
100    Lisp_Object Qouter_window_id;
101    #endif
102    Lisp_Object Qparent_id;
103    Lisp_Object Qtitle, Qname;
104    Lisp_Object Qunsplittable;
105    Lisp_Object Qmenu_bar_lines, Qtool_bar_lines;
106    Lisp_Object Qleft_fringe, Qright_fringe;
107    Lisp_Object Qbuffer_predicate, Qbuffer_list;
108  Lisp_Object Qtty_color_mode;  Lisp_Object Qtty_color_mode;
109    
110    Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
111    
112    Lisp_Object Qface_set_after_frame_default;
113    
114    
115  Lisp_Object Vterminal_frame;  Lisp_Object Vterminal_frame;
116  Lisp_Object Vdefault_frame_alist;  Lisp_Object Vdefault_frame_alist;
117  Lisp_Object Vmouse_position_function;  Lisp_Object Vmouse_position_function;
118  Lisp_Object Vmouse_highlight;  Lisp_Object Vmouse_highlight;
119    Lisp_Object Vdelete_frame_functions;
120    
121  static void  static void
122  set_menu_bar_lines_1 (window, n)  set_menu_bar_lines_1 (window, n)
# Line 91  set_menu_bar_lines_1 (window, n) Line 128  set_menu_bar_lines_1 (window, n)
128    XSETFASTINT (w->last_modified, 0);    XSETFASTINT (w->last_modified, 0);
129    XSETFASTINT (w->top, XFASTINT (w->top) + n);    XSETFASTINT (w->top, XFASTINT (w->top) + n);
130    XSETFASTINT (w->height, XFASTINT (w->height) - n);    XSETFASTINT (w->height, XFASTINT (w->height) - n);
131      
132    if (INTEGERP (w->orig_top))    if (INTEGERP (w->orig_top))
133      XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);      XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n);
134    if (INTEGERP (w->orig_height))    if (INTEGERP (w->orig_height))
# Line 293  make_frame (mini_p) Line 330  make_frame (mini_p)
330      buf = Fcurrent_buffer ();      buf = Fcurrent_buffer ();
331      /* If buf is a 'hidden' buffer (i.e. one whose name starts with      /* If buf is a 'hidden' buffer (i.e. one whose name starts with
332         a space), try to find another one.  */         a space), try to find another one.  */
333      if (XSTRING (Fbuffer_name (buf))->data[0] == ' ')      if (SREF (Fbuffer_name (buf), 0) == ' ')
334        buf = Fother_buffer (buf, Qnil, Qnil);        buf = Fother_buffer (buf, Qnil, Qnil);
335    
336      /* Use set_window_buffer, not Fset_window_buffer, and don't let      /* Use set_window_buffer, not Fset_window_buffer, and don't let
# Line 366  make_frame_without_minibuffer (mini_wind Line 403  make_frame_without_minibuffer (mini_wind
403              call1 (intern ("make-initial-minibuffer-frame"), display);              call1 (intern ("make-initial-minibuffer-frame"), display);
404            UNGCPRO;            UNGCPRO;
405          }          }
406      
407        mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;        mini_window = XFRAME (kb->Vdefault_minibuffer_frame)->minibuffer_window;
408      }      }
409    
# Line 490  make_terminal_frame () Line 527  make_terminal_frame ()
527    make_mac_terminal_frame (f);    make_mac_terminal_frame (f);
528  #else  #else
529    f->output_data.x = &tty_display;    f->output_data.x = &tty_display;
530    #ifdef CANNOT_DUMP
531      FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
532      FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
533    #endif
534  #endif /* MAC_OS8 */  #endif /* MAC_OS8 */
535  #endif /* WINDOWSNT */  #endif /* WINDOWSNT */
536  #endif /* MSDOS */  #endif /* MSDOS */
# Line 571  do_switch_frame (frame, track, for_delet Line 612  do_switch_frame (frame, track, for_delet
612       int track, for_deletion;       int track, for_deletion;
613  {  {
614    struct frame *sf = SELECTED_FRAME ();    struct frame *sf = SELECTED_FRAME ();
615      
616    /* If FRAME is a switch-frame event, extract the frame we should    /* If FRAME is a switch-frame event, extract the frame we should
617       switch to.  */       switch to.  */
618    if (CONSP (frame)    if (CONSP (frame)
# Line 769  If omitted, FRAME defaults to the curren Line 810  If omitted, FRAME defaults to the curren
810       Lisp_Object frame;       Lisp_Object frame;
811  {  {
812    Lisp_Object window;    Lisp_Object window;
813      
814    if (NILP (frame))    if (NILP (frame))
815      window = SELECTED_FRAME ()->root_window;      window = SELECTED_FRAME ()->root_window;
816    else    else
# Line 777  If omitted, FRAME defaults to the curren Line 818  If omitted, FRAME defaults to the curren
818        CHECK_LIVE_FRAME (frame);        CHECK_LIVE_FRAME (frame);
819        window = XFRAME (frame)->root_window;        window = XFRAME (frame)->root_window;
820      }      }
821      
822    return window;    return window;
823  }  }
824    
# Line 789  If omitted, FRAME defaults to the curren Line 830  If omitted, FRAME defaults to the curren
830       Lisp_Object frame;       Lisp_Object frame;
831  {  {
832    Lisp_Object window;    Lisp_Object window;
833      
834    if (NILP (frame))    if (NILP (frame))
835      window = SELECTED_FRAME ()->selected_window;      window = SELECTED_FRAME ()->selected_window;
836    else    else
# Line 811  If FRAME is the selected frame, this mak Line 852  If FRAME is the selected frame, this mak
852  {  {
853    if (NILP (frame))    if (NILP (frame))
854      frame = selected_frame;      frame = selected_frame;
855      
856    CHECK_LIVE_FRAME (frame);    CHECK_LIVE_FRAME (frame);
857    CHECK_LIVE_WINDOW (window);    CHECK_LIVE_WINDOW (window);
858    
# Line 1011  Otherwise, include all frames.  */) Line 1052  Otherwise, include all frames.  */)
1052  {  {
1053    if (NILP (frame))    if (NILP (frame))
1054      frame = selected_frame;      frame = selected_frame;
1055      
1056    CHECK_LIVE_FRAME (frame);    CHECK_LIVE_FRAME (frame);
1057    return next_frame (frame, miniframe);    return next_frame (frame, miniframe);
1058  }  }
# Line 1088  A frame may not be deleted if its minibu Line 1129  A frame may not be deleted if its minibu
1129  Normally, you may not delete a frame if all other frames are invisible,  Normally, you may not delete a frame if all other frames are invisible,
1130  but if the second optional argument FORCE is non-nil, you may do so.  but if the second optional argument FORCE is non-nil, you may do so.
1131    
1132  This function runs `delete-frame-hook' before actually deleting the  This function runs `delete-frame-functions' before actually deleting the
1133  frame.  The hook is called with one argument FRAME.  */)  frame, unless the frame is a tooltip.
1134    The functions are run with one arg, the frame to be deleted.  */)
1135       (frame, force)       (frame, force)
1136       Lisp_Object frame, force;       Lisp_Object frame, force;
1137  {  {
# Line 1115  frame.  The hook is called with one argu Line 1157  frame.  The hook is called with one argu
1157  #ifdef MAC_OS8  #ifdef MAC_OS8
1158        /* Terminal frame deleted before any other visible frames are        /* Terminal frame deleted before any other visible frames are
1159           created.  */           created.  */
1160        && strcmp (XSTRING (f->name)->data, "F1") != 0        && strcmp (SDATA (f->name), "F1") != 0
1161  #endif  #endif
1162       )       )
1163      error ("Attempt to delete the sole visible or iconified frame");      error ("Attempt to delete the sole visible or iconified frame");
# Line 1148  frame.  The hook is called with one argu Line 1190  frame.  The hook is called with one argu
1190          }          }
1191      }      }
1192    
1193    /* Run `delete-frame-hook'.  */    /* Run `delete-frame-functions' unless frame is a tooltip.  */
1194    if (!NILP (Vrun_hooks))    if (!NILP (Vrun_hooks)
1195          && NILP (Fframe_parameter (frame, intern ("tooltip"))))
1196      {      {
1197        Lisp_Object args[2];        Lisp_Object args[2];
1198        args[0] = intern ("delete-frame-hook");        args[0] = intern ("delete-frame-functions");
1199        args[1] = frame;        args[1] = frame;
1200        Frun_hook_with_args (2, args);        Frun_hook_with_args (2, args);
1201      }      }
# Line 1204  frame.  The hook is called with one argu Line 1247  frame.  The hook is called with one argu
1247      x_clear_frame_selections (f);      x_clear_frame_selections (f);
1248  #endif  #endif
1249    
1250    /* Free glyphs.    /* Free glyphs.
1251       This function must be called before the window tree of the       This function must be called before the window tree of the
1252       frame is deleted because windows contain dynamically allocated       frame is deleted because windows contain dynamically allocated
1253       memory. */       memory. */
1254    free_glyphs (f);    free_glyphs (f);
# Line 1585  If omitted, FRAME defaults to the curren Line 1628  If omitted, FRAME defaults to the curren
1628  {  {
1629    if (NILP (frame))    if (NILP (frame))
1630      frame = selected_frame;      frame = selected_frame;
1631      
1632    CHECK_LIVE_FRAME (frame);    CHECK_LIVE_FRAME (frame);
1633    
1634  #if 0 /* This isn't logically necessary, and it can do GC.  */  #if 0 /* This isn't logically necessary, and it can do GC.  */
# Line 1694  doesn't support multiple overlapping fra Line 1737  doesn't support multiple overlapping fra
1737      frame = selected_frame;      frame = selected_frame;
1738    
1739    CHECK_LIVE_FRAME (frame);    CHECK_LIVE_FRAME (frame);
1740      
1741    if (frame_raise_lower_hook)    if (frame_raise_lower_hook)
1742      (*frame_raise_lower_hook) (XFRAME (frame), 0);      (*frame_raise_lower_hook) (XFRAME (frame), 0);
1743    
# Line 1742  The redirection lasts until `redirect-fr Line 1785  The redirection lasts until `redirect-fr
1785    
1786    if (frame_rehighlight_hook)    if (frame_rehighlight_hook)
1787      (*frame_rehighlight_hook) (XFRAME (frame));      (*frame_rehighlight_hook) (XFRAME (frame));
1788      
1789    return Qnil;    return Qnil;
1790  }  }
1791    
# Line 1818  frames_discard_buffer (buffer) Line 1861  frames_discard_buffer (buffer)
1861      }      }
1862  }  }
1863    
 /* Move BUFFER to the end of the buffer-list of each frame.  */  
   
 void  
 frames_bury_buffer (buffer)  
      Lisp_Object buffer;  
 {  
   Lisp_Object frame, tail;  
   
   FOR_EACH_FRAME (tail, frame)  
     {  
       struct frame *f = XFRAME (frame);  
       Lisp_Object found;  
         
       found = Fmemq (buffer, f->buffer_list);  
       if (!NILP (found))  
         f->buffer_list = nconc2 (Fdelq (buffer, f->buffer_list),  
                                  Fcons (buffer, Qnil));  
     }  
 }  
   
1864  /* Modify the alist in *ALISTPTR to associate PROP with VAL.  /* Modify the alist in *ALISTPTR to associate PROP with VAL.
1865     If the alist already has an element for PROP, we change it.  */     If the alist already has an element for PROP, we change it.  */
1866    
# Line 1889  set_term_frame_name (f, name) Line 1912  set_term_frame_name (f, name)
1912    
1913        /* Check for no change needed in this very common case        /* Check for no change needed in this very common case
1914           before we do any consing.  */           before we do any consing.  */
1915        if (frame_name_fnn_p (XSTRING (f->name)->data,        if (frame_name_fnn_p (SDATA (f->name),
1916                              STRING_BYTES (XSTRING (f->name))))                              SBYTES (f->name)))
1917          return;          return;
1918    
1919        terminal_frame_count++;        terminal_frame_count++;
# Line 1907  set_term_frame_name (f, name) Line 1930  set_term_frame_name (f, name)
1930    
1931        /* Don't allow the user to set the frame name to F<num>, so it        /* Don't allow the user to set the frame name to F<num>, so it
1932           doesn't clash with the names we generate for terminal frames.  */           doesn't clash with the names we generate for terminal frames.  */
1933        if (frame_name_fnn_p (XSTRING (name)->data, STRING_BYTES (XSTRING (name))))        if (frame_name_fnn_p (SDATA (name), SBYTES (name)))
1934          error ("Frame names of the form F<num> are usurped by Emacs");          error ("Frame names of the form F<num> are usurped by Emacs");
1935      }      }
1936    
# Line 1962  store_frame_param (f, prop, val) Line 1985  store_frame_param (f, prop, val)
1985    
1986    /* Update some other special parameters in their special places    /* Update some other special parameters in their special places
1987       in addition to the alist.  */       in addition to the alist.  */
1988      
1989    if (EQ (prop, Qbuffer_predicate))    if (EQ (prop, Qbuffer_predicate))
1990      f->buffer_predicate = val;      f->buffer_predicate = val;
1991    
# Line 2012  If FRAME is omitted, return information Line 2035  If FRAME is omitted, return information
2035    
2036    alist = Fcopy_alist (f->param_alist);    alist = Fcopy_alist (f->param_alist);
2037    GCPRO1 (alist);    GCPRO1 (alist);
2038      
2039    if (!FRAME_WINDOW_P (f))    if (!FRAME_WINDOW_P (f))
2040      {      {
2041        int fg = FRAME_FOREGROUND_PIXEL (f);        int fg = FRAME_FOREGROUND_PIXEL (f);
# Line 2025  If FRAME is omitted, return information Line 2048  If FRAME is omitted, return information
2048        elt = Fassq (Qforeground_color, alist);        elt = Fassq (Qforeground_color, alist);
2049        if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))        if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2050          {          {
2051            if (strncmp (XSTRING (XCDR (elt))->data,            if (strncmp (SDATA (XCDR (elt)),
2052                         unspecified_bg,                         unspecified_bg,
2053                         XSTRING (XCDR (elt))->size) == 0)                         SCHARS (XCDR (elt))) == 0)
2054              store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));              store_in_alist (&alist, Qforeground_color, tty_color_name (f, bg));
2055            else if (strncmp (XSTRING (XCDR (elt))->data,            else if (strncmp (SDATA (XCDR (elt)),
2056                              unspecified_fg,                              unspecified_fg,
2057                              XSTRING (XCDR (elt))->size) == 0)                              SCHARS (XCDR (elt))) == 0)
2058              store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));              store_in_alist (&alist, Qforeground_color, tty_color_name (f, fg));
2059          }          }
2060        else        else
# Line 2039  If FRAME is omitted, return information Line 2062  If FRAME is omitted, return information
2062        elt = Fassq (Qbackground_color, alist);        elt = Fassq (Qbackground_color, alist);
2063        if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))        if (!NILP (elt) && CONSP (elt) && STRINGP (XCDR (elt)))
2064          {          {
2065            if (strncmp (XSTRING (XCDR (elt))->data,            if (strncmp (SDATA (XCDR (elt)),
2066                         unspecified_fg,                         unspecified_fg,
2067                         XSTRING (XCDR (elt))->size) == 0)                         SCHARS (XCDR (elt))) == 0)
2068              store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));              store_in_alist (&alist, Qbackground_color, tty_color_name (f, fg));
2069            else if (strncmp (XSTRING (XCDR (elt))->data,            else if (strncmp (SDATA (XCDR (elt)),
2070                              unspecified_bg,                              unspecified_bg,
2071                              XSTRING (XCDR (elt))->size) == 0)                              SCHARS (XCDR (elt))) == 0)
2072              store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));              store_in_alist (&alist, Qbackground_color, tty_color_name (f, bg));
2073          }          }
2074        else        else
# Line 2101  If FRAME is nil, describe the currently Line 2124  If FRAME is nil, describe the currently
2124    else    else
2125      CHECK_FRAME (frame);      CHECK_FRAME (frame);
2126    CHECK_SYMBOL (parameter);    CHECK_SYMBOL (parameter);
2127      
2128    f = XFRAME (frame);    f = XFRAME (frame);
2129    value = Qnil;    value = Qnil;
2130      
2131    if (FRAME_LIVE_P (f))    if (FRAME_LIVE_P (f))
2132      {      {
2133        /* Avoid consing in frequent cases.  */        /* Avoid consing in frequent cases.  */
# Line 2127  If FRAME is nil, describe the currently Line 2150  If FRAME is nil, describe the currently
2150                   "unspecified".  We need to do the same here.  */                   "unspecified".  We need to do the same here.  */
2151                if (STRINGP (value) && !FRAME_WINDOW_P (f))                if (STRINGP (value) && !FRAME_WINDOW_P (f))
2152                  {                  {
2153                    char *color_name;                    const char *color_name;
2154                    EMACS_INT csz;                    EMACS_INT csz;
2155    
2156                    if (EQ (parameter, Qbackground_color))                    if (EQ (parameter, Qbackground_color))
2157                      {                      {
2158                        color_name = XSTRING (value)->data;                        color_name = SDATA (value);
2159                        csz = XSTRING (value)->size;                        csz = SCHARS (value);
2160                        if (strncmp (color_name, unspecified_bg, csz) == 0)                        if (strncmp (color_name, unspecified_bg, csz) == 0)
2161                          value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));                          value = tty_color_name (f, FRAME_BACKGROUND_PIXEL (f));
2162                        else if (strncmp (color_name, unspecified_fg, csz) == 0)                        else if (strncmp (color_name, unspecified_fg, csz) == 0)
# Line 2141  If FRAME is nil, describe the currently Line 2164  If FRAME is nil, describe the currently
2164                      }                      }
2165                    else if (EQ (parameter, Qforeground_color))                    else if (EQ (parameter, Qforeground_color))
2166                      {                      {
2167                        color_name = XSTRING (value)->data;                        color_name = SDATA (value);
2168                        csz = XSTRING (value)->size;                        csz = SCHARS (value);
2169                        if (strncmp (color_name, unspecified_fg, csz) == 0)                        if (strncmp (color_name, unspecified_fg, csz) == 0)
2170                          value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));                          value = tty_color_name (f, FRAME_FOREGROUND_PIXEL (f));
2171                        else if (strncmp (color_name, unspecified_bg, csz) == 0)                        else if (strncmp (color_name, unspecified_bg, csz) == 0)
# Line 2159  If FRAME is nil, describe the currently Line 2182  If FRAME is nil, describe the currently
2182        else        else
2183          value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));          value = Fcdr (Fassq (parameter, Fframe_parameters (frame)));
2184      }      }
2185      
2186    return value;    return value;
2187  }  }
2188    
2189    
2190  DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,  DEFUN ("modify-frame-parameters", Fmodify_frame_parameters,
2191         Smodify_frame_parameters, 2, 2, 0,         Smodify_frame_parameters, 2, 2, 0,
2192         doc: /* Modify the parameters of frame FRAME according to ALIST.         doc: /* Modify the parameters of frame FRAME according to ALIST.
2193  If FRAME is nil, it defaults to the selected frame.  If FRAME is nil, it defaults to the selected frame.
# Line 2182  enabled such bindings for that variable Line 2205  enabled such bindings for that variable
2205  {  {
2206    FRAME_PTR f;    FRAME_PTR f;
2207    register Lisp_Object tail, prop, val;    register Lisp_Object tail, prop, val;
2208    int count = BINDING_STACK_SIZE ();    int count = SPECPDL_INDEX ();
2209    
2210    /* Bind this to t to inhibit initialization of the default face from    /* Bind this to t to inhibit initialization of the default face from
2211       X resources in face-set-after-frame-default.  If we don't inhibit       X resources in face-set-after-frame-default.  If we don't inhibit
# Line 2291  For a terminal screen, the value is alwa Line 2314  For a terminal screen, the value is alwa
2314      return make_number (1);      return make_number (1);
2315  }  }
2316    
2317  DEFUN ("frame-pixel-height", Fframe_pixel_height,  DEFUN ("frame-pixel-height", Fframe_pixel_height,
2318         Sframe_pixel_height, 0, 1, 0,         Sframe_pixel_height, 0, 1, 0,
2319         doc: /* Return a FRAME's height in pixels.         doc: /* Return a FRAME's height in pixels.
2320  This counts only the height available for text lines,  This counts only the height available for text lines,
# Line 2316  If FRAME is omitted, the selected frame Line 2339  If FRAME is omitted, the selected frame
2339      return make_number (FRAME_HEIGHT (f));      return make_number (FRAME_HEIGHT (f));
2340  }  }
2341    
2342  DEFUN ("frame-pixel-width", Fframe_pixel_width,  DEFUN ("frame-pixel-width", Fframe_pixel_width,
2343         Sframe_pixel_width, 0, 1, 0,         Sframe_pixel_width, 0, 1, 0,
2344         doc: /* Return FRAME's width in pixels.         doc: /* Return FRAME's width in pixels.
2345  For a terminal frame, the result really gives the width in characters.  For a terminal frame, the result really gives the width in characters.
# Line 2424  DEFUN ("set-frame-size", Fset_frame_size Line 2447  DEFUN ("set-frame-size", Fset_frame_size
2447    return Qnil;    return Qnil;
2448  }  }
2449    
2450  DEFUN ("set-frame-position", Fset_frame_position,  DEFUN ("set-frame-position", Fset_frame_position,
2451         Sset_frame_position, 3, 3, 0,         Sset_frame_position, 3, 3, 0,
2452         doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.         doc: /* Sets position of FRAME in pixels to XOFFSET by YOFFSET.
2453  This is actually the position of the upper left corner of the frame.  This is actually the position of the upper left corner of the frame.
# Line 2450  the rightmost or bottommost possible pos Line 2473  the rightmost or bottommost possible pos
2473  }  }
2474    
2475    
2476    /***********************************************************************
2477                                    Frame Parameters
2478     ***********************************************************************/
2479    
2480    /* Connect the frame-parameter names for X frames
2481       to the ways of passing the parameter values to the window system.
2482    
2483       The name of a parameter, as a Lisp symbol,
2484       has an `x-frame-parameter' property which is an integer in Lisp
2485       that is an index in this table.  */
2486    
2487    struct frame_parm_table {
2488      char *name;
2489      Lisp_Object *variable;
2490    };
2491    
2492    static struct frame_parm_table frame_parms[] =
2493    {
2494      {"auto-raise",                &Qauto_raise},
2495      {"auto-lower",                &Qauto_lower},
2496      {"background-color",          0},
2497      {"border-color",              &Qborder_color},
2498      {"border-width",              &Qborder_width},
2499      {"cursor-color",              &Qcursor_color},
2500      {"cursor-type",               &Qcursor_type},
2501      {"font",                      0},
2502      {"foreground-color",          0},
2503      {"icon-name",                 &Qicon_name},
2504      {"icon-type",                 &Qicon_type},
2505      {"internal-border-width",     &Qinternal_border_width},
2506      {"menu-bar-lines",            &Qmenu_bar_lines},
2507      {"mouse-color",               &Qmouse_color},
2508      {"name",                      &Qname},
2509      {"scroll-bar-width",          &Qscroll_bar_width},
2510      {"title",                     &Qtitle},
2511      {"unsplittable",              &Qunsplittable},
2512      {"vertical-scroll-bars",      &Qvertical_scroll_bars},
2513      {"visibility",                &Qvisibility},
2514      {"tool-bar-lines",            &Qtool_bar_lines},
2515      {"scroll-bar-foreground",     &Qscroll_bar_foreground},
2516      {"scroll-bar-background",     &Qscroll_bar_background},
2517      {"screen-gamma",              &Qscreen_gamma},
2518      {"line-spacing",              &Qline_spacing},
2519      {"left-fringe",               &Qleft_fringe},
2520      {"right-fringe",              &Qright_fringe},
2521      {"wait-for-wm",               &Qwait_for_wm},
2522      {"fullscreen",                &Qfullscreen},
2523    };
2524    
2525    #ifdef HAVE_WINDOW_SYSTEM
2526    
2527    extern Lisp_Object Qbox;
2528    extern Lisp_Object Qtop;
2529    
2530    /* Calculate fullscreen size.  Return in *TOP_POS and *LEFT_POS the
2531       wanted positions of the WM window (not emacs window).
2532       Return in *WIDTH and *HEIGHT the wanted width and height of Emacs
2533       window (FRAME_X_WINDOW).
2534     */
2535    
2536    void
2537    x_fullscreen_adjust (f, width, height, top_pos, left_pos)
2538         struct frame *f;
2539         int *width;
2540         int *height;
2541         int *top_pos;
2542         int *left_pos;
2543    {
2544      int newwidth = f->width, newheight = f->height;
2545    
2546      *top_pos = FRAME_X_OUTPUT (f)->top_pos;
2547      *left_pos = FRAME_X_OUTPUT (f)->left_pos;
2548    
2549      if (FRAME_X_OUTPUT (f)->want_fullscreen & FULLSCREEN_HEIGHT)
2550        {
2551          int ph;
2552    
2553          ph = FRAME_X_DISPLAY_INFO (f)->height;
2554          newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
2555          ph = CHAR_TO_PIXEL_HEIGHT (f, newheight)
2556            - FRAME_X_OUTPUT (f)->y_pixels_diff;
2557          newheight = PIXEL_TO_CHAR_HEIGHT (f, ph);
2558          *top_pos = 0;
2559        }
2560    
2561      if (FRAME_X_OUTPUT (f)->want_fullscreen & FULLSCREEN_WIDTH)
2562        {
2563          int pw;
2564    
2565          pw = FRAME_X_DISPLAY_INFO (f)->width;
2566          newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
2567          pw = CHAR_TO_PIXEL_WIDTH (f, newwidth)
2568            - FRAME_X_OUTPUT (f)->x_pixels_diff;
2569          newwidth = PIXEL_TO_CHAR_WIDTH (f, pw);
2570          *left_pos = 0;
2571        }
2572    
2573      *width = newwidth;
2574      *height = newheight;
2575    }
2576    
2577    
2578    /* Really try to move where we want to be in case of fullscreen.  Some WMs
2579       moves the window where we tell them.  Some (mwm, twm) moves the outer
2580       window manager window there instead.
2581       Try to compensate for those WM here. */
2582    
2583    static void
2584    x_fullscreen_move (f, new_top, new_left)
2585         struct frame *f;
2586         int new_top;
2587         int new_left;
2588    {
2589      if (new_top != FRAME_X_OUTPUT (f)->top_pos
2590          || new_left != FRAME_X_OUTPUT (f)->left_pos)
2591        {
2592          int move_x = new_left;
2593          int move_y = new_top;
2594    
2595    #ifdef HAVE_X_WINDOWS
2596          move_x += FRAME_X_OUTPUT (f)->x_pixels_outer_diff;
2597          move_y += FRAME_X_OUTPUT (f)->y_pixels_outer_diff;
2598    #endif
2599    
2600          FRAME_X_OUTPUT (f)->want_fullscreen |= FULLSCREEN_MOVE_WAIT;
2601          x_set_offset (f, move_x, move_y, 1);
2602        }
2603    }
2604    
2605    /* Change the parameters of frame F as specified by ALIST.
2606       If a parameter is not specially recognized, do nothing special;
2607       otherwise call the `x_set_...' function for that parameter.
2608       Except for certain geometry properties, always call store_frame_param
2609       to store the new value in the parameter alist.  */
2610    
2611    void
2612    x_set_frame_parameters (f, alist)
2613         FRAME_PTR f;
2614         Lisp_Object alist;
2615    {
2616      Lisp_Object tail;
2617    
2618      /* If both of these parameters are present, it's more efficient to
2619         set them both at once.  So we wait until we've looked at the
2620         entire list before we set them.  */
2621      int width, height;
2622    
2623      /* Same here.  */
2624      Lisp_Object left, top;
2625    
2626      /* Same with these.  */
2627      Lisp_Object icon_left, icon_top;
2628    
2629      /* Record in these vectors all the parms specified.  */
2630      Lisp_Object *parms;
2631      Lisp_Object *values;
2632      int i, p;
2633      int left_no_change = 0, top_no_change = 0;
2634      int icon_left_no_change = 0, icon_top_no_change = 0;
2635      int fullscreen_is_being_set = 0;
2636    
2637      struct gcpro gcpro1, gcpro2;
2638    
2639      i = 0;
2640      for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2641        i++;
2642    
2643      parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2644      values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object));
2645    
2646      /* Extract parm names and values into those vectors.  */
2647    
2648      i = 0;
2649      for (tail = alist; CONSP (tail); tail = Fcdr (tail))
2650        {
2651          Lisp_Object elt;
2652    
2653          elt = Fcar (tail);
2654          parms[i] = Fcar (elt);
2655          values[i] = Fcdr (elt);
2656          i++;
2657        }
2658      /* TAIL and ALIST are not used again below here.  */
2659      alist = tail = Qnil;
2660    
2661      GCPRO2 (*parms, *values);
2662      gcpro1.nvars = i;
2663      gcpro2.nvars = i;
2664    
2665      /* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
2666         because their values appear in VALUES and strings are not valid.  */
2667      top = left = Qunbound;
2668      icon_left = icon_top = Qunbound;
2669    
2670      /* Provide default values for HEIGHT and WIDTH.  */
2671      if (FRAME_NEW_WIDTH (f))
2672        width = FRAME_NEW_WIDTH (f);
2673      else
2674        width = FRAME_WIDTH (f);
2675    
2676      if (FRAME_NEW_HEIGHT (f))
2677        height = FRAME_NEW_HEIGHT (f);
2678      else
2679        height = FRAME_HEIGHT (f);
2680    
2681      /* Process foreground_color and background_color before anything else.
2682         They are independent of other properties, but other properties (e.g.,
2683         cursor_color) are dependent upon them.  */
2684      /* Process default font as well, since fringe widths depends on it.  */
2685      /* Also, process fullscreen, width and height depend upon that */
2686      for (p = 0; p < i; p++)
2687        {
2688          Lisp_Object prop, val;
2689    
2690          prop = parms[p];
2691          val = values[p];
2692          if (EQ (prop, Qforeground_color)
2693              || EQ (prop, Qbackground_color)
2694              || EQ (prop, Qfont)
2695              || EQ (prop, Qfullscreen))
2696            {
2697              register Lisp_Object param_index, old_value;
2698    
2699              old_value = get_frame_param (f, prop);
2700              fullscreen_is_being_set |= EQ (prop, Qfullscreen);
2701    
2702              if (NILP (Fequal (val, old_value)))
2703                {
2704                  store_frame_param (f, prop, val);
2705    
2706                  param_index = Fget (prop, Qx_frame_parameter);
2707                  if (NATNUMP (param_index)
2708                      && (XFASTINT (param_index)
2709                          < sizeof (frame_parms)/sizeof (frame_parms[0]))
2710                      && rif->frame_parm_handlers[XINT (param_index)])
2711                    (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2712                }
2713            }
2714        }
2715    
2716      /* Now process them in reverse of specified order.  */
2717      for (i--; i >= 0; i--)
2718        {
2719          Lisp_Object prop, val;
2720    
2721          prop = parms[i];
2722          val = values[i];
2723    
2724          if (EQ (prop, Qwidth) && NUMBERP (val))
2725            width = XFASTINT (val);
2726          else if (EQ (prop, Qheight) && NUMBERP (val))
2727            height = XFASTINT (val);
2728          else if (EQ (prop, Qtop))
2729            top = val;
2730          else if (EQ (prop, Qleft))
2731            left = val;
2732          else if (EQ (prop, Qicon_top))
2733            icon_top = val;
2734          else if (EQ (prop, Qicon_left))
2735            icon_left = val;
2736          else if (EQ (prop, Qforeground_color)
2737                   || EQ (prop, Qbackground_color)
2738                   || EQ (prop, Qfont)
2739                   || EQ (prop, Qfullscreen))
2740            /* Processed above.  */
2741            continue;
2742          else
2743            {
2744              register Lisp_Object param_index, old_value;
2745    
2746              old_value = get_frame_param (f, prop);
2747    
2748              store_frame_param (f, prop, val);
2749    
2750              param_index = Fget (prop, Qx_frame_parameter);
2751              if (NATNUMP (param_index)
2752                  && (XFASTINT (param_index)
2753                      < sizeof (frame_parms)/sizeof (frame_parms[0]))
2754                  && rif->frame_parm_handlers[XINT (param_index)])
2755                (*(rif->frame_parm_handlers[XINT (param_index)])) (f, val, old_value);
2756            }
2757        }
2758    
2759      /* Don't die if just one of these was set.  */
2760      if (EQ (left, Qunbound))
2761        {
2762          left_no_change = 1;
2763          if (FRAME_X_OUTPUT (f)->left_pos < 0)
2764            left = Fcons (Qplus, Fcons (make_number (FRAME_X_OUTPUT (f)->left_pos), Qnil));
2765          else
2766            XSETINT (left, FRAME_X_OUTPUT (f)->left_pos);
2767        }
2768      if (EQ (top, Qunbound))
2769        {
2770          top_no_change = 1;
2771          if (FRAME_X_OUTPUT (f)->top_pos < 0)
2772            top = Fcons (Qplus, Fcons (make_number (FRAME_X_OUTPUT (f)->top_pos), Qnil));
2773          else
2774            XSETINT (top, FRAME_X_OUTPUT (f)->top_pos);
2775        }
2776    
2777      /* If one of the icon positions was not set, preserve or default it.  */
2778      if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left))
2779        {
2780          icon_left_no_change = 1;
2781          icon_left = Fcdr (Fassq (Qicon_left, f->param_alist));
2782          if (NILP (icon_left))
2783            XSETINT (icon_left, 0);
2784        }
2785      if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top))
2786        {
2787          icon_top_no_change = 1;
2788          icon_top = Fcdr (Fassq (Qicon_top, f->param_alist));
2789          if (NILP (icon_top))
2790            XSETINT (icon_top, 0);
2791        }
2792    
2793    #ifndef HAVE_CARBON
2794      /* MAC_TODO: fullscreen */
2795      if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
2796        {
2797          /* If the frame is visible already and the fullscreen parameter is
2798             being set, it is too late to set WM manager hints to specify
2799             size and position.
2800             Here we first get the width, height and position that applies to
2801             fullscreen.  We then move the frame to the appropriate
2802             position.  Resize of the frame is taken care of in the code after
2803             this if-statement. */
2804          int new_left, new_top;
2805    
2806          x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
2807          x_fullscreen_move (f, new_top, new_left);
2808        }
2809    #endif
2810    
2811      /* Don't set these parameters unless they've been explicitly
2812         specified.  The window might be mapped or resized while we're in
2813         this function, and we don't want to override that unless the lisp
2814         code has asked for it.
2815    
2816         Don't set these parameters unless they actually differ from the
2817         window's current parameters; the window may not actually exist
2818         yet.  */
2819      {
2820        Lisp_Object frame;
2821    
2822        check_frame_size (f, &height, &width);
2823    
2824        XSETFRAME (frame, f);
2825    
2826        if (width != FRAME_WIDTH (f)
2827            || height != FRAME_HEIGHT (f)
2828            || FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f))
2829          Fset_frame_size (frame, make_number (width), make_number (height));
2830    
2831        if ((!NILP (left) || !NILP (top))
2832            && ! (left_no_change && top_no_change)
2833            && ! (NUMBERP (left) && XINT (left) == FRAME_X_OUTPUT (f)->left_pos
2834                  && NUMBERP (top) && XINT (top) == FRAME_X_OUTPUT (f)->top_pos))
2835          {
2836            int leftpos = 0;
2837            int toppos = 0;
2838    
2839            /* Record the signs.  */
2840            FRAME_X_OUTPUT (f)->size_hint_flags &= ~ (XNegative | YNegative);
2841            if (EQ (left, Qminus))
2842              FRAME_X_OUTPUT (f)->size_hint_flags |= XNegative;
2843            else if (INTEGERP (left))
2844              {
2845                leftpos = XINT (left);
2846                if (leftpos < 0)
2847                  FRAME_X_OUTPUT (f)->size_hint_flags |= XNegative;
2848              }
2849            else if (CONSP (left) && EQ (XCAR (left), Qminus)
2850                     && CONSP (XCDR (left))
2851                     && INTEGERP (XCAR (XCDR (left))))
2852              {
2853                leftpos = - XINT (XCAR (XCDR (left)));
2854                FRAME_X_OUTPUT (f)->size_hint_flags |= XNegative;
2855              }
2856            else if (CONSP (left) && EQ (XCAR (left), Qplus)
2857                     && CONSP (XCDR (left))
2858                     && INTEGERP (XCAR (XCDR (left))))
2859              {
2860                leftpos = XINT (XCAR (XCDR (left)));
2861              }
2862    
2863            if (EQ (top, Qminus))
2864              FRAME_X_OUTPUT (f)->size_hint_flags |= YNegative;
2865            else if (INTEGERP (top))
2866              {
2867                toppos = XINT (top);
2868                if (toppos < 0)
2869                  FRAME_X_OUTPUT (f)->size_hint_flags |= YNegative;
2870              }
2871            else if (CONSP (top) && EQ (XCAR (top), Qminus)
2872                     && CONSP (XCDR (top))
2873                     && INTEGERP (XCAR (XCDR (top))))
2874              {
2875                toppos = - XINT (XCAR (XCDR (top)));
2876                FRAME_X_OUTPUT (f)->size_hint_flags |= YNegative;
2877              }
2878            else if (CONSP (top) && EQ (XCAR (top), Qplus)
2879                     && CONSP (XCDR (top))
2880                     && INTEGERP (XCAR (XCDR (top))))
2881              {
2882                toppos = XINT (XCAR (XCDR (top)));
2883              }
2884    
2885    
2886            /* Store the numeric value of the position.  */
2887            FRAME_X_OUTPUT (f)->top_pos = toppos;
2888            FRAME_X_OUTPUT (f)->left_pos = leftpos;
2889    
2890            FRAME_X_OUTPUT (f)->win_gravity = NorthWestGravity;
2891    
2892            /* Actually set that position, and convert to absolute.  */
2893            x_set_offset (f, leftpos, toppos, -1);
2894          }
2895    
2896        if ((!NILP (icon_left) || !NILP (icon_top))
2897            && ! (icon_left_no_change && icon_top_no_change))
2898          x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top));
2899      }
2900    
2901      UNGCPRO;
2902    }
2903    
2904    
2905    /* Insert a description of internally-recorded parameters of frame X
2906       into the parameter alist *ALISTPTR that is to be given to the user.
2907       Only parameters that are specific to the X window system
2908       and whose values are not correctly recorded in the frame's
2909       param_alist need to be considered here.  */
2910    
2911    void
2912    x_report_frame_params (f, alistptr)
2913         struct frame *f;
2914         Lisp_Object *alistptr;
2915    {
2916      char buf[16];
2917      Lisp_Object tem;
2918    
2919      /* Represent negative positions (off the top or left screen edge)
2920         in a way that Fmodify_frame_parameters will understand correctly.  */
2921      XSETINT (tem, FRAME_X_OUTPUT (f)->left_pos);
2922      if (FRAME_X_OUTPUT (f)->left_pos >= 0)
2923        store_in_alist (alistptr, Qleft, tem);
2924      else
2925        store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil)));
2926    
2927      XSETINT (tem, FRAME_X_OUTPUT (f)->top_pos);
2928      if (FRAME_X_OUTPUT (f)->top_pos >= 0)
2929        store_in_alist (alistptr, Qtop, tem);
2930      else
2931        store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil)));
2932    
2933      store_in_alist (alistptr, Qborder_width,
2934                      make_number (FRAME_X_OUTPUT (f)->border_width));
2935      store_in_alist (alistptr, Qinternal_border_width,
2936                      make_number (FRAME_X_OUTPUT (f)->internal_border_width));
2937      store_in_alist (alistptr, Qleft_fringe,
2938                      make_number (FRAME_X_OUTPUT (f)->left_fringe_width));
2939      store_in_alist (alistptr, Qright_fringe,
2940                      make_number (FRAME_X_OUTPUT (f)->right_fringe_width));
2941      store_in_alist (alistptr, Qscroll_bar_width,
2942                      (! FRAME_HAS_VERTICAL_SCROLL_BARS (f)
2943                       ? make_number (0)
2944                       : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
2945                       ? make_number (FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
2946                       /* nil means "use default width"
2947                          for non-toolkit scroll bar.
2948                          ruler-mode.el depends on this.  */
2949                       : Qnil));
2950      sprintf (buf, "%ld", (long) FRAME_X_WINDOW (f));
2951      store_in_alist (alistptr, Qwindow_id,
2952                      build_string (buf));
2953    #ifdef HAVE_X_WINDOWS
2954    #ifdef USE_X_TOOLKIT
2955      /* Tooltip frame may not have this widget.  */
2956      if (FRAME_X_OUTPUT (f)->widget)
2957    #endif
2958        sprintf (buf, "%ld", (long) FRAME_OUTER_WINDOW (f));
2959      store_in_alist (alistptr, Qouter_window_id,
2960                      build_string (buf));
2961    #endif
2962      store_in_alist (alistptr, Qicon_name, f->icon_name);
2963      FRAME_SAMPLE_VISIBILITY (f);
2964      store_in_alist (alistptr, Qvisibility,
2965                      (FRAME_VISIBLE_P (f) ? Qt
2966                       : FRAME_ICONIFIED_P (f) ? Qicon : Qnil));
2967      store_in_alist (alistptr, Qdisplay,
2968                      XCAR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
2969    
2970    #ifndef HAVE_CARBON
2971    /* A Mac Window is identified by a struct, not an integer.  */
2972      if (FRAME_X_OUTPUT (f)->parent_desc == FRAME_X_DISPLAY_INFO (f)->root_window)
2973        tem = Qnil;
2974      else
2975        XSETFASTINT (tem, FRAME_X_OUTPUT (f)->parent_desc);
2976      store_in_alist (alistptr, Qparent_id, tem);
2977    #endif
2978    }
2979    
2980    
2981    /* Change the `fullscreen' frame parameter of frame F.  OLD_VALUE is
2982       the previous value of that parameter, NEW_VALUE is the new value. */
2983    
2984    void
2985    x_set_fullscreen (f, new_value, old_value)
2986         struct frame *f;
2987         Lisp_Object new_value, old_value;
2988    {
2989    #ifndef HAVE_CARBON
2990      if (NILP (new_value))
2991        FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_NONE;
2992      else if (EQ (new_value, Qfullboth))
2993        FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_BOTH;
2994      else if (EQ (new_value, Qfullwidth))
2995        FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_WIDTH;
2996      else if (EQ (new_value, Qfullheight))
2997        FRAME_X_OUTPUT (f)->want_fullscreen = FULLSCREEN_HEIGHT;
2998    #endif
2999    }
3000    
3001    
3002    /* Change the `line-spacing' frame parameter of frame F.  OLD_VALUE is
3003       the previous value of that parameter, NEW_VALUE is the new value.  */
3004    
3005    void
3006    x_set_line_spacing (f, new_value, old_value)
3007         struct frame *f;
3008         Lisp_Object new_value, old_value;
3009    {
3010      if (NILP (new_value))
3011        f->extra_line_spacing = 0;
3012      else if (NATNUMP (new_value))
3013        f->extra_line_spacing = XFASTINT (new_value);
3014      else
3015        Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"),
3016                                Fcons (new_value, Qnil)));
3017      if (FRAME_VISIBLE_P (f))
3018        redraw_frame (f);
3019    }
3020    
3021    
3022    /* Change the `screen-gamma' frame parameter of frame F.  OLD_VALUE is
3023       the previous value of that parameter, NEW_VALUE is the new value.  */
3024    
3025    void
3026    x_set_screen_gamma (f, new_value, old_value)
3027         struct frame *f;
3028         Lisp_Object new_value, old_value;
3029    {
3030      if (NILP (new_value))
3031        f->gamma = 0;
3032      else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0)
3033        /* The value 0.4545 is the normal viewing gamma.  */
3034        f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value));
3035      else
3036        Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"),
3037                                Fcons (new_value, Qnil)));
3038    
3039      clear_face_cache (0);
3040    }
3041    
3042    
3043    void
3044    x_set_font (f, arg, oldval)
3045         struct frame *f;
3046         Lisp_Object arg, oldval;
3047    {
3048      Lisp_Object result;
3049      Lisp_Object fontset_name;
3050      Lisp_Object frame;
3051      int old_fontset = FRAME_FONTSET(f);
3052    
3053      CHECK_STRING (arg);
3054    
3055      fontset_name = Fquery_fontset (arg, Qnil);
3056    
3057      BLOCK_INPUT;
3058      result = (STRINGP (fontset_name)
3059                ? x_new_fontset (f, SDATA (fontset_name))
3060                : x_new_font (f, SDATA (arg)));
3061      UNBLOCK_INPUT;
3062    
3063      if (EQ (result, Qnil))
3064        error ("Font `%s' is not defined", SDATA (arg));
3065      else if (EQ (result, Qt))
3066        error ("The characters of the given font have varying widths");
3067      else if (STRINGP (result))
3068        {
3069          if (STRINGP (fontset_name))
3070            {
3071              /* Fontset names are built from ASCII font names, so the
3072                 names may be equal despite there was a change.  */
3073              if (old_fontset == FRAME_FONTSET (f))
3074                return;
3075            }
3076          else if (!NILP (Fequal (result, oldval)))
3077            return;
3078    
3079          store_frame_param (f, Qfont, result);
3080          recompute_basic_faces (f);
3081        }
3082      else
3083        abort ();
3084    
3085      do_pending_window_change (0);
3086    
3087      /* Don't call `face-set-after-frame-default' when faces haven't been
3088         initialized yet.  This is the case when called from
3089         Fx_create_frame.  In that case, the X widget or window doesn't
3090         exist either, and we can end up in x_report_frame_params with a
3091         null widget which gives a segfault.  */
3092      if (FRAME_FACE_CACHE (f))
3093        {
3094          XSETFRAME (frame, f);
3095          call1 (Qface_set_after_frame_default, frame);
3096        }
3097    }
3098    
3099    
3100    void
3101    x_set_fringe_width (f, new_value, old_value)
3102         struct frame *f;
3103         Lisp_Object new_value, old_value;
3104    {
3105      compute_fringe_widths (f, 1);
3106    }
3107    
3108    void
3109    x_set_border_width (f, arg, oldval)
3110         struct frame *f;
3111         Lisp_Object arg, oldval;
3112    {
3113      CHECK_NUMBER (arg);
3114    
3115      if (XINT (arg) == FRAME_X_OUTPUT (f)->border_width)
3116        return;
3117    
3118    #ifndef HAVE_CARBON
3119      if (FRAME_X_WINDOW (f) != 0)
3120        error ("Cannot change the border width of a window");
3121    #endif /* MAC_TODO */
3122    
3123      FRAME_X_OUTPUT (f)->border_width = XINT (arg);
3124    }
3125    
3126    void
3127    x_set_internal_border_width (f, arg, oldval)
3128         struct frame *f;
3129         Lisp_Object arg, oldval;
3130    {
3131      int old = FRAME_X_OUTPUT (f)->internal_border_width;
3132    
3133      CHECK_NUMBER (arg);
3134      FRAME_X_OUTPUT (f)->internal_border_width = XINT (arg);
3135      if (FRAME_X_OUTPUT (f)->internal_border_width < 0)
3136        FRAME_X_OUTPUT (f)->internal_border_width = 0;
3137    
3138    #ifdef USE_X_TOOLKIT
3139      if (FRAME_X_OUTPUT (f)->edit_widget)
3140        widget_store_internal_border (FRAME_X_OUTPUT (f)->edit_widget);
3141    #endif
3142    
3143      if (FRAME_X_OUTPUT (f)->internal_border_width == old)
3144        return;
3145    
3146      if (FRAME_X_WINDOW (f) != 0)
3147        {
3148          x_set_window_size (f, 0, f->width, f->height);
3149          SET_FRAME_GARBAGED (f);
3150          do_pending_window_change (0);
3151        }
3152      else
3153        SET_FRAME_GARBAGED (f);
3154    }
3155    
3156    void
3157    x_set_visibility (f, value, oldval)
3158         struct frame *f;
3159         Lisp_Object value, oldval;
3160    {
3161      Lisp_Object frame;
3162      XSETFRAME (frame, f);
3163    
3164      if (NILP (value))
3165        Fmake_frame_invisible (frame, Qt);
3166      else if (EQ (value, Qicon))
3167        Ficonify_frame (frame);
3168      else
3169        Fmake_frame_visible (frame);
3170    }
3171    
3172    void
3173    x_set_autoraise (f, arg, oldval)
3174         struct frame *f;
3175         Lisp_Object arg, oldval;
3176    {
3177      f->auto_raise = !EQ (Qnil, arg);
3178    }
3179    
3180    void
3181    x_set_autolower (f, arg, oldval)
3182         struct frame *f;
3183         Lisp_Object arg, oldval;
3184    {
3185      f->auto_lower = !EQ (Qnil, arg);
3186    }
3187    
3188    void
3189    x_set_unsplittable (f, arg, oldval)
3190         struct frame *f;
3191         Lisp_Object arg, oldval;
3192    {
3193      f->no_split = !NILP (arg);
3194    }
3195    
3196    void
3197    x_set_vertical_scroll_bars (f, arg, oldval)
3198         struct frame *f;
3199         Lisp_Object arg, oldval;
3200    {
3201      if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f))
3202          || (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f))
3203          || (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f))
3204          || (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f)))
3205        {
3206          FRAME_VERTICAL_SCROLL_BAR_TYPE (f)
3207            = (NILP (arg)
3208               ? vertical_scroll_bar_none
3209               : EQ (Qleft, arg)
3210               ? vertical_scroll_bar_left
3211               : EQ (Qright, arg)
3212               ? vertical_scroll_bar_right
3213    #ifdef HAVE_NTGUI
3214               /* MS-Windows has scroll bars on the right by default.  */
3215               : vertical_scroll_bar_right
3216    #else
3217               : vertical_scroll_bar_left
3218    #endif
3219               );
3220    
3221          /* We set this parameter before creating the X window for the
3222             frame, so we can get the geometry right from the start.
3223             However, if the window hasn't been created yet, we shouldn't
3224             call x_set_window_size.  */
3225          if (FRAME_X_WINDOW (f))
3226            x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
3227          do_pending_window_change (0);
3228        }
3229    }
3230    
3231    void
3232    x_set_scroll_bar_width (f, arg, oldval)
3233         struct frame *f;
3234         Lisp_Object arg, oldval;
3235    {
3236      int wid = FONT_WIDTH (FRAME_FONT (f));
3237    
3238      if (NILP (arg))
3239        {
3240          x_set_scroll_bar_default_width (f);
3241    
3242          if (FRAME_X_WINDOW (f))
3243            x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
3244          do_pending_window_change (0);
3245        }
3246      else if (INTEGERP (arg) && XINT (arg) > 0
3247               && XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f))
3248        {
3249          if (XFASTINT (arg) <= 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM)
3250            XSETINT (arg, 2 * VERTICAL_SCROLL_BAR_WIDTH_TRIM + 1);
3251    
3252          FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg);
3253          FRAME_SCROLL_BAR_COLS (f) = (XFASTINT (arg) + wid-1) / wid;
3254          if (FRAME_X_WINDOW (f))
3255            x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
3256          do_pending_window_change (0);
3257        }
3258    
3259      change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0, 0);
3260      XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0;
3261      XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0;
3262    }
3263    
3264    
3265    
3266    /* Return non-nil if frame F wants a bitmap icon.  */
3267    
3268    Lisp_Object
3269    x_icon_type (f)
3270         FRAME_PTR f;
3271    {
3272      Lisp_Object tem;
3273    
3274      tem = assq_no_quit (Qicon_type, f->param_alist);
3275      if (CONSP (tem))
3276        return XCDR (tem);
3277      else
3278        return Qnil;
3279    }
3280    
3281    
3282    /* Subroutines of creating an X frame.  */
3283    
3284    /* Make sure that Vx_resource_name is set to a reasonable value.
3285       Fix it up, or set it to `emacs' if it is too hopeless.  */
3286    
3287    void
3288    validate_x_resource_name ()
3289    {
3290      int len = 0;
3291      /* Number of valid characters in the resource name.  */
3292      int good_count = 0;
3293      /* Number of invalid characters in the resource name.  */
3294      int bad_count = 0;
3295      Lisp_Object new;
3296      int i;
3297    
3298      if (!STRINGP (Vx_resource_class))
3299        Vx_resource_class = build_string (EMACS_CLASS);
3300    
3301      if (STRINGP (Vx_resource_name))
3302        {
3303          unsigned char *p = SDATA (Vx_resource_name);
3304          int i;
3305    
3306          len = SBYTES (Vx_resource_name);
3307    
3308          /* Only letters, digits, - and _ are valid in resource names.
3309             Count the valid characters and count the invalid ones.  */
3310          for (i = 0; i < len; i++)
3311            {
3312              int c = p[i];
3313              if (! ((c >= 'a' && c <= 'z')
3314                     || (c >= 'A' && c <= 'Z')
3315                     || (c >= '0' && c <= '9')
3316                     || c == '-' || c == '_'))
3317                bad_count++;
3318              else
3319                good_count++;
3320            }
3321        }
3322      else
3323        /* Not a string => completely invalid.  */
3324        bad_count = 5, good_count = 0;
3325    
3326      /* If name is valid already, return.  */
3327      if (bad_count == 0)
3328        return;
3329    
3330      /* If name is entirely invalid, or nearly so, use `emacs'.  */
3331      if (good_count == 0
3332          || (good_count == 1 && bad_count > 0))
3333        {
3334          Vx_resource_name = build_string ("emacs");
3335          return;
3336        }
3337    
3338      /* Name is partly valid.  Copy it and replace the invalid characters
3339         with underscores.  */
3340    
3341      Vx_resource_name = new = Fcopy_sequence (Vx_resource_name);
3342    
3343      for (i = 0; i < len; i++)
3344        {
3345          int c = SREF (new, i);
3346          if (! ((c >= 'a' && c <= 'z')
3347                 || (c >= 'A' && c <= 'Z')
3348                 || (c >= '0' && c <= '9')
3349                 || c == '-' || c == '_'))
3350            SSET (new, i, '_');
3351        }
3352    }
3353    
3354    
3355    extern char *x_get_string_resource P_ ((XrmDatabase, char *, char *));
3356    extern Display_Info *check_x_display_info P_ ((Lisp_Object));
3357    
3358    
3359    /* Get specified attribute from resource database RDB.  
3360       See Fx_get_resource below for other parameters.  */
3361    
3362    static Lisp_Object
3363    xrdb_get_resource (rdb, attribute, class, component, subclass)
3364         XrmDatabase rdb;
3365         Lisp_Object attribute, class, component, subclass;
3366    {
3367      register char *value;
3368      char *name_key;
3369      char *class_key;
3370    
3371      CHECK_STRING (attribute);
3372      CHECK_STRING (class);
3373    
3374      if (!NILP (component))
3375        CHECK_STRING (component);
3376      if (!NILP (subclass))
3377        CHECK_STRING (subclass);
3378      if (NILP (component) != NILP (subclass))
3379        error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither");
3380    
3381      validate_x_resource_name ();
3382    
3383      /* Allocate space for the components, the dots which separate them,
3384         and the final '\0'.  Make them big enough for the worst case.  */
3385      name_key = (char *) alloca (SBYTES (Vx_resource_name)
3386                                  + (STRINGP (component)
3387                                     ? SBYTES (component) : 0)
3388                                  + SBYTES (attribute)
3389                                  + 3);
3390    
3391      class_key = (char *) alloca (SBYTES (Vx_resource_class)
3392                                   + SBYTES (class)
3393                                   + (STRINGP (subclass)
3394                                      ? SBYTES (subclass) : 0)
3395                                   + 3);
3396    
3397      /* Start with emacs.FRAMENAME for the name (the specific one)
3398         and with `Emacs' for the class key (the general one).  */
3399      strcpy (name_key, SDATA (Vx_resource_name));
3400      strcpy (class_key, SDATA (Vx_resource_class));
3401    
3402      strcat (class_key, ".");
3403      strcat (class_key, SDATA (class));
3404    
3405      if (!NILP (component))
3406        {
3407          strcat (class_key, ".");
3408          strcat (class_key, SDATA (subclass));
3409    
3410          strcat (name_key, ".");
3411          strcat (name_key, SDATA (component));
3412        }
3413    
3414      strcat (name_key, ".");
3415      strcat (name_key, SDATA (attribute));
3416    
3417      value = x_get_string_resource (rdb, name_key, class_key);
3418    
3419      if (value != (char *) 0)
3420        return build_string (value);
3421      else
3422        return Qnil;
3423    }
3424    
3425    
3426    DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
3427           doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.
3428    This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the
3429    class, where INSTANCE is the name under which Emacs was invoked, or
3430    the name specified by the `-name' or `-rn' command-line arguments.
3431    
3432    The optional arguments COMPONENT and SUBCLASS add to the key and the
3433    class, respectively.  You must specify both of them or neither.
3434    If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'
3435    and the class is `Emacs.CLASS.SUBCLASS'.  */)
3436         (attribute, class, component, subclass)
3437         Lisp_Object attribute, class, component, subclass;
3438    {
3439    #ifdef HAVE_X_WINDOWS
3440      check_x ();
3441    #endif
3442    
3443      return xrdb_get_resource (check_x_display_info (Qnil)->xrdb,
3444                                attribute, class, component, subclass);
3445    }
3446    
3447    /* Get an X resource, like Fx_get_resource, but for display DPYINFO.  */
3448    
3449    Lisp_Object
3450    display_x_get_resource (dpyinfo, attribute, class, component, subclass)
3451         Display_Info *dpyinfo;
3452         Lisp_Object attribute, class, component, subclass;
3453    {
3454      return xrdb_get_resource (dpyinfo->xrdb,
3455                                attribute, class, component, subclass);
3456    }
3457    
3458    /* Used when C code wants a resource value.  */
3459    
3460    char *
3461    x_get_resource_string (attribute, class)
3462         char *attribute, *class;
3463    {
3464      char *name_key;
3465      char *class_key;
3466      struct frame *sf = SELECTED_FRAME ();
3467    
3468      /* Allocate space for the components, the dots which separate them,
3469         and the final '\0'.  */
3470      name_key = (char *) alloca (SBYTES (Vinvocation_name)
3471                                  + strlen (attribute) + 2);
3472      class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1)
3473                                   + strlen (class) + 2);
3474    
3475      sprintf (name_key, "%s.%s", SDATA (Vinvocation_name), attribute);
3476      sprintf (class_key, "%s.%s", EMACS_CLASS, class);
3477    
3478      return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
3479                                    name_key, class_key);
3480    }
3481    
3482    
3483    /* Return the value of parameter PARAM.
3484    
3485       First search ALIST, then Vdefault_frame_alist, then the X defaults
3486       database, using ATTRIBUTE as the attribute name and CLASS as its class.
3487    
3488       Convert the resource to the type specified by desired_type.
3489    
3490       If no default is specified, return Qunbound.  If you call
3491       x_get_arg, make sure you deal with Qunbound in a reasonable way,
3492       and don't let it get stored in any Lisp-visible variables!  */
3493    
3494    Lisp_Object
3495    x_get_arg (dpyinfo, alist, param, attribute, class, type)
3496         Display_Info *dpyinfo;
3497         Lisp_Object alist, param;
3498         char *attribute;
3499         char *class;
3500         enum resource_types type;
3501    {
3502      register Lisp_Object tem;
3503    
3504      tem = Fassq (param, alist);
3505      if (EQ (tem, Qnil))
3506        tem = Fassq (param, Vdefault_frame_alist);
3507      if (EQ (tem, Qnil))
3508        {
3509          if (attribute)
3510            {
3511              tem = display_x_get_resource (dpyinfo,
3512                                            build_string (attribute),
3513                                            build_string (class),
3514                                            Qnil, Qnil);
3515    
3516              if (NILP (tem))
3517                return Qunbound;
3518    
3519              switch (type)
3520                {
3521                case RES_TYPE_NUMBER:
3522                  return make_number (atoi (SDATA (tem)));
3523    
3524                case RES_TYPE_FLOAT:
3525                  return make_float (atof (SDATA (tem)));
3526    
3527                case RES_TYPE_BOOLEAN:
3528                  tem = Fdowncase (tem);
3529                  if (!strcmp (SDATA (tem), "on")
3530                      || !strcmp (SDATA (tem), "true"))
3531                    return Qt;
3532                  else
3533                    return Qnil;
3534    
3535                case RES_TYPE_STRING:
3536                  return tem;
3537    
3538                case RES_TYPE_SYMBOL:
3539                  /* As a special case, we map the values `true' and `on'
3540                     to Qt, and `false' and `off' to Qnil.  */
3541                  {
3542                    Lisp_Object lower;
3543                    lower = Fdowncase (tem);
3544                    if (!strcmp (SDATA (lower), "on")
3545                        || !strcmp (SDATA (lower), "true"))
3546                      return Qt;
3547                    else if (!strcmp (SDATA (lower), "off")
3548                          || !strcmp (SDATA (lower), "false"))
3549                      return Qnil;
3550                    else
3551                      return Fintern (tem, Qnil);
3552                  }
3553    
3554                default:
3555                  abort ();
3556                }
3557            }
3558          else
3559            return Qunbound;
3560        }
3561      return Fcdr (tem);
3562    }
3563    
3564    Lisp_Object
3565    x_frame_get_arg (f, alist, param, attribute, class, type)
3566         struct frame *f;
3567         Lisp_Object alist, param;
3568         char *attribute;
3569         char *class;
3570         enum resource_types type;
3571    {
3572      return x_get_arg (FRAME_X_DISPLAY_INFO (f),
3573                        alist, param, attribute, class, type);
3574    }
3575    
3576    /* Like x_frame_get_arg, but also record the value in f->param_alist.  */
3577    
3578    Lisp_Object
3579    x_frame_get_and_record_arg (f, alist, param, attribute, class, type)
3580         struct frame *f;
3581         Lisp_Object alist, param;
3582         char *attribute;
3583         char *class;
3584         enum resource_types type;
3585    {
3586      Lisp_Object value;
3587    
3588      value = x_get_arg (FRAME_X_DISPLAY_INFO (f), alist, param,
3589                         attribute, class, type);
3590      if (! NILP (value))
3591        store_frame_param (f, param, value);
3592    
3593      return value;
3594    }
3595    
3596    
3597    /* Record in frame F the specified or default value according to ALIST
3598       of the parameter named PROP (a Lisp symbol).
3599       If no value is specified for PROP, look for an X default for XPROP
3600       on the frame named NAME.
3601       If that is not found either, use the value DEFLT.  */
3602    
3603    Lisp_Object
3604    x_default_parameter (f, alist, prop, deflt, xprop, xclass, type)
3605         struct frame *f;
3606         Lisp_Object alist;
3607         Lisp_Object prop;
3608         Lisp_Object deflt;
3609         char *xprop;
3610         char *xclass;
3611         enum resource_types type;
3612    {
3613      Lisp_Object tem;
3614    
3615      tem = x_frame_get_arg (f, alist, prop, xprop, xclass, type);
3616      if (EQ (tem, Qunbound))
3617        tem = deflt;
3618      x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil));
3619      return tem;
3620    }
3621    
3622    
3623    
3624    
3625    DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
3626           doc: /* Parse an X-style geometry string STRING.
3627    Returns an alist of the form ((top . TOP), (left . LEFT) ... ).
3628    The properties returned may include `top', `left', `height', and `width'.
3629    The value of `left' or `top' may be an integer,
3630    or a list (+ N) meaning N pixels relative to top/left corner,
3631    or a list (- N) meaning -N pixels relative to bottom/right corner.  */)
3632         (string)
3633         Lisp_Object string;
3634    {
3635      int geometry, x, y;
3636      unsigned int width, height;
3637      Lisp_Object result;
3638    
3639      CHECK_STRING (string);
3640    
3641      geometry = XParseGeometry ((char *) SDATA (string),
3642                                 &x, &y, &width, &height);
3643    
3644    #if 0
3645      if (!!(geometry & XValue) != !!(geometry & YValue))
3646        error ("Must specify both x and y position, or neither");
3647    #endif
3648    
3649      result = Qnil;
3650      if (geometry & XValue)
3651        {
3652          Lisp_Object element;
3653    
3654          if (x >= 0 && (geometry & XNegative))
3655            element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil)));
3656          else if (x < 0 && ! (geometry & XNegative))
3657            element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil)));
3658          else
3659            element = Fcons (Qleft, make_number (x));
3660          result = Fcons (element, result);
3661        }
3662    
3663      if (geometry & YValue)
3664        {
3665          Lisp_Object element;
3666    
3667          if (y >= 0 && (geometry & YNegative))
3668            element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil)));
3669          else if (y < 0 && ! (geometry & YNegative))
3670            element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil)));
3671          else
3672            element = Fcons (Qtop, make_number (y));
3673          result = Fcons (element, result);
3674        }
3675    
3676      if (geometry & WidthValue)
3677        result = Fcons (Fcons (Qwidth, make_number (width)), result);
3678      if (geometry & HeightValue)
3679        result = Fcons (Fcons (Qheight, make_number (height)), result);
3680    
3681      return result;
3682    }
3683    
3684    /* Calculate the desired size and position of frame F.
3685       Return the flags saying which aspects were specified.
3686    
3687       Also set the win_gravity and size_hint_flags of F.
3688    
3689       Adjust height for toolbar if TOOLBAR_P is 1.
3690    
3691       This function does not make the coordinates positive.  */
3692    
3693    #define DEFAULT_ROWS 40
3694    #define DEFAULT_COLS 80
3695    
3696    int
3697    x_figure_window_size (f, parms, toolbar_p)
3698         struct frame *f;
3699         Lisp_Object parms;
3700         int toolbar_p;
3701    {
3702      register Lisp_Object tem0, tem1, tem2;
3703      long window_prompting = 0;
3704      Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3705    
3706      /* Default values if we fall through.
3707         Actually, if that happens we should get
3708         window manager prompting.  */
3709      SET_FRAME_WIDTH (f, DEFAULT_COLS);
3710      f->height = DEFAULT_ROWS;
3711      /* Window managers expect that if program-specified
3712         positions are not (0,0), they're intentional, not defaults.  */
3713      FRAME_X_OUTPUT (f)->top_pos = 0;
3714      FRAME_X_OUTPUT (f)->left_pos = 0;
3715    
3716      /* Ensure that old new_width and new_height will not override the
3717         values set here.  */
3718      /* ++KFS: This was specific to W32, but seems ok for all platforms */
3719      FRAME_NEW_WIDTH (f) = 0;
3720      FRAME_NEW_HEIGHT (f) = 0;
3721    
3722      tem0 = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
3723      tem1 = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
3724      tem2 = x_get_arg (dpyinfo, parms, Quser_size, 0, 0, RES_TYPE_NUMBER);
3725      if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3726        {
3727          if (!EQ (tem0, Qunbound))
3728            {
3729              CHECK_NUMBER (tem0);
3730              f->height = XINT (tem0);
3731            }
3732          if (!EQ (tem1, Qunbound))
3733            {
3734              CHECK_NUMBER (tem1);
3735              SET_FRAME_WIDTH (f, XINT (tem1));
3736            }
3737          if (!NILP (tem2) && !EQ (tem2, Qunbound))
3738            window_prompting |= USSize;
3739          else
3740            window_prompting |= PSize;
3741        }
3742    
3743      FRAME_X_OUTPUT (f)->vertical_scroll_bar_extra
3744        = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f)
3745           ? 0
3746    #ifndef HAVE_X_WINDOWS
3747           /* +KFS: This was specific for W32 and MAC.. why?  */
3748           : FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0
3749           ? FRAME_SCROLL_BAR_PIXEL_WIDTH (f)
3750    #endif
3751           : (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (FRAME_X_OUTPUT (f)->font)));
3752    
3753      /* This used to be done _before_ calling x_figure_window_size, but
3754         since the height is reset here, this was really a no-op.  I
3755         assume that moving it here does what Gerd intended (although he
3756         no longer can remember what that was...  ++KFS, 2003-03-25.  */
3757    
3758      /* Add the tool-bar height to the initial frame height so that the
3759         user gets a text display area of the size he specified with -g or
3760         via .Xdefaults.  Later changes of the tool-bar height don't
3761         change the frame size.  This is done so that users can create
3762         tall Emacs frames without having to guess how tall the tool-bar
3763         will get.  */
3764      if (toolbar_p && FRAME_TOOL_BAR_LINES (f))
3765        {
3766          int margin, relief, bar_height;
3767    
3768          relief = (tool_bar_button_relief >= 0
3769                    ? tool_bar_button_relief
3770                    : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
3771    
3772          if (INTEGERP (Vtool_bar_button_margin)
3773              && XINT (Vtool_bar_button_margin) > 0)
3774            margin = XFASTINT (Vtool_bar_button_margin);
3775          else if (CONSP (Vtool_bar_button_margin)
3776                   && INTEGERP (XCDR (Vtool_bar_button_margin))
3777                   && XINT (XCDR (Vtool_bar_button_margin)) > 0)
3778            margin = XFASTINT (XCDR (Vtool_bar_button_margin));
3779          else
3780            margin = 0;
3781    
3782          bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief;
3783          f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f);
3784        }
3785    
3786      compute_fringe_widths (f, 0);
3787    
3788      FRAME_X_OUTPUT (f)->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
3789      FRAME_X_OUTPUT (f)->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
3790    
3791      tem0 = x_get_arg (dpyinfo, parms, Qtop, 0, 0, RES_TYPE_NUMBER);
3792      tem1 = x_get_arg (dpyinfo, parms, Qleft, 0, 0, RES_TYPE_NUMBER);
3793      tem2 = x_get_arg (dpyinfo, parms, Quser_position, 0, 0, RES_TYPE_NUMBER);
3794      if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound))
3795        {
3796          if (EQ (tem0, Qminus))
3797            {
3798              FRAME_X_OUTPUT (f)->top_pos = 0;
3799              window_prompting |= YNegative;
3800            }
3801          else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus)
3802                   && CONSP (XCDR (tem0))
3803                   && INTEGERP (XCAR (XCDR (tem0))))
3804            {
3805              FRAME_X_OUTPUT (f)->top_pos = - XINT (XCAR (XCDR (tem0)));
3806              window_prompting |= YNegative;
3807            }
3808          else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus)
3809                   && CONSP (XCDR (tem0))
3810                   && INTEGERP (XCAR (XCDR (tem0))))
3811            {
3812              FRAME_X_OUTPUT (f)->top_pos = XINT (XCAR (XCDR (tem0)));
3813            }
3814          else if (EQ (tem0, Qunbound))
3815            FRAME_X_OUTPUT (f)->top_pos = 0;
3816          else
3817            {
3818              CHECK_NUMBER (tem0);
3819              FRAME_X_OUTPUT (f)->top_pos = XINT (tem0);
3820              if (FRAME_X_OUTPUT (f)->top_pos < 0)
3821                window_prompting |= YNegative;
3822            }
3823    
3824          if (EQ (tem1, Qminus))
3825            {
3826              FRAME_X_OUTPUT (f)->left_pos = 0;
3827              window_prompting |= XNegative;
3828            }
3829          else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus)
3830                   && CONSP (XCDR (tem1))
3831                   && INTEGERP (XCAR (XCDR (tem1))))
3832            {
3833              FRAME_X_OUTPUT (f)->left_pos = - XINT (XCAR (XCDR (tem1)));
3834              window_prompting |= XNegative;
3835            }
3836          else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus)
3837                   && CONSP (XCDR (tem1))
3838                   && INTEGERP (XCAR (XCDR (tem1))))
3839            {
3840              FRAME_X_OUTPUT (f)->left_pos = XINT (XCAR (XCDR (tem1)));
3841            }
3842          else if (EQ (tem1, Qunbound))
3843            FRAME_X_OUTPUT (f)->left_pos = 0;
3844          else
3845            {
3846              CHECK_NUMBER (tem1);
3847              FRAME_X_OUTPUT (f)->left_pos = XINT (tem1);
3848              if (FRAME_X_OUTPUT (f)->left_pos < 0)
3849                window_prompting |= XNegative;
3850            }
3851    
3852          if (!NILP (tem2) && ! EQ (tem2, Qunbound))
3853            window_prompting |= USPosition;
3854          else
3855            window_prompting |= PPosition;
3856        }
3857    
3858      if (FRAME_X_OUTPUT (f)->want_fullscreen != FULLSCREEN_NONE)
3859        {
3860          int left, top;
3861          int width, height;
3862    
3863          /* It takes both for some WM:s to place it where we want */
3864          window_prompting = USPosition | PPosition;
3865          x_fullscreen_adjust (f, &width, &height, &top, &left);
3866          f->width = width;
3867          f->height = height;
3868          FRAME_X_OUTPUT (f)->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width);
3869          FRAME_X_OUTPUT (f)->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height);
3870          FRAME_X_OUTPUT (f)->left_pos = left;
3871          FRAME_X_OUTPUT (f)->top_pos = top;
3872        }
3873    
3874      if (window_prompting & XNegative)
3875        {
3876          if (window_prompting & YNegative)
3877            FRAME_X_OUTPUT (f)->win_gravity = SouthEastGravity;
3878          else
3879            FRAME_X_OUTPUT (f)->win_gravity = NorthEastGravity;
3880        }
3881      else
3882        {
3883          if (window_prompting & YNegative)
3884            FRAME_X_OUTPUT (f)->win_gravity = SouthWestGravity;
3885          else
3886            FRAME_X_OUTPUT (f)->win_gravity = NorthWestGravity;
3887        }
3888    
3889      FRAME_X_OUTPUT (f)->size_hint_flags = window_prompting;
3890    
3891      return window_prompting;
3892    }
3893    
3894    
3895    
3896    #endif /* HAVE_WINDOW_SYSTEM */
3897    
3898    
3899    
3900    /***********************************************************************
3901                                    Initialization
3902     ***********************************************************************/
3903    
3904  void  void
3905  syms_of_frame ()  syms_of_frame ()
3906  {  {
# Line 2465  syms_of_frame () Line 3916  syms_of_frame ()
3916    staticpro (&Qminibuffer);    staticpro (&Qminibuffer);
3917    Qmodeline = intern ("modeline");    Qmodeline = intern ("modeline");
3918    staticpro (&Qmodeline);    staticpro (&Qmodeline);
   Qname = intern ("name");  
   staticpro (&Qname);  
3919    Qonly = intern ("only");    Qonly = intern ("only");
3920    staticpro (&Qonly);    staticpro (&Qonly);
   Qunsplittable = intern ("unsplittable");  
   staticpro (&Qunsplittable);  
   Qmenu_bar_lines = intern ("menu-bar-lines");  
   staticpro (&Qmenu_bar_lines);  
   Qtool_bar_lines = intern ("tool-bar-lines");  
   staticpro (&Qtool_bar_lines);  
3921    Qwidth = intern ("width");    Qwidth = intern ("width");
3922    staticpro (&Qwidth);    staticpro (&Qwidth);
3923      Qgeometry = intern ("geometry");
3924      staticpro (&Qgeometry);
3925      Qicon_left = intern ("icon-left");
3926      staticpro (&Qicon_left);
3927      Qicon_top = intern ("icon-top");
3928      staticpro (&Qicon_top);
3929      Qleft = intern ("left");
3930      staticpro (&Qleft);
3931      Qright = intern ("right");
3932      staticpro (&Qright);
3933      Quser_position = intern ("user-position");
3934      staticpro (&Quser_position);
3935      Quser_size = intern ("user-size");
3936      staticpro (&Quser_size);
3937      Qwindow_id = intern ("window-id");
3938      staticpro (&Qwindow_id);
3939    #ifdef HAVE_X_WINDOWS
3940      Qouter_window_id = intern ("outer-window-id");
3941      staticpro (&Qouter_window_id);
3942    #endif
3943      Qparent_id = intern ("parent-id");
3944      staticpro (&Qparent_id);
3945    Qx = intern ("x");    Qx = intern ("x");
3946    staticpro (&Qx);    staticpro (&Qx);
3947    Qw32 = intern ("w32");    Qw32 = intern ("w32");
# Line 2491  syms_of_frame () Line 3956  syms_of_frame ()
3956    staticpro (&Qbuffer_predicate);    staticpro (&Qbuffer_predicate);
3957    Qbuffer_list = intern ("buffer-list");    Qbuffer_list = intern ("buffer-list");
3958    staticpro (&Qbuffer_list);    staticpro (&Qbuffer_list);
   Qtitle = intern ("title");  
   staticpro (&Qtitle);  
3959    Qdisplay_type = intern ("display-type");    Qdisplay_type = intern ("display-type");
3960    staticpro (&Qdisplay_type);    staticpro (&Qdisplay_type);
3961    Qbackground_mode = intern ("background-mode");    Qbackground_mode = intern ("background-mode");
3962    staticpro (&Qbackground_mode);    staticpro (&Qbackground_mode);
   Qleft_fringe = intern ("left-fringe");  
   staticpro (&Qleft_fringe);  
   Qright_fringe = intern ("right-fringe");  
   staticpro (&Qright_fringe);  
3963    Qtty_color_mode = intern ("tty-color-mode");    Qtty_color_mode = intern ("tty-color-mode");
3964    staticpro (&Qtty_color_mode);    staticpro (&Qtty_color_mode);
3965    
3966      Qface_set_after_frame_default = intern ("face-set-after-frame-default");
3967      staticpro (&Qface_set_after_frame_default);
3968    
3969      Qfullwidth = intern ("fullwidth");
3970      staticpro (&Qfullwidth);
3971      Qfullheight = intern ("fullheight");
3972      staticpro (&Qfullheight);
3973      Qfullboth = intern ("fullboth");
3974      staticpro (&Qfullboth);
3975      Qx_resource_name = intern ("x-resource-name");
3976      staticpro (&Qx_resource_name);
3977    
3978      Qx_frame_parameter = intern ("x-frame-parameter");
3979      staticpro (&Qx_frame_parameter);
3980    
3981      {
3982        int i;
3983    
3984        for (i = 0; i < sizeof (frame_parms) / sizeof (frame_parms[0]); i++)
3985          {
3986            Lisp_Object v = intern (frame_parms[i].name);
3987            if (frame_parms[i].variable)
3988              {
3989                *frame_parms[i].variable = v;
3990                staticpro (frame_parms[i].variable);
3991              }
3992            Fput (v, Qx_frame_parameter, make_number (i));
3993          }
3994      }
3995    
3996    #ifdef HAVE_WINDOW_SYSTEM
3997      DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
3998        doc: /* The name Emacs uses to look up X resources.
3999    `x-get-resource' uses this as the first component of the instance name
4000    when requesting resource values.
4001    Emacs initially sets `x-resource-name' to the name under which Emacs
4002    was invoked, or to the value specified with the `-name' or `-rn'
4003    switches, if present.
4004    
4005    It may be useful to bind this variable locally around a call
4006    to `x-get-resource'.  See also the variable `x-resource-class'.  */);
4007      Vx_resource_name = Qnil;
4008    
4009      DEFVAR_LISP ("x-resource-class", &Vx_resource_class,
4010        doc: /* The class Emacs uses to look up X resources.
4011    `x-get-resource' uses this as the first component of the instance class
4012    when requesting resource values.
4013    
4014    Emacs initially sets `x-resource-class' to "Emacs".
4015    
4016    Setting this variable permanently is not a reasonable thing to do,
4017    but binding this variable locally around a call to `x-get-resource'
4018    is a reasonable practice.  See also the variable `x-resource-name'.  */);
4019      Vx_resource_class = build_string (EMACS_CLASS);
4020    #endif
4021    
4022    DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,    DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
4023                 doc: /* Alist of default values for frame creation.                 doc: /* Alist of default values for frame creation.
4024  These may be set in your init file, like this:  These may be set in your init file, like this:
# Line 2538  which need to do mouse handling at the L Line 4053  which need to do mouse handling at the L
4053    Vmouse_position_function = Qnil;    Vmouse_position_function = Qnil;
4054    
4055    DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,    DEFVAR_LISP ("mouse-highlight", &Vmouse_highlight,
4056                 doc: /* If non-nil, clickable text is highlighted when mouse is over it.                   doc: /* If non-nil, clickable text is highlighted when mouse is over it.
4057  If the value is an integer, highlighting is only shown after moving the  If the value is an integer, highlighting is only shown after moving the
4058  mouse, while keyboard input turns off the highlight even when the mouse  mouse, while keyboard input turns off the highlight even when the mouse
4059  is over the clickable text.  However, the mouse shape still indicates  is over the clickable text.  However, the mouse shape still indicates
4060  when the mouse is over clickable text.  */);  when the mouse is over clickable text.  */);
4061    Vmouse_highlight = Qt;    Vmouse_highlight = Qt;
4062    
4063      DEFVAR_LISP ("delete-frame-functions", &Vdelete_frame_functions,
4064                   doc: /* Functions to be run before deleting a frame.
4065    The functions are run with one arg, the frame to be deleted.
4066    See `delete-frame'.  */);
4067      Vdelete_frame_functions = Qnil;
4068    
4069    DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,    DEFVAR_KBOARD ("default-minibuffer-frame", Vdefault_minibuffer_frame,
4070                   doc: /* Minibufferless frames use this frame's minibuffer.                   doc: /* Minibufferless frames use this frame's minibuffer.
4071    
# Line 2607  This variable is local to the current te Line 4128  This variable is local to the current te
4128    defsubr (&Sset_frame_width);    defsubr (&Sset_frame_width);
4129    defsubr (&Sset_frame_size);    defsubr (&Sset_frame_size);
4130    defsubr (&Sset_frame_position);    defsubr (&Sset_frame_position);
4131    
4132    #ifdef HAVE_WINDOW_SYSTEM
4133      defsubr (&Sx_get_resource);
4134      defsubr (&Sx_parse_geometry);
4135    #endif
4136    
4137  }  }

Legend:
Removed from v.1.284  
changed lines
  Added in v.1.284.2.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26