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