comparison src/EmacsFrame.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
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 "redisplay.h"
44 #include "window.h"
45
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,
51 ArgList, Cardinal *);
52 static XtGeometryResult EmacsFrameQueryGeometry (Widget, XtWidgetGeometry*,
53 XtWidgetGeometry*);
54
55 extern void
56 emacs_Xt_mapping_action (Widget w, XMappingEvent* event);
57
58 #undef XtOffset
59 #define XtOffset(p_type,field) \
60 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
61 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
62
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},
68
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 (XtPointer) XtBOTTOM_RIGHT
90 #else
91 (XtPointer) XtBOTTOM_LEFT
92 #endif
93 },
94 #endif /* HAVE_SCROLLBARS */
95 #ifdef HAVE_TOOLBARS
96 {XtNtopToolBarHeight, XtCTopToolBarHeight, XtRInt, sizeof (int),
97 offset (top_toolbar_height), XtRImmediate, (XtPointer)-1},
98 {XtNbottomToolBarHeight, XtCBottomToolBarHeight, XtRInt, sizeof (int),
99 offset (bottom_toolbar_height), XtRImmediate, (XtPointer)-1},
100 {XtNleftToolBarWidth, XtCLeftToolBarWidth, XtRInt, sizeof (int),
101 offset (left_toolbar_width), XtRImmediate, (XtPointer)-1},
102 {XtNrightToolBarWidth, XtCRightToolBarWidth, XtRInt, sizeof (int),
103 offset (right_toolbar_width), XtRImmediate, (XtPointer)-1},
104 {XtNtopToolBarShadowColor, XtCTopToolBarShadowColor, XtRPixel, sizeof(Pixel),
105 offset(top_toolbar_shadow_pixel), XtRString, "Gray90"},
106 {XtNbottomToolBarShadowColor, XtCBottomToolBarShadowColor, XtRPixel,
107 sizeof(Pixel), offset(bottom_toolbar_shadow_pixel), XtRString,
108 "Gray40"},
109 {XtNbackgroundToolBarColor, XtCBackgroundToolBarColor, XtRPixel,
110 sizeof(Pixel), offset(background_toolbar_pixel), XtRString,
111 "Gray75"},
112 {XtNtopToolBarShadowPixmap, XtCTopToolBarShadowPixmap, XtRPixmap,
113 sizeof (Pixmap), offset(top_toolbar_shadow_pixmap), XtRImmediate,
114 (XtPointer)None},
115 {XtNbottomToolBarShadowPixmap, XtCBottomToolBarShadowPixmap, XtRPixmap,
116 sizeof (Pixmap), offset(bottom_toolbar_shadow_pixmap), XtRImmediate,
117 (XtPointer)None},
118 {XtNtoolBarShadowThickness, XtCToolBarShadowThickness, XtRDimension,
119 sizeof (Dimension), offset (toolbar_shadow_thickness), XtRImmediate,
120 (XtPointer)2},
121 #endif /* HAVE_TOOLBARS */
122 {XtNinterline, XtCInterline, XtRInt, sizeof (int),
123 offset (interline), XtRImmediate, (XtPointer)0},
124 {
125 #ifdef I18N4
126 XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
127 #else
128 XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
129 #endif
130 offset(font), XtRImmediate, (XtPointer)0
131 },
132 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
133 offset(foreground_pixel), XtRString, "XtDefaultForeground"},
134 {XtNcursorColor, XtCForeground, XtRPixel, sizeof(Pixel),
135 offset(cursor_color), XtRString, "XtDefaultForeground"},
136 {XtNbarCursor, XtCBarCursor, XtRBoolean, sizeof (Boolean),
137 offset (bar_cursor), XtRImmediate, (XtPointer)0},
138 {XtNvisualBell, XtCVisualBell, XtRBoolean, sizeof (Boolean),
139 offset (visual_bell), XtRImmediate, (XtPointer)0},
140 {XtNbellVolume, XtCBellVolume, XtRInt, sizeof (int),
141 offset (bell_volume), XtRImmediate, (XtPointer)0},
142 {XtNuseBackingStore, XtCUseBackingStore, XtRBoolean, sizeof (Boolean),
143 offset (use_backing_store), XtRImmediate, (XtPointer)0},
144 {XtNpreferredWidth, XtCPreferredWidth, XtRDimension, sizeof (Dimension),
145 offset (preferred_width), XtRImmediate, (XtPointer)0},
146 {XtNpreferredHeight, XtCPreferredHeight, XtRDimension, sizeof (Dimension),
147 offset (preferred_height), XtRImmediate, (XtPointer)0},
148 };
149
150 #undef offset
151
152 /* Xt is stupid and dumb.
153 Xt is stupid and dumb.
154 Xt is stupid and dumb. */
155
156 static XtActionsRec
157 emacsFrameActionsTable [] = {
158 {"mapping", (XtActionProc) emacs_Xt_mapping_action},
159 };
160
161 static char
162 emacsFrameTranslations [] = "\
163 <Mapping>: mapping()\n\
164 ";
165
166 /* If we're running under Motif, make this widget a subclass
167 of XmPrimitive. It's not clear this is necessary, but it
168 may make focus behavior work better. */
169
170 EmacsFrameClassRec emacsFrameClassRec = {
171 { /* core fields */
172 #ifdef LWLIB_USES_MOTIF
173 /* superclass */ (WidgetClass) &xmPrimitiveClassRec,
174 #else
175 /* superclass */ &widgetClassRec,
176 #endif
177 /* class_name */ "EmacsFrame",
178 /* widget_size */ sizeof(EmacsFrameRec),
179 /* class_initialize */ EmacsFrameClassInitialize,
180 /* class_part_initialize */ 0,
181 /* class_inited */ FALSE,
182 /* initialize */ EmacsFrameInitialize,
183 /* initialize_hook */ 0,
184 /* realize */ EmacsFrameRealize,
185 /* actions */ emacsFrameActionsTable,
186 /* num_actions */ XtNumber (emacsFrameActionsTable),
187 /* resources */ resources,
188 /* resource_count */ XtNumber(resources),
189 /* xrm_class */ NULLQUARK,
190 /* compress_motion */ TRUE,
191 /* compress_exposure */ TRUE,
192 /* compress_enterleave */ TRUE,
193 /* visible_interest */ FALSE,
194 /* destroy */ NULL,
195 /* resize */ EmacsFrameResize,
196 /* expose */ XtInheritExpose,
197 /* set_values */ EmacsFrameSetValues,
198 /* set_values_hook */ 0,
199 /* set_values_almost */ XtInheritSetValuesAlmost,
200 /* get_values_hook */ 0,
201 /* accept_focus */ XtInheritAcceptFocus,
202 /* version */ XtVersion,
203 /* callback_private */ 0,
204 /* tm_table */ emacsFrameTranslations,
205 /* query_geometry */ EmacsFrameQueryGeometry,
206 /* display_accelerator */ XtInheritDisplayAccelerator,
207 /* extension */ 0
208 },
209 #ifdef LWLIB_USES_MOTIF
210 { /* XmPrimitiveClassPart
211 */
212 (XtWidgetProc) _XtInherit, /* border_highlight */
213 (XtWidgetProc) _XtInherit, /* border_unhighlight */
214 /* Setting the following to NULL causes PrimitiveInitialize()
215 not to add traversal (TAB etc. to switch focus) and
216 focus-in/out (border highlight/unhighlight) translations.
217 If you want those translations, use the value XtInheritTranslations
218 instead. Doing this, however, will interfere with Emacs
219 focus handling (which highlights/unhighlights the text cursor),
220 and will lead to strange display results around the border of the
221 widget. */
222 NULL, /* translations */
223 NULL, /* arm_and_activate */
224 NULL, /* get resources */
225 0, /* num get_resources */
226 NULL, /* extension */
227 },
228 #endif /* LWLIB_USES_MOTIF */
229 {
230 0
231 }
232 };
233 WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
234
235 static void
236 update_various_frame_slots (EmacsFrame ew)
237 {
238 ew->emacs_frame.frame->pixheight = ew->core.height;
239 ew->emacs_frame.frame->pixwidth = ew->core.width;
240 ew->emacs_frame.frame->internal_border_width =
241 ew->emacs_frame.internal_border_width;
242 }
243
244 static void
245 EmacsFrameInitialize (Widget request, Widget new,
246 ArgList dum1, Cardinal *dum2)
247 {
248 EmacsFrame ew = (EmacsFrame)new;
249 struct frame *f = ew->emacs_frame.frame;
250
251 if (!f)
252 fatal ("can't create an emacs frame widget without a frame.");
253 }
254
255 void emacs_Xt_event_handler (Widget wid /* unused */,
256 XtPointer closure /* unused */,
257 XEvent *event,
258 Boolean *continue_to_dispatch /* unused */);
259
260 static void
261 EmacsFrameRealize (Widget widget, XtValueMask *mask,
262 XSetWindowAttributes *attrs)
263 {
264 EmacsFrame ew = (EmacsFrame) widget;
265 struct frame *f = ew->emacs_frame.frame;
266 Widget shell_widget = FRAME_X_SHELL_WIDGET (f);
267
268 attrs->event_mask = (ExposureMask |
269 StructureNotifyMask |
270 VisibilityChangeMask |
271 PropertyChangeMask |
272 StructureNotifyMask |
273 /*SubstructureNotifyMask |*/
274 /*SubstructureRedirectMask |*/ /* Only for WMs! */
275 KeyPressMask |
276 KeyReleaseMask |
277 ButtonPressMask |
278 ButtonReleaseMask |
279 FocusChangeMask |
280 PointerMotionHintMask |
281 PointerMotionMask |
282 LeaveWindowMask |
283 EnterWindowMask);
284
285 #ifdef I18N4
286 /* Make sure that events wanted by the input method are selected. */
287 attrs->event_mask |= input_method_event_mask;
288 #endif
289
290 *mask |= CWEventMask;
291
292 if (ew->emacs_frame.use_backing_store)
293 {
294 attrs->backing_store = Always;
295 *mask |= CWBackingStore;
296 }
297 XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
298 attrs);
299
300 /* snarf the events we want. */
301 XtInsertEventHandler (widget, attrs->event_mask, TRUE,
302 emacs_Xt_event_handler, NULL, XtListHead);
303 /* some events (e.g. map-notify and WM_DELETE_WINDOW) get sent
304 directly to the shell, and the above event handler won't see
305 them. So add a handler to get them. These events don't
306 propagate, so there's no danger of them being seen twice. */
307 XtInsertEventHandler (shell_widget,
308 EnterWindowMask | LeaveWindowMask |
309 VisibilityChangeMask | StructureNotifyMask |
310 KeyPressMask,
311 TRUE, emacs_Xt_event_handler, NULL, XtListHead);
312
313 #ifdef EXTERNAL_WIDGET
314 /* #### Not sure if this special case is necessary */
315 if (!FRAME_X_EXTERNAL_WINDOW_P (f))
316 #endif
317 /* This is necessary under Motif in order to make it possible to click in
318 a buffer and move focus out of a dialog box or control panel and back
319 into emacs-land; also necessary so that you can still type chars
320 if the cursor is over the menubar or scrollbar. */
321 lw_set_keyboard_focus (shell_widget, FRAME_X_TEXT_WIDGET (f));
322 }
323
324 /* DO NOT CALL THIS FUNCTION! Only Xt is supposed to do this. */
325
326 static void
327 EmacsFrameResize (Widget widget)
328 {
329 EmacsFrame ew = (EmacsFrame)widget;
330 struct frame *f = ew->emacs_frame.frame;
331 int columns;
332 int rows;
333 XtWidgetGeometry req, repl;
334
335 pixel_to_char_size (f, ew->core.width, ew->core.height, &columns, &rows);
336 update_various_frame_slots (ew);
337 change_frame_size (f, rows, columns, 0);
338
339 /* Now we tell the EmacsShell that we've changed the size of the non-fixed
340 portion of the frame. Note that, if we the resize occurred as a result
341 of EmacsFrameSetCharSize(), this information will be stored twice.
342 This is not a big deal, as storing this information doesn't actually
343 do anything until the next resize. */
344 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
345 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
346
347 /* Kick the manager so that it knows we've changed size. */
348 req.request_mode = 0;
349 XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
350 EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
351 repl.height);
352 }
353
354 static Boolean
355 EmacsFrameSetValues (Widget cur_widget, Widget req_widget, Widget new_widget,
356 ArgList dum1, Cardinal *dum2)
357 {
358 EmacsFrame cur = (EmacsFrame) cur_widget;
359 EmacsFrame new = (EmacsFrame) new_widget;
360 Lisp_Object frame = Qnil;
361
362 XSETFRAME (frame, new->emacs_frame.frame);
363 in_resource_setting++;
364 /* This function does not need to do much. Pretty much everything
365 interesting will get done in the resize method, which will
366 (if necessary) get called by Xt when this function returns
367 (see below).
368 */
369
370 /* #### This function will not work if it is not called from
371 update_EmacsFrame(), called from SET_FACE_PROPERTY().
372 The code located there should be moved inside of here instead,
373 so that things work if either SET_FACE_PROPERTY() is
374 called or XtSetValues() is called.
375 */
376
377 if (cur->emacs_frame.iconic != new->emacs_frame.iconic &&
378 FRAME_X_TOP_LEVEL_FRAME_P (new->emacs_frame.frame))
379 x_wm_set_shell_iconic_p (FRAME_X_SHELL_WIDGET (new->emacs_frame.frame),
380 new->emacs_frame.iconic);
381
382 if (!in_specifier_change_function)
383 {
384 /* If we got here, then we were likely called as a result of
385 the EditRes protocol, so go ahead and change scrollbar-width
386 and scrollbar-height. Otherwise, we're merely mirroring
387 a change made to scrollbar-width etc. so don't do anything
388 special. */
389 #ifdef HAVE_SCROLLBARS
390 if (cur->emacs_frame.scrollbar_width !=
391 new->emacs_frame.scrollbar_width)
392 Fadd_spec_to_specifier
393 (Vscrollbar_width,
394 make_int (new->emacs_frame.scrollbar_width),
395 frame, Qnil, Qnil);
396 if (cur->emacs_frame.scrollbar_height !=
397 new->emacs_frame.scrollbar_height)
398 Fadd_spec_to_specifier
399 (Vscrollbar_height,
400 make_int (new->emacs_frame.scrollbar_height),
401 frame, Qnil, Qnil);
402 #endif
403 #ifdef HAVE_TOOLBARS
404 if (cur->emacs_frame.top_toolbar_height !=
405 new->emacs_frame.top_toolbar_height)
406 Fadd_spec_to_specifier
407 (Vtoolbar_size[TOP_TOOLBAR],
408 make_int (new->emacs_frame.top_toolbar_height),
409 frame, Qnil, Qnil);
410 if (cur->emacs_frame.bottom_toolbar_height !=
411 new->emacs_frame.bottom_toolbar_height)
412 Fadd_spec_to_specifier
413 (Vtoolbar_size[BOTTOM_TOOLBAR],
414 make_int (new->emacs_frame.bottom_toolbar_height),
415 frame, Qnil, Qnil);
416 if (cur->emacs_frame.left_toolbar_width !=
417 new->emacs_frame.left_toolbar_width)
418 Fadd_spec_to_specifier
419 (Vtoolbar_size[LEFT_TOOLBAR],
420 make_int (new->emacs_frame.left_toolbar_width),
421 frame, Qnil, Qnil);
422 if (cur->emacs_frame.right_toolbar_width !=
423 new->emacs_frame.right_toolbar_width)
424 Fadd_spec_to_specifier
425 (Vtoolbar_size[RIGHT_TOOLBAR],
426 make_int (new->emacs_frame.right_toolbar_width),
427 frame, Qnil, Qnil);
428 #endif
429 }
430 in_resource_setting--;
431
432 return False;
433
434 /* Note that if either (a) we return True, or (b) the width or
435 height has changed, an Expose event will be generated. The Xt
436 manual says you should not return True if the width or height has
437 changed, because then two Expose events will be generated.
438
439 In any case, there is no need to return True because
440 SET_FACE_PROPERTY(), which does the resource
441 setting, automatically forces a redisplay as necessary. */
442 }
443
444 static XtGeometryResult
445 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
446 XtWidgetGeometry *result)
447 {
448 EmacsFrame ew = (EmacsFrame) widget;
449 int mask = request->request_mode;
450 Dimension width, height;
451 int ok_width_int, ok_height_int;
452 Dimension ok_width, ok_height;
453
454 /* We have a definite preference for what size we would like
455 to be.
456
457 1) If a preferred size was specified for us, use it.
458 (This is not currently used)
459 2) If a proposed size was given, round it to the nearest
460 multiple of the default char size and return it.
461 3) Otherwise, take our current size and round it to the
462 nearest multiple of the default char size. */
463
464 width = mask & CWWidth ? request->width : ew->core.width;
465 height = mask & CWHeight ? request->height : ew->core.height;
466 round_size_to_char (ew->emacs_frame.frame, width, height,
467 &ok_width_int, &ok_height_int);
468 ok_width = (Dimension) ok_width_int;
469 ok_height = (Dimension) ok_height_int;
470 if (ew->emacs_frame.preferred_width)
471 ok_width = ew->emacs_frame.preferred_width;
472 if (ew->emacs_frame.preferred_height)
473 ok_height = ew->emacs_frame.preferred_height;
474 result->request_mode |= CWWidth | CWHeight;
475 result->width = ok_width;
476 result->height = ok_height;
477 if (((mask & CWWidth) && ok_width != request->width)
478 || ((mask & CWHeight) && ok_height != request->height))
479 return XtGeometryAlmost;
480 else
481 return XtGeometryYes;
482 }
483 /**** string-to-scrollbar-placement converter: modelled after edge-type
484 converter in Xaw/Form.c ****/
485
486 #define done(address, type) \
487 toVal->size = sizeof(type); \
488 toVal->addr = (XtPointer) address; \
489 return /* `;' supplied by caller */
490
491 /* This variable cannot be a stack variable. */
492 static unsigned char cvt_string_scrollbar_placement;
493
494 /* ARGSUSED */
495 static void
496 _CvtStringToScrollBarPlacement (args, num_args, fromVal, toVal)
497 XrmValuePtr args; /* unused */
498 Cardinal *num_args; /* unused */
499 XrmValuePtr fromVal;
500 XrmValuePtr toVal;
501 {
502 XrmQuark q;
503 char lowerName[1000];
504
505 XmuCopyISOLatin1Lowered (lowerName, (char*)fromVal->addr);
506 q = XrmStringToQuark(lowerName);
507 if (q == XrmStringToQuark ("top_left"))
508 {
509 cvt_string_scrollbar_placement = XtTOP_LEFT;
510 done (&cvt_string_scrollbar_placement, unsigned char);
511 }
512 if (q == XrmStringToQuark ("bottom_left"))
513 {
514 cvt_string_scrollbar_placement = XtBOTTOM_LEFT;
515 done (&cvt_string_scrollbar_placement, unsigned char);
516 }
517 if (q == XrmStringToQuark ("top_right"))
518 {
519 cvt_string_scrollbar_placement = XtTOP_RIGHT;
520 done (&cvt_string_scrollbar_placement, unsigned char);
521 }
522 if (q == XrmStringToQuark ("bottom_right"))
523 {
524 cvt_string_scrollbar_placement = XtBOTTOM_RIGHT;
525 done (&cvt_string_scrollbar_placement, unsigned char);
526 }
527 XtStringConversionWarning (fromVal->addr, "scrollBarPlacement");
528 toVal->addr = NULL;
529 toVal->size = 0;
530 }
531
532 static void
533 EmacsFrameClassInitialize (void)
534 {
535 XtAddConverter (XtRString, XtRScrollBarPlacement,
536 _CvtStringToScrollBarPlacement, NULL, 0);
537 }
538
539 /********************* Special entrypoints *******************/
540
541 void
542 EmacsFrameRecomputeCellSize (Widget w)
543 {
544 EmacsFrame ew = (EmacsFrame) w;
545 int cw, ch;
546 struct frame *f = ew->emacs_frame.frame;
547
548 if (! XtIsSubclass (w, emacsFrameClass))
549 abort ();
550
551 default_face_height_and_width (make_frame (f), &ch, &cw);
552 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
553 x_wm_set_cell_size (FRAME_X_SHELL_WIDGET (f), cw, ch);
554 }
555
556 /* Set the size of the widget to have the number of rows and columns
557 specified. This both causes the X window to change and the
558 internal frame structures to get modified to match. */
559
560 void
561 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
562 {
563 EmacsFrame ew = (EmacsFrame) widget;
564 int pixel_width, pixel_height;
565 struct frame *f = ew->emacs_frame.frame;
566
567 if (columns < 3)
568 columns = 3; /* no way buddy */
569 if (rows < 1)
570 rows = 1;
571
572 char_to_pixel_size (f, columns, rows, &pixel_width, &pixel_height);
573
574 if (FRAME_X_TOP_LEVEL_FRAME_P (f))
575 x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
576
577 XtVaSetValues ((Widget) ew,
578 XtNwidth, (Dimension) pixel_width,
579 XtNheight, (Dimension) pixel_height,
580 0);
581 }