1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-26 15:21:51 -08:00
emacs/src/widget.c
Martin Rudalics a190b4cfd8 Major rewrite of adjust_frame_size
Have adjust_frame_size pass native frame sizes to backends
instead of text sizes.  Expand frame size history management.
Drop PIXELWISE argument from change_frame_size and convert
native to text sizes only when calling adjust_frame_size.  Use
convention in arguments that -1 instead of 0 means that no size
change is required.  When adjusting frame sizes pick up delayed
size changes (Bug#46827).

* lisp/frame.el (frame-notice-user-settings, make-frame): Don't
set frame size history.
(frame--size-history): Rewrite doc-string.  Handle new formats
of `frame-size-history' entries.
* src/dispextern.h (delayed_size_change): Extern it.
(change_frame_size): Drop last argument from extern.
* src/dispnew.c (delayed_size_change): Make it global.
(handle_window_change_signal): Reformat.  Drop last argument
from change_frame_size call.
(do_pending_window_change, init_display_interactive): Drop last
argument from change_frame_size call.
(change_frame_size_1): NEW_WIDTH and NEW_HEIGHT now specify
native sizes.  Drop last argument PIXELWISE.  Queue a change
when it either differs from F's current pixel sizes or F's
previously queued sizes.  Inject frame_size_history_extra call
when queuing.  Adopt convention that for queued sizes -1 means
that no size change is required.  Convert from native to text
sizes when calling adjust_frame_size.
(change_frame_size): Drop last argument PIXELWISE and drop it
also in change_frame_size_1 calls.
* src/frame.c (frame_size_history_add): Remove.
(frame_inhibit_resize): Remove call to frame_size_history_add.
(set_menu_bar_lines, set_tab_bar_lines): Simplify.  Drop last
argument from change_frame_size call.
(frame_windows_min_size): No more static.
(keep_ratio): Minor rewrite using macros.
(frame_size_history_adjust, frame_size_history_plain)
(frame_size_history_extra): New functions.
(adjust_frame_size): Major rewrite.  Adopt new convention that
negative values for new sizes mean no change.  Pick up delayed
size changes from F's new_width and new_height slots
(Bug#46827).  Call set_window_size_hook with native instead of
text sizes.  Do not sanitize window sizes any more.  Call
frame_size_history_adjust instead of frame_size_history_add.
Always set F's resized_p slot to true.
(make_frame): Initialize new_width and new_height slots to -1.
Simplify setup of initial sizes and an adjust_frame_size call.
(Fframe_parameters): Drop processing F's new_pixelwise slot.
(check_frame_pixels): Reorder to make declarations appear first.
(Fset_frame_height, Fset_frame_width, Fset_frame_size): Pass
explicit width and height values to adjust_frame_size instead of
-1.
(gui_set_frame_parameters): Minor rewrite making sure that
explicit sizes and the corresponding parameter are passed to
adjust_frame_size.  Remove frame_size_history_add call.
(gui_figure_window_size): Drop last two arguments.  Simplify
assignment of initial size.  Set new_height and new_width slots
to -1.  Use adjust_frame_size to set sizes instead of returning
them to caller.
(syms_of_frame): Drop symbols used by frame size history; these
are now built on-the-fly.  Also drop some menu bar related
symbols in favor of Qmenu_bar_lines.
* src/frame.h (struct frame): Remove new_pixelwise.
(SET_FRAME_COLS, SET_FRAME_LINES, SET_FRAME_WIDTH)
(SET_FRAME_HEIGHT): Remove macros.
(frame_size_history_add): Remove externs.
(frame_windows_min_size, frame_size_history_plain)
(frame_size_history_extra): Add externs.
(FRAME_WINDOWS_WIDTH, FRAME_WINDOWS_HEIGHT): Rename to
FRAME_INNER_WIDTH and FRAME_INNER_HEIGHT.
(gui_figure_window_size): Drop last two arguments from
extern.
* src/gtkutil.c (xg_frame_resized): Rename arguments to WIDTH
and HEIGHT.  Consult delayed_size_change to handle case where
WIDTH and HEIGHT do not match F's new_width and new_height
values.  Call change_frame_size with native sizes and without
PIXELWISE argument.  Instead of frame_size_history_add call
frame_size_history_extra.
(xg_frame_set_char_size): WIDTH and HEIGHT are native sizes now;
fix adjust_frame_size call accordingly.  Instead of
frame_size_history_add call frame_size_history_extra.
(style_changed_cb): Call xg_frame_set_char_size with native
instead of text sizes.
(tb_size_cb): Remove frame_size_history_add call.  Call
adjust_frame_size with INHIBIT 5.
(free_frame_tool_bar, xg_change_toolbar_position): Remove
frame_size_history_add call.
(update_frame_tool_bar): Call adjust_frame_size with INHIBIT 2
and let it handle frame_inhibit_implied_resize and
fullheight/-width.  Remove frame_size_history_add call.
* src/keyboard.c (Fsuspend_emacs): Call change_frame_size with
native sizes.
* src/nsfns.m (ns_set_tool_bar_lines): Call adjust_frame_size
with INHIBIT 2 and let it handle frame_inhibit_implied_resize
and fullheight/-width.  Remove frame_size_history_add call.
(Fx_create_frame): Drop two last arguments in
gui_figure_window_size call.  Do not SET_FRAME_WIDTH and
SET_FRAME_HEIGHT, the adjust_frame_size in
gui_figure_window_size did that already.
* src/nsterm.m (ns_set_window_size): Drop PIXELWISE argument and
its processing; WIDTH and HEIGHT represent native pixel sizes
now.  Call change_frame_size with native sizes.  Remove call to
frame_size_history_add.
([EmacsView viewDidResize:]): Call change_frame_size with native
sizes.
* src/term.c (Fresume_tty): Call change_frame_size with native
sizes.
* src/termhooks.h (*set_window_size_hook): Drop last argument
PIXELWISE.
* src/w32fns.c (w32_change_tab_bar_height)
(w32_change_tool_bar_height): Fix handling of these in the initial
phase before they have been resized at least once.
(Fx_create_frame, w32_create_tip_frame): Drop two last arguments
in gui_figure_window_size call.  Do not SET_FRAME_WIDTH and
SET_FRAME_HEIGHT (or SET_FRAME_COLS and SET_FRAME_LINES), the
adjust_frame_size in gui_figure_window_size did that already.
* src/w32inevt.c (resize_event, maybe_generate_resize_event):
Pass native sizes to change_frame_size.
* src/w32term.c (w32_read_socket): When WM_WINDOWPOSCHANGED pass
native sizes to change_frame_size.
(w32_new_font): Recalculate FRAME_TAB_BAR_HEIGHT.  Simplify
code.
(w32fullscreen_hook): Call change_frame_size with native sizes.
(w32_set_window_size): Drop argument PIXELWISE and its
processing; WIDTH and HEIGHT are native sizes now.  Remove
frame_size_history_add calls.  Pass native sizes to
change_frame_size.
* src/widget.c (set_frame_size): Set width and height of widget
directly.  Call frame_size_history_plain instead of
frame_size_history_add.
(update_from_various_frame_slots): Call
frame_size_history_extra.
(EmacsFrameRealize): Call frame_size_history_plain.
(EmacsFrameResize): Call change_frame_size with native sizes.
Call frame_size_history_extra instead of frame_size_history_add.
(EmacsFrameSetCharSize): Call frame_size_history_extra.  Drop
PIXELWISE argument in x_set_window_size call and specify pixels.
(pixel_to_text_size): Remove function.
* src/xdisp.c (resize_mini_window): Replace FRAME_WINDOWS_HEIGHT
with FRAME_INNER_HEIGHT.
(redisplay_tab_bar): Don't set tab_bar_redisplayed when we did
not redisplay it.
(redisplay_tool_bar): Don't call it for external tool bar.
Don't set tool_bar_redisplayed when we did not redisplay it.
(redisplay_window): When the tool bar is external call
update_frame_tool_bar directly.
* src/xfns.c (x_set_menu_bar_lines): Call adjust_frame_size only
if number of menu bar lines changed and fix 6th argument.
(x_change_tab_bar_height, x_change_tool_bar_height): Fix
handling of these in the initial phase before they have been
resized at least once.
(Fx_create_frame, x_create_tip_frame): Drop two last arguments
in gui_figure_window_size call.  Do not SET_FRAME_WIDTH and
SET_FRAME_HEIGHT (or SET_FRAME_COLS and SET_FRAME_LINES), the
adjust_frame_size in gui_figure_window_size did that already.
* src/xmenu.c (update_frame_menubar): Fix 6th arg of
adjust_frame_size call.
(free_frame_menubar): For Motif frames fix fullscreen and
`frame-inhibit-implied-resize' handling.  Fix 6th arg of
adjust_frame_size calls.
* src/xterm.c (x_net_wm_state): Remove call to
frame_size_history_add.
(handle_one_xevent): For PropertyNotify and UnmapNotify events
add frame_size_history_plain calls.  For MapNotify and
ConfigureNotify events add a frame_size_history_extra call.  For
ConfigureNotify events also handle delayed size changes and call
change_frame_size with native sizes.
(x_new_font): Recalculate FRAME_TAB_BAR_HEIGHT.  Simplify code.
(x_handle_net_wm_state): Remove frame_size_history_add call.
(x_check_fullscreen): Remove frame_size_history_add call.  Call
change_frame_size with native height.
(x_set_window_size_1): WIDTH and HEIGHT are now native.  Remove
some frame_size_history_add calls and add frame_size_history_extra
calls instead.  If the frame is not visible call adjust_frame_size
directly instead of calling change_frame_size.
(x_set_window_size): Drop PIXELWISE argument.  WIDTH and HEIGHT
represent native sizes now.
(x_make_frame_visible, x_make_frame_invisible): Call
frame_size_history_plain.
* src/xterm.h (x_set_window_size): Drop last argument from
extern declaration.
2021-04-27 09:53:42 +02:00

476 lines
14 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* The emacs frame widget.
Copyright (C) 1992-1993, 2000-2021 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* Emacs 19 face widget ported by Fred Pierresteguy */
/* This file has been censored by the Communications Decency Act.
That law was passed under the guise of a ban on pornography, but
it bans far more than that. This file did not contain pornography,
but it was censored nonetheless. */
#include <config.h>
#include "widget.h"
#include <stdlib.h>
#include "lisp.h"
#include "sysstdio.h"
#include "xterm.h"
#include "frame.h"
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#include <X11/cursorfont.h>
#include "widgetprv.h"
#include <X11/ObjectP.h>
#include <X11/Shell.h>
#include <X11/ShellP.h>
#include "../lwlib/lwlib.h"
static void EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2);
static void EmacsFrameDestroy (Widget widget);
static void EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs);
static void EmacsFrameResize (Widget widget);
static XtGeometryResult EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *result);
#define offset(field) offsetof (EmacsFrameRec, emacs_frame.field)
static XtResource resources[] = {
{(char *) XtNgeometry, (char *) XtCGeometry, XtRString, sizeof (String),
offset (geometry), XtRString, (XtPointer) 0},
{XtNiconic, XtCIconic, XtRBoolean, sizeof (Boolean),
offset (iconic), XtRImmediate, (XtPointer) False},
{(char *) XtNemacsFrame, (char *) XtCEmacsFrame,
XtRPointer, sizeof (XtPointer),
offset (frame), XtRImmediate, 0},
{(char *) XtNminibuffer, (char *) XtCMinibuffer, XtRInt, sizeof (int),
offset (minibuffer), XtRImmediate, (XtPointer)0},
{(char *) XtNunsplittable, (char *) XtCUnsplittable,
XtRBoolean, sizeof (Boolean),
offset (unsplittable), XtRImmediate, (XtPointer)0},
{(char *) XtNinternalBorderWidth, (char *) XtCInternalBorderWidth,
XtRInt, sizeof (int),
offset (internal_border_width), XtRImmediate, (XtPointer)4},
{(char *) XtNinterline, (char *) XtCInterline, XtRInt, sizeof (int),
offset (interline), XtRImmediate, (XtPointer)0},
{(char *) XtNforeground, (char *) XtCForeground, XtRPixel, sizeof (Pixel),
offset (foreground_pixel), XtRString, (char *) "XtDefaultForeground"},
{(char *) XtNcursorColor, (char *) XtCForeground, XtRPixel, sizeof (Pixel),
offset (cursor_color), XtRString, (char *) "XtDefaultForeground"},
{(char *) XtNbarCursor, (char *) XtCBarCursor, XtRBoolean, sizeof (Boolean),
offset (bar_cursor), XtRImmediate, (XtPointer)0},
{(char *) XtNvisualBell, (char *) XtCVisualBell, XtRBoolean, sizeof (Boolean),
offset (visual_bell), XtRImmediate, (XtPointer)0},
{(char *) XtNbellVolume, (char *) XtCBellVolume, XtRInt, sizeof (int),
offset (bell_volume), XtRImmediate, (XtPointer)0},
};
#undef offset
/*
static XtActionsRec
emacsFrameActionsTable [] = {
{"keypress", key_press},
{"focus_in", emacs_frame_focus_handler},
{"focus_out", emacs_frame_focus_handler},
};
static char
emacsFrameTranslations [] = "\
<KeyPress>: keypress()\n\
<FocusIn>: focus_in()\n\
<FocusOut>: focus_out()\n\
";
*/
static EmacsFrameClassRec emacsFrameClassRec = {
{ /* core fields */
/* superclass */ 0, /* filled in by emacsFrameClass */
/* class_name */ (char *) "EmacsFrame",
/* widget_size */ sizeof (EmacsFrameRec),
/* class_initialize */ 0,
/* class_part_initialize */ 0,
/* class_inited */ FALSE,
/* initialize */ EmacsFrameInitialize,
/* initialize_hook */ 0,
/* realize */ EmacsFrameRealize,
/* actions */ 0, /*emacsFrameActionsTable*/
/* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
/* resources */ resources,
/* resource_count */ XtNumber (resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ EmacsFrameDestroy,
/* resize */ EmacsFrameResize,
/* expose */ XtInheritExpose,
/* Emacs never does XtSetvalues on this widget, so we have no code
for it. */
/* set_values */ 0, /* Not supported */
/* set_values_hook */ 0,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ 0,
/* accept_focus */ XtInheritAcceptFocus,
/* version */ XtVersion,
/* callback_private */ 0,
/* tm_table */ 0, /*emacsFrameTranslations*/
/* query_geometry */ EmacsFrameQueryGeometry,
/* display_accelerator */ XtInheritDisplayAccelerator,
/* extension */ 0
}
};
WidgetClass
emacsFrameClass (void)
{
/* Set the superclass here rather than relying on static
initialization, to work around an unexelf.c bug on x86 platforms
that use the GNU Gold linker (Bug#27248). */
emacsFrameClassRec.core_class.superclass = &widgetClassRec;
return (WidgetClass) &emacsFrameClassRec;
}
static void
get_default_char_pixel_size (EmacsFrame ew, int *pixel_width, int *pixel_height)
{
struct frame *f = ew->emacs_frame.frame;
*pixel_width = FRAME_COLUMN_WIDTH (f);
*pixel_height = FRAME_LINE_HEIGHT (f);
}
static void
pixel_to_char_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height, int *char_width, int *char_height)
{
struct frame *f = ew->emacs_frame.frame;
*char_width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, (int) pixel_width);
*char_height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (int) pixel_height);
}
static void
char_to_pixel_size (EmacsFrame ew, int char_width, int char_height, Dimension *pixel_width, Dimension *pixel_height)
{
struct frame *f = ew->emacs_frame.frame;
*pixel_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, char_width);
*pixel_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, char_height);
}
static void
round_size_to_char (EmacsFrame ew, Dimension in_width, Dimension in_height, Dimension *out_width, Dimension *out_height)
{
int char_width;
int char_height;
pixel_to_char_size (ew, in_width, in_height, &char_width, &char_height);
char_to_pixel_size (ew, char_width, char_height, out_width, out_height);
}
static Widget
get_wm_shell (Widget w)
{
Widget wmshell;
for (wmshell = XtParent (w);
wmshell && !XtIsWMShell (wmshell);
wmshell = XtParent (wmshell));
return wmshell;
}
#if 0 /* Currently not used. */
static void
mark_shell_size_user_specified (Widget wmshell)
{
if (! XtIsWMShell (wmshell)) emacs_abort ();
/* This is kind of sleazy, but I can't see how else to tell it to make it
mark the WM_SIZE_HINTS size as user specified when appropriate. */
((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;
}
#endif
static void
set_frame_size (EmacsFrame ew)
{
/* The widget hierarchy is
argv[0] emacsShell pane Frame-NAME
ApplicationShell EmacsShell Paned EmacsFrame
We accept geometry specs in this order:
*Frame-NAME.geometry
*EmacsFrame.geometry
Emacs.geometry
Other possibilities for widget hierarchies might be
argv[0] frame pane Frame-NAME
ApplicationShell EmacsShell Paned EmacsFrame
or
argv[0] Frame-NAME pane Frame-NAME
ApplicationShell EmacsShell Paned EmacsFrame
or
argv[0] Frame-NAME pane emacsTextPane
ApplicationShell EmacsFrame Paned EmacsTextPane
With the current setup, the text-display-area is the part which is
an emacs "frame", since that's the only part managed by emacs proper
(the menubar and the parent of the menubar and all that sort of thing
are managed by lwlib.)
The EmacsShell widget is simply a replacement for the Shell widget
which is able to deal with using an externally-supplied window instead
of always creating its own. It is not actually emacs specific, and
should possibly have class "Shell" instead of "EmacsShell" to simplify
the resources.
*/
struct frame *f = ew->emacs_frame.frame;
ew->core.width = FRAME_PIXEL_WIDTH (f);
ew->core.height = FRAME_PIXEL_HEIGHT (f);
if (CONSP (frame_size_history))
frame_size_history_plain
(f, build_string ("set_frame_size"));
}
static void
update_wm_hints (EmacsFrame ew)
{
Widget wmshell = get_wm_shell ((Widget) ew);
int cw;
int ch;
Dimension rounded_width;
Dimension rounded_height;
int char_width;
int char_height;
int base_width;
int base_height;
/* This happens when the frame is just created. */
if (! wmshell) return;
pixel_to_char_size (ew, ew->core.width, ew->core.height,
&char_width, &char_height);
char_to_pixel_size (ew, char_width, char_height,
&rounded_width, &rounded_height);
get_default_char_pixel_size (ew, &cw, &ch);
base_width = (wmshell->core.width - ew->core.width
+ (rounded_width - (char_width * cw)));
base_height = (wmshell->core.height - ew->core.height
+ (rounded_height - (char_height * ch)));
/* This is kind of sleazy, but I can't see how else to tell it to
make it mark the WM_SIZE_HINTS size as user specified.
*/
/* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
XtVaSetValues (wmshell,
XtNbaseWidth, (XtArgVal) base_width,
XtNbaseHeight, (XtArgVal) base_height,
XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw),
XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch),
XtNminWidth, (XtArgVal) base_width,
XtNminHeight, (XtArgVal) base_height,
NULL);
}
void
widget_update_wm_size_hints (Widget widget)
{
EmacsFrame ew = (EmacsFrame) widget;
update_wm_hints (ew);
}
static void
update_various_frame_slots (EmacsFrame ew)
{
struct frame *f = ew->emacs_frame.frame;
f->internal_border_width = ew->emacs_frame.internal_border_width;
}
static void
update_from_various_frame_slots (EmacsFrame ew)
{
struct frame *f = ew->emacs_frame.frame;
struct x_output *x = f->output_data.x;
ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
ew->core.width = FRAME_PIXEL_WIDTH (f);
ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
ew->emacs_frame.internal_border_width = f->internal_border_width;
ew->emacs_frame.foreground_pixel = FRAME_FOREGROUND_PIXEL (f);
ew->emacs_frame.cursor_color = x->cursor_pixel;
ew->core.border_pixel = x->border_pixel;
if (CONSP (frame_size_history))
frame_size_history_extra
(f, build_string ("update_from_various_frame_slots"),
FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
ew->core.width, ew->core.height,
f->new_width, f->new_height);
}
static void
EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2)
{
EmacsFrame ew = (EmacsFrame) new;
if (!ew->emacs_frame.frame)
{
fputs ("can't create an emacs frame widget without a frame\n", stderr);
exit (1);
}
update_from_various_frame_slots (ew);
set_frame_size (ew);
}
static void
resize_cb (Widget widget,
XtPointer closure,
XEvent *event,
Boolean *continue_to_dispatch)
{
EmacsFrameResize (widget);
}
static void
EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs)
{
EmacsFrame ew = (EmacsFrame) widget;
struct frame *f = ew->emacs_frame.frame;
/* This used to contain SubstructureRedirectMask, but this turns out
to be a problem with XIM on Solaris, and events from that mask
don't seem to be used. Let's check that. */
attrs->event_mask = (STANDARD_EVENT_SET
| PropertyChangeMask
| SubstructureNotifyMask);
*mask |= CWEventMask;
XtCreateWindow (widget, InputOutput, (Visual *) CopyFromParent, *mask,
attrs);
/* Some ConfigureNotify events does not end up in EmacsFrameResize so
make sure we get them all. Seen with xfcwm4 for example. */
XtAddRawEventHandler (widget, StructureNotifyMask, False, resize_cb, NULL);
if (CONSP (frame_size_history))
frame_size_history_plain
(f, build_string ("EmacsFrameRealize"));
update_wm_hints (ew);
}
static void
EmacsFrameDestroy (Widget widget)
{
/* All GCs are now freed in x_free_frame_resources. */
}
static void
EmacsFrameResize (Widget widget)
{
EmacsFrame ew = (EmacsFrame) widget;
struct frame *f = ew->emacs_frame.frame;
if (CONSP (frame_size_history))
frame_size_history_extra
(f, build_string ("EmacsFrameResize"),
FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
ew->core.width, ew->core.height,
f->new_width, f->new_height);
change_frame_size (f, ew->core.width, ew->core.height, false, true, false);
update_wm_hints (ew);
update_various_frame_slots (ew);
cancel_mouse_face (f);
}
static XtGeometryResult
EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
XtWidgetGeometry *result)
{
int mask = request->request_mode;
if (mask & (CWWidth | CWHeight) && !frame_resize_pixelwise)
{
EmacsFrame ew = (EmacsFrame) widget;
Dimension ok_width, ok_height;
round_size_to_char (ew,
mask & CWWidth ? request->width : ew->core.width,
mask & CWHeight ? request->height : ew->core.height,
&ok_width, &ok_height);
if ((mask & CWWidth) && (ok_width != request->width))
{
result->request_mode |= CWWidth;
result->width = ok_width;
}
if ((mask & CWHeight) && (ok_height != request->height))
{
result->request_mode |= CWHeight;
result->height = ok_height;
}
}
return result->request_mode ? XtGeometryAlmost : XtGeometryYes;
}
/* Special entry points */
void
EmacsFrameSetCharSize (Widget widget, int columns, int rows)
{
EmacsFrame ew = (EmacsFrame) widget;
struct frame *f = ew->emacs_frame.frame;
if (CONSP (frame_size_history))
frame_size_history_extra
(f, build_string ("EmacsFrameSetCharSize"),
FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f),
columns, rows,
f->new_width, f->new_height);
if (!frame_inhibit_resize (f, 0, Qfont)
&& !frame_inhibit_resize (f, 1, Qfont))
x_set_window_size (f, 0, columns * FRAME_COLUMN_WIDTH (f),
rows * FRAME_LINE_HEIGHT (f));
}
void
widget_store_internal_border (Widget widget)
{
EmacsFrame ew = (EmacsFrame) widget;
struct frame *f = ew->emacs_frame.frame;
ew->emacs_frame.internal_border_width = f->internal_border_width;
}