1 /* The emacs frame widget.
2 Copyright (C) 1992, 1993, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006, 2007, 2008, 2009 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 of the License, or
10 (at your option) any later version.
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. If not, see <http://www.gnu.org/licenses/>. */
20 /* Emacs 19 face widget ported by Fred Pierresteguy */
22 /* This file has been censored by the Communications Decency Act.
23 That law was passed under the guise of a ban on pornography, but
24 it bans far more than that. This file did not contain pornography,
25 but it was censored nonetheless.
27 For information on US government censorship of the Internet, and
28 what you can do to bring back freedom of the press, see the web
29 site http://www.vtw.org/
41 #include "dispextern.h"
42 #include "blockinput.h"
44 #include <X11/StringDefs.h>
45 #include <X11/IntrinsicP.h>
46 #include <X11/cursorfont.h>
47 #include "widgetprv.h"
48 #include <X11/ObjectP.h>
49 #include <X11/Shell.h>
50 #include <X11/ShellP.h>
51 #include "../lwlib/lwlib.h"
54 #include "syssignal.h"
56 #include "character.h"
59 /* This sucks: this is the first default that x-faces.el tries. This won't
60 be used unless neither the "Emacs.EmacsFrame" resource nor the
61 "Emacs.EmacsFrame" resource is set; the frame
62 may have the wrong default size if this font doesn't exist, but some other
63 font that x-faces.el does. The workaround is to specify some font in the
64 resource database; I don't know a solution other than duplicating the font-
65 searching code from x-faces.el in this file.
67 This also means that if "Emacs.EmacsFrame" is specified as a non-
68 existent font, then Xt is going to substitute "XtDefaultFont" for it,
69 which is a different size than this one. The solution for this is to
70 make x-faces.el try to use XtDefaultFont. The problem with that is that
71 XtDefaultFont is almost certainly variable-width.
73 #### Perhaps we could have this code explicitly set XtDefaultFont to this?
75 #define DEFAULT_FACE_FONT "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*"
78 static void EmacsFrameInitialize (/*Widget, Widget, ArgList, Cardinal * */);
79 static void EmacsFrameDestroy (/* Widget */);
80 static void EmacsFrameRealize (/* Widget, XtValueMask*, XSetWindowAttributes* */);
81 void EmacsFrameResize (/* Widget widget */);
82 static Boolean
EmacsFrameSetValues (/* Widget, Widget, Widget,
83 ArgList, Cardinal * */);
84 static XtGeometryResult
EmacsFrameQueryGeometry (/* Widget, XtWidgetGeometry*,
85 XtWidgetGeometry* */);
89 #define XtOffset(p_type,field) \
90 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
91 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
93 static XtResource resources
[] = {
94 {XtNgeometry
, XtCGeometry
, XtRString
, sizeof(String
),
95 offset (geometry
), XtRString
, (XtPointer
) 0},
96 {XtNiconic
, XtCIconic
, XtRBoolean
, sizeof(Boolean
),
97 offset (iconic
), XtRImmediate
, (XtPointer
) False
},
99 {XtNemacsFrame
, XtCEmacsFrame
, XtRPointer
, sizeof (XtPointer
),
100 offset (frame
), XtRImmediate
, 0},
102 {XtNminibuffer
, XtCMinibuffer
, XtRInt
, sizeof (int),
103 offset (minibuffer
), XtRImmediate
, (XtPointer
)0},
104 {XtNunsplittable
, XtCUnsplittable
, XtRBoolean
, sizeof (Boolean
),
105 offset (unsplittable
), XtRImmediate
, (XtPointer
)0},
106 {XtNinternalBorderWidth
, XtCInternalBorderWidth
, XtRInt
, sizeof (int),
107 offset (internal_border_width
), XtRImmediate
, (XtPointer
)4},
108 {XtNinterline
, XtCInterline
, XtRInt
, sizeof (int),
109 offset (interline
), XtRImmediate
, (XtPointer
)0},
110 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof(struct font
*),
111 offset(font
),XtRString
, DEFAULT_FACE_FONT
},
112 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
113 offset(foreground_pixel
), XtRString
, "XtDefaultForeground"},
114 {XtNcursorColor
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
115 offset(cursor_color
), XtRString
, "XtDefaultForeground"},
116 {XtNbarCursor
, XtCBarCursor
, XtRBoolean
, sizeof (Boolean
),
117 offset (bar_cursor
), XtRImmediate
, (XtPointer
)0},
118 {XtNvisualBell
, XtCVisualBell
, XtRBoolean
, sizeof (Boolean
),
119 offset (visual_bell
), XtRImmediate
, (XtPointer
)0},
120 {XtNbellVolume
, XtCBellVolume
, XtRInt
, sizeof (int),
121 offset (bell_volume
), XtRImmediate
, (XtPointer
)0},
128 emacsFrameActionsTable [] = {
129 {"keypress", key_press},
130 {"focus_in", emacs_frame_focus_handler},
131 {"focus_out", emacs_frame_focus_handler},
135 emacsFrameTranslations [] = "\
136 <KeyPress>: keypress()\n\
137 <FocusIn>: focus_in()\n\
138 <FocusOut>: focus_out()\n\
142 EmacsFrameClassRec emacsFrameClassRec
= {
144 /* superclass */ &widgetClassRec
,
145 /* class_name */ "EmacsFrame",
146 /* widget_size */ sizeof(EmacsFrameRec
),
147 /* class_initialize */ 0,
148 /* class_part_initialize */ 0,
149 /* class_inited */ FALSE
,
150 /* initialize */ EmacsFrameInitialize
,
151 /* initialize_hook */ 0,
152 /* realize */ EmacsFrameRealize
,
153 /* actions */ 0, /*emacsFrameActionsTable*/
154 /* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
155 /* resources */ resources
,
156 /* resource_count */ XtNumber(resources
),
157 /* xrm_class */ NULLQUARK
,
158 /* compress_motion */ TRUE
,
159 /* compress_exposure */ TRUE
,
160 /* compress_enterleave */ TRUE
,
161 /* visible_interest */ FALSE
,
162 /* destroy */ EmacsFrameDestroy
,
163 /* resize */ EmacsFrameResize
,
164 /* expose */ XtInheritExpose
,
165 /* set_values */ EmacsFrameSetValues
,
166 /* set_values_hook */ 0,
167 /* set_values_almost */ XtInheritSetValuesAlmost
,
168 /* get_values_hook */ 0,
169 /* accept_focus */ XtInheritAcceptFocus
,
170 /* version */ XtVersion
,
171 /* callback_private */ 0,
172 /* tm_table */ 0, /*emacsFrameTranslations*/
173 /* query_geometry */ EmacsFrameQueryGeometry
,
174 /* display_accelerator */ XtInheritDisplayAccelerator
,
179 WidgetClass emacsFrameClass
= (WidgetClass
) &emacsFrameClassRec
;
182 get_default_char_pixel_size (ew
, pixel_width
, pixel_height
)
187 struct frame
* f
= ew
->emacs_frame
.frame
;
188 *pixel_width
= FRAME_COLUMN_WIDTH (f
);
189 *pixel_height
= FRAME_LINE_HEIGHT (f
);
193 pixel_to_char_size (ew
, pixel_width
, pixel_height
, char_width
, char_height
)
195 Dimension pixel_width
;
196 Dimension pixel_height
;
200 struct frame
* f
= ew
->emacs_frame
.frame
;
201 *char_width
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, (int) pixel_width
);
202 *char_height
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, (int) pixel_height
);
206 char_to_pixel_size (ew
, char_width
, char_height
, pixel_width
, pixel_height
)
210 Dimension
* pixel_width
;
211 Dimension
* pixel_height
;
213 struct frame
* f
= ew
->emacs_frame
.frame
;
214 *pixel_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, char_width
);
215 *pixel_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, char_height
);
219 round_size_to_char (ew
, in_width
, in_height
, out_width
, out_height
)
223 Dimension
* out_width
;
224 Dimension
* out_height
;
228 pixel_to_char_size (ew
, in_width
, in_height
, &char_width
, &char_height
);
229 char_to_pixel_size (ew
, char_width
, char_height
, out_width
, out_height
);
238 for (wmshell
= XtParent (w
);
239 wmshell
&& !XtIsWMShell (wmshell
);
240 wmshell
= XtParent (wmshell
));
245 #if 0 /* Currently not used. */
248 mark_shell_size_user_specified (wmshell
)
251 if (! XtIsWMShell (wmshell
)) abort ();
252 /* This is kind of sleazy, but I can't see how else to tell it to make it
253 mark the WM_SIZE_HINTS size as user specified when appropriate. */
254 ((WMShellWidget
) wmshell
)->wm
.size_hints
.flags
|= USSize
;
260 /* Can't have static frame locals because of some broken compilers.
261 Normally, initializing a variable like this doesn't work in emacs,
262 but it's ok in this file because it must come after lastfile (and
263 thus have its data not go into text space) because Xt needs to
264 write to initialized data objects too.
267 static Boolean first_frame_p
= True
;
274 /* The widget hierarchy is
276 argv[0] emacsShell pane Frame-NAME
277 ApplicationShell EmacsShell Paned EmacsFrame
279 We accept geometry specs in this order:
285 Other possibilities for widget hierarchies might be
287 argv[0] frame pane Frame-NAME
288 ApplicationShell EmacsShell Paned EmacsFrame
290 argv[0] Frame-NAME pane Frame-NAME
291 ApplicationShell EmacsShell Paned EmacsFrame
293 argv[0] Frame-NAME pane emacsTextPane
294 ApplicationShell EmacsFrame Paned EmacsTextPane
296 With the current setup, the text-display-area is the part which is
297 an emacs "frame", since that's the only part managed by emacs proper
298 (the menubar and the parent of the menubar and all that sort of thing
299 are managed by lwlib.)
301 The EmacsShell widget is simply a replacement for the Shell widget
302 which is able to deal with using an externally-supplied window instead
303 of always creating its own. It is not actually emacs specific, and
304 should possibly have class "Shell" instead of "EmacsShell" to simplify
309 /* Hairily merged geometry */
310 unsigned int w
= FRAME_COLS (ew
->emacs_frame
.frame
);
311 unsigned int h
= FRAME_LINES (ew
->emacs_frame
.frame
);
313 Widget wmshell
= get_wm_shell ((Widget
) ew
);
314 /* Each Emacs shell is now independent and top-level. */
316 if (! XtIsSubclass (wmshell
, shellWidgetClass
)) abort ();
318 /* We don't need this for the moment. The geometry is computed in
321 /* If the EmacsFrame doesn't have a geometry but the shell does,
322 treat that as the geometry of the frame. (Is this bogus?
324 if (ew
->emacs_frame
.geometry
== 0)
325 XtVaGetValues (wmshell
, XtNgeometry
, &ew
->emacs_frame
.geometry
, NULL
);
327 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
328 this bogus? I'm not sure.) */
329 if (!ew
->emacs_frame
.iconic
)
330 XtVaGetValues (wmshell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
335 XtVaGetValues (app_shell
, XtNgeometry
, &geom
, NULL
);
337 app_flags
= XParseGeometry (geom
, &app_x
, &app_y
, &app_w
, &app_h
);
340 if (ew
->emacs_frame
.geometry
)
341 frame_flags
= XParseGeometry (ew
->emacs_frame
.geometry
,
347 /* If this is the first frame created:
348 ====================================
350 - Use the ApplicationShell's size/position, if specified.
351 (This is "Emacs.geometry", or the "-geometry" command line arg.)
352 - Else use the EmacsFrame's size/position.
353 (This is "*Frame-NAME.geometry")
355 - If the AppShell is iconic, the frame should be iconic.
357 AppShell comes first so that -geometry always applies to the first
358 frame created, even if there is an "every frame" entry in the
361 if (app_flags
& (XValue
| YValue
))
363 x
= app_x
; y
= app_y
;
364 flags
|= (app_flags
& (XValue
| YValue
| XNegative
| YNegative
));
366 else if (frame_flags
& (XValue
| YValue
))
368 x
= frame_x
; y
= frame_y
;
369 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
372 if (app_flags
& (WidthValue
| HeightValue
))
374 w
= app_w
; h
= app_h
;
375 flags
|= (app_flags
& (WidthValue
| HeightValue
));
377 else if (frame_flags
& (WidthValue
| HeightValue
))
379 w
= frame_w
; h
= frame_h
;
380 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
383 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
384 if (!ew
->emacs_frame
.iconic
)
385 XtVaGetValues (app_shell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
387 first_frame_p
= False
;
391 /* If this is not the first frame created:
392 ========================================
394 - use the EmacsFrame's size/position if specified
395 - Otherwise, use the ApplicationShell's size, but not position.
397 So that means that one can specify the position of the first frame
398 with "Emacs.geometry" or `-geometry'; but can only specify the
399 position of subsequent frames with "*Frame-NAME.geometry".
401 AppShell comes second so that -geometry does not apply to subsequent
402 frames when there is an "every frame" entry in the resource db,
403 but does apply to the first frame.
405 if (frame_flags
& (XValue
| YValue
))
407 x
= frame_x
; y
= frame_y
;
408 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
411 if (frame_flags
& (WidthValue
| HeightValue
))
413 w
= frame_w
; h
= frame_h
;
414 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
416 else if (app_flags
& (WidthValue
| HeightValue
))
420 flags
|= (app_flags
& (WidthValue
| HeightValue
));
425 struct frame
*f
= ew
->emacs_frame
.frame
;
426 Dimension pixel_width
, pixel_height
;
428 /* Take into account the size of the scrollbar. Always use the
429 number of columns occupied by the scroll bar here otherwise we
430 might end up with a frame width that is not a multiple of the
431 frame's character width which is bad for vertically split
433 f
->scroll_bar_actual_width
434 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
436 compute_fringe_widths (f
, 0);
438 #if 0 /* This can run Lisp code, and it is dangerous to give
439 out the frame to Lisp code before it officially exists.
440 This is handled in Fx_create_frame so not needed here. */
441 change_frame_size (f
, h
, w
, 1, 0, 0);
443 char_to_pixel_size (ew
, w
, h
, &pixel_width
, &pixel_height
);
444 ew
->core
.width
= pixel_width
;
445 ew
->core
.height
= pixel_height
;
447 #if 0 /* xfns.c takes care of this now. */
448 /* If a position was specified, assign it to the shell widget.
449 (Else WM won't do anything with it.)
451 if (flags
& (XValue
| YValue
))
453 /* the tricky things with the sign is to make sure that
457 sprintf (shell_position
, "=%c%d%c%d",
458 flags
& XNegative
? '-' : '+', x
< 0 ? -x
: x
,
459 flags
& YNegative
? '-' : '+', y
< 0 ? -y
: y
);
460 len
= strlen (shell_position
) + 1;
461 tem
= (char *) xmalloc (len
);
462 strncpy (tem
, shell_position
, len
);
463 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
465 else if (flags
& (WidthValue
| HeightValue
))
469 sprintf (shell_position
, "=%dx%d", pixel_width
, pixel_height
);
470 len
= strlen (shell_position
) + 1;
471 tem
= (char *) xmalloc (len
);
472 strncpy (tem
, shell_position
, len
);
473 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
476 /* If the geometry spec we're using has W/H components, mark the size
477 in the WM_SIZE_HINTS as user specified. */
478 if (flags
& (WidthValue
| HeightValue
))
479 mark_shell_size_user_specified (wmshell
);
481 /* Also assign the iconic status of the frame to the Shell, so that
483 XtVaSetValues (wmshell
, XtNiconic
, ew
->emacs_frame
.iconic
, NULL
);
488 /* Nonzero tells update_wm_hints not to do anything
489 (the caller should call update_wm_hints explicitly later.) */
490 int update_hints_inhibit
;
496 Widget wmshell
= get_wm_shell ((Widget
)ew
);
499 Dimension rounded_width
;
500 Dimension rounded_height
;
505 int min_rows
= 0, min_cols
= 0;
507 if (update_hints_inhibit
)
511 check_frame_size (ew
->emacs_frame
.frame
, &min_rows
, &min_cols
);
514 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
,
515 &char_width
, &char_height
);
516 char_to_pixel_size (ew
, char_width
, char_height
,
517 &rounded_width
, &rounded_height
);
518 get_default_char_pixel_size (ew
, &cw
, &ch
);
520 base_width
= (wmshell
->core
.width
- ew
->core
.width
521 + (rounded_width
- (char_width
* cw
)));
522 base_height
= (wmshell
->core
.height
- ew
->core
.height
523 + (rounded_height
- (char_height
* ch
)));
525 /* This is kind of sleazy, but I can't see how else to tell it to
526 make it mark the WM_SIZE_HINTS size as user specified.
528 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
530 XtVaSetValues (wmshell
,
531 XtNbaseWidth
, (XtArgVal
) base_width
,
532 XtNbaseHeight
, (XtArgVal
) base_height
,
533 XtNwidthInc
, (XtArgVal
) cw
,
534 XtNheightInc
, (XtArgVal
) ch
,
535 XtNminWidth
, (XtArgVal
) (base_width
+ min_cols
* cw
),
536 XtNminHeight
, (XtArgVal
) (base_height
+ min_rows
* ch
),
543 create_frame_gcs (ew
)
546 struct frame
*s
= ew
->emacs_frame
.frame
;
548 s
->output_data
.x
->normal_gc
549 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
550 (unsigned long)0, (XGCValues
*)0);
551 s
->output_data
.x
->reverse_gc
552 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
553 (unsigned long)0, (XGCValues
*)0);
554 s
->output_data
.x
->cursor_gc
555 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
556 (unsigned long)0, (XGCValues
*)0);
557 s
->output_data
.x
->black_relief
.gc
= 0;
558 s
->output_data
.x
->white_relief
.gc
= 0;
563 static char setup_frame_cursor_bits
[] =
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,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
576 struct frame
* s
= ew
->emacs_frame
.frame
;
577 Pixmap blank_stipple
, blank_tile
;
578 unsigned long valuemask
= (GCForeground
| GCBackground
| GCGraphicsExposures
579 | GCStipple
| GCTile
);
582 XSETFONT (font
, ew
->emacs_frame
.font
);
583 font
= Ffont_xlfd_name (font
, Qnil
);
586 XFontStruct
*xfont
= XLoadQueryFont (FRAME_X_DISPLAY_INFO (s
)->display
,
590 gc_values
.font
= xfont
->fid
;
595 /* We have to initialize all of our GCs to have a stipple/tile, otherwise
596 XGetGCValues returns uninitialized data when we query the stipple
597 (instead of None or something sensible) and it makes things hard.
599 This should be fixed for real by not querying the GCs but instead having
600 some GC-based cache instead of the current face-based cache which doesn't
601 effectively cache all of the GC settings we need to use.
605 = XCreateBitmapFromData (XtDisplay (ew
),
606 RootWindowOfScreen (XtScreen (ew
)),
607 setup_frame_cursor_bits
, 2, 2);
609 /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
610 never actually get used as a background tile!
613 = XCreatePixmapFromBitmapData (XtDisplay(ew
),
614 RootWindowOfScreen (XtScreen (ew
)),
615 setup_frame_cursor_bits
, 2, 2,
616 (unsigned long)0, (unsigned long)1,
620 gc_values
.foreground
= ew
->emacs_frame
.foreground_pixel
;
621 gc_values
.background
= ew
->core
.background_pixel
;
622 gc_values
.graphics_exposures
= False
;
623 gc_values
.stipple
= blank_stipple
;
624 gc_values
.tile
= blank_tile
;
625 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->normal_gc
,
626 valuemask
, &gc_values
);
628 /* Reverse video style. */
629 gc_values
.foreground
= ew
->core
.background_pixel
;
630 gc_values
.background
= ew
->emacs_frame
.foreground_pixel
;
631 gc_values
.graphics_exposures
= False
;
632 gc_values
.stipple
= blank_stipple
;
633 gc_values
.tile
= blank_tile
;
634 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->reverse_gc
,
635 valuemask
, &gc_values
);
637 /* Cursor has to have an empty stipple. */
638 gc_values
.foreground
= ew
->core
.background_pixel
;
639 gc_values
.background
= ew
->emacs_frame
.cursor_color
;
640 gc_values
.graphics_exposures
= False
;
641 gc_values
.tile
= blank_tile
;
643 = XCreateBitmapFromData (XtDisplay (ew
),
644 RootWindowOfScreen (XtScreen (ew
)),
645 setup_frame_cursor_bits
, 16, 16);
646 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->cursor_gc
,
647 valuemask
, &gc_values
);
651 update_various_frame_slots (ew
)
654 struct frame
*f
= ew
->emacs_frame
.frame
;
655 struct x_output
*x
= f
->output_data
.x
;
656 FRAME_PIXEL_HEIGHT (f
) = ew
->core
.height
+ x
->menubar_height
;
657 FRAME_PIXEL_WIDTH (f
) = ew
->core
.width
;
658 f
->internal_border_width
= ew
->emacs_frame
.internal_border_width
;
663 update_from_various_frame_slots (ew
)
666 struct frame
*f
= ew
->emacs_frame
.frame
;
667 struct x_output
*x
= f
->output_data
.x
;
668 ew
->core
.height
= FRAME_PIXEL_HEIGHT (f
) - x
->menubar_height
;
669 ew
->core
.width
= FRAME_PIXEL_WIDTH (f
);
670 ew
->core
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
671 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
672 ew
->emacs_frame
.font
= x
->font
;
673 ew
->emacs_frame
.foreground_pixel
= FRAME_FOREGROUND_PIXEL (f
);
674 ew
->emacs_frame
.cursor_color
= x
->cursor_pixel
;
675 ew
->core
.border_pixel
= x
->border_pixel
;
679 EmacsFrameInitialize (request
, new, dum1
, dum2
)
685 EmacsFrame ew
= (EmacsFrame
)new;
687 if (!ew
->emacs_frame
.frame
)
690 "can't create an emacs frame widget without a frame\n");
694 update_from_various_frame_slots (ew
);
700 EmacsFrameRealize (widget
, mask
, attrs
)
703 XSetWindowAttributes
*attrs
;
705 EmacsFrame ew
= (EmacsFrame
)widget
;
707 /* This used to contain SubstructureRedirectMask, but this turns out
708 to be a problem with XIM on Solaris, and events from that mask
709 don't seem to be used. Let's check that. */
710 attrs
->event_mask
= (STANDARD_EVENT_SET
712 | SubstructureNotifyMask
);
713 *mask
|= CWEventMask
;
714 XtCreateWindow (widget
, InputOutput
, (Visual
*)CopyFromParent
, *mask
,
716 update_wm_hints (ew
);
719 extern void free_frame_faces (/* struct frame * */);
722 EmacsFrameDestroy (widget
)
725 EmacsFrame ew
= (EmacsFrame
) widget
;
726 struct frame
* s
= ew
->emacs_frame
.frame
;
729 if (! s
->output_data
.x
) abort ();
733 if (s
->output_data
.x
->white_relief
.gc
)
734 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->white_relief
.gc
);
735 if (s
->output_data
.x
->black_relief
.gc
)
736 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->black_relief
.gc
);
741 EmacsFrameResize (widget
)
744 EmacsFrame ew
= (EmacsFrame
)widget
;
745 struct frame
*f
= ew
->emacs_frame
.frame
;
749 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
, &columns
, &rows
);
750 change_frame_size (f
, rows
, columns
, 0, 1, 0);
751 update_wm_hints (ew
);
752 update_various_frame_slots (ew
);
754 cancel_mouse_face (f
);
758 EmacsFrameSetValues (cur_widget
, req_widget
, new_widget
, dum1
, dum2
)
765 EmacsFrame cur
= (EmacsFrame
)cur_widget
;
766 EmacsFrame
new = (EmacsFrame
)new_widget
;
768 Boolean needs_a_refresh
= False
;
769 Boolean has_to_recompute_size
;
770 Boolean has_to_recompute_gcs
;
771 Boolean has_to_update_hints
;
773 int char_width
, char_height
;
774 Dimension pixel_width
;
775 Dimension pixel_height
;
777 has_to_recompute_gcs
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
778 || (cur
->emacs_frame
.foreground_pixel
779 != new->emacs_frame
.foreground_pixel
)
780 || (cur
->core
.background_pixel
781 != new->core
.background_pixel
)
784 has_to_recompute_size
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
785 && cur
->core
.width
== new->core
.width
786 && cur
->core
.height
== new->core
.height
);
788 has_to_update_hints
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
);
790 if (has_to_recompute_gcs
)
792 setup_frame_gcs (new);
793 needs_a_refresh
= True
;
796 if (has_to_recompute_size
)
798 pixel_width
= new->core
.width
;
799 pixel_height
= new->core
.height
;
800 pixel_to_char_size (new, pixel_width
, pixel_height
, &char_width
,
802 char_to_pixel_size (new, char_width
, char_height
, &pixel_width
,
804 new->core
.width
= pixel_width
;
805 new->core
.height
= pixel_height
;
807 change_frame_size (new->emacs_frame
.frame
, char_height
, char_width
,
809 needs_a_refresh
= True
;
812 if (has_to_update_hints
)
813 update_wm_hints (new);
815 update_various_frame_slots (new);
817 /* #### This doesn't work, I haven't been able to find ANY kludge that
818 will let (x-create-frame '((iconic . t))) work. It seems that changes
819 to wm_shell's iconic slot have no effect after it has been realized,
820 and calling XIconifyWindow doesn't work either (even though the window
821 has been created.) Perhaps there is some property we could smash
822 directly, but I'm sick of this for now.
824 if (cur
->emacs_frame
.iconic
!= new->emacs_frame
.iconic
)
826 Widget wmshell
= get_wm_shell ((Widget
) cur
);
827 XtVaSetValues (wmshell
, XtNiconic
,
828 (XtArgVal
) new->emacs_frame
.iconic
, NULL
);
831 return needs_a_refresh
;
834 static XtGeometryResult
835 EmacsFrameQueryGeometry (widget
, request
, result
)
837 XtWidgetGeometry
* request
;
838 XtWidgetGeometry
* result
;
840 EmacsFrame ew
= (EmacsFrame
)widget
;
842 int mask
= request
->request_mode
;
843 Dimension ok_width
, ok_height
;
845 if (mask
& (CWWidth
| CWHeight
))
847 round_size_to_char (ew
,
848 (mask
& CWWidth
) ? request
->width
: ew
->core
.width
,
849 ((mask
& CWHeight
) ? request
->height
851 &ok_width
, &ok_height
);
852 if ((mask
& CWWidth
) && (ok_width
!= request
->width
))
854 result
->request_mode
|= CWWidth
;
855 result
->width
= ok_width
;
857 if ((mask
& CWHeight
) && (ok_height
!= request
->height
))
859 result
->request_mode
|= CWHeight
;
860 result
->height
= ok_height
;
863 return result
->request_mode
? XtGeometryAlmost
: XtGeometryYes
;
866 /* Special entrypoints */
868 EmacsFrameSetCharSize (widget
, columns
, rows
)
873 EmacsFrame ew
= (EmacsFrame
) widget
;
874 Dimension pixel_width
, pixel_height
;
875 struct frame
*f
= ew
->emacs_frame
.frame
;
877 if (columns
< 3) columns
= 3; /* no way buddy */
879 check_frame_size (f
, &rows
, &columns
);
880 f
->scroll_bar_actual_width
881 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
883 compute_fringe_widths (f
, 0);
885 char_to_pixel_size (ew
, columns
, rows
, &pixel_width
, &pixel_height
);
887 #if 0 /* This doesn't seem to be right. The frame gets too wide. --gerd. */
888 /* Something is really strange here wrt to the border width:
889 Apparently, XtNwidth and XtNheight include the border, so we have
890 to add it here. But the XtNborderWidth set for the widgets has
891 no similarity to what f->border_width is set to. */
892 XtVaGetValues (widget
, XtNborderWidth
, &border_width
, NULL
);
893 pixel_height
+= 2 * border_width
;
894 pixel_width
+= 2 * border_width
;
897 /* Manually change the height and width of all our widgets,
898 adjusting each widget by the same increments. */
899 if (ew
->core
.width
!= pixel_width
900 || ew
->core
.height
!= pixel_height
)
902 int hdelta
= pixel_height
- ew
->core
.height
;
903 int wdelta
= pixel_width
- ew
->core
.width
;
904 int column_widget_height
= f
->output_data
.x
->column_widget
->core
.height
;
905 int column_widget_width
= f
->output_data
.x
->column_widget
->core
.width
;
906 int outer_widget_height
= f
->output_data
.x
->widget
->core
.height
;
907 int outer_widget_width
= f
->output_data
.x
->widget
->core
.width
;
908 int old_left
= f
->output_data
.x
->widget
->core
.x
;
909 int old_top
= f
->output_data
.x
->widget
->core
.y
;
911 /* Input is blocked here, and Xt waits for some event to
914 lw_refigure_widget (f
->output_data
.x
->column_widget
, False
);
915 update_hints_inhibit
= 1;
917 /* Xt waits for a ConfigureNotify event from the window manager
918 in EmacsFrameSetCharSize when the shell widget is resized.
919 For some window managers like fvwm2 2.2.5 and KDE 2.1 this
920 event doesn't arrive for an unknown reason and Emacs hangs in
921 Xt when the default font is changed. Tell Xt not to wait,
922 depending on the value of the frame parameter
924 x_catch_errors (FRAME_X_DISPLAY (f
));
925 XtVaSetValues (f
->output_data
.x
->widget
,
926 XtNwaitForWm
, (XtArgVal
) f
->output_data
.x
->wait_for_wm
,
930 /* Workaround: When a SIGIO or SIGALRM occurs while Xt is
931 waiting for a ConfigureNotify event (see above), this leads
932 to Xt waiting indefinitely instead of using its default
933 timeout (5 seconds). */
936 sigblock (sigmask (SIGIO
));
939 /* Do parents first, otherwise LessTif's geometry management
940 enters an infinite loop (as of 2000-01-15). This is fixed in
941 later versions of LessTif (as of 2001-03-13); I'll leave it
942 as is because I think it can't do any harm. */
943 /* In April 2002, simon.marshall@misys.com reports the problem
944 seems not to occur any longer. */
945 x_catch_errors (FRAME_X_DISPLAY (f
));
946 XtVaSetValues (f
->output_data
.x
->widget
,
947 XtNheight
, (XtArgVal
) (outer_widget_height
+ hdelta
),
948 XtNwidth
, (XtArgVal
) (outer_widget_width
+ wdelta
),
950 XtVaSetValues (f
->output_data
.x
->column_widget
,
951 XtNheight
, (XtArgVal
) (column_widget_height
+ hdelta
),
952 XtNwidth
, (XtArgVal
) column_widget_width
+ wdelta
,
954 XtVaSetValues ((Widget
) ew
,
955 XtNheight
, (XtArgVal
) pixel_height
,
956 XtNwidth
, (XtArgVal
) pixel_width
,
961 sigunblock (sigmask (SIGIO
));
965 lw_refigure_widget (f
->output_data
.x
->column_widget
, True
);
967 update_hints_inhibit
= 0;
968 update_wm_hints (ew
);
970 /* These seem to get clobbered. I don't know why. - rms. */
971 f
->output_data
.x
->widget
->core
.x
= old_left
;
972 f
->output_data
.x
->widget
->core
.y
= old_top
;
975 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
976 receive in the ConfigureNotify event; if we get what we asked
977 for, then the event won't cause the screen to become garbaged, so
978 we have to make sure to do it here. */
979 SET_FRAME_GARBAGED (f
);
984 widget_store_internal_border (widget
)
987 EmacsFrame ew
= (EmacsFrame
) widget
;
988 FRAME_PTR f
= ew
->emacs_frame
.frame
;
990 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
993 /* arch-tag: 931d28e5-0d59-405a-8325-7d475d0a13d9
994 (do not change this comment) */