comparison src/frame.c @ 5043:d0c14ea98592

various frame-geometry fixes -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-02-15 Ben Wing <ben@xemacs.org> * EmacsFrame.c: * EmacsFrame.c (EmacsFrameResize): * console-msw-impl.h: * console-msw-impl.h (struct mswindows_frame): * console-msw-impl.h (FRAME_MSWINDOWS_TARGET_RECT): * device-tty.c: * device-tty.c (tty_asynch_device_change): * event-msw.c: * event-msw.c (mswindows_wnd_proc): * faces.c (Fface_list): * faces.h: * frame-gtk.c: * frame-gtk.c (gtk_set_initial_frame_size): * frame-gtk.c (gtk_set_frame_size): * frame-msw.c: * frame-msw.c (mswindows_init_frame_1): * frame-msw.c (mswindows_set_frame_size): * frame-msw.c (mswindows_size_frame_internal): * frame-msw.c (msprinter_init_frame_3): * frame.c: * frame.c (enum): * frame.c (Fmake_frame): * frame.c (adjust_frame_size): * frame.c (store_minibuf_frame_prop): * frame.c (Fframe_property): * frame.c (Fframe_properties): * frame.c (Fframe_displayable_pixel_height): * frame.c (Fframe_displayable_pixel_width): * frame.c (internal_set_frame_size): * frame.c (Fset_frame_height): * frame.c (Fset_frame_pixel_height): * frame.c (Fset_frame_displayable_pixel_height): * frame.c (Fset_frame_width): * frame.c (Fset_frame_pixel_width): * frame.c (Fset_frame_displayable_pixel_width): * frame.c (Fset_frame_size): * frame.c (Fset_frame_pixel_size): * frame.c (Fset_frame_displayable_pixel_size): * frame.c (frame_conversion_internal_1): * frame.c (get_frame_displayable_pixel_size): * frame.c (change_frame_size_1): * frame.c (change_frame_size): * frame.c (generate_title_string): * frame.h: * gtk-xemacs.c: * gtk-xemacs.c (gtk_xemacs_size_request): * gtk-xemacs.c (gtk_xemacs_size_allocate): * gtk-xemacs.c (gtk_xemacs_paint): * gutter.c: * gutter.c (update_gutter_geometry): * redisplay.c (end_hold_frame_size_changes): * redisplay.c (redisplay_frame): * toolbar.c: * toolbar.c (update_frame_toolbars_geometry): * window.c: * window.c (frame_pixsize_valid_p): * window.c (check_frame_size): Various fixes to frame geometry to make it a bit easier to understand and fix some bugs. 1. IMPORTANT: Some renamings. Will need to be applied carefully to the carbon repository, in the following order: -- pixel_to_char_size -> pixel_to_frame_unit_size -- char_to_pixel_size -> frame_unit_to_pixel_size -- pixel_to_real_char_size -> pixel_to_char_size -- char_to_real_pixel_size -> char_to_pixel_size -- Reverse second and third arguments of change_frame_size() and change_frame_size_1() to try to make functions consistent in putting width before height. -- Eliminate old round_size_to_char, because it didn't really do anything differently from round_size_to_real_char() -- round_size_to_real_char -> round_size_to_char; any places that called the old round_size_to_char should just call the new one. 2. IMPORTANT FOR CARBON: The set_frame_size() method is now passed sizes in "frame units", like all other frame-sizing functions, rather than some hacked-up combination of char-cell units and total pixel size. This only affects window systems that use "pixelated geometry", and I'm not sure if Carbon is one of them. MS Windows is pixelated, X and GTK are not. For pixelated-geometry systems, the size in set_frame_size() is in displayable pixels rather than total pixels and needs to be converted appropriately; take a look at the changes made to mswindows_set_frame_size() method if necessary. 3. Add a big long comment in frame.c describing how frame geometry works. 4. Remove MS Windows-specific character height and width fields, duplicative and unused. 5. frame-displayable-pixel-* and set-frame-displayable-pixel-* didn't use to work on MS Windows, but they do now. 6. In general, clean up the handling of "pixelated geometry" so that fewer functions have to worry about this. This is really an abomination that should be removed entirely but that will have to happen later. Fix some buggy code in frame_conversion_internal() that happened to "work" because it was countered by oppositely buggy code in change_frame_size(). 7. Clean up some frame-size code in toolbar.c and use functions already provided in frame.c instead of rolling its own. 8. Fix check_frame_size() in window.c, which formerly didn't take pixelated geometry into account.
author Ben Wing <ben@xemacs.org>
date Mon, 15 Feb 2010 22:14:11 -0600
parents 16112448d484
children e84a30b0e4a2
comparison
equal deleted inserted replaced
5042:f395ee7ad844 5043:d0c14ea98592
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=.texttexttextte...=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
656 { 957 {
657 reset_face_cachels (XWINDOW (f->minibuffer_window)); 958 reset_face_cachels (XWINDOW (f->minibuffer_window));
658 reset_glyph_cachels (XWINDOW (f->minibuffer_window)); 959 reset_glyph_cachels (XWINDOW (f->minibuffer_window));
659 } 960 }
660 961
661 change_frame_size (f, f->height, f->width, 0); 962 change_frame_size (f, f->width, f->height, 0);
662 } 963 }
663 964
664 MAYBE_FRAMEMETH (f, init_frame_2, (f, props)); 965 MAYBE_FRAMEMETH (f, init_frame_2, (f, props));
665 Fset_frame_properties (frame, props); 966 Fset_frame_properties (frame, props);
666 MAYBE_FRAMEMETH (f, init_frame_3, (f)); 967 MAYBE_FRAMEMETH (f, init_frame_3, (f));
701 will eventually do. Unfortunately gutter sizing code relies 1002 will eventually do. Unfortunately gutter sizing code relies
702 on the frame in question being visible so we can't do this 1003 on the frame in question being visible so we can't do this
703 earlier. */ 1004 earlier. */
704 init_frame_gutters (f); 1005 init_frame_gutters (f);
705 1006
706 change_frame_size (f, f->height, f->width, 0); 1007 change_frame_size (f, f->width, f->height, 0);
707 } 1008 }
708 1009
709 if (first_frame_on_device) 1010 if (first_frame_on_device)
710 { 1011 {
711 if (first_frame_on_console) 1012 if (first_frame_on_console)
824 } 1125 }
825 1126
826 if (!keep_char_size) 1127 if (!keep_char_size)
827 { 1128 {
828 int height, width; 1129 int height, width;
829 pixel_to_char_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f), 1130 pixel_to_frame_unit_size (f, FRAME_PIXWIDTH(f), FRAME_PIXHEIGHT(f),
830 &width, &height); 1131 &width, &height);
831 change_frame_size (f, height, width, 0); 1132 change_frame_size (f, width, height, 0);
832 CLEAR_FRAME_SIZE_SLIPPED (f); 1133 CLEAR_FRAME_SIZE_SLIPPED (f);
833 } 1134 }
834 } 1135 }
835 1136
836 /* 1137 /*
2308 2609
2309 2610
2310 /***************************************************************************/ 2611 /***************************************************************************/
2311 /* frame properties */ 2612 /* frame properties */
2312 /***************************************************************************/ 2613 /***************************************************************************/
2313
2314 static void internal_set_frame_size (struct frame *f, int cols, int rows,
2315 int pretend);
2316 2614
2317 static void 2615 static void
2318 store_minibuf_frame_prop (struct frame *f, Lisp_Object val) 2616 store_minibuf_frame_prop (struct frame *f, Lisp_Object val)
2319 { 2617 {
2320 /* This can call Lisp. */ 2618 /* This can call Lisp. */
2606 2904
2607 if (EQ (Qname, property)) return f->name; 2905 if (EQ (Qname, property)) return f->name;
2608 2906
2609 if (EQ (Qheight, property) || EQ (Qwidth, property)) 2907 if (EQ (Qheight, property) || EQ (Qwidth, property))
2610 { 2908 {
2611 if (window_system_pixelated_geometry (frame)) 2909 int width, height;
2612 { 2910 get_frame_char_size (f, &width, &height);
2613 int width, height; 2911 return make_int (EQ (Qheight, property) ? height : width);
2614 pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2615 &width, &height);
2616 return make_int (EQ (Qheight, property) ? height: width);
2617 }
2618 else
2619 return make_int (EQ (Qheight, property) ?
2620 FRAME_HEIGHT (f) :
2621 FRAME_WIDTH (f));
2622 } 2912 }
2623 2913
2624 /* NOTE: FSF returns Qnil instead of Qt for FRAME_HAS_MINIBUF_P. 2914 /* NOTE: FSF returns Qnil instead of Qt for FRAME_HAS_MINIBUF_P.
2625 This is over-the-top bogosity, because it's inconsistent with 2915 This is over-the-top bogosity, because it's inconsistent with
2626 the semantics of `minibuffer' when passed to `make-frame'. 2916 the semantics of `minibuffer' when passed to `make-frame'.
2708 FRAME_HAS_MINIBUF_P (f) ? Qt : 2998 FRAME_HAS_MINIBUF_P (f) ? Qt :
2709 FRAME_MINIBUF_WINDOW (f)), 2999 FRAME_MINIBUF_WINDOW (f)),
2710 result); 3000 result);
2711 { 3001 {
2712 int width, height; 3002 int width, height;
2713 3003 get_frame_char_size (f, &width, &height);
2714 if (window_system_pixelated_geometry (frame))
2715 {
2716 pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
2717 &width, &height);
2718 }
2719 else
2720 {
2721 height = FRAME_HEIGHT (f);
2722 width = FRAME_WIDTH (f);
2723 }
2724 result = cons3 (Qwidth , make_int (width), result); 3004 result = cons3 (Qwidth , make_int (width), result);
2725 result = cons3 (Qheight, make_int (height), result); 3005 result = cons3 (Qheight, make_int (height), result);
2726 } 3006 }
2727 3007
2728 result = cons3 (Qname, f->name, result); 3008 result = cons3 (Qname, f->name, result);
2744 Return the height of the displayable area in pixels of FRAME. 3024 Return the height of the displayable area in pixels of FRAME.
2745 */ 3025 */
2746 (frame)) 3026 (frame))
2747 { 3027 {
2748 struct frame *f = decode_frame (frame); 3028 struct frame *f = decode_frame (frame);
2749 int height, pheight; 3029 int width, height;
2750 frame = wrap_frame (f); 3030
2751 3031 get_frame_displayable_pixel_size (f, &width, &height);
2752 if (!window_system_pixelated_geometry (frame)) 3032 return make_int (height);
2753 {
2754 height = FRAME_HEIGHT (f);
2755
2756 frame_conversion_internal (f, CHAR_TO_DISPLAYABLE_PIXEL,
2757 0, &pheight, 0, &height, 0);
2758 }
2759 else
2760 pheight = FRAME_PIXHEIGHT (f);
2761
2762 return make_int (pheight);
2763 } 3033 }
2764 3034
2765 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /* 3035 DEFUN ("frame-pixel-width", Fframe_pixel_width, 0, 1, 0, /*
2766 Return the total width in pixels of FRAME. 3036 Return the total width in pixels of FRAME.
2767 */ 3037 */
2774 Return the width of the displayable area in pixels of FRAME. 3044 Return the width of the displayable area in pixels of FRAME.
2775 */ 3045 */
2776 (frame)) 3046 (frame))
2777 { 3047 {
2778 struct frame *f = decode_frame (frame); 3048 struct frame *f = decode_frame (frame);
2779 int width, pwidth; 3049 int width, height;
2780 frame = wrap_frame (f); 3050
2781 3051 get_frame_displayable_pixel_size (f, &width, &height);
2782 if (!window_system_pixelated_geometry (frame)) 3052 return make_int (width);
2783 {
2784 width = FRAME_WIDTH (f);
2785
2786 frame_conversion_internal (f, CHAR_TO_DISPLAYABLE_PIXEL,
2787 &pwidth, 0, &width, 0, 0);
2788 }
2789 else
2790 pwidth = FRAME_PIXWIDTH (f);
2791
2792 return make_int (pwidth);
2793 } 3053 }
2794 3054
2795 DEFUN ("frame-name", Fframe_name, 0, 1, 0, /* 3055 DEFUN ("frame-name", Fframe_name, 0, 1, 0, /*
2796 Return the name of FRAME (defaulting to the selected frame). 3056 Return the name of FRAME (defaulting to the selected frame).
2797 This is not the same as the `title' of the frame. 3057 This is not the same as the `title' of the frame.
2813 (frame)) 3073 (frame))
2814 { 3074 {
2815 return make_int (decode_frame (frame)->modiff); 3075 return make_int (decode_frame (frame)->modiff);
2816 } 3076 }
2817 3077
2818 static void 3078 void
2819 internal_set_frame_size (struct frame *f, int cols, int rows, int pretend) 3079 internal_set_frame_size (struct frame *f, int cols, int rows, int pretend)
2820 { 3080 {
2821 /* This can call Lisp. See mswindows_set_frame_size(). */ 3081 /* This can call Lisp. See mswindows_set_frame_size(). */
2822 /* An explicit size change cancels any pending frame size adjustment */ 3082 /* An explicit size change cancels any pending frame size adjustment */
2823 CLEAR_FRAME_SIZE_SLIPPED (f); 3083 CLEAR_FRAME_SIZE_SLIPPED (f);
2824 3084
2825 if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size)) 3085 if (pretend || !HAS_FRAMEMETH_P (f, set_frame_size))
2826 change_frame_size (f, rows, cols, 0); 3086 change_frame_size (f, cols, rows, 0);
2827 else 3087 else
2828 FRAMEMETH (f, set_frame_size, (f, cols, rows)); 3088 FRAMEMETH (f, set_frame_size, (f, cols, rows));
2829 } 3089 }
2830 3090
2831 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /* 3091 DEFUN ("set-frame-height", Fset_frame_height, 2, 3, 0, /*
2835 */ 3095 */
2836 (frame, lines, pretend)) 3096 (frame, lines, pretend))
2837 { 3097 {
2838 /* This can call Lisp. */ 3098 /* This can call Lisp. */
2839 struct frame *f = decode_frame (frame); 3099 struct frame *f = decode_frame (frame);
2840 int height, width; 3100 int cwidth, cheight;
2841 frame = wrap_frame (f); 3101 int guwidth, guheight;
3102
2842 CHECK_INT (lines); 3103 CHECK_INT (lines);
2843 3104 get_frame_char_size (f, &cwidth, &cheight);
2844 if (window_system_pixelated_geometry (frame)) 3105 cheight = XINT (lines);
2845 { 3106 frame_conversion_internal (f, SIZE_CHAR_CELL, cwidth, cheight,
2846 char_to_real_pixel_size (f, 0, XINT (lines), 0, &height); 3107 SIZE_FRAME_UNIT, &guwidth, &guheight);
2847 width = FRAME_PIXWIDTH (f); 3108 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2848 } 3109 return wrap_frame (f);
2849 else
2850 {
2851 height = XINT (lines);
2852 width = FRAME_WIDTH (f);
2853 }
2854
2855 internal_set_frame_size (f, width, height, !NILP (pretend));
2856 return frame;
2857 } 3110 }
2858 3111
2859 DEFUN ("set-frame-pixel-height", Fset_frame_pixel_height, 2, 3, 0, /* 3112 DEFUN ("set-frame-pixel-height", Fset_frame_pixel_height, 2, 3, 0, /*
2860 Specify that the frame FRAME is a total of HEIGHT pixels tall. 3113 Specify that the frame FRAME is a total of HEIGHT pixels tall.
2861 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall 3114 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall
2863 */ 3116 */
2864 (frame, height, pretend)) 3117 (frame, height, pretend))
2865 { 3118 {
2866 /* This can call Lisp. */ 3119 /* This can call Lisp. */
2867 struct frame *f = decode_frame (frame); 3120 struct frame *f = decode_frame (frame);
2868 int pheight, width; 3121 int pwidth, pheight;
2869 frame = wrap_frame (f); 3122 int guwidth, guheight;
3123
2870 CHECK_INT (height); 3124 CHECK_INT (height);
2871 3125 pheight = XINT (height);
2872 if (!window_system_pixelated_geometry (frame)) 3126 pwidth = FRAME_PIXWIDTH (f);
2873 { 3127 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
2874 int h = XINT (height); 3128 SIZE_FRAME_UNIT, &guwidth, &guheight);
2875 width = FRAME_WIDTH (f); 3129 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2876 3130 return wrap_frame (f);
2877 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, 0, &h, 0, &pheight, 0);
2878 }
2879 else
2880 {
2881 width = FRAME_PIXWIDTH (f);
2882 pheight = XINT (height);
2883 }
2884
2885 internal_set_frame_size (f, width, pheight, !NILP (pretend));
2886 return frame;
2887 } 3131 }
2888 3132
2889 DEFUN ("set-frame-displayable-pixel-height", Fset_frame_displayable_pixel_height, 2, 3, 0, /* 3133 DEFUN ("set-frame-displayable-pixel-height", Fset_frame_displayable_pixel_height, 2, 3, 0, /*
2890 Specify that the displayable area of frame FRAME is HEIGHT pixels tall. 3134 Specify that the displayable area of frame FRAME is HEIGHT pixels tall.
2891 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall 3135 Optional third arg non-nil means that redisplay should be HEIGHT pixels tall
2893 */ 3137 */
2894 (frame, height, pretend)) 3138 (frame, height, pretend))
2895 { 3139 {
2896 /* This can call Lisp. */ 3140 /* This can call Lisp. */
2897 struct frame *f = decode_frame (frame); 3141 struct frame *f = decode_frame (frame);
2898 int pheight, width; 3142 int pwidth, pheight;
2899 frame = wrap_frame (f); 3143 int guwidth, guheight;
3144
2900 CHECK_INT (height); 3145 CHECK_INT (height);
2901 3146 get_frame_displayable_pixel_size (f, &pwidth, &pheight);
2902 if (!window_system_pixelated_geometry (frame)) 3147 pheight = XINT (height);
2903 { 3148 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
2904 int h = XINT (height); 3149 SIZE_FRAME_UNIT, &guwidth, &guheight);
2905 width = FRAME_WIDTH (f); 3150 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2906 frame_conversion_internal (f, DISPLAYABLE_PIXEL_TO_CHAR, 0, &h, 0, &pheight, 0); 3151 return wrap_frame (f);
2907 }
2908 else
2909 {
2910 width = FRAME_PIXWIDTH (f);
2911 pheight = XINT (height);
2912 }
2913
2914 internal_set_frame_size (f, width, pheight, !NILP (pretend));
2915 return frame;
2916 } 3152 }
2917 3153
2918 3154
2919 DEFUN ("set-frame-width", Fset_frame_width, 2, 3, 0, /* 3155 DEFUN ("set-frame-width", Fset_frame_width, 2, 3, 0, /*
2920 Specify that the frame FRAME has COLS columns. 3156 Specify that the frame FRAME has COLS columns.
2923 */ 3159 */
2924 (frame, cols, pretend)) 3160 (frame, cols, pretend))
2925 { 3161 {
2926 /* This can call Lisp. */ 3162 /* This can call Lisp. */
2927 struct frame *f = decode_frame (frame); 3163 struct frame *f = decode_frame (frame);
2928 int width, height; 3164 int cwidth, cheight;
2929 frame = wrap_frame (f); 3165 int guwidth, guheight;
3166
2930 CHECK_INT (cols); 3167 CHECK_INT (cols);
2931 3168 get_frame_char_size (f, &cwidth, &cheight);
2932 if (window_system_pixelated_geometry (frame)) 3169 cwidth = XINT (cols);
2933 { 3170 frame_conversion_internal (f, SIZE_CHAR_CELL, cwidth, cheight,
2934 char_to_real_pixel_size (f, XINT (cols), 0, &width, 0); 3171 SIZE_FRAME_UNIT, &guwidth, &guheight);
2935 height = FRAME_PIXHEIGHT (f); 3172 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2936 } 3173 return wrap_frame (f);
2937 else
2938 {
2939 width = XINT (cols);
2940 height = FRAME_HEIGHT (f);
2941 }
2942
2943 internal_set_frame_size (f, width, height, !NILP (pretend));
2944 return frame;
2945 } 3174 }
2946 3175
2947 DEFUN ("set-frame-pixel-width", Fset_frame_pixel_width, 2, 3, 0, /* 3176 DEFUN ("set-frame-pixel-width", Fset_frame_pixel_width, 2, 3, 0, /*
2948 Specify that the frame FRAME is a total of WIDTH pixels wide. 3177 Specify that the frame FRAME is a total of WIDTH pixels wide.
2949 Optional third arg non-nil means that redisplay should be WIDTH wide 3178 Optional third arg non-nil means that redisplay should be WIDTH wide
2951 */ 3180 */
2952 (frame, width, pretend)) 3181 (frame, width, pretend))
2953 { 3182 {
2954 /* This can call Lisp. */ 3183 /* This can call Lisp. */
2955 struct frame *f = decode_frame (frame); 3184 struct frame *f = decode_frame (frame);
2956 int height, pwidth; 3185 int pwidth, pheight;
2957 frame = wrap_frame (f); 3186 int guwidth, guheight;
3187
2958 CHECK_INT (width); 3188 CHECK_INT (width);
2959 3189 pwidth = XINT (width);
2960 if (!window_system_pixelated_geometry (frame)) 3190 pheight = FRAME_PIXHEIGHT (f);
2961 { 3191 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pwidth, pheight,
2962 int w = XINT (width); 3192 SIZE_FRAME_UNIT, &guwidth, &guheight);
2963 height = FRAME_HEIGHT (f); 3193 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2964 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, &w, 0, &pwidth, 0, 0); 3194 return wrap_frame (f);
2965 }
2966 else
2967 {
2968 height = FRAME_PIXHEIGHT (f);
2969 pwidth = XINT (width);
2970 }
2971
2972 internal_set_frame_size (f, pwidth, height, !NILP (pretend));
2973 return frame;
2974 } 3195 }
2975 3196
2976 DEFUN ("set-frame-displayable-pixel-width", Fset_frame_displayable_pixel_width, 2, 3, 0, /* 3197 DEFUN ("set-frame-displayable-pixel-width", Fset_frame_displayable_pixel_width, 2, 3, 0, /*
2977 Specify that the displayable area of frame FRAME is WIDTH pixels wide. 3198 Specify that the displayable area of frame FRAME is WIDTH pixels wide.
2978 Optional third arg non-nil means that redisplay should be WIDTH wide 3199 Optional third arg non-nil means that redisplay should be WIDTH wide
2980 */ 3201 */
2981 (frame, width, pretend)) 3202 (frame, width, pretend))
2982 { 3203 {
2983 /* This can call Lisp. */ 3204 /* This can call Lisp. */
2984 struct frame *f = decode_frame (frame); 3205 struct frame *f = decode_frame (frame);
2985 int height, pwidth; 3206 int pwidth, pheight;
2986 frame = wrap_frame (f); 3207 int guwidth, guheight;
3208
2987 CHECK_INT (width); 3209 CHECK_INT (width);
2988 3210 get_frame_displayable_pixel_size (f, &pwidth, &pheight);
2989 if (!window_system_pixelated_geometry (frame)) 3211 pwidth = XINT (width);
2990 { 3212 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL, pwidth, pheight,
2991 int w = XINT (width); 3213 SIZE_FRAME_UNIT, &guwidth, &guheight);
2992 height = FRAME_HEIGHT (f); 3214 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
2993 frame_conversion_internal (f, DISPLAYABLE_PIXEL_TO_CHAR, &w, 0, &pwidth, 0, 0); 3215 return wrap_frame (f);
2994 }
2995 else
2996 {
2997 height = FRAME_PIXHEIGHT (f);
2998 pwidth = XINT (width);
2999 }
3000
3001 internal_set_frame_size (f, pwidth, height, !NILP (pretend));
3002 return frame;
3003 } 3216 }
3004 3217
3005 DEFUN ("set-frame-size", Fset_frame_size, 3, 4, 0, /* 3218 DEFUN ("set-frame-size", Fset_frame_size, 3, 4, 0, /*
3006 Set the size of FRAME to COLS by ROWS, measured in characters. 3219 Set the size of FRAME to COLS by ROWS, measured in characters.
3007 Optional fourth arg non-nil means that redisplay should use COLS by ROWS 3220 Optional fourth arg non-nil means that redisplay should use COLS by ROWS
3009 */ 3222 */
3010 (frame, cols, rows, pretend)) 3223 (frame, cols, rows, pretend))
3011 { 3224 {
3012 /* This can call Lisp. */ 3225 /* This can call Lisp. */
3013 struct frame *f = decode_frame (frame); 3226 struct frame *f = decode_frame (frame);
3014 int height, width; 3227 int guwidth, guheight;
3015 frame = wrap_frame (f); 3228
3016 CHECK_INT (cols); 3229 CHECK_INT (cols);
3017 CHECK_INT (rows); 3230 CHECK_INT (rows);
3018 3231 frame_conversion_internal (f, SIZE_CHAR_CELL, XINT (cols), XINT (rows),
3019 if (window_system_pixelated_geometry (frame)) 3232 SIZE_FRAME_UNIT, &guwidth, &guheight);
3020 char_to_real_pixel_size (f, XINT (cols), XINT (rows), &width, &height); 3233 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3021 else 3234 return wrap_frame (f);
3022 {
3023 height = XINT (rows);
3024 width = XINT (cols);
3025 }
3026
3027 internal_set_frame_size (f, width, height, !NILP (pretend));
3028 return frame;
3029 } 3235 }
3030 3236
3031 DEFUN ("set-frame-pixel-size", Fset_frame_pixel_size, 3, 4, 0, /* 3237 DEFUN ("set-frame-pixel-size", Fset_frame_pixel_size, 3, 4, 0, /*
3032 Set the total size of FRAME to WIDTH by HEIGHT, measured in pixels. 3238 Set the total size of FRAME to WIDTH by HEIGHT, measured in pixels.
3033 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT 3239 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT
3035 */ 3241 */
3036 (frame, width, height, pretend)) 3242 (frame, width, height, pretend))
3037 { 3243 {
3038 /* This can call Lisp. */ 3244 /* This can call Lisp. */
3039 struct frame *f = decode_frame (frame); 3245 struct frame *f = decode_frame (frame);
3040 int pheight, pwidth; 3246 int guwidth, guheight;
3041 frame = wrap_frame (f); 3247
3042 CHECK_INT (width); 3248 CHECK_INT (width);
3043 CHECK_INT (height); 3249 CHECK_INT (height);
3044 3250 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, XINT (width), XINT (height),
3045 if (!window_system_pixelated_geometry (frame)) 3251 SIZE_FRAME_UNIT, &guwidth, &guheight);
3046 { 3252 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3047 int w = XINT (width); 3253 return wrap_frame (f);
3048 int h = XINT (height);
3049 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, &w, &h, &pwidth, &pheight, 0);
3050 }
3051 else
3052 {
3053 pheight = XINT (height);
3054 pwidth = XINT (width);
3055 }
3056
3057 internal_set_frame_size (f, pwidth, pheight, !NILP (pretend));
3058 return frame;
3059 } 3254 }
3060 3255
3061 DEFUN ("set-frame-displayable-pixel-size", Fset_frame_displayable_pixel_size, 3, 4, 0, /* 3256 DEFUN ("set-frame-displayable-pixel-size", Fset_frame_displayable_pixel_size, 3, 4, 0, /*
3062 Set the displayable size of FRAME to WIDTH by HEIGHT, measured in pixels. 3257 Set the displayable size of FRAME to WIDTH by HEIGHT, measured in pixels.
3063 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT 3258 Optional fourth arg non-nil means that redisplay should use WIDTH by HEIGHT
3065 */ 3260 */
3066 (frame, width, height, pretend)) 3261 (frame, width, height, pretend))
3067 { 3262 {
3068 /* This can call Lisp. */ 3263 /* This can call Lisp. */
3069 struct frame *f = decode_frame (frame); 3264 struct frame *f = decode_frame (frame);
3070 int pheight, pwidth; 3265 int guwidth, guheight;
3071 frame = wrap_frame (f); 3266
3072 CHECK_INT (width); 3267 CHECK_INT (width);
3073 CHECK_INT (height); 3268 CHECK_INT (height);
3074 3269 frame_conversion_internal (f, SIZE_DISPLAYABLE_PIXEL,
3075 if (!window_system_pixelated_geometry (frame)) 3270 XINT (width), XINT (height),
3076 { 3271 SIZE_FRAME_UNIT, &guwidth, &guheight);
3077 int w = XINT (width); 3272 internal_set_frame_size (f, guwidth, guheight, !NILP (pretend));
3078 int h = XINT (height); 3273 return wrap_frame (f);
3079 frame_conversion_internal (f, DISPLAYABLE_PIXEL_TO_CHAR, &w, &h, &pwidth, &pheight, 0);
3080 }
3081 else
3082 {
3083 pheight = XINT (height);
3084 pwidth = XINT (width);
3085 }
3086
3087 internal_set_frame_size (f, pwidth, pheight, !NILP (pretend));
3088 return frame;
3089 } 3274 }
3090 3275
3091 DEFUN ("set-frame-position", Fset_frame_position, 3, 3, 0, /* 3276 DEFUN ("set-frame-position", Fset_frame_position, 3, 3, 0, /*
3092 Set position of FRAME in pixels to XOFFSET by YOFFSET. 3277 Set position of FRAME in pixels to XOFFSET by YOFFSET.
3093 This is actually the position of the upper left corner of the frame. 3278 This is actually the position of the upper left corner of the frame.
3108 3293
3109 3294
3110 /* Frame size conversion functions moved here from EmacsFrame.c 3295 /* Frame size conversion functions moved here from EmacsFrame.c
3111 because they're generic and really don't belong in that file. 3296 because they're generic and really don't belong in that file.
3112 Function get_default_char_pixel_size() removed because it's 3297 Function get_default_char_pixel_size() removed because it's
3113 exactly the same as default_face_height_and_width(). */ 3298 exactly the same as default_face_height_and_width().
3299
3300 Convert between total pixel size, displayable pixel size and
3301 character-cell size. Variables are either "in" or "out"
3302 depending on the value of PIXEL_TO_CHAR.
3303 */
3114 static void 3304 static void
3115 frame_conversion_internal (struct frame *f, 3305 frame_conversion_internal_1 (struct frame *f,
3116 pixel_to_char_mode_t pixel_to_char, 3306 pixel_to_char_mode_t pixel_to_char,
3117 int *pixel_width, int *pixel_height, 3307 int *total_pixel_width, int *total_pixel_height,
3118 int *char_width, int *char_height, 3308 int *disp_pixel_width, int *disp_pixel_height,
3119 int real_face) 3309 int *char_width, int *char_height)
3120 { 3310 {
3121 int cpw; 3311 int cpw, cph;
3122 int cph;
3123 int egw; 3312 int egw;
3124 int obw, obh, bdr; 3313 int obw, obh, bdr;
3125 Lisp_Object frame, window; 3314 Lisp_Object frame, window;
3126 3315
3127 frame = wrap_frame (f); 3316 frame = wrap_frame (f);
3128 if (real_face) 3317 default_face_height_and_width (frame, &cph, &cpw);
3129 default_face_height_and_width (frame, &cph, &cpw);
3130 else
3131 default_face_height_and_width_1 (frame, &cph, &cpw);
3132 3318
3133 window = FRAME_SELECTED_WINDOW (f); 3319 window = FRAME_SELECTED_WINDOW (f);
3134 3320
3135 egw = max (glyph_width (Vcontinuation_glyph, window), 3321 egw = max (glyph_width (Vcontinuation_glyph, window),
3136 glyph_width (Vtruncation_glyph, window)); 3322 glyph_width (Vtruncation_glyph, window));
3152 much space. */ 3338 much space. */
3153 switch (pixel_to_char) 3339 switch (pixel_to_char)
3154 { 3340 {
3155 case DISPLAYABLE_PIXEL_TO_CHAR: 3341 case DISPLAYABLE_PIXEL_TO_CHAR:
3156 if (char_width) 3342 if (char_width)
3157 *char_width = ROUND_UP (*pixel_width, cpw) / cpw; 3343 *char_width = ROUND_UP (*disp_pixel_width, cpw) / cpw;
3158 if (char_height) 3344 if (char_height)
3159 *char_height = ROUND_UP (*pixel_height, cph) / cph; 3345 *char_height = ROUND_UP (*disp_pixel_height, cph) / cph;
3346 break;
3347 case CHAR_TO_DISPLAYABLE_PIXEL:
3348 if (disp_pixel_width)
3349 *disp_pixel_width = *char_width * cpw;
3350 if (disp_pixel_height)
3351 *disp_pixel_height = *char_height * cph;
3160 break; 3352 break;
3161 case TOTAL_PIXEL_TO_CHAR: 3353 case TOTAL_PIXEL_TO_CHAR:
3162 /* Convert to chars so that the total frame size is pixel_width x 3354 /* Convert to chars so that the total frame size is pixel_width x
3163 pixel_height. */ 3355 pixel_height. */
3164 if (char_width) 3356 if (char_width)
3165 *char_width = 1 + ((*pixel_width - egw) - bdr - obw) / cpw; 3357 *char_width = 1 + ((*total_pixel_width - egw) - bdr - obw) / cpw;
3166 if (char_height) 3358 if (char_height)
3167 *char_height = (*pixel_height - bdr - obh) / cph; 3359 *char_height = (*total_pixel_height - bdr - obh) / cph;
3168 break; 3360 break;
3169 case CHAR_TO_TOTAL_PIXEL: 3361 case CHAR_TO_TOTAL_PIXEL:
3170 if (pixel_width) 3362 if (total_pixel_width)
3171 *pixel_width = (*char_width - 1) * cpw + egw + bdr + obw; 3363 *total_pixel_width = (*char_width - 1) * cpw + egw + bdr + obw;
3172 if (pixel_height) 3364 if (total_pixel_height)
3173 *pixel_height = *char_height * cph + bdr + obh; 3365 *total_pixel_height = *char_height * cph + bdr + obh;
3174 break; 3366 break;
3175 case CHAR_TO_DISPLAYABLE_PIXEL: 3367 case TOTAL_PIXEL_TO_DISPLAYABLE_PIXEL:
3176 if (pixel_width) 3368 /* Convert to chars so that the total frame size is pixel_width x
3177 *pixel_width = *char_width * cpw; 3369 pixel_height. */
3178 if (pixel_height) 3370 if (disp_pixel_width)
3179 *pixel_height = *char_height * cph; 3371 *disp_pixel_width = cpw + (*total_pixel_width - egw) - bdr - obw;
3372 if (disp_pixel_height)
3373 *disp_pixel_height = *total_pixel_height - bdr - obh;
3180 break; 3374 break;
3181 } 3375 case DISPLAYABLE_PIXEL_TO_TOTAL_PIXEL:
3182 } 3376 if (total_pixel_width)
3183 3377 *total_pixel_width = *disp_pixel_width - cpw + egw + bdr + obw;
3184 /* This takes the size in pixels of the text area, and returns the number 3378 if (total_pixel_height)
3379 *total_pixel_height = *disp_pixel_height + bdr + obh;
3380 break;
3381 }
3382 }
3383
3384
3385 static enum frame_size_type
3386 canonicalize_frame_size_type (enum frame_size_type type, int pixgeom)
3387 {
3388 if (type == SIZE_FRAME_UNIT)
3389 {
3390 if (pixgeom)
3391 type = SIZE_DISPLAYABLE_PIXEL;
3392 else
3393 type = SIZE_CHAR_CELL;
3394 }
3395 return type;
3396 }
3397
3398 /* Basic frame conversion function. Convert source size to destination
3399 size, where either of them can be in total pixels, displayable pixels,
3400 frame units or character-cell units. */
3401
3402 static void
3403 frame_conversion_internal (struct frame *f,
3404 enum frame_size_type source,
3405 int source_width, int source_height,
3406 enum frame_size_type dest,
3407 int *dest_width, int *dest_height)
3408 {
3409 int pixgeom = window_system_pixelated_geometry (wrap_frame (f));
3410 dest = canonicalize_frame_size_type (dest, pixgeom);
3411 source = canonicalize_frame_size_type (source, pixgeom);
3412 if (source == dest)
3413 {
3414 *dest_width = source_width;
3415 *dest_height = source_height;
3416 }
3417 else if (source == SIZE_TOTAL_PIXEL && dest == SIZE_CHAR_CELL)
3418 frame_conversion_internal_1 (f, TOTAL_PIXEL_TO_CHAR,
3419 &source_width, &source_height, 0, 0,
3420 dest_width, dest_height);
3421 else if (source == SIZE_DISPLAYABLE_PIXEL && dest == SIZE_CHAR_CELL)
3422 frame_conversion_internal_1 (f, DISPLAYABLE_PIXEL_TO_CHAR, 0, 0,
3423 &source_width, &source_height,
3424 dest_width, dest_height);
3425 else if (source == SIZE_TOTAL_PIXEL && dest == SIZE_DISPLAYABLE_PIXEL)
3426 frame_conversion_internal_1 (f, TOTAL_PIXEL_TO_DISPLAYABLE_PIXEL,
3427 &source_width, &source_height,
3428 dest_width, dest_height, 0, 0);
3429 else if (dest == SIZE_TOTAL_PIXEL && source == SIZE_CHAR_CELL)
3430 frame_conversion_internal_1 (f, CHAR_TO_TOTAL_PIXEL,
3431 dest_width, dest_height, 0, 0,
3432 &source_width, &source_height);
3433 else if (dest == SIZE_DISPLAYABLE_PIXEL && source == SIZE_CHAR_CELL)
3434 frame_conversion_internal_1 (f, CHAR_TO_DISPLAYABLE_PIXEL, 0, 0,
3435 dest_width, dest_height,
3436 &source_width, &source_height);
3437 else if (dest == SIZE_TOTAL_PIXEL && source == SIZE_DISPLAYABLE_PIXEL)
3438 frame_conversion_internal_1 (f, DISPLAYABLE_PIXEL_TO_TOTAL_PIXEL,
3439 dest_width, dest_height,
3440 &source_width, &source_height, 0, 0);
3441 else
3442 {
3443 ABORT ();
3444 if (dest_width)
3445 *dest_width = 0;
3446 if (dest_height)
3447 *dest_height = 0;
3448 }
3449 }
3450
3451 /* This takes the size in pixels of the client area, and returns the number
3185 of characters that will fit there, taking into account the internal 3452 of characters that will fit there, taking into account the internal
3186 border width, and the pixel width of the line terminator glyphs (which 3453 border width, and the pixel width of the line terminator glyphs (which
3187 always count as one "character" wide, even if they are not the same size 3454 always count as one "character" wide, even if they are not the same size
3188 as the default character size of the default font). The frame scrollbar 3455 as the default character size of the default font). The frame scrollbar
3189 width and left and right toolbar widths are also subtracted out of the 3456 width and left and right toolbar widths are also subtracted out of the
3190 available width. The frame scrollbar height and top and bottom toolbar 3457 available width. The frame scrollbar height and top and bottom toolbar
3191 heights are subtracted out of the available height. 3458 heights are subtracted out of the available height.
3192 3459
3193 Therefore the result is not necessarily a multiple of anything in 3460 Therefore the result is not necessarily a multiple of anything in
3194 particular. */ 3461 particular. */
3462
3195 void 3463 void
3196 pixel_to_char_size (struct frame *f, int pixel_width, int pixel_height, 3464 pixel_to_char_size (struct frame *f, int pixel_width, int pixel_height,
3197 int *char_width, int *char_height) 3465 int *char_width, int *char_height)
3198 { 3466 {
3199 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, 3467 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pixel_width, pixel_height,
3200 &pixel_width, &pixel_height, char_width, 3468 SIZE_CHAR_CELL, char_width, char_height);
3201 char_height, 0); 3469 }
3202 } 3470
3203 3471 /* Given a character size, this returns the minimum pixel size of the
3204 /* Given a character size, this returns the minimum number of pixels 3472 client area necessary to display that many characters, taking into
3205 necessary to display that many characters, taking into account the 3473 account the internal border width, scrollbar height and width, toolbar
3206 internal border width, scrollbar height and width, toolbar heights and 3474 heights and widths and the size of the line terminator glyphs (assuming
3207 widths and the size of the line terminator glyphs (assuming the line 3475 the line terminators take up exactly one character position).
3208 terminators take up exactly one character position).
3209 3476
3210 Therefore the result is not necessarily a multiple of anything in 3477 Therefore the result is not necessarily a multiple of anything in
3211 particular. */ 3478 particular. */
3479
3212 void 3480 void
3213 char_to_pixel_size (struct frame *f, int char_width, int char_height, 3481 char_to_pixel_size (struct frame *f, int char_width, int char_height,
3214 int *pixel_width, int *pixel_height) 3482 int *pixel_width, int *pixel_height)
3215 { 3483 {
3216 frame_conversion_internal (f, CHAR_TO_TOTAL_PIXEL, 3484 frame_conversion_internal (f, SIZE_CHAR_CELL, char_width, char_height,
3217 pixel_width, pixel_height, &char_width, 3485 SIZE_TOTAL_PIXEL, pixel_width, pixel_height);
3218 &char_height, 0); 3486 }
3219 } 3487
3220 3488 /* Versions of the above that operate in "frame units" instead of
3221 /* Given a pixel size, rounds DOWN to the smallest size in pixels necessary 3489 characters. frame units are the same as characters except on
3222 to display the same number of characters as are displayable now. 3490 MS Windows and MS Printer frames, where they are displayable-area
3223 */ 3491 pixels. */
3492
3493 void
3494 pixel_to_frame_unit_size (struct frame *f, int pixel_width, int pixel_height,
3495 int *frame_unit_width, int *frame_unit_height)
3496 {
3497 frame_conversion_internal (f, SIZE_TOTAL_PIXEL, pixel_width, pixel_height,
3498 SIZE_FRAME_UNIT, frame_unit_width,
3499 frame_unit_height);
3500 }
3501
3502 void
3503 frame_unit_to_pixel_size (struct frame *f, int frame_unit_width,
3504 int frame_unit_height,
3505 int *pixel_width, int *pixel_height)
3506 {
3507 frame_conversion_internal (f, SIZE_FRAME_UNIT, frame_unit_width,
3508 frame_unit_height,
3509 SIZE_TOTAL_PIXEL, pixel_width, pixel_height);
3510 }
3511
3224 void 3512 void
3225 round_size_to_char (struct frame *f, int in_width, int in_height, 3513 round_size_to_char (struct frame *f, int in_width, int in_height,
3226 int *out_width, int *out_height) 3514 int *out_width, int *out_height)
3227 { 3515 {
3228 int char_width; 3516 int char_width;
3229 int char_height; 3517 int char_height;
3230 pixel_to_char_size (f, in_width, in_height, &char_width, &char_height); 3518 pixel_to_char_size (f, in_width, in_height, &char_width, &char_height);
3231 char_to_pixel_size (f, char_width, char_height, out_width, out_height); 3519 char_to_pixel_size (f, char_width, char_height, out_width, out_height);
3232 } 3520 }
3233 3521
3234 /* Versions of the above which always account for real font metrics. 3522 /* Get the frame size in character cells, recalculating on the fly.
3235 */ 3523 #### The logic of this function follows former logic elsewhere,
3236 void 3524 which used FRAME_PIXWIDTH() on pixelated-geometry systems but
3237 pixel_to_real_char_size (struct frame *f, int pixel_width, int pixel_height, 3525 FRAME_WIDTH() on non-pixelated-geometry systems. Not clear why not
3238 int *char_width, int *char_height) 3526 always just use one or the other.
3239 { 3527
3240 frame_conversion_internal (f, TOTAL_PIXEL_TO_CHAR, 3528 Why don't we just use FRAME_CHARWIDTH() etc. in get_frame_char_size()?
3241 &pixel_width, &pixel_height, char_width, 3529 That wouldn't work because change_frame_size_1() depends on the
3242 char_height, 1); 3530 following function to *set* the values of FRAME_CHARWIDTH() etc.
3243 } 3531
3244 3532 But elsewhere I suppose we could use it.
3245 void 3533 */
3246 char_to_real_pixel_size (struct frame *f, int char_width, int char_height, 3534
3247 int *pixel_width, int *pixel_height) 3535 static void
3248 { 3536 get_frame_char_size (struct frame *f, int *out_width, int *out_height)
3249 frame_conversion_internal (f, CHAR_TO_TOTAL_PIXEL, 3537 {
3250 pixel_width, pixel_height, &char_width, 3538 if (window_system_pixelated_geometry (wrap_frame (f)))
3251 &char_height, 1); 3539 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
3252 } 3540 out_width, out_height);
3253 3541 else
3254 void 3542 {
3255 round_size_to_real_char (struct frame *f, int in_width, int in_height, 3543 *out_width = FRAME_WIDTH (f);
3256 int *out_width, int *out_height) 3544 *out_height = FRAME_HEIGHT (f);
3257 { 3545 }
3258 int char_width; 3546 }
3259 int char_height; 3547
3260 pixel_to_real_char_size (f, in_width, in_height, &char_width, &char_height); 3548 static void
3261 char_to_real_pixel_size (f, char_width, char_height, out_width, out_height); 3549 get_frame_displayable_pixel_size (struct frame *f, int *out_width,
3550 int *out_height)
3551 {
3552 frame_conversion_internal (f, SIZE_FRAME_UNIT, FRAME_WIDTH (f),
3553 FRAME_HEIGHT (f), SIZE_DISPLAYABLE_PIXEL,
3554 out_width, out_height);
3262 } 3555 }
3263 3556
3264 /* Change the frame height and/or width. Values may be given as zero to 3557 /* Change the frame height and/or width. Values may be given as zero to
3265 indicate no change is to take place. */ 3558 indicate no change is to take place. */
3266 static void 3559 static void
3267 change_frame_size_1 (struct frame *f, int newheight, int newwidth) 3560 change_frame_size_1 (struct frame *f, int newwidth, int newheight)
3268 { 3561 {
3269 Lisp_Object frame; 3562 Lisp_Object frame;
3270 int new_pixheight, new_pixwidth; 3563 int new_pixheight, new_pixwidth;
3271 int font_height, real_font_height, font_width; 3564 int real_font_height, real_font_width;
3272 3565
3273 /* #### Chuck -- shouldn't we be checking to see if the frame 3566 /* #### Chuck -- shouldn't we be checking to see if the frame
3274 is being "changed" to its existing size, and do nothing if so? */ 3567 is being "changed" to its existing size, and do nothing if so? */
3275 /* No, because it would hose toolbar updates. The toolbar 3568 /* No, because it would hose toolbar updates. The toolbar
3276 update code relies on this function to cause window `top' and 3569 update code relies on this function to cause window `top' and
3277 `left' coordinates to be recomputed even though no frame size 3570 `left' coordinates to be recomputed even though no frame size
3278 change occurs. --kyle */ 3571 change occurs. --kyle */
3279 if (in_display || hold_frame_size_changes) 3572 if (in_display || hold_frame_size_changes)
3280 ABORT (); 3573 ABORT ();
3281 3574
3575 /* If we don't have valid values, exit. */
3576 if (!newheight && !newwidth)
3577 return;
3578
3282 frame = wrap_frame (f); 3579 frame = wrap_frame (f);
3283 3580
3284 default_face_height_and_width (frame, &real_font_height, 0); 3581 default_face_height_and_width (frame, &real_font_height, &real_font_width);
3285 default_face_height_and_width_1 (frame, &font_height, &font_width); 3582 if (window_system_pixelated_geometry (frame))
3583 {
3584 new_pixheight = newheight;
3585 new_pixwidth = newwidth - real_font_width;
3586 }
3587 else
3588 {
3589 new_pixheight = newheight * real_font_height;
3590 new_pixwidth = (newwidth - 1) * real_font_width;
3591 }
3286 3592
3287 /* This size-change overrides any pending one for this frame. */ 3593 /* This size-change overrides any pending one for this frame. */
3288 f->size_change_pending = 0; 3594 f->size_change_pending = 0;
3289 FRAME_NEW_HEIGHT (f) = 0; 3595 FRAME_NEW_HEIGHT (f) = 0;
3290 FRAME_NEW_WIDTH (f) = 0; 3596 FRAME_NEW_WIDTH (f) = 0;
3291 3597
3292 new_pixheight = newheight * font_height;
3293 new_pixwidth = (newwidth - 1) * font_width;
3294 3598
3295 /* #### dependency on FRAME_WIN_P should be removed. */ 3599 /* #### dependency on FRAME_WIN_P should be removed. */
3296 if (FRAME_WIN_P (f)) 3600 if (FRAME_WIN_P (f))
3297 { 3601 {
3298 new_pixheight += FRAME_SCROLLBAR_HEIGHT (f); 3602 new_pixheight += FRAME_SCROLLBAR_HEIGHT (f);
3336 trunc_width = glyph_width (Vtruncation_glyph, 3640 trunc_width = glyph_width (Vtruncation_glyph,
3337 FRAME_SELECTED_WINDOW (f)); 3641 FRAME_SELECTED_WINDOW (f));
3338 cont_width = glyph_width (Vcontinuation_glyph, 3642 cont_width = glyph_width (Vcontinuation_glyph,
3339 FRAME_SELECTED_WINDOW (f)); 3643 FRAME_SELECTED_WINDOW (f));
3340 adjustment = max (trunc_width, cont_width); 3644 adjustment = max (trunc_width, cont_width);
3341 adjustment = max (adjustment, font_width); 3645 adjustment = max (adjustment, real_font_width);
3342 3646
3343 new_pixwidth += adjustment; 3647 new_pixwidth += adjustment;
3344 } 3648 }
3345 3649
3346 /* If we don't have valid values, exit. */ 3650 if (newheight)
3347 if (!new_pixheight && !new_pixwidth)
3348 return;
3349
3350 if (new_pixheight)
3351 { 3651 {
3352 /* Adjust for gutters here so that we always get set 3652 /* Adjust for gutters here so that we always get set
3353 properly. */ 3653 properly. */
3354 new_pixheight -= 3654 new_pixheight -=
3355 (FRAME_TOP_GUTTER_BOUNDS (f) 3655 (FRAME_TOP_GUTTER_BOUNDS (f)
3396 FRAME_HEIGHT (f) = newheight; 3696 FRAME_HEIGHT (f) = newheight;
3397 if (FRAME_TTY_P (f)) 3697 if (FRAME_TTY_P (f))
3398 f->pixheight = newheight; 3698 f->pixheight = newheight;
3399 } 3699 }
3400 3700
3401 if (new_pixwidth) 3701 if (newwidth)
3402 { 3702 {
3403 /* Adjust for gutters here so that we always get set 3703 /* Adjust for gutters here so that we always get set
3404 properly. */ 3704 properly. */
3405 new_pixwidth -= 3705 new_pixwidth -=
3406 (FRAME_LEFT_GUTTER_BOUNDS (f) 3706 (FRAME_LEFT_GUTTER_BOUNDS (f)
3420 FRAME_WIDTH (f) = newwidth; 3720 FRAME_WIDTH (f) = newwidth;
3421 if (FRAME_TTY_P (f)) 3721 if (FRAME_TTY_P (f))
3422 f->pixwidth = newwidth; 3722 f->pixwidth = newwidth;
3423 } 3723 }
3424 3724
3425 if (window_system_pixelated_geometry (frame)) 3725 get_frame_char_size (f, &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
3426 pixel_to_real_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
3427 &FRAME_CHARWIDTH (f), &FRAME_CHARHEIGHT (f));
3428 else
3429 {
3430 FRAME_CHARWIDTH (f) = FRAME_WIDTH (f);
3431 FRAME_CHARHEIGHT (f) = FRAME_HEIGHT (f);
3432 }
3433 3726
3434 MARK_FRAME_TOOLBARS_CHANGED (f); 3727 MARK_FRAME_TOOLBARS_CHANGED (f);
3435 MARK_FRAME_GUTTERS_CHANGED (f); 3728 MARK_FRAME_GUTTERS_CHANGED (f);
3436 MARK_FRAME_CHANGED (f); 3729 MARK_FRAME_CHANGED (f);
3437 f->echo_area_garbaged = 1; 3730 f->echo_area_garbaged = 1;
3438 } 3731 }
3439 3732
3440 void 3733 void
3441 change_frame_size (struct frame *f, int newheight, int newwidth, int delay) 3734 change_frame_size (struct frame *f, int newwidth, int newheight, int delay)
3442 { 3735 {
3443 /* sometimes we get passed a size that's too small (esp. when a 3736 /* sometimes we get passed a size that's too small (esp. when a
3444 client widget gets resized, since we have no control over this). 3737 client widget gets resized, since we have no control over this).
3445 So deal. */ 3738 So deal. */
3446 check_frame_size (f, &newheight, &newwidth); 3739 check_frame_size (f, &newheight, &newwidth);
3468 if (FRAME_TTY_P (f)) 3761 if (FRAME_TTY_P (f))
3469 { 3762 {
3470 Lisp_Object frmcons; 3763 Lisp_Object frmcons;
3471 3764
3472 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f))) 3765 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f)))
3473 change_frame_size_1 (XFRAME (XCAR (frmcons)), newheight, newwidth); 3766 change_frame_size_1 (XFRAME (XCAR (frmcons)), newwidth, newheight);
3474 } 3767 }
3475 else 3768 else
3476 change_frame_size_1 (f, newheight, newwidth); 3769 change_frame_size_1 (f, newwidth, newheight);
3477 } 3770 }
3478 3771
3479 3772
3480 /* The caller is responsible for freeing the returned string. */ 3773 /* The caller is responsible for freeing the returned string. */
3481 static Ibyte * 3774 static Ibyte *