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
= FONT_HEIGHT (f
->display
.x
->font
);
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
);
311 if (! XtIsSubclass (wmshell
, shellWidgetClass
)) abort ();
312 if (! XtIsSubclass (app_shell
, shellWidgetClass
)) abort ();
314 /* If the EmacsFrame doesn't have a geometry but the shell does,
315 treat that as the geometry of the frame. (Is this bogus?
317 if (ew
->emacs_frame
.geometry
== 0)
318 XtVaGetValues (wmshell
, XtNgeometry
, &ew
->emacs_frame
.geometry
, 0);
320 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
321 this bogus? I'm not sure.) */
322 if (!ew
->emacs_frame
.iconic
)
323 XtVaGetValues (wmshell
, XtNiconic
, &ew
->emacs_frame
.iconic
, 0);
328 XtVaGetValues (app_shell
, XtNgeometry
, &geom
, 0);
330 app_flags
= XParseGeometry (geom
, &app_x
, &app_y
, &app_w
, &app_h
);
333 if (ew
->emacs_frame
.geometry
)
334 frame_flags
= XParseGeometry (ew
->emacs_frame
.geometry
,
340 /* If this is the first frame created:
341 ====================================
343 - Use the ApplicationShell's size/position, if specified.
344 (This is "Emacs.geometry", or the "-geometry" command line arg.)
345 - Else use the EmacsFrame's size/position.
346 (This is "*Frame-NAME.geometry")
348 - If the AppShell is iconic, the frame should be iconic.
350 AppShell comes first so that -geometry always applies to the first
351 frame created, even if there is an "every frame" entry in the
354 if (app_flags
& (XValue
| YValue
))
356 x
= app_x
; y
= app_y
;
357 flags
|= (app_flags
& (XValue
| YValue
| XNegative
| YNegative
));
359 else if (frame_flags
& (XValue
| YValue
))
361 x
= frame_x
; y
= frame_y
;
362 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
365 if (app_flags
& (WidthValue
| HeightValue
))
367 w
= app_w
; h
= app_h
;
368 flags
|= (app_flags
& (WidthValue
| HeightValue
));
370 else if (frame_flags
& (WidthValue
| HeightValue
))
372 w
= frame_w
; h
= frame_h
;
373 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
376 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
377 if (!ew
->emacs_frame
.iconic
)
378 XtVaGetValues (app_shell
, XtNiconic
, &ew
->emacs_frame
.iconic
, 0);
380 first_frame_p
= False
;
384 /* If this is not the first frame created:
385 ========================================
387 - use the EmacsFrame's size/position if specified
388 - Otherwise, use the ApplicationShell's size, but not position.
390 So that means that one can specify the position of the first frame
391 with "Emacs.geometry" or `-geometry'; but can only specify the
392 position of subsequent frames with "*Frame-NAME.geometry".
394 AppShell comes second so that -geometry does not apply to subsequent
395 frames when there is an "every frame" entry in the resource db,
396 but does apply to the first frame.
398 if (frame_flags
& (XValue
| YValue
))
400 x
= frame_x
; y
= frame_y
;
401 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
404 if (frame_flags
& (WidthValue
| HeightValue
))
406 w
= frame_w
; h
= frame_h
;
407 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
409 else if (app_flags
& (WidthValue
| HeightValue
))
413 flags
|= (app_flags
& (WidthValue
| HeightValue
));
418 struct frame
* frame
= ew
->emacs_frame
.frame
;
419 Dimension pixel_width
, pixel_height
;
420 char shell_position
[32];
422 /* Take into account the size of the scrollbar */
423 frame
->display
.x
->vertical_scroll_bar_extra
424 = (FRAME_HAS_VERTICAL_SCROLL_BARS (frame
)
425 ? VERTICAL_SCROLL_BAR_PIXEL_WIDTH (frame
)
429 change_frame_size (frame
, h
, w
, 1, 0);
430 char_to_pixel_size (ew
, w
, h
, &pixel_width
, &pixel_height
);
431 ew
->core
.width
= pixel_width
;
432 ew
->core
.height
= pixel_height
;
435 /* If a position was specified, assign it to the shell widget.
436 (Else WM won't do anything with it.)
438 if (flags
& (XValue
| YValue
))
440 /* the tricky things with the sign is to make sure that
444 sprintf (shell_position
, "=%c%d%c%d",
445 flags
& XNegative
? '-' : '+', x
< 0 ? -x
: x
,
446 flags
& YNegative
? '-' : '+', y
< 0 ? -y
: y
);
447 len
= strlen (shell_position
) + 1;
448 tem
= (char *) xmalloc (len
);
449 strncpy (tem
, shell_position
, len
);
450 XtVaSetValues (wmshell
, XtNgeometry
, tem
, 0);
452 else if (flags
& (WidthValue
| HeightValue
))
456 sprintf (shell_position
, "=%dx%d", pixel_width
, pixel_height
);
457 len
= strlen (shell_position
) + 1;
458 tem
= (char *) xmalloc (len
);
459 strncpy (tem
, shell_position
, len
);
460 XtVaSetValues (wmshell
, XtNgeometry
, tem
, 0);
463 /* If the geometry spec we're using has W/H components, mark the size
464 in the WM_SIZE_HINTS as user specified. */
465 if (flags
& (WidthValue
| HeightValue
))
466 mark_shell_size_user_specified (wmshell
);
468 /* Also assign the iconic status of the frame to the Shell, so that
470 XtVaSetValues (wmshell
, XtNiconic
, ew
->emacs_frame
.iconic
, 0);
479 Widget wmshell
= get_wm_shell ((Widget
)ew
);
482 Dimension rounded_width
;
483 Dimension rounded_height
;
488 int min_rows
= 0, min_cols
= 0;
490 check_frame_size (ew
->emacs_frame
.frame
, &min_rows
, &min_cols
);
492 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
,
493 &char_width
, &char_height
);
494 char_to_pixel_size (ew
, char_width
, char_height
,
495 &rounded_width
, &rounded_height
);
496 get_default_char_pixel_size (ew
, &cw
, &ch
);
498 base_width
= (wmshell
->core
.width
- ew
->core
.width
499 + (rounded_width
- (char_width
* cw
)));
500 base_height
= (wmshell
->core
.height
- ew
->core
.height
501 + (rounded_height
- (char_height
* ch
)));
503 /* This is kind of sleazy, but I can't see how else to tell it to
504 make it mark the WM_SIZE_HINTS size as user specified.
506 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
508 XtVaSetValues (wmshell
,
509 XtNbaseWidth
, base_width
,
510 XtNbaseHeight
, base_height
,
513 XtNminWidth
, base_width
+ min_cols
* cw
,
514 XtNminHeight
, base_height
+ min_rows
* ch
,
519 create_frame_gcs (ew
)
522 struct frame
* s
= ew
->emacs_frame
.frame
;
524 s
->display
.x
->normal_gc
=
525 XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)), 0, 0);
526 s
->display
.x
->reverse_gc
=
527 XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)), 0, 0);
528 s
->display
.x
->cursor_gc
=
529 XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)), 0, 0);
537 struct frame
* s
= ew
->emacs_frame
.frame
;
538 Pixmap blank_stipple
, blank_tile
;
540 static char cursor_bits
[] =
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
548 /* We have to initialize all of our GCs to have a stipple/tile, otherwise
549 XGetGCValues returns uninitialized data when we query the stipple
550 (instead of None or something sensible) and it makes things hard.
552 This should be fixed for real by not querying the GCs but instead having
553 some GC-based cache instead of the current face-based cache which doesn't
554 effectively cache all of the GC settings we need to use.
558 XCreateBitmapFromData (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
561 /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
562 never actually get used as a background tile!
565 XCreatePixmapFromBitmapData (XtDisplay(ew
),
566 RootWindowOfScreen (XtScreen (ew
)),
567 cursor_bits
, 2, 2, 0, 1, ew
->core
.depth
);
570 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
571 gc_values
.foreground
= ew
->emacs_frame
.foreground_pixel
;
572 gc_values
.background
= ew
->core
.background_pixel
;
573 gc_values
.graphics_exposures
= False
;
574 gc_values
.stipple
= blank_stipple
;
575 gc_values
.tile
= blank_tile
;
576 XChangeGC (XtDisplay (ew
), s
->display
.x
->normal_gc
,
577 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
578 | GCStipple
| GCTile
),
581 /* Reverse video style. */
582 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
583 gc_values
.foreground
= ew
->core
.background_pixel
;
584 gc_values
.background
= ew
->emacs_frame
.foreground_pixel
;
585 gc_values
.graphics_exposures
= False
;
586 gc_values
.stipple
= blank_stipple
;
587 gc_values
.tile
= blank_tile
;
588 XChangeGC (XtDisplay (ew
), s
->display
.x
->reverse_gc
,
589 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
590 | GCStipple
| GCTile
),
593 /* Cursor has to have an empty stipple. */
594 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
595 gc_values
.foreground
= ew
->core
.background_pixel
;
596 gc_values
.background
= ew
->emacs_frame
.cursor_color
;
597 gc_values
.graphics_exposures
= False
;
598 gc_values
.tile
= blank_tile
;
600 XCreateBitmapFromData (XtDisplay (ew
),
601 RootWindowOfScreen (XtScreen (ew
)),
602 cursor_bits
, 16, 16);
603 XChangeGC (XtDisplay (ew
), s
->display
.x
->cursor_gc
,
604 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
605 | GCStipple
| GCTile
),
610 update_various_frame_slots (ew
)
613 struct x_display
* x
= ew
->emacs_frame
.frame
->display
.x
;
614 x
->pixel_height
= ew
->core
.height
;
615 x
->pixel_width
= ew
->core
.width
;
616 x
->internal_border_width
= ew
->emacs_frame
.internal_border_width
;
621 update_from_various_frame_slots (ew
)
624 struct x_display
* x
= ew
->emacs_frame
.frame
->display
.x
;
625 ew
->core
.height
= x
->pixel_height
;
626 ew
->core
.width
= x
->pixel_width
;
627 ew
->core
.background_pixel
= x
->background_pixel
;
628 ew
->emacs_frame
.internal_border_width
= x
->internal_border_width
;
629 ew
->emacs_frame
.font
= x
->font
;
630 ew
->emacs_frame
.foreground_pixel
= x
->foreground_pixel
;
631 ew
->emacs_frame
.cursor_color
= x
->cursor_pixel
;
632 ew
->core
.border_pixel
= x
->border_pixel
;
636 EmacsFrameInitialize (request
, new, dum1
, dum2
)
642 EmacsFrame ew
= (EmacsFrame
)new;
644 if (!ew
->emacs_frame
.frame
)
647 "can't create an emacs frame widget without a frame\n");
651 #if 0 /* done in xfns.c */
652 /* If the "Emacs.EmacsFrame.{default,Face}.{attributeFont,AttributeFont}"
653 resource is set, then it always overrides "Emacs.EmacsFrame.{font,Font}".
654 It's unfortunate that we have to do this, but we need to know the font
655 size for frame-sizing purposes before the faces get initialized. If
656 the "default.attributeFont" isn't set, then we use the font of this
657 EmacsFrame itself, defaulting to XtDefaultFont. Up in the lisp code,
658 the "default" face will use the frame's font if its own is not set,
659 so everything stays in sync -- it's not possible for the frame's font
660 and the default face's font to be different.
665 face_res
.resource_name
= "attributeFont";
666 face_res
.resource_class
= "AttributeFont";
667 face_res
.resource_type
= XtRFontStruct
;
668 face_res
.resource_size
= sizeof (XFontStruct
*);
669 face_res
.resource_offset
= 0;
670 face_res
.default_type
= XtRImmediate
;
671 face_res
.default_addr
= 0;
672 XtGetSubresources ((Widget
) ew
, (XtPointer
) &f
, "default", "Face",
673 &face_res
, 1, NULL
, 0);
676 ew
->emacs_frame
.font
= f
;
677 else if (! ew
->emacs_frame
.font
)
679 fprintf (stderr
, "emacs frame widget could not load a font\n");
684 /* Update the font field in frame */
685 ew
->emacs_frame
.frame
->display
.x
->font
= ew
->emacs_frame
.font
;
688 update_from_various_frame_slots (ew
);
690 /*create_frame_gcs (ew);
691 setup_frame_gcs (ew);
692 update_various_frame_slots (ew); */
697 EmacsFrameRealize (widget
, mask
, attrs
)
700 XSetWindowAttributes
*attrs
;
702 EmacsFrame ew
= (EmacsFrame
)widget
;
704 attrs
->event_mask
= (KeyPressMask
| ExposureMask
| ButtonPressMask
|
705 ButtonReleaseMask
| StructureNotifyMask
|
706 FocusChangeMask
| PointerMotionHintMask
|
707 PointerMotionMask
| LeaveWindowMask
| EnterWindowMask
|
708 VisibilityChangeMask
| PropertyChangeMask
|
709 StructureNotifyMask
| SubstructureNotifyMask
|
710 SubstructureRedirectMask
);
711 *mask
|= CWEventMask
;
712 XtCreateWindow (widget
, InputOutput
, (Visual
*)CopyFromParent
, *mask
,
714 update_wm_hints (ew
);
717 extern void free_frame_faces (/* struct frame * */);
720 EmacsFrameDestroy (widget
)
723 EmacsFrame ew
= (EmacsFrame
) widget
;
724 struct frame
* s
= ew
->emacs_frame
.frame
;
727 if (! s
->display
.x
) abort ();
728 if (! s
->display
.x
->normal_gc
) abort ();
730 /* this would be called from Fdelete_frame() but it needs to free some
731 stuff after the widget has been finalized but before the widget has
733 free_frame_faces (s
);
735 /* need to be careful that the face-freeing code doesn't free these too */
736 XFreeGC (XtDisplay (widget
), s
->display
.x
->normal_gc
);
737 XFreeGC (XtDisplay (widget
), s
->display
.x
->reverse_gc
);
738 XFreeGC (XtDisplay (widget
), s
->display
.x
->cursor_gc
);
742 EmacsFrameResize (widget
)
745 EmacsFrame ew
= (EmacsFrame
)widget
;
746 struct frame
*f
= ew
->emacs_frame
.frame
;
750 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
, &columns
, &rows
);
751 change_frame_size (f
, rows
, columns
, 1, 0);
752 update_wm_hints (ew
);
753 update_various_frame_slots (ew
);
757 EmacsFrameSetValues (cur_widget
, req_widget
, new_widget
, dum1
, dum2
)
764 EmacsFrame cur
= (EmacsFrame
)cur_widget
;
765 EmacsFrame
new = (EmacsFrame
)new_widget
;
767 Boolean needs_a_refresh
= False
;
768 Boolean has_to_recompute_size
;
769 Boolean has_to_recompute_gcs
;
770 Boolean has_to_update_hints
;
772 int char_width
, char_height
;
773 Dimension pixel_width
;
774 Dimension pixel_height
;
776 has_to_recompute_gcs
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
777 || (cur
->emacs_frame
.foreground_pixel
778 != new->emacs_frame
.foreground_pixel
)
779 || (cur
->core
.background_pixel
780 != new->core
.background_pixel
)
783 has_to_recompute_size
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
784 && cur
->core
.width
== new->core
.width
785 && cur
->core
.height
== new->core
.height
);
787 has_to_update_hints
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
);
789 if (has_to_recompute_gcs
)
791 setup_frame_gcs (new);
792 needs_a_refresh
= True
;
795 if (has_to_recompute_size
)
797 pixel_width
= new->core
.width
;
798 pixel_height
= new->core
.height
;
799 pixel_to_char_size (new, pixel_width
, pixel_height
, &char_width
,
801 char_to_pixel_size (new, char_width
, char_height
, &pixel_width
,
803 new->core
.width
= pixel_width
;
804 new->core
.height
= pixel_height
;
806 change_frame_size (new->emacs_frame
.frame
, char_height
, char_width
,
808 needs_a_refresh
= True
;
811 if (has_to_update_hints
)
812 update_wm_hints (new);
814 update_various_frame_slots (new);
816 /* #### This doesn't work, I haven't been able to find ANY kludge that
817 will let (x-create-frame '((iconic . t))) work. It seems that changes
818 to wm_shell's iconic slot have no effect after it has been realized,
819 and calling XIconifyWindow doesn't work either (even thought the window
820 has been created.) Perhaps there is some property we could smash
821 directly, but I'm sick of this for now. Xt is a steaming pile of shit!
823 if (cur
->emacs_frame
.iconic
!= new->emacs_frame
.iconic
)
825 Widget wmshell
= get_wm_shell ((Widget
) cur
);
826 XtVaSetValues (wmshell
, XtNiconic
, new->emacs_frame
.iconic
, 0);
829 return needs_a_refresh
;
832 static XtGeometryResult
833 EmacsFrameQueryGeometry (widget
, request
, result
)
835 XtWidgetGeometry
* request
;
836 XtWidgetGeometry
* result
;
838 EmacsFrame ew
= (EmacsFrame
)widget
;
840 int mask
= request
->request_mode
;
841 Dimension ok_width
, ok_height
;
843 if (mask
& (CWWidth
| CWHeight
))
845 round_size_to_char (ew
,
846 (mask
& CWWidth
) ? request
->width
: ew
->core
.width
,
847 ((mask
& CWHeight
) ? request
->height
849 &ok_width
, &ok_height
);
850 if ((mask
& CWWidth
) && (ok_width
!= request
->width
))
852 result
->request_mode
|= CWWidth
;
853 result
->width
= ok_width
;
855 if ((mask
& CWHeight
) && (ok_height
!= request
->height
))
857 result
->request_mode
|= CWHeight
;
858 result
->height
= ok_height
;
861 return result
->request_mode
? XtGeometryAlmost
: XtGeometryYes
;
864 /* Special entrypoints */
866 EmacsFrameSetCharSize (widget
, columns
, rows
)
871 EmacsFrame ew
= (EmacsFrame
) widget
;
872 Dimension pixel_width
, pixel_height
, granted_width
, granted_height
;
873 XtGeometryResult result
;
874 if (columns
< 3) columns
= 3; /* no way buddy */
875 if (rows
< 3) rows
= 3;
877 char_to_pixel_size (ew
, columns
, rows
, &pixel_width
, &pixel_height
);
878 result
= XtMakeResizeRequest ((Widget
)ew
,
879 pixel_width
, pixel_height
,
880 &granted_width
, &granted_height
);
881 if (result
== XtGeometryAlmost
)
882 XtMakeResizeRequest ((Widget
) ew
, granted_width
, granted_height
,
884 /* damn Paned widget won't ever change its width. Force it. */
885 if (ew
->core
.width
!= pixel_width
)
887 XtVaSetValues (XtParent ((Widget
) ew
), XtNwidth
, pixel_width
, 0);
888 XtVaSetValues ((Widget
) ew
, XtNwidth
, pixel_width
, 0);