1 /* The emacs frame widget.
2 Copyright (C) 1992, 1993, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* Emacs 19 face widget ported by Fred Pierresteguy */
24 /* This file has been censored by the Communications Decency Act.
25 That law was passed under the guise of a ban on pornography, but
26 it bans far more than that. This file did not contain pornography,
27 but it was censored nonetheless.
29 For information on US government censorship of the Internet, and
30 what you can do to bring back freedom of the press, see the web
31 site http://www.vtw.org/
43 #include "dispextern.h"
44 #include "blockinput.h"
46 #include <X11/StringDefs.h>
47 #include <X11/IntrinsicP.h>
48 #include <X11/cursorfont.h>
49 #include "widgetprv.h"
50 #include <X11/ObjectP.h>
51 #include <X11/Shell.h>
52 #include <X11/ShellP.h>
53 #include "../lwlib/lwlib.h"
56 #include "syssignal.h"
58 /* This sucks: this is the first default that x-faces.el tries. This won't
59 be used unless neither the "Emacs.EmacsFrame" resource nor the
60 "Emacs.EmacsFrame" resource is set; the frame
61 may have the wrong default size if this font doesn't exist, but some other
62 font that x-faces.el does. The workaround is to specify some font in the
63 resource database; I don't know a solution other than duplicating the font-
64 searching code from x-faces.el in this file.
66 This also means that if "Emacs.EmacsFrame" is specified as a non-
67 existent font, then Xt is going to substitute "XtDefaultFont" for it,
68 which is a different size than this one. The solution for this is to
69 make x-faces.el try to use XtDefaultFont. The problem with that is that
70 XtDefaultFont is almost certainly variable-width.
72 #### Perhaps we could have this code explicitly set XtDefaultFont to this?
74 #define DEFAULT_FACE_FONT "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*"
77 static void EmacsFrameInitialize (/*Widget, Widget, ArgList, Cardinal * */);
78 static void EmacsFrameDestroy (/* Widget */);
79 static void EmacsFrameRealize (/* Widget, XtValueMask*, XSetWindowAttributes* */);
80 void EmacsFrameResize (/* Widget widget */);
81 static Boolean
EmacsFrameSetValues (/* Widget, Widget, Widget,
82 ArgList, Cardinal * */);
83 static XtGeometryResult
EmacsFrameQueryGeometry (/* Widget, XtWidgetGeometry*,
84 XtWidgetGeometry* */);
88 #define XtOffset(p_type,field) \
89 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
90 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
92 static XtResource resources
[] = {
93 {XtNgeometry
, XtCGeometry
, XtRString
, sizeof(String
),
94 offset (geometry
), XtRString
, (XtPointer
) 0},
95 {XtNiconic
, XtCIconic
, XtRBoolean
, sizeof(Boolean
),
96 offset (iconic
), XtRImmediate
, (XtPointer
) False
},
98 {XtNemacsFrame
, XtCEmacsFrame
, XtRPointer
, sizeof (XtPointer
),
99 offset (frame
), XtRImmediate
, 0},
101 {XtNminibuffer
, XtCMinibuffer
, XtRInt
, sizeof (int),
102 offset (minibuffer
), XtRImmediate
, (XtPointer
)0},
103 {XtNunsplittable
, XtCUnsplittable
, XtRBoolean
, sizeof (Boolean
),
104 offset (unsplittable
), XtRImmediate
, (XtPointer
)0},
105 {XtNinternalBorderWidth
, XtCInternalBorderWidth
, XtRInt
, sizeof (int),
106 offset (internal_border_width
), XtRImmediate
, (XtPointer
)4},
107 {XtNinterline
, XtCInterline
, XtRInt
, sizeof (int),
108 offset (interline
), XtRImmediate
, (XtPointer
)0},
109 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof(XFontStruct
*),
110 offset(font
),XtRString
, DEFAULT_FACE_FONT
},
111 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
112 offset(foreground_pixel
), XtRString
, "XtDefaultForeground"},
113 {XtNcursorColor
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
114 offset(cursor_color
), XtRString
, "XtDefaultForeground"},
115 {XtNbarCursor
, XtCBarCursor
, XtRBoolean
, sizeof (Boolean
),
116 offset (bar_cursor
), XtRImmediate
, (XtPointer
)0},
117 {XtNvisualBell
, XtCVisualBell
, XtRBoolean
, sizeof (Boolean
),
118 offset (visual_bell
), XtRImmediate
, (XtPointer
)0},
119 {XtNbellVolume
, XtCBellVolume
, XtRInt
, sizeof (int),
120 offset (bell_volume
), XtRImmediate
, (XtPointer
)0},
127 emacsFrameActionsTable [] = {
128 {"keypress", key_press},
129 {"focus_in", emacs_frame_focus_handler},
130 {"focus_out", emacs_frame_focus_handler},
134 emacsFrameTranslations [] = "\
135 <KeyPress>: keypress()\n\
136 <FocusIn>: focus_in()\n\
137 <FocusOut>: focus_out()\n\
141 EmacsFrameClassRec emacsFrameClassRec
= {
143 /* superclass */ &widgetClassRec
,
144 /* class_name */ "EmacsFrame",
145 /* widget_size */ sizeof(EmacsFrameRec
),
146 /* class_initialize */ 0,
147 /* class_part_initialize */ 0,
148 /* class_inited */ FALSE
,
149 /* initialize */ EmacsFrameInitialize
,
150 /* initialize_hook */ 0,
151 /* realize */ EmacsFrameRealize
,
152 /* actions */ 0, /*emacsFrameActionsTable*/
153 /* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
154 /* resources */ resources
,
155 /* resource_count */ XtNumber(resources
),
156 /* xrm_class */ NULLQUARK
,
157 /* compress_motion */ TRUE
,
158 /* compress_exposure */ TRUE
,
159 /* compress_enterleave */ TRUE
,
160 /* visible_interest */ FALSE
,
161 /* destroy */ EmacsFrameDestroy
,
162 /* resize */ EmacsFrameResize
,
163 /* expose */ XtInheritExpose
,
164 /* set_values */ EmacsFrameSetValues
,
165 /* set_values_hook */ 0,
166 /* set_values_almost */ XtInheritSetValuesAlmost
,
167 /* get_values_hook */ 0,
168 /* accept_focus */ XtInheritAcceptFocus
,
169 /* version */ XtVersion
,
170 /* callback_private */ 0,
171 /* tm_table */ 0, /*emacsFrameTranslations*/
172 /* query_geometry */ EmacsFrameQueryGeometry
,
173 /* display_accelerator */ XtInheritDisplayAccelerator
,
178 WidgetClass emacsFrameClass
= (WidgetClass
) &emacsFrameClassRec
;
181 get_default_char_pixel_size (ew
, pixel_width
, pixel_height
)
186 struct frame
* f
= ew
->emacs_frame
.frame
;
187 *pixel_width
= FRAME_COLUMN_WIDTH (f
);
188 *pixel_height
= FRAME_LINE_HEIGHT (f
);
192 pixel_to_char_size (ew
, pixel_width
, pixel_height
, char_width
, char_height
)
194 Dimension pixel_width
;
195 Dimension pixel_height
;
199 struct frame
* f
= ew
->emacs_frame
.frame
;
200 *char_width
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, (int) pixel_width
);
201 *char_height
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, (int) pixel_height
);
205 char_to_pixel_size (ew
, char_width
, char_height
, pixel_width
, pixel_height
)
209 Dimension
* pixel_width
;
210 Dimension
* pixel_height
;
212 struct frame
* f
= ew
->emacs_frame
.frame
;
213 *pixel_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, char_width
);
214 *pixel_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, char_height
);
218 round_size_to_char (ew
, in_width
, in_height
, out_width
, out_height
)
222 Dimension
* out_width
;
223 Dimension
* out_height
;
227 pixel_to_char_size (ew
, in_width
, in_height
, &char_width
, &char_height
);
228 char_to_pixel_size (ew
, char_width
, char_height
, out_width
, out_height
);
237 for (wmshell
= XtParent (w
);
238 wmshell
&& !XtIsWMShell (wmshell
);
239 wmshell
= XtParent (wmshell
));
244 #if 0 /* Currently not used. */
247 mark_shell_size_user_specified (wmshell
)
250 if (! XtIsWMShell (wmshell
)) abort ();
251 /* This is kind of sleazy, but I can't see how else to tell it to make it
252 mark the WM_SIZE_HINTS size as user specified when appropriate. */
253 ((WMShellWidget
) wmshell
)->wm
.size_hints
.flags
|= USSize
;
259 /* Can't have static frame locals because of some broken compilers.
260 Normally, initializing a variable like this doesn't work in emacs,
261 but it's ok in this file because it must come after lastfile (and
262 thus have its data not go into text space) because Xt needs to
263 write to initialized data objects too.
266 static Boolean first_frame_p
= True
;
273 /* The widget hierarchy is
275 argv[0] emacsShell pane Frame-NAME
276 ApplicationShell EmacsShell Paned EmacsFrame
278 We accept geometry specs in this order:
284 Other possibilities for widget hierarchies might be
286 argv[0] frame pane Frame-NAME
287 ApplicationShell EmacsShell Paned EmacsFrame
289 argv[0] Frame-NAME pane Frame-NAME
290 ApplicationShell EmacsShell Paned EmacsFrame
292 argv[0] Frame-NAME pane emacsTextPane
293 ApplicationShell EmacsFrame Paned EmacsTextPane
295 With the current setup, the text-display-area is the part which is
296 an emacs "frame", since that's the only part managed by emacs proper
297 (the menubar and the parent of the menubar and all that sort of thing
298 are managed by lwlib.)
300 The EmacsShell widget is simply a replacement for the Shell widget
301 which is able to deal with using an externally-supplied window instead
302 of always creating its own. It is not actually emacs specific, and
303 should possibly have class "Shell" instead of "EmacsShell" to simplify
308 /* Hairily merged geometry */
309 unsigned int w
= FRAME_COLS (ew
->emacs_frame
.frame
);
310 unsigned int h
= FRAME_LINES (ew
->emacs_frame
.frame
);
312 Widget wmshell
= get_wm_shell ((Widget
) ew
);
313 /* Each Emacs shell is now independent and top-level. */
315 if (! XtIsSubclass (wmshell
, shellWidgetClass
)) abort ();
317 /* We don't need this for the moment. The geometry is computed in
320 /* If the EmacsFrame doesn't have a geometry but the shell does,
321 treat that as the geometry of the frame. (Is this bogus?
323 if (ew
->emacs_frame
.geometry
== 0)
324 XtVaGetValues (wmshell
, XtNgeometry
, &ew
->emacs_frame
.geometry
, NULL
);
326 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
327 this bogus? I'm not sure.) */
328 if (!ew
->emacs_frame
.iconic
)
329 XtVaGetValues (wmshell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
334 XtVaGetValues (app_shell
, XtNgeometry
, &geom
, NULL
);
336 app_flags
= XParseGeometry (geom
, &app_x
, &app_y
, &app_w
, &app_h
);
339 if (ew
->emacs_frame
.geometry
)
340 frame_flags
= XParseGeometry (ew
->emacs_frame
.geometry
,
346 /* If this is the first frame created:
347 ====================================
349 - Use the ApplicationShell's size/position, if specified.
350 (This is "Emacs.geometry", or the "-geometry" command line arg.)
351 - Else use the EmacsFrame's size/position.
352 (This is "*Frame-NAME.geometry")
354 - If the AppShell is iconic, the frame should be iconic.
356 AppShell comes first so that -geometry always applies to the first
357 frame created, even if there is an "every frame" entry in the
360 if (app_flags
& (XValue
| YValue
))
362 x
= app_x
; y
= app_y
;
363 flags
|= (app_flags
& (XValue
| YValue
| XNegative
| YNegative
));
365 else if (frame_flags
& (XValue
| YValue
))
367 x
= frame_x
; y
= frame_y
;
368 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
371 if (app_flags
& (WidthValue
| HeightValue
))
373 w
= app_w
; h
= app_h
;
374 flags
|= (app_flags
& (WidthValue
| HeightValue
));
376 else if (frame_flags
& (WidthValue
| HeightValue
))
378 w
= frame_w
; h
= frame_h
;
379 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
382 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
383 if (!ew
->emacs_frame
.iconic
)
384 XtVaGetValues (app_shell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
386 first_frame_p
= False
;
390 /* If this is not the first frame created:
391 ========================================
393 - use the EmacsFrame's size/position if specified
394 - Otherwise, use the ApplicationShell's size, but not position.
396 So that means that one can specify the position of the first frame
397 with "Emacs.geometry" or `-geometry'; but can only specify the
398 position of subsequent frames with "*Frame-NAME.geometry".
400 AppShell comes second so that -geometry does not apply to subsequent
401 frames when there is an "every frame" entry in the resource db,
402 but does apply to the first frame.
404 if (frame_flags
& (XValue
| YValue
))
406 x
= frame_x
; y
= frame_y
;
407 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
410 if (frame_flags
& (WidthValue
| HeightValue
))
412 w
= frame_w
; h
= frame_h
;
413 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
415 else if (app_flags
& (WidthValue
| HeightValue
))
419 flags
|= (app_flags
& (WidthValue
| HeightValue
));
424 struct frame
*f
= ew
->emacs_frame
.frame
;
425 Dimension pixel_width
, pixel_height
;
427 /* Take into account the size of the scrollbar. Always use the
428 number of columns occupied by the scroll bar here otherwise we
429 might end up with a frame width that is not a multiple of the
430 frame's character width which is bad for vertically split
432 f
->scroll_bar_actual_width
433 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
435 compute_fringe_widths (f
, 0);
437 #if 0 /* This can run Lisp code, and it is dangerous to give
438 out the frame to Lisp code before it officially exists.
439 This is handled in Fx_create_frame so not needed here. */
440 change_frame_size (f
, h
, w
, 1, 0, 0);
442 char_to_pixel_size (ew
, w
, h
, &pixel_width
, &pixel_height
);
443 ew
->core
.width
= pixel_width
;
444 ew
->core
.height
= pixel_height
;
446 #if 0 /* xfns.c takes care of this now. */
447 /* If a position was specified, assign it to the shell widget.
448 (Else WM won't do anything with it.)
450 if (flags
& (XValue
| YValue
))
452 /* the tricky things with the sign is to make sure that
456 sprintf (shell_position
, "=%c%d%c%d",
457 flags
& XNegative
? '-' : '+', x
< 0 ? -x
: x
,
458 flags
& YNegative
? '-' : '+', y
< 0 ? -y
: y
);
459 len
= strlen (shell_position
) + 1;
460 tem
= (char *) xmalloc (len
);
461 strncpy (tem
, shell_position
, len
);
462 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
464 else if (flags
& (WidthValue
| HeightValue
))
468 sprintf (shell_position
, "=%dx%d", pixel_width
, pixel_height
);
469 len
= strlen (shell_position
) + 1;
470 tem
= (char *) xmalloc (len
);
471 strncpy (tem
, shell_position
, len
);
472 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
475 /* If the geometry spec we're using has W/H components, mark the size
476 in the WM_SIZE_HINTS as user specified. */
477 if (flags
& (WidthValue
| HeightValue
))
478 mark_shell_size_user_specified (wmshell
);
480 /* Also assign the iconic status of the frame to the Shell, so that
482 XtVaSetValues (wmshell
, XtNiconic
, ew
->emacs_frame
.iconic
, NULL
);
487 /* Nonzero tells update_wm_hints not to do anything
488 (the caller should call update_wm_hints explicitly later.) */
489 int update_hints_inhibit
;
495 Widget wmshell
= get_wm_shell ((Widget
)ew
);
498 Dimension rounded_width
;
499 Dimension rounded_height
;
504 int min_rows
= 0, min_cols
= 0;
506 if (update_hints_inhibit
)
510 check_frame_size (ew
->emacs_frame
.frame
, &min_rows
, &min_cols
);
513 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
,
514 &char_width
, &char_height
);
515 char_to_pixel_size (ew
, char_width
, char_height
,
516 &rounded_width
, &rounded_height
);
517 get_default_char_pixel_size (ew
, &cw
, &ch
);
519 base_width
= (wmshell
->core
.width
- ew
->core
.width
520 + (rounded_width
- (char_width
* cw
)));
521 base_height
= (wmshell
->core
.height
- ew
->core
.height
522 + (rounded_height
- (char_height
* ch
)));
524 /* This is kind of sleazy, but I can't see how else to tell it to
525 make it mark the WM_SIZE_HINTS size as user specified.
527 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
529 XtVaSetValues (wmshell
,
530 XtNbaseWidth
, (XtArgVal
) base_width
,
531 XtNbaseHeight
, (XtArgVal
) base_height
,
532 XtNwidthInc
, (XtArgVal
) cw
,
533 XtNheightInc
, (XtArgVal
) ch
,
534 XtNminWidth
, (XtArgVal
) (base_width
+ min_cols
* cw
),
535 XtNminHeight
, (XtArgVal
) (base_height
+ min_rows
* ch
),
542 create_frame_gcs (ew
)
545 struct frame
*s
= ew
->emacs_frame
.frame
;
547 s
->output_data
.x
->normal_gc
548 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
549 (unsigned long)0, (XGCValues
*)0);
550 s
->output_data
.x
->reverse_gc
551 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
552 (unsigned long)0, (XGCValues
*)0);
553 s
->output_data
.x
->cursor_gc
554 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
555 (unsigned long)0, (XGCValues
*)0);
556 s
->output_data
.x
->black_relief
.gc
= 0;
557 s
->output_data
.x
->white_relief
.gc
= 0;
562 static char setup_frame_cursor_bits
[] =
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
575 struct frame
* s
= ew
->emacs_frame
.frame
;
576 Pixmap blank_stipple
, blank_tile
;
578 /* We have to initialize all of our GCs to have a stipple/tile, otherwise
579 XGetGCValues returns uninitialized data when we query the stipple
580 (instead of None or something sensible) and it makes things hard.
582 This should be fixed for real by not querying the GCs but instead having
583 some GC-based cache instead of the current face-based cache which doesn't
584 effectively cache all of the GC settings we need to use.
588 = XCreateBitmapFromData (XtDisplay (ew
),
589 RootWindowOfScreen (XtScreen (ew
)),
590 setup_frame_cursor_bits
, 2, 2);
592 /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
593 never actually get used as a background tile!
596 = XCreatePixmapFromBitmapData (XtDisplay(ew
),
597 RootWindowOfScreen (XtScreen (ew
)),
598 setup_frame_cursor_bits
, 2, 2,
599 (unsigned long)0, (unsigned long)1,
603 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
604 gc_values
.foreground
= ew
->emacs_frame
.foreground_pixel
;
605 gc_values
.background
= ew
->core
.background_pixel
;
606 gc_values
.graphics_exposures
= False
;
607 gc_values
.stipple
= blank_stipple
;
608 gc_values
.tile
= blank_tile
;
609 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->normal_gc
,
610 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
611 | GCStipple
| GCTile
),
614 /* Reverse video style. */
615 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
616 gc_values
.foreground
= ew
->core
.background_pixel
;
617 gc_values
.background
= ew
->emacs_frame
.foreground_pixel
;
618 gc_values
.graphics_exposures
= False
;
619 gc_values
.stipple
= blank_stipple
;
620 gc_values
.tile
= blank_tile
;
621 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->reverse_gc
,
622 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
623 | GCStipple
| GCTile
),
626 /* Cursor has to have an empty stipple. */
627 gc_values
.font
= ew
->emacs_frame
.font
->fid
;
628 gc_values
.foreground
= ew
->core
.background_pixel
;
629 gc_values
.background
= ew
->emacs_frame
.cursor_color
;
630 gc_values
.graphics_exposures
= False
;
631 gc_values
.tile
= blank_tile
;
633 = XCreateBitmapFromData (XtDisplay (ew
),
634 RootWindowOfScreen (XtScreen (ew
)),
635 setup_frame_cursor_bits
, 16, 16);
636 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->cursor_gc
,
637 (GCFont
| GCForeground
| GCBackground
| GCGraphicsExposures
638 | GCStipple
| GCTile
),
643 update_various_frame_slots (ew
)
646 struct frame
*f
= ew
->emacs_frame
.frame
;
647 struct x_output
*x
= f
->output_data
.x
;
648 FRAME_PIXEL_HEIGHT (f
) = ew
->core
.height
+ x
->menubar_height
;
649 FRAME_PIXEL_WIDTH (f
) = ew
->core
.width
;
650 f
->internal_border_width
= ew
->emacs_frame
.internal_border_width
;
655 update_from_various_frame_slots (ew
)
658 struct frame
*f
= ew
->emacs_frame
.frame
;
659 struct x_output
*x
= f
->output_data
.x
;
660 ew
->core
.height
= FRAME_PIXEL_HEIGHT (f
) - x
->menubar_height
;
661 ew
->core
.width
= FRAME_PIXEL_WIDTH (f
);
662 ew
->core
.background_pixel
= x
->background_pixel
;
663 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
664 ew
->emacs_frame
.font
= x
->font
;
665 ew
->emacs_frame
.foreground_pixel
= x
->foreground_pixel
;
666 ew
->emacs_frame
.cursor_color
= x
->cursor_pixel
;
667 ew
->core
.border_pixel
= x
->border_pixel
;
671 EmacsFrameInitialize (request
, new, dum1
, dum2
)
677 EmacsFrame ew
= (EmacsFrame
)new;
679 if (!ew
->emacs_frame
.frame
)
682 "can't create an emacs frame widget without a frame\n");
686 #if 0 /* done in xfns.c */
687 /* If the "Emacs.EmacsFrame.{default,Face}.{attributeFont,AttributeFont}"
688 resource is set, then it always overrides "Emacs.EmacsFrame.{font,Font}".
689 It's unfortunate that we have to do this, but we need to know the font
690 size for frame-sizing purposes before the faces get initialized. If
691 the "default.attributeFont" isn't set, then we use the font of this
692 EmacsFrame itself, defaulting to XtDefaultFont. Up in the lisp code,
693 the "default" face will use the frame's font if its own is not set,
694 so everything stays in sync -- it's not possible for the frame's font
695 and the default face's font to be different.
700 face_res
.resource_name
= "attributeFont";
701 face_res
.resource_class
= "AttributeFont";
702 face_res
.resource_type
= XtRFontStruct
;
703 face_res
.resource_size
= sizeof (XFontStruct
*);
704 face_res
.resource_offset
= 0;
705 face_res
.default_type
= XtRImmediate
;
706 face_res
.default_addr
= 0;
707 XtGetSubresources ((Widget
) ew
, (XtPointer
) &f
, "default", "Face",
708 &face_res
, 1, NULL
, 0);
711 ew
->emacs_frame
.font
= f
;
712 else if (! ew
->emacs_frame
.font
)
714 fprintf (stderr
, "emacs frame widget could not load a font\n");
719 /* Update the font field in frame */
720 FRAME_FONT (ew
->emacs_frame
.frame
) = ew
->emacs_frame
.font
;
723 update_from_various_frame_slots (ew
);
725 /*create_frame_gcs (ew);
726 setup_frame_gcs (ew);
727 update_various_frame_slots (ew); */
732 EmacsFrameRealize (widget
, mask
, attrs
)
735 XSetWindowAttributes
*attrs
;
737 EmacsFrame ew
= (EmacsFrame
)widget
;
739 /* This used to contain SubstructureRedirectMask, but this turns out
740 to be a problem with XIM on Solaris, and events from that mask
741 don't seem to be used. Let's check that. */
742 attrs
->event_mask
= (STANDARD_EVENT_SET
744 | SubstructureNotifyMask
);
745 *mask
|= CWEventMask
;
746 XtCreateWindow (widget
, InputOutput
, (Visual
*)CopyFromParent
, *mask
,
748 update_wm_hints (ew
);
751 extern void free_frame_faces (/* struct frame * */);
754 EmacsFrameDestroy (widget
)
757 EmacsFrame ew
= (EmacsFrame
) widget
;
758 struct frame
* s
= ew
->emacs_frame
.frame
;
761 if (! s
->output_data
.x
) abort ();
765 if (s
->output_data
.x
->white_relief
.gc
)
766 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->white_relief
.gc
);
767 if (s
->output_data
.x
->black_relief
.gc
)
768 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->black_relief
.gc
);
773 EmacsFrameResize (widget
)
776 EmacsFrame ew
= (EmacsFrame
)widget
;
777 struct frame
*f
= ew
->emacs_frame
.frame
;
781 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
, &columns
, &rows
);
782 change_frame_size (f
, rows
, columns
, 0, 1, 0);
783 update_wm_hints (ew
);
784 update_various_frame_slots (ew
);
786 cancel_mouse_face (f
);
790 EmacsFrameSetValues (cur_widget
, req_widget
, new_widget
, dum1
, dum2
)
797 EmacsFrame cur
= (EmacsFrame
)cur_widget
;
798 EmacsFrame
new = (EmacsFrame
)new_widget
;
800 Boolean needs_a_refresh
= False
;
801 Boolean has_to_recompute_size
;
802 Boolean has_to_recompute_gcs
;
803 Boolean has_to_update_hints
;
805 int char_width
, char_height
;
806 Dimension pixel_width
;
807 Dimension pixel_height
;
809 has_to_recompute_gcs
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
810 || (cur
->emacs_frame
.foreground_pixel
811 != new->emacs_frame
.foreground_pixel
)
812 || (cur
->core
.background_pixel
813 != new->core
.background_pixel
)
816 has_to_recompute_size
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
817 && cur
->core
.width
== new->core
.width
818 && cur
->core
.height
== new->core
.height
);
820 has_to_update_hints
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
);
822 if (has_to_recompute_gcs
)
824 setup_frame_gcs (new);
825 needs_a_refresh
= True
;
828 if (has_to_recompute_size
)
830 pixel_width
= new->core
.width
;
831 pixel_height
= new->core
.height
;
832 pixel_to_char_size (new, pixel_width
, pixel_height
, &char_width
,
834 char_to_pixel_size (new, char_width
, char_height
, &pixel_width
,
836 new->core
.width
= pixel_width
;
837 new->core
.height
= pixel_height
;
839 change_frame_size (new->emacs_frame
.frame
, char_height
, char_width
,
841 needs_a_refresh
= True
;
844 if (has_to_update_hints
)
845 update_wm_hints (new);
847 update_various_frame_slots (new);
849 /* #### This doesn't work, I haven't been able to find ANY kludge that
850 will let (x-create-frame '((iconic . t))) work. It seems that changes
851 to wm_shell's iconic slot have no effect after it has been realized,
852 and calling XIconifyWindow doesn't work either (even though the window
853 has been created.) Perhaps there is some property we could smash
854 directly, but I'm sick of this for now.
856 if (cur
->emacs_frame
.iconic
!= new->emacs_frame
.iconic
)
858 Widget wmshell
= get_wm_shell ((Widget
) cur
);
859 XtVaSetValues (wmshell
, XtNiconic
,
860 (XtArgVal
) new->emacs_frame
.iconic
, NULL
);
863 return needs_a_refresh
;
866 static XtGeometryResult
867 EmacsFrameQueryGeometry (widget
, request
, result
)
869 XtWidgetGeometry
* request
;
870 XtWidgetGeometry
* result
;
872 EmacsFrame ew
= (EmacsFrame
)widget
;
874 int mask
= request
->request_mode
;
875 Dimension ok_width
, ok_height
;
877 if (mask
& (CWWidth
| CWHeight
))
879 round_size_to_char (ew
,
880 (mask
& CWWidth
) ? request
->width
: ew
->core
.width
,
881 ((mask
& CWHeight
) ? request
->height
883 &ok_width
, &ok_height
);
884 if ((mask
& CWWidth
) && (ok_width
!= request
->width
))
886 result
->request_mode
|= CWWidth
;
887 result
->width
= ok_width
;
889 if ((mask
& CWHeight
) && (ok_height
!= request
->height
))
891 result
->request_mode
|= CWHeight
;
892 result
->height
= ok_height
;
895 return result
->request_mode
? XtGeometryAlmost
: XtGeometryYes
;
898 /* Special entrypoints */
900 EmacsFrameSetCharSize (widget
, columns
, rows
)
905 EmacsFrame ew
= (EmacsFrame
) widget
;
906 Dimension pixel_width
, pixel_height
;
907 struct frame
*f
= ew
->emacs_frame
.frame
;
909 if (columns
< 3) columns
= 3; /* no way buddy */
911 check_frame_size (f
, &rows
, &columns
);
912 f
->scroll_bar_actual_width
913 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
915 compute_fringe_widths (f
, 0);
917 char_to_pixel_size (ew
, columns
, rows
, &pixel_width
, &pixel_height
);
919 #if 0 /* This doesn't seem to be right. The frame gets too wide. --gerd. */
920 /* Something is really strange here wrt to the border width:
921 Apparently, XtNwidth and XtNheight include the border, so we have
922 to add it here. But the XtNborderWidth set for the widgets has
923 no similarity to what f->border_width is set to. */
924 XtVaGetValues (widget
, XtNborderWidth
, &border_width
, NULL
);
925 pixel_height
+= 2 * border_width
;
926 pixel_width
+= 2 * border_width
;
929 /* Manually change the height and width of all our widgets,
930 adjusting each widget by the same increments. */
931 if (ew
->core
.width
!= pixel_width
932 || ew
->core
.height
!= pixel_height
)
934 int hdelta
= pixel_height
- ew
->core
.height
;
935 int wdelta
= pixel_width
- ew
->core
.width
;
936 int column_widget_height
= f
->output_data
.x
->column_widget
->core
.height
;
937 int column_widget_width
= f
->output_data
.x
->column_widget
->core
.width
;
938 int outer_widget_height
= f
->output_data
.x
->widget
->core
.height
;
939 int outer_widget_width
= f
->output_data
.x
->widget
->core
.width
;
940 int old_left
= f
->output_data
.x
->widget
->core
.x
;
941 int old_top
= f
->output_data
.x
->widget
->core
.y
;
943 /* Input is blocked here, and Xt waits for some event to
946 lw_refigure_widget (f
->output_data
.x
->column_widget
, False
);
947 update_hints_inhibit
= 1;
949 /* Xt waits for a ConfigureNotify event from the window manager
950 in EmacsFrameSetCharSize when the shell widget is resized.
951 For some window managers like fvwm2 2.2.5 and KDE 2.1 this
952 event doesn't arrive for an unknown reason and Emacs hangs in
953 Xt when the default font is changed. Tell Xt not to wait,
954 depending on the value of the frame parameter
956 x_catch_errors (FRAME_X_DISPLAY (f
));
957 XtVaSetValues (f
->output_data
.x
->widget
,
958 XtNwaitForWm
, (XtArgVal
) f
->output_data
.x
->wait_for_wm
,
962 /* Workaround: When a SIGIO or SIGALRM occurs while Xt is
963 waiting for a ConfigureNotify event (see above), this leads
964 to Xt waiting indefinitely instead of using its default
965 timeout (5 seconds). */
968 sigblock (sigmask (SIGIO
));
971 /* Do parents first, otherwise LessTif's geometry management
972 enters an infinite loop (as of 2000-01-15). This is fixed in
973 later versions of LessTif (as of 2001-03-13); I'll leave it
974 as is because I think it can't do any harm. */
975 /* In April 2002, simon.marshall@misys.com reports the problem
976 seems not to occur any longer. */
977 x_catch_errors (FRAME_X_DISPLAY (f
));
978 XtVaSetValues (f
->output_data
.x
->widget
,
979 XtNheight
, (XtArgVal
) (outer_widget_height
+ hdelta
),
980 XtNwidth
, (XtArgVal
) (outer_widget_width
+ wdelta
),
982 XtVaSetValues (f
->output_data
.x
->column_widget
,
983 XtNheight
, (XtArgVal
) (column_widget_height
+ hdelta
),
984 XtNwidth
, (XtArgVal
) column_widget_width
+ wdelta
,
986 XtVaSetValues ((Widget
) ew
,
987 XtNheight
, (XtArgVal
) pixel_height
,
988 XtNwidth
, (XtArgVal
) pixel_width
,
993 sigunblock (sigmask (SIGIO
));
997 lw_refigure_widget (f
->output_data
.x
->column_widget
, True
);
999 update_hints_inhibit
= 0;
1000 update_wm_hints (ew
);
1002 /* These seem to get clobbered. I don't know why. - rms. */
1003 f
->output_data
.x
->widget
->core
.x
= old_left
;
1004 f
->output_data
.x
->widget
->core
.y
= old_top
;
1007 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
1008 receive in the ConfigureNotify event; if we get what we asked
1009 for, then the event won't cause the screen to become garbaged, so
1010 we have to make sure to do it here. */
1011 SET_FRAME_GARBAGED (f
);
1016 widget_store_internal_border (widget
)
1019 EmacsFrame ew
= (EmacsFrame
) widget
;
1020 FRAME_PTR f
= ew
->emacs_frame
.frame
;
1022 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
1025 /* arch-tag: 931d28e5-0d59-405a-8325-7d475d0a13d9
1026 (do not change this comment) */