1 /* The emacs frame widget.
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* Emacs 19 face widget ported by Fred Pierresteguy */
29 #include "dispextern.h"
32 #include <X11/StringDefs.h>
33 #include <X11/IntrinsicP.h>
34 #include <X11/cursorfont.h>
35 #include "widgetprv.h"
36 #include <X11/ObjectP.h>
37 #include <X11/Shell.h>
38 #include <X11/ShellP.h>
40 #define max(a, b) ((a) > (b) ? (a) : (b))
42 /* This sucks: this is the first default that x-faces.el tries. This won't
43 be used unless neither the "Emacs.EmacsFrame" resource nor the
44 "Emacs.EmacsFrame" resource is set; the frame
45 may have the wrong default size if this font doesn't exist, but some other
46 font that x-faces.el does. The workaround is to specify some font in the
47 resource database; I don't know a solution other than duplicating the font-
48 searching code from x-faces.el in this file.
50 This also means that if "Emacs.EmacsFrame" is specified as a non-
51 existent font, then Xt is going to substitute "XtDefaultFont" for it,
52 which is a different size than this one. The solution for this is to
53 make x-faces.el try to use XtDefaultFont. The problem with that is that
54 XtDefaultFont is almost certainly variable-width.
56 #### Perhaps we could have this code explicitly set XtDefaultFont to this?
58 #define DEFAULT_FACE_FONT "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*"
61 static void EmacsFrameInitialize (/*Widget, Widget, ArgList, Cardinal * */);
62 static void EmacsFrameDestroy (/* Widget */);
63 static void EmacsFrameRealize (/* Widget, XtValueMask*, XSetWindowAttributes* */);
64 void EmacsFrameResize (/* Widget widget */);
65 static Boolean
EmacsFrameSetValues (/* Widget, Widget, Widget,
66 ArgList, Cardinal * */);
67 static XtGeometryResult
EmacsFrameQueryGeometry (/* Widget, XtWidgetGeometry*,
68 XtWidgetGeometry* */);
72 #define XtOffset(p_type,field) \
73 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
74 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
76 static XtResource resources
[] = {
77 {XtNgeometry
, XtCGeometry
, XtRString
, sizeof(String
),
78 offset (geometry
), XtRString
, (XtPointer
) 0},
79 {XtNiconic
, XtCIconic
, XtRBoolean
, sizeof(Boolean
),
80 offset (iconic
), XtRImmediate
, (XtPointer
) False
},
82 {XtNemacsFrame
, XtCEmacsFrame
, XtRPointer
, sizeof (XtPointer
),
83 offset (frame
), XtRImmediate
, 0},
85 {XtNminibuffer
, XtCMinibuffer
, XtRInt
, sizeof (int),
86 offset (minibuffer
), XtRImmediate
, (XtPointer
)0},
87 {XtNunsplittable
, XtCUnsplittable
, XtRBoolean
, sizeof (Boolean
),
88 offset (unsplittable
), XtRImmediate
, (XtPointer
)0},
89 {XtNinternalBorderWidth
, XtCInternalBorderWidth
, XtRInt
, sizeof (int),
90 offset (internal_border_width
), XtRImmediate
, (XtPointer
)4},
91 {XtNinterline
, XtCInterline
, XtRInt
, sizeof (int),
92 offset (interline
), XtRImmediate
, (XtPointer
)0},
93 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof(XFontStruct
*),
94 offset(font
),XtRString
, DEFAULT_FACE_FONT
},
95 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
96 offset(foreground_pixel
), XtRString
, "XtDefaultForeground"},
97 {XtNcursorColor
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
98 offset(cursor_color
), XtRString
, "XtDefaultForeground"},
99 {XtNbarCursor
, XtCBarCursor
, XtRBoolean
, sizeof (Boolean
),
100 offset (bar_cursor
), XtRImmediate
, (XtPointer
)0},
101 {XtNvisualBell
, XtCVisualBell
, XtRBoolean
, sizeof (Boolean
),
102 offset (visual_bell
), XtRImmediate
, (XtPointer
)0},
103 {XtNbellVolume
, XtCBellVolume
, XtRInt
, sizeof (int),
104 offset (bell_volume
), XtRImmediate
, (XtPointer
)0},
111 emacsFrameActionsTable [] = {
112 {"keypress", key_press},
113 {"focus_in", emacs_frame_focus_handler},
114 {"focus_out", emacs_frame_focus_handler},
118 emacsFrameTranslations [] = "\
119 <KeyPress>: keypress()\n\
120 <FocusIn>: focus_in()\n\
121 <FocusOut>: focus_out()\n\
125 EmacsFrameClassRec emacsFrameClassRec
= {
127 /* superclass */ &widgetClassRec
,
128 /* class_name */ "EmacsFrame",
129 /* widget_size */ sizeof(EmacsFrameRec
),
130 /* class_initialize */ 0,
131 /* class_part_initialize */ 0,
132 /* class_inited */ FALSE
,
133 /* initialize */ EmacsFrameInitialize
,
134 /* initialize_hook */ 0,
135 /* realize */ EmacsFrameRealize
,
136 /* actions */ 0, /*emacsFrameActionsTable*/
137 /* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
138 /* resources */ resources
,
139 /* resource_count */ XtNumber(resources
),
140 /* xrm_class */ NULLQUARK
,
141 /* compress_motion */ TRUE
,
142 /* compress_exposure */ TRUE
,
143 /* compress_enterleave */ TRUE
,
144 /* visible_interest */ FALSE
,
145 /* destroy */ EmacsFrameDestroy
,
146 /* resize */ EmacsFrameResize
,
147 /* expose */ XtInheritExpose
,
148 /* set_values */ EmacsFrameSetValues
,
149 /* set_values_hook */ 0,
150 /* set_values_almost */ XtInheritSetValuesAlmost
,
151 /* get_values_hook */ 0,
152 /* accept_focus */ XtInheritAcceptFocus
,
153 /* version */ XtVersion
,
154 /* callback_private */ 0,
155 /* tm_table */ 0, /*emacsFrameTranslations*/
156 /* query_geometry */ EmacsFrameQueryGeometry
,
157 /* display_accelerator */ XtInheritDisplayAccelerator
,
162 WidgetClass emacsFrameClass
= (WidgetClass
) &emacsFrameClassRec
;
165 get_default_char_pixel_size (ew
, pixel_width
, pixel_height
)
170 struct frame
* f
= ew
->emacs_frame
.frame
;
171 *pixel_width
= FONT_WIDTH (f
->display
.x
->font
);
172 *pixel_height
= f
->display
.x
->line_height
;
176 pixel_to_char_size (ew
, pixel_width
, pixel_height
, char_width
, char_height
)
178 Dimension pixel_width
;
179 Dimension pixel_height
;
183 struct frame
* f
= ew
->emacs_frame
.frame
;
184 *char_width
= PIXEL_TO_CHAR_WIDTH (f
, pixel_width
);
185 *char_height
= PIXEL_TO_CHAR_HEIGHT (f
, pixel_height
);
189 char_to_pixel_size (ew
, char_width
, char_height
, pixel_width
, pixel_height
)
193 Dimension
* pixel_width
;
194 Dimension
* pixel_height
;
196 struct frame
* f
= ew
->emacs_frame
.frame
;
197 *pixel_width
= CHAR_TO_PIXEL_WIDTH (f
, char_width
);
198 *pixel_height
= CHAR_TO_PIXEL_HEIGHT (f
, char_height
);
202 round_size_to_char (ew
, in_width
, in_height
, out_width
, out_height
)
206 Dimension
* out_width
;
207 Dimension
* out_height
;
211 pixel_to_char_size (ew
, in_width
, in_height
, &char_width
, &char_height
);
212 char_to_pixel_size (ew
, char_width
, char_height
, out_width
, out_height
);
221 for (wmshell
= XtParent (w
);
222 wmshell
&& !XtIsWMShell (wmshell
);
223 wmshell
= XtParent (wmshell
));
229 mark_shell_size_user_specified (wmshell
)
232 if (! XtIsWMShell (wmshell
)) abort ();
233 /* This is kind of sleazy, but I can't see how else to tell it to make it
234 mark the WM_SIZE_HINTS size as user specified when appropriate. */
235 ((WMShellWidget
) wmshell
)->wm
.size_hints
.flags
|= USSize
;
239 /* Can't have static frame locals because of some broken compilers.
240 Normally, initializing a variable like this doesn't work in emacs,
241 but it's ok in this file because it must come after lastfile (and
242 thus have its data not go into text space) because Xt needs to
243 write to initialized data objects too.
245 static Boolean first_frame_p
= True
;
251 /* The widget hierarchy is
253 argv[0] emacsShell pane Frame-NAME
254 ApplicationShell EmacsShell Paned EmacsFrame
256 We accept geometry specs in this order:
262 Other possibilities for widget hierarchies might be
264 argv[0] frame pane Frame-NAME
265 ApplicationShell EmacsShell Paned EmacsFrame
267 argv[0] Frame-NAME pane Frame-NAME
268 ApplicationShell EmacsShell Paned EmacsFrame
270 argv[0] Frame-NAME pane emacsTextPane
271 ApplicationShell EmacsFrame Paned EmacsTextPane
273 With the current setup, the text-display-area is the part which is
274 an emacs "frame", since that's the only part managed by emacs proper
275 (the menubar and the parent of the menubar and all that sort of thing
276 are managed by lwlib.)
278 The EmacsShell widget is simply a replacement for the Shell widget
279 which is able to deal with using an externally-supplied window instead
280 of always creating its own. It is not actually emacs specific, and
281 should possibly have class "Shell" instead of "EmacsShell" to simplify
286 /* Geometry of the AppShell */
290 unsigned int app_w
= 0;
291 unsigned int app_h
= 0;
293 /* Geometry of the EmacsFrame */
297 unsigned int frame_w
= 0;
298 unsigned int frame_h
= 0;
300 /* Hairily merged geometry */
303 unsigned int w
= ew
->emacs_frame
.frame
->width
;
304 unsigned int h
= ew
->emacs_frame
.frame
->height
;
307 Widget wmshell
= get_wm_shell ((Widget
) ew
);
308 Widget app_shell
= XtParent ((Widget
) wmshell
);
310 if (! XtIsSubclass (wmshell
, shellWidgetClass
)) abort ();
311 if (! XtIsSubclass (app_shell
, shellWidgetClass
)) abort ();
313 /* We don't need this for the momment. The geometry is computed in
316 /* If the EmacsFrame doesn't have a geometry but the shell does,
317 treat that as the geometry of the frame. (Is this bogus?
319 if (ew
->emacs_frame
.geometry
== 0)
320 XtVaGetValues (wmshell
, XtNgeometry
, &ew
->emacs_frame
.geometry
, 0);
322 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
323 this bogus? I'm not sure.) */
324 if (!ew
->emacs_frame
.iconic
)
325 XtVaGetValues (wmshell
, XtNiconic
, &ew
->emacs_frame
.iconic
, 0);
330 XtVaGetValues (app_shell
, XtNgeometry
, &geom
, 0);
332 app_flags
= XParseGeometry (geom
, &app_x
, &app_y
, &app_w
, &app_h
);
335 if (ew
->emacs_frame
.geometry
)
336 frame_flags
= XParseGeometry (ew
->emacs_frame
.geometry
,
342 /* If this is the first frame created:
343 ====================================
345 - Use the ApplicationShell's size/position, if specified.
346 (This is "Emacs.geometry", or the "-geometry" command line arg.)
347 - Else use the EmacsFrame's size/position.
348 (This is "*Frame-NAME.geometry")
350 - If the AppShell is iconic, the frame should be iconic.
352 AppShell comes first so that -geometry always applies to the first
353 frame created, even if there is an "every frame" entry in the
356 if (app_flags
& (XValue
| YValue
))
358 x
= app_x
; y
= app_y
;
359 flags
|= (app_flags
& (XValue
| YValue
| XNegative
| YNegative
));
361 else if (frame_flags
& (XValue
| YValue
))
363 x
= frame_x
; y
= frame_y
;
364 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
367 if (app_flags
& (WidthValue
| HeightValue
))
369 w
= app_w
; h
= app_h
;
370 flags
|= (app_flags
& (WidthValue
| HeightValue
));
372 else if (frame_flags
& (WidthValue
| HeightValue
))
374 w
= frame_w
; h
= frame_h
;
375 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
378 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
379 if (!ew
->emacs_frame
.iconic
)
380 XtVaGetValues (app_shell
, XtNiconic
, &ew
->emacs_frame
.iconic
, 0);
382 first_frame_p
= False
;
386 /* If this is not the first frame created:
387 ========================================
389 - use the EmacsFrame's size/position if specified
390 - Otherwise, use the ApplicationShell's size, but not position.
392 So that means that one can specify the position of the first frame
393 with "Emacs.geometry" or `-geometry'; but can only specify the
394 position of subsequent frames with "*Frame-NAME.geometry".
396 AppShell comes second so that -geometry does not apply to subsequent
397 frames when there is an "every frame" entry in the resource db,
398 but does apply to the first frame.
400 if (frame_flags
& (XValue
| YValue
))
402 x
= frame_x
; y
= frame_y
;
403 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
406 if (frame_flags
& (WidthValue
| HeightValue
))
408 w
= frame_w
; h
= frame_h
;
409 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
411 else if (app_flags
& (WidthValue
| HeightValue
))
415 flags
|= (app_flags
& (WidthValue
| HeightValue
));
420 struct frame
* frame
= ew
->emacs_frame
.frame
;
421 Dimension pixel_width
, pixel_height
;
422 char shell_position
[32];
424 /* Take into account the size of the scrollbar */
425 frame
->display
.x
->vertical_scroll_bar_extra
426 = (FRAME_HAS_VERTICAL_SCROLL_BARS (frame
)
427 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (frame
)
431 change_frame_size (frame
, h
, w
, 1, 0);
432 char_to_pixel_size (ew
, w
, h
, &pixel_width
, &pixel_height
);
433 ew
->core
.width
= pixel_width
;
434 ew
->core
.height
= pixel_height
;
436 #if 0 /* xfns.c takes care of this now. */
437 /* If a position was specified, assign it to the shell widget.
438 (Else WM won't do anything with it.)
440 if (flags
& (XValue
| YValue
))
442 /* the tricky things with the sign is to make sure that
446 sprintf (shell_position
, "=%c%d%c%d",
447 flags
& XNegative
? '-' : '+', x
< 0 ? -x
: x
,
448 flags
& YNegative
? '-' : '+', y
< 0 ? -y
: y
);
449 len
= strlen (shell_position
) + 1;
450 tem
= (char *) xmalloc (len
);
451 strncpy (tem
, shell_position
, len
);
452 XtVaSetValues (wmshell
, XtNgeometry
, tem
, 0);
454 else if (flags
& (WidthValue
| HeightValue
))
458 sprintf (shell_position
, "=%dx%d", pixel_width
, pixel_height
);
459 len
= strlen (shell_position
) + 1;
460 tem
= (char *) xmalloc (len
);
461 strncpy (tem
, shell_position
, len
);
462 XtVaSetValues (wmshell
, XtNgeometry
, tem
, 0);
465 /* If the geometry spec we're using has W/H components, mark the size
466 in the WM_SIZE_HINTS as user specified. */
467 if (flags
& (WidthValue
| HeightValue
))
468 mark_shell_size_user_specified (wmshell
);
470 /* Also assign the iconic status of the frame to the Shell, so that
472 XtVaSetValues (wmshell
, XtNiconic
, ew
->emacs_frame
.iconic
, 0);
482 Widget wmshell
= get_wm_shell ((Widget
)ew
);
485 Dimension rounded_width
;
486 Dimension rounded_height
;
491 int min_rows
= 0, min_cols
= 0;
493 check_frame_size (ew
->emacs_frame
.frame
, &min_rows
, &min_cols
);
495 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
,
496 &char_width
, &char_height
);
497 char_to_pixel_size (ew
, char_width
, char_height
,
498 &rounded_width
, &rounded_height
);
499 get_default_char_pixel_size (ew
, &cw
, &ch
);
501 base_width
= (wmshell
->core
.width
- ew
->core
.width
502 + (rounded_width
- (char_width
* cw
)));
503 base_height
= (wmshell
->core
.height
- ew
->core
.height
504 + (rounded_height
- (char_height
* ch
)));
506 /* This is kind of sleazy, but I can't see how else to tell it to
507 make it mark the WM_SIZE_HINTS size as user specified.
509 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
511 XtVaSetValues (wmshell
,
512 XtNbaseWidth
, base_width
,
513 XtNbaseHeight
, base_height
,
516 XtNminWidth
, base_width
+ min_cols
* cw
,
517 XtNminHeight
, base_height
+ min_rows
* ch
,
522 create_frame_gcs (ew
)
525 struct frame
* s
= ew
->emacs_frame
.frame
;
527 s
->display
.x
->normal_gc
=
528 XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)), 0, 0);
529 s
->display
.x
->reverse_gc
=
530 XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)), 0, 0);
531 s
->display
.x
->cursor_gc
=
532 XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)), 0, 0);
535 static char setup_frame_cursor_bits
[] =
537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
548 struct frame
* s
= ew
->emacs_frame
.frame
;
549 Pixmap blank_stipple
, blank_tile
;
551 /* We have to initialize all of our GCs to have a stipple/tile, otherwise
552 XGetGCValues returns uninitialized data when we query the stipple
553 (instead of None or something sensible) and it makes things hard.
555 This should be fixed for real by not querying the GCs but instead having
556 some GC-based cache instead of the current face-based cache which doesn't
557 effectively cache all of the GC settings we need to use.
561 XCreateBitmapFromData (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
562 setup_frame_cursor_bits
, 2, 2);
564 /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
565 never actually get used as a background tile!
568 XCreatePixmapFromBitmapData (XtDisplay(ew
),
569 RootWindowOfScreen (XtScreen (ew
)),
570 setup_frame_cursor_bits
, 2, 2, 0, 1,
574 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
575 gc_values
.foreground
= ew
->emacs_frame
.foreground_pixel
;
576 gc_values
.background
= ew
->core
.background_pixel
;
577 gc_values
.graphics_exposures
= False
;
578 gc_values
.stipple
= blank_stipple
;
579 gc_values
.tile
= blank_tile
;
580 XChangeGC (XtDisplay (ew
), s
->display
.x
->normal_gc
,
581 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
582 | GCStipple
| GCTile
),
585 /* Reverse video style. */
586 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
587 gc_values
.foreground
= ew
->core
.background_pixel
;
588 gc_values
.background
= ew
->emacs_frame
.foreground_pixel
;
589 gc_values
.graphics_exposures
= False
;
590 gc_values
.stipple
= blank_stipple
;
591 gc_values
.tile
= blank_tile
;
592 XChangeGC (XtDisplay (ew
), s
->display
.x
->reverse_gc
,
593 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
594 | GCStipple
| GCTile
),
597 /* Cursor has to have an empty stipple. */
598 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
599 gc_values
.foreground
= ew
->core
.background_pixel
;
600 gc_values
.background
= ew
->emacs_frame
.cursor_color
;
601 gc_values
.graphics_exposures
= False
;
602 gc_values
.tile
= blank_tile
;
604 XCreateBitmapFromData (XtDisplay (ew
),
605 RootWindowOfScreen (XtScreen (ew
)),
606 setup_frame_cursor_bits
, 16, 16);
607 XChangeGC (XtDisplay (ew
), s
->display
.x
->cursor_gc
,
608 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
609 | GCStipple
| GCTile
),
614 update_various_frame_slots (ew
)
617 struct x_display
* x
= ew
->emacs_frame
.frame
->display
.x
;
618 x
->pixel_height
= ew
->core
.height
;
619 x
->pixel_width
= ew
->core
.width
;
620 x
->internal_border_width
= ew
->emacs_frame
.internal_border_width
;
625 update_from_various_frame_slots (ew
)
628 struct x_display
* x
= ew
->emacs_frame
.frame
->display
.x
;
629 ew
->core
.height
= x
->pixel_height
;
630 ew
->core
.width
= x
->pixel_width
;
631 ew
->core
.background_pixel
= x
->background_pixel
;
632 ew
->emacs_frame
.internal_border_width
= x
->internal_border_width
;
633 ew
->emacs_frame
.font
= x
->font
;
634 ew
->emacs_frame
.foreground_pixel
= x
->foreground_pixel
;
635 ew
->emacs_frame
.cursor_color
= x
->cursor_pixel
;
636 ew
->core
.border_pixel
= x
->border_pixel
;
640 EmacsFrameInitialize (request
, new, dum1
, dum2
)
646 EmacsFrame ew
= (EmacsFrame
)new;
648 if (!ew
->emacs_frame
.frame
)
651 "can't create an emacs frame widget without a frame\n");
655 #if 0 /* done in xfns.c */
656 /* If the "Emacs.EmacsFrame.{default,Face}.{attributeFont,AttributeFont}"
657 resource is set, then it always overrides "Emacs.EmacsFrame.{font,Font}".
658 It's unfortunate that we have to do this, but we need to know the font
659 size for frame-sizing purposes before the faces get initialized. If
660 the "default.attributeFont" isn't set, then we use the font of this
661 EmacsFrame itself, defaulting to XtDefaultFont. Up in the lisp code,
662 the "default" face will use the frame's font if its own is not set,
663 so everything stays in sync -- it's not possible for the frame's font
664 and the default face's font to be different.
669 face_res
.resource_name
= "attributeFont";
670 face_res
.resource_class
= "AttributeFont";
671 face_res
.resource_type
= XtRFontStruct
;
672 face_res
.resource_size
= sizeof (XFontStruct
*);
673 face_res
.resource_offset
= 0;
674 face_res
.default_type
= XtRImmediate
;
675 face_res
.default_addr
= 0;
676 XtGetSubresources ((Widget
) ew
, (XtPointer
) &f
, "default", "Face",
677 &face_res
, 1, NULL
, 0);
680 ew
->emacs_frame
.font
= f
;
681 else if (! ew
->emacs_frame
.font
)
683 fprintf (stderr
, "emacs frame widget could not load a font\n");
688 /* Update the font field in frame */
689 ew
->emacs_frame
.frame
->display
.x
->font
= ew
->emacs_frame
.font
;
692 update_from_various_frame_slots (ew
);
694 /*create_frame_gcs (ew);
695 setup_frame_gcs (ew);
696 update_various_frame_slots (ew); */
701 EmacsFrameRealize (widget
, mask
, attrs
)
704 XSetWindowAttributes
*attrs
;
706 EmacsFrame ew
= (EmacsFrame
)widget
;
708 attrs
->event_mask
= (KeyPressMask
| ExposureMask
| ButtonPressMask
|
709 ButtonReleaseMask
| StructureNotifyMask
|
710 FocusChangeMask
| PointerMotionHintMask
|
711 PointerMotionMask
| LeaveWindowMask
| EnterWindowMask
|
712 VisibilityChangeMask
| PropertyChangeMask
|
713 StructureNotifyMask
| SubstructureNotifyMask
|
714 SubstructureRedirectMask
);
715 *mask
|= CWEventMask
;
716 XtCreateWindow (widget
, InputOutput
, (Visual
*)CopyFromParent
, *mask
,
718 update_wm_hints (ew
);
721 extern void free_frame_faces (/* struct frame * */);
724 EmacsFrameDestroy (widget
)
727 EmacsFrame ew
= (EmacsFrame
) widget
;
728 struct frame
* s
= ew
->emacs_frame
.frame
;
731 if (! s
->display
.x
) abort ();
732 if (! s
->display
.x
->normal_gc
) abort ();
734 /* this would be called from Fdelete_frame() but it needs to free some
735 stuff after the widget has been finalized but before the widget has
737 free_frame_faces (s
);
739 /* need to be careful that the face-freeing code doesn't free these too */
740 XFreeGC (XtDisplay (widget
), s
->display
.x
->normal_gc
);
741 XFreeGC (XtDisplay (widget
), s
->display
.x
->reverse_gc
);
742 XFreeGC (XtDisplay (widget
), s
->display
.x
->cursor_gc
);
746 EmacsFrameResize (widget
)
749 EmacsFrame ew
= (EmacsFrame
)widget
;
750 struct frame
*f
= ew
->emacs_frame
.frame
;
754 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
, &columns
, &rows
);
755 change_frame_size (f
, rows
, columns
, 1, 0);
756 update_wm_hints (ew
);
757 update_various_frame_slots (ew
);
761 EmacsFrameSetValues (cur_widget
, req_widget
, new_widget
, dum1
, dum2
)
768 EmacsFrame cur
= (EmacsFrame
)cur_widget
;
769 EmacsFrame
new = (EmacsFrame
)new_widget
;
771 Boolean needs_a_refresh
= False
;
772 Boolean has_to_recompute_size
;
773 Boolean has_to_recompute_gcs
;
774 Boolean has_to_update_hints
;
776 int char_width
, char_height
;
777 Dimension pixel_width
;
778 Dimension pixel_height
;
780 has_to_recompute_gcs
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
781 || (cur
->emacs_frame
.foreground_pixel
782 != new->emacs_frame
.foreground_pixel
)
783 || (cur
->core
.background_pixel
784 != new->core
.background_pixel
)
787 has_to_recompute_size
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
788 && cur
->core
.width
== new->core
.width
789 && cur
->core
.height
== new->core
.height
);
791 has_to_update_hints
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
);
793 if (has_to_recompute_gcs
)
795 setup_frame_gcs (new);
796 needs_a_refresh
= True
;
799 if (has_to_recompute_size
)
801 pixel_width
= new->core
.width
;
802 pixel_height
= new->core
.height
;
803 pixel_to_char_size (new, pixel_width
, pixel_height
, &char_width
,
805 char_to_pixel_size (new, char_width
, char_height
, &pixel_width
,
807 new->core
.width
= pixel_width
;
808 new->core
.height
= pixel_height
;
810 change_frame_size (new->emacs_frame
.frame
, char_height
, char_width
,
812 needs_a_refresh
= True
;
815 if (has_to_update_hints
)
816 update_wm_hints (new);
818 update_various_frame_slots (new);
820 /* #### This doesn't work, I haven't been able to find ANY kludge that
821 will let (x-create-frame '((iconic . t))) work. It seems that changes
822 to wm_shell's iconic slot have no effect after it has been realized,
823 and calling XIconifyWindow doesn't work either (even thought the window
824 has been created.) Perhaps there is some property we could smash
825 directly, but I'm sick of this for now. Xt is a steaming pile of shit!
827 if (cur
->emacs_frame
.iconic
!= new->emacs_frame
.iconic
)
829 Widget wmshell
= get_wm_shell ((Widget
) cur
);
830 XtVaSetValues (wmshell
, XtNiconic
, new->emacs_frame
.iconic
, 0);
833 return needs_a_refresh
;
836 static XtGeometryResult
837 EmacsFrameQueryGeometry (widget
, request
, result
)
839 XtWidgetGeometry
* request
;
840 XtWidgetGeometry
* result
;
842 EmacsFrame ew
= (EmacsFrame
)widget
;
844 int mask
= request
->request_mode
;
845 Dimension ok_width
, ok_height
;
847 if (mask
& (CWWidth
| CWHeight
))
849 round_size_to_char (ew
,
850 (mask
& CWWidth
) ? request
->width
: ew
->core
.width
,
851 ((mask
& CWHeight
) ? request
->height
853 &ok_width
, &ok_height
);
854 if ((mask
& CWWidth
) && (ok_width
!= request
->width
))
856 result
->request_mode
|= CWWidth
;
857 result
->width
= ok_width
;
859 if ((mask
& CWHeight
) && (ok_height
!= request
->height
))
861 result
->request_mode
|= CWHeight
;
862 result
->height
= ok_height
;
865 return result
->request_mode
? XtGeometryAlmost
: XtGeometryYes
;
868 /* Special entrypoints */
870 EmacsFrameSetCharSize (widget
, columns
, rows
)
875 EmacsFrame ew
= (EmacsFrame
) widget
;
876 Dimension pixel_width
, pixel_height
, granted_width
, granted_height
;
877 XtGeometryResult result
;
878 struct frame
*f
= ew
->emacs_frame
.frame
;
882 if (columns
< 3) columns
= 3; /* no way buddy */
883 if (rows
< 3) rows
= 3;
885 check_frame_size (f
, &rows
, &columns
);
886 f
->display
.x
->vertical_scroll_bar_extra
887 = (FRAME_HAS_VERTICAL_SCROLL_BARS (f
)
888 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (f
)
890 char_to_pixel_size (ew
, columns
, rows
, &pixel_width
, &pixel_height
);
892 /* Recompute the entire geometry management. */
893 if (ew
->core
.width
!= pixel_width
|| ew
->core
.height
!= pixel_height
)
895 int hdelta
= pixel_height
- ew
->core
.height
;
896 int column_widget_height
= f
->display
.x
->column_widget
->core
.height
;
897 int old_left
= f
->display
.x
->widget
->core
.x
;
898 int old_top
= f
->display
.x
->widget
->core
.y
;
900 XawPanedSetRefigureMode (f
->display
.x
->column_widget
, False
);
903 XtSetArg (al
[ac
], XtNheight
, pixel_height
); ac
++;
904 XtSetArg (al
[ac
], XtNwidth
, pixel_width
); ac
++;
905 XtSetValues ((Widget
) ew
, al
, ac
);
908 XtSetArg (al
[ac
], XtNheight
, column_widget_height
+ hdelta
); ac
++;
909 XtSetArg (al
[ac
], XtNwidth
, pixel_width
); ac
++;
910 XtSetValues (f
->display
.x
->column_widget
, al
, ac
);
912 XawPanedSetRefigureMode (f
->display
.x
->column_widget
, True
);
914 /* These seem to get clobbered. I don't know why. - rms. */
915 f
->display
.x
->widget
->core
.x
= old_left
;
916 f
->display
.x
->widget
->core
.y
= old_top
;
919 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
920 receive in the ConfigureNotify event; if we get what we asked
921 for, then the event won't cause the screen to become garbaged, so
922 we have to make sure to do it here. */
923 SET_FRAME_GARBAGED (f
);