Convert function definitions in lwlib files to standard C.
[bpt/emacs.git] / lwlib / lwlib.c
CommitLineData
07bf635f 1/* A general interface to the widgets of different toolkits.
4424d48a
GM
2Copyright (C) 1992, 1993 Lucid, Inc.
3Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2003, 2004,
114f9c96 4 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
07bf635f
RS
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
07bf635f 9modify it under the terms of the GNU General Public License as published by
2aa86c0f 10the Free Software Foundation; either version 2, or (at your option)
07bf635f
RS
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
07bf635f
RS
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. */
07bf635f 22
0f0912e6
PE
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
d7306fe6 27#include <setjmp.h>
a3bf8a8c
RS
28#include "../src/lisp.h"
29
07bf635f 30#include <sys/types.h>
07bf635f 31#include <stdio.h>
5f61736f 32#include <ctype.h>
e7818b5a 33#include "lwlib-int.h"
07bf635f 34#include "lwlib-utils.h"
01492d1b 35#include <X11/StringDefs.h>
07bf635f 36
07bf635f
RS
37#if defined (USE_LUCID)
38#include "lwlib-Xlw.h"
39#endif
40#if defined (USE_MOTIF)
41#include "lwlib-Xm.h"
ce5a08a1
FP
42#else /* not USE_MOTIF */
43#if defined (USE_LUCID)
44#define USE_XAW
45#endif /* not USE_MOTIF && USE_LUCID */
07bf635f 46#endif
9331cca8 47#if defined (USE_XAW)
5262c5c7
CY
48#ifdef HAVE_XAW3D
49#include <X11/Xaw3d/Paned.h>
50#else /* !HAVE_XAW3D */
cec17865 51#include <X11/Xaw/Paned.h>
5262c5c7 52#endif /* HAVE_XAW3D */
9331cca8
FP
53#include "lwlib-Xaw.h"
54#endif
07bf635f 55
db0e17de
DL
56#if !defined (USE_LUCID) && !defined (USE_MOTIF)
57 #error At least one of USE_LUCID or USE_MOTIF must be defined.
07bf635f
RS
58#endif
59
2af91681
PR
60#ifndef max
61#define max(x, y) ((x) > (y) ? (x) : (y))
62#endif
63
07bf635f
RS
64/* List of all widgets managed by the library. */
65static widget_info*
66all_widget_info = NULL;
67
99dcca2f
KH
68#ifdef USE_MOTIF
69char *lwlib_toolkit_type = "motif";
70#else
71char *lwlib_toolkit_type = "lucid";
72#endif
07bf635f 73
f57e2426
J
74static widget_value *merge_widget_value (widget_value *,
75 widget_value *,
76 int, int *);
77static void instantiate_widget_instance (widget_instance *);
78static int my_strcasecmp (char *, char *);
79static void safe_free_str (char *);
80static void free_widget_value_tree (widget_value *);
81static widget_value *copy_widget_value_tree (widget_value *,
82 change_type);
83static widget_info *allocate_widget_info (char *, char *, LWLIB_ID,
84 widget_value *,
85 lw_callback, lw_callback,
86 lw_callback, lw_callback);
87static void free_widget_info (widget_info *);
88static void mark_widget_destroyed (Widget, XtPointer, XtPointer);
89static widget_instance *allocate_widget_instance (widget_info *,
90 Widget, Boolean);
91static void free_widget_instance (widget_instance *);
92static widget_info *get_widget_info (LWLIB_ID, Boolean);
93static widget_instance *get_widget_instance (Widget, Boolean);
94static widget_instance *find_instance (LWLIB_ID, Widget, Boolean);
95static Boolean safe_strcmp (char *, char *);
96static Widget name_to_widget (widget_instance *, char *);
97static void set_one_value (widget_instance *, widget_value *, Boolean);
98static void update_one_widget_instance (widget_instance *, Boolean);
99static void update_all_widget_values (widget_info *, Boolean);
100static void initialize_widget_instance (widget_instance *);
101static widget_creation_function find_in_table (char *, widget_creation_entry *);
102static Boolean dialog_spec_p (char *);
103static void destroy_one_instance (widget_instance *);
104static void lw_pop_all_widgets (LWLIB_ID, Boolean);
105static Boolean get_one_value (widget_instance *, widget_value *);
106static void show_one_widget_busy (Widget, Boolean);
177c0ea7 107
cec17865 108void
c3174d16 109lwlib_memset (char *address, int value, size_t length)
f60044f5
RS
110{
111 int i;
112
113 for (i = 0; i < length; i++)
114 address[i] = value;
115}
116
cec17865 117void
c3174d16 118lwlib_bcopy (char *from, char *to, int length)
f60044f5
RS
119{
120 int i;
121
122 for (i = 0; i < length; i++)
123 to[i] = from[i];
124}
07bf635f 125\f/* utility functions for widget_instance and widget_info */
bb2ee72b 126char *
c3174d16 127safe_strdup (const char *s)
07bf635f
RS
128{
129 char *result;
130 if (! s) return 0;
131 result = (char *) malloc (strlen (s) + 1);
132 if (! result)
133 return 0;
134 strcpy (result, s);
135 return result;
136}
137
5f61736f
RS
138/* Like strcmp but ignore differences in case. */
139
140static int
c3174d16 141my_strcasecmp (char *s1, char *s2)
5f61736f
RS
142{
143 while (1)
144 {
145 int c1 = *s1++;
146 int c2 = *s2++;
147 if (isupper (c1))
148 c1 = tolower (c1);
149 if (isupper (c2))
150 c2 = tolower (c2);
151 if (c1 != c2)
152 return (c1 > c2 ? 1 : -1);
153 if (c1 == 0)
154 return 0;
155 }
156}
157
07bf635f 158static void
c3174d16 159safe_free_str (char *s)
07bf635f 160{
c2cd06e6 161 free (s);
07bf635f
RS
162}
163
164static widget_value *widget_value_free_list = 0;
0b96f00b 165static int malloc_cpt = 0;
07bf635f
RS
166
167widget_value *
c3174d16 168malloc_widget_value (void)
07bf635f
RS
169{
170 widget_value *wv;
171 if (widget_value_free_list)
172 {
173 wv = widget_value_free_list;
174 widget_value_free_list = wv->free_list;
175 wv->free_list = 0;
176 }
177 else
178 {
179 wv = (widget_value *) malloc (sizeof (widget_value));
0b96f00b 180 malloc_cpt++;
07bf635f 181 }
db0e17de 182 lwlib_memset ((void*) wv, 0, sizeof (widget_value));
07bf635f
RS
183 return wv;
184}
185
7ef3956a 186/* this is analogous to free(). It frees only what was allocated
177c0ea7 187 by malloc_widget_value(), and no substructures.
07bf635f
RS
188 */
189void
c3174d16 190free_widget_value (widget_value *wv)
07bf635f
RS
191{
192 if (wv->free_list)
193 abort ();
0b96f00b 194
d2a5919f 195 if (malloc_cpt > 25)
0b96f00b
FP
196 {
197 /* When the number of already allocated cells is too big,
198 We free it. */
0b96f00b 199 free (wv);
d2a5919f 200 malloc_cpt--;
0b96f00b
FP
201 }
202 else
203 {
204 wv->free_list = widget_value_free_list;
205 widget_value_free_list = wv;
206 }
07bf635f
RS
207}
208
209static void
c3174d16 210free_widget_value_tree (widget_value *wv)
07bf635f
RS
211{
212 if (!wv)
213 return;
214
c2cd06e6
JM
215 free (wv->name);
216 free (wv->value);
217 free (wv->key);
07bf635f 218
a3bf8a8c 219 wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
07bf635f
RS
220
221 if (wv->toolkit_data && wv->free_toolkit_data)
222 {
53e28d2a 223 XtFree (wv->toolkit_data);
07bf635f
RS
224 wv->toolkit_data = (void *) 0xDEADBEEF;
225 }
226
227 if (wv->contents && (wv->contents != (widget_value*)1))
228 {
229 free_widget_value_tree (wv->contents);
230 wv->contents = (widget_value *) 0xDEADBEEF;
231 }
232 if (wv->next)
233 {
234 free_widget_value_tree (wv->next);
235 wv->next = (widget_value *) 0xDEADBEEF;
236 }
237 free_widget_value (wv);
238}
239
240static widget_value *
c3174d16 241copy_widget_value_tree (widget_value *val, change_type change)
07bf635f
RS
242{
243 widget_value* copy;
177c0ea7 244
07bf635f
RS
245 if (!val)
246 return NULL;
247 if (val == (widget_value *) 1)
248 return val;
249
250 copy = malloc_widget_value ();
251 copy->name = safe_strdup (val->name);
252 copy->value = safe_strdup (val->value);
253 copy->key = safe_strdup (val->key);
a3bf8a8c 254 copy->help = val->help;
07bf635f 255 copy->enabled = val->enabled;
da88f592 256 copy->button_type = val->button_type;
07bf635f
RS
257 copy->selected = val->selected;
258 copy->edited = False;
259 copy->change = change;
0c12a958 260 copy->this_one_change = change;
07bf635f
RS
261 copy->contents = copy_widget_value_tree (val->contents, change);
262 copy->call_data = val->call_data;
263 copy->next = copy_widget_value_tree (val->next, change);
264 copy->toolkit_data = NULL;
265 copy->free_toolkit_data = False;
266 return copy;
267}
268
269static widget_info *
02512b20
GM
270allocate_widget_info (type, name, id, val, pre_activate_cb,
271 selection_cb, post_activate_cb, highlight_cb)
5f61736f
RS
272 char* type;
273 char* name;
274 LWLIB_ID id;
275 widget_value* val;
276 lw_callback pre_activate_cb;
277 lw_callback selection_cb;
278 lw_callback post_activate_cb;
02512b20 279 lw_callback highlight_cb;
07bf635f
RS
280{
281 widget_info* info = (widget_info*)malloc (sizeof (widget_info));
282 info->type = safe_strdup (type);
283 info->name = safe_strdup (name);
284 info->id = id;
285 info->val = copy_widget_value_tree (val, STRUCTURAL_CHANGE);
286 info->busy = False;
287 info->pre_activate_cb = pre_activate_cb;
288 info->selection_cb = selection_cb;
289 info->post_activate_cb = post_activate_cb;
02512b20 290 info->highlight_cb = highlight_cb;
07bf635f
RS
291 info->instances = NULL;
292
293 info->next = all_widget_info;
294 all_widget_info = info;
295
296 return info;
297}
298
299static void
c3174d16 300free_widget_info (widget_info *info)
07bf635f
RS
301{
302 safe_free_str (info->type);
303 safe_free_str (info->name);
304 free_widget_value_tree (info->val);
f60044f5 305 lwlib_memset ((void*)info, 0xDEADBEEF, sizeof (widget_info));
07bf635f
RS
306 free (info);
307}
308
309static void
c3174d16 310mark_widget_destroyed (Widget widget, XtPointer closure, XtPointer call_data)
07bf635f
RS
311{
312 widget_instance* instance = (widget_instance*)closure;
313
314 /* be very conservative */
315 if (instance->widget == widget)
316 instance->widget = NULL;
317}
318
db0e17de
DL
319/* The messy #ifdef PROTOTYPES here and elsewhere are prompted by a
320 flood of warnings about argument promotion from proprietary ISO C
321 compilers. (etags still only makes one entry for each function.) */
07bf635f 322static widget_instance *
db0e17de
DL
323#ifdef PROTOTYPES
324allocate_widget_instance (widget_info* info, Widget parent, Boolean pop_up_p)
325#else
5f61736f
RS
326allocate_widget_instance (info, parent, pop_up_p)
327 widget_info* info;
328 Widget parent;
329 Boolean pop_up_p;
db0e17de 330#endif
07bf635f
RS
331{
332 widget_instance* instance =
333 (widget_instance*)malloc (sizeof (widget_instance));
02512b20 334 bzero (instance, sizeof *instance);
07bf635f
RS
335 instance->parent = parent;
336 instance->pop_up_p = pop_up_p;
337 instance->info = info;
338 instance->next = info->instances;
339 info->instances = instance;
340
7ef3956a 341 instantiate_widget_instance (instance);
07bf635f
RS
342
343 XtAddCallback (instance->widget, XtNdestroyCallback,
344 mark_widget_destroyed, (XtPointer)instance);
345 return instance;
346}
347
348static void
c3174d16 349free_widget_instance (widget_instance *instance)
07bf635f 350{
f60044f5 351 lwlib_memset ((void*)instance, 0xDEADBEEF, sizeof (widget_instance));
07bf635f
RS
352 free (instance);
353}
354
355static widget_info *
db0e17de
DL
356#ifdef PROTOTYPES
357get_widget_info (LWLIB_ID id, Boolean remove_p)
358#else
5f61736f
RS
359get_widget_info (id, remove_p)
360 LWLIB_ID id;
361 Boolean remove_p;
db0e17de 362#endif
07bf635f
RS
363{
364 widget_info* info;
365 widget_info* prev;
366 for (prev = NULL, info = all_widget_info;
367 info;
368 prev = info, info = info->next)
369 if (info->id == id)
370 {
371 if (remove_p)
372 {
373 if (prev)
374 prev->next = info->next;
375 else
376 all_widget_info = info->next;
377 }
378 return info;
379 }
380 return NULL;
381}
382
9331cca8
FP
383/* Internal function used by the library dependent implementation to get the
384 widget_value for a given widget in an instance */
385widget_info *
c3174d16 386lw_get_widget_info (LWLIB_ID id)
9331cca8
FP
387{
388 return get_widget_info (id, 0);
389}
390
07bf635f 391static widget_instance *
db0e17de
DL
392#ifdef PROTOTYPES
393get_widget_instance (Widget widget, Boolean remove_p)
394#else
5f61736f
RS
395get_widget_instance (widget, remove_p)
396 Widget widget;
397 Boolean remove_p;
db0e17de 398#endif
07bf635f
RS
399{
400 widget_info* info;
401 widget_instance* instance;
402 widget_instance* prev;
403 for (info = all_widget_info; info; info = info->next)
404 for (prev = NULL, instance = info->instances;
405 instance;
406 prev = instance, instance = instance->next)
407 if (instance->widget == widget)
408 {
409 if (remove_p)
410 {
411 if (prev)
412 prev->next = instance->next;
413 else
414 info->instances = instance->next;
415 }
416 return instance;
417 }
418 return (widget_instance *) 0;
419}
420
02512b20
GM
421/* Value is a pointer to the widget_instance corresponding to
422 WIDGET, or null if WIDGET is not a lwlib widget. */
423
424widget_instance *
c3174d16 425lw_get_widget_instance (Widget widget)
02512b20
GM
426{
427 return get_widget_instance (widget, False);
428}
429
07bf635f 430static widget_instance*
db0e17de
DL
431#ifdef PROTOTYPES
432find_instance (LWLIB_ID id, Widget parent, Boolean pop_up_p)
433#else
5f61736f
RS
434find_instance (id, parent, pop_up_p)
435 LWLIB_ID id;
436 Widget parent;
437 Boolean pop_up_p;
db0e17de 438#endif
07bf635f
RS
439{
440 widget_info* info = get_widget_info (id, False);
441 widget_instance* instance;
442
443 if (info)
444 for (instance = info->instances; instance; instance = instance->next)
445 if (instance->parent == parent && instance->pop_up_p == pop_up_p)
446 return instance;
447
448 return NULL;
449}
450
451\f
452/* utility function for widget_value */
453static Boolean
c3174d16 454safe_strcmp (char *s1, char *s2)
07bf635f
RS
455{
456 if (!!s1 ^ !!s2) return True;
457 return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2;
458}
459
07bf635f
RS
460
461#if 0
462# define EXPLAIN(name, oc, nc, desc, a1, a2) \
463 printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
464 name, \
465 (oc == NO_CHANGE ? "none" : \
466 (oc == INVISIBLE_CHANGE ? "invisible" : \
467 (oc == VISIBLE_CHANGE ? "visible" : \
468 (oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
469 oc, \
470 (nc == NO_CHANGE ? "none" : \
471 (nc == INVISIBLE_CHANGE ? "invisible" : \
472 (nc == VISIBLE_CHANGE ? "visible" : \
473 (nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
474 nc, desc, a1, a2)
475#else
476# define EXPLAIN(name, oc, nc, desc, a1, a2)
477#endif
478
479
480static widget_value *
c3174d16 481merge_widget_value (widget_value *val1, widget_value *val2, int level, int *change_p)
07bf635f 482{
0c12a958 483 change_type change, this_one_change;
07bf635f
RS
484 widget_value* merged_next;
485 widget_value* merged_contents;
486
487 if (!val1)
488 {
489 if (val2)
a17063b5
GM
490 {
491 *change_p = 1;
492 return copy_widget_value_tree (val2, STRUCTURAL_CHANGE);
493 }
07bf635f
RS
494 else
495 return NULL;
496 }
497 if (!val2)
498 {
a17063b5 499 *change_p = 1;
07bf635f
RS
500 free_widget_value_tree (val1);
501 return NULL;
502 }
177c0ea7 503
07bf635f
RS
504 change = NO_CHANGE;
505
506 if (safe_strcmp (val1->name, val2->name))
507 {
508 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "name change",
509 val1->name, val2->name);
510 change = max (change, STRUCTURAL_CHANGE);
511 safe_free_str (val1->name);
512 val1->name = safe_strdup (val2->name);
513 }
514 if (safe_strcmp (val1->value, val2->value))
515 {
516 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "value change",
517 val1->value, val2->value);
518 change = max (change, VISIBLE_CHANGE);
519 safe_free_str (val1->value);
520 val1->value = safe_strdup (val2->value);
521 }
522 if (safe_strcmp (val1->key, val2->key))
523 {
524 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "key change",
525 val1->key, val2->key);
526 change = max (change, VISIBLE_CHANGE);
527 safe_free_str (val1->key);
528 val1->key = safe_strdup (val2->key);
529 }
a3bf8a8c 530 if (! EQ (val1->help, val2->help))
02512b20
GM
531 {
532 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "help change",
533 val1->help, val2->help);
534 change = max (change, VISIBLE_CHANGE);
a3bf8a8c 535 val1->help = val2->help;
02512b20 536 }
07bf635f
RS
537 if (val1->enabled != val2->enabled)
538 {
539 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "enablement change",
540 val1->enabled, val2->enabled);
541 change = max (change, VISIBLE_CHANGE);
542 val1->enabled = val2->enabled;
543 }
da88f592
GM
544 if (val1->button_type != val2->button_type)
545 {
546 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "button type change",
547 val1->button_type, val2->button_type);
548 change = max (change, VISIBLE_CHANGE);
549 val1->button_type = val2->button_type;
550 }
07bf635f
RS
551 if (val1->selected != val2->selected)
552 {
553 EXPLAIN (val1->name, change, VISIBLE_CHANGE, "selection change",
554 val1->selected, val2->selected);
555 change = max (change, VISIBLE_CHANGE);
556 val1->selected = val2->selected;
557 }
558 if (val1->call_data != val2->call_data)
559 {
560 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change",
561 val1->call_data, val2->call_data);
562 change = max (change, INVISIBLE_CHANGE);
563 val1->call_data = val2->call_data;
564 }
565
566 if (level > 0)
567 {
568 merged_contents =
a17063b5
GM
569 merge_widget_value (val1->contents, val2->contents, level - 1,
570 change_p);
177c0ea7 571
07bf635f
RS
572 if (val1->contents && !merged_contents)
573 {
7ef3956a
RS
574 /* This used to say INVISIBLE_CHANGE,
575 but it is visible and vitally important when
576 the contents of the menu bar itself are entirely deleted.
577
578 But maybe it doesn't matter. This fails to fix the bug. */
579 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(contents gone)",
07bf635f 580 0, 0);
7ef3956a 581 change = max (change, STRUCTURAL_CHANGE);
07bf635f
RS
582 }
583 else if (merged_contents && merged_contents->change != NO_CHANGE)
584 {
585 EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents change)",
586 0, 0);
587 change = max (change, INVISIBLE_CHANGE);
61069f2b 588#if 0 /* This was replaced by the August 9 1996 change in lwlib-Xm.c. */
2fe6d204
RS
589#ifdef USE_MOTIF
590 change = max (merged_contents->change, change);
61069f2b 591#endif
2fe6d204 592#endif
07bf635f 593 }
177c0ea7 594
07bf635f
RS
595 val1->contents = merged_contents;
596 }
597
0c12a958
RS
598 this_one_change = change;
599
a17063b5 600 merged_next = merge_widget_value (val1->next, val2->next, level, change_p);
07bf635f
RS
601
602 if (val1->next && !merged_next)
603 {
604 EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(following gone)",
605 0, 0);
606 change = max (change, STRUCTURAL_CHANGE);
607 }
608 else if (merged_next)
609 {
610 if (merged_next->change)
611 EXPLAIN (val1->name, change, merged_next->change, "(following change)",
612 0, 0);
613 change = max (change, merged_next->change);
614 }
615
616 val1->next = merged_next;
617
0c12a958 618 val1->this_one_change = this_one_change;
07bf635f 619 val1->change = change;
177c0ea7 620
07bf635f
RS
621 if (change > NO_CHANGE && val1->toolkit_data)
622 {
a17063b5 623 *change_p = 1;
07bf635f 624 if (val1->free_toolkit_data)
53e28d2a 625 XtFree (val1->toolkit_data);
07bf635f
RS
626 val1->toolkit_data = NULL;
627 }
628
629 return val1;
630}
631
632\f
633/* modifying the widgets */
634static Widget
c3174d16 635name_to_widget (widget_instance *instance, char *name)
07bf635f
RS
636{
637 Widget widget = NULL;
638
639 if (!instance->widget)
640 return NULL;
641
642 if (!strcmp (XtName (instance->widget), name))
643 widget = instance->widget;
644 else
645 {
646 int length = strlen (name) + 2;
f60044f5 647 char* real_name = (char *) xmalloc (length);
07bf635f
RS
648 real_name [0] = '*';
649 strcpy (real_name + 1, name);
177c0ea7 650
07bf635f 651 widget = XtNameToWidget (instance->widget, real_name);
f60044f5
RS
652
653 free (real_name);
07bf635f
RS
654 }
655 return widget;
656}
657
658static void
db0e17de
DL
659#ifdef PROTOTYPES
660set_one_value (widget_instance* instance, widget_value* val, Boolean deep_p)
661#else
5f61736f
RS
662set_one_value (instance, val, deep_p)
663 widget_instance* instance;
664 widget_value* val;
665 Boolean deep_p;
db0e17de 666#endif
07bf635f
RS
667{
668 Widget widget = name_to_widget (instance, val->name);
177c0ea7 669
07bf635f
RS
670 if (widget)
671 {
672#if defined (USE_LUCID)
673 if (lw_lucid_widget_p (instance->widget))
674 xlw_update_one_widget (instance, widget, val, deep_p);
675#endif
676#if defined (USE_MOTIF)
677 if (lw_motif_widget_p (instance->widget))
678 xm_update_one_widget (instance, widget, val, deep_p);
679#endif
9331cca8
FP
680#if defined (USE_XAW)
681 if (lw_xaw_widget_p (instance->widget))
682 xaw_update_one_widget (instance, widget, val, deep_p);
07bf635f
RS
683#endif
684 }
685}
686
687static void
db0e17de
DL
688#ifdef PROTOTYPES
689update_one_widget_instance (widget_instance* instance, Boolean deep_p)
690#else
5f61736f
RS
691update_one_widget_instance (instance, deep_p)
692 widget_instance* instance;
693 Boolean deep_p;
db0e17de 694#endif
07bf635f
RS
695{
696 widget_value *val;
697
698 if (!instance->widget)
699 /* the widget was destroyed */
700 return;
701
702 for (val = instance->info->val; val; val = val->next)
703 if (val->change != NO_CHANGE)
704 set_one_value (instance, val, deep_p);
705}
706
707static void
db0e17de
DL
708#ifdef PROTOTYPES
709update_all_widget_values (widget_info* info, Boolean deep_p)
710#else
5f61736f
RS
711update_all_widget_values (info, deep_p)
712 widget_info* info;
713 Boolean deep_p;
db0e17de 714#endif
07bf635f
RS
715{
716 widget_instance* instance;
717 widget_value* val;
718
719 for (instance = info->instances; instance; instance = instance->next)
720 update_one_widget_instance (instance, deep_p);
721
722 for (val = info->val; val; val = val->next)
723 val->change = NO_CHANGE;
724}
725
a17063b5 726int
db0e17de
DL
727#ifdef PROTOTYPES
728lw_modify_all_widgets (LWLIB_ID id, widget_value* val, Boolean deep_p)
729#else
5f61736f
RS
730lw_modify_all_widgets (id, val, deep_p)
731 LWLIB_ID id;
732 widget_value* val;
733 Boolean deep_p;
db0e17de 734#endif
07bf635f
RS
735{
736 widget_info* info = get_widget_info (id, False);
737 widget_value* new_val;
738 widget_value* next_new_val;
739 widget_value* cur;
740 widget_value* prev;
741 widget_value* next;
742 int found;
a17063b5 743 int change_p = 0;
07bf635f
RS
744
745 if (!info)
fdc4d3cd 746 return 0;
07bf635f
RS
747
748 for (new_val = val; new_val; new_val = new_val->next)
749 {
750 next_new_val = new_val->next;
751 new_val->next = NULL;
752 found = False;
753 for (prev = NULL, cur = info->val; cur; prev = cur, cur = cur->next)
754 if (!strcmp (cur->name, new_val->name))
755 {
756 found = True;
757 next = cur->next;
758 cur->next = NULL;
a17063b5
GM
759 cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1,
760 &change_p);
07bf635f
RS
761 if (prev)
762 prev->next = cur ? cur : next;
763 else
764 info->val = cur ? cur : next;
765 if (cur)
766 cur->next = next;
767 break;
768 }
769 if (!found)
770 {
771 /* Could not find it, add it */
772 if (prev)
773 prev->next = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
774 else
775 info->val = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
a17063b5 776 change_p = 1;
07bf635f
RS
777 }
778 new_val->next = next_new_val;
779 }
780
781 update_all_widget_values (info, deep_p);
a17063b5 782 return change_p;
07bf635f
RS
783}
784
785\f
786/* creating the widgets */
787
788static void
c3174d16 789initialize_widget_instance (widget_instance *instance)
07bf635f
RS
790{
791 widget_value* val;
792
793 for (val = instance->info->val; val; val = val->next)
794 val->change = STRUCTURAL_CHANGE;
795
796 update_one_widget_instance (instance, True);
797
798 for (val = instance->info->val; val; val = val->next)
799 val->change = NO_CHANGE;
800}
801
802
803static widget_creation_function
c3174d16 804find_in_table (char *type, widget_creation_entry *table)
07bf635f
RS
805{
806 widget_creation_entry* cur;
807 for (cur = table; cur->type; cur++)
ed9c1473 808 if (!my_strcasecmp (type, cur->type))
07bf635f
RS
809 return cur->function;
810 return NULL;
811}
812
813static Boolean
c3174d16 814dialog_spec_p (char *name)
07bf635f 815{
177c0ea7 816 /* return True if name matches [EILPQeilpq][1-9][Bb] or
07bf635f
RS
817 [EILPQeilpq][1-9][Bb][Rr][1-9] */
818 if (!name)
819 return False;
177c0ea7 820
07bf635f
RS
821 switch (name [0])
822 {
823 case 'E': case 'I': case 'L': case 'P': case 'Q':
824 case 'e': case 'i': case 'l': case 'p': case 'q':
825 if (name [1] >= '0' && name [1] <= '9')
826 {
827 if (name [2] != 'B' && name [2] != 'b')
828 return False;
829 if (!name [3])
830 return True;
831 if ((name [3] == 'T' || name [3] == 't') && !name [4])
832 return True;
833 if ((name [3] == 'R' || name [3] == 'r')
834 && name [4] >= '0' && name [4] <= '9' && !name [5])
835 return True;
836 return False;
837 }
838 else
839 return False;
177c0ea7 840
07bf635f
RS
841 default:
842 return False;
843 }
844}
845
846static void
c3174d16 847instantiate_widget_instance (widget_instance *instance)
07bf635f
RS
848{
849 widget_creation_function function = NULL;
850
851#if defined (USE_LUCID)
852 if (!function)
853 function = find_in_table (instance->info->type, xlw_creation_table);
854#endif
855#if defined(USE_MOTIF)
856 if (!function)
857 function = find_in_table (instance->info->type, xm_creation_table);
858#endif
9331cca8
FP
859#if defined (USE_XAW)
860 if (!function)
861 function = find_in_table (instance->info->type, xaw_creation_table);
862#endif
07bf635f
RS
863
864 if (!function)
865 {
866 if (dialog_spec_p (instance->info->type))
867 {
868#if defined (USE_LUCID)
869 /* not yet */
870#endif
871#if defined(USE_MOTIF)
872 if (!function)
873 function = xm_create_dialog;
874#endif
9331cca8
FP
875#if defined (USE_XAW)
876 if (!function)
877 function = xaw_create_dialog;
07bf635f
RS
878#endif
879 }
880 }
177c0ea7 881
07bf635f
RS
882 if (!function)
883 {
884 printf ("No creation function for widget type %s\n",
885 instance->info->type);
886 abort ();
887 }
888
889 instance->widget = (*function) (instance);
890
891 if (!instance->widget)
892 abort ();
893
894 /* XtRealizeWidget (instance->widget);*/
895}
896
177c0ea7 897void
02512b20
GM
898lw_register_widget (type, name, id, val, pre_activate_cb,
899 selection_cb, post_activate_cb, highlight_cb)
5f61736f
RS
900 char* type;
901 char* name;
902 LWLIB_ID id;
903 widget_value* val;
904 lw_callback pre_activate_cb;
905 lw_callback selection_cb;
906 lw_callback post_activate_cb;
02512b20 907 lw_callback highlight_cb;
07bf635f
RS
908{
909 if (!get_widget_info (id, False))
910 allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb,
02512b20 911 post_activate_cb, highlight_cb);
07bf635f
RS
912}
913
914Widget
db0e17de
DL
915#ifdef PROTOTYPES
916lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
917#else
5f61736f
RS
918lw_get_widget (id, parent, pop_up_p)
919 LWLIB_ID id;
920 Widget parent;
921 Boolean pop_up_p;
db0e17de 922#endif
07bf635f
RS
923{
924 widget_instance* instance;
177c0ea7 925
07bf635f
RS
926 instance = find_instance (id, parent, pop_up_p);
927 return instance ? instance->widget : NULL;
928}
929
930Widget
db0e17de
DL
931#ifdef PROTOTYPES
932lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
933#else
5f61736f
RS
934lw_make_widget (id, parent, pop_up_p)
935 LWLIB_ID id;
936 Widget parent;
937 Boolean pop_up_p;
db0e17de 938#endif
07bf635f
RS
939{
940 widget_instance* instance;
941 widget_info* info;
177c0ea7 942
07bf635f
RS
943 instance = find_instance (id, parent, pop_up_p);
944 if (!instance)
945 {
946 info = get_widget_info (id, False);
947 if (!info)
948 return NULL;
949 instance = allocate_widget_instance (info, parent, pop_up_p);
950 initialize_widget_instance (instance);
951 }
952 if (!instance->widget)
953 abort ();
954 return instance->widget;
955}
956
957Widget
db0e17de
DL
958#ifdef PROTOTYPES
959lw_create_widget (char* type, char* name, LWLIB_ID id, widget_value* val,
960 Widget parent, Boolean pop_up_p,
961 lw_callback pre_activate_cb, lw_callback selection_cb,
962 lw_callback post_activate_cb, lw_callback highlight_cb)
963#else
02512b20
GM
964lw_create_widget (type, name, id, val, parent, pop_up_p, pre_activate_cb,
965 selection_cb, post_activate_cb, highlight_cb)
5f61736f
RS
966 char* type;
967 char* name;
968 LWLIB_ID id;
969 widget_value* val;
970 Widget parent;
971 Boolean pop_up_p;
972 lw_callback pre_activate_cb;
973 lw_callback selection_cb;
974 lw_callback post_activate_cb;
02512b20 975 lw_callback highlight_cb;
db0e17de 976#endif
07bf635f
RS
977{
978 lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb,
02512b20 979 post_activate_cb, highlight_cb);
07bf635f
RS
980 return lw_make_widget (id, parent, pop_up_p);
981}
177c0ea7 982
07bf635f
RS
983\f
984/* destroying the widgets */
985static void
c3174d16 986destroy_one_instance (widget_instance *instance)
07bf635f
RS
987{
988 /* Remove the destroy callback on the widget; that callback will try to
989 dereference the instance object (to set its widget slot to 0, since the
990 widget is dead.) Since the instance is now dead, we don't have to worry
991 about the fact that its widget is dead too.
992
993 This happens in the Phase2Destroy of the widget, so this callback would
994 not have been run until arbitrarily long after the instance was freed.
995 */
996 if (instance->widget)
997 XtRemoveCallback (instance->widget, XtNdestroyCallback,
998 mark_widget_destroyed, (XtPointer)instance);
999
1000 if (instance->widget)
1001 {
1002 /* The else are pretty tricky here, including the empty statement
1003 at the end because it would be very bad to destroy a widget
1004 twice. */
1005#if defined (USE_LUCID)
1006 if (lw_lucid_widget_p (instance->widget))
1007 xlw_destroy_instance (instance);
1008 else
1009#endif
1010#if defined (USE_MOTIF)
1011 if (lw_motif_widget_p (instance->widget))
1012 xm_destroy_instance (instance);
1013 else
1014#endif
9331cca8
FP
1015#if defined (USE_XAW)
1016 if (lw_xaw_widget_p (instance->widget))
1017 xaw_destroy_instance (instance);
177c0ea7 1018 else
07bf635f
RS
1019#endif
1020 /* do not remove the empty statement */
1021 ;
1022 }
1023
1024 free_widget_instance (instance);
1025}
1026
1027void
c3174d16 1028lw_destroy_widget (Widget w)
07bf635f
RS
1029{
1030 widget_instance* instance = get_widget_instance (w, True);
177c0ea7 1031
07bf635f
RS
1032 if (instance)
1033 {
1034 widget_info *info = instance->info;
1035 /* instance has already been removed from the list; free it */
1036 destroy_one_instance (instance);
1037 /* if there are no instances left, free the info too */
1038 if (!info->instances)
1039 lw_destroy_all_widgets (info->id);
1040 }
1041}
1042
1043void
c3174d16 1044lw_destroy_all_widgets (LWLIB_ID id)
07bf635f
RS
1045{
1046 widget_info* info = get_widget_info (id, True);
1047 widget_instance* instance;
1048 widget_instance* next;
1049
1050 if (info)
1051 {
1052 for (instance = info->instances; instance; )
1053 {
1054 next = instance->next;
1055 destroy_one_instance (instance);
1056 instance = next;
1057 }
1058 free_widget_info (info);
1059 }
1060}
1061
1062void
c3174d16 1063lw_destroy_everything (void)
07bf635f
RS
1064{
1065 while (all_widget_info)
1066 lw_destroy_all_widgets (all_widget_info->id);
1067}
1068
1069void
c3174d16 1070lw_destroy_all_pop_ups (void)
07bf635f
RS
1071{
1072 widget_info* info;
1073 widget_info* next;
1074 widget_instance* instance;
1075
1076 for (info = all_widget_info; info; info = next)
1077 {
1078 next = info->next;
1079 instance = info->instances;
1080 if (instance && instance->pop_up_p)
1081 lw_destroy_all_widgets (info->id);
1082 }
1083}
1084
1085#ifdef USE_MOTIF
9e3fe459 1086extern Widget first_child (/* Widget */); /* garbage */
07bf635f
RS
1087#endif
1088
1089Widget
c3174d16 1090lw_raise_all_pop_up_widgets (void)
07bf635f
RS
1091{
1092 widget_info* info;
1093 widget_instance* instance;
1094 Widget result = NULL;
1095
1096 for (info = all_widget_info; info; info = info->next)
1097 for (instance = info->instances; instance; instance = instance->next)
1098 if (instance->pop_up_p)
1099 {
1100 Widget widget = instance->widget;
1101 if (widget)
1102 {
1103 if (XtIsManaged (widget)
1104#ifdef USE_MOTIF
1105 /* What a complete load of crap!!!!
1106 When a dialogShell is on the screen, it is not managed!
1107 */
1108 || (lw_motif_widget_p (instance->widget) &&
1109 XtIsManaged (first_child (widget)))
1110#endif
1111 )
1112 {
1113 if (!result)
1114 result = widget;
1115 XMapRaised (XtDisplay (widget), XtWindow (widget));
1116 }
1117 }
1118 }
1119 return result;
1120}
1121
1122static void
db0e17de
DL
1123#ifdef PROTOTYPES
1124lw_pop_all_widgets (LWLIB_ID id, Boolean up)
1125#else
5f61736f
RS
1126lw_pop_all_widgets (id, up)
1127 LWLIB_ID id;
1128 Boolean up;
db0e17de 1129#endif
07bf635f
RS
1130{
1131 widget_info* info = get_widget_info (id, False);
1132 widget_instance* instance;
1133
1134 if (info)
1135 for (instance = info->instances; instance; instance = instance->next)
1136 if (instance->pop_up_p && instance->widget)
1137 {
07bf635f
RS
1138#if defined (USE_LUCID)
1139 if (lw_lucid_widget_p (instance->widget))
9331cca8
FP
1140 {
1141 XtRealizeWidget (instance->widget);
1142 xlw_pop_instance (instance, up);
1143 }
07bf635f
RS
1144#endif
1145#if defined (USE_MOTIF)
1146 if (lw_motif_widget_p (instance->widget))
9331cca8
FP
1147 {
1148 XtRealizeWidget (instance->widget);
1149 xm_pop_instance (instance, up);
1150 }
07bf635f 1151#endif
9331cca8
FP
1152#if defined (USE_XAW)
1153 if (lw_xaw_widget_p (instance->widget))
1154 {
1155 XtRealizeWidget (XtParent (instance->widget));
1156 XtRealizeWidget (instance->widget);
1157 xaw_pop_instance (instance, up);
1158 }
07bf635f
RS
1159#endif
1160 }
1161}
1162
1163void
c3174d16 1164lw_pop_up_all_widgets (LWLIB_ID id)
07bf635f
RS
1165{
1166 lw_pop_all_widgets (id, True);
1167}
1168
1169void
c3174d16 1170lw_pop_down_all_widgets (LWLIB_ID id)
07bf635f
RS
1171{
1172 lw_pop_all_widgets (id, False);
1173}
1174
1175void
c3174d16 1176lw_popup_menu (Widget widget, XEvent *event)
07bf635f
RS
1177{
1178#if defined (USE_LUCID)
1179 if (lw_lucid_widget_p (widget))
5b3b31d6 1180 xlw_popup_menu (widget, event);
07bf635f
RS
1181#endif
1182#if defined (USE_MOTIF)
1183 if (lw_motif_widget_p (widget))
5b3b31d6 1184 xm_popup_menu (widget, event);
07bf635f 1185#endif
9331cca8
FP
1186#if defined (USE_XAW)
1187 if (lw_xaw_widget_p (widget))
5b3b31d6 1188 xaw_popup_menu (widget, event);
9331cca8 1189#endif
07bf635f
RS
1190}
1191
1192\f/* get the values back */
1193static Boolean
c3174d16 1194get_one_value (widget_instance *instance, widget_value *val)
07bf635f
RS
1195{
1196 Widget widget = name_to_widget (instance, val->name);
177c0ea7 1197
07bf635f
RS
1198 if (widget)
1199 {
1200#if defined (USE_LUCID)
1201 if (lw_lucid_widget_p (instance->widget))
1202 xlw_update_one_value (instance, widget, val);
1203#endif
1204#if defined (USE_MOTIF)
1205 if (lw_motif_widget_p (instance->widget))
1206 xm_update_one_value (instance, widget, val);
1207#endif
9331cca8
FP
1208#if defined (USE_XAW)
1209 if (lw_xaw_widget_p (instance->widget))
1210 xaw_update_one_value (instance, widget, val);
07bf635f
RS
1211#endif
1212 return True;
1213 }
1214 else
1215 return False;
1216}
1217
1218Boolean
c3174d16 1219lw_get_some_values (LWLIB_ID id, widget_value *val_out)
07bf635f
RS
1220{
1221 widget_info* info = get_widget_info (id, False);
1222 widget_instance* instance;
1223 widget_value* val;
1224 Boolean result = False;
1225
1226 if (!info)
1227 return False;
1228
1229 instance = info->instances;
1230 if (!instance)
1231 return False;
1232
1233 for (val = val_out; val; val = val->next)
1234 if (get_one_value (instance, val))
1235 result = True;
1236
1237 return result;
1238}
1239
1240widget_value*
c3174d16 1241lw_get_all_values (LWLIB_ID id)
07bf635f
RS
1242{
1243 widget_info* info = get_widget_info (id, False);
1244 widget_value* val = info->val;
1245 if (lw_get_some_values (id, val))
1246 return val;
1247 else
1248 return NULL;
1249}
1250
1251/* internal function used by the library dependent implementation to get the
1252 widget_value for a given widget in an instance */
1253widget_value*
c3174d16 1254lw_get_widget_value_for_widget (widget_instance *instance, Widget w)
07bf635f
RS
1255{
1256 char* name = XtName (w);
1257 widget_value* cur;
1258 for (cur = instance->info->val; cur; cur = cur->next)
1259 if (!strcmp (cur->name, name))
1260 return cur;
1261 return NULL;
1262}
1263
1264\f/* update other instances value when one thing changed */
bd2c5b53
KH
1265
1266/* To forbid recursive calls */
1267static Boolean lwlib_updating;
1268
177c0ea7 1269/* This function can be used as a an XtCallback for the widgets that get
07bf635f
RS
1270 modified to update other instances of the widgets. Closure should be the
1271 widget_instance. */
1272void
c3174d16 1273lw_internal_update_other_instances (Widget widget, XtPointer closure, XtPointer call_data)
07bf635f 1274{
07bf635f
RS
1275 widget_instance* instance = (widget_instance*)closure;
1276 char* name = XtName (widget);
1277 widget_info* info;
1278 widget_instance* cur;
1279 widget_value* val;
1280
bd2c5b53
KH
1281 /* Avoid possibly infinite recursion. */
1282 if (lwlib_updating)
07bf635f
RS
1283 return;
1284
1285 /* protect against the widget being destroyed */
1286 if (XtWidgetBeingDestroyedP (widget))
1287 return;
1288
1289 /* Return immediately if there are no other instances */
1290 info = instance->info;
1291 if (!info->instances->next)
1292 return;
1293
bd2c5b53 1294 lwlib_updating = True;
07bf635f
RS
1295
1296 for (val = info->val; val && strcmp (val->name, name); val = val->next);
1297
1298 if (val && get_one_value (instance, val))
1299 for (cur = info->instances; cur; cur = cur->next)
1300 if (cur != instance)
1301 set_one_value (cur, val, True);
1302
bd2c5b53 1303 lwlib_updating = False;
07bf635f
RS
1304}
1305
1306
1307\f/* get the id */
1308
1309LWLIB_ID
c3174d16 1310lw_get_widget_id (Widget w)
07bf635f
RS
1311{
1312 widget_instance* instance = get_widget_instance (w, False);
1313
1314 return instance ? instance->info->id : 0;
1315}
1316
1317\f/* set the keyboard focus */
1318void
c3174d16 1319lw_set_keyboard_focus (Widget parent, Widget w)
07bf635f
RS
1320{
1321#if defined (USE_MOTIF)
1322 xm_set_keyboard_focus (parent, w);
1323#else
1324 XtSetKeyboardFocus (parent, w);
1325#endif
1326}
1327
1328\f/* Show busy */
1329static void
db0e17de
DL
1330#ifdef PROTOTYPES
1331show_one_widget_busy (Widget w, Boolean flag)
1332#else
5f61736f
RS
1333show_one_widget_busy (w, flag)
1334 Widget w;
1335 Boolean flag;
db0e17de 1336#endif
07bf635f
RS
1337{
1338 Pixel foreground = 0;
1339 Pixel background = 1;
1340 Widget widget_to_invert = XtNameToWidget (w, "*sheet");
1341 if (!widget_to_invert)
1342 widget_to_invert = w;
177c0ea7 1343
07bf635f
RS
1344 XtVaGetValues (widget_to_invert,
1345 XtNforeground, &foreground,
1346 XtNbackground, &background,
8dd095ee 1347 NULL);
07bf635f
RS
1348 XtVaSetValues (widget_to_invert,
1349 XtNforeground, background,
1350 XtNbackground, foreground,
8dd095ee 1351 NULL);
07bf635f
RS
1352}
1353
1354void
db0e17de
DL
1355#ifdef PROTOTYPES
1356lw_show_busy (Widget w, Boolean busy)
1357#else
5f61736f
RS
1358lw_show_busy (w, busy)
1359 Widget w;
1360 Boolean busy;
db0e17de 1361#endif
07bf635f
RS
1362{
1363 widget_instance* instance = get_widget_instance (w, False);
1364 widget_info* info;
1365 widget_instance* next;
1366
1367 if (instance)
1368 {
1369 info = instance->info;
1370 if (info->busy != busy)
1371 {
1372 for (next = info->instances; next; next = next->next)
1373 if (next->widget)
1374 show_one_widget_busy (next->widget, busy);
1375 info->busy = busy;
1376 }
1377 }
1378}
2af91681
PR
1379
1380/* This hack exists because Lucid/Athena need to execute the strange
1381 function below to support geometry management. */
1382void
db0e17de
DL
1383#ifdef PROTOTYPES
1384lw_refigure_widget (Widget w, Boolean doit)
1385#else
2af91681
PR
1386lw_refigure_widget (w, doit)
1387 Widget w;
1388 Boolean doit;
db0e17de 1389#endif
2af91681 1390{
177c0ea7 1391#if defined (USE_XAW)
2af91681
PR
1392 XawPanedSetRefigureMode (w, doit);
1393#endif
1394#if defined (USE_MOTIF)
1395 if (doit)
2af91681 1396 XtManageChild (w);
a61155bc
RS
1397 else
1398 XtUnmanageChild (w);
2af91681
PR
1399#endif
1400}
1401
1402/* Toolkit independent way of determining if an event window is in the
1403 menubar. */
1404Boolean
c3174d16 1405lw_window_is_in_menubar (Window win, Widget menubar_widget)
2af91681
PR
1406{
1407 return menubar_widget
1408#if defined (USE_LUCID)
1409 && XtWindow (menubar_widget) == win;
1410#endif
1411#if defined (USE_MOTIF)
c17d59fc
RS
1412 && ((XtWindow (menubar_widget) == win)
1413 || (XtWindowToWidget (XtDisplay (menubar_widget), win)
1414 && (XtParent (XtWindowToWidget (XtDisplay (menubar_widget), win))
1415 == menubar_widget)));
2af91681
PR
1416#endif
1417}
1418
1419/* Motif hack to set the main window areas. */
1420void
c3174d16 1421lw_set_main_areas (Widget parent, Widget menubar, Widget work_area)
2af91681
PR
1422{
1423#if defined (USE_MOTIF)
6618806e 1424 xm_set_main_areas (parent, menubar, work_area);
2af91681
PR
1425#endif
1426}
1427
1428/* Manage resizing for Motif. This disables resizing when the menubar
1429 is about to be modified. */
1430void
db0e17de
DL
1431#ifdef PROTOTYPES
1432lw_allow_resizing (Widget w, Boolean flag)
1433#else
2af91681
PR
1434lw_allow_resizing (w, flag)
1435 Widget w;
1436 Boolean flag;
db0e17de 1437#endif
2af91681
PR
1438{
1439#if defined (USE_MOTIF)
f78c5177 1440 xm_manage_resizing (w, flag);
2af91681
PR
1441#endif
1442}
da88f592
GM
1443
1444
1445/* Value is non-zero if LABEL is a menu separator. If it is, *TYPE is
1446 set to an appropriate enumerator of type enum menu_separator.
1447 MOTIF_P non-zero means map separator types not supported by Motif
1448 to similar ones that are supported. */
1449
1450int
c3174d16 1451lw_separator_p (char *label, enum menu_separator *type, int motif_p)
da88f592 1452{
0f3360b0 1453 int separator_p = 0;
da88f592
GM
1454
1455 if (strlen (label) >= 3
1456 && bcmp (label, "--:", 3) == 0)
1457 {
1458 static struct separator_table
1459 {
1460 char *name;
1461 enum menu_separator type;
1462 }
1463 separator_names[] =
1464 {
4a5301d8
PJ
1465 {"space", SEPARATOR_NO_LINE},
1466 {"noLine", SEPARATOR_NO_LINE},
1467 {"singleLine", SEPARATOR_SINGLE_LINE},
1468 {"doubleLine", SEPARATOR_DOUBLE_LINE},
1469 {"singleDashedLine", SEPARATOR_SINGLE_DASHED_LINE},
1470 {"doubleDashedLine", SEPARATOR_DOUBLE_DASHED_LINE},
1471 {"shadowEtchedIn", SEPARATOR_SHADOW_ETCHED_IN},
1472 {"shadowEtchedOut", SEPARATOR_SHADOW_ETCHED_OUT},
1473 {"shadowEtchedInDash", SEPARATOR_SHADOW_ETCHED_IN_DASH},
1474 {"shadowEtchedOutDash", SEPARATOR_SHADOW_ETCHED_OUT_DASH},
1475 {"shadowDoubleEtchedIn", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
1476 {"shadowDoubleEtchedOut", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
1477 {"shadowDoubleEtchedInDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
1478 {"shadowDoubleEtchedOutDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
1479 {0,0}
da88f592
GM
1480 };
1481
1482 int i;
1483
1484 label += 3;
1485 for (i = 0; separator_names[i].name; ++i)
1486 if (strcmp (label, separator_names[i].name) == 0)
1487 {
1488 separator_p = 1;
1489 *type = separator_names[i].type;
1490
2af98732
GM
1491 /* If separator type is not supported under Motif,
1492 use a similar one. */
1493 if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
1494 *type -= 4;
1495 break;
1496 }
1497 }
1498 else if (strlen (label) > 3
46d74a69
GM
1499 && bcmp (label, "--", 2) == 0
1500 && label[2] != '-')
2af98732
GM
1501 {
1502 /* Alternative, more Emacs-style names. */
1503 static struct separator_table
1504 {
1505 char *name;
1506 enum menu_separator type;
1507 }
1508 separator_names[] =
1509 {
4a5301d8
PJ
1510 {"space", SEPARATOR_NO_LINE},
1511 {"no-line", SEPARATOR_NO_LINE},
1512 {"single-line", SEPARATOR_SINGLE_LINE},
1513 {"double-line", SEPARATOR_DOUBLE_LINE},
1514 {"single-dashed-line", SEPARATOR_SINGLE_DASHED_LINE},
1515 {"double-dashed-line", SEPARATOR_DOUBLE_DASHED_LINE},
1516 {"shadow-etched-in", SEPARATOR_SHADOW_ETCHED_IN},
1517 {"shadow-etched-out", SEPARATOR_SHADOW_ETCHED_OUT},
1518 {"shadow-etched-in-dash", SEPARATOR_SHADOW_ETCHED_IN_DASH},
1519 {"shadow-etched-out-dash", SEPARATOR_SHADOW_ETCHED_OUT_DASH},
1520 {"shadow-double-etched-in", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
1521 {"shadow-double-etched-out", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
1522 {"shadow-double-etched-in-dash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
1523 {"shadow-double-etched-out-dash",SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
1524 {0,0}
2af98732
GM
1525 };
1526
1527 int i;
1528
1529 label += 2;
1530 for (i = 0; separator_names[i].name; ++i)
1531 if (strcmp (label, separator_names[i].name) == 0)
1532 {
1533 separator_p = 1;
1534 *type = separator_names[i].type;
1535
da88f592
GM
1536 /* If separator type is not supported under Motif,
1537 use a similar one. */
1538 if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
1539 *type -= 4;
1540 break;
1541 }
1542 }
1543 else
1544 {
1545 /* Old-style separator, maybe. It's a separator if it contains
1546 only dashes. */
1547 while (*label == '-')
1548 ++label;
1549 separator_p = *label == 0;
1550 *type = SEPARATOR_SHADOW_ETCHED_IN;
1551 }
1552
1553 return separator_p;
1554}
1555
ab5796a9
MB
1556/* arch-tag: 3d730f36-a441-4a71-9971-48ef3b5a4d9f
1557 (do not change this comment) */