New property dynamic-docstring-function for docstrings.
[emacs.git] / lwlib / lwlib-Xaw.c
blobd37fb70fdb8098dbeb5c9346ff5dab3241bac6c1
1 /* The lwlib interface to Athena widgets.
3 Copyright (C) 1993 Chuck Thompson <cthomp@cs.uiuc.edu>
4 Copyright (C) 1994, 2001-2012 Free Software Foundation, Inc.
6 This file is part of the Lucid Widget Library.
8 The Lucid Widget Library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
11 any later version.
13 The Lucid Widget Library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include <config.h>
25 #include <stdio.h>
26 #include <setjmp.h>
28 #include <lisp.h>
30 #include "lwlib-Xaw.h"
32 #include <X11/StringDefs.h>
33 #include <X11/IntrinsicP.h>
34 #include <X11/CoreP.h>
35 #include <X11/Shell.h>
37 #ifdef HAVE_XAW3D
38 #include <X11/Xaw3d/Scrollbar.h>
39 #include <X11/Xaw3d/Paned.h>
40 #include <X11/Xaw3d/Dialog.h>
41 #include <X11/Xaw3d/Form.h>
42 #include <X11/Xaw3d/Command.h>
43 #include <X11/Xaw3d/Label.h>
44 #else /* !HAVE_XAW3D */
45 #include <X11/Xaw/Scrollbar.h>
46 #include <X11/Xaw/Paned.h>
47 #include <X11/Xaw/Dialog.h>
48 #include <X11/Xaw/Form.h>
49 #include <X11/Xaw/Command.h>
50 #include <X11/Xaw/Label.h>
51 #endif /* HAVE_XAW3D */
53 #include <X11/Xatom.h>
55 #ifdef HAVE_XFT
56 #include <X11/Xft/Xft.h>
58 struct widget_xft_data
60 Widget widget;
61 XftFont *xft_font;
62 XftDraw *xft_draw;
63 XftColor xft_fg, xft_bg;
64 int p_width, p_height;
65 Pixmap p;
69 #endif
71 static void xaw_generic_callback (Widget widget,
72 XtPointer closure,
73 XtPointer call_data);
76 Boolean
77 lw_xaw_widget_p (Widget widget)
79 return (XtIsSubclass (widget, scrollbarWidgetClass) ||
80 XtIsSubclass (widget, dialogWidgetClass));
84 #ifdef HAVE_XFT
85 static void
86 fill_xft_data (struct widget_xft_data *data, Widget widget, XftFont *font)
88 Pixel bg, fg;
89 XColor colors[2];
91 data->widget = widget;
92 data->xft_font = font;
93 XtVaGetValues (widget,
94 XtNbackground, &bg,
95 XtNforeground, &fg,
96 NULL);
98 colors[0].pixel = data->xft_fg.pixel = fg;
99 colors[1].pixel = data->xft_bg.pixel = bg;
100 XQueryColors (XtDisplay (widget),
101 DefaultColormapOfScreen (XtScreen (widget)),
102 colors, 2);
104 data->xft_fg.color.alpha = 0xFFFF;
105 data->xft_fg.color.red = colors[0].red;
106 data->xft_fg.color.green = colors[0].green;
107 data->xft_fg.color.blue = colors[0].blue;
108 data->xft_bg.color.alpha = 0xFFFF;
109 data->xft_bg.color.red = colors[1].red;
110 data->xft_bg.color.green = colors[1].green;
111 data->xft_bg.color.blue = colors[1].blue;
113 data->p = None;
114 data->xft_draw = 0;
115 data->p_width = data->p_height = 0;
118 static XftFont*
119 openFont (Widget widget, char *name)
121 char *fname = name;
122 int screen = XScreenNumberOfScreen (XtScreen (widget));
123 int len = strlen (fname), i = len-1;
124 XftFont *fn;
126 /* Try to convert Gtk-syntax (Sans 9) to Xft syntax Sans-9. */
127 while (i > 0 && '0' <= fname[i] && fname[i] <= '9')
128 --i;
129 if (fname[i] == ' ')
131 fname = xstrdup (name);
132 fname[i] = '-';
135 fn = XftFontOpenName (XtDisplay (widget), screen, fname);
136 if (fname != name) xfree (fname);
138 return fn;
141 static int
142 get_text_width_and_height (Widget widget, char *text,
143 XftFont *xft_font,
144 int *height)
146 int w = 0, h = 0;
147 char *bp = text;
149 while (bp && *bp != '\0')
151 XGlyphInfo gi;
152 char *cp = strchr (bp, '\n');
153 XftTextExtentsUtf8 (XtDisplay (widget), xft_font,
154 (FcChar8 *) bp,
155 cp ? cp - bp : strlen (bp),
156 &gi);
157 bp = cp ? cp + 1 : NULL;
158 h += xft_font->height;
159 if (w < gi.width) w = gi.width;
162 *height = h;
163 return w;
166 static void
167 draw_text (struct widget_xft_data *data, char *lbl, int inverse)
169 Screen *sc = XtScreen (data->widget);
170 int screen = XScreenNumberOfScreen (sc);
171 int y = data->xft_font->ascent;
172 int x = inverse ? 0 : 2;
173 char *bp = lbl;
175 data->xft_draw = XftDrawCreate (XtDisplay (data->widget),
176 data->p,
177 DefaultVisual (XtDisplay (data->widget),
178 screen),
179 DefaultColormapOfScreen (sc));
180 XftDrawRect (data->xft_draw,
181 inverse ? &data->xft_fg : &data->xft_bg,
182 0, 0, data->p_width, data->p_height);
184 if (!inverse) y += 2;
185 while (bp && *bp != '\0')
187 char *cp = strchr (bp, '\n');
188 XftDrawStringUtf8 (data->xft_draw,
189 inverse ? &data->xft_bg : &data->xft_fg,
190 data->xft_font, x, y,
191 (FcChar8 *) bp,
192 cp ? cp - bp : strlen (bp));
193 bp = cp ? cp + 1 : NULL;
194 /* 1.2 gives reasonable line spacing. */
195 y += data->xft_font->height * 1.2;
201 static void
202 set_text (struct widget_xft_data *data, Widget toplevel, char *lbl, int margin)
204 int width, height;
206 width = get_text_width_and_height (data->widget, lbl, data->xft_font,
207 &height);
208 data->p_width = width + margin;
209 data->p_height = height + margin;
211 data->p = XCreatePixmap (XtDisplay (data->widget),
212 XtWindow (toplevel),
213 data->p_width,
214 data->p_height,
215 DefaultDepthOfScreen (XtScreen (data->widget)));
216 draw_text (data, lbl, 0);
217 XtVaSetValues (data->widget, XtNbitmap, data->p, NULL);
220 static struct widget_xft_data *
221 find_xft_data (Widget widget)
223 widget_instance *inst = NULL;
224 Widget parent = XtParent (widget);
225 struct widget_xft_data *data = NULL;
226 int nr;
227 while (parent && !inst)
229 inst = lw_get_widget_instance (parent);
230 parent = XtParent (parent);
232 if (!inst || !inst->xft_data || !inst->xft_data[0].xft_font) return 0;
234 for (nr = 0; data == NULL && nr < inst->nr_xft_data; ++nr)
236 if (inst->xft_data[nr].widget == widget)
237 data = &inst->xft_data[nr];
240 return data;
243 static void
244 command_press (Widget widget,
245 XEvent* event,
246 String *params,
247 Cardinal *num_params)
249 struct widget_xft_data *data = find_xft_data (widget);
250 if (data)
252 char *lbl;
253 /* Since this isn't used for rectangle buttons, use it to for armed. */
254 XtVaSetValues (widget, XtNcornerRoundPercent, 1, NULL);
256 XtVaGetValues (widget, XtNlabel, &lbl, NULL);
257 draw_text (data, lbl, 1);
261 static void
262 command_reset (Widget widget,
263 XEvent* event,
264 String *params,
265 Cardinal *num_params)
267 struct widget_xft_data *data = find_xft_data (widget);
268 if (data)
270 Dimension cr;
271 XtVaGetValues (widget, XtNcornerRoundPercent, &cr, NULL);
272 if (cr == 1)
274 char *lbl;
275 XtVaSetValues (widget, XtNcornerRoundPercent, 0, NULL);
276 XtVaGetValues (widget, XtNlabel, &lbl, NULL);
277 draw_text (data, lbl, 0);
283 #endif
285 void
286 xaw_update_one_widget (widget_instance *instance,
287 Widget widget,
288 widget_value *val,
289 Boolean deep_p)
291 if (XtIsSubclass (widget, dialogWidgetClass))
294 #ifdef HAVE_XFT
295 if (instance->xft_data && instance->xft_data[0].xft_font)
297 set_text (&instance->xft_data[0], instance->parent,
298 val->contents->value, 10);
300 #endif
301 XtVaSetValues (widget, XtNlabel, val->contents->value, NULL);
303 else if (XtIsSubclass (widget, commandWidgetClass))
305 Dimension bw = 0;
306 Arg al[10];
307 int ac = 0;
309 XtVaGetValues (widget, XtNborderWidth, &bw, NULL);
310 if (bw == 0)
311 /* Don't let buttons end up with 0 borderwidth, that's ugly...
312 Yeah, all this should really be done through app-defaults files
313 or fallback resources, but that's a whole different can of worms
314 that I don't feel like opening right now. Making Athena widgets
315 not look like shit is just entirely too much work.
318 XtSetArg (al[0], XtNborderWidth, 1);
319 XtSetValues (widget, al, 1);
322 XtSetSensitive (widget, val->enabled);
323 XtSetArg (al[ac], XtNlabel, val->value);ac++;
324 /* Force centered button text. Se above. */
325 XtSetArg (al[ac], XtNjustify, XtJustifyCenter);ac++;
326 #ifdef HAVE_XFT
327 if (instance->xft_data && instance->xft_data[0].xft_font)
329 int th;
330 int nr;
331 for (nr = 0; nr < instance->nr_xft_data; ++nr)
332 if (instance->xft_data[nr].widget == widget)
333 break;
334 if (nr < instance->nr_xft_data)
336 set_text (&instance->xft_data[nr], instance->parent,
337 val->value, 6);
339 /* Must set internalHeight to twice the highlight thickness,
340 or else it gets overwritten by our pixmap. Probably a bug. */
341 XtVaGetValues (widget, XtNhighlightThickness, &th, NULL);
342 XtSetArg (al[ac], XtNinternalHeight, 2*th);ac++;
345 #endif
346 XtSetValues (widget, al, ac);
347 XtRemoveAllCallbacks (widget, XtNcallback);
348 XtAddCallback (widget, XtNcallback, xaw_generic_callback, instance);
352 void
353 xaw_update_one_value (widget_instance *instance,
354 Widget widget,
355 widget_value *val)
357 /* This function is not used by the scrollbars and those are the only
358 Athena widget implemented at the moment so do nothing. */
359 return;
362 void
363 xaw_destroy_instance (widget_instance *instance)
365 #ifdef HAVE_XFT
366 if (instance->xft_data)
368 int i;
369 for (i = 0; i < instance->nr_xft_data; ++i)
371 if (instance->xft_data[i].xft_draw)
372 XftDrawDestroy (instance->xft_data[i].xft_draw);
373 if (instance->xft_data[i].p != None)
375 XtVaSetValues (instance->xft_data[i].widget, XtNbitmap, None,
376 NULL);
377 XFreePixmap (XtDisplay (instance->widget),
378 instance->xft_data[i].p);
381 if (instance->xft_data[0].xft_font)
382 XftFontClose (XtDisplay (instance->widget),
383 instance->xft_data[0].xft_font);
384 xfree (instance->xft_data);
386 #endif
387 if (XtIsSubclass (instance->widget, dialogWidgetClass))
388 /* Need to destroy the Shell too. */
389 XtDestroyWidget (XtParent (instance->widget));
390 else
391 XtDestroyWidget (instance->widget);
394 void
395 xaw_popup_menu (Widget widget, XEvent *event)
397 /* An Athena menubar has not been implemented. */
398 return;
401 void
402 xaw_pop_instance (widget_instance *instance, Boolean up)
404 Widget widget = instance->widget;
406 if (up)
408 if (XtIsSubclass (widget, dialogWidgetClass))
410 /* For dialogs, we need to call XtPopup on the parent instead
411 of calling XtManageChild on the widget.
412 Also we need to hack the shell's WM_PROTOCOLS to get it to
413 understand what the close box is supposed to do!!
415 Display *dpy = XtDisplay (widget);
416 Widget shell = XtParent (widget);
417 Atom props [2];
418 int i = 0;
419 props [i++] = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
420 XChangeProperty (dpy, XtWindow (shell),
421 XInternAtom (dpy, "WM_PROTOCOLS", False),
422 XA_ATOM, 32, PropModeAppend,
423 (unsigned char *) props, i);
425 /* Center the widget in its parent. Why isn't this kind of crap
426 done automatically? I thought toolkits were supposed to make
427 life easier?
430 unsigned int x, y, w, h;
431 Widget topmost = instance->parent;
432 Arg args[2];
434 w = shell->core.width;
435 h = shell->core.height;
436 while (topmost->core.parent && XtIsRealized (topmost->core.parent))
437 topmost = topmost->core.parent;
438 if (topmost->core.width < w) x = topmost->core.x;
439 else x = topmost->core.x + ((topmost->core.width - w) / 2);
440 if (topmost->core.height < h) y = topmost->core.y;
441 else y = topmost->core.y + ((topmost->core.height - h) / 2);
442 /* Using XtMoveWidget caused the widget to come
443 out in the wrong place with vtwm.
444 Question of virtual vs real coords, perhaps. */
445 XtSetArg (args[0], XtNx, x);
446 XtSetArg (args[1], XtNy, y);
447 XtSetValues (shell, args, 2);
450 /* Finally, pop it up. */
451 XtPopup (shell, XtGrabNonexclusive);
453 else
454 XtManageChild (widget);
456 else
458 if (XtIsSubclass (widget, dialogWidgetClass))
459 XtUnmanageChild (XtParent (widget));
460 else
461 XtUnmanageChild (widget);
466 /* Dialog boxes */
468 static char overrideTrans[] =
469 "<Message>WM_PROTOCOLS: lwlib_delete_dialog()";
470 /* Dialogs pop down on any key press */
471 static char dialogOverride[] =
472 "<KeyPress>Escape: lwlib_delete_dialog()";
473 static void wm_delete_window (Widget w,
474 XEvent *event,
475 String *params,
476 Cardinal *num_params);
477 static XtActionsRec xaw_actions [] = {
478 {"lwlib_delete_dialog", wm_delete_window}
480 static Boolean actions_initted = False;
482 #ifdef HAVE_XFT
483 static XtActionsRec button_actions[] =
485 { "my_reset", command_reset },
486 { "my_press", command_press },
488 char buttonTrans[] =
489 "<Leave>: reset() my_reset()\n"
490 "<Btn1Down>: set() my_press()\n"
491 "<Btn1Up>: my_reset() notify() unset()\n";
492 #endif
494 static Widget
495 make_dialog (char* name,
496 Widget parent,
497 Boolean pop_up_p,
498 char* shell_title,
499 char* icon_name,
500 Boolean text_input_slot,
501 Boolean radio_box,
502 Boolean list,
503 int left_buttons,
504 int right_buttons,
505 widget_instance *instance)
507 Arg av [20];
508 int ac = 0;
509 int i, bc;
510 char button_name [255];
511 Widget shell;
512 Widget dialog;
513 Widget button;
514 XtTranslations override;
515 #ifdef HAVE_XFT
516 XftFont *xft_font = 0;
517 XtTranslations button_override;
518 #endif
520 if (! pop_up_p) abort (); /* not implemented */
521 if (text_input_slot) abort (); /* not implemented */
522 if (radio_box) abort (); /* not implemented */
523 if (list) abort (); /* not implemented */
525 if (! actions_initted)
527 XtAppContext app = XtWidgetToApplicationContext (parent);
528 XtAppAddActions (app, xaw_actions,
529 sizeof (xaw_actions) / sizeof (xaw_actions[0]));
530 #ifdef HAVE_XFT
531 XtAppAddActions (app, button_actions,
532 sizeof (button_actions) / sizeof (button_actions[0]));
533 #endif
534 actions_initted = True;
537 override = XtParseTranslationTable (overrideTrans);
539 ac = 0;
540 XtSetArg (av[ac], XtNtitle, shell_title); ac++;
541 XtSetArg (av[ac], XtNallowShellResize, True); ac++;
543 /* Don't allow any geometry request from the user. */
544 XtSetArg (av[ac], XtNgeometry, 0); ac++;
546 shell = XtCreatePopupShell ("dialog", transientShellWidgetClass,
547 parent, av, ac);
548 XtOverrideTranslations (shell, override);
550 ac = 0;
551 dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac);
552 override = XtParseTranslationTable (dialogOverride);
553 XtOverrideTranslations (dialog, override);
555 #ifdef HAVE_XFT
557 int num;
558 Widget *ch = NULL;
559 Widget w = 0;
560 XtVaGetValues (dialog,
561 XtNnumChildren, &num,
562 XtNchildren, &ch, NULL);
563 for (i = 0; i < num; ++i)
565 if (!XtIsSubclass (ch[i], commandWidgetClass)
566 && XtIsSubclass (ch[i], labelWidgetClass))
568 w = ch[i];
569 break;
572 instance->xft_data = 0;
573 instance->nr_xft_data = 0;
574 if (w)
576 XtResource rec[] =
577 { { "font", "Font", XtRString, sizeof(String), 0, XtRString,
578 (XtPointer)"Sans-10" }};
579 char *fontName = NULL;
580 XtVaGetSubresources (dialog, &fontName, "Dialog", "dialog",
581 rec, 1, (String)NULL);
582 if (fontName)
584 XFontStruct *xfn = XLoadQueryFont (XtDisplay (dialog), fontName);
585 if (!xfn)
586 xft_font = openFont (dialog, fontName);
587 else
588 XFreeFont (XtDisplay (dialog), xfn);
591 if (xft_font)
593 instance->nr_xft_data = left_buttons + right_buttons + 1;
594 instance->xft_data = calloc (instance->nr_xft_data,
595 sizeof(*instance->xft_data));
597 fill_xft_data (&instance->xft_data[0], w, xft_font);
601 button_override = XtParseTranslationTable (buttonTrans);
603 #endif
605 bc = 0;
606 button = 0;
607 for (i = 0; i < left_buttons; i++)
609 ac = 0;
610 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
611 XtSetArg (av [ac], XtNleft, XtChainLeft); ac++;
612 XtSetArg (av [ac], XtNright, XtChainLeft); ac++;
613 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
614 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
615 XtSetArg (av [ac], XtNresizable, True); ac++;
616 #ifdef HAVE_XAW3D
617 if (DefaultDepthOfScreen (XtScreen (dialog)) >= 16)
619 /* Turn of dithered shadow if we can. Looks bad */
620 XtSetArg (av [ac], "beNiceToColormap", False); ac++;
622 #endif
623 sprintf (button_name, "button%d", ++bc);
624 button = XtCreateManagedWidget (button_name, commandWidgetClass,
625 dialog, av, ac);
626 #ifdef HAVE_XFT
627 if (xft_font)
629 fill_xft_data (&instance->xft_data[bc], button, xft_font);
630 XtOverrideTranslations (button, button_override);
632 #endif
635 for (i = 0; i < right_buttons; i++)
637 ac = 0;
638 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
639 if (i == 0)
641 /* Separator to the other buttons. */
642 XtSetArg (av [ac], XtNhorizDistance, 30); ac++;
644 XtSetArg (av [ac], XtNleft, XtChainRight); ac++;
645 XtSetArg (av [ac], XtNright, XtChainRight); ac++;
646 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
647 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
648 XtSetArg (av [ac], XtNresizable, True); ac++;
649 #ifdef HAVE_XAW3D
650 if (DefaultDepthOfScreen (XtScreen (dialog)) >= 16)
652 /* Turn of dithered shadow if we can. Looks bad */
653 XtSetArg (av [ac], "beNiceToColormap", False); ac++;
655 #endif
656 sprintf (button_name, "button%d", ++bc);
657 button = XtCreateManagedWidget (button_name, commandWidgetClass,
658 dialog, av, ac);
659 #ifdef HAVE_XFT
660 if (xft_font)
662 fill_xft_data (&instance->xft_data[bc], button, xft_font);
663 XtOverrideTranslations (button, button_override);
665 #endif
668 return dialog;
671 Widget
672 xaw_create_dialog (widget_instance *instance)
674 char *name = instance->info->type;
675 Widget parent = instance->parent;
676 Widget widget;
677 Boolean pop_up_p = instance->pop_up_p;
678 char *shell_name = 0;
679 char *icon_name = 0;
680 Boolean text_input_slot = False;
681 Boolean radio_box = False;
682 Boolean list = False;
683 int total_buttons;
684 int left_buttons = 0;
685 int right_buttons = 1;
687 switch (name [0]) {
688 case 'E': case 'e':
689 icon_name = "dbox-error";
690 shell_name = "Error";
691 break;
693 case 'I': case 'i':
694 icon_name = "dbox-info";
695 shell_name = "Information";
696 break;
698 case 'L': case 'l':
699 list = True;
700 icon_name = "dbox-question";
701 shell_name = "Prompt";
702 break;
704 case 'P': case 'p':
705 text_input_slot = True;
706 icon_name = "dbox-question";
707 shell_name = "Prompt";
708 break;
710 case 'Q': case 'q':
711 icon_name = "dbox-question";
712 shell_name = "Question";
713 break;
716 total_buttons = name [1] - '0';
718 if (name [3] == 'T' || name [3] == 't')
720 text_input_slot = False;
721 radio_box = True;
723 else if (name [3])
724 right_buttons = name [4] - '0';
726 left_buttons = total_buttons - right_buttons;
728 widget = make_dialog (name, parent, pop_up_p,
729 shell_name, icon_name, text_input_slot, radio_box,
730 list, left_buttons, right_buttons, instance);
731 return widget;
735 static void
736 xaw_generic_callback (Widget widget, XtPointer closure, XtPointer call_data)
738 widget_instance *instance = (widget_instance *) closure;
739 Widget instance_widget;
740 LWLIB_ID id;
741 XtPointer user_data;
743 lw_internal_update_other_instances (widget, closure, call_data);
745 if (! instance)
746 return;
747 if (widget->core.being_destroyed)
748 return;
750 instance_widget = instance->widget;
751 if (!instance_widget)
752 return;
754 id = instance->info->id;
756 /* Damn! Athena doesn't give us a way to hang our own data on the
757 buttons, so we have to go find it... I guess this assumes that
758 all instances of a button have the same call data. */
760 widget_value *val = instance->info->val->contents;
761 char *name = XtName (widget);
762 while (val)
764 if (val->name && !strcmp (val->name, name))
765 break;
766 val = val->next;
768 if (! val) abort ();
769 user_data = val->call_data;
772 if (instance->info->selection_cb)
773 instance->info->selection_cb (widget, id, user_data);
776 static void
777 wm_delete_window (Widget w,
778 XEvent *event,
779 String *params,
780 Cardinal *num_params)
782 LWLIB_ID id;
783 Cardinal nkids;
784 int i;
785 Widget *kids = 0;
786 Widget widget = 0, shell;
788 if (XtIsSubclass (w, dialogWidgetClass))
789 shell = XtParent (w);
790 else
791 shell = w;
793 if (! XtIsSubclass (shell, shellWidgetClass))
794 abort ();
795 XtVaGetValues (shell, XtNnumChildren, &nkids, NULL);
796 XtVaGetValues (shell, XtNchildren, &kids, NULL);
797 if (!kids || !*kids)
798 abort ();
799 for (i = 0; i < nkids; i++)
801 widget = kids[i];
802 if (XtIsSubclass (widget, dialogWidgetClass))
803 break;
805 if (! widget) return;
807 id = lw_get_widget_id (widget);
808 if (! id) abort ();
811 widget_info *info = lw_get_widget_info (id);
812 if (! info) abort ();
813 if (info->selection_cb)
814 info->selection_cb (widget, id, (XtPointer) -1);
817 lw_destroy_all_widgets (id);
822 static Widget
823 xaw_create_main (widget_instance *instance)
825 Arg al[1];
826 int ac;
828 /* Create a vertical Paned to hold menubar */
829 ac = 0;
830 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
831 return XtCreateWidget (instance->info->name, panedWidgetClass,
832 instance->parent, al, ac);
835 widget_creation_entry
836 xaw_creation_table [] =
838 {"main", xaw_create_main},
839 {NULL, NULL}