gnus-art.el: Rewrite the Date header formatting functionality.
[emacs/old-mirror.git] / lwlib / lwlib-Xaw.c
blobcf98a37196873ceb303fcfd7533a7235ba3dbf9d
1 /* The lwlib interface to Athena widgets.
2 Copyright (C) 1993 Chuck Thompson <cthomp@cs.uiuc.edu>
3 Copyright (C) 1994, 2001-2011 Free Software Foundation, Inc.
5 This file is part of the Lucid Widget Library.
7 The Lucid Widget Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
10 any later version.
12 The Lucid Widget Library 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; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <stdio.h>
27 #include <setjmp.h>
28 #include <ctype.h>
30 #include "../src/lisp.h"
32 #include "lwlib-Xaw.h"
34 #include <X11/StringDefs.h>
35 #include <X11/IntrinsicP.h>
36 #include <X11/CoreP.h>
37 #include <X11/Shell.h>
39 #ifdef HAVE_XAW3D
40 #include <X11/Xaw3d/Scrollbar.h>
41 #include <X11/Xaw3d/Paned.h>
42 #include <X11/Xaw3d/Dialog.h>
43 #include <X11/Xaw3d/Form.h>
44 #include <X11/Xaw3d/Command.h>
45 #include <X11/Xaw3d/Label.h>
46 #else /* !HAVE_XAW3D */
47 #include <X11/Xaw/Scrollbar.h>
48 #include <X11/Xaw/Paned.h>
49 #include <X11/Xaw/Dialog.h>
50 #include <X11/Xaw/Form.h>
51 #include <X11/Xaw/Command.h>
52 #include <X11/Xaw/Label.h>
53 #endif /* HAVE_XAW3D */
55 #include <X11/Xatom.h>
57 #ifdef HAVE_XFT
58 #include <X11/Xft/Xft.h>
60 struct widget_xft_data
62 Widget widget;
63 XftFont *xft_font;
64 XftDraw *xft_draw;
65 XftColor xft_fg, xft_bg;
66 int p_width, p_height;
67 Pixmap p;
71 #endif
73 static void xaw_generic_callback (Widget widget,
74 XtPointer closure,
75 XtPointer call_data);
78 Boolean
79 lw_xaw_widget_p (Widget widget)
81 return (XtIsSubclass (widget, scrollbarWidgetClass) ||
82 XtIsSubclass (widget, dialogWidgetClass));
86 #ifdef HAVE_XFT
87 static void
88 fill_xft_data (struct widget_xft_data *data, Widget widget, XftFont *font)
90 Pixel bg, fg;
91 XColor colors[2];
93 data->widget = widget;
94 data->xft_font = font;
95 XtVaGetValues (widget,
96 XtNbackground, &bg,
97 XtNforeground, &fg,
98 NULL);
100 colors[0].pixel = data->xft_fg.pixel = fg;
101 colors[1].pixel = data->xft_bg.pixel = bg;
102 XQueryColors (XtDisplay (widget),
103 DefaultColormapOfScreen (XtScreen (widget)),
104 colors, 2);
106 data->xft_fg.color.alpha = 0xFFFF;
107 data->xft_fg.color.red = colors[0].red;
108 data->xft_fg.color.green = colors[0].green;
109 data->xft_fg.color.blue = colors[0].blue;
110 data->xft_bg.color.alpha = 0xFFFF;
111 data->xft_bg.color.red = colors[1].red;
112 data->xft_bg.color.green = colors[1].green;
113 data->xft_bg.color.blue = colors[1].blue;
115 data->p = None;
116 data->xft_draw = 0;
117 data->p_width = data->p_height = 0;
120 static XftFont*
121 openFont (Widget widget, char *name)
123 char *fname = name;
124 int screen = XScreenNumberOfScreen (XtScreen (widget));
125 int len = strlen (fname), i = len-1;
126 XftFont *fn;
128 /* Try to convert Gtk-syntax (Sans 9) to Xft syntax Sans-9. */
129 while (i > 0 && isdigit (fname[i]))
130 --i;
131 if (fname[i] == ' ')
133 fname = xstrdup (name);
134 fname[i] = '-';
137 fn = XftFontOpenName (XtDisplay (widget), screen, fname);
138 if (fname != name) free (fname);
140 return fn;
143 static int
144 get_text_width_and_height (Widget widget, char *text,
145 XftFont *xft_font,
146 int *height)
148 int w = 0, h = 0;
149 char *bp = text;
151 while (bp && *bp != '\0')
153 XGlyphInfo gi;
154 char *cp = strchr (bp, '\n');
155 XftTextExtentsUtf8 (XtDisplay (widget), xft_font,
156 (FcChar8 *) bp,
157 cp ? cp - bp : strlen (bp),
158 &gi);
159 bp = cp ? cp + 1 : NULL;
160 h += xft_font->height;
161 if (w < gi.width) w = gi.width;
164 *height = h;
165 return w;
168 static void
169 draw_text (struct widget_xft_data *data, char *lbl, int inverse)
171 Screen *sc = XtScreen (data->widget);
172 int screen = XScreenNumberOfScreen (sc);
173 int y = data->xft_font->ascent;
174 int x = inverse ? 0 : 2;
175 char *bp = lbl;
177 data->xft_draw = XftDrawCreate (XtDisplay (data->widget),
178 data->p,
179 DefaultVisual (XtDisplay (data->widget),
180 screen),
181 DefaultColormapOfScreen (sc));
182 XftDrawRect (data->xft_draw,
183 inverse ? &data->xft_fg : &data->xft_bg,
184 0, 0, data->p_width, data->p_height);
186 if (!inverse) y += 2;
187 while (bp && *bp != '\0')
189 char *cp = strchr (bp, '\n');
190 XftDrawStringUtf8 (data->xft_draw,
191 inverse ? &data->xft_bg : &data->xft_fg,
192 data->xft_font, x, y,
193 (FcChar8 *) bp,
194 cp ? cp - bp : strlen (bp));
195 bp = cp ? cp + 1 : NULL;
196 /* 1.2 gives reasonable line spacing. */
197 y += data->xft_font->height * 1.2;
203 static void
204 set_text (struct widget_xft_data *data, Widget toplevel, char *lbl, int margin)
206 int width, height;
208 width = get_text_width_and_height (data->widget, lbl, data->xft_font,
209 &height);
210 data->p_width = width + margin;
211 data->p_height = height + margin;
213 data->p = XCreatePixmap (XtDisplay (data->widget),
214 XtWindow (toplevel),
215 data->p_width,
216 data->p_height,
217 DefaultDepthOfScreen (XtScreen (data->widget)));
218 draw_text (data, lbl, 0);
219 XtVaSetValues (data->widget, XtNbitmap, data->p, NULL);
222 static struct widget_xft_data *
223 find_xft_data (Widget widget)
225 widget_instance *inst = NULL;
226 Widget parent = XtParent (widget);
227 struct widget_xft_data *data = NULL;
228 int nr;
229 while (parent && !inst)
231 inst = lw_get_widget_instance (parent);
232 parent = XtParent (parent);
234 if (!inst || !inst->xft_data || !inst->xft_data[0].xft_font) return 0;
236 for (nr = 0; data == NULL && nr < inst->nr_xft_data; ++nr)
238 if (inst->xft_data[nr].widget == widget)
239 data = &inst->xft_data[nr];
242 return data;
245 static void
246 command_press (Widget widget,
247 XEvent* event,
248 String *params,
249 Cardinal *num_params)
251 struct widget_xft_data *data = find_xft_data (widget);
252 if (data)
254 char *lbl;
255 /* Since this isn't used for rectangle buttons, use it to for armed. */
256 XtVaSetValues (widget, XtNcornerRoundPercent, 1, NULL);
258 XtVaGetValues (widget, XtNlabel, &lbl, NULL);
259 draw_text (data, lbl, 1);
263 static void
264 command_reset (Widget widget,
265 XEvent* event,
266 String *params,
267 Cardinal *num_params)
269 struct widget_xft_data *data = find_xft_data (widget);
270 if (data)
272 Dimension cr;
273 XtVaGetValues (widget, XtNcornerRoundPercent, &cr, NULL);
274 if (cr == 1)
276 char *lbl;
277 XtVaSetValues (widget, XtNcornerRoundPercent, 0, NULL);
278 XtVaGetValues (widget, XtNlabel, &lbl, NULL);
279 draw_text (data, lbl, 0);
285 #endif
287 void
288 xaw_update_one_widget (widget_instance *instance,
289 Widget widget,
290 widget_value *val,
291 Boolean deep_p)
293 if (XtIsSubclass (widget, dialogWidgetClass))
296 #ifdef HAVE_XFT
297 if (instance->xft_data && instance->xft_data[0].xft_font)
299 set_text (&instance->xft_data[0], instance->parent,
300 val->contents->value, 10);
302 #endif
303 XtVaSetValues (widget, XtNlabel, val->contents->value, NULL);
305 else if (XtIsSubclass (widget, commandWidgetClass))
307 Dimension bw = 0;
308 Arg al[10];
309 int ac = 0;
311 XtVaGetValues (widget, XtNborderWidth, &bw, NULL);
312 if (bw == 0)
313 /* Don't let buttons end up with 0 borderwidth, that's ugly...
314 Yeah, all this should really be done through app-defaults files
315 or fallback resources, but that's a whole different can of worms
316 that I don't feel like opening right now. Making Athena widgets
317 not look like shit is just entirely too much work.
320 XtSetArg (al[0], XtNborderWidth, 1);
321 XtSetValues (widget, al, 1);
324 XtSetSensitive (widget, val->enabled);
325 XtSetArg (al[ac], XtNlabel, val->value);ac++;
326 /* Force centered button text. Se above. */
327 XtSetArg (al[ac], XtNjustify, XtJustifyCenter);ac++;
328 #ifdef HAVE_XFT
329 if (instance->xft_data && instance->xft_data[0].xft_font)
331 int th;
332 int nr;
333 for (nr = 0; nr < instance->nr_xft_data; ++nr)
334 if (instance->xft_data[nr].widget == widget)
335 break;
336 if (nr < instance->nr_xft_data)
338 set_text (&instance->xft_data[nr], instance->parent,
339 val->value, 6);
341 /* Must set internalHeight to twice the highlight thickness,
342 or else it gets overwritten by our pixmap. Probably a bug. */
343 XtVaGetValues (widget, XtNhighlightThickness, &th, NULL);
344 XtSetArg (al[ac], XtNinternalHeight, 2*th);ac++;
347 #endif
348 XtSetValues (widget, al, ac);
349 XtRemoveAllCallbacks (widget, XtNcallback);
350 XtAddCallback (widget, XtNcallback, xaw_generic_callback, instance);
354 void
355 xaw_update_one_value (widget_instance *instance,
356 Widget widget,
357 widget_value *val)
359 /* This function is not used by the scrollbars and those are the only
360 Athena widget implemented at the moment so do nothing. */
361 return;
364 void
365 xaw_destroy_instance (widget_instance *instance)
367 #ifdef HAVE_XFT
368 if (instance->xft_data)
370 int i;
371 for (i = 0; i < instance->nr_xft_data; ++i)
373 if (instance->xft_data[i].xft_draw)
374 XftDrawDestroy (instance->xft_data[i].xft_draw);
375 if (instance->xft_data[i].p != None)
377 XtVaSetValues (instance->xft_data[i].widget, XtNbitmap, None,
378 NULL);
379 XFreePixmap (XtDisplay (instance->widget),
380 instance->xft_data[i].p);
383 if (instance->xft_data[0].xft_font)
384 XftFontClose (XtDisplay (instance->widget),
385 instance->xft_data[0].xft_font);
386 free (instance->xft_data);
388 #endif
389 if (XtIsSubclass (instance->widget, dialogWidgetClass))
390 /* Need to destroy the Shell too. */
391 XtDestroyWidget (XtParent (instance->widget));
392 else
393 XtDestroyWidget (instance->widget);
396 void
397 xaw_popup_menu (Widget widget, XEvent *event)
399 /* An Athena menubar has not been implemented. */
400 return;
403 void
404 xaw_pop_instance (widget_instance *instance, Boolean up)
406 Widget widget = instance->widget;
408 if (up)
410 if (XtIsSubclass (widget, dialogWidgetClass))
412 /* For dialogs, we need to call XtPopup on the parent instead
413 of calling XtManageChild on the widget.
414 Also we need to hack the shell's WM_PROTOCOLS to get it to
415 understand what the close box is supposed to do!!
417 Display *dpy = XtDisplay (widget);
418 Widget shell = XtParent (widget);
419 Atom props [2];
420 int i = 0;
421 props [i++] = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
422 XChangeProperty (dpy, XtWindow (shell),
423 XInternAtom (dpy, "WM_PROTOCOLS", False),
424 XA_ATOM, 32, PropModeAppend,
425 (unsigned char *) props, i);
427 /* Center the widget in its parent. Why isn't this kind of crap
428 done automatically? I thought toolkits were supposed to make
429 life easier?
432 unsigned int x, y, w, h;
433 Widget topmost = instance->parent;
434 Arg args[2];
436 w = shell->core.width;
437 h = shell->core.height;
438 while (topmost->core.parent && XtIsRealized (topmost->core.parent))
439 topmost = topmost->core.parent;
440 if (topmost->core.width < w) x = topmost->core.x;
441 else x = topmost->core.x + ((topmost->core.width - w) / 2);
442 if (topmost->core.height < h) y = topmost->core.y;
443 else y = topmost->core.y + ((topmost->core.height - h) / 2);
444 /* Using XtMoveWidget caused the widget to come
445 out in the wrong place with vtwm.
446 Question of virtual vs real coords, perhaps. */
447 XtSetArg (args[0], XtNx, x);
448 XtSetArg (args[1], XtNy, y);
449 XtSetValues (shell, args, 2);
452 /* Finally, pop it up. */
453 XtPopup (shell, XtGrabNonexclusive);
455 else
456 XtManageChild (widget);
458 else
460 if (XtIsSubclass (widget, dialogWidgetClass))
461 XtUnmanageChild (XtParent (widget));
462 else
463 XtUnmanageChild (widget);
468 /* Dialog boxes */
470 static char overrideTrans[] =
471 "<Message>WM_PROTOCOLS: lwlib_delete_dialog()";
472 /* Dialogs pop down on any key press */
473 static char dialogOverride[] =
474 "<KeyPress>Escape: lwlib_delete_dialog()";
475 static void wm_delete_window (Widget w,
476 XEvent *event,
477 String *params,
478 Cardinal *num_params);
479 static XtActionsRec xaw_actions [] = {
480 {"lwlib_delete_dialog", wm_delete_window}
482 static Boolean actions_initted = False;
484 #ifdef HAVE_XFT
485 static XtActionsRec button_actions[] =
487 { "my_reset", command_reset },
488 { "my_press", command_press },
490 char buttonTrans[] =
491 "<Leave>: reset() my_reset()\n"
492 "<Btn1Down>: set() my_press()\n"
493 "<Btn1Up>: my_reset() notify() unset()\n";
494 #endif
496 static Widget
497 make_dialog (char* name,
498 Widget parent,
499 Boolean pop_up_p,
500 char* shell_title,
501 char* icon_name,
502 Boolean text_input_slot,
503 Boolean radio_box,
504 Boolean list,
505 int left_buttons,
506 int right_buttons,
507 widget_instance *instance)
509 Arg av [20];
510 int ac = 0;
511 int i, bc;
512 char button_name [255];
513 Widget shell;
514 Widget dialog;
515 Widget button;
516 XtTranslations override;
517 #ifdef HAVE_XFT
518 XftFont *xft_font = 0;
519 XtTranslations button_override;
520 #endif
522 if (! pop_up_p) abort (); /* not implemented */
523 if (text_input_slot) abort (); /* not implemented */
524 if (radio_box) abort (); /* not implemented */
525 if (list) abort (); /* not implemented */
527 if (! actions_initted)
529 XtAppContext app = XtWidgetToApplicationContext (parent);
530 XtAppAddActions (app, xaw_actions,
531 sizeof (xaw_actions) / sizeof (xaw_actions[0]));
532 #ifdef HAVE_XFT
533 XtAppAddActions (app, button_actions,
534 sizeof (button_actions) / sizeof (button_actions[0]));
535 #endif
536 actions_initted = True;
539 override = XtParseTranslationTable (overrideTrans);
541 ac = 0;
542 XtSetArg (av[ac], XtNtitle, shell_title); ac++;
543 XtSetArg (av[ac], XtNallowShellResize, True); ac++;
545 /* Don't allow any geometry request from the user. */
546 XtSetArg (av[ac], XtNgeometry, 0); ac++;
548 shell = XtCreatePopupShell ("dialog", transientShellWidgetClass,
549 parent, av, ac);
550 XtOverrideTranslations (shell, override);
552 ac = 0;
553 dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac);
554 override = XtParseTranslationTable (dialogOverride);
555 XtOverrideTranslations (dialog, override);
557 #ifdef HAVE_XFT
559 int num;
560 Widget *ch = NULL;
561 Widget w = 0;
562 XtVaGetValues (dialog,
563 XtNnumChildren, &num,
564 XtNchildren, &ch, NULL);
565 for (i = 0; i < num; ++i)
567 if (!XtIsSubclass (ch[i], commandWidgetClass)
568 && XtIsSubclass (ch[i], labelWidgetClass))
570 w = ch[i];
571 break;
574 instance->xft_data = 0;
575 instance->nr_xft_data = 0;
576 if (w)
578 XtResource rec[] =
579 { { "faceName", "FaceName", XtRString, sizeof(String), 0, XtRString,
580 (XtPointer)"Sans-14" }};
581 char *faceName;
582 XtVaGetSubresources (dialog, &faceName, "Dialog", "dialog",
583 rec, 1, (String)NULL);
584 if (strcmp ("none", faceName) != 0)
585 xft_font = openFont (dialog, faceName);
586 if (xft_font)
588 instance->nr_xft_data = left_buttons + right_buttons + 1;
589 instance->xft_data = calloc (instance->nr_xft_data,
590 sizeof(*instance->xft_data));
592 fill_xft_data (&instance->xft_data[0], w, xft_font);
596 button_override = XtParseTranslationTable (buttonTrans);
598 #endif
600 bc = 0;
601 button = 0;
602 for (i = 0; i < left_buttons; i++)
604 ac = 0;
605 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
606 XtSetArg (av [ac], XtNleft, XtChainLeft); ac++;
607 XtSetArg (av [ac], XtNright, XtChainLeft); ac++;
608 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
609 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
610 XtSetArg (av [ac], XtNresizable, True); ac++;
611 #ifdef HAVE_XAW3D
612 if (DefaultDepthOfScreen (XtScreen (dialog)) >= 16)
614 /* Turn of dithered shadow if we can. Looks bad */
615 XtSetArg (av [ac], "beNiceToColormap", False); ac++;
617 #endif
618 sprintf (button_name, "button%d", ++bc);
619 button = XtCreateManagedWidget (button_name, commandWidgetClass,
620 dialog, av, ac);
621 #ifdef HAVE_XFT
622 if (xft_font)
624 fill_xft_data (&instance->xft_data[bc], button, xft_font);
625 XtOverrideTranslations (button, button_override);
627 #endif
630 for (i = 0; i < right_buttons; i++)
632 ac = 0;
633 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
634 if (i == 0)
636 /* Separator to the other buttons. */
637 XtSetArg (av [ac], XtNhorizDistance, 30); ac++;
639 XtSetArg (av [ac], XtNleft, XtChainRight); ac++;
640 XtSetArg (av [ac], XtNright, XtChainRight); ac++;
641 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
642 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
643 XtSetArg (av [ac], XtNresizable, True); ac++;
644 #ifdef HAVE_XAW3D
645 if (DefaultDepthOfScreen (XtScreen (dialog)) >= 16)
647 /* Turn of dithered shadow if we can. Looks bad */
648 XtSetArg (av [ac], "beNiceToColormap", False); ac++;
650 #endif
651 sprintf (button_name, "button%d", ++bc);
652 button = XtCreateManagedWidget (button_name, commandWidgetClass,
653 dialog, av, ac);
654 #ifdef HAVE_XFT
655 if (xft_font)
657 fill_xft_data (&instance->xft_data[bc], button, xft_font);
658 XtOverrideTranslations (button, button_override);
660 #endif
663 return dialog;
666 Widget
667 xaw_create_dialog (widget_instance *instance)
669 char *name = instance->info->type;
670 Widget parent = instance->parent;
671 Widget widget;
672 Boolean pop_up_p = instance->pop_up_p;
673 char *shell_name = 0;
674 char *icon_name = 0;
675 Boolean text_input_slot = False;
676 Boolean radio_box = False;
677 Boolean list = False;
678 int total_buttons;
679 int left_buttons = 0;
680 int right_buttons = 1;
682 switch (name [0]) {
683 case 'E': case 'e':
684 icon_name = "dbox-error";
685 shell_name = "Error";
686 break;
688 case 'I': case 'i':
689 icon_name = "dbox-info";
690 shell_name = "Information";
691 break;
693 case 'L': case 'l':
694 list = True;
695 icon_name = "dbox-question";
696 shell_name = "Prompt";
697 break;
699 case 'P': case 'p':
700 text_input_slot = True;
701 icon_name = "dbox-question";
702 shell_name = "Prompt";
703 break;
705 case 'Q': case 'q':
706 icon_name = "dbox-question";
707 shell_name = "Question";
708 break;
711 total_buttons = name [1] - '0';
713 if (name [3] == 'T' || name [3] == 't')
715 text_input_slot = False;
716 radio_box = True;
718 else if (name [3])
719 right_buttons = name [4] - '0';
721 left_buttons = total_buttons - right_buttons;
723 widget = make_dialog (name, parent, pop_up_p,
724 shell_name, icon_name, text_input_slot, radio_box,
725 list, left_buttons, right_buttons, instance);
726 return widget;
730 static void
731 xaw_generic_callback (Widget widget, XtPointer closure, XtPointer call_data)
733 widget_instance *instance = (widget_instance *) closure;
734 Widget instance_widget;
735 LWLIB_ID id;
736 XtPointer user_data;
738 lw_internal_update_other_instances (widget, closure, call_data);
740 if (! instance)
741 return;
742 if (widget->core.being_destroyed)
743 return;
745 instance_widget = instance->widget;
746 if (!instance_widget)
747 return;
749 id = instance->info->id;
751 /* Damn! Athena doesn't give us a way to hang our own data on the
752 buttons, so we have to go find it... I guess this assumes that
753 all instances of a button have the same call data. */
755 widget_value *val = instance->info->val->contents;
756 char *name = XtName (widget);
757 while (val)
759 if (val->name && !strcmp (val->name, name))
760 break;
761 val = val->next;
763 if (! val) abort ();
764 user_data = val->call_data;
767 if (instance->info->selection_cb)
768 instance->info->selection_cb (widget, id, user_data);
771 static void
772 wm_delete_window (Widget w,
773 XEvent *event,
774 String *params,
775 Cardinal *num_params)
777 LWLIB_ID id;
778 Cardinal nkids;
779 int i;
780 Widget *kids = 0;
781 Widget widget = 0, shell;
783 if (XtIsSubclass (w, dialogWidgetClass))
784 shell = XtParent (w);
785 else
786 shell = w;
788 if (! XtIsSubclass (shell, shellWidgetClass))
789 abort ();
790 XtVaGetValues (shell, XtNnumChildren, &nkids, NULL);
791 XtVaGetValues (shell, XtNchildren, &kids, NULL);
792 if (!kids || !*kids)
793 abort ();
794 for (i = 0; i < nkids; i++)
796 widget = kids[i];
797 if (XtIsSubclass (widget, dialogWidgetClass))
798 break;
800 if (! widget) return;
802 id = lw_get_widget_id (widget);
803 if (! id) abort ();
806 widget_info *info = lw_get_widget_info (id);
807 if (! info) abort ();
808 if (info->selection_cb)
809 info->selection_cb (widget, id, (XtPointer) -1);
812 lw_destroy_all_widgets (id);
817 static Widget
818 xaw_create_main (widget_instance *instance)
820 Arg al[1];
821 int ac;
823 /* Create a vertical Paned to hold menubar */
824 ac = 0;
825 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
826 return XtCreateWidget (instance->info->name, panedWidgetClass,
827 instance->parent, al, ac);
830 widget_creation_entry
831 xaw_creation_table [] =
833 {"main", xaw_create_main},
834 {NULL, NULL}