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.
6 This file is part of XEmacs.
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
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
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. */
23 /* Synched up with: Not in FSF. */
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
32 #include "console-x.h"
34 #include "objects-x.h"
35 #include <X11/Shell.h>
36 #include "EmacsFrameP.h"
37 #include "EmacsManager.h" /* for EmacsManagerChangeSize */
43 #include "redisplay.h"
46 static void EmacsFrameClassInitialize (void);
47 static void EmacsFrameInitialize (Widget, Widget, ArgList, Cardinal *);
48 static void EmacsFrameRealize (Widget, XtValueMask*, XSetWindowAttributes*);
49 static void EmacsFrameResize (Widget widget);
50 static Boolean EmacsFrameSetValues (Widget, Widget, Widget,
52 static XtGeometryResult EmacsFrameQueryGeometry (Widget, XtWidgetGeometry*,
56 emacs_Xt_mapping_action (Widget w, XEvent* event);
59 #define XtOffset(p_type,field) \
60 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
61 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
63 static XtResource resources[] = {
64 {XtNgeometry, XtCGeometry, XtRString, sizeof(String),
65 offset (geometry), XtRString, (XtPointer) 0},
66 {XtNiconic, XtCIconic, XtRBoolean, sizeof(Boolean),
67 offset (iconic), XtRImmediate, (XtPointer) False},
69 {XtNemacsFrame, XtCEmacsFrame, XtRPointer, sizeof (XtPointer),
70 offset (frame), XtRImmediate, 0},
71 {XtNmenubar, XtCMenubar, XtRBoolean, sizeof (Boolean),
72 offset (menubar_p), XtRImmediate, (XtPointer) True},
73 {XtNinitiallyUnmapped, XtCInitiallyUnmapped, XtRBoolean, sizeof (Boolean),
74 offset (initially_unmapped), XtRImmediate, (XtPointer) False},
75 {XtNminibuffer, XtCMinibuffer, XtRBoolean, sizeof (Boolean),
76 offset (minibuffer), XtRImmediate, (XtPointer) True},
77 {XtNunsplittable, XtCUnsplittable, XtRBoolean, sizeof (Boolean),
78 offset (unsplittable), XtRImmediate, (XtPointer) False},
79 {XtNinternalBorderWidth, XtCInternalBorderWidth, XtRInt, sizeof (int),
80 offset (internal_border_width), XtRImmediate, (XtPointer)4},
81 #ifdef HAVE_SCROLLBARS
82 {XtNscrollBarWidth, XtCScrollBarWidth, XtRInt, sizeof (int),
83 offset (scrollbar_width), XtRImmediate, (XtPointer)-1},
84 {XtNscrollBarHeight, XtCScrollBarHeight, XtRInt, sizeof (int),
85 offset (scrollbar_height), XtRImmediate, (XtPointer)-1},
86 {XtNscrollBarPlacement, XtCScrollBarPlacement, XtRScrollBarPlacement,
87 sizeof(unsigned char), offset(scrollbar_placement), XtRImmediate,
88 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
89 defined (LWLIB_SCROLLBARS_ATHENA3D)
90 (XtPointer) XtBOTTOM_RIGHT
92 (XtPointer) XtBOTTOM_LEFT
95 #endif /* HAVE_SCROLLBARS */
97 {XtNtopToolBarHeight, XtCTopToolBarHeight, XtRInt, sizeof (int),
98 offset (top_toolbar_height), XtRImmediate, (XtPointer)-1},
99 {XtNbottomToolBarHeight, XtCBottomToolBarHeight, XtRInt, sizeof (int),
100 offset (bottom_toolbar_height), XtRImmediate, (XtPointer)-1},
101 {XtNleftToolBarWidth, XtCLeftToolBarWidth, XtRInt, sizeof (int),
102 offset (left_toolbar_width), XtRImmediate, (XtPointer)-1},
103 {XtNrightToolBarWidth, XtCRightToolBarWidth, XtRInt, sizeof (int),
104 offset (right_toolbar_width), XtRImmediate, (XtPointer)-1},
105 {XtNtopToolBarBorderWidth, XtCTopToolBarBorderWidth, XtRInt,
107 offset (top_toolbar_border_width), XtRImmediate, (XtPointer)-1},
108 {XtNbottomToolBarBorderWidth, XtCBottomToolBarBorderWidth, XtRInt,
110 offset (bottom_toolbar_border_width), XtRImmediate, (XtPointer)-1},
111 {XtNleftToolBarBorderWidth, XtCLeftToolBarBorderWidth, XtRInt,
113 offset (left_toolbar_border_width), XtRImmediate, (XtPointer)-1},
114 {XtNrightToolBarBorderWidth, XtCRightToolBarBorderWidth, XtRInt,
116 offset (right_toolbar_border_width), XtRImmediate, (XtPointer)-1},
117 {XtNtopToolBarShadowColor, XtCTopToolBarShadowColor, XtRPixel, sizeof(Pixel),
118 offset(top_toolbar_shadow_pixel), XtRString, "#000000"},
119 {XtNbottomToolBarShadowColor, XtCBottomToolBarShadowColor, XtRPixel,
120 sizeof(Pixel), offset(bottom_toolbar_shadow_pixel), XtRString, "#000000"},
121 {XtNbackgroundToolBarColor, XtCBackgroundToolBarColor, XtRPixel,
122 sizeof(Pixel), offset(background_toolbar_pixel), XtRImmediate,
124 {XtNforegroundToolBarColor, XtCForegroundToolBarColor, XtRPixel,
125 sizeof(Pixel), offset(foreground_toolbar_pixel), XtRImmediate,
127 {XtNtopToolBarShadowPixmap, XtCTopToolBarShadowPixmap, XtRPixmap,
128 sizeof (Pixmap), offset(top_toolbar_shadow_pixmap), XtRImmediate,
130 {XtNbottomToolBarShadowPixmap, XtCBottomToolBarShadowPixmap, XtRPixmap,
131 sizeof (Pixmap), offset(bottom_toolbar_shadow_pixmap), XtRImmediate,
133 {XtNtoolBarShadowThickness, XtCToolBarShadowThickness, XtRDimension,
134 sizeof (Dimension), offset (toolbar_shadow_thickness), XtRImmediate,
136 #endif /* HAVE_TOOLBARS */
137 {XtNinterline, XtCInterline, XtRInt, sizeof (int),
138 offset (interline), XtRImmediate, (XtPointer)0},
141 XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
143 XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
145 offset(font), XtRImmediate, (XtPointer)0
147 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
148 offset(foreground_pixel), XtRString, "Black"},
149 {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
150 offset(background_pixel), XtRString, "Gray80"},
151 {XtNcursorColor, XtCForeground, XtRPixel, sizeof(Pixel),
152 offset(cursor_color), XtRString, "XtDefaultForeground"},
153 {XtNbarCursor, XtCBarCursor, XtRBoolean, sizeof (Boolean),
154 offset (bar_cursor), XtRImmediate, (XtPointer)0},
155 {XtNvisualBell, XtCVisualBell, XtRBoolean, sizeof (Boolean),
156 offset (visual_bell), XtRImmediate, (XtPointer)0},
157 {XtNbellVolume, XtCBellVolume, XtRInt, sizeof (int),
158 offset (bell_volume), XtRImmediate, (XtPointer)0},
159 {XtNuseBackingStore, XtCUseBackingStore, XtRBoolean, sizeof (Boolean),
160 offset (use_backing_store), XtRImmediate, (XtPointer)0},
161 {XtNpreferredWidth, XtCPreferredWidth, XtRDimension, sizeof (Dimension),
162 offset (preferred_width), XtRImmediate, (XtPointer)0},
163 {XtNpreferredHeight, XtCPreferredHeight, XtRDimension, sizeof (Dimension),
164 offset (preferred_height), XtRImmediate, (XtPointer)0},
169 /* Xt is stupid and dumb.
170 Xt is stupid and dumb.
171 Xt is stupid and dumb. */
174 emacsFrameActionsTable [] = {
175 {"mapping", (XtActionProc) emacs_Xt_mapping_action},
179 emacsFrameTranslations [] = "\
180 <Mapping>: mapping()\n\
183 /* If we're running under Motif, make this widget a subclass
184 of XmPrimitive. It's not clear this is necessary, but it
185 may make focus behavior work better. */
187 EmacsFrameClassRec emacsFrameClassRec = {
189 #ifdef LWLIB_USES_MOTIF
190 /* superclass */ (WidgetClass) &xmPrimitiveClassRec,
192 /* superclass */ &widgetClassRec,
194 /* class_name */ "EmacsFrame",
195 /* widget_size */ sizeof(EmacsFrameRec),
196 /* class_initialize */ EmacsFrameClassInitialize,
197 /* class_part_initialize */ 0,
198 /* class_inited */ FALSE,
199 /* initialize */ EmacsFrameInitialize,
200 /* initialize_hook */ 0,
201 /* realize */ EmacsFrameRealize,
202 /* actions */ emacsFrameActionsTable,
203 /* num_actions */ XtNumber (emacsFrameActionsTable),
204 /* resources */ resources,
205 /* resource_count */ XtNumber(resources),
206 /* xrm_class */ NULLQUARK,
207 /* compress_motion */ TRUE,
208 /* compress_exposure */ TRUE,
209 /* compress_enterleave */ TRUE,
210 /* visible_interest */ FALSE,
212 /* resize */ EmacsFrameResize,
213 /* expose */ XtInheritExpose,
214 /* set_values */ EmacsFrameSetValues,
215 /* set_values_hook */ 0,
216 /* set_values_almost */ XtInheritSetValuesAlmost,
217 /* get_values_hook */ 0,
218 /* accept_focus */ XtInheritAcceptFocus,
219 /* version */ XtVersion,
220 /* callback_private */ 0,
221 /* tm_table */ emacsFrameTranslations,
222 /* query_geometry */ EmacsFrameQueryGeometry,
223 /* display_accelerator */ XtInheritDisplayAccelerator,
226 #ifdef LWLIB_USES_MOTIF
227 { /* XmPrimitiveClassPart
229 (XtWidgetProc) _XtInherit, /* border_highlight */
230 (XtWidgetProc) _XtInherit, /* border_unhighlight */
231 /* Setting the following to NULL causes PrimitiveInitialize()
232 not to add traversal (TAB etc. to switch focus) and
233 focus-in/out (border highlight/unhighlight) translations.
234 If you want those translations, use the value XtInheritTranslations
235 instead. Doing this, however, will interfere with Emacs
236 focus handling (which highlights/unhighlights the text cursor),
237 and will lead to strange display results around the border of the
239 NULL, /* translations */
240 NULL, /* arm_and_activate */
241 NULL, /* get resources */
242 0, /* num get_resources */
243 NULL, /* extension */
245 #endif /* LWLIB_USES_MOTIF */
250 WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
253 update_various_frame_slots (EmacsFrame ew)
255 ew->emacs_frame.frame->pixheight = ew->core.height;
256 ew->emacs_frame.frame->pixwidth = ew->core.width;
260 EmacsFrameInitialize (Widget request, Widget new,
261 ArgList dum1, Cardinal *dum2)
263 EmacsFrame ew = (EmacsFrame)new;
264 struct frame *f = ew->emacs_frame.frame;
267 fatal ("can't create an emacs frame widget without a frame.");
269 ew->emacs_frame.frame->internal_border_width =
270 ew->emacs_frame.internal_border_width;
273 void emacs_Xt_event_handler (Widget wid /* unused */,
274 XtPointer closure /* unused */,
276 Boolean *continue_to_dispatch /* unused */);
279 EmacsFrameRealize (Widget widget, XtValueMask *mask,
280 XSetWindowAttributes *attrs)
282 EmacsFrame ew = (EmacsFrame) widget;
283 struct frame *f = ew->emacs_frame.frame;
284 Widget shell_widget = FRAME_X_SHELL_WIDGET (f);
288 VisibilityChangeMask |
290 StructureNotifyMask |
291 SubstructureNotifyMask |
292 /*SubstructureRedirectMask |*/ /* Only for WMs! */
298 PointerMotionHintMask |
305 /* Make sure that events wanted by the input method are selected. */
306 attrs->event_mask |= input_method_event_mask;
309 *mask |= CWEventMask;
311 if (ew->emacs_frame.use_backing_store)
313 attrs->backing_store = Always;
314 *mask |= CWBackingStore;
316 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
319 /* snarf the events we want. */
320 XtInsertEventHandler (widget, attrs->event_mask, TRUE,
321 emacs_Xt_event_handler, NULL, XtListHead);
322 /* some events (e.g. map-notify and WM_DELETE_WINDOW) get sent
323 directly to the shell, and the above event handler won't see
324 them. So add a handler to get them. These events don't
325 propagate, so there's no danger of them being seen twice. */
326 XtInsertEventHandler (shell_widget,
327 EnterWindowMask | LeaveWindowMask |
328 VisibilityChangeMask | StructureNotifyMask |
330 TRUE, emacs_Xt_event_handler, NULL, XtListHead);
332 #ifdef EXTERNAL_WIDGET
333 /* #### Not sure if this special case is necessary */
334 if (!FRAME_X_EXTERNAL_WINDOW_P (f))
336 /* This is necessary under Motif in order to make it possible to click in
337 a buffer and move focus out of a dialog box or control panel and back
338 into emacs-land; also necessary so that you can still type chars
339 if the cursor is over the menubar or scrollbar. */
340 lw_set_keyboard_focus (shell_widget, FRAME_X_TEXT_WIDGET (f));
343 /* DO NOT CALL THIS FUNCTION! Only Xt is supposed to do this. */
346 EmacsFrameResize (Widget widget)
348 EmacsFrame ew = (EmacsFrame)widget;
349 struct frame *f = ew->emacs_frame.frame;
352 XtWidgetGeometry req, repl;
354 update_various_frame_slots (ew);
356 pixel_to_char_size (f, ew->core.width, ew->core.height, &columns, &rows);
357 change_frame_size (f, rows, columns, 0);
359 /* Now we tell the EmacsShell that we've changed the size of the non-fixed
360 portion of the frame. Note that, if we the resize occurred as a result
361 of EmacsFrameSetCharSize(), this information will be stored twice.
362 This is not a big deal, as storing this information doesn't actually
363 do anything until the next resize. */
364 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
365 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
367 /* Kick the manager so that it knows we've changed size. */
368 req.request_mode = 0;
369 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
370 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
375 EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget,
376 ArgList argv, Cardinal *argc)
378 EmacsFrame cur = (EmacsFrame) cur_widget;
379 EmacsFrame new = (EmacsFrame) new_widget;
380 struct frame *f = new->emacs_frame.frame;
383 XSETFRAME (frame, f);
384 in_resource_setting++;
385 /* This function does not need to do much. Pretty much everything
386 interesting will get done in the resize method, which will
387 (if necessary) get called by Xt when this function returns
391 /* #### This function will not work if it is not called from
392 update_EmacsFrame(), called from SET_FACE_PROPERTY().
393 The code located there should be moved inside of here instead,
394 so that things work if either SET_FACE_PROPERTY() is
395 called or XtSetValues() is called.
398 if (cur->emacs_frame.iconic != new->emacs_frame.iconic &&
399 FRAME_X_TOP_LEVEL_FRAME_P (new->emacs_frame.frame))
400 x_wm_set_shell_iconic_p (FRAME_X_SHELL_WIDGET (new->emacs_frame.frame),
401 new->emacs_frame.iconic);
403 /* If we got here, then we were likely called as a result of
404 the EditRes protocol, so go ahead and change scrollbar-width
405 and scrollbar-height. Otherwise, we're merely mirroring
406 a change made to scrollbar-width etc. so don't do anything
408 if (cur->emacs_frame.internal_border_width !=
409 new->emacs_frame.internal_border_width)
411 f->internal_border_width = new->emacs_frame.internal_border_width;
412 MARK_FRAME_SIZE_SLIPPED (f);
415 #ifdef HAVE_SCROLLBARS
416 if (cur->emacs_frame.scrollbar_width !=
417 new->emacs_frame.scrollbar_width)
418 Fadd_spec_to_specifier
420 make_int (new->emacs_frame.scrollbar_width),
422 if (cur->emacs_frame.scrollbar_height !=
423 new->emacs_frame.scrollbar_height)
424 Fadd_spec_to_specifier
426 make_int (new->emacs_frame.scrollbar_height),
428 #endif /* HAVE_SCROLLBARS */
430 if (cur->emacs_frame.top_toolbar_height !=
431 new->emacs_frame.top_toolbar_height)
432 Fadd_spec_to_specifier
433 (Vtoolbar_size[TOP_TOOLBAR],
434 make_int (new->emacs_frame.top_toolbar_height),
436 if (cur->emacs_frame.bottom_toolbar_height !=
437 new->emacs_frame.bottom_toolbar_height)
438 Fadd_spec_to_specifier
439 (Vtoolbar_size[BOTTOM_TOOLBAR],
440 make_int (new->emacs_frame.bottom_toolbar_height),
442 if (cur->emacs_frame.left_toolbar_width !=
443 new->emacs_frame.left_toolbar_width)
444 Fadd_spec_to_specifier
445 (Vtoolbar_size[LEFT_TOOLBAR],
446 make_int (new->emacs_frame.left_toolbar_width),
448 if (cur->emacs_frame.right_toolbar_width !=
449 new->emacs_frame.right_toolbar_width)
450 Fadd_spec_to_specifier
451 (Vtoolbar_size[RIGHT_TOOLBAR],
452 make_int (new->emacs_frame.right_toolbar_width),
454 if (cur->emacs_frame.top_toolbar_border_width !=
455 new->emacs_frame.top_toolbar_border_width)
456 Fadd_spec_to_specifier
457 (Vtoolbar_border_width[TOP_TOOLBAR],
458 make_int (new->emacs_frame.top_toolbar_border_width),
460 if (cur->emacs_frame.bottom_toolbar_border_width !=
461 new->emacs_frame.bottom_toolbar_border_width)
462 Fadd_spec_to_specifier
463 (Vtoolbar_border_width[BOTTOM_TOOLBAR],
464 make_int (new->emacs_frame.bottom_toolbar_border_width),
466 if (cur->emacs_frame.left_toolbar_border_width !=
467 new->emacs_frame.left_toolbar_border_width)
468 Fadd_spec_to_specifier
469 (Vtoolbar_border_width[LEFT_TOOLBAR],
470 make_int (new->emacs_frame.left_toolbar_border_width),
472 if (cur->emacs_frame.right_toolbar_border_width !=
473 new->emacs_frame.right_toolbar_border_width)
474 Fadd_spec_to_specifier
475 (Vtoolbar_border_width[RIGHT_TOOLBAR],
476 make_int (new->emacs_frame.right_toolbar_border_width),
478 #endif /* HAVE_TOOLBARS */
480 in_resource_setting--;
482 /* If the request was to resize us, but the size has not changed, Xt
483 will do nothing, and won't call our resize callback. Since such a
484 request might be issued as a result of hiding/showing menubar or
485 changing toolbar placement, where we rely on relayout made by the
486 callback, we go ahead and simulate such a call */
487 if (cur->core.width == new->core.width
488 && cur->core.height == new->core.height)
491 for (i=0; i<*argc; i++)
492 if (strcmp (argv[i].name, XtNwidth) == 0
493 || strcmp (argv[i].name, XtNheight) == 0)
495 EmacsFrameResize (new_widget);
502 /* Note that if either (a) we return True, or (b) the width or
503 height has changed, an Expose event will be generated. The Xt
504 manual says you should not return True if the width or height has
505 changed, because then two Expose events will be generated.
507 In any case, there is no need to return True because
508 SET_FACE_PROPERTY(), which does the resource
509 setting, automatically forces a redisplay as necessary. */
512 static XtGeometryResult
513 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
514 XtWidgetGeometry *result)
516 EmacsFrame ew = (EmacsFrame) widget;
517 int mask = request->request_mode;
518 Dimension width, height;
519 int ok_width_int, ok_height_int;
520 Dimension ok_width, ok_height;
522 /* We have a definite preference for what size we would like
525 1) If a preferred size was specified for us, use it.
526 (This is not currently used)
527 2) If a proposed size was given, round it to the nearest
528 multiple of the default char size and return it.
529 3) Otherwise, take our current size and round it to the
530 nearest multiple of the default char size. */
532 width = mask & CWWidth ? request->width : ew->core.width;
533 height = mask & CWHeight ? request->height : ew->core.height;
534 round_size_to_char (ew->emacs_frame.frame, width, height,
535 &ok_width_int, &ok_height_int);
536 ok_width = (Dimension) ok_width_int;
537 ok_height = (Dimension) ok_height_int;
538 if (ew->emacs_frame.preferred_width)
539 ok_width = ew->emacs_frame.preferred_width;
540 if (ew->emacs_frame.preferred_height)
541 ok_height = ew->emacs_frame.preferred_height;
542 result->request_mode |= CWWidth | CWHeight;
543 result->width = ok_width;
544 result->height = ok_height;
545 if (((mask & CWWidth) && ok_width != request->width)
546 || ((mask & CWHeight) && ok_height != request->height))
547 return XtGeometryAlmost;
549 return XtGeometryYes;
552 /* Xt string-to-scrollbar-placement converter */
553 /* ### Convert this to a `new-style' converter (See XtAddTypeConverter) */
555 /* This variable cannot be a stack variable. */
556 static unsigned char cvt_string_scrollbar_placement;
560 Xt_StringToScrollBarPlacement (XrmValuePtr args, /* unused */
561 Cardinal *num_args, /* unused */
566 char *lowerName = (char *) alloca (strlen ((char *) fromVal->addr) + 1);
568 XmuCopyISOLatin1Lowered (lowerName, (char *) fromVal->addr);
569 q = XrmStringToQuark (lowerName);
571 toVal->size = sizeof (cvt_string_scrollbar_placement);
572 toVal->addr = (XPointer) &cvt_string_scrollbar_placement;
574 if (q == XrmStringToQuark ("top-left")
575 || q == XrmStringToQuark ("top_left"))
576 cvt_string_scrollbar_placement = XtTOP_LEFT;
577 else if (q == XrmStringToQuark ("bottom-left")
578 || q == XrmStringToQuark ("bottom_left"))
579 cvt_string_scrollbar_placement = XtBOTTOM_LEFT;
580 else if (q == XrmStringToQuark ("top-right")
581 || q == XrmStringToQuark ("top_right"))
582 cvt_string_scrollbar_placement = XtTOP_RIGHT;
583 else if (q == XrmStringToQuark ("bottom-right")
584 || q == XrmStringToQuark ("bottom_right"))
585 cvt_string_scrollbar_placement = XtBOTTOM_RIGHT;
588 XtStringConversionWarning (fromVal->addr, "scrollBarPlacement");
595 EmacsFrameClassInitialize (void)
597 XtAddConverter (XtRString, XtRScrollBarPlacement,
598 Xt_StringToScrollBarPlacement, NULL, 0);
601 /********************* Special entrypoints *******************/
604 EmacsFrameRecomputeCellSize (Widget w)
606 EmacsFrame ew = (EmacsFrame) w;
608 struct frame *f = ew->emacs_frame.frame;
610 if (! XtIsSubclass (w, emacsFrameClass))
613 default_face_height_and_width (make_frame (f), &ch, &cw);
614 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
615 x_wm_set_cell_size (FRAME_X_SHELL_WIDGET (f), cw, ch);
618 /* Set the size of the widget to have the number of rows and columns
619 specified. This both causes the X window to change and the
620 internal frame structures to get modified to match. */
623 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
625 EmacsFrame ew = (EmacsFrame) widget;
626 int pixel_width, pixel_height;
627 struct frame *f = ew->emacs_frame.frame;
631 columns = 3; /* no way buddy */
635 char_to_pixel_size (f, columns, rows, &pixel_width, &pixel_height);
637 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
638 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
640 XtSetArg (al [0], XtNwidth, (Dimension) pixel_width);
641 XtSetArg (al [1], XtNheight, (Dimension) pixel_height);
642 XtSetValues ((Widget) ew, al, 2);