428
+ − 1 /* The emacs frame widget.
+ − 2 Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ − 3 Copyright (C) 1993-1995 Sun Microsystems, Inc.
+ − 4 Copyright (C) 1995 Ben Wing.
+ − 5
+ − 6 This file is part of XEmacs.
+ − 7
+ − 8 XEmacs is free software; you can redistribute it and/or modify it
+ − 9 under the terms of the GNU General Public License as published by the
+ − 10 Free Software Foundation; either version 2, or (at your option) any
+ − 11 later version.
+ − 12
+ − 13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 16 for more details.
+ − 17
+ − 18 You should have received a copy of the GNU General Public License
+ − 19 along with XEmacs; see the file COPYING. If not, write to
+ − 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 21 Boston, MA 02111-1307, USA. */
+ − 22
+ − 23 /* Synched up with: Not in FSF. */
+ − 24
+ − 25 /* #### Note to potential hackers: Don't mess with this unless you're
+ − 26 sure you know what you're doing! Xt is a lot more subtle than
+ − 27 you may think. */
+ − 28
+ − 29 #include <config.h>
+ − 30 #include "lisp.h"
+ − 31
800
+ − 32 #include "device.h"
+ − 33 #include "faces.h"
+ − 34 #include "frame.h"
+ − 35 #include "toolbar.h"
+ − 36 #include "window.h"
+ − 37
428
+ − 38 #include "console-x.h"
+ − 39 #include "glyphs-x.h"
+ − 40 #include "objects-x.h"
800
+ − 41
428
+ − 42 #include <X11/Shell.h>
+ − 43 #include "EmacsFrameP.h"
+ − 44 #include "EmacsManager.h" /* for EmacsManagerChangeSize */
+ − 45 #include "xmu.h"
+ − 46
+ − 47 static void EmacsFrameClassInitialize (void);
+ − 48 static void EmacsFrameInitialize (Widget, Widget, ArgList, Cardinal *);
+ − 49 static void EmacsFrameRealize (Widget, XtValueMask*, XSetWindowAttributes*);
+ − 50 static void EmacsFrameResize (Widget widget);
+ − 51 static Boolean EmacsFrameSetValues (Widget, Widget, Widget,
+ − 52 ArgList, Cardinal *);
+ − 53 static XtGeometryResult EmacsFrameQueryGeometry (Widget, XtWidgetGeometry*,
+ − 54 XtWidgetGeometry*);
+ − 55
+ − 56 extern void
+ − 57 emacs_Xt_mapping_action (Widget w, XEvent* event);
+ − 58
+ − 59 #undef XtOffset
+ − 60 #define XtOffset(p_type,field) \
+ − 61 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
440
+ − 62 #define offset(field) XtOffset (EmacsFrame, emacs_frame.field)
428
+ − 63
+ − 64 static XtResource resources[] = {
440
+ − 65 { XtNgeometry, XtCGeometry,
+ − 66 XtRString, sizeof (String),
+ − 67 offset (geometry), XtRString, (XtPointer) 0 },
+ − 68 { XtNiconic, XtCIconic,
+ − 69 XtRBoolean, sizeof (Boolean),
+ − 70 offset (iconic), XtRImmediate, (XtPointer) False },
428
+ − 71
440
+ − 72 { XtNemacsFrame, XtCEmacsFrame,
+ − 73 XtRPointer, sizeof (XtPointer),
+ − 74 offset (frame), XtRImmediate, 0 },
+ − 75 { XtNmenubar, XtCMenubar,
+ − 76 XtRBoolean, sizeof (Boolean),
+ − 77 offset (menubar_p), XtRImmediate, (XtPointer) True },
+ − 78 { XtNinitiallyUnmapped, XtCInitiallyUnmapped,
+ − 79 XtRBoolean, sizeof (Boolean),
+ − 80 offset (initially_unmapped), XtRImmediate, (XtPointer) False },
+ − 81 { XtNminibuffer, XtCMinibuffer,
+ − 82 XtRBoolean, sizeof (Boolean),
+ − 83 offset (minibuffer), XtRImmediate, (XtPointer) True },
+ − 84 { XtNunsplittable, XtCUnsplittable,
+ − 85 XtRBoolean, sizeof (Boolean),
+ − 86 offset (unsplittable), XtRImmediate, (XtPointer) False },
+ − 87 { XtNinternalBorderWidth, XtCInternalBorderWidth,
+ − 88 XtRInt, sizeof (int),
+ − 89 offset (internal_border_width), XtRImmediate, (XtPointer)4 },
428
+ − 90 #ifdef HAVE_SCROLLBARS
440
+ − 91 { XtNscrollBarWidth, XtCScrollBarWidth,
+ − 92 XtRInt, sizeof (int),
+ − 93 offset (scrollbar_width), XtRImmediate, (XtPointer)-1 },
+ − 94 { XtNscrollBarHeight, XtCScrollBarHeight,
+ − 95 XtRInt, sizeof (int),
+ − 96 offset (scrollbar_height), XtRImmediate, (XtPointer)-1 },
+ − 97 { XtNscrollBarPlacement, XtCScrollBarPlacement,
+ − 98 XtRScrollBarPlacement, sizeof (unsigned char),
+ − 99 offset (scrollbar_placement), XtRImmediate,
428
+ − 100 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
+ − 101 defined (LWLIB_SCROLLBARS_ATHENA3D)
440
+ − 102 (XtPointer) XtBOTTOM_RIGHT
428
+ − 103 #else
440
+ − 104 (XtPointer) XtBOTTOM_LEFT
428
+ − 105 #endif
+ − 106 },
+ − 107 #endif /* HAVE_SCROLLBARS */
440
+ − 108
428
+ − 109 #ifdef HAVE_TOOLBARS
440
+ − 110 { XtNtopToolBarHeight, XtCTopToolBarHeight,
+ − 111 XtRInt, sizeof (int),
+ − 112 offset (top_toolbar_height), XtRImmediate, (XtPointer)-1 },
+ − 113 { XtNbottomToolBarHeight, XtCBottomToolBarHeight,
+ − 114 XtRInt, sizeof (int),
+ − 115 offset (bottom_toolbar_height), XtRImmediate, (XtPointer)-1 },
+ − 116 { XtNleftToolBarWidth, XtCLeftToolBarWidth,
+ − 117 XtRInt, sizeof (int),
+ − 118 offset (left_toolbar_width), XtRImmediate, (XtPointer)-1 },
+ − 119 { XtNrightToolBarWidth, XtCRightToolBarWidth,
+ − 120 XtRInt, sizeof (int),
+ − 121 offset (right_toolbar_width), XtRImmediate, (XtPointer)-1 },
+ − 122 { XtNtopToolBarBorderWidth, XtCTopToolBarBorderWidth,
+ − 123 XtRInt, sizeof (int),
+ − 124 offset (top_toolbar_border_width), XtRImmediate, (XtPointer)-1 },
+ − 125 { XtNbottomToolBarBorderWidth, XtCBottomToolBarBorderWidth,
+ − 126 XtRInt, sizeof (int),
+ − 127 offset (bottom_toolbar_border_width), XtRImmediate, (XtPointer)-1 },
+ − 128 { XtNleftToolBarBorderWidth, XtCLeftToolBarBorderWidth,
+ − 129 XtRInt, sizeof (int),
+ − 130 offset (left_toolbar_border_width), XtRImmediate, (XtPointer)-1 },
+ − 131 { XtNrightToolBarBorderWidth, XtCRightToolBarBorderWidth,
+ − 132 XtRInt, sizeof (int),
+ − 133 offset (right_toolbar_border_width), XtRImmediate, (XtPointer)-1 },
+ − 134 { XtNtopToolBarShadowColor, XtCTopToolBarShadowColor,
+ − 135 XtRPixel, sizeof (Pixel),
+ − 136 offset(top_toolbar_shadow_pixel), XtRString, (XtPointer) "#000000" },
+ − 137 { XtNbottomToolBarShadowColor, XtCBottomToolBarShadowColor,
+ − 138 XtRPixel, sizeof (Pixel),
+ − 139 offset (bottom_toolbar_shadow_pixel), XtRString, (XtPointer) "#000000" },
+ − 140 { XtNbackgroundToolBarColor, XtCBackgroundToolBarColor,
+ − 141 XtRPixel, sizeof (Pixel),
+ − 142 offset (background_toolbar_pixel), XtRImmediate, (XtPointer)-1 },
+ − 143 { XtNforegroundToolBarColor, XtCForegroundToolBarColor,
+ − 144 XtRPixel, sizeof (Pixel),
+ − 145 offset (foreground_toolbar_pixel), XtRImmediate, (XtPointer)-1 },
+ − 146 { XtNtopToolBarShadowPixmap, XtCTopToolBarShadowPixmap,
+ − 147 XtRPixmap, sizeof (Pixmap),
+ − 148 offset (top_toolbar_shadow_pixmap), XtRImmediate, (XtPointer)None },
+ − 149 { XtNbottomToolBarShadowPixmap, XtCBottomToolBarShadowPixmap,
+ − 150 XtRPixmap, sizeof (Pixmap),
+ − 151 offset (bottom_toolbar_shadow_pixmap), XtRImmediate, (XtPointer)None },
+ − 152 { XtNtoolBarShadowThickness, XtCToolBarShadowThickness,
+ − 153 XtRDimension, sizeof (Dimension),
+ − 154 offset (toolbar_shadow_thickness), XtRImmediate, (XtPointer)2 },
428
+ − 155 #endif /* HAVE_TOOLBARS */
440
+ − 156
+ − 157 { XtNinterline, XtCInterline,
+ − 158 XtRInt, sizeof (int),
+ − 159 offset (interline), XtRImmediate, (XtPointer)0 },
428
+ − 160 {
440
+ − 161 XtNfont, XtCFont,
+ − 162 XtRFontStruct, sizeof (XFontStruct *),
428
+ − 163 offset(font), XtRImmediate, (XtPointer)0
+ − 164 },
440
+ − 165 { XtNforeground, XtCForeground,
+ − 166 XtRPixel, sizeof (Pixel),
+ − 167 offset(foreground_pixel), XtRString, (XtPointer) "Black" },
+ − 168 { XtNbackground, XtCBackground,
+ − 169 XtRPixel, sizeof (Pixel),
+ − 170 offset(background_pixel), XtRString, (XtPointer) "Gray80" },
+ − 171 { XtNcursorColor, XtCForeground,
+ − 172 XtRPixel, sizeof (Pixel),
+ − 173 offset(cursor_color), XtRString, (XtPointer) "XtDefaultForeground" },
+ − 174 { XtNbarCursor, XtCBarCursor,
+ − 175 XtRBoolean, sizeof (Boolean),
+ − 176 offset (bar_cursor), XtRImmediate, (XtPointer)0 },
+ − 177 { XtNvisualBell, XtCVisualBell,
+ − 178 XtRBoolean, sizeof (Boolean),
+ − 179 offset (visual_bell), XtRImmediate, (XtPointer)0 },
+ − 180 { XtNbellVolume, XtCBellVolume,
+ − 181 XtRInt, sizeof (int),
+ − 182 offset (bell_volume), XtRImmediate, (XtPointer)0 },
+ − 183 { XtNuseBackingStore, XtCUseBackingStore,
+ − 184 XtRBoolean, sizeof (Boolean),
+ − 185 offset (use_backing_store), XtRImmediate, (XtPointer)0 },
+ − 186 { XtNpreferredWidth, XtCPreferredWidth,
+ − 187 XtRDimension, sizeof (Dimension),
+ − 188 offset (preferred_width), XtRImmediate, (XtPointer)0 },
+ − 189 { XtNpreferredHeight, XtCPreferredHeight,
+ − 190 XtRDimension, sizeof (Dimension),
+ − 191 offset (preferred_height), XtRImmediate, (XtPointer)0 },
428
+ − 192 };
+ − 193
+ − 194 #undef offset
+ − 195
+ − 196 /* Xt is stupid and dumb.
+ − 197 Xt is stupid and dumb.
+ − 198 Xt is stupid and dumb. */
+ − 199
+ − 200 static XtActionsRec
+ − 201 emacsFrameActionsTable [] = {
+ − 202 {"mapping", (XtActionProc) emacs_Xt_mapping_action},
+ − 203 };
+ − 204
+ − 205 static char
+ − 206 emacsFrameTranslations [] = "\
+ − 207 <Mapping>: mapping()\n\
+ − 208 ";
+ − 209
+ − 210 /* If we're running under Motif, make this widget a subclass
+ − 211 of XmPrimitive. It's not clear this is necessary, but it
+ − 212 may make focus behavior work better. */
+ − 213
+ − 214 EmacsFrameClassRec emacsFrameClassRec = {
+ − 215 { /* core fields */
+ − 216 #ifdef LWLIB_USES_MOTIF
+ − 217 /* superclass */ (WidgetClass) &xmPrimitiveClassRec,
+ − 218 #else
+ − 219 /* superclass */ &widgetClassRec,
+ − 220 #endif
+ − 221 /* class_name */ "EmacsFrame",
440
+ − 222 /* widget_size */ sizeof (EmacsFrameRec),
428
+ − 223 /* class_initialize */ EmacsFrameClassInitialize,
+ − 224 /* class_part_initialize */ 0,
+ − 225 /* class_inited */ FALSE,
+ − 226 /* initialize */ EmacsFrameInitialize,
+ − 227 /* initialize_hook */ 0,
+ − 228 /* realize */ EmacsFrameRealize,
+ − 229 /* actions */ emacsFrameActionsTable,
+ − 230 /* num_actions */ XtNumber (emacsFrameActionsTable),
+ − 231 /* resources */ resources,
440
+ − 232 /* resource_count */ XtNumber (resources),
428
+ − 233 /* xrm_class */ NULLQUARK,
+ − 234 /* compress_motion */ TRUE,
+ − 235 /* compress_exposure */ TRUE,
+ − 236 /* compress_enterleave */ TRUE,
+ − 237 /* visible_interest */ FALSE,
+ − 238 /* destroy */ NULL,
+ − 239 /* resize */ EmacsFrameResize,
+ − 240 /* expose */ XtInheritExpose,
+ − 241 /* set_values */ EmacsFrameSetValues,
+ − 242 /* set_values_hook */ 0,
+ − 243 /* set_values_almost */ XtInheritSetValuesAlmost,
+ − 244 /* get_values_hook */ 0,
+ − 245 /* accept_focus */ XtInheritAcceptFocus,
+ − 246 /* version */ XtVersion,
+ − 247 /* callback_private */ 0,
+ − 248 /* tm_table */ emacsFrameTranslations,
+ − 249 /* query_geometry */ EmacsFrameQueryGeometry,
+ − 250 /* display_accelerator */ XtInheritDisplayAccelerator,
+ − 251 /* extension */ 0
+ − 252 },
+ − 253 #ifdef LWLIB_USES_MOTIF
+ − 254 { /* XmPrimitiveClassPart
+ − 255 */
+ − 256 (XtWidgetProc) _XtInherit, /* border_highlight */
+ − 257 (XtWidgetProc) _XtInherit, /* border_unhighlight */
+ − 258 /* Setting the following to NULL causes PrimitiveInitialize()
+ − 259 not to add traversal (TAB etc. to switch focus) and
+ − 260 focus-in/out (border highlight/unhighlight) translations.
+ − 261 If you want those translations, use the value XtInheritTranslations
+ − 262 instead. Doing this, however, will interfere with Emacs
+ − 263 focus handling (which highlights/unhighlights the text cursor),
+ − 264 and will lead to strange display results around the border of the
+ − 265 widget. */
+ − 266 NULL, /* translations */
+ − 267 NULL, /* arm_and_activate */
+ − 268 NULL, /* get resources */
+ − 269 0, /* num get_resources */
+ − 270 NULL, /* extension */
+ − 271 },
+ − 272 #endif /* LWLIB_USES_MOTIF */
+ − 273 {
+ − 274 0
+ − 275 }
+ − 276 };
+ − 277 WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
+ − 278
+ − 279 static void
+ − 280 update_various_frame_slots (EmacsFrame ew)
+ − 281 {
+ − 282 ew->emacs_frame.frame->pixheight = ew->core.height;
+ − 283 ew->emacs_frame.frame->pixwidth = ew->core.width;
+ − 284 }
+ − 285
+ − 286 static void
+ − 287 EmacsFrameInitialize (Widget request, Widget new,
+ − 288 ArgList dum1, Cardinal *dum2)
+ − 289 {
+ − 290 EmacsFrame ew = (EmacsFrame)new;
+ − 291 struct frame *f = ew->emacs_frame.frame;
+ − 292
+ − 293 if (!f)
+ − 294 fatal ("can't create an emacs frame widget without a frame.");
+ − 295
+ − 296 ew->emacs_frame.frame->internal_border_width =
+ − 297 ew->emacs_frame.internal_border_width;
+ − 298 }
+ − 299
+ − 300 void emacs_Xt_event_handler (Widget wid /* unused */,
+ − 301 XtPointer closure /* unused */,
+ − 302 XEvent *event,
+ − 303 Boolean *continue_to_dispatch /* unused */);
+ − 304
+ − 305 static void
+ − 306 EmacsFrameRealize (Widget widget, XtValueMask *mask,
+ − 307 XSetWindowAttributes *attrs)
+ − 308 {
+ − 309 EmacsFrame ew = (EmacsFrame) widget;
+ − 310 struct frame *f = ew->emacs_frame.frame;
+ − 311 Widget shell_widget = FRAME_X_SHELL_WIDGET (f);
+ − 312
+ − 313 attrs->event_mask =
+ − 314 ExposureMask |
+ − 315 VisibilityChangeMask |
+ − 316 PropertyChangeMask |
+ − 317 StructureNotifyMask |
+ − 318 SubstructureNotifyMask |
+ − 319 /*SubstructureRedirectMask |*/ /* Only for WMs! */
+ − 320 KeyPressMask |
+ − 321 KeyReleaseMask |
+ − 322 ButtonPressMask |
+ − 323 ButtonReleaseMask |
+ − 324 FocusChangeMask |
+ − 325 PointerMotionHintMask |
+ − 326 PointerMotionMask |
+ − 327 LeaveWindowMask |
+ − 328 EnterWindowMask;
+ − 329
+ − 330
+ − 331 *mask |= CWEventMask;
+ − 332
+ − 333 if (ew->emacs_frame.use_backing_store)
+ − 334 {
+ − 335 attrs->backing_store = Always;
+ − 336 *mask |= CWBackingStore;
+ − 337 }
+ − 338 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
+ − 339 attrs);
+ − 340
+ − 341 /* snarf the events we want. */
+ − 342 XtInsertEventHandler (widget, attrs->event_mask, TRUE,
+ − 343 emacs_Xt_event_handler, NULL, XtListHead);
+ − 344 /* some events (e.g. map-notify and WM_DELETE_WINDOW) get sent
+ − 345 directly to the shell, and the above event handler won't see
+ − 346 them. So add a handler to get them. These events don't
+ − 347 propagate, so there's no danger of them being seen twice. */
+ − 348 XtInsertEventHandler (shell_widget,
+ − 349 EnterWindowMask | LeaveWindowMask |
+ − 350 VisibilityChangeMask | StructureNotifyMask |
+ − 351 KeyPressMask,
+ − 352 TRUE, emacs_Xt_event_handler, NULL, XtListHead);
+ − 353
+ − 354 #ifdef EXTERNAL_WIDGET
+ − 355 /* #### Not sure if this special case is necessary */
+ − 356 if (!FRAME_X_EXTERNAL_WINDOW_P (f))
+ − 357 #endif
+ − 358 /* This is necessary under Motif in order to make it possible to click in
+ − 359 a buffer and move focus out of a dialog box or control panel and back
+ − 360 into emacs-land; also necessary so that you can still type chars
+ − 361 if the cursor is over the menubar or scrollbar. */
+ − 362 lw_set_keyboard_focus (shell_widget, FRAME_X_TEXT_WIDGET (f));
+ − 363 }
+ − 364
+ − 365 /* DO NOT CALL THIS FUNCTION! Only Xt is supposed to do this. */
+ − 366
+ − 367 static void
+ − 368 EmacsFrameResize (Widget widget)
+ − 369 {
+ − 370 EmacsFrame ew = (EmacsFrame)widget;
+ − 371 struct frame *f = ew->emacs_frame.frame;
+ − 372 int columns;
+ − 373 int rows;
+ − 374 XtWidgetGeometry req, repl;
+ − 375
+ − 376 update_various_frame_slots (ew);
+ − 377
+ − 378 pixel_to_char_size (f, ew->core.width, ew->core.height, &columns, &rows);
+ − 379 change_frame_size (f, rows, columns, 0);
+ − 380
+ − 381 /* Now we tell the EmacsShell that we've changed the size of the non-fixed
+ − 382 portion of the frame. Note that, if we the resize occurred as a result
+ − 383 of EmacsFrameSetCharSize(), this information will be stored twice.
+ − 384 This is not a big deal, as storing this information doesn't actually
+ − 385 do anything until the next resize. */
+ − 386 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
+ − 387 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
+ − 388
+ − 389 /* Kick the manager so that it knows we've changed size. */
+ − 390 req.request_mode = 0;
+ − 391 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
+ − 392 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
+ − 393 repl.height);
+ − 394 }
+ − 395
+ − 396 static Boolean
+ − 397 EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget,
+ − 398 ArgList argv, Cardinal *argc)
+ − 399 {
+ − 400 EmacsFrame cur = (EmacsFrame) cur_widget;
+ − 401 EmacsFrame new = (EmacsFrame) new_widget;
+ − 402 struct frame *f = new->emacs_frame.frame;
793
+ − 403 Lisp_Object frame = wrap_frame (f);
428
+ − 404 in_resource_setting++;
+ − 405 /* This function does not need to do much. Pretty much everything
+ − 406 interesting will get done in the resize method, which will
+ − 407 (if necessary) get called by Xt when this function returns
+ − 408 (see below).
+ − 409 */
+ − 410
+ − 411 /* #### This function will not work if it is not called from
+ − 412 update_EmacsFrame(), called from SET_FACE_PROPERTY().
+ − 413 The code located there should be moved inside of here instead,
+ − 414 so that things work if either SET_FACE_PROPERTY() is
+ − 415 called or XtSetValues() is called.
+ − 416 */
+ − 417
+ − 418 if (cur->emacs_frame.iconic != new->emacs_frame.iconic &&
+ − 419 FRAME_X_TOP_LEVEL_FRAME_P (new->emacs_frame.frame))
+ − 420 x_wm_set_shell_iconic_p (FRAME_X_SHELL_WIDGET (new->emacs_frame.frame),
+ − 421 new->emacs_frame.iconic);
+ − 422
+ − 423 /* If we got here, then we were likely called as a result of
+ − 424 the EditRes protocol, so go ahead and change scrollbar-width
+ − 425 and scrollbar-height. Otherwise, we're merely mirroring
+ − 426 a change made to scrollbar-width etc. so don't do anything
+ − 427 special. */
+ − 428 if (cur->emacs_frame.internal_border_width !=
+ − 429 new->emacs_frame.internal_border_width)
+ − 430 {
+ − 431 f->internal_border_width = new->emacs_frame.internal_border_width;
+ − 432 MARK_FRAME_SIZE_SLIPPED (f);
+ − 433 }
+ − 434
+ − 435 #ifdef HAVE_SCROLLBARS
+ − 436 if (cur->emacs_frame.scrollbar_width !=
+ − 437 new->emacs_frame.scrollbar_width)
+ − 438 Fadd_spec_to_specifier
+ − 439 (Vscrollbar_width,
+ − 440 make_int (new->emacs_frame.scrollbar_width),
+ − 441 frame, Qnil, Qnil);
+ − 442 if (cur->emacs_frame.scrollbar_height !=
+ − 443 new->emacs_frame.scrollbar_height)
+ − 444 Fadd_spec_to_specifier
+ − 445 (Vscrollbar_height,
+ − 446 make_int (new->emacs_frame.scrollbar_height),
+ − 447 frame, Qnil, Qnil);
+ − 448 #endif /* HAVE_SCROLLBARS */
+ − 449 #ifdef HAVE_TOOLBARS
+ − 450 if (cur->emacs_frame.top_toolbar_height !=
+ − 451 new->emacs_frame.top_toolbar_height)
+ − 452 Fadd_spec_to_specifier
+ − 453 (Vtoolbar_size[TOP_TOOLBAR],
+ − 454 make_int (new->emacs_frame.top_toolbar_height),
+ − 455 frame, Qnil, Qnil);
+ − 456 if (cur->emacs_frame.bottom_toolbar_height !=
+ − 457 new->emacs_frame.bottom_toolbar_height)
+ − 458 Fadd_spec_to_specifier
+ − 459 (Vtoolbar_size[BOTTOM_TOOLBAR],
+ − 460 make_int (new->emacs_frame.bottom_toolbar_height),
+ − 461 frame, Qnil, Qnil);
+ − 462 if (cur->emacs_frame.left_toolbar_width !=
+ − 463 new->emacs_frame.left_toolbar_width)
+ − 464 Fadd_spec_to_specifier
+ − 465 (Vtoolbar_size[LEFT_TOOLBAR],
+ − 466 make_int (new->emacs_frame.left_toolbar_width),
+ − 467 frame, Qnil, Qnil);
+ − 468 if (cur->emacs_frame.right_toolbar_width !=
+ − 469 new->emacs_frame.right_toolbar_width)
+ − 470 Fadd_spec_to_specifier
+ − 471 (Vtoolbar_size[RIGHT_TOOLBAR],
+ − 472 make_int (new->emacs_frame.right_toolbar_width),
+ − 473 frame, Qnil, Qnil);
+ − 474 if (cur->emacs_frame.top_toolbar_border_width !=
+ − 475 new->emacs_frame.top_toolbar_border_width)
+ − 476 Fadd_spec_to_specifier
+ − 477 (Vtoolbar_border_width[TOP_TOOLBAR],
+ − 478 make_int (new->emacs_frame.top_toolbar_border_width),
+ − 479 frame, Qnil, Qnil);
+ − 480 if (cur->emacs_frame.bottom_toolbar_border_width !=
+ − 481 new->emacs_frame.bottom_toolbar_border_width)
+ − 482 Fadd_spec_to_specifier
+ − 483 (Vtoolbar_border_width[BOTTOM_TOOLBAR],
+ − 484 make_int (new->emacs_frame.bottom_toolbar_border_width),
+ − 485 frame, Qnil, Qnil);
+ − 486 if (cur->emacs_frame.left_toolbar_border_width !=
+ − 487 new->emacs_frame.left_toolbar_border_width)
+ − 488 Fadd_spec_to_specifier
+ − 489 (Vtoolbar_border_width[LEFT_TOOLBAR],
+ − 490 make_int (new->emacs_frame.left_toolbar_border_width),
+ − 491 frame, Qnil, Qnil);
+ − 492 if (cur->emacs_frame.right_toolbar_border_width !=
+ − 493 new->emacs_frame.right_toolbar_border_width)
+ − 494 Fadd_spec_to_specifier
+ − 495 (Vtoolbar_border_width[RIGHT_TOOLBAR],
+ − 496 make_int (new->emacs_frame.right_toolbar_border_width),
+ − 497 frame, Qnil, Qnil);
+ − 498 #endif /* HAVE_TOOLBARS */
+ − 499
+ − 500 in_resource_setting--;
+ − 501
+ − 502 /* If the request was to resize us, but the size has not changed, Xt
+ − 503 will do nothing, and won't call our resize callback. Since such a
+ − 504 request might be issued as a result of hiding/showing menubar or
+ − 505 changing toolbar placement, where we rely on relayout made by the
+ − 506 callback, we go ahead and simulate such a call */
+ − 507 if (cur->core.width == new->core.width
+ − 508 && cur->core.height == new->core.height)
+ − 509 {
+ − 510 int i;
647
+ − 511 for (i = 0; i < (int) *argc; i++)
428
+ − 512 if (strcmp (argv[i].name, XtNwidth) == 0
+ − 513 || strcmp (argv[i].name, XtNheight) == 0)
+ − 514 {
+ − 515 EmacsFrameResize (new_widget);
+ − 516 break;
+ − 517 }
+ − 518 }
+ − 519
+ − 520 return False;
+ − 521
+ − 522 /* Note that if either (a) we return True, or (b) the width or
+ − 523 height has changed, an Expose event will be generated. The Xt
+ − 524 manual says you should not return True if the width or height has
+ − 525 changed, because then two Expose events will be generated.
+ − 526
+ − 527 In any case, there is no need to return True because
+ − 528 SET_FACE_PROPERTY(), which does the resource
+ − 529 setting, automatically forces a redisplay as necessary. */
+ − 530 }
+ − 531
+ − 532 static XtGeometryResult
+ − 533 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
+ − 534 XtWidgetGeometry *result)
+ − 535 {
+ − 536 EmacsFrame ew = (EmacsFrame) widget;
+ − 537 int mask = request->request_mode;
+ − 538 Dimension width, height;
+ − 539 int ok_width_int, ok_height_int;
+ − 540 Dimension ok_width, ok_height;
+ − 541
+ − 542 /* We have a definite preference for what size we would like
+ − 543 to be.
+ − 544
+ − 545 1) If a preferred size was specified for us, use it.
+ − 546 (This is not currently used)
+ − 547 2) If a proposed size was given, round it to the nearest
+ − 548 multiple of the default char size and return it.
+ − 549 3) Otherwise, take our current size and round it to the
+ − 550 nearest multiple of the default char size. */
+ − 551
+ − 552 width = mask & CWWidth ? request->width : ew->core.width;
+ − 553 height = mask & CWHeight ? request->height : ew->core.height;
+ − 554 round_size_to_char (ew->emacs_frame.frame, width, height,
+ − 555 &ok_width_int, &ok_height_int);
+ − 556 ok_width = (Dimension) ok_width_int;
+ − 557 ok_height = (Dimension) ok_height_int;
+ − 558 if (ew->emacs_frame.preferred_width)
+ − 559 ok_width = ew->emacs_frame.preferred_width;
+ − 560 if (ew->emacs_frame.preferred_height)
+ − 561 ok_height = ew->emacs_frame.preferred_height;
+ − 562 result->request_mode |= CWWidth | CWHeight;
+ − 563 result->width = ok_width;
+ − 564 result->height = ok_height;
+ − 565 if (((mask & CWWidth) && ok_width != request->width)
+ − 566 || ((mask & CWHeight) && ok_height != request->height))
+ − 567 return XtGeometryAlmost;
+ − 568 else
+ − 569 return XtGeometryYes;
+ − 570 }
+ − 571
+ − 572 /* Xt string-to-scrollbar-placement converter */
440
+ − 573 /* #### Convert this to a `new-style' converter (See XtAddTypeConverter) */
428
+ − 574
+ − 575 /* This variable cannot be a stack variable. */
+ − 576 static unsigned char cvt_string_scrollbar_placement;
+ − 577
+ − 578 /* ARGSUSED */
+ − 579 static void
+ − 580 Xt_StringToScrollBarPlacement (XrmValuePtr args, /* unused */
+ − 581 Cardinal *num_args, /* unused */
+ − 582 XrmValuePtr fromVal,
+ − 583 XrmValuePtr toVal)
+ − 584 {
+ − 585 XrmQuark q;
851
+ − 586 char *lowerName = (char *) ALLOCA (strlen ((char *) fromVal->addr) + 1);
428
+ − 587
+ − 588 XmuCopyISOLatin1Lowered (lowerName, (char *) fromVal->addr);
+ − 589 q = XrmStringToQuark (lowerName);
+ − 590
+ − 591 toVal->size = sizeof (cvt_string_scrollbar_placement);
+ − 592 toVal->addr = (XPointer) &cvt_string_scrollbar_placement;
+ − 593
+ − 594 if (q == XrmStringToQuark ("top-left")
+ − 595 || q == XrmStringToQuark ("top_left"))
+ − 596 cvt_string_scrollbar_placement = XtTOP_LEFT;
+ − 597 else if (q == XrmStringToQuark ("bottom-left")
+ − 598 || q == XrmStringToQuark ("bottom_left"))
+ − 599 cvt_string_scrollbar_placement = XtBOTTOM_LEFT;
+ − 600 else if (q == XrmStringToQuark ("top-right")
+ − 601 || q == XrmStringToQuark ("top_right"))
+ − 602 cvt_string_scrollbar_placement = XtTOP_RIGHT;
+ − 603 else if (q == XrmStringToQuark ("bottom-right")
+ − 604 || q == XrmStringToQuark ("bottom_right"))
+ − 605 cvt_string_scrollbar_placement = XtBOTTOM_RIGHT;
+ − 606 else
+ − 607 {
+ − 608 XtStringConversionWarning (fromVal->addr, "scrollBarPlacement");
+ − 609 toVal->addr = NULL;
+ − 610 toVal->size = 0;
+ − 611 }
+ − 612 }
+ − 613
+ − 614 static void
+ − 615 EmacsFrameClassInitialize (void)
+ − 616 {
+ − 617 XtAddConverter (XtRString, XtRScrollBarPlacement,
+ − 618 Xt_StringToScrollBarPlacement, NULL, 0);
+ − 619 }
+ − 620
+ − 621 /********************* Special entrypoints *******************/
+ − 622
+ − 623 void
+ − 624 EmacsFrameRecomputeCellSize (Widget w)
+ − 625 {
+ − 626 EmacsFrame ew = (EmacsFrame) w;
+ − 627 int cw, ch;
+ − 628 struct frame *f = ew->emacs_frame.frame;
+ − 629
+ − 630 if (! XtIsSubclass (w, emacsFrameClass))
+ − 631 abort ();
+ − 632
771
+ − 633 default_face_height_and_width (wrap_frame (f), &ch, &cw);
428
+ − 634 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
+ − 635 x_wm_set_cell_size (FRAME_X_SHELL_WIDGET (f), cw, ch);
+ − 636 }
+ − 637
+ − 638 /* Set the size of the widget to have the number of rows and columns
+ − 639 specified. This both causes the X window to change and the
+ − 640 internal frame structures to get modified to match. */
+ − 641
+ − 642 void
+ − 643 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
+ − 644 {
+ − 645 EmacsFrame ew = (EmacsFrame) widget;
+ − 646 int pixel_width, pixel_height;
+ − 647 struct frame *f = ew->emacs_frame.frame;
+ − 648
+ − 649 if (columns < 3)
+ − 650 columns = 3; /* no way buddy */
+ − 651 if (rows < 1)
+ − 652 rows = 1;
+ − 653
+ − 654 char_to_pixel_size (f, columns, rows, &pixel_width, &pixel_height);
+ − 655
+ − 656 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
+ − 657 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
+ − 658
+ − 659 {
+ − 660 Arg al [2];
+ − 661 XtSetArg (al [0], XtNwidth, pixel_width);
+ − 662 XtSetArg (al [1], XtNheight, pixel_height);
+ − 663 XtSetValues ((Widget) ew, al, countof (al));
+ − 664 }
+ − 665 }