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/
42 #include "dispextern.h"
43 #include "blockinput.h"
45 #include <X11/StringDefs.h>
46 #include <X11/IntrinsicP.h>
47 #include <X11/cursorfont.h>
48 #include "widgetprv.h"
49 #include <X11/ObjectP.h>
50 #include <X11/Shell.h>
51 #include <X11/ShellP.h>
52 #include "../lwlib/lwlib.h"
55 #include "syssignal.h"
57 #include "character.h"
60 /* This sucks: this is the first default that x-faces.el tries. This won't
61 be used unless neither the "Emacs.EmacsFrame" resource nor the
62 "Emacs.EmacsFrame" resource is set; the frame
63 may have the wrong default size if this font doesn't exist, but some other
64 font that x-faces.el does. The workaround is to specify some font in the
65 resource database; I don't know a solution other than duplicating the font-
66 searching code from x-faces.el in this file.
68 This also means that if "Emacs.EmacsFrame" is specified as a non-
69 existent font, then Xt is going to substitute "XtDefaultFont" for it,
70 which is a different size than this one. The solution for this is to
71 make x-faces.el try to use XtDefaultFont. The problem with that is that
72 XtDefaultFont is almost certainly variable-width.
74 #### Perhaps we could have this code explicitly set XtDefaultFont to this?
76 #define DEFAULT_FACE_FONT "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*"
79 static void EmacsFrameInitialize (/*Widget, Widget, ArgList, Cardinal * */);
80 static void EmacsFrameDestroy (/* Widget */);
81 static void EmacsFrameRealize (/* Widget, XtValueMask*, XSetWindowAttributes* */);
82 void EmacsFrameResize (/* Widget widget */);
83 static Boolean
EmacsFrameSetValues (/* Widget, Widget, Widget,
84 ArgList, Cardinal * */);
85 static XtGeometryResult
EmacsFrameQueryGeometry (/* Widget, XtWidgetGeometry*,
86 XtWidgetGeometry* */);
90 #define XtOffset(p_type,field) \
91 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
92 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
94 static XtResource resources
[] = {
95 {XtNgeometry
, XtCGeometry
, XtRString
, sizeof(String
),
96 offset (geometry
), XtRString
, (XtPointer
) 0},
97 {XtNiconic
, XtCIconic
, XtRBoolean
, sizeof(Boolean
),
98 offset (iconic
), XtRImmediate
, (XtPointer
) False
},
100 {XtNemacsFrame
, XtCEmacsFrame
, XtRPointer
, sizeof (XtPointer
),
101 offset (frame
), XtRImmediate
, 0},
103 {XtNminibuffer
, XtCMinibuffer
, XtRInt
, sizeof (int),
104 offset (minibuffer
), XtRImmediate
, (XtPointer
)0},
105 {XtNunsplittable
, XtCUnsplittable
, XtRBoolean
, sizeof (Boolean
),
106 offset (unsplittable
), XtRImmediate
, (XtPointer
)0},
107 {XtNinternalBorderWidth
, XtCInternalBorderWidth
, XtRInt
, sizeof (int),
108 offset (internal_border_width
), XtRImmediate
, (XtPointer
)4},
109 {XtNinterline
, XtCInterline
, XtRInt
, sizeof (int),
110 offset (interline
), XtRImmediate
, (XtPointer
)0},
111 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof(struct font
*),
112 offset(font
),XtRString
, DEFAULT_FACE_FONT
},
113 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
114 offset(foreground_pixel
), XtRString
, "XtDefaultForeground"},
115 {XtNcursorColor
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
116 offset(cursor_color
), XtRString
, "XtDefaultForeground"},
117 {XtNbarCursor
, XtCBarCursor
, XtRBoolean
, sizeof (Boolean
),
118 offset (bar_cursor
), XtRImmediate
, (XtPointer
)0},
119 {XtNvisualBell
, XtCVisualBell
, XtRBoolean
, sizeof (Boolean
),
120 offset (visual_bell
), XtRImmediate
, (XtPointer
)0},
121 {XtNbellVolume
, XtCBellVolume
, XtRInt
, sizeof (int),
122 offset (bell_volume
), XtRImmediate
, (XtPointer
)0},
129 emacsFrameActionsTable [] = {
130 {"keypress", key_press},
131 {"focus_in", emacs_frame_focus_handler},
132 {"focus_out", emacs_frame_focus_handler},
136 emacsFrameTranslations [] = "\
137 <KeyPress>: keypress()\n\
138 <FocusIn>: focus_in()\n\
139 <FocusOut>: focus_out()\n\
143 EmacsFrameClassRec emacsFrameClassRec
= {
145 /* superclass */ &widgetClassRec
,
146 /* class_name */ "EmacsFrame",
147 /* widget_size */ sizeof(EmacsFrameRec
),
148 /* class_initialize */ 0,
149 /* class_part_initialize */ 0,
150 /* class_inited */ FALSE
,
151 /* initialize */ EmacsFrameInitialize
,
152 /* initialize_hook */ 0,
153 /* realize */ EmacsFrameRealize
,
154 /* actions */ 0, /*emacsFrameActionsTable*/
155 /* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
156 /* resources */ resources
,
157 /* resource_count */ XtNumber(resources
),
158 /* xrm_class */ NULLQUARK
,
159 /* compress_motion */ TRUE
,
160 /* compress_exposure */ TRUE
,
161 /* compress_enterleave */ TRUE
,
162 /* visible_interest */ FALSE
,
163 /* destroy */ EmacsFrameDestroy
,
164 /* resize */ EmacsFrameResize
,
165 /* expose */ XtInheritExpose
,
166 /* set_values */ EmacsFrameSetValues
,
167 /* set_values_hook */ 0,
168 /* set_values_almost */ XtInheritSetValuesAlmost
,
169 /* get_values_hook */ 0,
170 /* accept_focus */ XtInheritAcceptFocus
,
171 /* version */ XtVersion
,
172 /* callback_private */ 0,
173 /* tm_table */ 0, /*emacsFrameTranslations*/
174 /* query_geometry */ EmacsFrameQueryGeometry
,
175 /* display_accelerator */ XtInheritDisplayAccelerator
,
180 WidgetClass emacsFrameClass
= (WidgetClass
) &emacsFrameClassRec
;
183 get_default_char_pixel_size (ew
, pixel_width
, pixel_height
)
188 struct frame
* f
= ew
->emacs_frame
.frame
;
189 *pixel_width
= FRAME_COLUMN_WIDTH (f
);
190 *pixel_height
= FRAME_LINE_HEIGHT (f
);
194 pixel_to_char_size (ew
, pixel_width
, pixel_height
, char_width
, char_height
)
196 Dimension pixel_width
;
197 Dimension pixel_height
;
201 struct frame
* f
= ew
->emacs_frame
.frame
;
202 *char_width
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, (int) pixel_width
);
203 *char_height
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, (int) pixel_height
);
207 char_to_pixel_size (ew
, char_width
, char_height
, pixel_width
, pixel_height
)
211 Dimension
* pixel_width
;
212 Dimension
* pixel_height
;
214 struct frame
* f
= ew
->emacs_frame
.frame
;
215 *pixel_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, char_width
);
216 *pixel_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, char_height
);
220 round_size_to_char (ew
, in_width
, in_height
, out_width
, out_height
)
224 Dimension
* out_width
;
225 Dimension
* out_height
;
229 pixel_to_char_size (ew
, in_width
, in_height
, &char_width
, &char_height
);
230 char_to_pixel_size (ew
, char_width
, char_height
, out_width
, out_height
);
239 for (wmshell
= XtParent (w
);
240 wmshell
&& !XtIsWMShell (wmshell
);
241 wmshell
= XtParent (wmshell
));
246 #if 0 /* Currently not used. */
249 mark_shell_size_user_specified (wmshell
)
252 if (! XtIsWMShell (wmshell
)) abort ();
253 /* This is kind of sleazy, but I can't see how else to tell it to make it
254 mark the WM_SIZE_HINTS size as user specified when appropriate. */
255 ((WMShellWidget
) wmshell
)->wm
.size_hints
.flags
|= USSize
;
261 /* Can't have static frame locals because of some broken compilers.
262 Normally, initializing a variable like this doesn't work in emacs,
263 but it's ok in this file because it must come after lastfile (and
264 thus have its data not go into text space) because Xt needs to
265 write to initialized data objects too.
268 static Boolean first_frame_p
= True
;
275 /* The widget hierarchy is
277 argv[0] emacsShell pane Frame-NAME
278 ApplicationShell EmacsShell Paned EmacsFrame
280 We accept geometry specs in this order:
286 Other possibilities for widget hierarchies might be
288 argv[0] frame pane Frame-NAME
289 ApplicationShell EmacsShell Paned EmacsFrame
291 argv[0] Frame-NAME pane Frame-NAME
292 ApplicationShell EmacsShell Paned EmacsFrame
294 argv[0] Frame-NAME pane emacsTextPane
295 ApplicationShell EmacsFrame Paned EmacsTextPane
297 With the current setup, the text-display-area is the part which is
298 an emacs "frame", since that's the only part managed by emacs proper
299 (the menubar and the parent of the menubar and all that sort of thing
300 are managed by lwlib.)
302 The EmacsShell widget is simply a replacement for the Shell widget
303 which is able to deal with using an externally-supplied window instead
304 of always creating its own. It is not actually emacs specific, and
305 should possibly have class "Shell" instead of "EmacsShell" to simplify
310 /* Hairily merged geometry */
311 unsigned int w
= FRAME_COLS (ew
->emacs_frame
.frame
);
312 unsigned int h
= FRAME_LINES (ew
->emacs_frame
.frame
);
314 Widget wmshell
= get_wm_shell ((Widget
) ew
);
315 /* Each Emacs shell is now independent and top-level. */
317 if (! XtIsSubclass (wmshell
, shellWidgetClass
)) abort ();
319 /* We don't need this for the moment. The geometry is computed in
322 /* If the EmacsFrame doesn't have a geometry but the shell does,
323 treat that as the geometry of the frame. (Is this bogus?
325 if (ew
->emacs_frame
.geometry
== 0)
326 XtVaGetValues (wmshell
, XtNgeometry
, &ew
->emacs_frame
.geometry
, NULL
);
328 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
329 this bogus? I'm not sure.) */
330 if (!ew
->emacs_frame
.iconic
)
331 XtVaGetValues (wmshell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
336 XtVaGetValues (app_shell
, XtNgeometry
, &geom
, NULL
);
338 app_flags
= XParseGeometry (geom
, &app_x
, &app_y
, &app_w
, &app_h
);
341 if (ew
->emacs_frame
.geometry
)
342 frame_flags
= XParseGeometry (ew
->emacs_frame
.geometry
,
348 /* If this is the first frame created:
349 ====================================
351 - Use the ApplicationShell's size/position, if specified.
352 (This is "Emacs.geometry", or the "-geometry" command line arg.)
353 - Else use the EmacsFrame's size/position.
354 (This is "*Frame-NAME.geometry")
356 - If the AppShell is iconic, the frame should be iconic.
358 AppShell comes first so that -geometry always applies to the first
359 frame created, even if there is an "every frame" entry in the
362 if (app_flags
& (XValue
| YValue
))
364 x
= app_x
; y
= app_y
;
365 flags
|= (app_flags
& (XValue
| YValue
| XNegative
| YNegative
));
367 else if (frame_flags
& (XValue
| YValue
))
369 x
= frame_x
; y
= frame_y
;
370 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
373 if (app_flags
& (WidthValue
| HeightValue
))
375 w
= app_w
; h
= app_h
;
376 flags
|= (app_flags
& (WidthValue
| HeightValue
));
378 else if (frame_flags
& (WidthValue
| HeightValue
))
380 w
= frame_w
; h
= frame_h
;
381 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
384 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
385 if (!ew
->emacs_frame
.iconic
)
386 XtVaGetValues (app_shell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
388 first_frame_p
= False
;
392 /* If this is not the first frame created:
393 ========================================
395 - use the EmacsFrame's size/position if specified
396 - Otherwise, use the ApplicationShell's size, but not position.
398 So that means that one can specify the position of the first frame
399 with "Emacs.geometry" or `-geometry'; but can only specify the
400 position of subsequent frames with "*Frame-NAME.geometry".
402 AppShell comes second so that -geometry does not apply to subsequent
403 frames when there is an "every frame" entry in the resource db,
404 but does apply to the first frame.
406 if (frame_flags
& (XValue
| YValue
))
408 x
= frame_x
; y
= frame_y
;
409 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
412 if (frame_flags
& (WidthValue
| HeightValue
))
414 w
= frame_w
; h
= frame_h
;
415 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
417 else if (app_flags
& (WidthValue
| HeightValue
))
421 flags
|= (app_flags
& (WidthValue
| HeightValue
));
426 struct frame
*f
= ew
->emacs_frame
.frame
;
427 Dimension pixel_width
, pixel_height
;
429 /* Take into account the size of the scrollbar. Always use the
430 number of columns occupied by the scroll bar here otherwise we
431 might end up with a frame width that is not a multiple of the
432 frame's character width which is bad for vertically split
434 f
->scroll_bar_actual_width
435 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
437 compute_fringe_widths (f
, 0);
439 #if 0 /* This can run Lisp code, and it is dangerous to give
440 out the frame to Lisp code before it officially exists.
441 This is handled in Fx_create_frame so not needed here. */
442 change_frame_size (f
, h
, w
, 1, 0, 0);
444 char_to_pixel_size (ew
, w
, h
, &pixel_width
, &pixel_height
);
445 ew
->core
.width
= pixel_width
;
446 ew
->core
.height
= pixel_height
;
448 #if 0 /* xfns.c takes care of this now. */
449 /* If a position was specified, assign it to the shell widget.
450 (Else WM won't do anything with it.)
452 if (flags
& (XValue
| YValue
))
454 /* the tricky things with the sign is to make sure that
458 sprintf (shell_position
, "=%c%d%c%d",
459 flags
& XNegative
? '-' : '+', x
< 0 ? -x
: x
,
460 flags
& YNegative
? '-' : '+', y
< 0 ? -y
: y
);
461 len
= strlen (shell_position
) + 1;
462 tem
= (char *) xmalloc (len
);
463 strncpy (tem
, shell_position
, len
);
464 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
466 else if (flags
& (WidthValue
| HeightValue
))
470 sprintf (shell_position
, "=%dx%d", pixel_width
, pixel_height
);
471 len
= strlen (shell_position
) + 1;
472 tem
= (char *) xmalloc (len
);
473 strncpy (tem
, shell_position
, len
);
474 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
477 /* If the geometry spec we're using has W/H components, mark the size
478 in the WM_SIZE_HINTS as user specified. */
479 if (flags
& (WidthValue
| HeightValue
))
480 mark_shell_size_user_specified (wmshell
);
482 /* Also assign the iconic status of the frame to the Shell, so that
484 XtVaSetValues (wmshell
, XtNiconic
, ew
->emacs_frame
.iconic
, NULL
);
489 /* Nonzero tells update_wm_hints not to do anything
490 (the caller should call update_wm_hints explicitly later.) */
491 int update_hints_inhibit
;
497 Widget wmshell
= get_wm_shell ((Widget
)ew
);
500 Dimension rounded_width
;
501 Dimension rounded_height
;
506 int min_rows
= 0, min_cols
= 0;
508 if (update_hints_inhibit
)
512 check_frame_size (ew
->emacs_frame
.frame
, &min_rows
, &min_cols
);
515 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
,
516 &char_width
, &char_height
);
517 char_to_pixel_size (ew
, char_width
, char_height
,
518 &rounded_width
, &rounded_height
);
519 get_default_char_pixel_size (ew
, &cw
, &ch
);
521 base_width
= (wmshell
->core
.width
- ew
->core
.width
522 + (rounded_width
- (char_width
* cw
)));
523 base_height
= (wmshell
->core
.height
- ew
->core
.height
524 + (rounded_height
- (char_height
* ch
)));
526 /* This is kind of sleazy, but I can't see how else to tell it to
527 make it mark the WM_SIZE_HINTS size as user specified.
529 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
531 XtVaSetValues (wmshell
,
532 XtNbaseWidth
, (XtArgVal
) base_width
,
533 XtNbaseHeight
, (XtArgVal
) base_height
,
534 XtNwidthInc
, (XtArgVal
) cw
,
535 XtNheightInc
, (XtArgVal
) ch
,
536 XtNminWidth
, (XtArgVal
) (base_width
+ min_cols
* cw
),
537 XtNminHeight
, (XtArgVal
) (base_height
+ min_rows
* ch
),
544 create_frame_gcs (ew
)
547 struct frame
*s
= ew
->emacs_frame
.frame
;
549 s
->output_data
.x
->normal_gc
550 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
551 (unsigned long)0, (XGCValues
*)0);
552 s
->output_data
.x
->reverse_gc
553 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
554 (unsigned long)0, (XGCValues
*)0);
555 s
->output_data
.x
->cursor_gc
556 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
557 (unsigned long)0, (XGCValues
*)0);
558 s
->output_data
.x
->black_relief
.gc
= 0;
559 s
->output_data
.x
->white_relief
.gc
= 0;
564 static char setup_frame_cursor_bits
[] =
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,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
577 struct frame
* s
= ew
->emacs_frame
.frame
;
578 Pixmap blank_stipple
, blank_tile
;
579 unsigned long valuemask
= (GCForeground
| GCBackground
| GCGraphicsExposures
580 | GCStipple
| GCTile
);
583 XSETFONT (font
, ew
->emacs_frame
.font
);
584 font
= Ffont_xlfd_name (font
, Qnil
);
587 XFontStruct
*xfont
= XLoadQueryFont (FRAME_X_DISPLAY_INFO (s
)->display
,
591 gc_values
.font
= xfont
->fid
;
596 /* We have to initialize all of our GCs to have a stipple/tile, otherwise
597 XGetGCValues returns uninitialized data when we query the stipple
598 (instead of None or something sensible) and it makes things hard.
600 This should be fixed for real by not querying the GCs but instead having
601 some GC-based cache instead of the current face-based cache which doesn't
602 effectively cache all of the GC settings we need to use.
606 = XCreateBitmapFromData (XtDisplay (ew
),
607 RootWindowOfScreen (XtScreen (ew
)),
608 setup_frame_cursor_bits
, 2, 2);
610 /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
611 never actually get used as a background tile!
614 = XCreatePixmapFromBitmapData (XtDisplay(ew
),
615 RootWindowOfScreen (XtScreen (ew
)),
616 setup_frame_cursor_bits
, 2, 2,
617 (unsigned long)0, (unsigned long)1,
621 gc_values
.foreground
= ew
->emacs_frame
.foreground_pixel
;
622 gc_values
.background
= ew
->core
.background_pixel
;
623 gc_values
.graphics_exposures
= False
;
624 gc_values
.stipple
= blank_stipple
;
625 gc_values
.tile
= blank_tile
;
626 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->normal_gc
,
627 valuemask
, &gc_values
);
629 /* Reverse video style. */
630 gc_values
.foreground
= ew
->core
.background_pixel
;
631 gc_values
.background
= ew
->emacs_frame
.foreground_pixel
;
632 gc_values
.graphics_exposures
= False
;
633 gc_values
.stipple
= blank_stipple
;
634 gc_values
.tile
= blank_tile
;
635 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->reverse_gc
,
636 valuemask
, &gc_values
);
638 /* Cursor has to have an empty stipple. */
639 gc_values
.foreground
= ew
->core
.background_pixel
;
640 gc_values
.background
= ew
->emacs_frame
.cursor_color
;
641 gc_values
.graphics_exposures
= False
;
642 gc_values
.tile
= blank_tile
;
644 = XCreateBitmapFromData (XtDisplay (ew
),
645 RootWindowOfScreen (XtScreen (ew
)),
646 setup_frame_cursor_bits
, 16, 16);
647 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->cursor_gc
,
648 valuemask
, &gc_values
);
652 update_various_frame_slots (ew
)
655 struct frame
*f
= ew
->emacs_frame
.frame
;
656 struct x_output
*x
= f
->output_data
.x
;
657 FRAME_PIXEL_HEIGHT (f
) = ew
->core
.height
+ x
->menubar_height
;
658 FRAME_PIXEL_WIDTH (f
) = ew
->core
.width
;
659 f
->internal_border_width
= ew
->emacs_frame
.internal_border_width
;
664 update_from_various_frame_slots (ew
)
667 struct frame
*f
= ew
->emacs_frame
.frame
;
668 struct x_output
*x
= f
->output_data
.x
;
669 ew
->core
.height
= FRAME_PIXEL_HEIGHT (f
) - x
->menubar_height
;
670 ew
->core
.width
= FRAME_PIXEL_WIDTH (f
);
671 ew
->core
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
672 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
673 ew
->emacs_frame
.font
= x
->font
;
674 ew
->emacs_frame
.foreground_pixel
= FRAME_FOREGROUND_PIXEL (f
);
675 ew
->emacs_frame
.cursor_color
= x
->cursor_pixel
;
676 ew
->core
.border_pixel
= x
->border_pixel
;
680 EmacsFrameInitialize (request
, new, dum1
, dum2
)
686 EmacsFrame ew
= (EmacsFrame
)new;
688 if (!ew
->emacs_frame
.frame
)
691 "can't create an emacs frame widget without a frame\n");
695 update_from_various_frame_slots (ew
);
701 EmacsFrameRealize (widget
, mask
, attrs
)
704 XSetWindowAttributes
*attrs
;
706 EmacsFrame ew
= (EmacsFrame
)widget
;
708 /* This used to contain SubstructureRedirectMask, but this turns out
709 to be a problem with XIM on Solaris, and events from that mask
710 don't seem to be used. Let's check that. */
711 attrs
->event_mask
= (STANDARD_EVENT_SET
713 | SubstructureNotifyMask
);
714 *mask
|= CWEventMask
;
715 XtCreateWindow (widget
, InputOutput
, (Visual
*)CopyFromParent
, *mask
,
717 update_wm_hints (ew
);
720 extern void free_frame_faces (/* struct frame * */);
723 EmacsFrameDestroy (widget
)
726 EmacsFrame ew
= (EmacsFrame
) widget
;
727 struct frame
* s
= ew
->emacs_frame
.frame
;
730 if (! s
->output_data
.x
) abort ();
734 if (s
->output_data
.x
->white_relief
.gc
)
735 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->white_relief
.gc
);
736 if (s
->output_data
.x
->black_relief
.gc
)
737 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->black_relief
.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
, 0, 1, 0);
752 update_wm_hints (ew
);
753 update_various_frame_slots (ew
);
755 cancel_mouse_face (f
);
759 EmacsFrameSetValues (cur_widget
, req_widget
, new_widget
, dum1
, dum2
)
766 EmacsFrame cur
= (EmacsFrame
)cur_widget
;
767 EmacsFrame
new = (EmacsFrame
)new_widget
;
769 Boolean needs_a_refresh
= False
;
770 Boolean has_to_recompute_size
;
771 Boolean has_to_recompute_gcs
;
772 Boolean has_to_update_hints
;
774 int char_width
, char_height
;
775 Dimension pixel_width
;
776 Dimension pixel_height
;
778 has_to_recompute_gcs
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
779 || (cur
->emacs_frame
.foreground_pixel
780 != new->emacs_frame
.foreground_pixel
)
781 || (cur
->core
.background_pixel
782 != new->core
.background_pixel
)
785 has_to_recompute_size
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
786 && cur
->core
.width
== new->core
.width
787 && cur
->core
.height
== new->core
.height
);
789 has_to_update_hints
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
);
791 if (has_to_recompute_gcs
)
793 setup_frame_gcs (new);
794 needs_a_refresh
= True
;
797 if (has_to_recompute_size
)
799 pixel_width
= new->core
.width
;
800 pixel_height
= new->core
.height
;
801 pixel_to_char_size (new, pixel_width
, pixel_height
, &char_width
,
803 char_to_pixel_size (new, char_width
, char_height
, &pixel_width
,
805 new->core
.width
= pixel_width
;
806 new->core
.height
= pixel_height
;
808 change_frame_size (new->emacs_frame
.frame
, char_height
, char_width
,
810 needs_a_refresh
= True
;
813 if (has_to_update_hints
)
814 update_wm_hints (new);
816 update_various_frame_slots (new);
818 /* #### This doesn't work, I haven't been able to find ANY kludge that
819 will let (x-create-frame '((iconic . t))) work. It seems that changes
820 to wm_shell's iconic slot have no effect after it has been realized,
821 and calling XIconifyWindow doesn't work either (even though the window
822 has been created.) Perhaps there is some property we could smash
823 directly, but I'm sick of this for now.
825 if (cur
->emacs_frame
.iconic
!= new->emacs_frame
.iconic
)
827 Widget wmshell
= get_wm_shell ((Widget
) cur
);
828 XtVaSetValues (wmshell
, XtNiconic
,
829 (XtArgVal
) new->emacs_frame
.iconic
, NULL
);
832 return needs_a_refresh
;
835 static XtGeometryResult
836 EmacsFrameQueryGeometry (widget
, request
, result
)
838 XtWidgetGeometry
* request
;
839 XtWidgetGeometry
* result
;
841 EmacsFrame ew
= (EmacsFrame
)widget
;
843 int mask
= request
->request_mode
;
844 Dimension ok_width
, ok_height
;
846 if (mask
& (CWWidth
| CWHeight
))
848 round_size_to_char (ew
,
849 (mask
& CWWidth
) ? request
->width
: ew
->core
.width
,
850 ((mask
& CWHeight
) ? request
->height
852 &ok_width
, &ok_height
);
853 if ((mask
& CWWidth
) && (ok_width
!= request
->width
))
855 result
->request_mode
|= CWWidth
;
856 result
->width
= ok_width
;
858 if ((mask
& CWHeight
) && (ok_height
!= request
->height
))
860 result
->request_mode
|= CWHeight
;
861 result
->height
= ok_height
;
864 return result
->request_mode
? XtGeometryAlmost
: XtGeometryYes
;
867 /* Special entrypoints */
869 EmacsFrameSetCharSize (widget
, columns
, rows
)
874 EmacsFrame ew
= (EmacsFrame
) widget
;
875 Dimension pixel_width
, pixel_height
;
876 struct frame
*f
= ew
->emacs_frame
.frame
;
878 if (columns
< 3) columns
= 3; /* no way buddy */
880 check_frame_size (f
, &rows
, &columns
);
881 f
->scroll_bar_actual_width
882 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
884 compute_fringe_widths (f
, 0);
886 char_to_pixel_size (ew
, columns
, rows
, &pixel_width
, &pixel_height
);
888 #if 0 /* This doesn't seem to be right. The frame gets too wide. --gerd. */
889 /* Something is really strange here wrt to the border width:
890 Apparently, XtNwidth and XtNheight include the border, so we have
891 to add it here. But the XtNborderWidth set for the widgets has
892 no similarity to what f->border_width is set to. */
893 XtVaGetValues (widget
, XtNborderWidth
, &border_width
, NULL
);
894 pixel_height
+= 2 * border_width
;
895 pixel_width
+= 2 * border_width
;
898 /* Manually change the height and width of all our widgets,
899 adjusting each widget by the same increments. */
900 if (ew
->core
.width
!= pixel_width
901 || ew
->core
.height
!= pixel_height
)
903 int hdelta
= pixel_height
- ew
->core
.height
;
904 int wdelta
= pixel_width
- ew
->core
.width
;
905 int column_widget_height
= f
->output_data
.x
->column_widget
->core
.height
;
906 int column_widget_width
= f
->output_data
.x
->column_widget
->core
.width
;
907 int outer_widget_height
= f
->output_data
.x
->widget
->core
.height
;
908 int outer_widget_width
= f
->output_data
.x
->widget
->core
.width
;
909 int old_left
= f
->output_data
.x
->widget
->core
.x
;
910 int old_top
= f
->output_data
.x
->widget
->core
.y
;
912 /* Input is blocked here, and Xt waits for some event to
915 lw_refigure_widget (f
->output_data
.x
->column_widget
, False
);
916 update_hints_inhibit
= 1;
918 /* Xt waits for a ConfigureNotify event from the window manager
919 in EmacsFrameSetCharSize when the shell widget is resized.
920 For some window managers like fvwm2 2.2.5 and KDE 2.1 this
921 event doesn't arrive for an unknown reason and Emacs hangs in
922 Xt when the default font is changed. Tell Xt not to wait,
923 depending on the value of the frame parameter
925 x_catch_errors (FRAME_X_DISPLAY (f
));
926 XtVaSetValues (f
->output_data
.x
->widget
,
927 XtNwaitForWm
, (XtArgVal
) f
->output_data
.x
->wait_for_wm
,
931 /* Workaround: When a SIGIO or SIGALRM occurs while Xt is
932 waiting for a ConfigureNotify event (see above), this leads
933 to Xt waiting indefinitely instead of using its default
934 timeout (5 seconds). */
937 sigblock (sigmask (SIGIO
));
940 /* Do parents first, otherwise LessTif's geometry management
941 enters an infinite loop (as of 2000-01-15). This is fixed in
942 later versions of LessTif (as of 2001-03-13); I'll leave it
943 as is because I think it can't do any harm. */
944 /* In April 2002, simon.marshall@misys.com reports the problem
945 seems not to occur any longer. */
946 x_catch_errors (FRAME_X_DISPLAY (f
));
947 XtVaSetValues (f
->output_data
.x
->widget
,
948 XtNheight
, (XtArgVal
) (outer_widget_height
+ hdelta
),
949 XtNwidth
, (XtArgVal
) (outer_widget_width
+ wdelta
),
951 XtVaSetValues (f
->output_data
.x
->column_widget
,
952 XtNheight
, (XtArgVal
) (column_widget_height
+ hdelta
),
953 XtNwidth
, (XtArgVal
) column_widget_width
+ wdelta
,
955 XtVaSetValues ((Widget
) ew
,
956 XtNheight
, (XtArgVal
) pixel_height
,
957 XtNwidth
, (XtArgVal
) pixel_width
,
962 sigunblock (sigmask (SIGIO
));
966 lw_refigure_widget (f
->output_data
.x
->column_widget
, True
);
968 update_hints_inhibit
= 0;
969 update_wm_hints (ew
);
971 /* These seem to get clobbered. I don't know why. - rms. */
972 f
->output_data
.x
->widget
->core
.x
= old_left
;
973 f
->output_data
.x
->widget
->core
.y
= old_top
;
976 /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to
977 receive in the ConfigureNotify event; if we get what we asked
978 for, then the event won't cause the screen to become garbaged, so
979 we have to make sure to do it here. */
980 SET_FRAME_GARBAGED (f
);
985 widget_store_internal_border (widget
)
988 EmacsFrame ew
= (EmacsFrame
) widget
;
989 FRAME_PTR f
= ew
->emacs_frame
.frame
;
991 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
994 /* arch-tag: 931d28e5-0d59-405a-8325-7d475d0a13d9
995 (do not change this comment) */