aboutsummaryrefslogtreecommitdiffstats
path: root/lwlib
diff options
context:
space:
mode:
authorRichard M. Stallman <[email protected]>1994-01-18 23:52:19 +0000
committerRichard M. Stallman <[email protected]>1994-01-18 23:52:19 +0000
commit40a6a4dd2fb9e31c2da2f5924356baf16ca47ffd (patch)
treec3a10075b5f79e4d186929b98fde7fa13f172219 /lwlib
parente7818b5ac8611c09fea3ce9635128414d69f6462 (diff)
entered into RCS
Diffstat (limited to 'lwlib')
-rw-r--r--lwlib/lwlib-Xol.c317
-rw-r--r--lwlib/lwlib-Xol.h2
-rw-r--r--lwlib/lwlib-Xolmb.c370
-rw-r--r--lwlib/lwlib-Xolmb.h25
-rw-r--r--lwlib/lwlib-XolmbP.h49
5 files changed, 762 insertions, 1 deletions
diff --git a/lwlib/lwlib-Xol.c b/lwlib/lwlib-Xol.c
new file mode 100644
index 0000000000..e78751236f
--- /dev/null
+++ b/lwlib/lwlib-Xol.c
@@ -0,0 +1,317 @@
+#include "lwlib-Xol.h"
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/CompositeP.h>
+#include <X11/Shell.h>
+#include <Xol/Menu.h>
+#include <Xol/OpenLook.h>
+#include <Xol/MenuButton.h>
+#include <Xol/OblongButt.h>
+#include <Xol/ControlAre.h>
+#include <Xol/Stub.h>
+#include <Xol/StaticText.h>
+
+ /* forward declarations */
+static void
+update_menu_widget (widget_instance* instance, Widget widget,
+ widget_value* val);
+
+ /* Menu callbacks */
+static void
+pre_hook (Widget w, caddr_t client_data, caddr_t call_data)
+{
+ OlVirtualEvent ve = (OlVirtualEvent)call_data;
+ widget_instance* instance = (widget_instance*)client_data;
+
+ if (w->core.being_destroyed)
+ return;
+
+ if (XtParent (w) == instance->widget)
+ {
+ if (ve->xevent->type == ButtonPress && instance->info->pre_activate_cb)
+ instance->info->pre_activate_cb (instance->widget, instance->info->id,
+ NULL);
+ }
+}
+
+static void
+post_hook (Widget w, caddr_t client_data, caddr_t call_data)
+{
+ widget_instance* instance = (widget_instance*)client_data;
+
+ if (w->core.being_destroyed)
+ return;
+
+ if (instance->info->post_activate_cb)
+ instance->info->post_activate_cb (w, instance->info->id, NULL);
+}
+
+static void
+pick_hook (Widget w, caddr_t client_data, caddr_t call_data)
+{
+ widget_instance* instance = 0;
+ widget_value* val = (widget_value*)client_data;
+
+ if (w->core.being_destroyed)
+ return;
+
+ XtVaGetValues (w, XtNuserData, &instance, 0);
+
+ if (!instance)
+ return;
+
+ if (instance->info->selection_cb && val && val->enabled
+ && !val->contents)
+ instance->info->selection_cb (w, instance->info->id, val->call_data);
+}
+
+ /* creation functions */
+static Widget
+xol_create_menubar (widget_instance* instance)
+{
+ Widget widget =
+ XtVaCreateWidget (instance->info->name, controlAreaWidgetClass,
+ instance->parent, 0);
+ return widget;
+}
+
+static Widget
+xol_create_popup_menu (widget_instance* instance)
+{
+ Widget popup_shell =
+ XtCreatePopupShell (instance->info->name, menuShellWidgetClass,
+ instance->parent, NULL, 0);
+ return popup_shell;
+}
+
+widget_creation_entry
+xol_creation_table [] =
+{
+ {"menubar", xol_create_menubar},
+ {"popup", xol_create_popup_menu},
+ {NULL, NULL}
+};
+
+Widget
+xol_create_dialog (widget_instance* instance)
+{
+ return NULL;
+}
+
+Boolean
+lw_olit_widget_p (Widget widget)
+{
+ return True;
+}
+
+ /* update functions */
+static void
+destroy_all_children (Widget widget)
+{
+ Widget* children;
+ unsigned int number;
+ int i;
+
+ children = (Widget *) XtCompositeChildren (widget, &number);
+ if (children)
+ {
+ /* Unmanage all children and destroy them. They will only be
+ * really destroyed when we get out of DispatchEvent. */
+ for (i = 0; i < number; i++)
+ {
+ Widget child = children [i];
+ if (!child->core.being_destroyed)
+ {
+ XtUnmanageChild (child);
+ XtDestroyWidget (child);
+ }
+ }
+ XtFree (children);
+ }
+}
+
+static Boolean
+all_dashes_p (char* s)
+{
+ char* t;
+ for (t = s; *t; t++)
+ if (*t != '-')
+ return False;
+ return True;
+}
+
+static void
+make_menu_in_widget (widget_instance* instance, Widget widget,
+ widget_value* val)
+{
+ widget_value* cur;
+ Widget button;
+ Arg al [256];
+ int ac;
+ String label;
+
+ for (cur = val; cur; cur = cur->next)
+ {
+ ac = 0;
+ XtSetArg (al [ac], XtNsensitive, cur->enabled); ac++;
+ XtSetArg (al [ac], XtNuserData, instance); ac++;
+ XtSetArg (al [ac], XtNacceleratorText, cur->key); ac++;
+
+/* label = (char *) resource_string (widget, cur->name);*/
+ label = cur->name;
+ if (label)
+ {
+ XtSetArg (al [ac], XtNlabel, label); ac++;
+ }
+
+ if (all_dashes_p (cur->name))
+ {
+ /* no separator in OpenLook just make some space. */
+ XtSetArg (al [ac], XtNheight, 5); ac++;
+ XtSetArg (al [ac], XtNwidth, 5); ac++;
+ button = XtCreateWidget (cur->name, stubWidgetClass, widget, al, ac);
+ }
+ else if (!cur->contents)
+ {
+ if (!cur->call_data)
+ button =
+ XtCreateManagedWidget (cur->name, staticTextWidgetClass, widget,
+ al, ac);
+ else
+ {
+ button =
+ XtCreateManagedWidget (cur->name, oblongButtonWidgetClass,
+ widget, al, ac);
+ XtAddCallback (button, XtNselect, pick_hook, cur);
+ }
+ }
+ else
+ {
+ Widget menu = NULL;
+ button =
+ XtCreateManagedWidget (cur->name, menuButtonWidgetClass, widget,
+ al, ac);
+ XtVaGetValues (button, XtNmenuPane, &menu, 0);
+ if (!menu)
+ abort ();
+ make_menu_in_widget (instance, menu, cur->contents);
+ OlAddCallback (button, XtNconsumeEvent, pre_hook, instance);
+ }
+ }
+}
+
+static void
+update_one_menu_entry (widget_instance* instance, Widget widget,
+ widget_value* val)
+{
+ Arg al [256];
+ int ac;
+ Widget menu;
+ widget_value* contents;
+
+ if (val->change == NO_CHANGE)
+ return;
+
+ /* update the sensitivity */
+ XtVaSetValues (widget, XtNsensitive, val->enabled, 0);
+
+ /* update the pulldown/pullaside as needed */
+ ac = 0;
+ menu = NULL;
+ XtVaGetValues (widget, XtNmenuPane, &menu, 0);
+ contents = val->contents;
+
+ if (!menu)
+ {
+ if (contents)
+ {
+ /* in OLIT this woudl have to be a structural change on the
+ button. */
+ abort ();
+ }
+ }
+ else if (!contents)
+ {
+ /* in OLIT this woudl have to be a structural change on the button. */
+ abort ();
+ }
+ else if (contents->change != NO_CHANGE)
+ update_menu_widget (instance, menu, val);
+}
+
+static void
+update_menu_widget (widget_instance* instance, Widget widget,
+ widget_value* val)
+
+{
+ if (val->change == STRUCTURAL_CHANGE
+ || val->contents->change == STRUCTURAL_CHANGE)
+ {
+ destroy_all_children (widget);
+ make_menu_in_widget (instance, widget, val->contents);
+ }
+ else
+ {
+ /* Update all the buttons of the composite widget in order. */
+ Widget* children;
+ unsigned int num_children;
+ int i;
+ widget_value* cur;
+
+ children = (Widget *) XtCompositeChildren (widget, &num_children);
+ if (children)
+ {
+ for (i = 0, cur = val->contents; i < num_children; i++)
+ {
+ if (!cur)
+ abort ();
+ if (children [i]->core.being_destroyed
+ || strcmp (XtName (children [i]), cur->name))
+ continue;
+ update_one_menu_entry (instance, children [i], cur);
+ cur = cur->next;
+ }
+ XtFree (children);
+ }
+ if (cur)
+ abort ();
+ }
+}
+
+void
+xol_update_one_widget (widget_instance* instance, Widget widget,
+ widget_value* val, Boolean deep_p)
+{
+ Widget menu = widget;
+
+ if (XtIsShell (widget))
+ XtVaGetValues (widget, XtNmenuPane, &menu, 0);
+
+ update_menu_widget (instance, menu, val);
+}
+
+void
+xol_update_one_value (widget_instance* instance, Widget widget,
+ widget_value* val)
+{
+ return;
+}
+
+void
+xol_pop_instance (widget_instance* instance, Boolean up)
+{
+}
+
+void
+xol_popup_menu (Widget widget)
+{
+ OlMenuPost (widget);
+}
+
+ /* Destruction of instances */
+void
+xol_destroy_instance (widget_instance* instance)
+{
+ XtDestroyWidget (instance->widget);
+}
+
diff --git a/lwlib/lwlib-Xol.h b/lwlib/lwlib-Xol.h
index ee4d6481cb..3bf8d11e9e 100644
--- a/lwlib/lwlib-Xol.h
+++ b/lwlib/lwlib-Xol.h
@@ -1,7 +1,7 @@
#ifndef LWLIB_XOL_H
#define LWLIB_XOL_H
-#include "lwlib-internal.h"
+#include "lwlib-int.h"
extern widget_creation_entry xol_creation_table [];
extern Widget xol_create_dialog (widget_instance *);
diff --git a/lwlib/lwlib-Xolmb.c b/lwlib/lwlib-Xolmb.c
new file mode 100644
index 0000000000..f253e3e576
--- /dev/null
+++ b/lwlib/lwlib-Xolmb.c
@@ -0,0 +1,370 @@
+/* An OLIT menubar widget, by Chuck Thompson <[email protected]>
+ Copyright (C) 1993 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <X11/IntrinsicP.h>
+#include <X11/Intrinsic.h>
+#include <X11/CompositeP.h>
+#include <X11/Composite.h>
+#include "lwlib-Xol-mbP.h"
+#include "lwlib-Xol-mb.h"
+
+#define HORIZ_SPACING 4
+#define VERT_SPACING 4
+
+static void Initialize();
+static void Resize();
+static void ChangeManaged();
+static Boolean SetValues();
+static XtGeometryResult GeometryManager();
+static XtGeometryResult PreferredSize();
+static void do_layout();
+static XtGeometryResult try_layout();
+
+lwMenuBarClassRec lwMenubarClassRec =
+{
+ {
+ /* core_class members */
+
+ (WidgetClass) &compositeClassRec, /* superclass */
+ "Menubar", /* class_name */
+ sizeof(lwMenuBarRec), /* widget_size */
+ NULL, /* class_initialize */
+ NULL, /* class_part_initialize */
+ FALSE, /* class_inited */
+ Initialize, /* initialize */
+ NULL, /* initialize_hook */
+ XtInheritRealize, /* realize */
+ NULL, /* actions */
+ 0, /* num_actions */
+ NULL, /* resources */
+ 0, /* num_resources */
+ NULLQUARK, /* xrm_class */
+ TRUE, /* compress_motion */
+ XtExposeCompressMaximal, /* compress_exposure */
+ TRUE, /* compress_enterleave */
+ FALSE, /* visible_interest */
+ NULL, /* destroy */
+ Resize, /* resize */
+ NULL, /* expose */
+ NULL, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ NULL, /* tm_table */
+ PreferredSize, /* query_geometry */
+ NULL, /* display_accelerator */
+ NULL, /* extension */
+ },
+ {
+ /* composite_class members */
+
+ GeometryManager, /* geometry_manager */
+ ChangeManaged, /* change_managed */
+ XtInheritInsertChild, /* insert_child */
+ XtInheritDeleteChild, /* delete_child */
+ NULL, /* extension */
+ },
+ {
+ /* Menubar class members */
+
+ 0, /* empty */
+ }
+};
+WidgetClass lwMenubarWidgetClass = (WidgetClass) &lwMenubarClassRec;
+
+
+static void Initialize (request, new)
+ lwMenuBarWidget request, new;
+{
+ if (request->core.width <= 0)
+ new->core.width = 1;
+ if (request->core.height <= 0)
+ new->core.height = 23;
+}
+
+static void
+Resize (w)
+ lwMenuBarWidget w;
+{
+ do_layout(w);
+}
+
+static void
+do_layout (parent)
+ lwMenuBarWidget parent;
+{
+ Widget child;
+ int cnt;
+ int managed_children = 0;
+ int managed_width = 0;
+ int new_pos = 0;
+
+ /*
+ * Determine number of children which will fit on one line.
+ * For now we ignore the rest, making sure they are unmanaged.
+ */
+
+ cnt = 0;
+ while ((cnt < (int) parent->composite.num_children) &&
+ (managed_width < (int) parent->core.width))
+ {
+ child = parent->composite.children[cnt++];
+ managed_children++;
+ managed_width += child->core.width + child->core.border_width * 2 +
+ HORIZ_SPACING;
+ }
+
+ if (managed_width > (int) parent->core.width)
+ managed_children--;
+
+ /*
+ * Correct positioning of children.
+ */
+
+ cnt = 0;
+ while (managed_children)
+ {
+ child = parent->composite.children[cnt++];
+
+ if (!child->core.managed)
+ XtManageChild (child);
+
+ if ((child->core.x != new_pos) || (child->core.y != 0))
+ XtMoveWidget (child, new_pos, 0);
+ new_pos += child->core.width + child->core.border_width * 2 +
+ HORIZ_SPACING;
+
+ managed_children--;
+ }
+
+ /*
+ * Make sure all remaining children are unmanaged.
+ */
+
+ while (cnt < parent->composite.num_children)
+ {
+ child = parent->composite.children[cnt];
+
+ if (child->core.managed)
+ XtUnmanageChild (child);
+
+ if ((child->core.x != parent->core.width) ||
+ (child->core.y != parent->core.height))
+ XtMoveWidget (child, parent->core.width, parent->core.height);
+
+ cnt++;
+ }
+}
+
+
+static XtGeometryResult
+PreferredSize (w, request, preferred)
+ lwMenuBarWidget w;
+ XtWidgetGeometry *request, *preferred;
+{
+ Widget child;
+ int cnt;
+
+ /*
+ * If no changes are being made to the width or height, just agree.
+ */
+
+ if (!(request->request_mode & CWWidth) &&
+ !(request->request_mode & CWHeight))
+ return (XtGeometryYes);
+
+ /*
+ * Right now assume everything goes in one row. Calculate the
+ * minimum required width and height.
+ */
+
+ preferred->width = 0;
+ preferred->height = 0;
+
+ for (cnt = 0; cnt < w->composite.num_children; cnt++)
+ {
+ child = w->composite.children[cnt];
+ if (child->core.managed)
+ {
+ preferred->width += child->core.width + child->core.border_width*2 +
+ HORIZ_SPACING;
+ if (preferred->height < (Dimension) (child->core.height +
+ child->core.border_width * 2))
+ preferred->height = child->core.height +
+ child->core.border_width * 2;
+ }
+ }
+
+ preferred->request_mode = CWWidth | CWHeight;
+
+ /*
+ * Case: both height and width requested
+ */
+
+ if ((request->request_mode & CWWidth) &&
+ (request->request_mode & CWHeight))
+ {
+ /*
+ * Ok if same or bigger.
+ */
+
+ if (preferred->width <= request->width &&
+ preferred->height <= request->height)
+ {
+ preferred->width = request->width;
+ return (XtGeometryYes);
+ }
+
+ /*
+ * If both dimensions are too small, say no.
+ */
+
+ else
+ if (preferred->width > request->width &&
+ preferred->height > request->height)
+ return (XtGeometryNo);
+
+ /*
+ * Otherwise one must be right, so say almost.
+ */
+
+ else
+ return (XtGeometryAlmost);
+ }
+
+ /*
+ * If only one dimension is requested, either its OK or it isn't.
+ */
+
+ else
+ {
+ if (request->request_mode & CWWidth)
+ {
+ if (preferred->width <= request->width)
+ {
+ preferred->width = request->width;
+ return (XtGeometryYes);
+ }
+ else
+ return (XtGeometryNo);
+ }
+ else if (request->request_mode & CWHeight)
+ {
+ if (preferred->height <= request->height)
+ {
+ return (XtGeometryYes);
+ }
+ else
+ return (XtGeometryNo);
+ }
+
+ return (XtGeometryYes);
+ }
+}
+
+
+static XtGeometryResult
+GeometryManager (w, request, reply)
+ Widget w;
+ XtWidgetGeometry *request;
+ XtWidgetGeometry *reply;
+{
+
+ lwMenuBarWidget parent = (lwMenuBarWidget) w->core.parent;
+
+ /*
+ * If the widget wants to move, just say no.
+ */
+
+ if ((request->request_mode & CWX && request->x != w->core.x) ||
+ (request->request_mode & CWY && request->y != w->core.y))
+ return (XtGeometryNo);
+
+ /*
+ * Since everything "fits" for now, grant all requests.
+ */
+
+ if (request->request_mode & CWWidth)
+ w->core.width = request->width;
+ if (request->request_mode & CWHeight)
+ w->core.height = request->height;
+ if (request->request_mode & CWBorderWidth)
+ w->core.border_width = request->border_width;
+
+ do_layout (parent);
+ return (XtGeometryYes);
+}
+
+
+static XtGeometryResult
+try_layout (parent)
+ lwMenuBarWidget parent;
+{
+ Widget child;
+ int cnt;
+ int managed_children = 0;
+ int managed_width = 0;
+ int new_pos = 0;
+
+ /*
+ * Determine number of children which will fit on one line.
+ * For now we ignore the rest, making sure they are unmanaged.
+ */
+
+ cnt = 0;
+ while ((cnt < (int) parent->composite.num_children) &&
+ (managed_width < (int) parent->core.width))
+ {
+ child = parent->composite.children[cnt++];
+ if (child->core.managed)
+ {
+ managed_children++;
+ managed_width += child->core.width + child->core.border_width * 2 +
+ HORIZ_SPACING;
+ }
+ }
+
+ if (managed_width > (int) parent->core.width)
+ return (XtGeometryNo);
+ else
+ return (XtGeometryYes);
+}
+
+
+
+static void
+ChangeManaged (w)
+ lwMenuBarWidget w;
+{
+ XtGeometryResult result;
+
+ result = try_layout (w);
+
+ if (result != XtGeometryYes)
+ {
+ XtUnmanageChild (w->composite.children[w->composite.num_children - 1]);
+ XtMoveWidget (w->composite.children[w->composite.num_children-1],
+ w->core.width, w->core.height);
+ }
+
+ do_layout (w);
+}
diff --git a/lwlib/lwlib-Xolmb.h b/lwlib/lwlib-Xolmb.h
new file mode 100644
index 0000000000..7da31a7dce
--- /dev/null
+++ b/lwlib/lwlib-Xolmb.h
@@ -0,0 +1,25 @@
+/* An OLIT menubar widget, by Chuck Thompson <[email protected]>
+ Copyright (C) 1993 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef LW_MENUBAR_H
+#define LW_MENUBAR_H
+extern WidgetClass lwMenubarWidgetClass;
+typedef struct _lwMenuBarClassRec *lwMenuBarWidgetClass;
+typedef struct _lwMenuBarRec *lwMenuBarWidget;
+#endif /* LW_MENUBAR_H */
diff --git a/lwlib/lwlib-XolmbP.h b/lwlib/lwlib-XolmbP.h
new file mode 100644
index 0000000000..f2f6f77c0c
--- /dev/null
+++ b/lwlib/lwlib-XolmbP.h
@@ -0,0 +1,49 @@
+/* An OLIT menubar widget, by Chuck Thompson <[email protected]>
+ Copyright (C) 1993 Lucid, Inc.
+
+This file is part of the Lucid Widget Library.
+
+The Lucid Widget Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+The Lucid Widget Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef LW_MENUBARP_H
+#define LW_MENUBARP_H
+
+typedef struct _lwMenuBarClassPart
+{
+ int ignore;
+} lwMenuBarClassPart;
+
+typedef struct _lwMenuBarClassRec
+{
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ lwMenuBarClassPart menubar_class;
+} lwMenuBarClassRec;
+
+extern lwMenuBarClassRec lwMenubarClassRec;
+
+typedef struct
+{
+ int empty;
+} lwMenuBarPart;
+
+typedef struct _lwMenuBarRec
+{
+ CorePart core;
+ CompositePart composite;
+ lwMenuBarPart menubar;
+} lwMenuBarRec;
+
+#endif /* LW_MENUBARP_H */