1 /* The emacs frame widget.
2 Copyright (C) 1992-1993, 2000-2011 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 3 of the License, or
9 (at your option) any later version.
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. If not, see <http://www.gnu.org/licenses/>. */
19 /* Emacs 19 face widget ported by Fred Pierresteguy */
21 /* This file has been censored by the Communications Decency Act.
22 That law was passed under the guise of a ban on pornography, but
23 it bans far more than that. This file did not contain pornography,
24 but it was censored nonetheless.
26 For information on US government censorship of the Internet, and
27 what you can do to bring back freedom of the press, see the web
28 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 request
, Widget
new, ArgList dum1
, Cardinal
*dum2
);
79 static void EmacsFrameDestroy (Widget widget
);
80 static void EmacsFrameRealize (Widget widget
, XtValueMask
*mask
, XSetWindowAttributes
*attrs
);
81 void EmacsFrameResize (Widget widget
);
82 static Boolean
EmacsFrameSetValues (Widget cur_widget
, Widget req_widget
, Widget new_widget
, ArgList dum1
, Cardinal
*dum2
);
83 static XtGeometryResult
EmacsFrameQueryGeometry (Widget widget
, XtWidgetGeometry
*request
, XtWidgetGeometry
*result
);
87 #define XtOffset(p_type,field) \
88 ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
89 #define offset(field) XtOffset(EmacsFrame, emacs_frame.field)
91 static XtResource resources
[] = {
92 {XtNgeometry
, XtCGeometry
, XtRString
, sizeof(String
),
93 offset (geometry
), XtRString
, (XtPointer
) 0},
94 {XtNiconic
, XtCIconic
, XtRBoolean
, sizeof(Boolean
),
95 offset (iconic
), XtRImmediate
, (XtPointer
) False
},
97 {XtNemacsFrame
, XtCEmacsFrame
, XtRPointer
, sizeof (XtPointer
),
98 offset (frame
), XtRImmediate
, 0},
100 {XtNminibuffer
, XtCMinibuffer
, XtRInt
, sizeof (int),
101 offset (minibuffer
), XtRImmediate
, (XtPointer
)0},
102 {XtNunsplittable
, XtCUnsplittable
, XtRBoolean
, sizeof (Boolean
),
103 offset (unsplittable
), XtRImmediate
, (XtPointer
)0},
104 {XtNinternalBorderWidth
, XtCInternalBorderWidth
, XtRInt
, sizeof (int),
105 offset (internal_border_width
), XtRImmediate
, (XtPointer
)4},
106 {XtNinterline
, XtCInterline
, XtRInt
, sizeof (int),
107 offset (interline
), XtRImmediate
, (XtPointer
)0},
108 {XtNfont
, XtCFont
, XtRFontStruct
, sizeof(struct font
*),
109 offset(font
),XtRString
, DEFAULT_FACE_FONT
},
110 {XtNforeground
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
111 offset(foreground_pixel
), XtRString
, "XtDefaultForeground"},
112 {XtNcursorColor
, XtCForeground
, XtRPixel
, sizeof(Pixel
),
113 offset(cursor_color
), XtRString
, "XtDefaultForeground"},
114 {XtNbarCursor
, XtCBarCursor
, XtRBoolean
, sizeof (Boolean
),
115 offset (bar_cursor
), XtRImmediate
, (XtPointer
)0},
116 {XtNvisualBell
, XtCVisualBell
, XtRBoolean
, sizeof (Boolean
),
117 offset (visual_bell
), XtRImmediate
, (XtPointer
)0},
118 {XtNbellVolume
, XtCBellVolume
, XtRInt
, sizeof (int),
119 offset (bell_volume
), XtRImmediate
, (XtPointer
)0},
126 emacsFrameActionsTable [] = {
127 {"keypress", key_press},
128 {"focus_in", emacs_frame_focus_handler},
129 {"focus_out", emacs_frame_focus_handler},
133 emacsFrameTranslations [] = "\
134 <KeyPress>: keypress()\n\
135 <FocusIn>: focus_in()\n\
136 <FocusOut>: focus_out()\n\
140 EmacsFrameClassRec emacsFrameClassRec
= {
142 /* superclass */ &widgetClassRec
,
143 /* class_name */ "EmacsFrame",
144 /* widget_size */ sizeof(EmacsFrameRec
),
145 /* class_initialize */ 0,
146 /* class_part_initialize */ 0,
147 /* class_inited */ FALSE
,
148 /* initialize */ EmacsFrameInitialize
,
149 /* initialize_hook */ 0,
150 /* realize */ EmacsFrameRealize
,
151 /* actions */ 0, /*emacsFrameActionsTable*/
152 /* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
153 /* resources */ resources
,
154 /* resource_count */ XtNumber(resources
),
155 /* xrm_class */ NULLQUARK
,
156 /* compress_motion */ TRUE
,
157 /* compress_exposure */ TRUE
,
158 /* compress_enterleave */ TRUE
,
159 /* visible_interest */ FALSE
,
160 /* destroy */ EmacsFrameDestroy
,
161 /* resize */ EmacsFrameResize
,
162 /* expose */ XtInheritExpose
,
163 /* set_values */ EmacsFrameSetValues
,
164 /* set_values_hook */ 0,
165 /* set_values_almost */ XtInheritSetValuesAlmost
,
166 /* get_values_hook */ 0,
167 /* accept_focus */ XtInheritAcceptFocus
,
168 /* version */ XtVersion
,
169 /* callback_private */ 0,
170 /* tm_table */ 0, /*emacsFrameTranslations*/
171 /* query_geometry */ EmacsFrameQueryGeometry
,
172 /* display_accelerator */ XtInheritDisplayAccelerator
,
177 WidgetClass emacsFrameClass
= (WidgetClass
) &emacsFrameClassRec
;
180 get_default_char_pixel_size (EmacsFrame ew
, int *pixel_width
, int *pixel_height
)
182 struct frame
* f
= ew
->emacs_frame
.frame
;
183 *pixel_width
= FRAME_COLUMN_WIDTH (f
);
184 *pixel_height
= FRAME_LINE_HEIGHT (f
);
188 pixel_to_char_size (EmacsFrame ew
, Dimension pixel_width
, Dimension pixel_height
, int *char_width
, int *char_height
)
190 struct frame
* f
= ew
->emacs_frame
.frame
;
191 *char_width
= FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f
, (int) pixel_width
);
192 *char_height
= FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f
, (int) pixel_height
);
196 char_to_pixel_size (EmacsFrame ew
, int char_width
, int char_height
, Dimension
*pixel_width
, Dimension
*pixel_height
)
198 struct frame
* f
= ew
->emacs_frame
.frame
;
199 *pixel_width
= FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f
, char_width
);
200 *pixel_height
= FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f
, char_height
);
204 round_size_to_char (EmacsFrame ew
, Dimension in_width
, Dimension in_height
, Dimension
*out_width
, Dimension
*out_height
)
208 pixel_to_char_size (ew
, in_width
, in_height
, &char_width
, &char_height
);
209 char_to_pixel_size (ew
, char_width
, char_height
, out_width
, out_height
);
213 get_wm_shell (Widget w
)
217 for (wmshell
= XtParent (w
);
218 wmshell
&& !XtIsWMShell (wmshell
);
219 wmshell
= XtParent (wmshell
));
224 #if 0 /* Currently not used. */
227 mark_shell_size_user_specified (wmshell
)
230 if (! XtIsWMShell (wmshell
)) abort ();
231 /* This is kind of sleazy, but I can't see how else to tell it to make it
232 mark the WM_SIZE_HINTS size as user specified when appropriate. */
233 ((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.
246 static Boolean first_frame_p
= True
;
250 set_frame_size (EmacsFrame ew
)
252 /* The widget hierarchy is
254 argv[0] emacsShell pane Frame-NAME
255 ApplicationShell EmacsShell Paned EmacsFrame
257 We accept geometry specs in this order:
263 Other possibilities for widget hierarchies might be
265 argv[0] frame pane Frame-NAME
266 ApplicationShell EmacsShell Paned EmacsFrame
268 argv[0] Frame-NAME pane Frame-NAME
269 ApplicationShell EmacsShell Paned EmacsFrame
271 argv[0] Frame-NAME pane emacsTextPane
272 ApplicationShell EmacsFrame Paned EmacsTextPane
274 With the current setup, the text-display-area is the part which is
275 an emacs "frame", since that's the only part managed by emacs proper
276 (the menubar and the parent of the menubar and all that sort of thing
277 are managed by lwlib.)
279 The EmacsShell widget is simply a replacement for the Shell widget
280 which is able to deal with using an externally-supplied window instead
281 of always creating its own. It is not actually emacs specific, and
282 should possibly have class "Shell" instead of "EmacsShell" to simplify
287 /* Hairily merged geometry */
288 unsigned int w
= FRAME_COLS (ew
->emacs_frame
.frame
);
289 unsigned int h
= FRAME_LINES (ew
->emacs_frame
.frame
);
291 Widget wmshell
= get_wm_shell ((Widget
) ew
);
292 /* Each Emacs shell is now independent and top-level. */
294 if (! XtIsSubclass (wmshell
, shellWidgetClass
)) abort ();
296 /* We don't need this for the moment. The geometry is computed in
299 /* If the EmacsFrame doesn't have a geometry but the shell does,
300 treat that as the geometry of the frame. (Is this bogus?
302 if (ew
->emacs_frame
.geometry
== 0)
303 XtVaGetValues (wmshell
, XtNgeometry
, &ew
->emacs_frame
.geometry
, NULL
);
305 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
306 this bogus? I'm not sure.) */
307 if (!ew
->emacs_frame
.iconic
)
308 XtVaGetValues (wmshell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
313 XtVaGetValues (app_shell
, XtNgeometry
, &geom
, NULL
);
315 app_flags
= XParseGeometry (geom
, &app_x
, &app_y
, &app_w
, &app_h
);
318 if (ew
->emacs_frame
.geometry
)
319 frame_flags
= XParseGeometry (ew
->emacs_frame
.geometry
,
325 /* If this is the first frame created:
326 ====================================
328 - Use the ApplicationShell's size/position, if specified.
329 (This is "Emacs.geometry", or the "-geometry" command line arg.)
330 - Else use the EmacsFrame's size/position.
331 (This is "*Frame-NAME.geometry")
333 - If the AppShell is iconic, the frame should be iconic.
335 AppShell comes first so that -geometry always applies to the first
336 frame created, even if there is an "every frame" entry in the
339 if (app_flags
& (XValue
| YValue
))
341 x
= app_x
; y
= app_y
;
342 flags
|= (app_flags
& (XValue
| YValue
| XNegative
| YNegative
));
344 else if (frame_flags
& (XValue
| YValue
))
346 x
= frame_x
; y
= frame_y
;
347 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
350 if (app_flags
& (WidthValue
| HeightValue
))
352 w
= app_w
; h
= app_h
;
353 flags
|= (app_flags
& (WidthValue
| HeightValue
));
355 else if (frame_flags
& (WidthValue
| HeightValue
))
357 w
= frame_w
; h
= frame_h
;
358 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
361 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
362 if (!ew
->emacs_frame
.iconic
)
363 XtVaGetValues (app_shell
, XtNiconic
, &ew
->emacs_frame
.iconic
, NULL
);
365 first_frame_p
= False
;
369 /* If this is not the first frame created:
370 ========================================
372 - use the EmacsFrame's size/position if specified
373 - Otherwise, use the ApplicationShell's size, but not position.
375 So that means that one can specify the position of the first frame
376 with "Emacs.geometry" or `-geometry'; but can only specify the
377 position of subsequent frames with "*Frame-NAME.geometry".
379 AppShell comes second so that -geometry does not apply to subsequent
380 frames when there is an "every frame" entry in the resource db,
381 but does apply to the first frame.
383 if (frame_flags
& (XValue
| YValue
))
385 x
= frame_x
; y
= frame_y
;
386 flags
|= (frame_flags
& (XValue
| YValue
| XNegative
| YNegative
));
389 if (frame_flags
& (WidthValue
| HeightValue
))
391 w
= frame_w
; h
= frame_h
;
392 flags
|= (frame_flags
& (WidthValue
| HeightValue
));
394 else if (app_flags
& (WidthValue
| HeightValue
))
398 flags
|= (app_flags
& (WidthValue
| HeightValue
));
403 struct frame
*f
= ew
->emacs_frame
.frame
;
404 Dimension pixel_width
, pixel_height
;
406 /* Take into account the size of the scrollbar. Always use the
407 number of columns occupied by the scroll bar here otherwise we
408 might end up with a frame width that is not a multiple of the
409 frame's character width which is bad for vertically split
411 f
->scroll_bar_actual_width
412 = FRAME_SCROLL_BAR_COLS (f
) * FRAME_COLUMN_WIDTH (f
);
414 compute_fringe_widths (f
, 0);
416 #if 0 /* This can run Lisp code, and it is dangerous to give
417 out the frame to Lisp code before it officially exists.
418 This is handled in Fx_create_frame so not needed here. */
419 change_frame_size (f
, h
, w
, 1, 0, 0);
421 char_to_pixel_size (ew
, w
, h
, &pixel_width
, &pixel_height
);
422 ew
->core
.width
= pixel_width
;
423 ew
->core
.height
= pixel_height
;
425 #if 0 /* xfns.c takes care of this now. */
426 /* If a position was specified, assign it to the shell widget.
427 (Else WM won't do anything with it.)
429 if (flags
& (XValue
| YValue
))
431 /* the tricky things with the sign is to make sure that
435 sprintf (shell_position
, "=%c%d%c%d",
436 flags
& XNegative
? '-' : '+', x
< 0 ? -x
: x
,
437 flags
& YNegative
? '-' : '+', y
< 0 ? -y
: y
);
438 len
= strlen (shell_position
) + 1;
439 tem
= (char *) xmalloc (len
);
440 strncpy (tem
, shell_position
, len
);
441 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
443 else if (flags
& (WidthValue
| HeightValue
))
447 sprintf (shell_position
, "=%dx%d", pixel_width
, pixel_height
);
448 len
= strlen (shell_position
) + 1;
449 tem
= (char *) xmalloc (len
);
450 strncpy (tem
, shell_position
, len
);
451 XtVaSetValues (wmshell
, XtNgeometry
, tem
, NULL
);
454 /* If the geometry spec we're using has W/H components, mark the size
455 in the WM_SIZE_HINTS as user specified. */
456 if (flags
& (WidthValue
| HeightValue
))
457 mark_shell_size_user_specified (wmshell
);
459 /* Also assign the iconic status of the frame to the Shell, so that
461 XtVaSetValues (wmshell
, XtNiconic
, ew
->emacs_frame
.iconic
, NULL
);
466 /* Nonzero tells update_wm_hints not to do anything
467 (the caller should call update_wm_hints explicitly later.) */
468 int update_hints_inhibit
;
471 update_wm_hints (EmacsFrame ew
)
473 Widget wmshell
= get_wm_shell ((Widget
)ew
);
476 Dimension rounded_width
;
477 Dimension rounded_height
;
482 int min_rows
= 0, min_cols
= 0;
484 if (update_hints_inhibit
)
488 check_frame_size (ew
->emacs_frame
.frame
, &min_rows
, &min_cols
);
491 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
,
492 &char_width
, &char_height
);
493 char_to_pixel_size (ew
, char_width
, char_height
,
494 &rounded_width
, &rounded_height
);
495 get_default_char_pixel_size (ew
, &cw
, &ch
);
497 base_width
= (wmshell
->core
.width
- ew
->core
.width
498 + (rounded_width
- (char_width
* cw
)));
499 base_height
= (wmshell
->core
.height
- ew
->core
.height
500 + (rounded_height
- (char_height
* ch
)));
502 /* This is kind of sleazy, but I can't see how else to tell it to
503 make it mark the WM_SIZE_HINTS size as user specified.
505 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
507 XtVaSetValues (wmshell
,
508 XtNbaseWidth
, (XtArgVal
) base_width
,
509 XtNbaseHeight
, (XtArgVal
) base_height
,
510 XtNwidthInc
, (XtArgVal
) cw
,
511 XtNheightInc
, (XtArgVal
) ch
,
512 XtNminWidth
, (XtArgVal
) (base_width
+ min_cols
* cw
),
513 XtNminHeight
, (XtArgVal
) (base_height
+ min_rows
* ch
),
520 create_frame_gcs (ew
)
523 struct frame
*s
= ew
->emacs_frame
.frame
;
525 s
->output_data
.x
->normal_gc
526 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
527 (unsigned long)0, (XGCValues
*)0);
528 s
->output_data
.x
->reverse_gc
529 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
530 (unsigned long)0, (XGCValues
*)0);
531 s
->output_data
.x
->cursor_gc
532 = XCreateGC (XtDisplay (ew
), RootWindowOfScreen (XtScreen (ew
)),
533 (unsigned long)0, (XGCValues
*)0);
534 s
->output_data
.x
->black_relief
.gc
= 0;
535 s
->output_data
.x
->white_relief
.gc
= 0;
540 static char setup_frame_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
549 setup_frame_gcs (EmacsFrame ew
)
552 struct frame
* s
= ew
->emacs_frame
.frame
;
553 Pixmap blank_stipple
, blank_tile
;
554 unsigned long valuemask
= (GCForeground
| GCBackground
| GCGraphicsExposures
555 | GCStipple
| GCTile
);
558 XSETFONT (font
, ew
->emacs_frame
.font
);
559 font
= Ffont_xlfd_name (font
, Qnil
);
562 XFontStruct
*xfont
= XLoadQueryFont (FRAME_X_DISPLAY_INFO (s
)->display
,
566 gc_values
.font
= xfont
->fid
;
571 /* We have to initialize all of our GCs to have a stipple/tile, otherwise
572 XGetGCValues returns uninitialized data when we query the stipple
573 (instead of None or something sensible) and it makes things hard.
575 This should be fixed for real by not querying the GCs but instead having
576 some GC-based cache instead of the current face-based cache which doesn't
577 effectively cache all of the GC settings we need to use.
581 = XCreateBitmapFromData (XtDisplay (ew
),
582 RootWindowOfScreen (XtScreen (ew
)),
583 setup_frame_cursor_bits
, 2, 2);
585 /* use fg = 0, bg = 1 below, but it's irrelevant since this pixmap should
586 never actually get used as a background tile!
589 = XCreatePixmapFromBitmapData (XtDisplay(ew
),
590 RootWindowOfScreen (XtScreen (ew
)),
591 setup_frame_cursor_bits
, 2, 2,
592 (unsigned long)0, (unsigned long)1,
596 gc_values
.foreground
= ew
->emacs_frame
.foreground_pixel
;
597 gc_values
.background
= ew
->core
.background_pixel
;
598 gc_values
.graphics_exposures
= False
;
599 gc_values
.stipple
= blank_stipple
;
600 gc_values
.tile
= blank_tile
;
601 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->normal_gc
,
602 valuemask
, &gc_values
);
604 /* Reverse video style. */
605 gc_values
.foreground
= ew
->core
.background_pixel
;
606 gc_values
.background
= ew
->emacs_frame
.foreground_pixel
;
607 gc_values
.graphics_exposures
= False
;
608 gc_values
.stipple
= blank_stipple
;
609 gc_values
.tile
= blank_tile
;
610 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->reverse_gc
,
611 valuemask
, &gc_values
);
613 /* Cursor has to have an empty stipple. */
614 gc_values
.foreground
= ew
->core
.background_pixel
;
615 gc_values
.background
= ew
->emacs_frame
.cursor_color
;
616 gc_values
.graphics_exposures
= False
;
617 gc_values
.tile
= blank_tile
;
619 = XCreateBitmapFromData (XtDisplay (ew
),
620 RootWindowOfScreen (XtScreen (ew
)),
621 setup_frame_cursor_bits
, 16, 16);
622 XChangeGC (XtDisplay (ew
), s
->output_data
.x
->cursor_gc
,
623 valuemask
, &gc_values
);
627 update_various_frame_slots (EmacsFrame ew
)
629 struct frame
*f
= ew
->emacs_frame
.frame
;
630 struct x_output
*x
= f
->output_data
.x
;
631 FRAME_PIXEL_HEIGHT (f
) = ew
->core
.height
+ x
->menubar_height
;
632 FRAME_PIXEL_WIDTH (f
) = ew
->core
.width
;
633 f
->internal_border_width
= ew
->emacs_frame
.internal_border_width
;
638 update_from_various_frame_slots (EmacsFrame ew
)
640 struct frame
*f
= ew
->emacs_frame
.frame
;
641 struct x_output
*x
= f
->output_data
.x
;
642 ew
->core
.height
= FRAME_PIXEL_HEIGHT (f
) - x
->menubar_height
;
643 ew
->core
.width
= FRAME_PIXEL_WIDTH (f
);
644 ew
->core
.background_pixel
= FRAME_BACKGROUND_PIXEL (f
);
645 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;
646 ew
->emacs_frame
.font
= x
->font
;
647 ew
->emacs_frame
.foreground_pixel
= FRAME_FOREGROUND_PIXEL (f
);
648 ew
->emacs_frame
.cursor_color
= x
->cursor_pixel
;
649 ew
->core
.border_pixel
= x
->border_pixel
;
653 EmacsFrameInitialize (Widget request
, Widget
new, ArgList dum1
, Cardinal
*dum2
)
655 EmacsFrame ew
= (EmacsFrame
)new;
657 if (!ew
->emacs_frame
.frame
)
660 "can't create an emacs frame widget without a frame\n");
664 update_from_various_frame_slots (ew
);
670 EmacsFrameRealize (Widget widget
, XtValueMask
*mask
, XSetWindowAttributes
*attrs
)
672 EmacsFrame ew
= (EmacsFrame
)widget
;
674 /* This used to contain SubstructureRedirectMask, but this turns out
675 to be a problem with XIM on Solaris, and events from that mask
676 don't seem to be used. Let's check that. */
677 attrs
->event_mask
= (STANDARD_EVENT_SET
679 | SubstructureNotifyMask
);
680 *mask
|= CWEventMask
;
681 XtCreateWindow (widget
, InputOutput
, (Visual
*)CopyFromParent
, *mask
,
683 update_wm_hints (ew
);
686 extern void free_frame_faces (struct frame
*);
689 EmacsFrameDestroy (Widget widget
)
691 EmacsFrame ew
= (EmacsFrame
) widget
;
692 struct frame
* s
= ew
->emacs_frame
.frame
;
695 if (! s
->output_data
.x
) abort ();
699 if (s
->output_data
.x
->white_relief
.gc
)
700 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->white_relief
.gc
);
701 if (s
->output_data
.x
->black_relief
.gc
)
702 XFreeGC (XtDisplay (widget
), s
->output_data
.x
->black_relief
.gc
);
707 EmacsFrameResize (Widget widget
)
709 EmacsFrame ew
= (EmacsFrame
)widget
;
710 struct frame
*f
= ew
->emacs_frame
.frame
;
714 pixel_to_char_size (ew
, ew
->core
.width
, ew
->core
.height
, &columns
, &rows
);
715 change_frame_size (f
, rows
, columns
, 0, 1, 0);
716 update_wm_hints (ew
);
717 update_various_frame_slots (ew
);
719 cancel_mouse_face (f
);
723 EmacsFrameSetValues (Widget cur_widget
, Widget req_widget
, Widget new_widget
, ArgList dum1
, Cardinal
*dum2
)
725 EmacsFrame cur
= (EmacsFrame
)cur_widget
;
726 EmacsFrame
new = (EmacsFrame
)new_widget
;
728 Boolean needs_a_refresh
= False
;
729 Boolean has_to_recompute_size
;
730 Boolean has_to_recompute_gcs
;
731 Boolean has_to_update_hints
;
733 int char_width
, char_height
;
734 Dimension pixel_width
;
735 Dimension pixel_height
;
737 /* AFAIK, this function is never called. -- Jan D, Oct 2009. */
738 has_to_recompute_gcs
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
739 || (cur
->emacs_frame
.foreground_pixel
740 != new->emacs_frame
.foreground_pixel
)
741 || (cur
->core
.background_pixel
742 != new->core
.background_pixel
)
745 has_to_recompute_size
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
746 && cur
->core
.width
== new->core
.width
747 && cur
->core
.height
== new->core
.height
);
749 has_to_update_hints
= (cur
->emacs_frame
.font
!= new->emacs_frame
.font
);
751 if (has_to_recompute_gcs
)
753 setup_frame_gcs (new);
754 needs_a_refresh
= True
;
757 if (has_to_recompute_size
)
759 pixel_width
= new->core
.width
;
760 pixel_height
= new->core
.height
;
761 pixel_to_char_size (new, pixel_width
, pixel_height
, &char_width
,
763 char_to_pixel_size (new, char_width
, char_height
, &pixel_width
,
765 new->core
.width
= pixel_width
;
766 new->core
.height
= pixel_height
;
768 change_frame_size (new->emacs_frame
.frame
, char_height
, char_width
,
770 needs_a_refresh
= True
;
773 if (has_to_update_hints
)
774 update_wm_hints (new);
776 update_various_frame_slots (new);
778 /* #### This doesn't work, I haven't been able to find ANY kludge that
779 will let (x-create-frame '((iconic . t))) work. It seems that changes
780 to wm_shell's iconic slot have no effect after it has been realized,
781 and calling XIconifyWindow doesn't work either (even though the window
782 has been created.) Perhaps there is some property we could smash
783 directly, but I'm sick of this for now.
785 if (cur
->emacs_frame
.iconic
!= new->emacs_frame
.iconic
)
787 Widget wmshell
= get_wm_shell ((Widget
) cur
);
788 XtVaSetValues (wmshell
, XtNiconic
,
789 (XtArgVal
) new->emacs_frame
.iconic
, NULL
);
792 return needs_a_refresh
;
795 static XtGeometryResult
796 EmacsFrameQueryGeometry (Widget widget
, XtWidgetGeometry
*request
, XtWidgetGeometry
*result
)
798 EmacsFrame ew
= (EmacsFrame
)widget
;
800 int mask
= request
->request_mode
;
801 Dimension ok_width
, ok_height
;
803 if (mask
& (CWWidth
| CWHeight
))
805 round_size_to_char (ew
,
806 (mask
& CWWidth
) ? request
->width
: ew
->core
.width
,
807 ((mask
& CWHeight
) ? request
->height
809 &ok_width
, &ok_height
);
810 if ((mask
& CWWidth
) && (ok_width
!= request
->width
))
812 result
->request_mode
|= CWWidth
;
813 result
->width
= ok_width
;
815 if ((mask
& CWHeight
) && (ok_height
!= request
->height
))
817 result
->request_mode
|= CWHeight
;
818 result
->height
= ok_height
;
821 return result
->request_mode
? XtGeometryAlmost
: XtGeometryYes
;
824 /* Special entrypoints */
826 EmacsFrameSetCharSize (Widget widget
, int columns
, int rows
)
828 EmacsFrame ew
= (EmacsFrame
) widget
;
829 struct frame
*f
= ew
->emacs_frame
.frame
;
831 x_set_window_size (f
, 0, columns
, rows
);
836 widget_store_internal_border (Widget widget
)
838 EmacsFrame ew
= (EmacsFrame
) widget
;
839 FRAME_PTR f
= ew
->emacs_frame
.frame
;
841 ew
->emacs_frame
.internal_border_width
= f
->internal_border_width
;