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) NotUseful },
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 #ifdef LWLIB_USES_MOTIF
239 /* compress_exposure */ TRUE,
241 /* compress_exposure */ XtExposeCompressMaximal | XtExposeNoRegion,
243 /* compress_enterleave */ TRUE,
244 /* visible_interest */ FALSE,
246 /* resize */ EmacsFrameResize,
247 /* expose */ XtInheritExpose,
248 /* set_values */ EmacsFrameSetValues,
249 /* set_values_hook */ 0,
250 /* set_values_almost */ XtInheritSetValuesAlmost,
251 /* get_values_hook */ 0,
252 /* accept_focus */ XtInheritAcceptFocus,
253 /* version */ XtVersion,
254 /* callback_private */ 0,
255 /* tm_table */ emacsFrameTranslations,
256 /* query_geometry */ EmacsFrameQueryGeometry,
257 /* display_accelerator */ XtInheritDisplayAccelerator,
260 #ifdef LWLIB_USES_MOTIF
261 { /* XmPrimitiveClassPart
263 (XtWidgetProc) _XtInherit, /* border_highlight */
264 (XtWidgetProc) _XtInherit, /* border_unhighlight */
265 /* Setting the following to NULL causes PrimitiveInitialize()
266 not to add traversal (TAB etc. to switch focus) and
267 focus-in/out (border highlight/unhighlight) translations.
268 If you want those translations, use the value XtInheritTranslations
269 instead. Doing this, however, will interfere with Emacs
270 focus handling (which highlights/unhighlights the text cursor),
271 and will lead to strange display results around the border of the
273 NULL, /* translations */
274 NULL, /* arm_and_activate */
275 NULL, /* get resources */
276 0, /* num get_resources */
277 NULL, /* extension */
279 #endif /* LWLIB_USES_MOTIF */
284 WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
287 update_various_frame_slots (EmacsFrame ew)
289 ew->emacs_frame.frame->pixheight = ew->core.height;
290 ew->emacs_frame.frame->pixwidth = ew->core.width;
294 EmacsFrameInitialize (Widget request, Widget new,
295 ArgList dum1, Cardinal *dum2)
297 EmacsFrame ew = (EmacsFrame)new;
298 struct frame *f = ew->emacs_frame.frame;
301 fatal ("can't create an emacs frame widget without a frame.");
303 ew->emacs_frame.frame->internal_border_width =
304 ew->emacs_frame.internal_border_width;
307 void emacs_Xt_event_handler (Widget wid /* unused */,
308 XtPointer closure /* unused */,
310 Boolean *continue_to_dispatch /* unused */);
313 EmacsFrameRealize (Widget widget, XtValueMask *mask,
314 XSetWindowAttributes *attrs)
316 EmacsFrame ew = (EmacsFrame) widget;
317 struct frame *f = ew->emacs_frame.frame;
318 Widget shell_widget = FRAME_X_SHELL_WIDGET (f);
322 VisibilityChangeMask |
324 StructureNotifyMask |
325 SubstructureNotifyMask |
326 /*SubstructureRedirectMask |*/ /* Only for WMs! */
332 PointerMotionHintMask |
339 /* Make sure that events wanted by the input method are selected. */
340 attrs->event_mask |= input_method_event_mask;
343 *mask |= CWEventMask;
345 if (ew->emacs_frame.use_backing_store)
347 attrs->backing_store = Always;
348 *mask |= CWBackingStore;
350 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
353 /* snarf the events we want. */
354 XtInsertEventHandler (widget, attrs->event_mask, TRUE,
355 emacs_Xt_event_handler, NULL, XtListHead);
356 /* some events (e.g. map-notify and WM_DELETE_WINDOW) get sent
357 directly to the shell, and the above event handler won't see
358 them. So add a handler to get them. These events don't
359 propagate, so there's no danger of them being seen twice. */
360 XtInsertEventHandler (shell_widget,
361 EnterWindowMask | LeaveWindowMask |
362 VisibilityChangeMask | StructureNotifyMask |
364 TRUE, emacs_Xt_event_handler, NULL, XtListHead);
366 #ifdef EXTERNAL_WIDGET
367 /* #### Not sure if this special case is necessary */
368 if (!FRAME_X_EXTERNAL_WINDOW_P (f))
370 /* This is necessary under Motif in order to make it possible to click in
371 a buffer and move focus out of a dialog box or control panel and back
372 into emacs-land; also necessary so that you can still type chars
373 if the cursor is over the menubar or scrollbar. */
374 lw_set_keyboard_focus (shell_widget, FRAME_X_TEXT_WIDGET (f));
377 /* DO NOT CALL THIS FUNCTION! Only Xt is supposed to do this. */
380 EmacsFrameResize (Widget widget)
382 EmacsFrame ew = (EmacsFrame)widget;
383 struct frame *f = ew->emacs_frame.frame;
386 XtWidgetGeometry req, repl;
388 update_various_frame_slots (ew);
390 pixel_to_char_size (f, ew->core.width, ew->core.height, &columns, &rows);
391 change_frame_size (f, rows, columns, 0);
393 /* Now we tell the EmacsShell that we've changed the size of the non-fixed
394 portion of the frame. Note that, if we the resize occurred as a result
395 of EmacsFrameSetCharSize(), this information will be stored twice.
396 This is not a big deal, as storing this information doesn't actually
397 do anything until the next resize. */
398 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
399 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
401 /* Kick the manager so that it knows we've changed size. */
402 req.request_mode = 0;
403 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
404 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
409 EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget,
410 ArgList argv, Cardinal *argc)
412 EmacsFrame cur = (EmacsFrame) cur_widget;
413 EmacsFrame new = (EmacsFrame) new_widget;
414 struct frame *f = new->emacs_frame.frame;
417 XSETFRAME (frame, f);
418 in_resource_setting++;
419 /* This function does not need to do much. Pretty much everything
420 interesting will get done in the resize method, which will
421 (if necessary) get called by Xt when this function returns
425 /* #### This function will not work if it is not called from
426 update_EmacsFrame(), called from SET_FACE_PROPERTY().
427 The code located there should be moved inside of here instead,
428 so that things work if either SET_FACE_PROPERTY() is
429 called or XtSetValues() is called.
432 if (cur->emacs_frame.iconic != new->emacs_frame.iconic &&
433 FRAME_X_TOP_LEVEL_FRAME_P (new->emacs_frame.frame))
434 x_wm_set_shell_iconic_p (FRAME_X_SHELL_WIDGET (new->emacs_frame.frame),
435 new->emacs_frame.iconic);
437 /* If we got here, then we were likely called as a result of
438 the EditRes protocol, so go ahead and change scrollbar-width
439 and scrollbar-height. Otherwise, we're merely mirroring
440 a change made to scrollbar-width etc. so don't do anything
442 if (cur->emacs_frame.internal_border_width !=
443 new->emacs_frame.internal_border_width)
445 f->internal_border_width = new->emacs_frame.internal_border_width;
446 MARK_FRAME_SIZE_SLIPPED (f);
449 #ifdef HAVE_SCROLLBARS
450 if (cur->emacs_frame.scrollbar_width !=
451 new->emacs_frame.scrollbar_width)
452 Fadd_spec_to_specifier
454 make_int (new->emacs_frame.scrollbar_width),
456 if (cur->emacs_frame.scrollbar_height !=
457 new->emacs_frame.scrollbar_height)
458 Fadd_spec_to_specifier
460 make_int (new->emacs_frame.scrollbar_height),
462 #endif /* HAVE_SCROLLBARS */
464 if (cur->emacs_frame.top_toolbar_height !=
465 new->emacs_frame.top_toolbar_height)
466 Fadd_spec_to_specifier
467 (Vtoolbar_size[TOP_TOOLBAR],
468 make_int (new->emacs_frame.top_toolbar_height),
470 if (cur->emacs_frame.bottom_toolbar_height !=
471 new->emacs_frame.bottom_toolbar_height)
472 Fadd_spec_to_specifier
473 (Vtoolbar_size[BOTTOM_TOOLBAR],
474 make_int (new->emacs_frame.bottom_toolbar_height),
476 if (cur->emacs_frame.left_toolbar_width !=
477 new->emacs_frame.left_toolbar_width)
478 Fadd_spec_to_specifier
479 (Vtoolbar_size[LEFT_TOOLBAR],
480 make_int (new->emacs_frame.left_toolbar_width),
482 if (cur->emacs_frame.right_toolbar_width !=
483 new->emacs_frame.right_toolbar_width)
484 Fadd_spec_to_specifier
485 (Vtoolbar_size[RIGHT_TOOLBAR],
486 make_int (new->emacs_frame.right_toolbar_width),
488 if (cur->emacs_frame.top_toolbar_border_width !=
489 new->emacs_frame.top_toolbar_border_width)
490 Fadd_spec_to_specifier
491 (Vtoolbar_border_width[TOP_TOOLBAR],
492 make_int (new->emacs_frame.top_toolbar_border_width),
494 if (cur->emacs_frame.bottom_toolbar_border_width !=
495 new->emacs_frame.bottom_toolbar_border_width)
496 Fadd_spec_to_specifier
497 (Vtoolbar_border_width[BOTTOM_TOOLBAR],
498 make_int (new->emacs_frame.bottom_toolbar_border_width),
500 if (cur->emacs_frame.left_toolbar_border_width !=
501 new->emacs_frame.left_toolbar_border_width)
502 Fadd_spec_to_specifier
503 (Vtoolbar_border_width[LEFT_TOOLBAR],
504 make_int (new->emacs_frame.left_toolbar_border_width),
506 if (cur->emacs_frame.right_toolbar_border_width !=
507 new->emacs_frame.right_toolbar_border_width)
508 Fadd_spec_to_specifier
509 (Vtoolbar_border_width[RIGHT_TOOLBAR],
510 make_int (new->emacs_frame.right_toolbar_border_width),
512 #endif /* HAVE_TOOLBARS */
514 in_resource_setting--;
516 /* If the request was to resize us, but the size has not changed, Xt
517 will do nothing, and won't call our resize callback. Since such a
518 request might be issued as a result of hiding/showing menubar or
519 changing toolbar placement, where we rely on relayout made by the
520 callback, we go ahead and simulate such a call */
521 if (cur->core.width == new->core.width
522 && cur->core.height == new->core.height)
525 for (i=0; i<*argc; i++)
526 if (strcmp (argv[i].name, XtNwidth) == 0
527 || strcmp (argv[i].name, XtNheight) == 0)
529 EmacsFrameResize (new_widget);
536 /* Note that if either (a) we return True, or (b) the width or
537 height has changed, an Expose event will be generated. The Xt
538 manual says you should not return True if the width or height has
539 changed, because then two Expose events will be generated.
541 In any case, there is no need to return True because
542 SET_FACE_PROPERTY(), which does the resource
543 setting, automatically forces a redisplay as necessary. */
546 static XtGeometryResult
547 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
548 XtWidgetGeometry *result)
550 EmacsFrame ew = (EmacsFrame) widget;
551 int mask = request->request_mode;
552 Dimension width, height;
553 int ok_width_int, ok_height_int;
554 Dimension ok_width, ok_height;
556 /* We have a definite preference for what size we would like
559 1) If a preferred size was specified for us, use it.
560 (This is not currently used)
561 2) If a proposed size was given, round it to the nearest
562 multiple of the default char size and return it.
563 3) Otherwise, take our current size and round it to the
564 nearest multiple of the default char size. */
566 width = mask & CWWidth ? request->width : ew->core.width;
567 height = mask & CWHeight ? request->height : ew->core.height;
568 round_size_to_char (ew->emacs_frame.frame, width, height,
569 &ok_width_int, &ok_height_int);
570 ok_width = (Dimension) ok_width_int;
571 ok_height = (Dimension) ok_height_int;
572 if (ew->emacs_frame.preferred_width)
573 ok_width = ew->emacs_frame.preferred_width;
574 if (ew->emacs_frame.preferred_height)
575 ok_height = ew->emacs_frame.preferred_height;
576 result->request_mode |= CWWidth | CWHeight;
577 result->width = ok_width;
578 result->height = ok_height;
579 if (((mask & CWWidth) && ok_width != request->width)
580 || ((mask & CWHeight) && ok_height != request->height))
581 return XtGeometryAlmost;
583 return XtGeometryYes;
586 /* Xt string-to-scrollbar-placement converter */
587 /* #### Convert this to a `new-style' converter (See XtAddTypeConverter) */
589 /* This variable cannot be a stack variable. */
590 static unsigned char cvt_string_scrollbar_placement;
594 Xt_StringToScrollBarPlacement (XrmValuePtr args, /* unused */
595 Cardinal *num_args, /* unused */
600 char *lowerName = (char *) alloca (strlen ((char *) fromVal->addr) + 1);
602 XmuCopyISOLatin1Lowered (lowerName, (char *) fromVal->addr);
603 q = XrmStringToQuark (lowerName);
605 toVal->size = sizeof (cvt_string_scrollbar_placement);
606 toVal->addr = (XPointer) &cvt_string_scrollbar_placement;
608 if (q == XrmStringToQuark ("top-left")
609 || q == XrmStringToQuark ("top_left"))
610 cvt_string_scrollbar_placement = XtTOP_LEFT;
611 else if (q == XrmStringToQuark ("bottom-left")
612 || q == XrmStringToQuark ("bottom_left"))
613 cvt_string_scrollbar_placement = XtBOTTOM_LEFT;
614 else if (q == XrmStringToQuark ("top-right")
615 || q == XrmStringToQuark ("top_right"))
616 cvt_string_scrollbar_placement = XtTOP_RIGHT;
617 else if (q == XrmStringToQuark ("bottom-right")
618 || q == XrmStringToQuark ("bottom_right"))
619 cvt_string_scrollbar_placement = XtBOTTOM_RIGHT;
622 XtStringConversionWarning (fromVal->addr, "scrollBarPlacement");
629 EmacsFrameClassInitialize (void)
631 XtAddConverter (XtRString, XtRScrollBarPlacement,
632 Xt_StringToScrollBarPlacement, NULL, 0);
635 /********************* Special entrypoints *******************/
638 EmacsFrameRecomputeCellSize (Widget w)
640 EmacsFrame ew = (EmacsFrame) w;
642 struct frame *f = ew->emacs_frame.frame;
644 if (! XtIsSubclass (w, emacsFrameClass))
647 default_face_height_and_width (make_frame (f), &ch, &cw);
648 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
649 x_wm_set_cell_size (FRAME_X_SHELL_WIDGET (f), cw, ch);
652 /* Set the size of the widget to have the number of rows and columns
653 specified. This both causes the X window to change and the
654 internal frame structures to get modified to match. */
657 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
659 EmacsFrame ew = (EmacsFrame) widget;
660 int pixel_width, pixel_height;
661 struct frame *f = ew->emacs_frame.frame;
664 columns = 3; /* no way buddy */
668 char_to_pixel_size (f, columns, rows, &pixel_width, &pixel_height);
670 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
671 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
675 XtSetArg (al [0], XtNwidth, pixel_width);
676 XtSetArg (al [1], XtNheight, pixel_height);
677 XtSetValues ((Widget) ew, al, countof (al));