#ifdef NeXT
#undef __STRICT_BSD__
#endif
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "../src/lisp.h"
#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include "lwlib-int.h"
#include "lwlib-utils.h"
#include <X11/StringDefs.h>
#if defined (USE_LUCID)
#include "lwlib-Xlw.h"
#endif
#if defined (USE_MOTIF)
#include "lwlib-Xm.h"
#else
#if defined (USE_LUCID)
#define USE_XAW
#endif
#endif
#if defined (USE_XAW)
#include <X11/Xaw/Paned.h>
#include "lwlib-Xaw.h"
#endif
#if !defined (USE_LUCID) && !defined (USE_MOTIF)
#error At least one of USE_LUCID or USE_MOTIF must be defined.
#endif
#ifndef max
#define max(x, y) ((x) > (y) ? (x) : (y))
#endif
static widget_info*
all_widget_info = NULL;
#ifdef USE_MOTIF
char *lwlib_toolkit_type = "motif";
#else
char *lwlib_toolkit_type = "lucid";
#endif
static widget_value *merge_widget_value P_ ((widget_value *,
widget_value *,
int, int *));
static void instantiate_widget_instance P_ ((widget_instance *));
static int my_strcasecmp P_ ((char *, char *));
static void safe_free_str P_ ((char *));
static void free_widget_value_tree P_ ((widget_value *));
static widget_value *copy_widget_value_tree P_ ((widget_value *,
change_type));
static widget_info *allocate_widget_info P_ ((char *, char *, LWLIB_ID,
widget_value *,
lw_callback, lw_callback,
lw_callback, lw_callback));
static void free_widget_info P_ ((widget_info *));
static void mark_widget_destroyed P_ ((Widget, XtPointer, XtPointer));
static widget_instance *allocate_widget_instance P_ ((widget_info *,
Widget, Boolean));
static void free_widget_instance P_ ((widget_instance *));
static widget_info *get_widget_info P_ ((LWLIB_ID, Boolean));
static widget_instance *get_widget_instance P_ ((Widget, Boolean));
static widget_instance *find_instance P_ ((LWLIB_ID, Widget, Boolean));
static Boolean safe_strcmp P_ ((char *, char *));
static Widget name_to_widget P_ ((widget_instance *, char *));
static void set_one_value P_ ((widget_instance *, widget_value *, Boolean));
static void update_one_widget_instance P_ ((widget_instance *, Boolean));
static void update_all_widget_values P_ ((widget_info *, Boolean));
static void initialize_widget_instance P_ ((widget_instance *));
static widget_creation_function find_in_table P_ ((char *, widget_creation_entry *));
static Boolean dialog_spec_p P_ ((char *));
static void destroy_one_instance P_ ((widget_instance *));
static void lw_pop_all_widgets P_ ((LWLIB_ID, Boolean));
static Boolean get_one_value P_ ((widget_instance *, widget_value *));
static void show_one_widget_busy P_ ((Widget, Boolean));
void
lwlib_memset (address, value, length)
char *address;
int value;
size_t length;
{
int i;
for (i = 0; i < length; i++)
address[i] = value;
}
void
lwlib_bcopy (from, to, length)
char *from;
char *to;
int length;
{
int i;
for (i = 0; i < length; i++)
to[i] = from[i];
}
char *
safe_strdup (s)
const char *s;
{
char *result;
if (! s) return 0;
result = (char *) malloc (strlen (s) + 1);
if (! result)
return 0;
strcpy (result, s);
return result;
}
static int
my_strcasecmp (s1, s2)
char *s1, *s2;
{
while (1)
{
int c1 = *s1++;
int c2 = *s2++;
if (isupper (c1))
c1 = tolower (c1);
if (isupper (c2))
c2 = tolower (c2);
if (c1 != c2)
return (c1 > c2 ? 1 : -1);
if (c1 == 0)
return 0;
}
}
static void
safe_free_str (s)
char *s;
{
if (s) free (s);
}
static widget_value *widget_value_free_list = 0;
static int malloc_cpt = 0;
widget_value *
malloc_widget_value ()
{
widget_value *wv;
if (widget_value_free_list)
{
wv = widget_value_free_list;
widget_value_free_list = wv->free_list;
wv->free_list = 0;
}
else
{
wv = (widget_value *) malloc (sizeof (widget_value));
malloc_cpt++;
}
lwlib_memset ((void*) wv, 0, sizeof (widget_value));
return wv;
}
void
free_widget_value (wv)
widget_value *wv;
{
if (wv->free_list)
abort ();
if (malloc_cpt > 25)
{
free (wv);
malloc_cpt--;
}
else
{
wv->free_list = widget_value_free_list;
widget_value_free_list = wv;
}
}
static void
free_widget_value_tree (wv)
widget_value *wv;
{
if (!wv)
return;
if (wv->name) free (wv->name);
if (wv->value) free (wv->value);
if (wv->key) free (wv->key);
wv->name = wv->value = wv->key = (char *) 0xDEADBEEF;
if (wv->toolkit_data && wv->free_toolkit_data)
{
XtFree (wv->toolkit_data);
wv->toolkit_data = (void *) 0xDEADBEEF;
}
if (wv->contents && (wv->contents != (widget_value*)1))
{
free_widget_value_tree (wv->contents);
wv->contents = (widget_value *) 0xDEADBEEF;
}
if (wv->next)
{
free_widget_value_tree (wv->next);
wv->next = (widget_value *) 0xDEADBEEF;
}
free_widget_value (wv);
}
static widget_value *
copy_widget_value_tree (val, change)
widget_value* val;
change_type change;
{
widget_value* copy;
if (!val)
return NULL;
if (val == (widget_value *) 1)
return val;
copy = malloc_widget_value ();
copy->name = safe_strdup (val->name);
copy->value = safe_strdup (val->value);
copy->key = safe_strdup (val->key);
copy->help = val->help;
copy->enabled = val->enabled;
copy->button_type = val->button_type;
copy->selected = val->selected;
copy->edited = False;
copy->change = change;
copy->this_one_change = change;
copy->contents = copy_widget_value_tree (val->contents, change);
copy->call_data = val->call_data;
copy->next = copy_widget_value_tree (val->next, change);
copy->toolkit_data = NULL;
copy->free_toolkit_data = False;
return copy;
}
static widget_info *
allocate_widget_info (type, name, id, val, pre_activate_cb,
selection_cb, post_activate_cb, highlight_cb)
char* type;
char* name;
LWLIB_ID id;
widget_value* val;
lw_callback pre_activate_cb;
lw_callback selection_cb;
lw_callback post_activate_cb;
lw_callback highlight_cb;
{
widget_info* info = (widget_info*)malloc (sizeof (widget_info));
info->type = safe_strdup (type);
info->name = safe_strdup (name);
info->id = id;
info->val = copy_widget_value_tree (val, STRUCTURAL_CHANGE);
info->busy = False;
info->pre_activate_cb = pre_activate_cb;
info->selection_cb = selection_cb;
info->post_activate_cb = post_activate_cb;
info->highlight_cb = highlight_cb;
info->instances = NULL;
info->next = all_widget_info;
all_widget_info = info;
return info;
}
static void
free_widget_info (info)
widget_info* info;
{
safe_free_str (info->type);
safe_free_str (info->name);
free_widget_value_tree (info->val);
lwlib_memset ((void*)info, 0xDEADBEEF, sizeof (widget_info));
free (info);
}
static void
mark_widget_destroyed (widget, closure, call_data)
Widget widget;
XtPointer closure;
XtPointer call_data;
{
widget_instance* instance = (widget_instance*)closure;
if (instance->widget == widget)
instance->widget = NULL;
}
static widget_instance *
#ifdef PROTOTYPES
allocate_widget_instance (widget_info* info, Widget parent, Boolean pop_up_p)
#else
allocate_widget_instance (info, parent, pop_up_p)
widget_info* info;
Widget parent;
Boolean pop_up_p;
#endif
{
widget_instance* instance =
(widget_instance*)malloc (sizeof (widget_instance));
bzero (instance, sizeof *instance);
instance->parent = parent;
instance->pop_up_p = pop_up_p;
instance->info = info;
instance->next = info->instances;
info->instances = instance;
instantiate_widget_instance (instance);
XtAddCallback (instance->widget, XtNdestroyCallback,
mark_widget_destroyed, (XtPointer)instance);
return instance;
}
static void
free_widget_instance (instance)
widget_instance* instance;
{
lwlib_memset ((void*)instance, 0xDEADBEEF, sizeof (widget_instance));
free (instance);
}
static widget_info *
#ifdef PROTOTYPES
get_widget_info (LWLIB_ID id, Boolean remove_p)
#else
get_widget_info (id, remove_p)
LWLIB_ID id;
Boolean remove_p;
#endif
{
widget_info* info;
widget_info* prev;
for (prev = NULL, info = all_widget_info;
info;
prev = info, info = info->next)
if (info->id == id)
{
if (remove_p)
{
if (prev)
prev->next = info->next;
else
all_widget_info = info->next;
}
return info;
}
return NULL;
}
widget_info *
lw_get_widget_info (id)
LWLIB_ID id;
{
return get_widget_info (id, 0);
}
static widget_instance *
#ifdef PROTOTYPES
get_widget_instance (Widget widget, Boolean remove_p)
#else
get_widget_instance (widget, remove_p)
Widget widget;
Boolean remove_p;
#endif
{
widget_info* info;
widget_instance* instance;
widget_instance* prev;
for (info = all_widget_info; info; info = info->next)
for (prev = NULL, instance = info->instances;
instance;
prev = instance, instance = instance->next)
if (instance->widget == widget)
{
if (remove_p)
{
if (prev)
prev->next = instance->next;
else
info->instances = instance->next;
}
return instance;
}
return (widget_instance *) 0;
}
widget_instance *
lw_get_widget_instance (widget)
Widget widget;
{
return get_widget_instance (widget, False);
}
static widget_instance*
#ifdef PROTOTYPES
find_instance (LWLIB_ID id, Widget parent, Boolean pop_up_p)
#else
find_instance (id, parent, pop_up_p)
LWLIB_ID id;
Widget parent;
Boolean pop_up_p;
#endif
{
widget_info* info = get_widget_info (id, False);
widget_instance* instance;
if (info)
for (instance = info->instances; instance; instance = instance->next)
if (instance->parent == parent && instance->pop_up_p == pop_up_p)
return instance;
return NULL;
}
static Boolean
safe_strcmp (s1, s2)
char* s1;
char* s2;
{
if (!!s1 ^ !!s2) return True;
return (s1 && s2) ? strcmp (s1, s2) : s1 ? False : !!s2;
}
#if 0
# define EXPLAIN(name, oc, nc, desc, a1, a2) \
printf ("Change: \"%s\"\tmax(%s=%d,%s=%d)\t%s %d %d\n", \
name, \
(oc == NO_CHANGE ? "none" : \
(oc == INVISIBLE_CHANGE ? "invisible" : \
(oc == VISIBLE_CHANGE ? "visible" : \
(oc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
oc, \
(nc == NO_CHANGE ? "none" : \
(nc == INVISIBLE_CHANGE ? "invisible" : \
(nc == VISIBLE_CHANGE ? "visible" : \
(nc == STRUCTURAL_CHANGE ? "structural" : "???")))), \
nc, desc, a1, a2)
#else
# define EXPLAIN(name, oc, nc, desc, a1, a2)
#endif
static widget_value *
merge_widget_value (val1, val2, level, change_p)
widget_value* val1;
widget_value* val2;
int level;
int *change_p;
{
change_type change, this_one_change;
widget_value* merged_next;
widget_value* merged_contents;
if (!val1)
{
if (val2)
{
*change_p = 1;
return copy_widget_value_tree (val2, STRUCTURAL_CHANGE);
}
else
return NULL;
}
if (!val2)
{
*change_p = 1;
free_widget_value_tree (val1);
return NULL;
}
change = NO_CHANGE;
if (safe_strcmp (val1->name, val2->name))
{
EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "name change",
val1->name, val2->name);
change = max (change, STRUCTURAL_CHANGE);
safe_free_str (val1->name);
val1->name = safe_strdup (val2->name);
}
if (safe_strcmp (val1->value, val2->value))
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "value change",
val1->value, val2->value);
change = max (change, VISIBLE_CHANGE);
safe_free_str (val1->value);
val1->value = safe_strdup (val2->value);
}
if (safe_strcmp (val1->key, val2->key))
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "key change",
val1->key, val2->key);
change = max (change, VISIBLE_CHANGE);
safe_free_str (val1->key);
val1->key = safe_strdup (val2->key);
}
if (! EQ (val1->help, val2->help))
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "help change",
val1->help, val2->help);
change = max (change, VISIBLE_CHANGE);
val1->help = val2->help;
}
if (val1->enabled != val2->enabled)
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "enablement change",
val1->enabled, val2->enabled);
change = max (change, VISIBLE_CHANGE);
val1->enabled = val2->enabled;
}
if (val1->button_type != val2->button_type)
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "button type change",
val1->button_type, val2->button_type);
change = max (change, VISIBLE_CHANGE);
val1->button_type = val2->button_type;
}
if (val1->selected != val2->selected)
{
EXPLAIN (val1->name, change, VISIBLE_CHANGE, "selection change",
val1->selected, val2->selected);
change = max (change, VISIBLE_CHANGE);
val1->selected = val2->selected;
}
if (val1->call_data != val2->call_data)
{
EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "call-data change",
val1->call_data, val2->call_data);
change = max (change, INVISIBLE_CHANGE);
val1->call_data = val2->call_data;
}
if (level > 0)
{
merged_contents =
merge_widget_value (val1->contents, val2->contents, level - 1,
change_p);
if (val1->contents && !merged_contents)
{
EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(contents gone)",
0, 0);
change = max (change, STRUCTURAL_CHANGE);
}
else if (merged_contents && merged_contents->change != NO_CHANGE)
{
EXPLAIN (val1->name, change, INVISIBLE_CHANGE, "(contents change)",
0, 0);
change = max (change, INVISIBLE_CHANGE);
#if 0
#ifdef USE_MOTIF
change = max (merged_contents->change, change);
#endif
#endif
}
val1->contents = merged_contents;
}
this_one_change = change;
merged_next = merge_widget_value (val1->next, val2->next, level, change_p);
if (val1->next && !merged_next)
{
EXPLAIN (val1->name, change, STRUCTURAL_CHANGE, "(following gone)",
0, 0);
change = max (change, STRUCTURAL_CHANGE);
}
else if (merged_next)
{
if (merged_next->change)
EXPLAIN (val1->name, change, merged_next->change, "(following change)",
0, 0);
change = max (change, merged_next->change);
}
val1->next = merged_next;
val1->this_one_change = this_one_change;
val1->change = change;
if (change > NO_CHANGE && val1->toolkit_data)
{
*change_p = 1;
if (val1->free_toolkit_data)
XtFree (val1->toolkit_data);
val1->toolkit_data = NULL;
}
return val1;
}
static Widget
name_to_widget (instance, name)
widget_instance* instance;
char* name;
{
Widget widget = NULL;
if (!instance->widget)
return NULL;
if (!strcmp (XtName (instance->widget), name))
widget = instance->widget;
else
{
int length = strlen (name) + 2;
char* real_name = (char *) xmalloc (length);
real_name [0] = '*';
strcpy (real_name + 1, name);
widget = XtNameToWidget (instance->widget, real_name);
free (real_name);
}
return widget;
}
static void
#ifdef PROTOTYPES
set_one_value (widget_instance* instance, widget_value* val, Boolean deep_p)
#else
set_one_value (instance, val, deep_p)
widget_instance* instance;
widget_value* val;
Boolean deep_p;
#endif
{
Widget widget = name_to_widget (instance, val->name);
if (widget)
{
#if defined (USE_LUCID)
if (lw_lucid_widget_p (instance->widget))
xlw_update_one_widget (instance, widget, val, deep_p);
#endif
#if defined (USE_MOTIF)
if (lw_motif_widget_p (instance->widget))
xm_update_one_widget (instance, widget, val, deep_p);
#endif
#if defined (USE_XAW)
if (lw_xaw_widget_p (instance->widget))
xaw_update_one_widget (instance, widget, val, deep_p);
#endif
}
}
static void
#ifdef PROTOTYPES
update_one_widget_instance (widget_instance* instance, Boolean deep_p)
#else
update_one_widget_instance (instance, deep_p)
widget_instance* instance;
Boolean deep_p;
#endif
{
widget_value *val;
if (!instance->widget)
return;
for (val = instance->info->val; val; val = val->next)
if (val->change != NO_CHANGE)
set_one_value (instance, val, deep_p);
}
static void
#ifdef PROTOTYPES
update_all_widget_values (widget_info* info, Boolean deep_p)
#else
update_all_widget_values (info, deep_p)
widget_info* info;
Boolean deep_p;
#endif
{
widget_instance* instance;
widget_value* val;
for (instance = info->instances; instance; instance = instance->next)
update_one_widget_instance (instance, deep_p);
for (val = info->val; val; val = val->next)
val->change = NO_CHANGE;
}
int
#ifdef PROTOTYPES
lw_modify_all_widgets (LWLIB_ID id, widget_value* val, Boolean deep_p)
#else
lw_modify_all_widgets (id, val, deep_p)
LWLIB_ID id;
widget_value* val;
Boolean deep_p;
#endif
{
widget_info* info = get_widget_info (id, False);
widget_value* new_val;
widget_value* next_new_val;
widget_value* cur;
widget_value* prev;
widget_value* next;
int found;
int change_p = 0;
if (!info)
return 0;
for (new_val = val; new_val; new_val = new_val->next)
{
next_new_val = new_val->next;
new_val->next = NULL;
found = False;
for (prev = NULL, cur = info->val; cur; prev = cur, cur = cur->next)
if (!strcmp (cur->name, new_val->name))
{
found = True;
next = cur->next;
cur->next = NULL;
cur = merge_widget_value (cur, new_val, deep_p ? 1000 : 1,
&change_p);
if (prev)
prev->next = cur ? cur : next;
else
info->val = cur ? cur : next;
if (cur)
cur->next = next;
break;
}
if (!found)
{
if (prev)
prev->next = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
else
info->val = copy_widget_value_tree (new_val, STRUCTURAL_CHANGE);
change_p = 1;
}
new_val->next = next_new_val;
}
update_all_widget_values (info, deep_p);
return change_p;
}
static void
initialize_widget_instance (instance)
widget_instance* instance;
{
widget_value* val;
for (val = instance->info->val; val; val = val->next)
val->change = STRUCTURAL_CHANGE;
update_one_widget_instance (instance, True);
for (val = instance->info->val; val; val = val->next)
val->change = NO_CHANGE;
}
static widget_creation_function
find_in_table (type, table)
char* type;
widget_creation_entry* table;
{
widget_creation_entry* cur;
for (cur = table; cur->type; cur++)
if (!my_strcasecmp (type, cur->type))
return cur->function;
return NULL;
}
static Boolean
dialog_spec_p (name)
char* name;
{
if (!name)
return False;
switch (name [0])
{
case 'E': case 'I': case 'L': case 'P': case 'Q':
case 'e': case 'i': case 'l': case 'p': case 'q':
if (name [1] >= '0' && name [1] <= '9')
{
if (name [2] != 'B' && name [2] != 'b')
return False;
if (!name [3])
return True;
if ((name [3] == 'T' || name [3] == 't') && !name [4])
return True;
if ((name [3] == 'R' || name [3] == 'r')
&& name [4] >= '0' && name [4] <= '9' && !name [5])
return True;
return False;
}
else
return False;
default:
return False;
}
}
static void
instantiate_widget_instance (instance)
widget_instance* instance;
{
widget_creation_function function = NULL;
#if defined (USE_LUCID)
if (!function)
function = find_in_table (instance->info->type, xlw_creation_table);
#endif
#if defined(USE_MOTIF)
if (!function)
function = find_in_table (instance->info->type, xm_creation_table);
#endif
#if defined (USE_XAW)
if (!function)
function = find_in_table (instance->info->type, xaw_creation_table);
#endif
if (!function)
{
if (dialog_spec_p (instance->info->type))
{
#if defined (USE_LUCID)
#endif
#if defined(USE_MOTIF)
if (!function)
function = xm_create_dialog;
#endif
#if defined (USE_XAW)
if (!function)
function = xaw_create_dialog;
#endif
}
}
if (!function)
{
printf ("No creation function for widget type %s\n",
instance->info->type);
abort ();
}
instance->widget = (*function) (instance);
if (!instance->widget)
abort ();
}
void
lw_register_widget (type, name, id, val, pre_activate_cb,
selection_cb, post_activate_cb, highlight_cb)
char* type;
char* name;
LWLIB_ID id;
widget_value* val;
lw_callback pre_activate_cb;
lw_callback selection_cb;
lw_callback post_activate_cb;
lw_callback highlight_cb;
{
if (!get_widget_info (id, False))
allocate_widget_info (type, name, id, val, pre_activate_cb, selection_cb,
post_activate_cb, highlight_cb);
}
Widget
#ifdef PROTOTYPES
lw_get_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
#else
lw_get_widget (id, parent, pop_up_p)
LWLIB_ID id;
Widget parent;
Boolean pop_up_p;
#endif
{
widget_instance* instance;
instance = find_instance (id, parent, pop_up_p);
return instance ? instance->widget : NULL;
}
Widget
#ifdef PROTOTYPES
lw_make_widget (LWLIB_ID id, Widget parent, Boolean pop_up_p)
#else
lw_make_widget (id, parent, pop_up_p)
LWLIB_ID id;
Widget parent;
Boolean pop_up_p;
#endif
{
widget_instance* instance;
widget_info* info;
instance = find_instance (id, parent, pop_up_p);
if (!instance)
{
info = get_widget_info (id, False);
if (!info)
return NULL;
instance = allocate_widget_instance (info, parent, pop_up_p);
initialize_widget_instance (instance);
}
if (!instance->widget)
abort ();
return instance->widget;
}
Widget
#ifdef PROTOTYPES
lw_create_widget (char* type, char* name, LWLIB_ID id, widget_value* val,
Widget parent, Boolean pop_up_p,
lw_callback pre_activate_cb, lw_callback selection_cb,
lw_callback post_activate_cb, lw_callback highlight_cb)
#else
lw_create_widget (type, name, id, val, parent, pop_up_p, pre_activate_cb,
selection_cb, post_activate_cb, highlight_cb)
char* type;
char* name;
LWLIB_ID id;
widget_value* val;
Widget parent;
Boolean pop_up_p;
lw_callback pre_activate_cb;
lw_callback selection_cb;
lw_callback post_activate_cb;
lw_callback highlight_cb;
#endif
{
lw_register_widget (type, name, id, val, pre_activate_cb, selection_cb,
post_activate_cb, highlight_cb);
return lw_make_widget (id, parent, pop_up_p);
}
static void
destroy_one_instance (instance)
widget_instance* instance;
{
if (instance->widget)
XtRemoveCallback (instance->widget, XtNdestroyCallback,
mark_widget_destroyed, (XtPointer)instance);
if (instance->widget)
{
#if defined (USE_LUCID)
if (lw_lucid_widget_p (instance->widget))
xlw_destroy_instance (instance);
else
#endif
#if defined (USE_MOTIF)
if (lw_motif_widget_p (instance->widget))
xm_destroy_instance (instance);
else
#endif
#if defined (USE_XAW)
if (lw_xaw_widget_p (instance->widget))
xaw_destroy_instance (instance);
else
#endif
;
}
free_widget_instance (instance);
}
void
lw_destroy_widget (w)
Widget w;
{
widget_instance* instance = get_widget_instance (w, True);
if (instance)
{
widget_info *info = instance->info;
destroy_one_instance (instance);
if (!info->instances)
lw_destroy_all_widgets (info->id);
}
}
void
lw_destroy_all_widgets (id)
LWLIB_ID id;
{
widget_info* info = get_widget_info (id, True);
widget_instance* instance;
widget_instance* next;
if (info)
{
for (instance = info->instances; instance; )
{
next = instance->next;
destroy_one_instance (instance);
instance = next;
}
free_widget_info (info);
}
}
void
lw_destroy_everything ()
{
while (all_widget_info)
lw_destroy_all_widgets (all_widget_info->id);
}
void
lw_destroy_all_pop_ups ()
{
widget_info* info;
widget_info* next;
widget_instance* instance;
for (info = all_widget_info; info; info = next)
{
next = info->next;
instance = info->instances;
if (instance && instance->pop_up_p)
lw_destroy_all_widgets (info->id);
}
}
#ifdef USE_MOTIF
extern Widget first_child ();
#endif
Widget
lw_raise_all_pop_up_widgets ()
{
widget_info* info;
widget_instance* instance;
Widget result = NULL;
for (info = all_widget_info; info; info = info->next)
for (instance = info->instances; instance; instance = instance->next)
if (instance->pop_up_p)
{
Widget widget = instance->widget;
if (widget)
{
if (XtIsManaged (widget)
#ifdef USE_MOTIF
|| (lw_motif_widget_p (instance->widget) &&
XtIsManaged (first_child (widget)))
#endif
)
{
if (!result)
result = widget;
XMapRaised (XtDisplay (widget), XtWindow (widget));
}
}
}
return result;
}
static void
#ifdef PROTOTYPES
lw_pop_all_widgets (LWLIB_ID id, Boolean up)
#else
lw_pop_all_widgets (id, up)
LWLIB_ID id;
Boolean up;
#endif
{
widget_info* info = get_widget_info (id, False);
widget_instance* instance;
if (info)
for (instance = info->instances; instance; instance = instance->next)
if (instance->pop_up_p && instance->widget)
{
#if defined (USE_LUCID)
if (lw_lucid_widget_p (instance->widget))
{
XtRealizeWidget (instance->widget);
xlw_pop_instance (instance, up);
}
#endif
#if defined (USE_MOTIF)
if (lw_motif_widget_p (instance->widget))
{
XtRealizeWidget (instance->widget);
xm_pop_instance (instance, up);
}
#endif
#if defined (USE_XAW)
if (lw_xaw_widget_p (instance->widget))
{
XtRealizeWidget (XtParent (instance->widget));
XtRealizeWidget (instance->widget);
xaw_pop_instance (instance, up);
}
#endif
}
}
void
lw_pop_up_all_widgets (id)
LWLIB_ID id;
{
lw_pop_all_widgets (id, True);
}
void
lw_pop_down_all_widgets (id)
LWLIB_ID id;
{
lw_pop_all_widgets (id, False);
}
void
lw_popup_menu (widget, event)
Widget widget;
XEvent *event;
{
#if defined (USE_LUCID)
if (lw_lucid_widget_p (widget))
xlw_popup_menu (widget, event);
#endif
#if defined (USE_MOTIF)
if (lw_motif_widget_p (widget))
xm_popup_menu (widget, event);
#endif
#if defined (USE_XAW)
if (lw_xaw_widget_p (widget))
xaw_popup_menu (widget, event);
#endif
}
static Boolean
get_one_value (instance, val)
widget_instance* instance;
widget_value* val;
{
Widget widget = name_to_widget (instance, val->name);
if (widget)
{
#if defined (USE_LUCID)
if (lw_lucid_widget_p (instance->widget))
xlw_update_one_value (instance, widget, val);
#endif
#if defined (USE_MOTIF)
if (lw_motif_widget_p (instance->widget))
xm_update_one_value (instance, widget, val);
#endif
#if defined (USE_XAW)
if (lw_xaw_widget_p (instance->widget))
xaw_update_one_value (instance, widget, val);
#endif
return True;
}
else
return False;
}
Boolean
lw_get_some_values (id, val_out)
LWLIB_ID id;
widget_value* val_out;
{
widget_info* info = get_widget_info (id, False);
widget_instance* instance;
widget_value* val;
Boolean result = False;
if (!info)
return False;
instance = info->instances;
if (!instance)
return False;
for (val = val_out; val; val = val->next)
if (get_one_value (instance, val))
result = True;
return result;
}
widget_value*
lw_get_all_values (id)
LWLIB_ID id;
{
widget_info* info = get_widget_info (id, False);
widget_value* val = info->val;
if (lw_get_some_values (id, val))
return val;
else
return NULL;
}
widget_value*
lw_get_widget_value_for_widget (instance, w)
widget_instance* instance;
Widget w;
{
char* name = XtName (w);
widget_value* cur;
for (cur = instance->info->val; cur; cur = cur->next)
if (!strcmp (cur->name, name))
return cur;
return NULL;
}
static Boolean lwlib_updating;
void
lw_internal_update_other_instances (widget, closure, call_data)
Widget widget;
XtPointer closure;
XtPointer call_data;
{
widget_instance* instance = (widget_instance*)closure;
char* name = XtName (widget);
widget_info* info;
widget_instance* cur;
widget_value* val;
if (lwlib_updating)
return;
if (XtWidgetBeingDestroyedP (widget))
return;
info = instance->info;
if (!info->instances->next)
return;
lwlib_updating = True;
for (val = info->val; val && strcmp (val->name, name); val = val->next);
if (val && get_one_value (instance, val))
for (cur = info->instances; cur; cur = cur->next)
if (cur != instance)
set_one_value (cur, val, True);
lwlib_updating = False;
}
LWLIB_ID
lw_get_widget_id (w)
Widget w;
{
widget_instance* instance = get_widget_instance (w, False);
return instance ? instance->info->id : 0;
}
void
lw_set_keyboard_focus (parent, w)
Widget parent;
Widget w;
{
#if defined (USE_MOTIF)
xm_set_keyboard_focus (parent, w);
#else
XtSetKeyboardFocus (parent, w);
#endif
}
static void
#ifdef PROTOTYPES
show_one_widget_busy (Widget w, Boolean flag)
#else
show_one_widget_busy (w, flag)
Widget w;
Boolean flag;
#endif
{
Pixel foreground = 0;
Pixel background = 1;
Widget widget_to_invert = XtNameToWidget (w, "*sheet");
if (!widget_to_invert)
widget_to_invert = w;
XtVaGetValues (widget_to_invert,
XtNforeground, &foreground,
XtNbackground, &background,
NULL);
XtVaSetValues (widget_to_invert,
XtNforeground, background,
XtNbackground, foreground,
NULL);
}
void
#ifdef PROTOTYPES
lw_show_busy (Widget w, Boolean busy)
#else
lw_show_busy (w, busy)
Widget w;
Boolean busy;
#endif
{
widget_instance* instance = get_widget_instance (w, False);
widget_info* info;
widget_instance* next;
if (instance)
{
info = instance->info;
if (info->busy != busy)
{
for (next = info->instances; next; next = next->next)
if (next->widget)
show_one_widget_busy (next->widget, busy);
info->busy = busy;
}
}
}
void
#ifdef PROTOTYPES
lw_refigure_widget (Widget w, Boolean doit)
#else
lw_refigure_widget (w, doit)
Widget w;
Boolean doit;
#endif
{
#if defined (USE_XAW)
XawPanedSetRefigureMode (w, doit);
#endif
#if defined (USE_MOTIF)
if (doit)
XtManageChild (w);
else
XtUnmanageChild (w);
#endif
}
Boolean
lw_window_is_in_menubar (win, menubar_widget)
Window win;
Widget menubar_widget;
{
return menubar_widget
#if defined (USE_LUCID)
&& XtWindow (menubar_widget) == win;
#endif
#if defined (USE_MOTIF)
&& ((XtWindow (menubar_widget) == win)
|| (XtWindowToWidget (XtDisplay (menubar_widget), win)
&& (XtParent (XtWindowToWidget (XtDisplay (menubar_widget), win))
== menubar_widget)));
#endif
}
void
lw_set_main_areas (parent, menubar, work_area)
Widget parent;
Widget menubar;
Widget work_area;
{
#if defined (USE_MOTIF)
xm_set_main_areas (parent, menubar, work_area);
#endif
}
void
#ifdef PROTOTYPES
lw_allow_resizing (Widget w, Boolean flag)
#else
lw_allow_resizing (w, flag)
Widget w;
Boolean flag;
#endif
{
#if defined (USE_MOTIF)
xm_manage_resizing (w, flag);
#endif
}
int
lw_separator_p (label, type, motif_p)
char *label;
enum menu_separator *type;
int motif_p;
{
int separator_p = 0;
if (strlen (label) >= 3
&& bcmp (label, "--:", 3) == 0)
{
static struct separator_table
{
char *name;
enum menu_separator type;
}
separator_names[] =
{
{"space", SEPARATOR_NO_LINE},
{"noLine", SEPARATOR_NO_LINE},
{"singleLine", SEPARATOR_SINGLE_LINE},
{"doubleLine", SEPARATOR_DOUBLE_LINE},
{"singleDashedLine", SEPARATOR_SINGLE_DASHED_LINE},
{"doubleDashedLine", SEPARATOR_DOUBLE_DASHED_LINE},
{"shadowEtchedIn", SEPARATOR_SHADOW_ETCHED_IN},
{"shadowEtchedOut", SEPARATOR_SHADOW_ETCHED_OUT},
{"shadowEtchedInDash", SEPARATOR_SHADOW_ETCHED_IN_DASH},
{"shadowEtchedOutDash", SEPARATOR_SHADOW_ETCHED_OUT_DASH},
{"shadowDoubleEtchedIn", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
{"shadowDoubleEtchedOut", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
{"shadowDoubleEtchedInDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
{"shadowDoubleEtchedOutDash", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
{0,0}
};
int i;
label += 3;
for (i = 0; separator_names[i].name; ++i)
if (strcmp (label, separator_names[i].name) == 0)
{
separator_p = 1;
*type = separator_names[i].type;
if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
*type -= 4;
break;
}
}
else if (strlen (label) > 3
&& bcmp (label, "--", 2) == 0
&& label[2] != '-')
{
static struct separator_table
{
char *name;
enum menu_separator type;
}
separator_names[] =
{
{"space", SEPARATOR_NO_LINE},
{"no-line", SEPARATOR_NO_LINE},
{"single-line", SEPARATOR_SINGLE_LINE},
{"double-line", SEPARATOR_DOUBLE_LINE},
{"single-dashed-line", SEPARATOR_SINGLE_DASHED_LINE},
{"double-dashed-line", SEPARATOR_DOUBLE_DASHED_LINE},
{"shadow-etched-in", SEPARATOR_SHADOW_ETCHED_IN},
{"shadow-etched-out", SEPARATOR_SHADOW_ETCHED_OUT},
{"shadow-etched-in-dash", SEPARATOR_SHADOW_ETCHED_IN_DASH},
{"shadow-etched-out-dash", SEPARATOR_SHADOW_ETCHED_OUT_DASH},
{"shadow-double-etched-in", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN},
{"shadow-double-etched-out", SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT},
{"shadow-double-etched-in-dash", SEPARATOR_SHADOW_DOUBLE_ETCHED_IN_DASH},
{"shadow-double-etched-out-dash",SEPARATOR_SHADOW_DOUBLE_ETCHED_OUT_DASH},
{0,0}
};
int i;
label += 2;
for (i = 0; separator_names[i].name; ++i)
if (strcmp (label, separator_names[i].name) == 0)
{
separator_p = 1;
*type = separator_names[i].type;
if (motif_p && *type >= SEPARATOR_SHADOW_DOUBLE_ETCHED_IN)
*type -= 4;
break;
}
}
else
{
while (*label == '-')
++label;
separator_p = *label == 0;
*type = SEPARATOR_SHADOW_ETCHED_IN;
}
return separator_p;
}