Add 2010 to copyright years.
[bpt/emacs.git] / lwlib / lwlib-Xaw.c
CommitLineData
b70cfce2 1/* The lwlib interface to Athena widgets.
4424d48a
GM
2Copyright (C) 1993 Chuck Thompson <cthomp@cs.uiuc.edu>
3Copyright (C) 1994, 2001, 2002, 2003, 2004, 2005, 2006,
114f9c96 4 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
b70cfce2
FP
5
6This file is part of the Lucid Widget Library.
7
177c0ea7 8The Lucid Widget Library is free software; you can redistribute it and/or
b70cfce2
FP
9modify it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 1, or (at your option)
11any later version.
12
13The Lucid Widget Library is distributed in the hope that it will be useful,
177c0ea7 14but WITHOUT ANY WARRANTY; without even the implied warranty of
b70cfce2
FP
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Emacs; see the file COPYING. If not, write to
364c38d3
LK
20the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21Boston, MA 02110-1301, USA. */
b70cfce2 22
0f0912e6
PE
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
b70cfce2 27#include <stdio.h>
d7306fe6 28#include <setjmp.h>
b70cfce2 29
2f96293d
RS
30#include "../src/lisp.h"
31
b70cfce2
FP
32#include "lwlib-Xaw.h"
33
34#include <X11/StringDefs.h>
35#include <X11/IntrinsicP.h>
36#include <X11/CoreP.h>
37#include <X11/Shell.h>
38
5262c5c7
CY
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 */
b70cfce2
FP
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>
5262c5c7 53#endif /* HAVE_XAW3D */
b70cfce2
FP
54
55#include <X11/Xatom.h>
56
79140ef0 57static void xaw_generic_callback (/*Widget, XtPointer, XtPointer*/);
b70cfce2
FP
58
59
60Boolean
e14e13a4
FP
61lw_xaw_widget_p (widget)
62 Widget widget;
b70cfce2
FP
63{
64 return (XtIsSubclass (widget, scrollbarWidgetClass) ||
65 XtIsSubclass (widget, dialogWidgetClass));
66}
67
abf0cb21 68#if 0
b70cfce2 69static void
e14e13a4
FP
70xaw_update_scrollbar (instance, widget, val)
71 widget_instance *instance;
72 Widget widget;
73 widget_value *val;
b70cfce2 74{
b70cfce2
FP
75 if (val->scrollbar_data)
76 {
77 scrollbar_values *data = val->scrollbar_data;
78 Dimension height, width;
79 Dimension pos_x, pos_y;
80 int widget_shown, widget_topOfThumb;
81 float new_shown, new_topOfThumb;
82
83 XtVaGetValues (widget,
84 XtNheight, &height,
85 XtNwidth, &width,
86 XtNx, &pos_x,
87 XtNy, &pos_y,
88 XtNtopOfThumb, &widget_topOfThumb,
89 XtNshown, &widget_shown,
8dd095ee 90 NULL);
b70cfce2
FP
91
92 /*
93 * First size and position the scrollbar widget.
94 * We need to position it to second-guess the Paned widget's notion
95 * of what should happen when the WMShell gets resized.
96 */
97 if (height != data->scrollbar_height || pos_y != data->scrollbar_pos)
98 {
99 XtConfigureWidget (widget, pos_x, data->scrollbar_pos,
100 width, data->scrollbar_height, 0);
101
102 XtVaSetValues (widget,
103 XtNlength, data->scrollbar_height,
104 XtNthickness, width,
8dd095ee 105 NULL);
b70cfce2
FP
106 }
107
108 /*
109 * Now the size the scrollbar's slider.
110 */
111 new_shown = (float) data->slider_size /
112 (float) (data->maximum - data->minimum);
113
114 new_topOfThumb = (float) (data->slider_position - data->minimum) /
115 (float) (data->maximum - data->minimum);
116
117 if (new_shown > 1.0)
118 new_shown = 1.0;
119 if (new_shown < 0)
120 new_shown = 0;
121
122 if (new_topOfThumb > 1.0)
123 new_topOfThumb = 1.0;
124 if (new_topOfThumb < 0)
125 new_topOfThumb = 0;
126
127 if (new_shown != widget_shown || new_topOfThumb != widget_topOfThumb)
128 XawScrollbarSetThumb (widget, new_topOfThumb, new_shown);
129 }
b70cfce2 130}
abf0cb21 131#endif
b70cfce2
FP
132
133void
207c13a7
DL
134#ifdef PROTOTYPES
135xaw_update_one_widget (widget_instance *instance, Widget widget,
136 widget_value *val, Boolean deep_p)
137#else
e14e13a4
FP
138xaw_update_one_widget (instance, widget, val, deep_p)
139 widget_instance *instance;
140 Widget widget;
141 widget_value *val;
142 Boolean deep_p;
207c13a7 143#endif
b70cfce2 144{
13162c0e 145#if 0
b70cfce2
FP
146 if (XtIsSubclass (widget, scrollbarWidgetClass))
147 {
148 xaw_update_scrollbar (instance, widget, val);
149 }
13162c0e
RS
150#endif
151 if (XtIsSubclass (widget, dialogWidgetClass))
b70cfce2 152 {
05041ba0
FP
153 Arg al[1];
154 int ac = 0;
155 XtSetArg (al[ac], XtNlabel, val->contents->value); ac++;
156 XtSetValues (widget, al, ac);
b70cfce2
FP
157 }
158 else if (XtIsSubclass (widget, commandWidgetClass))
159 {
160 Dimension bw = 0;
13162c0e
RS
161 Arg al[3];
162
8dd095ee 163 XtVaGetValues (widget, XtNborderWidth, &bw, NULL);
b70cfce2
FP
164 if (bw == 0)
165 /* Don't let buttons end up with 0 borderwidth, that's ugly...
166 Yeah, all this should really be done through app-defaults files
167 or fallback resources, but that's a whole different can of worms
168 that I don't feel like opening right now. Making Athena widgets
169 not look like shit is just entirely too much work.
170 */
13162c0e
RS
171 {
172 XtSetArg (al[0], XtNborderWidth, 1);
173 XtSetValues (widget, al, 1);
174 }
b70cfce2 175
2a73ab60 176 XtSetSensitive (widget, val->enabled);
13162c0e 177 XtSetArg (al[0], XtNlabel, val->value);
13162c0e 178 /* Force centered button text. Se above. */
2a73ab60
GM
179 XtSetArg (al[1], XtNjustify, XtJustifyCenter);
180 XtSetValues (widget, al, 2);
b70cfce2
FP
181 XtRemoveAllCallbacks (widget, XtNcallback);
182 XtAddCallback (widget, XtNcallback, xaw_generic_callback, instance);
183 }
184}
185
186void
e14e13a4
FP
187xaw_update_one_value (instance, widget, val)
188 widget_instance *instance;
189 Widget widget;
190 widget_value *val;
b70cfce2
FP
191{
192 /* This function is not used by the scrollbars and those are the only
193 Athena widget implemented at the moment so do nothing. */
194 return;
195}
196
197void
e14e13a4
FP
198xaw_destroy_instance (instance)
199 widget_instance *instance;
b70cfce2
FP
200{
201 if (XtIsSubclass (instance->widget, dialogWidgetClass))
202 /* Need to destroy the Shell too. */
203 XtDestroyWidget (XtParent (instance->widget));
204 else
205 XtDestroyWidget (instance->widget);
206}
207
208void
4374c6b0 209xaw_popup_menu (widget, event)
e14e13a4 210 Widget widget;
4374c6b0 211 XEvent *event;
b70cfce2
FP
212{
213 /* An Athena menubar has not been implemented. */
214 return;
215}
216
217void
207c13a7
DL
218#ifdef PROTOTYPES
219xaw_pop_instance (widget_instance *instance, Boolean up)
220#else
e14e13a4
FP
221xaw_pop_instance (instance, up)
222 widget_instance *instance;
223 Boolean up;
207c13a7 224#endif
b70cfce2
FP
225{
226 Widget widget = instance->widget;
227
228 if (up)
229 {
230 if (XtIsSubclass (widget, dialogWidgetClass))
231 {
232 /* For dialogs, we need to call XtPopup on the parent instead
233 of calling XtManageChild on the widget.
234 Also we need to hack the shell's WM_PROTOCOLS to get it to
235 understand what the close box is supposed to do!!
236 */
237 Display *dpy = XtDisplay (widget);
238 Widget shell = XtParent (widget);
239 Atom props [2];
240 int i = 0;
241 props [i++] = XInternAtom (dpy, "WM_DELETE_WINDOW", False);
242 XChangeProperty (dpy, XtWindow (shell),
243 XInternAtom (dpy, "WM_PROTOCOLS", False),
244 XA_ATOM, 32, PropModeAppend,
245 (unsigned char *) props, i);
246
247 /* Center the widget in its parent. Why isn't this kind of crap
248 done automatically? I thought toolkits were supposed to make
249 life easier?
250 */
251 {
e363091e 252 unsigned int x, y, w, h;
b70cfce2 253 Widget topmost = instance->parent;
2af91681
PR
254 Arg args[2];
255
b70cfce2
FP
256 w = shell->core.width;
257 h = shell->core.height;
258 while (topmost->core.parent && XtIsRealized (topmost->core.parent))
259 topmost = topmost->core.parent;
260 if (topmost->core.width < w) x = topmost->core.x;
261 else x = topmost->core.x + ((topmost->core.width - w) / 2);
262 if (topmost->core.height < h) y = topmost->core.y;
263 else y = topmost->core.y + ((topmost->core.height - h) / 2);
2af91681
PR
264 /* Using XtMoveWidget caused the widget to come
265 out in the wrong place with vtwm.
266 Question of virtual vs real coords, perhaps. */
267 XtSetArg (args[0], XtNx, x);
268 XtSetArg (args[1], XtNy, y);
269 XtSetValues (shell, args, 2);
b70cfce2
FP
270 }
271
272 /* Finally, pop it up. */
273 XtPopup (shell, XtGrabNonexclusive);
274 }
275 else
276 XtManageChild (widget);
277 }
278 else
279 {
280 if (XtIsSubclass (widget, dialogWidgetClass))
281 XtUnmanageChild (XtParent (widget));
282 else
283 XtUnmanageChild (widget);
284 }
285}
286
287\f
288/* Dialog boxes */
289
290static char overrideTrans[] =
291 "<Message>WM_PROTOCOLS: lwlib_delete_dialog()";
244c93fe
JD
292/* Dialogs pop down on any key press */
293static char dialogOverride[] =
4e6e2184 294 "<KeyPress>Escape: lwlib_delete_dialog()";
b70cfce2
FP
295static void wm_delete_window();
296static XtActionsRec xaw_actions [] = {
297 {"lwlib_delete_dialog", wm_delete_window}
298};
299static Boolean actions_initted = False;
300
301static Widget
e14e13a4
FP
302make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, radio_box, list, left_buttons, right_buttons)
303 char* name;
304 Widget parent;
305 Boolean pop_up_p;
306 char* shell_title;
307 char* icon_name;
308 Boolean text_input_slot;
309 Boolean radio_box;
310 Boolean list;
311 int left_buttons;
312 int right_buttons;
b70cfce2
FP
313{
314 Arg av [20];
315 int ac = 0;
316 int i, bc;
317 char button_name [255];
318 Widget shell;
319 Widget dialog;
320 Widget button;
321 XtTranslations override;
322
323 if (! pop_up_p) abort (); /* not implemented */
324 if (text_input_slot) abort (); /* not implemented */
325 if (radio_box) abort (); /* not implemented */
326 if (list) abort (); /* not implemented */
327
328 if (! actions_initted)
329 {
330 XtAppContext app = XtWidgetToApplicationContext (parent);
331 XtAppAddActions (app, xaw_actions,
332 sizeof (xaw_actions) / sizeof (xaw_actions[0]));
333 actions_initted = True;
334 }
335
336 override = XtParseTranslationTable (overrideTrans);
337
338 ac = 0;
339 XtSetArg (av[ac], XtNtitle, shell_title); ac++;
340 XtSetArg (av[ac], XtNallowShellResize, True); ac++;
dc49df96
FP
341
342 /* Don't allow any geometry request from the user. */
343 XtSetArg (av[ac], XtNgeometry, 0); ac++;
344
b70cfce2
FP
345 shell = XtCreatePopupShell ("dialog", transientShellWidgetClass,
346 parent, av, ac);
347 XtOverrideTranslations (shell, override);
348
349 ac = 0;
350 dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac);
244c93fe
JD
351 override = XtParseTranslationTable (dialogOverride);
352 XtOverrideTranslations (dialog, override);
b70cfce2
FP
353
354 bc = 0;
355 button = 0;
356 for (i = 0; i < left_buttons; i++)
357 {
358 ac = 0;
359 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
360 XtSetArg (av [ac], XtNleft, XtChainLeft); ac++;
361 XtSetArg (av [ac], XtNright, XtChainLeft); ac++;
362 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
363 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
364 XtSetArg (av [ac], XtNresizable, True); ac++;
365 sprintf (button_name, "button%d", ++bc);
366 button = XtCreateManagedWidget (button_name, commandWidgetClass,
367 dialog, av, ac);
368 }
369 if (right_buttons)
370 {
371 /* Create a separator
372
373 I want the separator to take up the slack between the buttons on
374 the right and the buttons on the left (that is I want the buttons
375 after the separator to be packed against the right edge of the
177c0ea7 376 window) but I can't seem to make it do it.
b70cfce2
FP
377 */
378 ac = 0;
379 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
380/* XtSetArg (av [ac], XtNfromVert, XtNameToWidget (dialog, "label")); ac++; */
381 XtSetArg (av [ac], XtNleft, XtChainLeft); ac++;
382 XtSetArg (av [ac], XtNright, XtChainRight); ac++;
383 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
384 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
385 XtSetArg (av [ac], XtNlabel, ""); ac++;
386 XtSetArg (av [ac], XtNwidth, 30); ac++; /* #### aaack!! */
387 XtSetArg (av [ac], XtNborderWidth, 0); ac++;
388 XtSetArg (av [ac], XtNshapeStyle, XmuShapeRectangle); ac++;
389 XtSetArg (av [ac], XtNresizable, False); ac++;
390 XtSetArg (av [ac], XtNsensitive, False); ac++;
391 button = XtCreateManagedWidget ("separator",
392 /* labelWidgetClass, */
393 /* This has to be Command to fake out
394 the Dialog widget... */
395 commandWidgetClass,
396 dialog, av, ac);
397 }
398 for (i = 0; i < right_buttons; i++)
399 {
400 ac = 0;
401 XtSetArg (av [ac], XtNfromHoriz, button); ac++;
402 XtSetArg (av [ac], XtNleft, XtChainRight); ac++;
403 XtSetArg (av [ac], XtNright, XtChainRight); ac++;
404 XtSetArg (av [ac], XtNtop, XtChainBottom); ac++;
405 XtSetArg (av [ac], XtNbottom, XtChainBottom); ac++;
406 XtSetArg (av [ac], XtNresizable, True); ac++;
407 sprintf (button_name, "button%d", ++bc);
408 button = XtCreateManagedWidget (button_name, commandWidgetClass,
409 dialog, av, ac);
410 }
411
412 return dialog;
413}
414
415Widget
e14e13a4
FP
416xaw_create_dialog (instance)
417 widget_instance* instance;
b70cfce2
FP
418{
419 char *name = instance->info->type;
420 Widget parent = instance->parent;
421 Widget widget;
422 Boolean pop_up_p = instance->pop_up_p;
423 char *shell_name = 0;
ca79970e 424 char *icon_name = 0;
b70cfce2
FP
425 Boolean text_input_slot = False;
426 Boolean radio_box = False;
427 Boolean list = False;
428 int total_buttons;
429 int left_buttons = 0;
430 int right_buttons = 1;
431
432 switch (name [0]) {
433 case 'E': case 'e':
434 icon_name = "dbox-error";
435 shell_name = "Error";
436 break;
437
438 case 'I': case 'i':
439 icon_name = "dbox-info";
440 shell_name = "Information";
441 break;
442
443 case 'L': case 'l':
444 list = True;
445 icon_name = "dbox-question";
446 shell_name = "Prompt";
447 break;
448
449 case 'P': case 'p':
450 text_input_slot = True;
451 icon_name = "dbox-question";
452 shell_name = "Prompt";
453 break;
454
455 case 'Q': case 'q':
456 icon_name = "dbox-question";
457 shell_name = "Question";
458 break;
459 }
177c0ea7 460
b70cfce2
FP
461 total_buttons = name [1] - '0';
462
463 if (name [3] == 'T' || name [3] == 't')
464 {
465 text_input_slot = False;
466 radio_box = True;
467 }
468 else if (name [3])
469 right_buttons = name [4] - '0';
177c0ea7 470
b70cfce2 471 left_buttons = total_buttons - right_buttons;
177c0ea7 472
b70cfce2
FP
473 widget = make_dialog (name, parent, pop_up_p,
474 shell_name, icon_name, text_input_slot, radio_box,
475 list, left_buttons, right_buttons);
476
477 return widget;
478}
479
480
481static void
e14e13a4
FP
482xaw_generic_callback (widget, closure, call_data)
483 Widget widget;
484 XtPointer closure;
485 XtPointer call_data;
b70cfce2
FP
486{
487 widget_instance *instance = (widget_instance *) closure;
488 Widget instance_widget;
489 LWLIB_ID id;
490 XtPointer user_data;
491
492 lw_internal_update_other_instances (widget, closure, call_data);
493
494 if (! instance)
495 return;
496 if (widget->core.being_destroyed)
497 return;
498
499 instance_widget = instance->widget;
500 if (!instance_widget)
501 return;
502
503 id = instance->info->id;
504
505#if 0
506 user_data = NULL;
8dd095ee 507 XtVaGetValues (widget, XtNuserData, &user_data, NULL);
b70cfce2
FP
508#else
509 /* Damn! Athena doesn't give us a way to hang our own data on the
510 buttons, so we have to go find it... I guess this assumes that
511 all instances of a button have the same call data. */
512 {
513 widget_value *val = instance->info->val->contents;
514 char *name = XtName (widget);
515 while (val)
516 {
517 if (val->name && !strcmp (val->name, name))
518 break;
519 val = val->next;
520 }
521 if (! val) abort ();
522 user_data = val->call_data;
523 }
524#endif
525
526 if (instance->info->selection_cb)
527 instance->info->selection_cb (widget, id, user_data);
528}
529
530static void
244c93fe
JD
531wm_delete_window (w, closure, call_data)
532 Widget w;
e14e13a4
FP
533 XtPointer closure;
534 XtPointer call_data;
b70cfce2
FP
535{
536 LWLIB_ID id;
8dce2ddc
RS
537 Cardinal nkids;
538 int i;
b70cfce2 539 Widget *kids = 0;
244c93fe
JD
540 Widget widget, shell;
541
542 if (XtIsSubclass (w, dialogWidgetClass))
543 shell = XtParent (w);
544 else
545 shell = w;
546
b70cfce2
FP
547 if (! XtIsSubclass (shell, shellWidgetClass))
548 abort ();
8dd095ee
GM
549 XtVaGetValues (shell, XtNnumChildren, &nkids, NULL);
550 XtVaGetValues (shell, XtNchildren, &kids, NULL);
b70cfce2
FP
551 if (!kids || !*kids)
552 abort ();
8dce2ddc
RS
553 for (i = 0; i < nkids; i++)
554 {
555 widget = kids[i];
556 if (XtIsSubclass (widget, dialogWidgetClass))
557 break;
558 }
b70cfce2
FP
559 id = lw_get_widget_id (widget);
560 if (! id) abort ();
561
562 {
563 widget_info *info = lw_get_widget_info (id);
564 if (! info) abort ();
565 if (info->selection_cb)
566 info->selection_cb (widget, id, (XtPointer) -1);
567 }
568
569 lw_destroy_all_widgets (id);
570}
571
572\f
573/* Scrollbars */
574
abf0cb21 575#if 0
b70cfce2 576static void
e14e13a4
FP
577xaw_scrollbar_scroll (widget, closure, call_data)
578 Widget widget;
579 XtPointer closure;
580 XtPointer call_data;
b70cfce2 581{
b70cfce2
FP
582 widget_instance *instance = (widget_instance *) closure;
583 LWLIB_ID id;
584 scroll_event event_data;
585
586 if (!instance || widget->core.being_destroyed)
587 return;
588
589 id = instance->info->id;
590 event_data.slider_value = 0;
591 event_data.time = 0;
592
593 if ((int) call_data > 0)
594 event_data.action = SCROLLBAR_PAGE_DOWN;
595 else
596 event_data.action = SCROLLBAR_PAGE_UP;
597
598 if (instance->info->pre_activate_cb)
599 instance->info->pre_activate_cb (widget, id, (XtPointer) &event_data);
b70cfce2 600}
abf0cb21 601#endif
b70cfce2 602
abf0cb21 603#if 0
b70cfce2 604static void
e14e13a4
FP
605xaw_scrollbar_jump (widget, closure, call_data)
606 Widget widget;
607 XtPointer closure;
608 XtPointer call_data;
b70cfce2 609{
b70cfce2
FP
610 widget_instance *instance = (widget_instance *) closure;
611 LWLIB_ID id;
612 scroll_event event_data;
613 scrollbar_values *val =
614 (scrollbar_values *) instance->info->val->scrollbar_data;
615 float percent;
616
617 if (!instance || widget->core.being_destroyed)
618 return;
619
620 id = instance->info->id;
621
622 percent = * (float *) call_data;
623 event_data.slider_value =
624 (int) (percent * (float) (val->maximum - val->minimum)) + val->minimum;
625
626 event_data.time = 0;
627 event_data.action = SCROLLBAR_DRAG;
628
629 if (instance->info->pre_activate_cb)
630 instance->info->pre_activate_cb (widget, id, (XtPointer) &event_data);
b70cfce2 631}
abf0cb21 632#endif
b70cfce2
FP
633
634static Widget
e14e13a4
FP
635xaw_create_scrollbar (instance)
636 widget_instance *instance;
b70cfce2
FP
637{
638#if 0
639 Arg av[20];
640 int ac = 0;
641 Dimension width;
642 Widget scrollbar;
643
8dd095ee 644 XtVaGetValues (instance->parent, XtNwidth, &width, NULL);
177c0ea7 645
b70cfce2
FP
646 XtSetArg (av[ac], XtNshowGrip, 0); ac++;
647 XtSetArg (av[ac], XtNresizeToPreferred, 1); ac++;
648 XtSetArg (av[ac], XtNallowResize, True); ac++;
649 XtSetArg (av[ac], XtNskipAdjust, True); ac++;
650 XtSetArg (av[ac], XtNwidth, width); ac++;
651 XtSetArg (av[ac], XtNmappedWhenManaged, True); ac++;
652
653 scrollbar =
654 XtCreateWidget (instance->info->name, scrollbarWidgetClass,
655 instance->parent, av, ac);
656
657 /* We have to force the border width to be 0 otherwise the
658 geometry manager likes to start looping for awhile... */
8dd095ee 659 XtVaSetValues (scrollbar, XtNborderWidth, 0, NULL);
b70cfce2
FP
660
661 XtRemoveAllCallbacks (scrollbar, "jumpProc");
662 XtRemoveAllCallbacks (scrollbar, "scrollProc");
663
664 XtAddCallback (scrollbar, "jumpProc", xaw_scrollbar_jump,
665 (XtPointer) instance);
666 XtAddCallback (scrollbar, "scrollProc", xaw_scrollbar_scroll,
667 (XtPointer) instance);
668
669 return scrollbar;
21dd28d4
GM
670#else
671 return NULL;
b70cfce2
FP
672#endif
673}
674
2af91681
PR
675static Widget
676xaw_create_main (instance)
677 widget_instance *instance;
678{
679 Arg al[1];
680 int ac;
681
682 /* Create a vertical Paned to hold menubar */
683 ac = 0;
684 XtSetArg (al[ac], XtNborderWidth, 0); ac++;
685 return XtCreateWidget (instance->info->name, panedWidgetClass,
686 instance->parent, al, ac);
687}
688
b70cfce2
FP
689widget_creation_entry
690xaw_creation_table [] =
691{
692 {"scrollbar", xaw_create_scrollbar},
2af91681 693 {"main", xaw_create_main},
b70cfce2
FP
694 {NULL, NULL}
695};
ab5796a9
MB
696
697/* arch-tag: fbbd3589-ae1c-41a0-9142-f628cfee6564
698 (do not change this comment) */