comparison src/frame.c @ 5126:2a462149bd6a ben-lisp-object

merge
author Ben Wing <ben@xemacs.org>
date Wed, 24 Feb 2010 19:04:27 -0600
parents b5df3737028a 92dc90c0bb40
children a9c41067dd88
comparison
equal deleted inserted replaced
5125:b5df3737028a 5126:2a462149bd6a
1 /* Generic frame functions. 1 /* Generic frame functions.
2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. 2 Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996, 2002, 2003, 2005 Ben Wing. 3 Copyright (C) 1995, 1996, 2002, 2003, 2005, 2010 Ben Wing.
4 Copyright (C) 1995 Sun Microsystems, Inc. 4 Copyright (C) 1995 Sun Microsystems, Inc.
5 5
6 This file is part of XEmacs. 6 This file is part of XEmacs.
7 7
8 XEmacs is free software; you can redistribute it and/or modify it 8 XEmacs is free software; you can redistribute it and/or modify it
21 Boston, MA 02111-1307, USA. */ 21 Boston, MA 02111-1307, USA. */
22 22
23 /* Synched up with: FSF 19.30. */ 23 /* Synched up with: FSF 19.30. */
24 24
25 /* This file has been Mule-ized. */ 25 /* This file has been Mule-ized. */
26
27 /* About window and frame geometry [ben]:
28
29 Here is an ASCII diagram:
30
31 +------------------------------------------------------------------------|
32 | window-manager decoration |
33 | +--------------------------------------------------------------------+ |
34 | | menubar | |
35 | ###################################################################### |
36 | # toolbar # |
37 | #--------------------------------------------------------------------# |
38 | # | gutter | # |
39 | # |--------------------------------------------------------------| # |
40 | # | | internal border width | | # |
41 | # | | ******************************************************** | | # |
42 |w# | | * |s|v* |s* | | #w|
43 |i# | | * |c|e* |c* | | #i|
44 |n# | | * |r|r* |r* | | #n|
45 |d# | | * |o|t* |o* | | #d|
46 |o# | | * text area |l|.* text area |l* | | #o|
47 |w# | |i* |l| * |l*i| | #w|
48 |-# | |n* |b|d* |b*n| | #-|
49 |m# | |t* |a|i* |a*t| | #m|
50 |a# | |.* |r|v* |r*.| | #a|
51 |n# t| | *-------------------------+-|i*----------------------+-* | |t #n|
52 |a# o|g|b* scrollbar | |d* scrollbar | *b|g|o #a|
53 |g# o|u|o*-------------------------+-|e*----------------------+-*o|u|o #g|
54 |e# l|t|r* modeline |r* modeline *r|t|l #e|
55 |r# b|t|d********************************************************d|t|b #r|
56 | # a|e|e* =..texttexttex....= |s|v* |s*e|e|a # |
57 |d# r|r|r*o m=..texttexttextt..=o m|c|e* |c*r|r|r #d|
58 |e# | | *u a=.exttexttextte...=u a|r|r* |r* | | #e|
59 |c# | |w*t r=....texttexttex..=t r|o|t* |o*w| | #c|
60 |o# | |i*s g= etc. =s g|l|.* text area |l*i| | #o|
61 |r# | |d*i i= =i i|l| * |l*d| | #r|
62 |a# | |t*d n= =d n|b|d* |b*t| | #a|
63 |t# | |h*e = inner text area =e |a|i* |a*h| | #t|
64 |i# | | * = = |r|v* |r* | | #i|
65 |o# | | *---===================---+-|i*----------------------+-* | | #o|
66 |n# | | * scrollbar | |d* scrollbar | * | | #n|
67 | # | | *-------------------------+-|e*----------------------+-* | | # |
68 | # | | * modeline |r* modeline * | | # |
69 | # | | ******************************************************** | | # |
70 | # | | * minibuffer * | | # |
71 | # | | ******************************************************** | | # |
72 | # | | internal border width | | # |
73 | # |--------------------------------------------------------------| # |
74 | # | gutter | # |
75 | #--------------------------------------------------------------------# |
76 | # toolbar # |
77 | ###################################################################### |
78 | window manager decoration |
79 +------------------------------------------------------------------------+
80
81 # = boundary of client area; * = window boundaries, boundary of paned area
82 = = boundary of inner text area; . = inside margin area
83
84 Note in particular what happens at the corners, where a "corner box"
85 occurs. Top and bottom toolbars take precedence over left and right
86 toolbars, extending out horizontally into the corner boxes. Gutters
87 work the same way. The corner box where the scrollbars meet, however,
88 is assigned to neither scrollbar, and is known as the "dead box"; it is
89 an area that must be cleared specially.
90
91 THE FRAME
92 ---------
93
94 The "top-level window area" is the entire area of a top-level window (or
95 "frame"). The "client area" (a term from MS Windows) is the area of a
96 top-level window that XEmacs draws into and manages with redisplay.
97 This includes the toolbar, scrollbars, gutters, dividers, text area,
98 modeline and minibuffer. It does not include the menubar, title or
99 outer borders. The "non-client area" is the area of a top-level window
100 outside of the client area and includes the menubar, title and outer
101 borders. Internally, all frame coordinates are relative to the client
102 area.
103
104
105 THE NON-CLIENT AREA
106 -------------------
107
108 Under X, the non-client area is split into two parts:
109
110 (1) The outer layer is the window-manager decorations: The title and
111 borders. These are controlled by the window manager, a separate process
112 that controls the desktop, the location of icons, etc. When a process
113 tries to create a window, the window manager intercepts this action and
114 "reparents" the window, placing another window around it which contains
115 the window decorations, including the title bar, outer borders used for
116 resizing, etc. The window manager also implements any actions involving
117 the decorations, such as the ability to resize a window by dragging its
118 borders, move a window by dragging its title bar, etc. If there is no
119 window manager or you kill it, windows will have no decorations (and
120 will lose them if they previously had any) and you will not be able to
121 move or resize them.
122
123 (2) Inside of the window-manager decorations is the "shell", which is
124 managed by the toolkit and widget libraries your program is linked with.
125 The code in *-x.c uses the Xt toolkit and various possible widget
126 libraries built on top of Xt, such as Motif, Athena, the "Lucid"
127 widgets, etc. Another possibility is GTK (*-gtk.c), which implements
128 both the toolkit and widgets. Under Xt, the "shell" window is an
129 EmacsShell widget, containing an EmacsManager widget of the same size,
130 which in turn contains a menubar widget and an EmacsFrame widget, inside
131 of which is the client area. (The division into EmacsShell and
132 EmacsManager is due to the complex and screwy geometry-management system
133 in Xt [and X more generally]. The EmacsShell handles negotation with
134 the window manager; the place of the EmacsManager widget is normally
135 assumed by a widget that manages the geometry of its child widgets, but
136 the EmacsManager widget just lets the XEmacs redisplay mechanism do the
137 positioning.)
138
139 Under Windows, the non-client area is managed by the window system.
140 There is no division such as under X. Part of the window-system API
141 (USER.DLL) of Win32 includes functions to control the menubars, title,
142 etc. and implements the move and resize behavior. There *is* an
143 equivalent of the window manager, called the "shell", but it manages
144 only the desktop, not the windows themselves. The normal shell under
145 Windows is EXPLORER.EXE; if you kill this, you will lose the bar
146 containing the "Start" menu and tray and such, but the windows
147 themselves will not be affected or lose their decorations.
148
149
150 THE CLIENT AREA
151 ---------------
152
153 Inside of the client area is the toolbars, the gutters (where the buffer
154 tabs are displayed), the minibuffer, the internal border width, and one
155 or more non-overlapping "windows" (this is old Emacs terminology, from
156 before the time when frames existed at all; the standard terminology for
157 this would be "pane"). Each window can contain a modeline, horizontal
158 and/or vertical scrollbars, and (for non-rightmost windows) a vertical
159 divider, surrounding a text area.
160
161 The dimensions of the toolbars and gutters are determined by the formula
162 (THICKNESS + 2 * BORDER-THICKNESS), where "thickness" is a cover term
163 for height or width, as appropriate. The height and width come from
164 `default-toolbar-height' and `default-toolbar-width' and the specific
165 versions of these (`top-toolbar-height', `left-toolbar-width', etc.).
166 The border thickness comes from `default-toolbar-border-height' and
167 `default-toolbar-border-width', and the specific versions of these. The
168 gutter works exactly equivalently.
169
170 Note that for any particular toolbar or gutter, it will only be
171 displayed if [a] its visibility specifier (`default-toolbar-visible-p'
172 etc.) is non-nil; [b] its thickness (`default-toolbar-height' etc.) is
173 greater than 0; [c] its contents (`default-toolbar' etc.) are non-nil.
174
175 The position-specific toolbars interact with the default specifications
176 as follows: If the value for a position-specific specifier is not
177 defined in a particular domain (usually a window), and the position of
178 that specifier is set as the default position (using
179 `default-toolbar-position'), then the value from the corresponding
180 default specifier in that domain will be used. The gutters work the
181 same.
182
183
184 THE PANED AREA
185 --------------
186
187 The area occupied by the "windows" is called the paned area. Note that
188 this includes the minibuffer, which is just another window but is
189 special-cased in XEmacs. Each window can include a horizontal and/or
190 vertical scrollbar, a modeline and a vertical divider to its right, as
191 well as the text area. Only non-rightmost windows can include a
192 vertical divider. (The minibuffer normally does not include either
193 modeline or scrollbars.)
194
195 Note that, because the toolbars and gutters are controlled by
196 specifiers, and specifiers can have window-specific and buffer-specific
197 values, the size of the paned area can change depending on which window
198 is selected: In other words, if the selected window or buffer changes,
199 the entire paned area for the frame may change.
200
201
202 TEXT AREAS, FRINGES, MARGINS
203 ----------------------------
204
205 The space occupied by a window can be divided into the text area and the
206 fringes. The fringes include the modeline, scrollbars and vertical
207 divider on the right side (if any); inside of this is the text area,
208 where the text actually occurs. Note that a window may or may not
209 contain any of the elements that are part of the fringe -- this is
210 controlled by specifiers, e.g. `has-modeline-p',
211 `horizontal-scrollbar-visible-p', `vertical-scrollbar-visible-p',
212 `vertical-divider-always-visible-p', etc.
213
214 In addition, it is possible to set margins in the text area using the
215 specifiers `left-margin-width' and `right-margin-width'. When this is
216 done, only the "inner text area" (the area inside of the margins) will
217 be used for normal display of text; the margins will be used for glyphs
218 with a layout policy of `outside-margin' (as set on an extent containing
219 the glyph by `set-extent-begin-glyph-layout' or
220 `set-extent-end-glyph-layout'). However, the calculation of the text
221 area size (e.g. in the function `window-text-area-width') includes the
222 margins. Which margin is used depends on whether a glyph has been set
223 as the begin-glyph or end-glyph of an extent (`set-extent-begin-glyph'
224 etc.), using the left and right margins, respectively.
225
226 Technically, the margins outside of the inner text area are known as the
227 "outside margins". The "inside margins" are in the inner text area and
228 constitute the whitespace between the outside margins and the first or
229 last non-whitespace character in a line; their width can vary from line
230 to line. Glyphs will be placed in the inside margin if their layout
231 policy is `inside-margin' or `whitespace', with `whitespace' glyphs on
232 the inside and `inside-margin' glyphs on the outside. Inside-margin
233 glyphs can spill over into the outside margin if `use-left-overflow' or
234 `use-right-overflow', respectively, is non-nil.
235
236 See the Lisp Reference manual, under Annotations, for more details.
237
238
239 THE DISPLAYABLE AREA
240 --------------------
241
242 The "displayable area" is not so much an actual area as a convenient
243 fiction. It is the area used to convert between pixel and character
244 dimensions for frames. The character dimensions for a frame (e.g. as
245 returned by `frame-width' and `frame-height' and set by
246 `set-frame-width' and `set-frame-height') are determined from the
247 displayable area by dividing by the pixel size of the default font as
248 instantiated in the frame. (For proportional fonts, the "average" width
249 is used. Under Windows, this is a built-in property of the fonts.
250 Under X, this is based on the width of the lowercase 'n', or if this is
251 zero then the width of the default character. [We prefer 'n' to the
252 specified default character because many X fonts have a default
253 character with a zero or otherwise non-representative width.])
254
255 The displayable area is essentially the "theoretical" paned area of the
256 frame excluding the rightmost and bottom-most scrollbars. In this
257 context, "theoretical" means that all calculations on based on
258 frame-level values for toolbar, gutter and scrollbar thicknesses.
259 Because these thicknesses are controlled by specifiers, and specifiers
260 can have window-specific and buffer-specific values, these calculations
261 may or may not reflect the actual size of the paned area or of the
262 scrollbars when any particular window is selected. Note also that the
263 "displayable area" may not even be contiguous! In particular, if the
264 frame-level value of the horizontal scrollbar height is non-zero, then
265 the displayable area includes the paned area above and below the bottom
266 horizontal scrollbar but not the scrollbar itself.
267
268 As a further twist, the character-dimension calculations are adjusted so
269 that the truncation and continuation glyphs (see `truncation-glyph' and
270 `continuation-glyph') count as a single character even if they are wider
271 than the default font width. (Technically, the character width is
272 computed from the displayable-area width by subtracting the maximum of
273 the truncation-glyph width, continuation-glyph width and default-font
274 width before dividing by the default-font width, and then adding 1 to
275 the result.) (The ultimate motivation for this kludge as well as the
276 subtraction of the scrollbars, but not the minibuffer or bottom-most
277 modeline, is to maintain compatibility with TTY's.)
278
279 Despite all these concerns and kludges, however, the "displayable area"
280 concept works well in practice and mostly ensures that by default the
281 frame will actually fit 79 characters + continuation/truncation glyph.
282
283
284 WHICH FUNCTIONS USE WHICH?
285 --------------------------
286
287 [1] Top-level window area:
288
289 set-frame-position
290 `left' and `top' frame properties
291
292 [2] Client area:
293
294 frame-pixel-*, set-frame-pixel-*
295
296 [3] Paned area:
297
298 window-pixel-edges
299 event-x-pixel, event-y-pixel, event-properties, make-event
300
301 [4] Displayable area:
302
303 frame-width, frame-height and other all functions specifying frame size
304 in characters
305 frame-displayable-pixel-*
306
307 --ben
308
309 */
26 310
27 #include <config.h> 311 #include <config.h>
28 #include "lisp.h" 312 #include "lisp.h"
29 313
30 #include "buffer.h" /* for Vbuffer_alist */ 314 #include "buffer.h" /* for Vbuffer_alist */
118 Lisp_Object Vframe_being_created; 402 Lisp_Object Vframe_being_created;
119 Lisp_Object Qframe_being_created; 403 Lisp_Object Qframe_being_created;
120 404
121 static void store_minibuf_frame_prop (struct frame *f, Lisp_Object val); 405 static void store_minibuf_frame_prop (struct frame *f, Lisp_Object val);
122 406
123 typedef enum { 407 typedef enum
408 {
124 DISPLAYABLE_PIXEL_TO_CHAR, 409 DISPLAYABLE_PIXEL_TO_CHAR,
410 CHAR_TO_DISPLAYABLE_PIXEL,
125 TOTAL_PIXEL_TO_CHAR, 411 TOTAL_PIXEL_TO_CHAR,
126 CHAR_TO_TOTAL_PIXEL, 412 CHAR_TO_TOTAL_PIXEL,
127 CHAR_TO_DISPLAYABLE_PIXEL 413 TOTAL_PIXEL_TO_DISPLAYABLE_PIXEL,
128 } pixel_to_char_mode_t; 414 DISPLAYABLE_PIXEL_TO_TOTAL_PIXEL,
415 }
416 pixel_to_char_mode_t;
417
418 enum frame_size_type
419 {
420 SIZE_TOTAL_PIXEL,
421 SIZE_DISPLAYABLE_PIXEL,
422 SIZE_CHAR_CELL,
423 SIZE_FRAME_UNIT,
424 };
129 425
130 static void frame_conversion_internal (struct frame *f, 426 static void frame_conversion_internal (struct frame *f,
131 pixel_to_char_mode_t pixel_to_char, 427 enum frame_size_type source,
132 int *pixel_width, int *pixel_height, 428 int source_width, int source_height,
133 int *char_width, int *char_height, 429 enum frame_size_type dest,
134 int real_face); 430 int *dest_width, int *dest_height);
431 static void get_frame_char_size (struct frame *f, int *out_width,
432 int *out_height);
433 static void get_frame_displayable_pixel_size (struct frame *f, int *out_width,
434 int *out_height);
435
135 static struct display_line title_string_display_line; 436 static struct display_line title_string_display_line;
136 /* Used by generate_title_string. Global because they get used so much that 437 /* Used by generate_title_string. Global because they get used so much that
137 the dynamic allocation time adds up. */ 438 the dynamic allocation time adds up. */
138 static Ichar_dynarr *title_string_ichar_dynarr; 439 static Ichar_dynarr *title_string_ichar_dynarr;
139 440
651 { 952 {
652 reset_face_cachels (XWINDOW (f->minibuffer_window)); 953 reset_face_cachels (XWINDOW (f->minibuffer_window));
653 reset_glyph_cachels (XWINDOW (f->minibuffer_window)); 954 reset_glyph_cachels (XWINDOW (f->minibuffer_window));
654 } 955 }
655 956
656 change_frame_size (f, f->height, f->width, 0); 957 change_frame_size (f, f->width, f->height, 0);
657 } 958 }
658 959
659 MAYBE_FRAMEMETH (f, init_frame_2, (f, props)); 960 MAYBE_FRAMEMETH (f, init_frame_2, (f, props));
660 Fset_frame_properties (frame, props); 961 Fset_frame_properties (frame, props);
661 MAYBE_FRAMEMETH (f, init_frame_3, (f)); 962 MAYBE_FRAMEMETH (f, init_frame_3, (f));
696 will eventually do. Unfortunately gutter sizing code relies 997 will eventually do. Unfortunately gutter sizing code relies
697 on the frame in question being visible so we can't do this 998 on the frame in question being visible so we can't do this
698 earlier. */ 999 earlier. */
699 init_frame_gutters (f); 1000 init_frame_gutters (f);
700 1001
701 change_frame_size (f, f->height, f->width, 0); 1002 change_frame_size (f, f->width, f->height, 0);
702 } 1003 }
703 1004
704 if (first_frame_on_device) 1005 if (first_frame_on_device)
705 { 1006 {
706 if (first_frame_on_console) 1007 if (first_frame_on_console)
819 } 1120 }
820 1121
821 if (!keep_char_size) 1122 if (!keep_char_size)
822 { 1123 {
823 int height, width; 1124 int height, width;
824 pixel_to_char_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f), 1125 pixel_to_frame_unit_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f),
825 &width, &height); 1126 &width, &height);
826 change_frame_size (f, height, width, 0); 1127 change_frame_size (f, width, height, 0);
827 CLEAR_FRAME_SIZE_SLIPPED (f); 1128 CLEAR_FRAME_SIZE_SLIPPED (f);
828 } 1129 }
829 } 1130 }
830 1131
831 /* 1132 /*
1799 there. If this were not true, all of the frames present 2100 there. If this were not true, all of the frames present
1800 would have to be minibuffer-less, which implies that at some 2101 would have to be minibuffer-less, which implies that at some
1801 point their minibuffer frames must have been deleted, but 2102 point their minibuffer frames must have been deleted, but
1802 that is prohibited at the top; you can't delete surrogate 2103 that is prohibited at the top; you can't delete surrogate
1803 minibuffer frames. */ 2104 minibuffer frames. */
1804 if (NILP (frame_with_minibuf)) 2105 assert (!NILP (frame_with_minibuf));
1805 ABORT ();
1806 2106
1807 con->default_minibuffer_frame = frame_with_minibuf; 2107 con->default_minibuffer_frame = frame_with_minibuf;
1808 } 2108 }
1809 else 2109 else
1810 /* No frames left on this console--say no minibuffer either. */ 2110 /* No frames left on this console--say no minibuffer either. */
2303 2603
2304 2604
2305 /***************************************************************************/ 2605 /***************************************************************************/
2306 /* frame properties */ 2606 /* frame properties */
2307 /***************************************************************************/ 2607 /***************************************************************************/
2308
2309 static void internal_set_frame_size (struct frame *f, int cols, int rows,
2310 int pretend);
2311 2608
2312 static void 2609 static void
2313 store_minibuf_frame_prop (struct frame *f, Lisp_Object val) 2610 store_minibuf_frame_prop (struct frame *f, Lisp_Object val)
2314 { 2611 {
2315 /* This can call Lisp. */ 2612 /* This can call Lisp. */
2601 2898
2602 if (EQ (Qname, property)) return f->name; 2899 if (EQ (Qname, property)) return f->name;
2603 2900
2604 if (EQ (Qheight, property) || EQ (Qwidth, property)) 2901 if (EQ (Qheight, property) || EQ (Qwidth, property))
2605 { 2902 {
2606 if (window_system_pixelated_geometry (frame)) 2903 int width, height;
2607 { 2904 get_frame_char_size (f, &width, &height);
2608 int width, height; 2905 return make_int (EQ (Qheight, property) ? height : width);
2609 pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2610 &width, &height);
2611 return make_int (EQ (Qheight, property) ? height: width);
2612 }
2613 else
2614 return make_int (EQ (Qheight, property) ?
2615 FRAME_HEIGHT (f) :
2616 FRAME_WIDTH (f));
2617 } 2906 }
2618 2907
2619 /* NOTE: FSF returns Qnil instead of Qt for FRAME_HAS_MINIBUF_P. 2908 /* NOTE: FSF returns Qnil instead of Qt for FRAME_HAS_MINIBUF_P.
2620 This is over-the-top bogosity, because it's inconsistent with 2909 This is over-the-top bogosity, because it's inconsistent with
2621 the semantics of `minibuffer' when passed to `make-frame'. 2910 the semantics of `minibuffer' when passed to `make-frame'.
2703 FRAME_HAS_MINIBUF_P (f) ? Qt : 2992 FRAME_HAS_MINIBUF_P (f) ? Qt :
2704 FRAME_MINIBUF_WINDOW (f)), 2993 FRAME_MINIBUF_WINDOW (f)),
2705 result); 2994 result);
2706 { 2995 {
2707 int width, height; 2996 int width, height;
2708 2997 get_frame_char_size (f, &width, &height);
2709 if (window_system_pixelated_geometry (frame))
2710 {
2711 pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2712 &width, &height);
2713 }
2714 else
2715 {
2716 height = FRAME_HEIGHT (f);
2717 width = FRAME_WIDTH (f);
2718 }
2719 result = cons3 (Qwidth , make_int (width), result); 2998 result = cons3 (Qwidth , make_int (width), result);
2720 result = cons3 (Qheight, make_int (height), result); 2999 result = cons3 (Qheight, make_int (height), result);
2721 } 3000 }
2722 3001
2723 result = cons3 (Qname, f->name, result); 3002 result = cons3 (Qname, f->name, result);
2739 Return the height of the displayable area in pixels of FRAME. 3018 Return the height of the displayable area in pixels of FRAME.
2740 */ 3019 */
2741 (frame)) 3020 (frame))
2742 { 3021 {
2743 struct frame *f = decode_frame (frame); 3022 struct frame *f = decode_frame (frame);
2744 int height, pheight; 3023 int width, height;
2745 frame = wrap_frame (f); 3024
2746 3025 get_frame_displayable_pixel_size (f, &width, &height);
2747 if (!window_system_pixelated_geometry (frame)) 3026 return make_int (height);
2748 {
2749 height = FRAME_HEIGHT (f);
2750
2751 frame_conversion_internal (f, CHAR_TO_DISPLAYABLE_PIXEL,
2752 0, &pheight, 0, &height, 0);
2753 }
2754 else
2755 pheight = FRAME_PIXHEIGHT (f);
2756
2757 return make_int (pheight);
2758 } 3027 }
2759 3028
2760 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /* 3029 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /*
2761 Return the total width in pixels of FRAME. 3030 Return the total width in pixels of FRAME.
2762 */ 3031 */
2769 Return the width of the displayable area in pixels of FRAME. 3038 Return the width of the displayable area in pixels of FRAME.
2770 */ 3039 */
2771 (frame)) 3040 (frame))
2772 { 3041 {
2773 struct frame *f = decode_frame (frame); 3042 struct frame *f = decode_frame (frame);
2774 int width, pwidth; 3043 int width, height;
2775 frame = wrap_frame (f); 3044
2776 3045 get_frame_displayable_pixel_size (f, &width, &height);
2777 if (!window_system_pixelated_geometry (frame)) 3046 return make_int (width);
2778 {
2779 width = FRAME_WIDTH (f);
2780
2781 frame_conversion_internal (f, CHAR_TO_DISPLAYABLE_PIXEL,
2782 &pwidth, 0, &width, 0, 0);
2783 }
2784 else
2785 pwidth = FRAME_PIXWIDTH (f);
2786
2787 return make_int (pwidth);
2788 } 3047 }
2789 3048
2790 DEFUN ("frame-name", Fframe_name, 0, 1, 0, /* 3049 DEFUN ("frame-name", Fframe_name, 0, 1, 0, /*
2791 Return the name of FRAME (defaulting to the selected frame). 3050 Return the name of FRAME (defaulting to the selected frame).
2792 This is not the same as the `title' of the frame. 3051 This is not the same as the `title' of the frame.
2808 (frame)) 3067 (frame))
2809 { 3068 {
2810 return make_int (decode_frame (frame)->modiff); 3069 return make_int (decode_frame (frame)->modiff);
2811 } 3070 }
2812 3071
2813 static void 3072 void
2814 internal_set_frame_size (struct frame *f, int cols, int rows, int pretend) 3073 internal_set_frame_size (struct frame *f, int cols, int rows, int pretend)
2815 { 3074 {
2816 /* This can call Lisp. See mswindows_set_frame_size(). */ 3075 /* This can call Lisp. See mswindows_set_frame_size(). */
2817 /* An explicit size change cancels any pending frame size adjustment */ 3076 /* An explicit size change cancels any pending frame size adjustment */
2818 CLEAR_FRAME_SIZE_SLIPPED (f); 3077 CLEAR_FRAME_SIZE_SLIPPED (f);
2819 3078
2820 if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size)) 3079 if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size))
2821 change_frame_size (f, rows, cols, 0); 3080 change_frame_size (f, cols, rows, 0);
2822 else 3081 else
2823 FRAMEMETH (f, set_frame_size, (f, cols, rows)); 3082 FRAMEMETH (f, set_frame_size, (f, cols, rows));
2824 } 3083 }
2825 3084
2826 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /* 3085 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /*
2830 */ 3089 */
2831 (frame, lines, pretend)) 3090 (frame, lines, pretend))
2832 { 3091 {
2833 /* This can call Lisp. */ 3092 /* This can call Lisp. */
2834 struct frame *f = decode_frame (frame); 3093 struct frame *f = decode_frame (frame);
2835 int height, width; 3094 int cwidth, cheight;
2836 frame = wrap_frame (f); 3095 int guwidth, guheight;
3096
2837 CHECK_INT (lines); 3097 CHECK_INT (lines);
2838 3098 get_frame_char_size (f, &cwidth, &cheight);
2839 if (window_system_pixelated_geometry (frame)) 3099 cheight = XINT (lines);
2840 { 3100 frame_conversion_internal (f, SIZE_CHAR_CELL, cwidth, cheight,
2841 char_to_real_pixel_size (f, 0, XINT (lines), 0, &height); 3101 SIZE_FRAME_UNIT, &guwidth, &guheight);
2842 width = FRAME_PIXWIDTH (f); 3102 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2843 } 3103 return wrap_frame (f);
2844 else
2845 {
2846 height = XINT (lines);
2847 width = FRAME_WIDTH (f);
2848 }
2849
2850 internal_set_frame_size (f, width, height, !NILP (pretend));
2851 return frame;
2852 } 3104 }
2853 3105
2854 DEFUN ("set-frame-pixel-height", Fset_frame_pixel_height, 2, 3, 0, /* 3106 DEFUN ("set-frame-pixel-height", Fset_frame_pixel_height, 2, 3, 0, /*
2855 Specify that the frame FRAME is a total of HEIGHT pixels tall. 3107 Specify that the frame FRAME is a total of HEIGHT pixels tall.
2856 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall 3108 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall
2858 */ 3110 */
2859 (frame, height, pretend)) 3111 (frame, height, pretend))
2860 { 3112 {
2861 /* This can call Lisp. */ 3113 /* This can call Lisp. */
2862 struct frame *f = decode_frame (frame); 3114 struct frame *f = decode_frame (frame);
2863 int pheight, width; 3115 int pwidth, pheight;
2864 frame = wrap_frame (f); 3116 int guwidth, guheight;
3117
2865 CHECK_INT (height); 3118 CHECK_INT (height);
2866 3119 pheight = XINT (height);
2867 if (!window_system_pixelated_geometry (frame)) 3120 pwidth = FRAME_PIXWIDTH (f);
2868 { 3121 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
2869 int h = XINT (height); 3122 SIZE_FRAME_UNIT, &guwidth, &guheight);
2870 width = FRAME_WIDTH (f); 3123 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2871 3124 return wrap_frame (f);
2872 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, 0, &h, 0, &pheight, 0);
2873 }
2874 else
2875 {
2876 width = FRAME_PIXWIDTH (f);
2877 pheight = XINT (height);
2878 }
2879
2880 internal_set_frame_size (f, width, pheight, !NILP (pretend));
2881 return frame;
2882 } 3125 }
2883 3126
2884 DEFUN ("set-frame-displayable-pixel-height", Fset_frame_displayable_pixel_height, 2, 3, 0, /* 3127 DEFUN ("set-frame-displayable-pixel-height", Fset_frame_displayable_pixel_height, 2, 3, 0, /*
2885 Specify that the displayable area of frame FRAME is HEIGHT pixels tall. 3128 Specify that the displayable area of frame FRAME is HEIGHT pixels tall.
2886 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall 3129 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall
2888 */ 3131 */
2889 (frame, height, pretend)) 3132 (frame, height, pretend))
2890 { 3133 {
2891 /* This can call Lisp. */ 3134 /* This can call Lisp. */
2892 struct frame *f = decode_frame (frame); 3135 struct frame *f = decode_frame (frame);
2893 int pheight, width; 3136 int pwidth, pheight;
2894 frame = wrap_frame (f); 3137 int guwidth, guheight;
3138
2895 CHECK_INT (height); 3139 CHECK_INT (height);
2896 3140 get_frame_displayable_pixel_size (f, &pwidth, &pheight);
2897 if (!window_system_pixelated_geometry (frame)) 3141 pheight = XINT (height);
2898 { 3142 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
2899 int h = XINT (height); 3143 SIZE_FRAME_UNIT, &guwidth, &guheight);
2900 width = FRAME_WIDTH (f); 3144 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2901 frame_conversion_internal (f, DISPLAYABLE_PIXEL_TO_CHAR, 0, &h, 0, &pheight, 0); 3145 return wrap_frame (f);
2902 }
2903 else
2904 {
2905 width = FRAME_PIXWIDTH (f);
2906 pheight = XINT (height);
2907 }
2908
2909 internal_set_frame_size (f, width, pheight, !NILP (pretend));
2910 return frame;
2911 } 3146 }
2912 3147
2913 3148
2914 DEFUN ("set-frame-width", Fset_frame_width, 2, 3, 0, /* 3149 DEFUN ("set-frame-width", Fset_frame_width, 2, 3, 0, /*
2915 Specify that the frame FRAME has COLS columns. 3150 Specify that the frame FRAME has COLS columns.
2918 */ 3153 */
2919 (frame, cols, pretend)) 3154 (frame, cols, pretend))
2920 { 3155 {
2921 /* This can call Lisp. */ 3156 /* This can call Lisp. */
2922 struct frame *f = decode_frame (frame); 3157 struct frame *f = decode_frame (frame);
2923 int width, height; 3158 int cwidth, cheight;
2924 frame = wrap_frame (f); 3159 int guwidth, guheight;
3160
2925 CHECK_INT (cols); 3161 CHECK_INT (cols);
2926 3162 get_frame_char_size (f, &cwidth, &cheight);
2927 if (window_system_pixelated_geometry (frame)) 3163 cwidth = XINT (cols);
2928 { 3164 frame_conversion_internal (f, SIZE_CHAR_CELL, cwidth, cheight,
2929 char_to_real_pixel_size (f, XINT (cols), 0, &width, 0); 3165 SIZE_FRAME_UNIT, &guwidth, &guheight);
2930 height = FRAME_PIXHEIGHT (f); 3166 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2931 } 3167 return wrap_frame (f);
2932 else
2933 {
2934 width = XINT (cols);
2935 height = FRAME_HEIGHT (f);
2936 }
2937
2938 internal_set_frame_size (f, width, height, !NILP (pretend));
2939 return frame;
2940 } 3168 }
2941 3169
2942 DEFUN ("set-frame-pixel-width", Fset_frame_pixel_width, 2, 3, 0, /* 3170 DEFUN ("set-frame-pixel-width", Fset_frame_pixel_width, 2, 3, 0, /*
2943 Specify that the frame FRAME is a total of WIDTH pixels wide. 3171 Specify that the frame FRAME is a total of WIDTH pixels wide.
2944 Optional third arg non-nil means that redisplay should be WIDTH wide 3172 Optional third arg non-nil means that redisplay should be WIDTH wide
2946 */ 3174 */
2947 (frame, width, pretend)) 3175 (frame, width, pretend))
2948 { 3176 {
2949 /* This can call Lisp. */ 3177 /* This can call Lisp. */
2950 struct frame *f = decode_frame (frame); 3178 struct frame *f = decode_frame (frame);
2951 int height, pwidth; 3179 int pwidth, pheight;
2952 frame = wrap_frame (f); 3180 int guwidth, guheight;
3181
2953 CHECK_INT (width); 3182 CHECK_INT (width);
2954 3183 pwidth = XINT (width);
2955 if (!window_system_pixelated_geometry (frame)) 3184 pheight = FRAME_PIXHEIGHT (f);
2956 { 3185 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
2957 int w = XINT (width); 3186 SIZE_FRAME_UNIT, &guwidth, &guheight);
2958 height = FRAME_HEIGHT (f); 3187 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2959 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, &w, 0, &pwidth, 0, 0); 3188 return wrap_frame (f);
2960 }
2961 else
2962 {
2963 height = FRAME_PIXHEIGHT (f);
2964 pwidth = XINT (width);
2965 }
2966
2967 internal_set_frame_size (f, pwidth, height, !NILP (pretend));
2968 return frame;
2969 } 3189 }
2970 3190
2971 DEFUN ("set-frame-displayable-pixel-width", Fset_frame_displayable_pixel_width, 2, 3, 0, /* 3191 DEFUN ("set-frame-displayable-pixel-width", Fset_frame_displayable_pixel_width, 2, 3, 0, /*
2972 Specify that the displayable area of frame FRAME is WIDTH pixels wide. 3192 Specify that the displayable area of frame FRAME is WIDTH pixels wide.
2973 Optional third arg non-nil means that redisplay should be WIDTH wide 3193 Optional third arg non-nil means that redisplay should be WIDTH wide
2975 */ 3195 */
2976 (frame, width, pretend)) 3196 (frame, width, pretend))
2977 { 3197 {
2978 /* This can call Lisp. */ 3198 /* This can call Lisp. */
2979 struct frame *f = decode_frame (frame); 3199 struct frame *f = decode_frame (frame);
2980 int height, pwidth; 3200 int pwidth, pheight;
2981 frame = wrap_frame (f); 3201 int guwidth, guheight;
3202
2982 CHECK_INT (width); 3203 CHECK_INT (width);
2983 3204 get_frame_displayable_pixel_size (f, &pwidth, &pheight);
2984 if (!window_system_pixelated_geometry (frame)) 3205 pwidth = XINT (width);
2985 { 3206 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
2986 int w = XINT (width); 3207 SIZE_FRAME_UNIT, &guwidth, &guheight);
2987 height = FRAME_HEIGHT (f); 3208 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2988 frame_conversion_internal (f, DISPLAYABLE_PIXEL_TO_CHAR, &w, 0, &pwidth, 0, 0); 3209 return wrap_frame (f);
2989 }
2990 else
2991 {
2992 height = FRAME_PIXHEIGHT (f);
2993 pwidth = XINT (width);
2994 }
2995
2996 internal_set_frame_size (f, pwidth, height, !NILP (pretend));
2997 return frame;
2998 } 3210 }
2999 3211
3000 DEFUN ("set-frame-size", Fset_frame_size, 3, 4, 0, /* 3212 DEFUN ("set-frame-size", Fset_frame_size, 3, 4, 0, /*
3001 Set the size of FRAME to COLS by ROWS, measured in characters. 3213 Set the size of FRAME to COLS by ROWS, measured in characters.
3002 Optional fourth arg non-nil means that redisplay should use COLS by ROWS 3214 Optional fourth arg non-nil means that redisplay should use COLS by ROWS
3004 */ 3216 */
3005 (frame, cols, rows, pretend)) 3217 (frame, cols, rows, pretend))
3006 { 3218 {
3007 /* This can call Lisp. */ 3219 /* This can call Lisp. */
3008 struct frame *f = decode_frame (frame); 3220 struct frame *f = decode_frame (frame);
3009 int height, width; 3221 int guwidth, guheight;
3010 frame = wrap_frame (f); 3222
3011 CHECK_INT (cols); 3223 CHECK_INT (cols);
3012 CHECK_INT (rows); 3224 CHECK_INT (rows);
3013 3225 frame_conversion_internal (f, SIZE_CHAR_CELL, XINT (cols), XINT (rows),
3014 if (window_system_pixelated_geometry (frame)) 3226 SIZE_FRAME_UNIT, &guwidth, &guheight);
3015 char_to_real_pixel_size (f, XINT (cols), XINT (rows), &width, &height); 3227 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3016 else 3228 return wrap_frame (f);
3017 {
3018 height = XINT (rows);
3019 width = XINT (cols);
3020 }
3021
3022 internal_set_frame_size (f, width, height, !NILP (pretend));
3023 return frame;
3024 } 3229 }
3025 3230
3026 DEFUN ("set-frame-pixel-size", Fset_frame_pixel_size, 3, 4, 0, /* 3231 DEFUN ("set-frame-pixel-size", Fset_frame_pixel_size, 3, 4, 0, /*
3027 Set the total size of FRAME to WIDTH by HEIGHT, measured in pixels. 3232 Set the total size of FRAME to WIDTH by HEIGHT, measured in pixels.
3028 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT 3233 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT
3030 */ 3235 */
3031 (frame, width, height, pretend)) 3236 (frame, width, height, pretend))
3032 { 3237 {
3033 /* This can call Lisp. */ 3238 /* This can call Lisp. */
3034 struct frame *f = decode_frame (frame); 3239 struct frame *f = decode_frame (frame);
3035 int pheight, pwidth; 3240 int guwidth, guheight;
3036 frame = wrap_frame (f); 3241
3037 CHECK_INT (width); 3242 CHECK_INT (width);
3038 CHECK_INT (height); 3243 CHECK_INT (height);
3039 3244 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, XINT (width), XINT (height),
3040 if (!window_system_pixelated_geometry (frame)) 3245 SIZE_FRAME_UNIT, &guwidth, &guheight);
3041 { 3246 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3042 int w = XINT (width); 3247 return wrap_frame (f);
3043 int h = XINT (height);
3044 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, &w, &h, &pwidth, &pheight, 0);
3045 }
3046 else
3047 {
3048 pheight = XINT (height);
3049 pwidth = XINT (width);
3050 }
3051
3052 internal_set_frame_size (f, pwidth, pheight, !NILP (pretend));
3053 return frame;
3054 } 3248 }
3055 3249
3056 DEFUN ("set-frame-displayable-pixel-size", Fset_frame_displayable_pixel_size, 3, 4, 0, /* 3250 DEFUN ("set-frame-displayable-pixel-size", Fset_frame_displayable_pixel_size, 3, 4, 0, /*
3057 Set the displayable size of FRAME to WIDTH by HEIGHT, measured in pixels. 3251 Set the displayable size of FRAME to WIDTH by HEIGHT, measured in pixels.
3058 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT 3252 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT
3060 */ 3254 */
3061 (frame, width, height, pretend)) 3255 (frame, width, height, pretend))
3062 { 3256 {
3063 /* This can call Lisp. */ 3257 /* This can call Lisp. */
3064 struct frame *f = decode_frame (frame); 3258 struct frame *f = decode_frame (frame);
3065 int pheight, pwidth; 3259 int guwidth, guheight;
3066 frame = wrap_frame (f); 3260
3067 CHECK_INT (width); 3261 CHECK_INT (width);
3068 CHECK_INT (height); 3262 CHECK_INT (height);
3069 3263 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL,
3070 if (!window_system_pixelated_geometry (frame)) 3264 XINT (width), XINT (height),
3071 { 3265 SIZE_FRAME_UNIT, &guwidth, &guheight);
3072 int w = XINT (width); 3266 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3073 int h = XINT (height); 3267 return wrap_frame (f);
3074 frame_conversion_internal (f, DISPLAYABLE_PIXEL_TO_CHAR, &w, &h, &pwidth, &pheight, 0);
3075 }
3076 else
3077 {
3078 pheight = XINT (height);
3079 pwidth = XINT (width);
3080 }
3081
3082 internal_set_frame_size (f, pwidth, pheight, !NILP (pretend));
3083 return frame;
3084 } 3268 }
3085 3269
3086 DEFUN ("set-frame-position", Fset_frame_position, 3, 3, 0, /* 3270 DEFUN ("set-frame-position", Fset_frame_position, 3, 3, 0, /*
3087 Set position of FRAME in pixels to XOFFSET by YOFFSET. 3271 Set position of FRAME in pixels to XOFFSET by YOFFSET.
3088 This is actually the position of the upper left corner of the frame. 3272 This is actually the position of the upper left corner of the frame.
3103 3287
3104 3288
3105 /* Frame size conversion functions moved here from EmacsFrame.c 3289 /* Frame size conversion functions moved here from EmacsFrame.c
3106 because they're generic and really don't belong in that file. 3290 because they're generic and really don't belong in that file.
3107 Function get_default_char_pixel_size() removed because it's 3291 Function get_default_char_pixel_size() removed because it's
3108 exactly the same as default_face_height_and_width(). */ 3292 exactly the same as default_face_width_and_height().
3293
3294 Convert between total pixel size, displayable pixel size and
3295 character-cell size. Variables are either "in" or "out"
3296 depending on the value of PIXEL_TO_CHAR.
3297 */
3109 static void 3298 static void
3110 frame_conversion_internal (struct frame *f, 3299 frame_conversion_internal_1 (struct frame *f,
3111 pixel_to_char_mode_t pixel_to_char, 3300 pixel_to_char_mode_t pixel_to_char,
3112 int *pixel_width, int *pixel_height, 3301 int *total_pixel_width, int *total_pixel_height,
3113 int *char_width, int *char_height, 3302 int *disp_pixel_width, int *disp_pixel_height,
3114 int real_face) 3303 int *char_width, int *char_height)
3115 { 3304 {
3116 int cpw; 3305 int cpw, cph;
3117 int cph;
3118 int egw; 3306 int egw;
3119 int obw, obh, bdr; 3307 int obw, obh, bdr;
3120 Lisp_Object frame, window; 3308 Lisp_Object frame, window;
3121 3309
3122 frame = wrap_frame (f); 3310 frame = wrap_frame (f);
3123 if (real_face) 3311 default_face_width_and_height (frame, &cpw, &cph);
3124 default_face_height_and_width (frame, &cph, &cpw);
3125 else
3126 default_face_height_and_width_1 (frame, &cph, &cpw);
3127 3312
3128 window = FRAME_SELECTED_WINDOW (f); 3313 window = FRAME_SELECTED_WINDOW (f);
3129 3314
3315 /* #### It really seems like we should also be subtracting out the
3316 theoretical gutter width and height, just like we do for toolbars.
3317 There is currently a bug where if you call `set-frame-pixel-width'
3318 on MS Windows (at least, possibly also X) things get confused and
3319 the top of the root window overlaps the top gutter instead of being
3320 below it. This gets fixed next time you resize the frame using the
3321 mouse. Possibly this is caused by not handling the gutter height
3322 here? */
3130 egw = max (glyph_width (Vcontinuation_glyph, window), 3323 egw = max (glyph_width (Vcontinuation_glyph, window),
3131 glyph_width (Vtruncation_glyph, window)); 3324 glyph_width (Vtruncation_glyph, window));
3132 egw = max (egw, cpw); 3325 egw = max (egw, cpw);
3133 bdr = 2 * f->internal_border_width; 3326 bdr = 2 * f->internal_border_width;
3134 obw = FRAME_SCROLLBAR_WIDTH (f) + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f) + 3327 obw = FRAME_SCROLLBAR_WIDTH (f) + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f) +
3147 much space. */ 3340 much space. */
3148 switch (pixel_to_char) 3341 switch (pixel_to_char)
3149 { 3342 {
3150 case DISPLAYABLE_PIXEL_TO_CHAR: 3343 case DISPLAYABLE_PIXEL_TO_CHAR:
3151 if (char_width) 3344 if (char_width)
3152 *char_width = ROUND_UP (*pixel_width, cpw) / cpw; 3345 *char_width = ROUND_UP (*disp_pixel_width, cpw) / cpw;
3153 if (char_height) 3346 if (char_height)
3154 *char_height = ROUND_UP (*pixel_height, cph) / cph; 3347 *char_height = ROUND_UP (*disp_pixel_height, cph) / cph;
3348 break;
3349 case CHAR_TO_DISPLAYABLE_PIXEL:
3350 if (disp_pixel_width)
3351 *disp_pixel_width = *char_width * cpw;
3352 if (disp_pixel_height)
3353 *disp_pixel_height = *char_height * cph;
3155 break; 3354 break;
3156 case TOTAL_PIXEL_TO_CHAR: 3355 case TOTAL_PIXEL_TO_CHAR:
3157 /* Convert to chars so that the total frame size is pixel_width x 3356 /* Convert to chars so that the total frame size is pixel_width x
3158 pixel_height. */ 3357 pixel_height. */
3159 if (char_width) 3358 if (char_width)
3160 *char_width = 1 + ((*pixel_width - egw) - bdr - obw) / cpw; 3359 *char_width = 1 + ((*total_pixel_width - egw) - bdr - obw) / cpw;
3161 if (char_height) 3360 if (char_height)
3162 *char_height = (*pixel_height - bdr - obh) / cph; 3361 *char_height = (*total_pixel_height - bdr - obh) / cph;
3163 break; 3362 break;
3164 case CHAR_TO_TOTAL_PIXEL: 3363 case CHAR_TO_TOTAL_PIXEL:
3165 if (pixel_width) 3364 if (total_pixel_width)
3166 *pixel_width = (*char_width - 1) * cpw + egw + bdr + obw; 3365 *total_pixel_width = (*char_width - 1) * cpw + egw + bdr + obw;
3167 if (pixel_height) 3366 if (total_pixel_height)
3168 *pixel_height = *char_height * cph + bdr + obh; 3367 *total_pixel_height = *char_height * cph + bdr + obh;
3169 break; 3368 break;
3170 case CHAR_TO_DISPLAYABLE_PIXEL: 3369 case TOTAL_PIXEL_TO_DISPLAYABLE_PIXEL:
3171 if (pixel_width) 3370 /* Convert to chars so that the total frame size is pixel_width x
3172 *pixel_width = *char_width * cpw; 3371 pixel_height. */
3173 if (pixel_height) 3372 if (disp_pixel_width)
3174 *pixel_height = *char_height * cph; 3373 *disp_pixel_width = cpw + (*total_pixel_width - egw) - bdr - obw;
3374 if (disp_pixel_height)
3375 *disp_pixel_height = *total_pixel_height - bdr - obh;
3175 break; 3376 break;
3176 } 3377 case DISPLAYABLE_PIXEL_TO_TOTAL_PIXEL:
3177 } 3378 if (total_pixel_width)
3178 3379 *total_pixel_width = *disp_pixel_width - cpw + egw + bdr + obw;
3179 /* This takes the size in pixels of the text area, and returns the number 3380 if (total_pixel_height)
3381 *total_pixel_height = *disp_pixel_height + bdr + obh;
3382 break;
3383 }
3384 }
3385
3386
3387 static enum frame_size_type
3388 canonicalize_frame_size_type (enum frame_size_type type, int pixgeom)
3389 {
3390 if (type == SIZE_FRAME_UNIT)
3391 {
3392 if (pixgeom)
3393 type = SIZE_DISPLAYABLE_PIXEL;
3394 else
3395 type = SIZE_CHAR_CELL;
3396 }
3397 return type;
3398 }
3399
3400 /* Basic frame conversion function. Convert source size to destination
3401 size, where either of them can be in total pixels, displayable pixels,
3402 frame units or character-cell units. */
3403
3404 static void
3405 frame_conversion_internal (struct frame *f,
3406 enum frame_size_type source,
3407 int source_width, int source_height,
3408 enum frame_size_type dest,
3409 int *dest_width, int *dest_height)
3410 {
3411 int pixgeom = window_system_pixelated_geometry (wrap_frame (f));
3412 dest = canonicalize_frame_size_type (dest, pixgeom);
3413 source = canonicalize_frame_size_type (source, pixgeom);
3414 if (source == dest)
3415 {
3416 *dest_width = source_width;
3417 *dest_height = source_height;
3418 }
3419 else if (source == SIZE_TOTAL_PIXEL && dest == SIZE_CHAR_CELL)
3420 frame_conversion_internal_1 (f, TOTAL_PIXEL_TO_CHAR,
3421 &source_width, &source_height, 0, 0,
3422 dest_width, dest_height);
3423 else if (source == SIZE_DISPLAYABLE_PIXEL && dest == SIZE_CHAR_CELL)
3424 frame_conversion_internal_1 (f, DISPLAYABLE_PIXEL_TO_CHAR, 0, 0,
3425 &source_width, &source_height,
3426 dest_width, dest_height);
3427 else if (source == SIZE_TOTAL_PIXEL && dest == SIZE_DISPLAYABLE_PIXEL)
3428 frame_conversion_internal_1 (f, TOTAL_PIXEL_TO_DISPLAYABLE_PIXEL,
3429 &source_width, &source_height,
3430 dest_width, dest_height, 0, 0);
3431 else if (dest == SIZE_TOTAL_PIXEL && source == SIZE_CHAR_CELL)
3432 frame_conversion_internal_1 (f, CHAR_TO_TOTAL_PIXEL,
3433 dest_width, dest_height, 0, 0,
3434 &source_width, &source_height);
3435 else if (dest == SIZE_DISPLAYABLE_PIXEL && source == SIZE_CHAR_CELL)
3436 frame_conversion_internal_1 (f, CHAR_TO_DISPLAYABLE_PIXEL, 0, 0,
3437 dest_width, dest_height,
3438 &source_width, &source_height);
3439 else if (dest == SIZE_TOTAL_PIXEL && source == SIZE_DISPLAYABLE_PIXEL)
3440 frame_conversion_internal_1 (f, DISPLAYABLE_PIXEL_TO_TOTAL_PIXEL,
3441 dest_width, dest_height,
3442 &source_width, &source_height, 0, 0);
3443 else
3444 {
3445 ABORT ();
3446 if (dest_width)
3447 *dest_width = 0;
3448 if (dest_height)
3449 *dest_height = 0;
3450 }
3451 }
3452
3453 /* This takes the size in pixels of the client area, and returns the number
3180 of characters that will fit there, taking into account the internal 3454 of characters that will fit there, taking into account the internal
3181 border width, and the pixel width of the line terminator glyphs (which 3455 border width, and the pixel width of the line terminator glyphs (which
3182 always count as one "character" wide, even if they are not the same size 3456 always count as one "character" wide, even if they are not the same size
3183 as the default character size of the default font). The frame scrollbar 3457 as the default character size of the default font). The frame scrollbar
3184 width and left and right toolbar widths are also subtracted out of the 3458 width and left and right toolbar widths are also subtracted out of the
3185 available width. The frame scrollbar height and top and bottom toolbar 3459 available width. The frame scrollbar height and top and bottom toolbar
3186 heights are subtracted out of the available height. 3460 heights are subtracted out of the available height.
3187 3461
3188 Therefore the result is not necessarily a multiple of anything in 3462 Therefore the result is not necessarily a multiple of anything in
3189 particular. */ 3463 particular. */
3464
3190 void 3465 void
3191 pixel_to_char_size (struct frame *f, int pixel_width, int pixel_height, 3466 pixel_to_char_size (struct frame *f, int pixel_width, int pixel_height,
3192 int *char_width, int *char_height) 3467 int *char_width, int *char_height)
3193 { 3468 {
3194 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, 3469 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pixel_width, pixel_height,
3195 &pixel_width, &pixel_height, char_width, 3470 SIZE_CHAR_CELL, char_width, char_height);
3196 char_height, 0); 3471 }
3197 } 3472
3198 3473 /* Given a character size, this returns the minimum pixel size of the
3199 /* Given a character size, this returns the minimum number of pixels 3474 client area necessary to display that many characters, taking into
3200 necessary to display that many characters, taking into account the 3475 account the internal border width, scrollbar height and width, toolbar
3201 internal border width, scrollbar height and width, toolbar heights and 3476 heights and widths and the size of the line terminator glyphs (assuming
3202 widths and the size of the line terminator glyphs (assuming the line 3477 the line terminators take up exactly one character position).
3203 terminators take up exactly one character position).
3204 3478
3205 Therefore the result is not necessarily a multiple of anything in 3479 Therefore the result is not necessarily a multiple of anything in
3206 particular. */ 3480 particular. */
3481
3207 void 3482 void
3208 char_to_pixel_size (struct frame *f, int char_width, int char_height, 3483 char_to_pixel_size (struct frame *f, int char_width, int char_height,
3209 int *pixel_width, int *pixel_height) 3484 int *pixel_width, int *pixel_height)
3210 { 3485 {
3211 frame_conversion_internal (f, CHAR_TO_TOTAL_PIXEL, 3486 frame_conversion_internal (f, SIZE_CHAR_CELL, char_width, char_height,
3212 pixel_width, pixel_height, &char_width, 3487 SIZE_TOTAL_PIXEL, pixel_width, pixel_height);
3213 &char_height, 0); 3488 }
3214 } 3489
3215 3490 /* Versions of the above that operate in "frame units" instead of
3216 /* Given a pixel size, rounds DOWN to the smallest size in pixels necessary 3491 characters. frame units are the same as characters except on
3217 to display the same number of characters as are displayable now. 3492 MS Windows and MS Printer frames, where they are displayable-area
3218 */ 3493 pixels. */
3494
3495 void
3496 pixel_to_frame_unit_size (struct frame *f, int pixel_width, int pixel_height,
3497 int *frame_unit_width, int *frame_unit_height)
3498 {
3499 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pixel_width, pixel_height,
3500 SIZE_FRAME_UNIT, frame_unit_width,
3501 frame_unit_height);
3502 }
3503
3504 void
3505 frame_unit_to_pixel_size (struct frame *f, int frame_unit_width,
3506 int frame_unit_height,
3507 int *pixel_width, int *pixel_height)
3508 {
3509 frame_conversion_internal (f, SIZE_FRAME_UNIT, frame_unit_width,
3510 frame_unit_height,
3511 SIZE_TOTAL_PIXEL, pixel_width, pixel_height);
3512 }
3513
3219 void 3514 void
3220 round_size_to_char (struct frame *f, int in_width, int in_height, 3515 round_size_to_char (struct frame *f, int in_width, int in_height,
3221 int *out_width, int *out_height) 3516 int *out_width, int *out_height)
3222 { 3517 {
3223 int char_width; 3518 int char_width;
3224 int char_height; 3519 int char_height;
3225 pixel_to_char_size (f, in_width, in_height, &char_width, &char_height); 3520 pixel_to_char_size (f, in_width, in_height, &char_width, &char_height);
3226 char_to_pixel_size (f, char_width, char_height, out_width, out_height); 3521 char_to_pixel_size (f, char_width, char_height, out_width, out_height);
3227 } 3522 }
3228 3523
3229 /* Versions of the above which always account for real font metrics. 3524 /* Get the frame size in character cells, recalculating on the fly.
3230 */ 3525 #### The logic of this function follows former logic elsewhere,
3231 void 3526 which used FRAME_PIXWIDTH() on pixelated-geometry systems but
3232 pixel_to_real_char_size (struct frame *f, int pixel_width, int pixel_height, 3527 FRAME_WIDTH() on non-pixelated-geometry systems. Not clear why not
3233 int *char_width, int *char_height) 3528 always just use one or the other.
3234 { 3529
3235 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, 3530 Why don't we just use FRAME_CHARWIDTH() etc. in get_frame_char_size()?
3236 &pixel_width, &pixel_height, char_width, 3531 That wouldn't work because change_frame_size_1() depends on the
3237 char_height, 1); 3532 following function to *set* the values of FRAME_CHARWIDTH() etc.
3238 } 3533
3239 3534 But elsewhere I suppose we could use it.
3240 void 3535 */
3241 char_to_real_pixel_size (struct frame *f, int char_width, int char_height, 3536
3242 int *pixel_width, int *pixel_height)
3243 {
3244 frame_conversion_internal (f, CHAR_TO_TOTAL_PIXEL,
3245 pixel_width, pixel_height, &char_width,
3246 &char_height, 1);
3247 }
3248
3249 void
3250 round_size_to_real_char (struct frame *f, int in_width, int in_height,
3251 int *out_width, int *out_height)
3252 {
3253 int char_width;
3254 int char_height;
3255 pixel_to_real_char_size (f, in_width, in_height, &char_width, &char_height);
3256 char_to_real_pixel_size (f, char_width, char_height, out_width, out_height);
3257 }
3258
3259 /* Change the frame height and/or width. Values may be given as zero to
3260 indicate no change is to take place. */
3261 static void 3537 static void
3262 change_frame_size_1 (struct frame *f, int newheight, int newwidth) 3538 get_frame_char_size (struct frame *f, int *out_width, int *out_height)
3263 { 3539 {
3264 Lisp_Object frame; 3540 if (window_system_pixelated_geometry (wrap_frame (f)))
3541 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
3542 out_width, out_height);
3543 else
3544 {
3545 *out_width = FRAME_WIDTH (f);
3546 *out_height = FRAME_HEIGHT (f);
3547 }
3548 }
3549
3550 static void
3551 get_frame_displayable_pixel_size (struct frame *f, int *out_width,
3552 int *out_height)
3553 {
3554 frame_conversion_internal (f, SIZE_FRAME_UNIT, FRAME_WIDTH (f),
3555 FRAME_HEIGHT (f), SIZE_DISPLAYABLE_PIXEL,
3556 out_width, out_height);
3557 }
3558
3559 /* Change the frame height and/or width. Values passed in are in
3560 frame units (character cells on X/GTK, displayable-area pixels
3561 on MS Windows or generally on pixelated-geometry window systems). */
3562 static void
3563 change_frame_size_1 (struct frame *f, int newwidth, int newheight)
3564 {
3265 int new_pixheight, new_pixwidth; 3565 int new_pixheight, new_pixwidth;
3266 int font_height, real_font_height, font_width; 3566 int real_font_height, real_font_width;
3267 3567
3268 /* #### Chuck -- shouldn't we be checking to see if the frame 3568 /* #### Chuck -- shouldn't we be checking to see if the frame
3269 is being "changed" to its existing size, and do nothing if so? */ 3569 is being "changed" to its existing size, and do nothing if so? */
3270 /* No, because it would hose toolbar updates. The toolbar 3570 /* No, because it would hose toolbar updates. The toolbar
3271 update code relies on this function to cause window `top' and 3571 update code relies on this function to cause window `top' and
3272 `left' coordinates to be recomputed even though no frame size 3572 `left' coordinates to be recomputed even though no frame size
3273 change occurs. --kyle */ 3573 change occurs. --kyle */
3274 if (in_display || hold_frame_size_changes) 3574 assert (!in_display && !hold_frame_size_changes);
3275 ABORT (); 3575
3276 3576 /* We no longer allow bogus values passed in. */
3277 frame = wrap_frame (f); 3577 assert (newheight && newwidth);
3278 3578
3279 default_face_height_and_width (frame, &real_font_height, 0); 3579 default_face_width_and_height (wrap_frame (f), &real_font_width,
3280 default_face_height_and_width_1 (frame, &font_height, &font_width); 3580 &real_font_height);
3581
3582 frame_conversion_internal (f, SIZE_FRAME_UNIT, newwidth, newheight,
3583 SIZE_TOTAL_PIXEL, &new_pixwidth,
3584 &new_pixheight);
3281 3585
3282 /* This size-change overrides any pending one for this frame. */ 3586 /* This size-change overrides any pending one for this frame. */
3283 f->size_change_pending = 0; 3587 f->size_change_pending = 0;
3284 FRAME_NEW_HEIGHT (f) = 0; 3588 FRAME_NEW_HEIGHT (f) = 0;
3285 FRAME_NEW_WIDTH (f) = 0; 3589 FRAME_NEW_WIDTH (f) = 0;
3286 3590
3287 new_pixheight = newheight * font_height; 3591 /* We need to remove the boundaries of the paned area (see top of file)
3288 new_pixwidth = (newwidth - 1) * font_width; 3592 from the total-area pixel size, which is what we have now.
3289 3593
3290 /* #### dependency on FRAME_WIN_P should be removed. */ 3594 #### We should also be subtracting the internal borders. */
3291 if (FRAME_WIN_P (f)) 3595 new_pixheight -=
3292 { 3596 (FRAME_REAL_TOP_TOOLBAR_BOUNDS (f)
3293 new_pixheight += FRAME_SCROLLBAR_HEIGHT (f); 3597 + FRAME_REAL_BOTTOM_TOOLBAR_BOUNDS (f)
3294 new_pixwidth += FRAME_SCROLLBAR_WIDTH (f); 3598 + FRAME_TOP_GUTTER_BOUNDS (f)
3295 } 3599 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
3296 3600
3297 /* when frame_conversion_internal() calculated the number of rows/cols 3601 new_pixwidth -=
3298 in the frame, the theoretical toolbar sizes were subtracted out. 3602 (FRAME_REAL_LEFT_TOOLBAR_BOUNDS (f)
3299 The calculations below adjust for real toolbar height/width in 3603 + FRAME_REAL_RIGHT_TOOLBAR_BOUNDS (f)
3300 frame, which may be different from frame spec, taking the above 3604 + FRAME_LEFT_GUTTER_BOUNDS (f)
3301 fact into account */ 3605 + FRAME_RIGHT_GUTTER_BOUNDS (f));
3302 new_pixheight += 3606
3303 + FRAME_THEORETICAL_TOP_TOOLBAR_HEIGHT (f) 3607 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top
3304 + 2 * FRAME_THEORETICAL_TOP_TOOLBAR_BORDER_WIDTH (f) 3608 = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
3305 - FRAME_REAL_TOP_TOOLBAR_HEIGHT (f) 3609
3306 - 2 * FRAME_REAL_TOP_TOOLBAR_BORDER_WIDTH (f); 3610 if (FRAME_HAS_MINIBUF_P (f)
3307 3611 && ! FRAME_MINIBUF_ONLY_P (f))
3308 new_pixheight += 3612 /* Frame has both root and minibuffer. */
3309 + FRAME_THEORETICAL_BOTTOM_TOOLBAR_HEIGHT (f) 3613 {
3310 + 2 * FRAME_THEORETICAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f) 3614 /*
3311 - FRAME_REAL_BOTTOM_TOOLBAR_HEIGHT (f) 3615 * Leave the minibuffer height the same if the frame has
3312 - 2 * FRAME_REAL_BOTTOM_TOOLBAR_BORDER_WIDTH (f); 3616 * been initialized, and the minibuffer height is tall
3313 3617 * enough to display at least one line of text in the default
3314 new_pixwidth += 3618 * font, and the old minibuffer height is a multiple of the
3315 + FRAME_THEORETICAL_LEFT_TOOLBAR_WIDTH (f) 3619 * default font height. This should cause the minibuffer
3316 + 2 * FRAME_THEORETICAL_LEFT_TOOLBAR_BORDER_WIDTH (f) 3620 * height to be recomputed on font changes but not for
3317 - FRAME_REAL_LEFT_TOOLBAR_WIDTH (f) 3621 * other frame size changes, which seems reasonable.
3318 - 2 * FRAME_REAL_LEFT_TOOLBAR_BORDER_WIDTH (f); 3622 */
3319 3623 int old_minibuf_height =
3320 new_pixwidth += 3624 XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
3321 + FRAME_THEORETICAL_RIGHT_TOOLBAR_WIDTH (f) 3625 int minibuf_height =
3322 + 2 * FRAME_THEORETICAL_RIGHT_TOOLBAR_BORDER_WIDTH (f) 3626 f->init_finished && (old_minibuf_height % real_font_height) == 0 ?
3323 - FRAME_REAL_RIGHT_TOOLBAR_WIDTH (f) 3627 max(old_minibuf_height, real_font_height) :
3324 - 2 * FRAME_REAL_RIGHT_TOOLBAR_BORDER_WIDTH (f); 3628 real_font_height;
3325 3629 set_window_pixheight (FRAME_ROOT_WINDOW (f),
3326 /* Adjust the width for the end glyph which may be a different width 3630 /* - font_height for minibuffer */
3327 than the default character width. */ 3631 new_pixheight - minibuf_height, 0);
3328 { 3632
3329 int adjustment, trunc_width, cont_width; 3633 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top =
3330 3634 FRAME_TOP_BORDER_END (f) +
3331 trunc_width = glyph_width (Vtruncation_glyph, 3635 FRAME_TOP_GUTTER_BOUNDS (f) +
3332 FRAME_SELECTED_WINDOW (f)); 3636 FRAME_BOTTOM_GUTTER_BOUNDS (f) +
3333 cont_width = glyph_width (Vcontinuation_glyph, 3637 new_pixheight - minibuf_height;
3334 FRAME_SELECTED_WINDOW (f)); 3638
3335 adjustment = max (trunc_width, cont_width); 3639 set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0);
3336 adjustment = max (adjustment, font_width); 3640 }
3337 3641 else
3338 new_pixwidth += adjustment; 3642 /* Frame has just one top-level window. */
3339 } 3643 set_window_pixheight (FRAME_ROOT_WINDOW (f), new_pixheight, 0);
3340 3644
3341 /* If we don't have valid values, exit. */ 3645 FRAME_HEIGHT (f) = newheight;
3342 if (!new_pixheight && !new_pixwidth) 3646 if (FRAME_TTY_P (f))
3343 return; 3647 f->pixheight = newheight;
3344 3648
3345 if (new_pixheight) 3649 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left =
3346 { 3650 FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f);
3347 /* Adjust for gutters here so that we always get set 3651 set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0);
3348 properly. */ 3652
3349 new_pixheight -= 3653 if (FRAME_HAS_MINIBUF_P (f))
3350 (FRAME_TOP_GUTTER_BOUNDS (f) 3654 {
3351 + FRAME_BOTTOM_GUTTER_BOUNDS (f)); 3655 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left =
3352
3353 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_top
3354 = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
3355
3356 if (FRAME_HAS_MINIBUF_P (f)
3357 && ! FRAME_MINIBUF_ONLY_P (f))
3358 /* Frame has both root and minibuffer. */
3359 {
3360 /*
3361 * Leave the minibuffer height the same if the frame has
3362 * been initialized, and the minibuffer height is tall
3363 * enough to display at least one line of text in the default
3364 * font, and the old minibuffer height is a multiple of the
3365 * default font height. This should cause the minibuffer
3366 * height to be recomputed on font changes but not for
3367 * other frame size changes, which seems reasonable.
3368 */
3369 int old_minibuf_height =
3370 XWINDOW(FRAME_MINIBUF_WINDOW(f))->pixel_height;
3371 int minibuf_height =
3372 f->init_finished && (old_minibuf_height % real_font_height) == 0 ?
3373 max(old_minibuf_height, real_font_height) :
3374 real_font_height;
3375 set_window_pixheight (FRAME_ROOT_WINDOW (f),
3376 /* - font_height for minibuffer */
3377 new_pixheight - minibuf_height, 0);
3378
3379 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_top =
3380 FRAME_TOP_BORDER_END (f) +
3381 FRAME_TOP_GUTTER_BOUNDS (f) +
3382 FRAME_BOTTOM_GUTTER_BOUNDS (f) +
3383 new_pixheight - minibuf_height;
3384
3385 set_window_pixheight (FRAME_MINIBUF_WINDOW (f), minibuf_height, 0);
3386 }
3387 else
3388 /* Frame has just one top-level window. */
3389 set_window_pixheight (FRAME_ROOT_WINDOW (f), new_pixheight, 0);
3390
3391 FRAME_HEIGHT (f) = newheight;
3392 if (FRAME_TTY_P (f))
3393 f->pixheight = newheight;
3394 }
3395
3396 if (new_pixwidth)
3397 {
3398 /* Adjust for gutters here so that we always get set
3399 properly. */
3400 new_pixwidth -=
3401 (FRAME_LEFT_GUTTER_BOUNDS (f)
3402 + FRAME_RIGHT_GUTTER_BOUNDS (f));
3403
3404 XWINDOW (FRAME_ROOT_WINDOW (f))->pixel_left =
3405 FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f); 3656 FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f);
3406 set_window_pixwidth (FRAME_ROOT_WINDOW (f), new_pixwidth, 0); 3657 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0);
3407 3658 }
3408 if (FRAME_HAS_MINIBUF_P (f)) 3659
3409 { 3660 FRAME_WIDTH (f) = newwidth;
3410 XWINDOW (FRAME_MINIBUF_WINDOW (f))->pixel_left = 3661 if (FRAME_TTY_P (f))
3411 FRAME_LEFT_BORDER_END (f) + FRAME_LEFT_GUTTER_BOUNDS (f); 3662 f->pixwidth = newwidth;
3412 set_window_pixwidth (FRAME_MINIBUF_WINDOW (f), new_pixwidth, 0); 3663
3413 } 3664 /* #### On MS Windows, this references FRAME_PIXWIDTH() and FRAME_PIXHEIGHT().
3414 3665 I'm not sure we can count on those values being set. Instead we should
3415 FRAME_WIDTH (f) = newwidth; 3666 use the total pixel size we got near the top by calling
3416 if (FRAME_TTY_P (f)) 3667 frame_conversion_internal(). We should inline the logic in
3417 f->pixwidth = newwidth; 3668 get_frame_char_size() here and change that function so it just looks
3418 } 3669 at FRAME_CHARWIDTH() and FRAME_CHARHEIGHT(). */
3419 3670 get_frame_char_size (f, &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
3420 if (window_system_pixelated_geometry (frame))
3421 pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
3422 &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
3423 else
3424 {
3425 FRAME_CHARWIDTH (f) = FRAME_WIDTH (f);
3426 FRAME_CHARHEIGHT (f) = FRAME_HEIGHT (f);
3427 }
3428 3671
3429 MARK_FRAME_TOOLBARS_CHANGED (f); 3672 MARK_FRAME_TOOLBARS_CHANGED (f);
3430 MARK_FRAME_GUTTERS_CHANGED (f); 3673 MARK_FRAME_GUTTERS_CHANGED (f);
3431 MARK_FRAME_CHANGED (f); 3674 MARK_FRAME_CHANGED (f);
3432 f->echo_area_garbaged = 1; 3675 f->echo_area_garbaged = 1;
3433 } 3676 }
3434 3677
3435 void 3678 void
3436 change_frame_size (struct frame *f, int newheight, int newwidth, int delay) 3679 change_frame_size (struct frame *f, int newwidth, int newheight, int delay)
3437 { 3680 {
3438 /* sometimes we get passed a size that's too small (esp. when a 3681 /* sometimes we get passed a size that's too small (esp. when a
3439 client widget gets resized, since we have no control over this). 3682 client widget gets resized, since we have no control over this).
3440 So deal. */ 3683 So deal. */
3441 check_frame_size (f, &newheight, &newwidth); 3684 check_frame_size (f, &newwidth, &newheight);
3442 3685
3443 /* Unconditionally mark that the frame has changed size. This is 3686 /* Unconditionally mark that the frame has changed size. This is
3444 because many things need to know after the 3687 because many things need to know after the
3445 fact. f->size_change_pending will get reset below. The most that 3688 fact. f->size_change_pending will get reset below. The most that
3446 can happen is that we will cycle through redisplay once more 3689 can happen is that we will cycle through redisplay once more
3463 if (FRAME_TTY_P (f)) 3706 if (FRAME_TTY_P (f))
3464 { 3707 {
3465 Lisp_Object frmcons; 3708 Lisp_Object frmcons;
3466 3709
3467 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f))) 3710 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f)))
3468 change_frame_size_1 (XFRAME (XCAR (frmcons)), newheight, newwidth); 3711 change_frame_size_1 (XFRAME (XCAR (frmcons)), newwidth, newheight);
3469 } 3712 }
3470 else 3713 else
3471 change_frame_size_1 (f, newheight, newwidth); 3714 change_frame_size_1 (f, newwidth, newheight);
3472 } 3715 }
3473 3716
3474 3717
3475 /* The caller is responsible for freeing the returned string. */ 3718 /* The caller is responsible for freeing the returned string. */
3476 static Ibyte * 3719 static Ibyte *