]> code.delx.au - gnu-emacs/blob - src/widget.c
Merge from origin/emacs-24
[gnu-emacs] / src / widget.c
1 /* The emacs frame widget.
2 Copyright (C) 1992-1993, 2000-2015 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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/>. */
18
19 /* Emacs 19 face widget ported by Fred Pierresteguy */
20
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.
25
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/
29 */
30
31 #include <config.h>
32 #include <stdio.h>
33
34 #include "lisp.h"
35 #include "xterm.h"
36
37 #include "keyboard.h"
38 #include "frame.h"
39 #include "window.h"
40
41 #include "dispextern.h"
42 #include "blockinput.h"
43
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"
52
53 #include "character.h"
54 #include "font.h"
55
56
57 static void EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2);
58 static void EmacsFrameDestroy (Widget widget);
59 static void EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs);
60 static void EmacsFrameResize (Widget widget);
61 static XtGeometryResult EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *result);
62
63
64 #define offset(field) offsetof (EmacsFrameRec, emacs_frame.field)
65
66 static XtResource resources[] = {
67 {XtNgeometry, XtCGeometry, XtRString, sizeof (String),
68 offset (geometry), XtRString, (XtPointer) 0},
69 {XtNiconic, XtCIconic, XtRBoolean, sizeof (Boolean),
70 offset (iconic), XtRImmediate, (XtPointer) False},
71
72 {XtNemacsFrame, XtCEmacsFrame, XtRPointer, sizeof (XtPointer),
73 offset (frame), XtRImmediate, 0},
74
75 {XtNminibuffer, XtCMinibuffer, XtRInt, sizeof (int),
76 offset (minibuffer), XtRImmediate, (XtPointer)0},
77 {XtNunsplittable, XtCUnsplittable, XtRBoolean, sizeof (Boolean),
78 offset (unsplittable), XtRImmediate, (XtPointer)0},
79 {XtNinternalBorderWidth, XtCInternalBorderWidth, XtRInt, sizeof (int),
80 offset (internal_border_width), XtRImmediate, (XtPointer)4},
81 {XtNinterline, XtCInterline, XtRInt, sizeof (int),
82 offset (interline), XtRImmediate, (XtPointer)0},
83 {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
84 offset (foreground_pixel), XtRString, "XtDefaultForeground"},
85 {XtNcursorColor, XtCForeground, XtRPixel, sizeof (Pixel),
86 offset (cursor_color), XtRString, "XtDefaultForeground"},
87 {XtNbarCursor, XtCBarCursor, XtRBoolean, sizeof (Boolean),
88 offset (bar_cursor), XtRImmediate, (XtPointer)0},
89 {XtNvisualBell, XtCVisualBell, XtRBoolean, sizeof (Boolean),
90 offset (visual_bell), XtRImmediate, (XtPointer)0},
91 {XtNbellVolume, XtCBellVolume, XtRInt, sizeof (int),
92 offset (bell_volume), XtRImmediate, (XtPointer)0},
93 };
94
95 #undef offset
96
97 /*
98 static XtActionsRec
99 emacsFrameActionsTable [] = {
100 {"keypress", key_press},
101 {"focus_in", emacs_frame_focus_handler},
102 {"focus_out", emacs_frame_focus_handler},
103 };
104
105 static char
106 emacsFrameTranslations [] = "\
107 <KeyPress>: keypress()\n\
108 <FocusIn>: focus_in()\n\
109 <FocusOut>: focus_out()\n\
110 ";
111 */
112
113 static EmacsFrameClassRec emacsFrameClassRec = {
114 { /* core fields */
115 /* superclass */ &widgetClassRec,
116 /* class_name */ "EmacsFrame",
117 /* widget_size */ sizeof (EmacsFrameRec),
118 /* class_initialize */ 0,
119 /* class_part_initialize */ 0,
120 /* class_inited */ FALSE,
121 /* initialize */ EmacsFrameInitialize,
122 /* initialize_hook */ 0,
123 /* realize */ EmacsFrameRealize,
124 /* actions */ 0, /*emacsFrameActionsTable*/
125 /* num_actions */ 0, /*XtNumber (emacsFrameActionsTable)*/
126 /* resources */ resources,
127 /* resource_count */ XtNumber (resources),
128 /* xrm_class */ NULLQUARK,
129 /* compress_motion */ TRUE,
130 /* compress_exposure */ TRUE,
131 /* compress_enterleave */ TRUE,
132 /* visible_interest */ FALSE,
133 /* destroy */ EmacsFrameDestroy,
134 /* resize */ EmacsFrameResize,
135 /* expose */ XtInheritExpose,
136
137 /* Emacs never does XtSetvalues on this widget, so we have no code
138 for it. */
139 /* set_values */ 0, /* Not supported */
140 /* set_values_hook */ 0,
141 /* set_values_almost */ XtInheritSetValuesAlmost,
142 /* get_values_hook */ 0,
143 /* accept_focus */ XtInheritAcceptFocus,
144 /* version */ XtVersion,
145 /* callback_private */ 0,
146 /* tm_table */ 0, /*emacsFrameTranslations*/
147 /* query_geometry */ EmacsFrameQueryGeometry,
148 /* display_accelerator */ XtInheritDisplayAccelerator,
149 /* extension */ 0
150 }
151 };
152
153 WidgetClass emacsFrameClass = (WidgetClass) &emacsFrameClassRec;
154
155 static void
156 get_default_char_pixel_size (EmacsFrame ew, int *pixel_width, int *pixel_height)
157 {
158 struct frame* f = ew->emacs_frame.frame;
159 *pixel_width = FRAME_COLUMN_WIDTH (f);
160 *pixel_height = FRAME_LINE_HEIGHT (f);
161 }
162
163 static void
164 pixel_to_char_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height, int *char_width, int *char_height)
165 {
166 struct frame* f = ew->emacs_frame.frame;
167 *char_width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, (int) pixel_width);
168 *char_height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, (int) pixel_height);
169 }
170
171 static void
172 pixel_to_text_size (EmacsFrame ew, Dimension pixel_width, Dimension pixel_height, int *text_width, int *text_height)
173 {
174 struct frame* f = ew->emacs_frame.frame;
175 *text_width = FRAME_PIXEL_TO_TEXT_WIDTH (f, (int) pixel_width);
176 *text_height = FRAME_PIXEL_TO_TEXT_HEIGHT (f, (int) pixel_height);
177 }
178
179 static void
180 char_to_pixel_size (EmacsFrame ew, int char_width, int char_height, Dimension *pixel_width, Dimension *pixel_height)
181 {
182 struct frame* f = ew->emacs_frame.frame;
183 *pixel_width = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, char_width);
184 *pixel_height = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, char_height);
185 }
186
187 static void
188 round_size_to_char (EmacsFrame ew, Dimension in_width, Dimension in_height, Dimension *out_width, Dimension *out_height)
189 {
190 int char_width;
191 int char_height;
192 pixel_to_char_size (ew, in_width, in_height, &char_width, &char_height);
193 char_to_pixel_size (ew, char_width, char_height, out_width, out_height);
194 }
195
196 static Widget
197 get_wm_shell (Widget w)
198 {
199 Widget wmshell;
200
201 for (wmshell = XtParent (w);
202 wmshell && !XtIsWMShell (wmshell);
203 wmshell = XtParent (wmshell));
204
205 return wmshell;
206 }
207
208 #if 0 /* Currently not used. */
209
210 static void
211 mark_shell_size_user_specified (Widget wmshell)
212 {
213 if (! XtIsWMShell (wmshell)) emacs_abort ();
214 /* This is kind of sleazy, but I can't see how else to tell it to make it
215 mark the WM_SIZE_HINTS size as user specified when appropriate. */
216 ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;
217 }
218
219 #endif
220
221
222 /* Can't have static frame locals because of some broken compilers.
223 Normally, initializing a variable like this doesn't work in emacs,
224 but it's ok in this file because it must come after lastfile (and
225 thus have its data not go into text space) because Xt needs to
226 write to initialized data objects too.
227 */
228 #if 0
229 static Boolean first_frame_p = True;
230 #endif
231
232 static void
233 set_frame_size (EmacsFrame ew)
234 {
235 /* The widget hierarchy is
236
237 argv[0] emacsShell pane Frame-NAME
238 ApplicationShell EmacsShell Paned EmacsFrame
239
240 We accept geometry specs in this order:
241
242 *Frame-NAME.geometry
243 *EmacsFrame.geometry
244 Emacs.geometry
245
246 Other possibilities for widget hierarchies might be
247
248 argv[0] frame pane Frame-NAME
249 ApplicationShell EmacsShell Paned EmacsFrame
250 or
251 argv[0] Frame-NAME pane Frame-NAME
252 ApplicationShell EmacsShell Paned EmacsFrame
253 or
254 argv[0] Frame-NAME pane emacsTextPane
255 ApplicationShell EmacsFrame Paned EmacsTextPane
256
257 With the current setup, the text-display-area is the part which is
258 an emacs "frame", since that's the only part managed by emacs proper
259 (the menubar and the parent of the menubar and all that sort of thing
260 are managed by lwlib.)
261
262 The EmacsShell widget is simply a replacement for the Shell widget
263 which is able to deal with using an externally-supplied window instead
264 of always creating its own. It is not actually emacs specific, and
265 should possibly have class "Shell" instead of "EmacsShell" to simplify
266 the resources.
267
268 */
269
270 /* Hairily merged geometry */
271 int w = FRAME_COLS (ew->emacs_frame.frame);
272 int h = FRAME_LINES (ew->emacs_frame.frame);
273
274 Widget wmshell = get_wm_shell ((Widget) ew);
275 /* Each Emacs shell is now independent and top-level. */
276
277 if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort ();
278
279 /* We don't need this for the moment. The geometry is computed in
280 xfns.c. */
281 #if 0
282 /* If the EmacsFrame doesn't have a geometry but the shell does,
283 treat that as the geometry of the frame. (Is this bogus?
284 I'm not sure.) */
285 if (ew->emacs_frame.geometry == 0)
286 XtVaGetValues (wmshell, XtNgeometry, &ew->emacs_frame.geometry, NULL);
287
288 /* If the Shell is iconic, then the EmacsFrame is iconic. (Is
289 this bogus? I'm not sure.) */
290 if (!ew->emacs_frame.iconic)
291 XtVaGetValues (wmshell, XtNiconic, &ew->emacs_frame.iconic, NULL);
292
293
294 {
295 char *geom = 0;
296 XtVaGetValues (app_shell, XtNgeometry, &geom, NULL);
297 if (geom)
298 app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h);
299 }
300
301 if (ew->emacs_frame.geometry)
302 frame_flags = XParseGeometry (ew->emacs_frame.geometry,
303 &frame_x, &frame_y,
304 &frame_w, &frame_h);
305
306 if (first_frame_p)
307 {
308 /* If this is the first frame created:
309 ====================================
310
311 - Use the ApplicationShell's size/position, if specified.
312 (This is "Emacs.geometry", or the "-geometry" command line arg.)
313 - Else use the EmacsFrame's size/position.
314 (This is "*Frame-NAME.geometry")
315
316 - If the AppShell is iconic, the frame should be iconic.
317
318 AppShell comes first so that -geometry always applies to the first
319 frame created, even if there is an "every frame" entry in the
320 resource database.
321 */
322 if (app_flags & (XValue | YValue))
323 {
324 x = app_x; y = app_y;
325 flags |= (app_flags & (XValue | YValue | XNegative | YNegative));
326 }
327 else if (frame_flags & (XValue | YValue))
328 {
329 x = frame_x; y = frame_y;
330 flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
331 }
332
333 if (app_flags & (WidthValue | HeightValue))
334 {
335 w = app_w; h = app_h;
336 flags |= (app_flags & (WidthValue | HeightValue));
337 }
338 else if (frame_flags & (WidthValue | HeightValue))
339 {
340 w = frame_w; h = frame_h;
341 flags |= (frame_flags & (WidthValue | HeightValue));
342 }
343
344 /* If the AppShell is iconic, then the EmacsFrame is iconic. */
345 if (!ew->emacs_frame.iconic)
346 XtVaGetValues (app_shell, XtNiconic, &ew->emacs_frame.iconic, NULL);
347
348 first_frame_p = False;
349 }
350 else
351 {
352 /* If this is not the first frame created:
353 ========================================
354
355 - use the EmacsFrame's size/position if specified
356 - Otherwise, use the ApplicationShell's size, but not position.
357
358 So that means that one can specify the position of the first frame
359 with "Emacs.geometry" or `-geometry'; but can only specify the
360 position of subsequent frames with "*Frame-NAME.geometry".
361
362 AppShell comes second so that -geometry does not apply to subsequent
363 frames when there is an "every frame" entry in the resource db,
364 but does apply to the first frame.
365 */
366 if (frame_flags & (XValue | YValue))
367 {
368 x = frame_x; y = frame_y;
369 flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
370 }
371
372 if (frame_flags & (WidthValue | HeightValue))
373 {
374 w = frame_w; h = frame_h;
375 flags |= (frame_flags & (WidthValue | HeightValue));
376 }
377 else if (app_flags & (WidthValue | HeightValue))
378 {
379 w = app_w;
380 h = app_h;
381 flags |= (app_flags & (WidthValue | HeightValue));
382 }
383 }
384 #endif /* 0 */
385 {
386 Dimension pixel_width, pixel_height;
387
388 /* Take into account the size of the scrollbar. Always use the
389 number of columns occupied by the scroll bar here otherwise we
390 might end up with a frame width that is not a multiple of the
391 frame's character width which is bad for vertically split
392 windows. */
393
394 #if 0 /* This can run Lisp code, and it is dangerous to give
395 out the frame to Lisp code before it officially exists.
396 This is handled in Fx_create_frame so not needed here. */
397 change_frame_size (f, w, h, 1, 0, 0, 0);
398 #endif
399 char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
400 ew->core.width = pixel_width;
401 ew->core.height = pixel_height;
402
403 #if 0 /* xfns.c takes care of this now. */
404 /* If a position was specified, assign it to the shell widget.
405 (Else WM won't do anything with it.)
406 */
407 if (flags & (XValue | YValue))
408 {
409 /* the tricky things with the sign is to make sure that
410 -0 is printed -0. */
411 sprintf (shell_position, "=%c%d%c%d",
412 flags & XNegative ? '-' : '+', x < 0 ? -x : x,
413 flags & YNegative ? '-' : '+', y < 0 ? -y : y);
414 XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
415 }
416 else if (flags & (WidthValue | HeightValue))
417 {
418 sprintf (shell_position, "=%dx%d", pixel_width, pixel_height);
419 XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
420 }
421
422 /* If the geometry spec we're using has W/H components, mark the size
423 in the WM_SIZE_HINTS as user specified. */
424 if (flags & (WidthValue | HeightValue))
425 mark_shell_size_user_specified (wmshell);
426
427 /* Also assign the iconic status of the frame to the Shell, so that
428 the WM sees it. */
429 XtVaSetValues (wmshell, XtNiconic, ew->emacs_frame.iconic, NULL);
430 #endif /* 0 */
431 }
432 }
433
434 static void
435 update_wm_hints (EmacsFrame ew)
436 {
437 Widget wmshell = get_wm_shell ((Widget) ew);
438 int cw;
439 int ch;
440 Dimension rounded_width;
441 Dimension rounded_height;
442 int char_width;
443 int char_height;
444 int base_width;
445 int base_height;
446 int min_rows = 0, min_cols = 0;
447
448 /* This happens when the frame is just created. */
449 if (! wmshell) return;
450
451 pixel_to_char_size (ew, ew->core.width, ew->core.height,
452 &char_width, &char_height);
453 char_to_pixel_size (ew, char_width, char_height,
454 &rounded_width, &rounded_height);
455 get_default_char_pixel_size (ew, &cw, &ch);
456
457 base_width = (wmshell->core.width - ew->core.width
458 + (rounded_width - (char_width * cw)));
459 base_height = (wmshell->core.height - ew->core.height
460 + (rounded_height - (char_height * ch)));
461
462 /* This is kind of sleazy, but I can't see how else to tell it to
463 make it mark the WM_SIZE_HINTS size as user specified.
464 */
465 /* ((WMShellWidget) wmshell)->wm.size_hints.flags |= USSize;*/
466
467 XtVaSetValues (wmshell,
468 XtNbaseWidth, (XtArgVal) base_width,
469 XtNbaseHeight, (XtArgVal) base_height,
470 XtNwidthInc, (XtArgVal) (frame_resize_pixelwise ? 1 : cw),
471 XtNheightInc, (XtArgVal) (frame_resize_pixelwise ? 1 : ch),
472 XtNminWidth, (XtArgVal) (base_width + min_cols * cw),
473 XtNminHeight, (XtArgVal) (base_height + min_rows * ch),
474 NULL);
475 }
476
477 void
478 widget_update_wm_size_hints (Widget widget)
479 {
480 EmacsFrame ew = (EmacsFrame) widget;
481 update_wm_hints (ew);
482 }
483
484 static void
485 update_various_frame_slots (EmacsFrame ew)
486 {
487 struct frame *f = ew->emacs_frame.frame;
488
489 /* Don't do that: It confuses the check in change_frame_size_1 whether
490 the pixel size of the frame changed due to a change of the internal
491 border width. Bug#16736. */
492 if (false)
493 {
494 struct x_output *x = f->output_data.x;
495 FRAME_PIXEL_HEIGHT (f) = ew->core.height + x->menubar_height;
496 FRAME_PIXEL_WIDTH (f) = ew->core.width;
497 }
498
499 f->internal_border_width = ew->emacs_frame.internal_border_width;
500 }
501
502 static void
503 update_from_various_frame_slots (EmacsFrame ew)
504 {
505 struct frame *f = ew->emacs_frame.frame;
506 struct x_output *x = f->output_data.x;
507 ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
508 ew->core.width = FRAME_PIXEL_WIDTH (f);
509 ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
510 ew->emacs_frame.internal_border_width = f->internal_border_width;
511 ew->emacs_frame.foreground_pixel = FRAME_FOREGROUND_PIXEL (f);
512 ew->emacs_frame.cursor_color = x->cursor_pixel;
513 ew->core.border_pixel = x->border_pixel;
514 }
515
516 static void
517 EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2)
518 {
519 EmacsFrame ew = (EmacsFrame) new;
520
521 if (!ew->emacs_frame.frame)
522 {
523 fprintf (stderr,
524 "can't create an emacs frame widget without a frame\n");
525 exit (1);
526 }
527
528 update_from_various_frame_slots (ew);
529 set_frame_size (ew);
530 }
531
532 static void
533 resize_cb (Widget widget,
534 XtPointer closure,
535 XEvent* event,
536 Boolean* continue_to_dispatch)
537 {
538 EmacsFrameResize (widget);
539 }
540
541
542 static void
543 EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs)
544 {
545 EmacsFrame ew = (EmacsFrame) widget;
546
547 /* This used to contain SubstructureRedirectMask, but this turns out
548 to be a problem with XIM on Solaris, and events from that mask
549 don't seem to be used. Let's check that. */
550 attrs->event_mask = (STANDARD_EVENT_SET
551 | PropertyChangeMask
552 | SubstructureNotifyMask);
553 *mask |= CWEventMask;
554 XtCreateWindow (widget, InputOutput, (Visual *) CopyFromParent, *mask,
555 attrs);
556 /* Some ConfigureNotify events does not end up in EmacsFrameResize so
557 make sure we get them all. Seen with xfcwm4 for example. */
558 XtAddRawEventHandler (widget, StructureNotifyMask, False, resize_cb, NULL);
559 update_wm_hints (ew);
560 }
561
562 static void
563 EmacsFrameDestroy (Widget widget)
564 {
565 /* All GCs are now freed in x_free_frame_resources. */
566 }
567
568 static void
569 EmacsFrameResize (Widget widget)
570 {
571 EmacsFrame ew = (EmacsFrame) widget;
572 struct frame *f = ew->emacs_frame.frame;
573 int width, height;
574
575 pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
576
577 frame_size_history_add
578 (f, QEmacsFrameResize, width, height,
579 list2 (make_number (ew->core.width), make_number (ew->core.height)));
580
581 change_frame_size (f, width, height, 0, 1, 0, 1);
582
583 update_wm_hints (ew);
584 update_various_frame_slots (ew);
585
586 cancel_mouse_face (f);
587 }
588
589 static XtGeometryResult
590 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *result)
591 {
592 EmacsFrame ew = (EmacsFrame) widget;
593
594 int mask = request->request_mode;
595 Dimension ok_width, ok_height;
596
597 if (mask & (CWWidth | CWHeight))
598 {
599 round_size_to_char (ew,
600 (mask & CWWidth) ? request->width : ew->core.width,
601 ((mask & CWHeight) ? request->height
602 : ew->core.height),
603 &ok_width, &ok_height);
604 if ((mask & CWWidth) && (ok_width != request->width))
605 {
606 result->request_mode |= CWWidth;
607 result->width = ok_width;
608 }
609 if ((mask & CWHeight) && (ok_height != request->height))
610 {
611 result->request_mode |= CWHeight;
612 result->height = ok_height;
613 }
614 }
615 return result->request_mode ? XtGeometryAlmost : XtGeometryYes;
616 }
617
618 /* Special entry points */
619 void
620 EmacsFrameSetCharSize (Widget widget, int columns, int rows)
621 {
622 EmacsFrame ew = (EmacsFrame) widget;
623 struct frame *f = ew->emacs_frame.frame;
624
625 if (!frame_inhibit_resize (f, 0, Qfont)
626 && !frame_inhibit_resize (f, 1, Qfont))
627 x_set_window_size (f, 0, columns, rows, 0);
628 }
629
630 \f
631 void
632 widget_store_internal_border (Widget widget)
633 {
634 EmacsFrame ew = (EmacsFrame) widget;
635 struct frame *f = ew->emacs_frame.frame;
636
637 ew->emacs_frame.internal_border_width = f->internal_border_width;
638 }