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 */
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,
51 static XtGeometryResult EmacsFrameQueryGeometry (Widget, XtWidgetGeometry*,
55 emacs_Xt_mapping_action (Widget w, XEvent* event);
58 #define XtOffset(p_type,field) \
59 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
60 #define offset(field) XtOffset (EmacsFrame, emacs_frame.field)
62 static XtResource resources[] = {
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 },
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,
87 offset (internal_border_width), XtRImmediate, (XtPointer)4 },
88 #ifdef HAVE_SCROLLBARS
89 { XtNscrollBarWidth, XtCScrollBarWidth,
91 offset (scrollbar_width), XtRImmediate, (XtPointer)-1 },
92 { XtNscrollBarHeight, XtCScrollBarHeight,
94 offset (scrollbar_height), XtRImmediate, (XtPointer)-1 },
95 { XtNscrollBarPlacement, XtCScrollBarPlacement,
96 XtRScrollBarPlacement, sizeof (unsigned char),
97 offset (scrollbar_placement), XtRImmediate,
98 #if defined (LWLIB_SCROLLBARS_MOTIF) || defined (LWLIB_SCROLLBARS_LUCID) || \
99 defined (LWLIB_SCROLLBARS_ATHENA3D)
100 (XtPointer) XtBOTTOM_RIGHT
102 (XtPointer) XtBOTTOM_LEFT
105 #endif /* HAVE_SCROLLBARS */
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 },
153 #endif /* HAVE_TOOLBARS */
155 { XtNinterline, XtCInterline,
156 XtRInt, sizeof (int),
157 offset (interline), XtRImmediate, (XtPointer)0 },
160 XtNfontSet, XtCFontSet,
161 XtRFontSet, sizeof (XFontSet),
164 XtRFontStruct, sizeof (XFontStruct *),
166 offset(font), XtRImmediate, (XtPointer)0
168 { XtNforeground, XtCForeground,
169 XtRPixel, sizeof (Pixel),
170 offset(foreground_pixel), XtRString, (XtPointer) "Black" },
171 { XtNbackground, XtCBackground,
172 XtRPixel, sizeof (Pixel),
173 offset(background_pixel), XtRString, (XtPointer) "Gray80" },
174 { XtNcursorColor, XtCForeground,
175 XtRPixel, sizeof (Pixel),
176 offset(cursor_color), XtRString, (XtPointer) "XtDefaultForeground" },
177 { XtNbarCursor, XtCBarCursor,
178 XtRBoolean, sizeof (Boolean),
179 offset (bar_cursor), XtRImmediate, (XtPointer)0 },
180 { XtNvisualBell, XtCVisualBell,
181 XtRBoolean, sizeof (Boolean),
182 offset (visual_bell), XtRImmediate, (XtPointer)0 },
183 { XtNbellVolume, XtCBellVolume,
184 XtRInt, sizeof (int),
185 offset (bell_volume), XtRImmediate, (XtPointer)0 },
186 { XtNuseBackingStore, XtCUseBackingStore,
187 XtRBoolean, sizeof (Boolean),
188 offset (use_backing_store), XtRImmediate, (XtPointer)0 },
189 { XtNpreferredWidth, XtCPreferredWidth,
190 XtRDimension, sizeof (Dimension),
191 offset (preferred_width), XtRImmediate, (XtPointer)0 },
192 { XtNpreferredHeight, XtCPreferredHeight,
193 XtRDimension, sizeof (Dimension),
194 offset (preferred_height), XtRImmediate, (XtPointer)0 },
199 /* Xt is stupid and dumb.
200 Xt is stupid and dumb.
201 Xt is stupid and dumb. */
204 emacsFrameActionsTable [] = {
205 {"mapping", (XtActionProc) emacs_Xt_mapping_action},
209 emacsFrameTranslations [] = "\
210 <Mapping>: mapping()\n\
213 /* If we're running under Motif, make this widget a subclass
214 of XmPrimitive. It's not clear this is necessary, but it
215 may make focus behavior work better. */
217 EmacsFrameClassRec emacsFrameClassRec = {
219 #ifdef LWLIB_USES_MOTIF
220 /* superclass */ (WidgetClass) &xmPrimitiveClassRec,
222 /* superclass */ &widgetClassRec,
224 /* class_name */ "EmacsFrame",
225 /* widget_size */ sizeof (EmacsFrameRec),
226 /* class_initialize */ EmacsFrameClassInitialize,
227 /* class_part_initialize */ 0,
228 /* class_inited */ FALSE,
229 /* initialize */ EmacsFrameInitialize,
230 /* initialize_hook */ 0,
231 /* realize */ EmacsFrameRealize,
232 /* actions */ emacsFrameActionsTable,
233 /* num_actions */ XtNumber (emacsFrameActionsTable),
234 /* resources */ resources,
235 /* resource_count */ XtNumber (resources),
236 /* xrm_class */ NULLQUARK,
237 /* compress_motion */ TRUE,
238 /* compress_exposure */ TRUE,
239 /* compress_enterleave */ TRUE,
240 /* visible_interest */ FALSE,
242 /* resize */ EmacsFrameResize,
243 /* expose */ XtInheritExpose,
244 /* set_values */ EmacsFrameSetValues,
245 /* set_values_hook */ 0,
246 /* set_values_almost */ XtInheritSetValuesAlmost,
247 /* get_values_hook */ 0,
248 /* accept_focus */ XtInheritAcceptFocus,
249 /* version */ XtVersion,
250 /* callback_private */ 0,
251 /* tm_table */ emacsFrameTranslations,
252 /* query_geometry */ EmacsFrameQueryGeometry,
253 /* display_accelerator */ XtInheritDisplayAccelerator,
256 #ifdef LWLIB_USES_MOTIF
257 { /* XmPrimitiveClassPart
259 (XtWidgetProc) _XtInherit, /* border_highlight */
260 (XtWidgetProc) _XtInherit, /* border_unhighlight */
261 /* Setting the following to NULL causes PrimitiveInitialize()
262 not to add traversal (TAB etc. to switch focus) and
263 focus-in/out (border highlight/unhighlight) translations.
264 If you want those translations, use the value XtInheritTranslations
265 instead. Doing this, however, will interfere with Emacs
266 focus handling (which highlights/unhighlights the text cursor),
267 and will lead to strange display results around the border of the
269 NULL, /* translations */
270 NULL, /* arm_and_activate */
271 NULL, /* get resources */
272 0, /* num get_resources */
273 NULL, /* extension */
275 #endif /* LWLIB_USES_MOTIF */
280 WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
283 update_various_frame_slots (EmacsFrame ew)
285 ew->emacs_frame.frame->pixheight = ew->core.height;
286 ew->emacs_frame.frame->pixwidth = ew->core.width;
290 EmacsFrameInitialize (Widget request, Widget new,
291 ArgList dum1, Cardinal *dum2)
293 EmacsFrame ew = (EmacsFrame)new;
294 struct frame *f = ew->emacs_frame.frame;
297 fatal ("can't create an emacs frame widget without a frame.");
299 ew->emacs_frame.frame->internal_border_width =
300 ew->emacs_frame.internal_border_width;
303 void emacs_Xt_event_handler (Widget wid /* unused */,
304 XtPointer closure /* unused */,
306 Boolean *continue_to_dispatch /* unused */);
309 EmacsFrameRealize (Widget widget, XtValueMask *mask,
310 XSetWindowAttributes *attrs)
312 EmacsFrame ew = (EmacsFrame) widget;
313 struct frame *f = ew->emacs_frame.frame;
314 Widget shell_widget = FRAME_X_SHELL_WIDGET (f);
318 VisibilityChangeMask |
320 StructureNotifyMask |
321 SubstructureNotifyMask |
322 /*SubstructureRedirectMask |*/ /* Only for WMs! */
328 PointerMotionHintMask |
335 /* Make sure that events wanted by the input method are selected. */
336 attrs->event_mask |= input_method_event_mask;
339 *mask |= CWEventMask;
341 if (ew->emacs_frame.use_backing_store)
343 attrs->backing_store = Always;
344 *mask |= CWBackingStore;
346 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
349 /* snarf the events we want. */
350 XtInsertEventHandler (widget, attrs->event_mask, TRUE,
351 emacs_Xt_event_handler, NULL, XtListHead);
352 /* some events (e.g. map-notify and WM_DELETE_WINDOW) get sent
353 directly to the shell, and the above event handler won't see
354 them. So add a handler to get them. These events don't
355 propagate, so there's no danger of them being seen twice. */
356 XtInsertEventHandler (shell_widget,
357 EnterWindowMask | LeaveWindowMask |
358 VisibilityChangeMask | StructureNotifyMask |
360 TRUE, emacs_Xt_event_handler, NULL, XtListHead);
362 #ifdef EXTERNAL_WIDGET
363 /* #### Not sure if this special case is necessary */
364 if (!FRAME_X_EXTERNAL_WINDOW_P (f))
366 /* This is necessary under Motif in order to make it possible to click in
367 a buffer and move focus out of a dialog box or control panel and back
368 into emacs-land; also necessary so that you can still type chars
369 if the cursor is over the menubar or scrollbar. */
370 lw_set_keyboard_focus (shell_widget, FRAME_X_TEXT_WIDGET (f));
373 /* DO NOT CALL THIS FUNCTION! Only Xt is supposed to do this. */
376 EmacsFrameResize (Widget widget)
378 EmacsFrame ew = (EmacsFrame)widget;
379 struct frame *f = ew->emacs_frame.frame;
382 XtWidgetGeometry req, repl;
384 update_various_frame_slots (ew);
386 pixel_to_char_size (f, ew->core.width, ew->core.height, &columns, &rows);
387 change_frame_size (f, rows, columns, 0);
389 /* Now we tell the EmacsShell that we've changed the size of the non-fixed
390 portion of the frame. Note that, if we the resize occurred as a result
391 of EmacsFrameSetCharSize(), this information will be stored twice.
392 This is not a big deal, as storing this information doesn't actually
393 do anything until the next resize. */
394 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
395 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
397 /* Kick the manager so that it knows we've changed size. */
398 req.request_mode = 0;
399 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
400 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
405 EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget,
406 ArgList argv, Cardinal *argc)
408 EmacsFrame cur = (EmacsFrame) cur_widget;
409 EmacsFrame new = (EmacsFrame) new_widget;
410 struct frame *f = new->emacs_frame.frame;
413 XSETFRAME (frame, f);
414 in_resource_setting++;
415 /* This function does not need to do much. Pretty much everything
416 interesting will get done in the resize method, which will
417 (if necessary) get called by Xt when this function returns
421 /* #### This function will not work if it is not called from
422 update_EmacsFrame(), called from SET_FACE_PROPERTY().
423 The code located there should be moved inside of here instead,
424 so that things work if either SET_FACE_PROPERTY() is
425 called or XtSetValues() is called.
428 if (cur->emacs_frame.iconic != new->emacs_frame.iconic &&
429 FRAME_X_TOP_LEVEL_FRAME_P (new->emacs_frame.frame))
430 x_wm_set_shell_iconic_p (FRAME_X_SHELL_WIDGET (new->emacs_frame.frame),
431 new->emacs_frame.iconic);
433 /* If we got here, then we were likely called as a result of
434 the EditRes protocol, so go ahead and change scrollbar-width
435 and scrollbar-height. Otherwise, we're merely mirroring
436 a change made to scrollbar-width etc. so don't do anything
438 if (cur->emacs_frame.internal_border_width !=
439 new->emacs_frame.internal_border_width)
441 f->internal_border_width = new->emacs_frame.internal_border_width;
442 MARK_FRAME_SIZE_SLIPPED (f);
445 #ifdef HAVE_SCROLLBARS
446 if (cur->emacs_frame.scrollbar_width !=
447 new->emacs_frame.scrollbar_width)
448 Fadd_spec_to_specifier
450 make_int (new->emacs_frame.scrollbar_width),
452 if (cur->emacs_frame.scrollbar_height !=
453 new->emacs_frame.scrollbar_height)
454 Fadd_spec_to_specifier
456 make_int (new->emacs_frame.scrollbar_height),
458 #endif /* HAVE_SCROLLBARS */
460 if (cur->emacs_frame.top_toolbar_height !=
461 new->emacs_frame.top_toolbar_height)
462 Fadd_spec_to_specifier
463 (Vtoolbar_size[TOP_TOOLBAR],
464 make_int (new->emacs_frame.top_toolbar_height),
466 if (cur->emacs_frame.bottom_toolbar_height !=
467 new->emacs_frame.bottom_toolbar_height)
468 Fadd_spec_to_specifier
469 (Vtoolbar_size[BOTTOM_TOOLBAR],
470 make_int (new->emacs_frame.bottom_toolbar_height),
472 if (cur->emacs_frame.left_toolbar_width !=
473 new->emacs_frame.left_toolbar_width)
474 Fadd_spec_to_specifier
475 (Vtoolbar_size[LEFT_TOOLBAR],
476 make_int (new->emacs_frame.left_toolbar_width),
478 if (cur->emacs_frame.right_toolbar_width !=
479 new->emacs_frame.right_toolbar_width)
480 Fadd_spec_to_specifier
481 (Vtoolbar_size[RIGHT_TOOLBAR],
482 make_int (new->emacs_frame.right_toolbar_width),
484 if (cur->emacs_frame.top_toolbar_border_width !=
485 new->emacs_frame.top_toolbar_border_width)
486 Fadd_spec_to_specifier
487 (Vtoolbar_border_width[TOP_TOOLBAR],
488 make_int (new->emacs_frame.top_toolbar_border_width),
490 if (cur->emacs_frame.bottom_toolbar_border_width !=
491 new->emacs_frame.bottom_toolbar_border_width)
492 Fadd_spec_to_specifier
493 (Vtoolbar_border_width[BOTTOM_TOOLBAR],
494 make_int (new->emacs_frame.bottom_toolbar_border_width),
496 if (cur->emacs_frame.left_toolbar_border_width !=
497 new->emacs_frame.left_toolbar_border_width)
498 Fadd_spec_to_specifier
499 (Vtoolbar_border_width[LEFT_TOOLBAR],
500 make_int (new->emacs_frame.left_toolbar_border_width),
502 if (cur->emacs_frame.right_toolbar_border_width !=
503 new->emacs_frame.right_toolbar_border_width)
504 Fadd_spec_to_specifier
505 (Vtoolbar_border_width[RIGHT_TOOLBAR],
506 make_int (new->emacs_frame.right_toolbar_border_width),
508 #endif /* HAVE_TOOLBARS */
510 in_resource_setting--;
512 /* If the request was to resize us, but the size has not changed, Xt
513 will do nothing, and won't call our resize callback. Since such a
514 request might be issued as a result of hiding/showing menubar or
515 changing toolbar placement, where we rely on relayout made by the
516 callback, we go ahead and simulate such a call */
517 if (cur->core.width == new->core.width
518 && cur->core.height == new->core.height)
521 for (i=0; i<*argc; i++)
522 if (strcmp (argv[i].name, XtNwidth) == 0
523 || strcmp (argv[i].name, XtNheight) == 0)
525 EmacsFrameResize (new_widget);
532 /* Note that if either (a) we return True, or (b) the width or
533 height has changed, an Expose event will be generated. The Xt
534 manual says you should not return True if the width or height has
535 changed, because then two Expose events will be generated.
537 In any case, there is no need to return True because
538 SET_FACE_PROPERTY(), which does the resource
539 setting, automatically forces a redisplay as necessary. */
542 static XtGeometryResult
543 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
544 XtWidgetGeometry *result)
546 EmacsFrame ew = (EmacsFrame) widget;
547 int mask = request->request_mode;
548 Dimension width, height;
549 int ok_width_int, ok_height_int;
550 Dimension ok_width, ok_height;
552 /* We have a definite preference for what size we would like
555 1) If a preferred size was specified for us, use it.
556 (This is not currently used)
557 2) If a proposed size was given, round it to the nearest
558 multiple of the default char size and return it.
559 3) Otherwise, take our current size and round it to the
560 nearest multiple of the default char size. */
562 width = mask & CWWidth ? request->width : ew->core.width;
563 height = mask & CWHeight ? request->height : ew->core.height;
564 round_size_to_char (ew->emacs_frame.frame, width, height,
565 &ok_width_int, &ok_height_int);
566 ok_width = (Dimension) ok_width_int;
567 ok_height = (Dimension) ok_height_int;
568 if (ew->emacs_frame.preferred_width)
569 ok_width = ew->emacs_frame.preferred_width;
570 if (ew->emacs_frame.preferred_height)
571 ok_height = ew->emacs_frame.preferred_height;
572 result->request_mode |= CWWidth | CWHeight;
573 result->width = ok_width;
574 result->height = ok_height;
575 if (((mask & CWWidth) && ok_width != request->width)
576 || ((mask & CWHeight) && ok_height != request->height))
577 return XtGeometryAlmost;
579 return XtGeometryYes;
582 /* Xt string-to-scrollbar-placement converter */
583 /* #### Convert this to a `new-style' converter (See XtAddTypeConverter) */
585 /* This variable cannot be a stack variable. */
586 static unsigned char cvt_string_scrollbar_placement;
590 Xt_StringToScrollBarPlacement (XrmValuePtr args, /* unused */
591 Cardinal *num_args, /* unused */
596 char *lowerName = (char *) alloca (strlen ((char *) fromVal->addr) + 1);
598 XmuCopyISOLatin1Lowered (lowerName, (char *) fromVal->addr);
599 q = XrmStringToQuark (lowerName);
601 toVal->size = sizeof (cvt_string_scrollbar_placement);
602 toVal->addr = (XPointer) &cvt_string_scrollbar_placement;
604 if (q == XrmStringToQuark ("top-left")
605 || q == XrmStringToQuark ("top_left"))
606 cvt_string_scrollbar_placement = XtTOP_LEFT;
607 else if (q == XrmStringToQuark ("bottom-left")
608 || q == XrmStringToQuark ("bottom_left"))
609 cvt_string_scrollbar_placement = XtBOTTOM_LEFT;
610 else if (q == XrmStringToQuark ("top-right")
611 || q == XrmStringToQuark ("top_right"))
612 cvt_string_scrollbar_placement = XtTOP_RIGHT;
613 else if (q == XrmStringToQuark ("bottom-right")
614 || q == XrmStringToQuark ("bottom_right"))
615 cvt_string_scrollbar_placement = XtBOTTOM_RIGHT;
618 XtStringConversionWarning (fromVal->addr, "scrollBarPlacement");
625 EmacsFrameClassInitialize (void)
627 XtAddConverter (XtRString, XtRScrollBarPlacement,
628 Xt_StringToScrollBarPlacement, NULL, 0);
631 /********************* Special entrypoints *******************/
634 EmacsFrameRecomputeCellSize (Widget w)
636 EmacsFrame ew = (EmacsFrame) w;
638 struct frame *f = ew->emacs_frame.frame;
640 if (! XtIsSubclass (w, emacsFrameClass))
643 default_face_height_and_width (make_frame (f), &ch, &cw);
644 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
645 x_wm_set_cell_size (FRAME_X_SHELL_WIDGET (f), cw, ch);
648 /* Set the size of the widget to have the number of rows and columns
649 specified. This both causes the X window to change and the
650 internal frame structures to get modified to match. */
653 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
655 EmacsFrame ew = (EmacsFrame) widget;
656 int pixel_width, pixel_height;
657 struct frame *f = ew->emacs_frame.frame;
660 columns = 3; /* no way buddy */
664 char_to_pixel_size (f, columns, rows, &pixel_width, &pixel_height);
666 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
667 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
671 XtSetArg (al [0], XtNwidth, pixel_width);
672 XtSetArg (al [1], XtNheight, pixel_height);
673 XtSetValues ((Widget) ew, al, countof (al));