summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:52 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:52 +0000
commitefce7cb078dd34e9e9f7d6f5f5cdd0c8ef267691 (patch)
treef9652b85cbb9728b5999913ea2aadee0b3ad1a17
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
-rw-r--r--Editres-color.ad37
-rw-r--r--Editres.ad254
-rw-r--r--actions.c358
-rw-r--r--comm.c962
-rw-r--r--editres.c153
-rw-r--r--editres.man433
-rw-r--r--editresP.h352
-rw-r--r--geometry.c490
-rw-r--r--handler.c966
-rw-r--r--setvalues.c122
-rw-r--r--svpopup.c336
-rw-r--r--utils.c915
-rw-r--r--widgets.c1037
-rw-r--r--wtree.c733
14 files changed, 7148 insertions, 0 deletions
diff --git a/Editres-color.ad b/Editres-color.ad
new file mode 100644
index 0000000..62efee5
--- /dev/null
+++ b/Editres-color.ad
@@ -0,0 +1,37 @@
+! $Xorg: Edit-col.ad,v 1.3 2000/08/17 19:53:50 cpqbld Exp $
+! Here are some suggested resources if you are using a color workstation.
+! They look pretty good on my display, your mileage may vary.
+
+#include "Editres"
+
+*flashColor: Yellow
+
+*Background: RoyalBlue4
+*Foreground: Azure
+*BorderColor: LightCyan1
+
+*Tree.Background: Grey
+*Tree.Foreground: White
+
+*Tree.Toggle.Foreground: Gold
+*Tree.Toggle.BorderWidth: 0
+
+*MenuButton.Foreground: Gold
+*MenuButton.BorderWidth: 0
+
+*SmeBSB.Foreground: Gold
+
+*Porthole.Background: Grey
+*porthole.panner*Foreground: red
+*porthole.panner*Background: Grey
+*porthole.panner*BorderColor: Grey
+*porthole.panner*ShadowColor: Black
+*porthole.panner*BackgroundStipple: None
+
+*resourceBox*namesAndClasses.Background: Grey
+*resourceBox*namesAndClasses*Toggle.Background: RoyalBlue4
+*resourceBox*namesAndClasses*Toggle.Foreground: White
+*resourceBox*valueForm.Background: Grey
+*resourceBox*valueLabel.Background: Grey
+*resourceBox*valueLabel.Foreground: White
+*resourceBox*Command.Foreground: Gold
diff --git a/Editres.ad b/Editres.ad
new file mode 100644
index 0000000..7f5c45f
--- /dev/null
+++ b/Editres.ad
@@ -0,0 +1,254 @@
+! $Xorg: Editres.ad,v 1.3 2000/08/17 19:53:51 cpqbld Exp $
+! The App-defaults file for Editres.
+
+Editres.Geometry: 500x600
+
+*ShapeStyle: Oval
+*Tree*ShapeStyle: Rectangle
+
+! The rest of this file are either button names, or important for
+! functionality, modifying these values may cause strange program
+! behavior.
+
+*flash.BorderWidth: 0
+
+! Menu Button Names
+
+*Box*commands.Label: Commands
+*Box*treeCommands.Label: Tree
+
+*porthole.tree.width: 500
+*porthole.tree.height: 480
+
+! Universal Menu Entry Names
+*sendTree.Label: Get Tree
+*quit.Label: Quit
+
+*selectAll.Label: Select All
+*unselectAll.Label: Unselect All
+*invertAll.Label: Invert All
+*selectChildren.Label: Select Children
+*selectParent.Label: Select Parent
+*selectDescendants.Label: Select Descendants
+*selectAncestors.Label: Select Ancestors
+
+! Xt Menu Entry Names
+
+*xt*refreshTree.Label: Refresh Current Widget Tree
+*xt*dumpTreeToFile.Label: Dump Widget Tree to a File
+*xt*getResourceList.Label: Show Resource Box
+*xt*setValues.Label: Set Resource
+
+*xt*showClientWidget.Label: Select Widget in Client
+*xt*showWidgetNames.Label: Show Widget Names
+*xt*showClassNames.Label: Show Class Names
+*xt*showWidgetIDs.Label: Show Widget IDs
+*xt*showWidgetWindows.Label: Show Widget Windows
+*xt*flashActiveWidgets.Label: Flash Active Widgets
+
+! InterViews Menu Entry Names
+
+*iv*refreshTree.Label: Refresh Current Style Tree
+*iv*dumpTreeToFile.Label: Dump Style Tree to a File
+*iv*getResourceList.Label: Show Attribute Box
+*iv*setValues.Label: Set Attribute
+
+*iv*showClientWidget.Label: Select Style in Client
+*iv*showWidgetNames.Label: Show Style Names
+*iv*showClassNames.Label: Show Class Names
+*iv*showWidgetIDs.Label: Show Style IDs
+*iv*showWidgetWindows.Label: Show Style Windows
+*iv*flashActiveWidgets.Label: Flash Active Styles
+
+! Universal Toolkit Messages
+
+*label0: Action `%s' must have the Editres Protocol.
+*label1: Action %s's argument must be either `cancel' or `okay'.
+*label2: Action `%s' must have exactly one argument.
+*label3: Unknown parameter to action `%s' must be one of:\n
+*label4: It appears that this client does not understand\nthe Editres Protocol.
+*label5: Can't grab the mouse.\n
+*label6: Click the mouse pointer on any toolkit client.
+*label8: Message sent to client%s.
+*label9: Incorrectly formatted message from client.
+*label10: Unable to own the Resource Editor Command Selection
+*label11: Unknown Error code %d
+*label13: Welcome to the X Resource Editor version 1.1
+*label15: That window does not appear to be\nin the currently displayed client.
+*label16: Editres Internal Error: Unable to FindNode.\n
+*label18: There are no active nodes.
+*label20: ApplyResource: found no matches.
+*label21: Error: SVActiveEntry Action must have exactly one argument.
+*label22: Error: SVActiveEntry Action's first Argument must be either 'Resource' or 'Value'.
+*label24: Unable to open the file `%s' for writing.
+*label25: Error while trying to save Context\nAborting file dialog popup.
+*label26: Error while trying to find Context\nAborting...
+*label28: Loop in tree: node %s's parent (%s) has not been created yet\n
+*label30: There are no active nodes.
+*label31: Internal Error: Unknown select type.
+*label32: Internal Error: Unknown label type.
+*label33: Internal Error: Unknown activate type.
+*label34: Only one Resource Box can be active at a time.
+*label35: Unable to unpack protocol request.
+*label36: This version of editres uses protocol version %s,\nbut the client speaks version %s.
+
+! Xt Messages
+
+*xt*label7: Unable to own the Resource Selection
+*xt*label12: Widget Tree for client %s(%s).
+*xt*label14: Click on any widget in the client.\nEditres will select that widget in the tree display.
+*xt*label17: No widget Tree is avaliable.
+*xt*label19: This function requires exactly one (1) widget to be selected.
+*xt*label23: There are no currently active widgets.
+*xt*label27: There is no widget tree to display.
+*xt*label29: XSaveContext failed on widget %s.
+
+! InterViews Messages
+
+*iv*label7: Unable to own the Attribute Selection
+*iv*label12: Style Tree for client %s(%s).
+*iv*label14: Click on any style in the client.\nEditres will select that style in the tree display.
+*iv*label17: No style Tree is avaliable.
+*iv*label19: This function requires exactly one (1) style to be selected.
+*iv*label23: There are no currently active styles.
+*iv*label27: There is no style tree to display.
+*iv*label29: XSaveContext failed on style %s.
+
+*MenuButton.leftBitmap: menu10
+
+! For the Top Area
+
+*hPane.orientation: horizontal
+*hPane.preferredPaneSize: 100
+*hPane.Panner.width: 100
+*hPane.Panner.height: 100
+*hPane.Panner.preferredPaneSize: 100
+*Paned.Panner.showGrip: False
+*Paned.box.showGrip: False
+*Paned.hPane.showGrip: True
+
+! For the Filename popup dialog.
+
+*fileDialog*value:
+*fileDialog*allowShellResize: True
+*fileDialog*Text.baseTranslations: #override \n\
+ <Key>Return: PopdownFileDialog(okay)
+
+
+! Universal Resources for the Resource Box.
+
+*resourceLabel.font: \
+-*-new century schoolbook-bold-r-*-*-20-*-*-*-*-*-*-*
+*allowShellResize: True
+*resourceLabel.allowResize: True
+*List.verticalList: True
+*namesAndClasses*BorderWidth: 0
+*star.Label: *
+*dot.Label: .
+*namesLabel.font: \
+-*-new century schoolbook-bold-r-*-*-17-*-*-*-*-*-*-*
+*constraintLabel.font: \
+-*-new century schoolbook-bold-r-*-*-17-*-*-*-*-*-*-*
+*valueLabel.BorderWidth: 0
+*valueForm*preferredPaneSize: 100
+*valueText*editType: edit
+*valueText.Scroll: WhenNeeded
+*valueText.width: 300
+*setFile.Label: Set Save File
+*save.Label: Save
+*apply.Label: Apply
+*saveAndApply.Label: Save and Apply
+*commandBox.show.Label: Show
+
+! InterViews Resources for the Resource Box.
+
+*iv*single.Label: Any Style
+*iv*any.Label: Any Style Chain
+*iv*namesLabel.Label: Normal Attributes: mb2 gets a value
+*iv*constraintLabel.Label: Constraint Attributes
+*iv*valueLabel.Label: Enter Attribute Value:
+*iv*commandBox.cancel.Label: Popdown Attribute Box
+
+! Xt Resources for the Resource Box.
+
+*xt*single.Label: Any Widget
+*xt*any.Label: Any Widget Chain
+*xt*namesLabel.Label: Normal Resources: mb2 gets a value
+*xt*constraintLabel.Label: Constraint Resources
+*xt*valueLabel.Label: Enter Resource Value:
+*xt*commandBox.cancel.Label: Popdown Resource Box
+
+! This gives us an exactly one of many toggle, if toggle is
+! not set in each group the application will probabally core dump.
+
+*namesAndClasses*Toggle.baseTranslations: #override \n\
+ <Btn1Down>,<Btn1Up>: set() notify()
+
+
+*commandBox.skipAdjust: True
+
+! Get resource values action binding.
+
+*List.baseTranslations: #override \n\
+ <Btn2Down>,<Btn2Up>: Set() EnableGetVal() Notify()
+
+! Keyboard Actions for Tree and children of the Tree.
+
+*Tree.baseTranslations: #override \n\
+ :<Key>space: Select(nothing) \n\
+ :<Key>w: Select(widget) \n\
+ :<Key>s: Select(all) \n\
+ :<Key>i: Select(invert) \n\
+ :<Key>c: Select(children) \n\
+ :<Key>d: Select(descendants) \n\
+ :<Key>p: Select(parent) \n\
+ :<Key>a: Select(ancestors) \n\
+ :<Key>N: Relabel(name) \n\
+ :<Key>C: Relabel(class) \n\
+ :<Key>I: Relabel(id) \n\
+ :<Key>W: Relabel(window)
+
+*Tree.Toggle.baseTranslations: #override \n\
+ :<Key>space: Select(nothing) \n\
+ :<Key>w: Select(widget) \n\
+ :<Key>s: Select(all) \n\
+ :<Key>i: Select(invert) \n\
+ :<Key>c: Select(children) \n\
+ :<Key>d: Select(descendants) \n\
+ :<Key>p: Select(parent) \n\
+ :<Key>a: Select(ancestors) \n\
+ :<Key>N: Relabel(name) \n\
+ :<Key>C: Relabel(class) \n\
+ :<Key>I: Relabel(id) \n\
+ :<Key>W: Relabel(window) \n\
+ <Btn2Down>,<Btn2Up>: Select(nothing) toggle() notify() \n\
+ <Btn3Down>,<Btn3Up>: Relabel(toggle)
+
+! For the SetValues popup
+
+*setValuesPopup*resizable: True
+*setValuesPopup*left: ChainLeft
+*setValuesPopup*right: ChainLeft
+
+*setValuesPopup*label*Label: Use <Tab> to Change Fields.
+*setValuesPopup*Label*BorderWidth: 0
+
+*setValuesPopup*resourceLabel.Label: Resource Name:
+*setValuesPopup*valueLabel.Label: Value:
+*SimpleMenu*setValuesPopup*setValues.Label: Apply
+*setValuesPopup*cancel.Label: Cancel
+
+*setValuesPopup*Text*EditType: Edit
+*setValuesPopup*Text*resize: Width
+
+*setValuesPopup*resourceText.baseTranslations: #override \
+ <Key>Return: no-op(RingBell) \n\
+ Ctrl<Key>q,<Key>Tab: insert-char() \n\
+ <Btn1Down>: select-start() SVActiveEntry(Resource) \n\
+ <Key>Tab: SVActiveEntry(Value)
+
+*setValuesPopup*valueText.baseTranslations: #override \
+ <Key>Return: no-op(RingBell) \n\
+ Ctrl<Key>q,<Key>Tab: insert-char() \n\
+ <Btn1Down>: select-start() SVActiveEntry(Value)\n\
+ <Key>Tab: SVActiveEntry(Resource)
diff --git a/actions.c b/actions.c
new file mode 100644
index 0000000..80e8940
--- /dev/null
+++ b/actions.c
@@ -0,0 +1,358 @@
+/*
+ * $Xorg: actions.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/Xutil.h>
+
+#include <X11/Xaw/Cardinals.h>
+
+#include "editresP.h"
+
+/*
+ * External Functions.
+ */
+
+extern void SetMessage(), _TreeSelect(), _TreeSelectNode(), _FindWidget();
+extern void _TreeActivateNode(), _TreeRelabel(), _TreeRelabelNode();
+extern void PrepareToLayoutTree(), LayoutTree(), _PopdownFileDialog();
+
+/*
+ * Private data.
+ */
+
+struct ActionValues {
+ String name;
+ int type;
+};
+
+static struct ActionValues select_values[] = {
+ { "widget", (int) SelectWidget },
+ { "all", (int) SelectAll },
+ { "nothing", (int) SelectNone },
+ { "invert", (int) SelectInvert },
+ { "children", (int) SelectChildren },
+ { "descendants", (int) SelectDescendants },
+ { "parent", (int) SelectParent },
+ { "ancestors", (int) SelectAncestors }
+};
+
+static struct ActionValues label_values[] = {
+ { "name", (int) NameLabel },
+ { "class", (int) ClassLabel },
+ { "id", (int) IDLabel },
+ { "window", (int) WindowLabel },
+ { "toggle", (int) ToggleLabel }
+};
+
+static WNode * FindTreeNodeFromWidget();
+static Boolean CheckAndFindEntry();
+
+/* Function Name: EnableGetVal
+ * Description: sets a global variable to notify the Notify action
+ * for the resource list widet to do GetValues.
+ * Arguments: w - any widget in the widget tree.
+ * event - NOT USED.
+ * params, num_params - the parameters paseed to the action
+ * routine.
+ *
+ */
+
+Boolean do_get_values = False;
+
+/* ARGSUSED */
+static void
+EnableGetVal(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ do_get_values = True;
+}
+
+/* Function Name: SelectAction
+ * Description:
+ * Arguments: w - any widget in the widget tree.
+ * event - NOT USED.
+ * params, num_params - the parameters paseed to the action
+ * routine.
+ *
+ * params[0] - One of "nothing", "parent", "children", "ancestors",
+ * "descendants", "invert", "all"
+ * num_params - must be one.
+ */
+
+/* ARGSUSED */
+static void
+SelectAction(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ WNode * node;
+ int type;
+
+ if (!CheckAndFindEntry("Select", params, *num_params,
+ select_values, XtNumber(select_values), &type))
+ return;
+
+ switch(type) {
+ case SelectAll:
+ case SelectNone:
+ case SelectInvert:
+ _TreeSelect(global_tree_info, type);
+ break;
+ case SelectWidget:
+ _FindWidget(XtParent(w));
+ break;
+ default:
+ node = FindTreeNodeFromWidget(w);
+ if (node)
+ _TreeActivateNode(node, type);
+ else
+ _TreeSelect(global_tree_info, type);
+ break;
+ }
+}
+
+/* Function Name: RelabelAction
+ * Description:
+ * Arguments: w - any widget in the widget tree.
+ * event - NOT USED.
+ * params, num_params - the parameters paseed to the action
+ * routine.
+ *
+ * params[0] - One of "name", "class", "id"
+ * num_params - must be one.
+ */
+
+/* ARGSUSED */
+static void
+RelabelAction(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ WNode * node;
+ int type;
+
+ if (!CheckAndFindEntry("Relabel", params, *num_params,
+ label_values, XtNumber(label_values), &type))
+ return;
+
+ if ((node = FindTreeNodeFromWidget(w)) == NULL)
+ _TreeRelabel(global_tree_info, type);
+ else {
+ PrepareToLayoutTree(global_tree_info->tree_widget);
+ _TreeRelabelNode(node, type, FALSE);
+ LayoutTree(global_tree_info->tree_widget);
+ }
+}
+
+/* Function Name: PopdownFileDialogAction
+ * Description: Pops down the file dialog widget.
+ * and calls the approipriate handler.
+ * Arguments: w - any child of the dialog widget.
+ * event - the event that caused this action.
+ * params, num_params - params passed to the action routine.
+ * RETURNED none.
+ */
+
+/* ARGSUSED */
+
+static void
+PopdownFileDialogAction(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ char buf[BUFSIZ];
+ Boolean val;
+
+ if (*num_params != 1) {
+ sprintf(buf, res_labels[2],
+ "PopdownFileDialog");
+
+ SetMessage(global_screen_data.info_label, buf);
+ return;
+ }
+
+ XmuCopyISOLatin1Lowered(buf, params[0]);
+
+ if (streq(buf, "cancel"))
+ val = FALSE;
+ else if (streq(buf, "okay"))
+ val = TRUE;
+ else {
+ sprintf(buf, res_labels[1],
+ "PopdownFileDialog");
+
+ SetMessage(global_screen_data.info_label, buf);
+ return;
+ }
+
+ _PopdownFileDialog(w, (XtPointer)(long) val, NULL);
+}
+
+/* Function Name: ActionQuit
+ * Description: This function prints a message to stdout.
+ * Arguments: w - ** UNUSED **
+ * call_data - ** UNUSED **
+ * client_data - ** UNUSED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+ActionQuit(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ if (w==global_toplevel) {
+ XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
+ exit(0);
+ }
+ else {
+ if (streq(XtName(w), RESOURCE_BOX))
+ global_resource_box_up = FALSE;
+ XtPopdown(w);
+ XtDestroyWidget(w);
+ }
+}
+
+/* Function Name: SetApplicationActions
+ * Description: Sets my application actions.
+ * Arguments: app_con - the application context.
+ * Returns: none.
+ */
+
+extern void ModifySVEntry();
+
+static XtActionsRec actions[] = {
+ {"EnableGetVal", EnableGetVal},
+ {"Select", SelectAction},
+ {"SVActiveEntry", ModifySVEntry},
+ {"Relabel", RelabelAction},
+ {"PopdownFileDialog", PopdownFileDialogAction},
+ {"quit", ActionQuit}
+};
+
+void
+SetApplicationActions(app_con)
+XtAppContext app_con;
+{
+ XtAppAddActions(app_con, actions, XtNumber(actions));
+
+}
+
+
+/************************************************************
+ *
+ * Private functions
+ *
+ ************************************************************/
+
+/* Function Name: CheckAndFindEntry
+ * Description: Checks the args to make sure they are valid,
+ * then parses the arg list to find the correct action
+ * to take.
+ * Arguments: action_name - name of the action (for error messages).
+ * params, num_params - params passed to the action routine.
+ * table, num_table - table to check the parameters against.
+ * RETURNED type - info about the action to take.
+ * Returns: TRUE if the arguments are okay.
+ */
+
+static Boolean
+CheckAndFindEntry(action_name, params, num_params, table, num_table, type)
+String * params, action_name;
+Cardinal num_params, num_table;
+struct ActionValues * table;
+int * type;
+{
+ char buf[BUFSIZ];
+ int i;
+
+ if (num_params != 1) {
+ sprintf(buf, res_labels[2],
+ action_name);
+ SetMessage(global_screen_data.info_label, buf);
+ return(FALSE);
+ }
+
+ XmuCopyISOLatin1Lowered(buf, params[0]);
+ for ( i = 0 ; i < num_table; i++ )
+ if (streq(buf, table[i].name)) {
+ *type = table[i].type;
+ return(TRUE);
+ }
+
+ sprintf(buf,res_labels[3],
+ action_name);
+
+ for (i = 0; i < num_table; ) {
+ strcat(buf, table[i++].name);
+
+ if (i == (num_table - 1))
+ strcat(buf, ", or ");
+ else if (i < num_table)
+ strcat(buf, ", ");
+ }
+
+ SetMessage(global_screen_data.info_label, buf);
+ return(FALSE);
+}
+
+/* Function Name: FindTreeNodeFromWidget
+ * Description: finds the tree node associated with a widget.
+ * Arguments: w - widget to check.
+ * Returns: the node associated with this widget, or NULL.
+ */
+
+static WNode *
+FindTreeNodeFromWidget(w)
+Widget w;
+{
+ int ret_val;
+ XPointer data_return;
+
+ /*
+ * Yes, I really am casting a widget to a window ** TRUST ME ***
+ */
+
+ ret_val = XFindContext(XtDisplay(w), (Window) w, NODE_INFO, &data_return);
+
+ if (ret_val == 0)
+ return((WNode *) data_return);
+ return(NULL);
+}
+
diff --git a/comm.c b/comm.c
new file mode 100644
index 0000000..3cd1e71
--- /dev/null
+++ b/comm.c
@@ -0,0 +1,962 @@
+/* $Xorg: comm.c,v 1.5 2001/02/09 02:05:29 xorgcvs Exp $ */
+/*
+
+Copyright 1990, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+
+/*
+ * This file contains the code to communicate with the client that is
+ * being edited.
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h> /* Get standard string definitions. */
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h> /* For crosshair cursor. */
+#include <X11/Xproto.h>
+#include <X11/Xos.h> /* for XtNewString */
+
+#include <stdio.h>
+#include <X11/Xmu/Error.h>
+
+#include "editresP.h"
+
+/*
+ * static Globals.
+ */
+
+static Atom atom_comm, atom_command, atom_resource_editor, atom_client_value;
+static Atom atom_editres_protocol;
+
+/*
+ * external function definitions.
+ */
+
+extern void RebuildMenusAndLabel();
+extern ResIdent GetNewIdent();
+extern void SetMessage(), BuildVisualTree(),DisplayChild();
+extern char * GetFormattedSetValuesError(), *HandleFlashWidget();
+extern char * HandleGetResources(), *PrintSetValuesError();
+char * GetFailureMessage(), * ProtocolFailure();
+extern int HandleXErrors();
+extern void SetEntriesSensitive();
+
+static void TellUserAboutMessage(), BuildHeader(), FreeEvent();
+static Event * BuildEvent();
+static char * DispatchEvent();
+static void GetClientValue();
+static void ClientTimedOut(), LoseSelection(), SelectionDone();
+static Boolean ConvertCommand();
+
+
+extern Widget CM_entries[NUM_CM_ENTRIES], TM_entries[NUM_TM_ENTRIES];
+
+
+
+/* Function Name: ClientTimedOut
+ * Description: Called if the client takes too long to take our selection.
+ * Arguments: data - The widget that owns the client
+ * communication selection.
+ * id - *** UNUSED ***
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+ClientTimedOut(data, id)
+XtPointer data;
+XtIntervalId * id;
+{
+ char msg[BUFSIZ];
+ Widget w = (Widget) data;
+
+ global_client.ident = NO_IDENT;
+ XtDisownSelection(w, global_client.atom,
+ XtLastTimestampProcessed(XtDisplay(w)));
+
+ sprintf(msg, res_labels[4],
+ "the Editres Protocol.");
+ SetMessage(global_screen_data.info_label, msg);
+}
+
+
+
+/* Function Name: GetClientWindow
+ * Description: Gets the Client's window by asking the user.
+ * Arguments: w - a widget.
+ * Returns: a clients window, or None.
+ */
+
+Window
+GetClientWindow(w, x, y)
+Widget w;
+int *x, *y;
+{
+ int status;
+ Cursor cursor;
+ XEvent event;
+ int buttons = 0;
+ Display * dpy = XtDisplayOfObject(w);
+ Window target_win = None, root = RootWindowOfScreen(XtScreenOfObject(w));
+ XtAppContext app = XtWidgetToApplicationContext(w);
+
+ /* Make the target cursor */
+ cursor = XCreateFontCursor(dpy, XC_crosshair);
+
+ /* Grab the pointer using target cursor, letting it room all over */
+ status = XGrabPointer(dpy, root, False,
+ ButtonPressMask|ButtonReleaseMask, GrabModeSync,
+ GrabModeAsync, root, cursor, CurrentTime);
+ if (status != GrabSuccess) {
+ SetMessage(global_screen_data.info_label, res_labels[5]);
+ return(None);
+ }
+
+ /* Let the user select a window... */
+ while ((target_win == None) || (buttons != 0)) {
+ /* allow one more event */
+ XAllowEvents(dpy, SyncPointer, CurrentTime);
+ XtAppNextEvent(app, &event);
+ switch (event.type) {
+ case ButtonPress:
+ if (event.xbutton.window != root) {
+ XtDispatchEvent(&event);
+ break;
+ }
+
+ if (target_win == None) {
+ target_win = event.xbutton.subwindow; /* window selected */
+ if (x != NULL)
+ *x = event.xbutton.x_root;
+ if (y != NULL)
+ *y = event.xbutton.y_root;
+ }
+ buttons++;
+ break;
+ case ButtonRelease:
+ if (event.xbutton.window != root) {
+ XtDispatchEvent(&event);
+ break;
+ }
+
+ if (buttons > 0) /* There may have been some
+ down before we started */
+ buttons--;
+ break;
+ default:
+ XtDispatchEvent(&event);
+ break;
+ }
+ }
+
+ XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
+
+ return(XmuClientWindow(dpy, target_win));
+}
+
+
+
+/* Function Name: SetCommand
+ * Description: Causes this widget to own the resource editor's
+ * command selection.
+ * Arguments: w - the widget that will own the selection.
+ * command - command to send to client.
+ * msg - message to prompt the user to select a client.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+SetCommand(w, command, msg)
+ Widget w;
+ ResCommand command;
+ char * msg;
+{
+ XClientMessageEvent client_event;
+ Display * dpy = XtDisplay(w);
+
+ if (msg == NULL)
+ msg = res_labels[6];
+
+ SetMessage(global_screen_data.info_label, msg);
+
+ if (global_client.window == None)
+ if ( (global_client.window = GetClientWindow(w, NULL, NULL)) == None)
+ return;
+
+ global_client.ident = GetNewIdent();
+
+ global_client.command = command;
+ global_client.atom = atom_comm;
+
+ BuildHeader(&(global_client));
+
+ if (!XtOwnSelection(w, global_client.atom, CurrentTime, ConvertCommand,
+ LoseSelection, SelectionDone))
+ SetMessage(global_screen_data.info_label,
+ res_labels[7]);
+
+ client_event.window = global_client.window;
+ client_event.type = ClientMessage;
+ client_event.message_type = atom_resource_editor;
+ client_event.format = EDITRES_SEND_EVENT_FORMAT;
+ client_event.data.l[0] = XtLastTimestampProcessed(dpy);
+ client_event.data.l[1] = global_client.atom;
+ client_event.data.l[2] = (long) global_client.ident;
+ client_event.data.l[3] = global_effective_protocol_version;
+
+ global_error_code = NO_ERROR; /* Reset Error code. */
+ global_old_error_handler = XSetErrorHandler(HandleXErrors);
+ global_serial_num = NextRequest(dpy);
+
+ XSendEvent(dpy, global_client.window, FALSE, (long) 0,
+ (XEvent *) &client_event);
+
+ XSync(dpy, FALSE);
+ XSetErrorHandler(global_old_error_handler);
+ if (global_error_code == NO_WINDOW) {
+ char error_buf[BUFSIZ];
+
+ global_error_code = NO_ERROR; /* Reset Error code. */
+ sprintf(error_buf, "The communication window with%s%s.",
+ " application is no longer available\n",
+ "Please select a new widget tree");
+
+ global_client.window = None;
+ SetCommand(w, LocalSendWidgetTree, error_buf);
+ return;
+ }
+
+ TellUserAboutMessage(global_screen_data.info_label, command);
+ global_client.timeout = XtAppAddTimeOut(XtWidgetToApplicationContext(w),
+ CLIENT_TIME_OUT,
+ ClientTimedOut, (XtPointer) w);
+}
+
+
+
+/* Function Name: TellUserAboutMessage
+ * Description: Informs the user that we have sent a message to the client
+ * Arguments: label - the info label.
+ * command - command that we have executed.
+ * Returns: none.
+ */
+
+static void
+TellUserAboutMessage(label, command)
+Widget label;
+ResCommand command;
+{
+ char msg[BUFSIZ], *str;
+
+ switch(command) {
+ case LocalSendWidgetTree:
+ str = " asking for widget tree";
+ break;
+ case LocalSetValues:
+ str = " asking it to perform SetValues()";
+ break;
+ case LocalFlashWidget:
+ case LocalGetGeometry:
+ str = " asking it to perform GetGeometry()";
+ break;
+ case LocalGetResources:
+ str = " asking it to get a widget's resource list";
+ break;
+ case LocalFindChild:
+ str = " asking it to find the child Widget.";
+ break;
+ default:
+ str = "";
+ break;
+ }
+
+ sprintf(msg, res_labels[8], str);
+ SetMessage(label, msg);
+}
+
+
+
+/* Function Name: ConvertCommand
+ * Description: Converts the command string into a selection that can
+ * be sent to the client.
+ * Arguments: (see Xt)
+ * Returns: TRUE if we could convert the selection and target asked for.
+ */
+
+/* ARGSUSED */
+static Boolean
+ConvertCommand(w,selection,target,type_ret, value_ret, length_ret, format_ret)
+Widget w;
+Atom * selection, * target, * type_ret;
+XtPointer *value_ret;
+unsigned long * length_ret;
+int * format_ret;
+{
+ if ((*selection != atom_comm) || (*target != atom_command))
+ return(FALSE);
+
+ *type_ret = atom_editres_protocol;
+ *value_ret = (XtPointer) global_client.stream.real_top;
+ *length_ret = global_client.stream.size + HEADER_SIZE;
+ *format_ret = EDITRES_FORMAT;
+
+ return(TRUE);
+}
+
+
+
+/* Function Name: SelectionDone
+ * Description: done with the selection.
+ * Arguments: *** UNUSED ***
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+SelectionDone(w, sel, targ)
+ Widget w;
+ Atom *sel, *targ;
+{
+ /* Keep the toolkit from automaticaly freeing the selection value */
+}
+
+
+
+/* Function Name: LoseSelection
+ * Description: Called when we have lost the selection, asks client
+ * for the selection value.
+ * Arguments: w - the widget that just lost the selection.
+ * sel - the selection.
+ * Returns: none.
+ */
+
+static void
+LoseSelection(w, sel)
+Widget w;
+Atom * sel;
+{
+ if (global_client.timeout != 0) {
+ XtRemoveTimeOut(global_client.timeout);
+ global_client.timeout = 0;
+ }
+
+ XtGetSelectionValue(w, *sel, atom_client_value, GetClientValue,
+ NULL, XtLastTimestampProcessed(XtDisplay(w)));
+}
+
+
+
+/* Function Name: GetClientValue
+ * Description: Gets the value out of the client, and does good things
+ * to it.
+ * Arguments: w - the widget that asked for the selection.
+ * data - client_data *** UNUSED ***.
+ * sel - the selection.
+ * type - the type of the selection.
+ * value - the selection's value.
+ * length - the length of the selection's value.
+ * format - the format of the selection.
+ * Returns: none.
+ */
+
+static Boolean reset_protocol_level = True;
+
+/* ARGSUSED */
+static void
+GetClientValue(w, data, selection, type, value, length, format)
+Widget w;
+XtPointer data, value;
+Atom *selection, *type;
+unsigned long *length;
+int * format;
+{
+ Event * event;
+ ProtocolStream alloc_stream, *stream;
+ unsigned char ident, error_code;
+ char * error_str = NULL, msg[BUFSIZ];
+
+ if (*length == 0)
+ return;
+
+ stream = &alloc_stream; /* easier to think of it this way... */
+
+ stream->current = stream->top = (unsigned char *) value;
+ stream->size = HEADER_SIZE; /* size of header. */
+
+ /*
+ * Retrieve the Header.
+ */
+
+ if (*length < HEADER_SIZE) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[9]);
+ return;
+ }
+
+ (void) _XEditResGet8(stream, &ident);
+ if (global_client.ident != ident) {
+#ifdef DEBUG
+ if (global_resources.debug)
+ printf("Incorrect ident from client.\n");
+#endif
+ if (!XtOwnSelection(w, *selection, CurrentTime, ConvertCommand,
+ LoseSelection, SelectionDone))
+ SetMessage(global_screen_data.info_label,
+ res_labels[10]);
+ return;
+ }
+
+ (void) _XEditResGet8(stream, &error_code);
+ (void) _XEditResGet32(stream, &(stream->size));
+ stream->top = stream->current; /* reset stream to top of value.*/
+
+ switch ((int) error_code) {
+ case PartialSuccess:
+/*****
+ if (global_client.command == LocalSendWidgetTree &&
+ global_effective_protocol_version < CURRENT_PROTOCOL_VERSION)
+ ++global_effective_protocol_version;
+*****/
+ if ((event = BuildEvent(stream)) != NULL) {
+ error_str = DispatchEvent(event);
+ FreeEvent(event);
+ }
+ else {
+ sprintf(msg, "Unable to unpack protocol request.");
+ error_str = XtNewString(msg);
+ }
+ break;
+ case Failure:
+ error_str = GetFailureMessage(stream);
+ break;
+ case ProtocolMismatch:
+ error_str = ProtocolFailure(stream);
+ --global_effective_protocol_version;
+ /* normaly protocol version is reset to current during a SendWidgetTree
+ * request, however, after a protocol failure this is skiped once for
+ * a retry.
+ */
+ reset_protocol_level = False;
+ SetCommand(w, LocalSendWidgetTree, NULL);
+ break;
+ default:
+ sprintf(msg, res_labels[11], (int) error_code);
+ SetMessage(global_screen_data.info_label, msg);
+ break;
+ }
+
+ if (error_str == NULL) {
+ WNode * top;
+
+ if (global_tree_info == NULL)
+ return;
+
+ top = global_tree_info->top_node;
+ sprintf(msg, res_labels[12], top->name, top->class);
+ SetMessage(global_screen_data.info_label, msg);
+ return;
+ }
+ SetMessage(global_screen_data.info_label, error_str);
+ XtFree(error_str);
+}
+
+
+
+/* Function Name: BuildHeader
+ * Description: Puts the header into the message.
+ * Arguments: client_data - the client data.
+ * Returns: none.
+ */
+
+static void
+BuildHeader(client_data)
+CurrentClient * client_data;
+{
+ unsigned long old_alloc, old_size;
+ unsigned char * old_current;
+ EditresCommand command;
+ ProtocolStream * stream = &(client_data->stream);
+
+ /*
+ * We have cleverly keep enough space at the top of the header
+ * for the return protocol stream, so all we have to do is
+ * fill in the space.
+ */
+
+ /*
+ * Fool the insert routines into putting the header in the right
+ * place while being damn sure not to realloc (that would be very bad.
+ */
+
+ old_current = stream->current;
+ old_alloc = stream->alloc;
+ old_size = stream->size;
+
+ stream->current = stream->real_top;
+ stream->alloc = stream->size + (2 * HEADER_SIZE);
+
+ _XEditResPut8(stream, client_data->ident);
+ switch(client_data->command) {
+ case LocalSendWidgetTree:
+ if (reset_protocol_level) global_effective_protocol_version =
+ CURRENT_PROTOCOL_VERSION;
+ reset_protocol_level = True;
+ command = SendWidgetTree;
+ break;
+ case LocalSetValues:
+ command = SetValues;
+ break;
+ case LocalFlashWidget:
+ command = GetGeometry;
+ break;
+ case LocalGetResources:
+ command = GetResources;
+ break;
+ case LocalFindChild:
+ command = FindChild;
+ break;
+ case LocalGetValues:
+ command = GetValues;
+ break;
+ default:
+ command = SendWidgetTree;
+ break;
+ }
+
+ _XEditResPut8(stream, (unsigned char) command);
+ _XEditResPut32(stream, old_size);
+
+ stream->alloc = old_alloc;
+ stream->current = old_current;
+ stream->size = old_size;
+}
+
+
+
+/* Function Name: BuildEvent
+ * Description: Builds the event structure from the
+ * Arguments: stream - the protocol data stream.
+ * Returns: event - the event.
+ */
+
+static Event *
+BuildEvent(stream)
+ProtocolStream * stream;
+{
+ int i;
+ Event * event = (Event *) XtCalloc(sizeof(Event), 1);
+
+ /*
+ * The return value will be different depending upon the
+ * request sent out.
+ */
+
+ switch(global_client.command) {
+ case LocalSendWidgetTree:
+ {
+ SendWidgetTreeEvent * send_event = (SendWidgetTreeEvent *) event;
+
+ send_event->type = SendWidgetTree;
+
+ if (!_XEditResGet16(stream, &(send_event->num_entries)))
+ goto done;
+
+ send_event->info = (WidgetTreeInfo *)
+ XtCalloc(sizeof(WidgetTreeInfo),
+ send_event->num_entries);
+
+ for (i = 0; i < (int)send_event->num_entries; i++) {
+ WidgetTreeInfo * info = send_event->info + i;
+ if (!(_XEditResGetWidgetInfo(stream, &(info->widgets)) &&
+ _XEditResGetString8(stream, &(info->name)) &&
+ _XEditResGetString8(stream, &(info->class)) &&
+ _XEditResGet32(stream, &(info->window))))
+ {
+ goto done;
+ }
+ }
+
+ if (global_effective_protocol_version ==
+ CURRENT_PROTOCOL_VERSION) {
+ /* get toolkit type and reset if necessary */
+ if (!_XEditResGetString8(stream, &(send_event->toolkit)))
+ goto done;
+ }
+ /* set the command menu entries senitive */
+ SetEntriesSensitive(&CM_entries[CM_OFFSET], CM_NUM, True);
+ /* set the tree menu entries senitive */
+ SetEntriesSensitive(TM_entries, TM_NUM, True);
+ if (global_effective_protocol_version ==
+ CURRENT_PROTOCOL_VERSION) {
+ if (!strcmp(send_event->toolkit, "InterViews"))
+ RebuildMenusAndLabel("iv");
+ }
+ else
+ RebuildMenusAndLabel("xt");
+ }
+ break;
+ case LocalSetValues:
+ {
+ SetValuesEvent * sv_event = (SetValuesEvent *) event;
+
+ sv_event->type = SetValues;
+
+ if (!_XEditResGet16(stream, &(sv_event->num_entries)))
+ goto done;
+
+ sv_event->info = (SetValuesInfo *) XtCalloc(sizeof(SetValuesInfo),
+ sv_event->num_entries);
+
+ for (i = 0; i < (int)sv_event->num_entries; i++) {
+ SetValuesInfo * info = sv_event->info + i;
+ if (!(_XEditResGetWidgetInfo(stream, &(info->widgets)) &&
+ _XEditResGetString8(stream, &(info->message))))
+ {
+ goto done;
+ }
+ }
+ }
+ break;
+ case LocalGetResources:
+ {
+ GetResourcesEvent * res_event = (GetResourcesEvent *) event;
+
+ res_event->type = GetGeometry;
+
+ if (!_XEditResGet16(stream, &(res_event->num_entries)))
+ goto done;
+
+ res_event->info = (GetResourcesInfo *)
+ XtCalloc(sizeof(GetResourcesInfo),
+ res_event->num_entries);
+
+ for (i = 0; i < (int)res_event->num_entries; i++) {
+ GetResourcesInfo * res_info = res_event->info + i;
+ if (!(_XEditResGetWidgetInfo(stream, &(res_info->widgets)) &&
+ _XEditResGetBoolean(stream, &(res_info->error))))
+ {
+ goto done;
+ }
+ if (res_info->error) {
+ if (!_XEditResGetString8(stream, &(res_info->message)))
+ goto done;
+ }
+ else {
+ unsigned int j;
+
+ if (!_XEditResGet16(stream, &(res_info->num_resources)))
+ goto done;
+
+ res_info->res_info = (ResourceInfo *)
+ XtCalloc(sizeof(ResourceInfo),
+ res_info->num_resources);
+
+ for (j = 0; j < res_info->num_resources; j++) {
+ unsigned char temp;
+ ResourceInfo * info = res_info->res_info + j;
+ if (!(_XEditResGetResType(stream, &(temp)) &&
+ _XEditResGetString8(stream, &(info->name)) &&
+ _XEditResGetString8(stream, &(info->class)) &&
+ _XEditResGetString8(stream, &(info->type))))
+ {
+ goto done;
+ }
+ else
+ info->res_type = (ResourceType) temp;
+ } /* for */
+ } /* else */
+ } /* for */
+ }
+ break;
+ case LocalFlashWidget:
+ case LocalGetGeometry:
+ {
+ GetGeomEvent * geom_event = (GetGeomEvent *) event;
+
+ geom_event->type = GetGeometry;
+
+ if (!_XEditResGet16(stream, &(geom_event->num_entries)))
+ goto done;
+
+ geom_event->info = (GetGeomInfo *) XtCalloc(sizeof(GetGeomInfo),
+ geom_event->num_entries);
+
+ for (i = 0; i < (int)geom_event->num_entries; i++) {
+ GetGeomInfo * info = geom_event->info + i;
+ if (!(_XEditResGetWidgetInfo(stream, &(info->widgets)) &&
+ _XEditResGetBoolean(stream, &(info->error))))
+ {
+ goto done;
+ }
+ if (info->error) {
+ if (!_XEditResGetString8(stream, &(info->message)))
+ goto done;
+ }
+ else {
+ if (!(_XEditResGetBoolean(stream, &(info->visable)) &&
+ _XEditResGetSigned16(stream, &(info->x)) &&
+ _XEditResGetSigned16(stream, &(info->y)) &&
+ _XEditResGet16(stream, &(info->width)) &&
+ _XEditResGet16(stream, &(info->height)) &&
+ _XEditResGet16(stream, &(info->border_width))))
+ {
+ goto done;
+ }
+ }
+ }
+ }
+ break;
+ case LocalFindChild:
+ {
+ FindChildEvent * find_event = (FindChildEvent *) event;
+
+ find_event->type = FindChild;
+
+ if (!_XEditResGetWidgetInfo(stream, &(find_event->widgets)))
+ goto done;
+ }
+ break;
+ case LocalGetValues: /* This is for REPLY... */
+ {
+ Arg args[1];
+ GetValuesEvent * gv_event = (GetValuesEvent *) event;
+
+ gv_event->type = GetValues;
+
+ if (!_XEditResGet16(stream, &(gv_event->num_entries)))
+ goto done;
+
+ gv_event->info = (GetValuesInfo*)XtCalloc(sizeof(GetValuesInfo),1);
+
+ {
+ GetValuesInfo * info = gv_event->info;
+ if (!(_XEditResGetString8(stream, &(info->value))))
+ {
+ goto done;
+ }
+
+ /* set the string value of the asciitext widget. note that only
+ * one active node is dealt with here. This is ok because only
+ * one node can be active when the resource box is up.
+ */
+
+ XtSetArg (args[0], XtNstring, info->value);
+
+ XtSetValues(
+ global_tree_info->active_nodes[0]->resources->res_box->value_wid,
+ args, 1
+ );
+ }
+ }
+ break;
+
+ default:
+ goto done;
+ }
+
+ return(event);
+
+ done:
+ FreeEvent(event);
+ return(NULL);
+}
+
+
+
+/* Function Name: FreeEvent
+ * Description: Frees all memory associated with the event.
+ * Arguments: event - the event.
+ * Returns: none.
+ *
+ * NOTE: XtFree() returns w/o freeing if ptr is NULL.
+ */
+
+static void
+FreeEvent(event)
+Event * event;
+{
+ unsigned int i;
+
+ switch(event->any_event.type) {
+ case SendWidgetTree:
+ {
+ SendWidgetTreeEvent * send_event = (SendWidgetTreeEvent *) event;
+ WidgetTreeInfo * info = send_event->info;
+
+ if (info != NULL) {
+ for (i = 0; i < send_event->num_entries; i++, info++) {
+ XtFree((char *)info->widgets.ids);
+ XtFree(info->name);
+ XtFree(info->class);
+ }
+ XtFree((char *)send_event->info);
+ }
+ }
+ break;
+ case SetValues:
+ {
+ SetValuesEvent * sv_event = (SetValuesEvent *) event;
+ SetValuesInfo * info = sv_event->info;
+
+ if (info != NULL) {
+ for (i = 0; i < sv_event->num_entries; i++, info++) {
+ XtFree((char *)info->widgets.ids);
+ XtFree(info->message);
+ }
+ XtFree((char *)sv_event->info);
+ }
+ }
+ break;
+ case GetResources:
+ {
+ GetResourcesEvent * get_event = (GetResourcesEvent *) event;
+ GetResourcesInfo * info = get_event->info;
+
+ if (info != NULL) {
+ for (i = 0; i < get_event->num_entries; i++, info++) {
+ XtFree((char *)info->widgets.ids);
+ if (info->error)
+ XtFree(info->message);
+ else {
+ unsigned int j;
+ ResourceInfo * res_info = info->res_info;
+
+ if (res_info != NULL) {
+ for (j = 0;
+ j < info->num_resources; j++, res_info++)
+ {
+ XtFree(res_info->name);
+ XtFree(res_info->class);
+ XtFree(res_info->type);
+ }
+ XtFree((char *)info->res_info);
+ }
+ }
+ }
+ XtFree((char *)get_event->info);
+ }
+ }
+ break;
+ case GetGeometry:
+ {
+ GetGeomEvent * geom_event = (GetGeomEvent *) event;
+ GetGeomInfo * info = geom_event->info;
+
+ if (info != NULL) {
+ for (i = 0; i < geom_event->num_entries; i++, info++) {
+ XtFree((char *)info->widgets.ids);
+ if (info->error)
+ XtFree(info->message);
+ }
+ XtFree((char *)geom_event->info);
+ }
+ }
+ break;
+ case FindChild:
+ {
+ FindChildEvent * find_event = (FindChildEvent *) event;
+
+ XtFree((char *)find_event->widgets.ids);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+
+/* Function Name: DispatchEvent
+ * Description: Handles the event, calling the proper function.
+ * Arguments: event - the event.
+ * Returns: one.
+ */
+
+static char *
+DispatchEvent(event)
+Event * event;
+{
+ char * error = NULL;
+
+ switch(global_client.command) {
+ case LocalSendWidgetTree:
+ BuildVisualTree(global_tree_parent, event);
+ break;
+ case LocalSetValues:
+ error = PrintSetValuesError(event);
+ break;
+ case LocalFlashWidget:
+ error = HandleFlashWidget(event);
+ break;
+ case LocalGetResources:
+ error = HandleGetResources(event);
+ break;
+ case LocalFindChild:
+ DisplayChild(event);
+ break;
+ case LocalGetValues:
+ break;
+ default:
+ {
+ char msg[BUFSIZ];
+ sprintf(msg, "Internal error: Unknown command %d.",
+ global_client.command);
+ error = XtNewString(msg);
+ }
+ break;
+ }
+ return(error);
+}
+
+
+
+/* Function Name: InternAtoms
+ * Description: interns all static atoms.
+ * Arguments: display - the current display.
+ * Returns: none.
+ */
+
+void
+InternAtoms(dpy)
+Display * dpy;
+{
+ atom_comm = XInternAtom(dpy, EDITRES_COMM_ATOM, False);
+ atom_command = XInternAtom(dpy, EDITRES_COMMAND_ATOM, False);
+ atom_resource_editor = XInternAtom(dpy, EDITRES_NAME, False);
+ atom_client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
+ atom_editres_protocol = XInternAtom(dpy, EDITRES_PROTOCOL_ATOM, False);
+}
+
+ResIdent
+GetNewIdent()
+{
+ static ResIdent ident = 1;
+
+ return(ident++);
+}
+
diff --git a/editres.c b/editres.c
new file mode 100644
index 0000000..93fad17
--- /dev/null
+++ b/editres.c
@@ -0,0 +1,153 @@
+/*
+ * $Xorg: editres.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw/Cardinals.h>
+
+#define THIS_IS_MAIN /* Don't get extern definitions of global
+ variables. */
+
+#include "editresP.h"
+
+/*
+ * Global variables.
+ */
+
+/* array of toolkit dependent labels taken from the resource file */
+String res_labels[NUM_RES_LABELS];
+
+/* decremented if the target client does not speak the current version */
+int global_effective_protocol_version = CURRENT_PROTOCOL_VERSION;
+
+/* toolkit type of client whose "resources" we are currently editing */
+char *global_effective_toolkit = "xt";
+
+int global_error_code;
+unsigned long global_serial_num;
+int (*global_old_error_handler)();
+
+Boolean global_resource_box_up = FALSE;
+TreeInfo *global_tree_info = NULL;
+CurrentClient global_client;
+ScreenData global_screen_data;
+Widget global_tree_parent;
+Widget global_paned = NULL; /* named after toolkit */
+Widget global_toplevel;
+AppResources global_resources;
+
+/*
+ * external function definitions.
+ */
+
+extern void InternAtoms(), SetMessage(), BuildWidgetTree();
+extern void SetApplicationActions();
+
+static void Syntax();
+
+String fallback_resources[] = {
+ NULL,
+};
+
+#define Offset(field) (XtOffsetOf(AppResources, field))
+
+static XtResource editres_resources[] = {
+ {"debug", "Debug", XtRBoolean, sizeof(Boolean),
+ Offset(debug), XtRImmediate, (XtPointer) FALSE},
+ {"numFlashes", "NumFlashes", XtRInt, sizeof(int),
+ Offset(num_flashes), XtRImmediate, (XtPointer) NUM_FLASHES},
+ {"flashTime", "FlashTime", XtRInt, sizeof(int),
+ Offset(flash_time), XtRImmediate, (XtPointer) FLASH_TIME},
+ {"flashColor", XtCForeground, XtRPixel, sizeof(Pixel),
+ Offset(flash_color), XtRImmediate, (XtPointer) XtDefaultForeground},
+ {"saveResourceFile", "SaveResourcesFile", XtRString, sizeof(String),
+ Offset(save_resources_file), XtRString, (XtPointer) ""},
+};
+
+Atom wm_delete_window;
+
+void
+main(argc, argv)
+int argc;
+char **argv;
+{
+ XtAppContext app_con;
+
+ global_toplevel = XtAppInitialize(&app_con, "Editres", NULL, ZERO,
+ &argc, argv, fallback_resources,
+ NULL, ZERO);
+
+ if (argc != 1)
+ Syntax(app_con, argv[0]);
+
+ SetApplicationActions(app_con);
+ XtGetApplicationResources(global_toplevel, (XtPointer) &global_resources,
+ editres_resources, XtNumber(editres_resources),
+ NULL, (Cardinal) 0);
+ global_resources.allocated_save_resources_file = FALSE;
+
+ XtOverrideTranslations
+ (global_toplevel,
+ XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
+
+ /* build tree for Xt intrinsics */
+ BuildWidgetTree(global_toplevel);
+
+ SetMessage(global_screen_data.info_label,
+ res_labels[13]);
+
+ global_screen_data.set_values_popup = NULL;
+
+ InternAtoms(XtDisplay(global_toplevel));
+
+ XtRealizeWidget(global_toplevel);
+
+ wm_delete_window =
+ XInternAtom(XtDisplay(global_toplevel), "WM_DELETE_WINDOW",
+ False);
+ (void) XSetWMProtocols (XtDisplay(global_toplevel),
+ XtWindow(global_toplevel),
+ &wm_delete_window, 1);
+ XtAppMainLoop(app_con);
+}
+
+/* Function Name: Syntax
+ * Description: Prints a the calling syntax for this function to stdout.
+ * Arguments: app_con - the application context.
+ * call - the name of the application.
+ * Returns: none - exits tho.
+ */
+
+static void
+Syntax(app_con, call)
+XtAppContext app_con;
+char *call;
+{
+ XtDestroyApplicationContext(app_con);
+ fprintf(stderr, "Usage: %s\n", call);
+ exit(1);
+}
diff --git a/editres.man b/editres.man
new file mode 100644
index 0000000..3261876
--- /dev/null
+++ b/editres.man
@@ -0,0 +1,433 @@
+.\" $Xorg: editres.man,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
+.\" Copyright 1993, 1994, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH EDITRES 1 "Release 6.4" "X Version 11"
+.SH NAME
+editres \- a dynamic resource editor for X Toolkit applications
+.SH SYNTAX
+\fBeditres\fP [ \fI\-toolkitoption\fP .\|.\|. ]
+.SH OPTIONS
+.I Editres
+accepts all of the standard X Toolkit command line
+options (see \fIX(1)\fP). The order of the command line options is
+not important.
+.SH DESCRIPTION
+Editres is a tool that allows users and application developers to view
+the full widget hierarchy of any X Toolkit application that speaks the
+Editres protocol. In addition, editres will help the user construct
+resource specifications, allow the user to apply the resource to
+the application and view the results dynamically. Once the user is
+happy with a resource specification editres will append the resource
+string to the user's X Resources file.
+.SH USING EDITRES
+.I Editres
+provides a window consisting of the following four areas:
+.IP "Menu Bar" 25
+A set of popup menus that allow you full access to editres's features.
+.IP "Panner"
+The panner allows a more intuitive way to scroll the application tree display.
+.IP "Message Area"
+Displays information to the user about the action that editres expects
+of her.
+.IP "Application Widget Tree" 25
+This area will be used to display the selected application's widget tree.
+.LP
+To begin an editres session select the \fBGet Widget Tree\fP menu item from
+the command menu. This will change the pointer cursor to cross hair.
+You should now select the application you wish look at by clicking on
+any of its windows. If this application understands the editres
+protocol then editres will display the application's widget tree in its
+tree window. If
+the application does not understand the editres protocol editres will
+inform you of this fact in the message area after a few seconds delay.
+.LP
+Once you have a widget tree you may now select any of the other menu
+options. The effect of each of these is described below.
+.SH COMMANDS
+.IP "Get Widget Tree" 8
+Allows the user to click on any application that speaks the editres
+protocol and receive its widget tree.
+.IP "Refresh Current Widget Tree"
+Editres only knows about the widgets that exist at the present time.
+Many applications create and destroy widgets on the fly. Selecting
+this menu item will cause editres to ask the application to resend its
+widget tree, thus updating its information to the new state of the application.
+.IP
+For example,
+xman only creates the widgets for its \fItopbox\fP when it
+starts up. None of the widgets for the manual page window are created
+until the user actually clicks on the \fIManual Page\fP button. If
+you retrieved
+xman's widget tree before the the manual page is active, you may
+wish to refresh the widget tree after the manual page has been
+displayed. This will allow you to also edit the manual page's resources.
+.IP "Dump Widget Tree to a File"
+For documenting applications it is often useful to be able to
+dump the entire application widget tree to an ASCII file. This file
+can then be included in the manual page. When this menu item is selected
+a popup dialog is activated. Type the name of the file in this
+dialog, and either select \fIokay\fP, or type a carriage-return. Editres
+will now dump the widget tree to this file. To cancel the file dialog,
+select the \fIcancel\fP button.
+.IP "Show Resource Box"
+This command will popup a resource box for the current application. This
+resource box (described in detail below) will allow the user to see
+exactly which resources can be set for the widget that is currently
+selected in the widget tree display. Only one widget may be currently
+selected; if greater or fewer are selected editres will refuse to
+pop up the resource box and put an error message in the \fBMessage Area\fP.
+.IP "Set Resource"
+This command will popup a simple dialog box for setting an arbitrary
+resource on all selected widgets. You must type in the resource name,
+as well as the value. You can use the Tab key to switch between the
+resource name field the resource value field.
+.IP "Quit"
+Exits editres.
+.SH TREE COMMANDS
+The \fBTree\fP menu contains several commands that allow operations to
+be performed on the widget tree.
+.IP "Select Widget in Client"
+This menu item allows you to select any widget in the application; editres
+will then highlight the corresponding element the widget tree display.
+Once
+this menu item is selected the pointer cursor will again turn to a
+crosshair, and you must click any pointer button in the widget you
+wish to have displayed. Since some widgets are fully obscured by
+their children, it is not possible to get to every widget this way,
+but this mechanism does give very useful feedback between the elements
+in the widget tree and those in the actual application.
+.IP "Select All"
+.br
+.ns
+.IP "Unselect All"
+.br
+.ns
+.IP "Invert All"
+These functions allow the user to select, unselect, or invert all
+widgets in the widget tree.
+.IP "Select Children"
+.br
+.ns
+.IP "Select Parents"
+These functions select the immediate parent or children of each of the
+currently selected widgets.
+.IP "Select Descendants"
+.br
+.ns
+.IP "Select Ancestors"
+These functions select all parents or children of each of the
+currently selected widgets. This is a recursive search.
+.IP "Show Widget Names"
+.br
+.ns
+.IP "Show Class Names"
+.br
+.ns .IP "Show Widget IDs"
+.br
+.ns
+.IP "Show Widget Windows"
+When the tree widget is initially displayed the labels of each widget
+in the tree correspond to the widget names. These functions will
+cause the label of \fBall\fP widgets in the tree to be changed to show the
+class name, IDs, or window associated with each widget in the application.
+The widget IDs, and windows are shown as hex numbers.
+.LP
+In addition there are keyboard accelerators for each of the
+Tree operations. If the input focus is over an individual widget in
+the tree, then that operation will only effect that widget. If the
+input focus is in the Tree background it will have
+exactly the same effect as the corresponding menu item.
+.LP
+The translation
+entries shown may be applied to any widget in the application. If
+that widget is a child of the Tree widget, then it will only affect that
+widget, otherwise it will have the same effect as the commands in the
+tree menu.
+.IP "Flash Active Widgets"
+This command is the inverse of the \fBSelect Widget in Client\fP
+command, it will show the user each widget that is currently selected in
+the widget tree, by flashing the corresponding widget in the
+application \fInumFlashes\fP (three by default) times in the
+\fIflashColor\fP.
+.sp
+.nf
+.TA .5i 1.5i 4.0i
+.ta .5i 1.5i 4.0i
+ \fBKey Option Translation Entry\fP
+
+ space Unselect Select(nothing)
+ w Select Select(widget)
+ s Select Select(all)
+ i Invert Select(invert)
+ c Select Children Select(children)
+ d Select Descendants Select(descendants)
+ p Select Parent Select(parent)
+ a Select Ancestors Select(ancestors)
+ N Show Widget Names Relabel(name)
+ C Show Class Names Relabel(class)
+ I Show Widget IDs Relabel(id)
+ W Show Widget Windows Relabel(window)
+ T Toggle Widget/Class Name Relabel(toggle)
+.fi
+.sp
+Clicking button 1 on a widget adds it to the set of selected widgets.
+Clicking button 2 on a widget deselects all other widgets and then
+selects just that widget.
+Clicking button 3 on a widget toggles its label between the widget's
+instance name the widget's class name.
+.sp
+.SH USING THE RESOURCE BOX
+The resource box contains five different areas. Each of the areas,
+as they appear on the screen, from top to bottom will be discussed.
+.IP "The Resource Line"
+This area at the top of the resource box shows the current resource
+name exactly as it would appear if you were to save it to a file or
+apply it.
+.IP "The Widget Names and Classes"
+This area allows you to select exactly which widgets this resource will
+apply to. The area contains four lines, the first contains the
+name of the selected widget and all its ancestors, and the more restrictive
+dot (\fB.\fP) separator. The second line contains less specific the
+Class names
+of each widget, and well as the less restrictive star (\fB*\fP) separator.
+The third line contains a set of special buttons called \fBAny Widget\fP
+which will generalize this level to match any widget.
+The last line contains a set of special buttons called \fBAny
+Widget Chain\fP which will turn the single level into something that
+matches zero or more levels.
+.IP ""
+The initial state of this area is the most restrictive, using the
+resource names and the dot separator. By selecting the other buttons
+in this area you can ease the restrictions to allow more and more widgets
+to match the specification. The extreme case is to select all the
+\fBAny Widget Chain\fP buttons, which will match every widget in the
+application. As you select different buttons the tree display will update
+to show you exactly which widgets will be effected by the current
+resource specification.
+.IP "Normal and Constraint Resources"
+The next area allows you to select the name of the normal or
+constraint resources you wish to set. Some widgets may not have constraint
+resources, so that area will not appear.
+.IP "Resource Value"
+This next area allows you to enter the resource value. This value
+should be entered exactly as you would type a line into your resource file.
+Thus it should contain no unescaped new-lines. There are a few
+special character sequences for this file:
+.IP ""
+\\n - This will be replaced with a newline.
+.br
+.sp
+\\### - Where # is any octal digit. This will be replaced with a
+single byte that contains this sequence interpreted as an octal number.
+For example, a value containing a NULL byte can be stored by
+specifying \\000.
+.br
+.sp
+\\<new-line> - This will compress to nothing.
+.br
+.sp
+\\\\ - This will compress to a single backslash.
+.IP "Command Area"
+This area contains several command buttons, described in
+this section.
+.IP "Set Save File"
+This button allows the user to modify file that the resources
+will be saved to. This button will bring up a dialog box that will
+ask you for a filename; once the filename has been entered, either hit
+carriage-return or click on the \fIokay\fP button. To pop down the
+dialog box without changing the save file, click the \fIcancel\fP button.
+.IP "Save"
+This button will append the \fBresource line\fP described above to the
+end of the current save file. If no save file has been set the \fBSet
+Save File\fP dialog box will be popped up to prompt the user for a filename.
+.IP "Apply"
+This button attempts to perform a XtSetValues call on all widgets
+that match the \fBresource line\fP described above. The value specified
+is applied directly to all matching widgets. This behavior is an attempt
+to give a dynamic feel to the resource editor. Since this feature allows
+users to put an application in states it may not be willing to handle,
+a hook has been provided to allow specific applications to
+block these SetValues
+requests (see \fBBlocking Editres Requests\fP below).
+.IP ""
+Unfortunately due to design constraints imposed on the widgets by the X
+Toolkit and the Resource Manager, trying to coerce an inherently
+static system into dynamic behavior can cause strange results. There
+is no guarantee that the results of an apply will be the same as what
+will happen when you save the value and restart the application.
+This functionality is provided to try to give you a rough feel for what
+your changes will accomplish, and the results obtained should be considered
+suspect at best. Having said that, this is one of the neatest
+features of editres, and I strongly suggest that you play with it, and
+see what it can do.
+.IP "Save and Apply"
+This button combines the Save and Apply actions described above into
+one button.
+.IP "Popdown Resource Box"
+This button will remove the resource box from the display.
+.SH BLOCKING EDITRES REQUESTS
+The editres protocol has been built into the Athena Widget set. This allows
+all applications that are linked against Xaw to be able to speak to the
+resource editor. While this provides great flexibility, and is a
+useful tool, it can quite easily be abused. It is therefore possible
+for any Xaw application to specify a value for the \fBeditresBlock\fP
+resource described below, to keep editres from divulging information
+about its internals, or to disable the \fBSetValues\fP part of the protocol.
+.TP 8
+.B editresBlock (\fPClass\fB EditresBlock)
+Specifies which type of blocking this application wishes to impose on the
+editres protocol.
+.LP
+The accepted values are:
+.IP all 15
+Block all requests.
+.IP setValues
+Block all SetValues requests. As this is the only editres request that
+actually modifies the application, this is in effect stating that the
+application is read-only.
+.IP none
+Allow all editres requests.
+.LP
+Remember that these resources are set on any Xaw application, \fBnot
+editres\fP. They allow individual applications to keep all or some
+of the requests editres makes from ever succeeding. Of course,
+editres is also an Xaw application, so it may also be viewed and modified
+by editres (rather recursive, I know), these commands can be blocked
+by setting the \fBeditresBlock\fP resource on editres itself.
+.SH RESOURCES
+For \fIeditres\fP the available application resources are:
+.TP 8
+.B numFlashes (\fPClass\fB NumFlashes)
+Specifies the number of times the widgets in the application
+will be flashed when the \fBShow Active Widgets\fP command in invoked.
+.TP 8
+.B flashTime (\fPClass\fB FlashTime)
+Amount of time between the flashes described above.
+.TP 8
+.B flashColor (\fPClass\fB flashColor)
+Specifies the color used to flash application widgets. A bright color
+should be used that will immediately draw your attention to the area being
+flashed, such as red or yellow.
+.TP 8
+.B saveResourcesFile (\fPClass\fB SaveResourcesFile)
+This is the file the resource line will be append to when the \fBSave\fP
+button activated in the resource box.
+.SH WIDGETS
+In order to specify resources, it is useful to know the hierarchy of
+the widgets which compose \fIeditres\fP. In the notation below,
+indentation indicates hierarchical structure. The widget class name
+is given first, followed by the widget instance name.
+.sp
+.nf
+.TA .5i 1.0i 1.5i 2.0i
+.ta .5i 1.0i 1.5i 2.0i
+Editres editres
+ Paned paned
+ Box box
+ MenuButton commands
+ SimpleMenu menu
+ SmeBSB sendTree
+ SmeBSB refreshTree
+ SmeBSB dumpTreeToFile
+ SmeLine line
+ SmeBSB getResourceList
+ SmeLine line
+ SmeBSB quit
+ MenuButton treeCommands
+ SimpleMenu menu
+ SmeBSB showClientWidget
+ SmeBSB selectAll
+ SmeBSB unselectAll
+ SmeBSB invertAll
+ SmeLine line
+ SmeBSB selectChildren
+ SmeBSB selectParent
+ SmeBSB selectDescendants
+ SmeBSB selectAncestors
+ SmeLine line
+ SmeBSB showWidgetNames
+ SmeBSB showClassNames
+ SmeBSB showWidgetIDs
+ SmeBSB showWidgetWindows
+ SmeLine line
+ SmeBSB flashActiveWidgets
+ Paned hPane
+ Panner panner
+ Label userMessage
+ Grip grip
+ Porthole porthole
+ Tree tree
+ Toggle <name of widget in application>
+ .
+ .
+ .
+ TransientShell resourceBox
+ Paned pane
+ Label resourceLabel
+ Form namesAndClasses
+ Toggle dot
+ Toggle star
+ Toggle any
+ Toggle name
+ Toggle class
+ .
+ .
+ .
+ Label namesLabel
+ List namesList
+ Label constraintLabel
+ List constraintList
+ Form valueForm
+ Label valueLabel
+ Text valueText
+ Box commandBox
+ Command setFile
+ Command save
+ Command apply
+ Command saveAndApply
+ Command cancel
+ Grip grip
+ Grip grip
+.fi
+.sp
+.SH ENVIRONMENT
+.PP
+.TP 8
+.B DISPLAY
+to get the default host and display number.
+.TP 8
+.B XENVIRONMENT
+to get the name of a resource file that overrides the global resources
+stored in the RESOURCE_MANAGER property.
+.SH FILES
+<XRoot>/lib/X11/app-defaults/Editres - specifies required resources
+.SH SEE ALSO
+X(1), xrdb(1), Athena Widget Set
+.SH RESTRICTIONS
+This is a prototype, there are lots of nifty features I would love to add,
+but I hope this will give you some ideas about what a resource editor
+can do.
+.SH AUTHOR
+Chris D. Peterson, formerly MIT X Consortium
+
diff --git a/editresP.h b/editresP.h
new file mode 100644
index 0000000..a2f3d7b
--- /dev/null
+++ b/editresP.h
@@ -0,0 +1,352 @@
+
+/*
+ * $Xorg: editresP.h,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Chris D. Peterson, MIT X Consortium
+ */
+
+#include <X11/Xmu/EditresP.h>
+#include <X11/Xresource.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+# define CLIENT_TIME_OUT 60000 /* wait sixty seconds for the client. */
+#else
+# define CLIENT_TIME_OUT 5000 /* wait five seconds for the client. */
+#endif /* DEBUG */
+
+#define PROTOCOL_VERSION_ONE_POINT_ONE 5 /* version 1.1 */
+#define ONE_POINT_ONE_STRING "1.1"
+#define PROTOCOL_VERSION_ONE_POINT_ZERO 4 /* version 1.0 */
+#define ONE_POINT_ZERO_STRING "1.0" ONE_POINT_ONE_STRING
+
+#define CURRENT_PROTOCOL_VERSION PROTOCOL_VERSION_ONE_POINT_ONE
+#define CURRENT_PROTOCOL_VERSION_STRING ONE_POINT_ONE_STRING
+
+#define FLASH_TIME 1000 /* Default flash time in microseconds */
+#define NUM_FLASHES 3 /* Default number of flashes. */
+
+#define NO_IDENT 0 /* an ident that will match nothing. */
+
+#define NUM_INC 10 /* amount to increment allocators. */
+
+#define ANY_RADIO_DATA ("the any widget")
+#define RESOURCE_BOX ("resourceBox")
+
+extern void exit();
+
+/*
+ * Retrieving ResType and Boolean is the same as retrieving a Card8.
+ */
+
+#define _XEditResGetBoolean _XEditResGet8
+#define _XEditResGetResType _XEditResGet8
+
+/*
+ * Contexts to use with the X Context Manager.
+ */
+
+#define NODE_INFO ((XContext) 42)
+
+/*
+ * Error codes for X Server errors.
+ */
+
+#define NO_ERROR 0
+#define NO_WINDOW 1
+
+typedef enum {LocalSendWidgetTree, LocalSetValues, LocalFindChild,
+ LocalFlashWidget, LocalGetGeometry, LocalGetResources,
+ LocalGetValues} ResCommand;
+
+typedef enum {ClassLabel, NameLabel, IDLabel, WindowLabel,
+ ToggleLabel} LabelTypes;
+typedef enum {SelectWidget, SelectAll, SelectNone, SelectInvert, SelectParent,
+ SelectChildren, SelectDescendants, SelectAncestors} SelectTypes;
+
+typedef struct _NameInfo {
+ struct _NameInfo * next; /* Next element in the linked list. */
+ Widget sep_leader; /* The separator toggle group leader. */
+ Widget name_leader; /* The name toggle group leader. */
+} NameInfo;
+
+typedef struct _ResourceBoxInfo {
+ Widget value_wid; /* The string containing the value. */
+ Widget res_label; /* The label containing current resoruce. */
+ Widget shell; /* Shell widget containing resource box. */
+ Widget norm_list; /* The List widget for the normal list. */
+ Widget cons_list; /* The List widget for the
+ Constriaint Resources */
+ NameInfo * name_info; /* The info about the widgets for each
+ name and class in the instance heirarchy. */
+} ResourceBoxInfo;
+
+typedef struct _WidgetResourceInfo {
+ char * name, * class, *type; /* Name, Class and Type of each resource. */
+} WidgetResourceInfo;
+
+typedef struct _WidgetResources {
+ int num_normal, num_constraint;
+ WidgetResourceInfo *normal, *constraint;
+ ResourceBoxInfo * res_box;
+} WidgetResources;
+
+typedef struct _WNode {
+ char * name;
+ char * class;
+ unsigned long id, window;
+ struct _WNode * parent;
+ struct _WNode ** children;
+ struct _TreeInfo * tree_info;
+ Cardinal num_children, alloc_children;
+ Widget widget;
+ WidgetResources * resources;
+} WNode;
+
+/*
+ * Information for the Select any widget, toggle buttons in the resource
+ * boxes.
+ */
+
+typedef struct _AnyInfo {
+ WNode * node; /* A Pointer off to the node corrsponding to
+ this resource box. */
+ Widget left_dot, left_star; /* The dot and star widgets to our left. */
+ Widget right_dot, right_star; /* The dot and star widgets to our right. */
+ int left_count, *right_count; /* If count > 0 then desensitize the left or
+ right dot and star widgets. */
+} AnyInfo;
+
+/*
+ * Information about the client we are currently working with.
+ */
+
+typedef struct _CurrentClient {
+ ResCommand command; /* the command sent. */
+ ResIdent ident;
+ ProtocolStream stream; /* protocol stream for this client. */
+ XtIntervalId timeout; /* timeout set in case he doesn't answer. */
+ Window window; /* window to communicate with. */
+ Atom atom; /* Atom used to communicate with this client.*/
+} CurrentClient;
+
+/*
+ * Information about a tree we can display.
+ */
+
+typedef struct _TreeInfo {
+ Widget tree_widget; /* The Tree widget that contains all nodes */
+ WNode * top_node; /* The top node in the tree. */
+ WNode ** active_nodes; /* The currently active nodes. */
+ Cardinal num_nodes, alloc_nodes; /* number of active nodes, and space */
+ Widget * flash_widgets; /* list of widgets to flash on and off. */
+ Cardinal num_flash_widgets, alloc_flash_widgets; /* number of flash wids.*/
+} TreeInfo;
+
+/*
+ * Information specific to a give APPLICATION screen.
+ */
+
+typedef struct _ScreenData {
+ Widget set_values_popup; /* The SetValues popup. */
+ Widget res_text; /* SetValues resource text widget. */
+ Widget val_text; /* SetValues value text widget. */
+ Widget info_label; /* The information label. */
+} ScreenData;
+
+typedef struct _AppResources {
+ Boolean debug; /* Is debugging on? */
+ int num_flashes, flash_time; /* Number and duration of flashes. */
+ Pixel flash_color; /* Color of flash window. */
+ char * save_resources_file; /* File to save the resources into. */
+
+ /* Private state */
+ Boolean allocated_save_resources_file;
+} AppResources;
+
+/*
+ * Information needed to apply the resource string to all widgets.
+ */
+
+typedef struct _ApplyResourcesInfo {
+ char * name, *class; /* name and class of this resource. */
+ unsigned short count;
+ ProtocolStream * stream;
+ XrmDatabase database;
+} ApplyResourcesInfo;
+
+/*
+ * Information needed to get a resource string from a widget.
+ */
+
+typedef struct _ObtainResourcesInfo {
+ char * name, *class; /* name and class of this resource. */
+ unsigned short count;
+ ProtocolStream * stream;
+ XrmDatabase database;
+} ObtainResourcesInfo;
+
+/************************************************************
+ *
+ * The Event Structures.
+ *
+ ************************************************************/
+
+typedef struct _AnyEvent {
+ EditresCommand type;
+} AnyEvent;
+
+typedef struct _WidgetTreeInfo {
+ WidgetInfo widgets;
+ char * name;
+ char * class;
+ unsigned long window;
+} WidgetTreeInfo;
+
+typedef struct _SendWidgetTreeEvent {
+ EditresCommand type;
+ char * toolkit;
+ unsigned short num_entries;
+ WidgetTreeInfo * info;
+} SendWidgetTreeEvent;
+
+typedef struct _SetValuesInfo {
+ WidgetInfo widgets;
+ char * message;
+} SetValuesInfo;
+
+typedef struct _SetValuesEvent {
+ EditresCommand type;
+ unsigned short num_entries;
+ SetValuesInfo * info;
+} SetValuesEvent;
+
+typedef struct _GetValuesInfo {
+ WidgetInfo widgets;
+ char * value;
+} GetValuesInfo;
+
+typedef struct _GetValuesEvent {
+ EditresCommand type;
+ unsigned short num_entries;
+ GetValuesInfo * info;
+} GetValuesEvent;
+
+typedef struct _ResourceInfo {
+ ResourceType res_type;
+ char * name, *class, *type;
+} ResourceInfo;
+
+typedef struct _GetResourcesInfo {
+ WidgetInfo widgets;
+ Boolean error;
+ char * message;
+ unsigned short num_resources;
+ ResourceInfo * res_info;
+} GetResourcesInfo;
+
+typedef struct _GetResourcesEvent {
+ EditresCommand type;
+ unsigned short num_entries;
+ GetResourcesInfo * info;
+} GetResourcesEvent;
+
+typedef struct _GetGeomInfo {
+ EditresCommand type;
+ WidgetInfo widgets;
+ Boolean error;
+ char * message;
+ Boolean visable;
+ short x, y;
+ unsigned short width, height, border_width;
+} GetGeomInfo;
+
+typedef struct _GetGeomEvent {
+ EditresCommand type;
+ unsigned short num_entries;
+ GetGeomInfo * info;
+} GetGeomEvent;
+
+typedef struct _FindChildEvent {
+ EditresCommand type;
+ WidgetInfo widgets;
+} FindChildEvent;
+
+typedef union _Event {
+ AnyEvent any_event;
+ SendWidgetTreeEvent send_widget_tree_event;
+ SetValuesEvent set_values_event;
+ GetResourcesEvent get_resources_event;
+ GetGeomEvent get_geom_event;
+ FindChildEvent find_child_event;
+ GetValuesEvent get_values_event;
+} Event;
+
+/*
+ * number of application resource labels.
+ */
+
+#define NUM_RES_LABELS 37
+
+/*
+ * Global variables.
+ */
+
+#ifndef THIS_IS_MAIN
+ extern int global_effective_protocol_version;
+ extern char* global_effective_toolkit;
+ extern int global_error_code;
+ extern unsigned long global_serial_num;
+ extern int (*global_old_error_handler)();
+ extern Boolean global_resource_box_up;
+
+ extern TreeInfo *global_tree_info;
+ extern CurrentClient global_client;
+ extern ScreenData global_screen_data;
+ extern Widget global_tree_parent;
+ extern Widget global_paned; /* named after toolkit */
+ extern Widget global_toplevel;
+ extern AppResources global_resources;
+
+ extern String res_labels[NUM_RES_LABELS];
+#endif
+
+/*
+ * Macros.
+ */
+
+#define streq(a, b) ( strcmp((a), (b)) == 0 )
+
+/* number of entries in the command menu */
+#define NUM_CM_ENTRIES 8
+/* offset into CM entries for setting insensitive */
+#define CM_OFFSET 1
+/* number of CM entries to make insensitive */
+#define CM_NUM 5
+/* number of entries in the tree menu */
+#define NUM_TM_ENTRIES 16
+#define TM_OFFSET 0
+#define TM_NUM 16
diff --git a/geometry.c b/geometry.c
new file mode 100644
index 0000000..164308c
--- /dev/null
+++ b/geometry.c
@@ -0,0 +1,490 @@
+/*
+ * $Xorg: geometry.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Chris D. Peterson, MIT X Consortium
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <stdio.h>
+
+#include <X11/Xaw/Cardinals.h>
+
+#include "editresP.h"
+
+extern void SetMessage(), SetCommand(), SetAndCenterTreeNode(), AddString();
+extern void GetAllStrings(), InsertWidgetFromNode();
+extern int HandleXErrors();
+extern WNode * FindNode();
+
+static WNode *FindWidgetFromWindow(), *FindWidgetFromWindowGivenNode();
+static void CreateFlashWidget(), FlashWidgets();
+static void AddToFlashList(), _AddToFlashList();
+static void FlashWidgetsOn(), FlashWidgetsOff(), FlashWidgetsCleanup();
+
+/* Function Name: _FindWidget
+ * Description: Finds a widget in the tree and shows it to the user.
+ * Arguments: w - any widget in the application.
+ * Returns: none.
+ */
+
+void
+_FindWidget(w)
+Widget w;
+{
+ char msg[BUFSIZ];
+ WNode * node;
+ Window win, GetClientWindow();
+ int x, y; /* location of event in root coordinates. */
+
+ sprintf(msg, res_labels[14]);
+
+ SetMessage(global_screen_data.info_label, msg);
+
+ if ( (win = GetClientWindow(w, &x, &y)) != None) {
+ node = FindWidgetFromWindow(global_tree_info, win);
+ if (node != NULL) {
+ ProtocolStream * stream = &(global_client.stream);
+
+ _XEditResResetStream(stream);
+ InsertWidgetFromNode(stream, node);
+ _XEditResPut16(stream, (short) x);
+ _XEditResPut16(stream, (short) y);
+ SetCommand(w, LocalFindChild, NULL);
+ return;
+ }
+ }
+
+ SetMessage(global_screen_data.info_label,
+ res_labels[15]);
+}
+
+/* Function Name: FindWidgetFromWindow
+ * Description: finds a widget in the current tree given its window id.
+ * Arguments: tree_info - information about this tree.
+ * win - window to search for.
+ * Returns: node - the node corrosponding to this widget.
+ */
+
+static WNode *
+FindWidgetFromWindow(tree_info, win)
+TreeInfo * tree_info;
+Window win;
+{
+ if (tree_info == NULL)
+ return(NULL);
+
+ return(FindWidgetFromWindowGivenNode(tree_info->top_node, win));
+}
+
+/* Function Name: FindWidgetFromWindowGivenNode
+ * Description: finds a widget in the current tree given its window id.
+ * Arguments: node - current node.
+ * win - window to search for.
+ * Returns: node - the node corrosponding to this widget.
+ */
+
+static WNode *
+FindWidgetFromWindowGivenNode(node, win)
+WNode * node;
+Window win;
+{
+ int i;
+ WNode * ret_node;
+
+ if (node->window == win)
+ return(node);
+
+ for (i = 0; i < node->num_children; i++) {
+ ret_node = FindWidgetFromWindowGivenNode(node->children[i], win);
+ if (ret_node != NULL)
+ return(ret_node);
+ }
+ return(NULL);
+}
+
+/* Function Name: DisplayChild
+ * Description: Displays the child node returned by the client
+ * Arguments: event - the event from the client.
+ * Returns: none.
+ */
+
+void
+DisplayChild(event)
+Event * event;
+{
+ FindChildEvent * find_event = (FindChildEvent *) event;
+ WNode * node;
+ char msg[BUFSIZ];
+ void _FlashActiveWidgets();
+
+ node = FindNode(global_tree_info->top_node, find_event->widgets.ids,
+ find_event->widgets.num_widgets);
+
+ if (node == NULL) {
+ sprintf(msg, res_labels[13]);
+ SetMessage(global_screen_data.info_label, msg);
+ return;
+ }
+
+ SetAndCenterTreeNode(node);
+
+ node = node->tree_info->top_node;
+
+ sprintf(msg, res_labels[12], node->name, node->class);
+ SetMessage(global_screen_data.info_label, msg);
+
+ _FlashActiveWidgets(global_tree_info);
+}
+
+/* Function Name: _FlashActiveWidgets
+ * Description: Highlights all active widgets in the tree.
+ * Arguments: tree_info - information about the current tree.
+ * Returns: none.
+ */
+
+void
+_FlashActiveWidgets(tree_info)
+TreeInfo * tree_info;
+{
+ int i;
+ ProtocolStream * stream = &(global_client.stream);
+
+ if (tree_info == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[17]);
+ return;
+ }
+
+ if (tree_info->num_nodes == 0) {
+ SetMessage(global_screen_data.info_label,res_labels[18]);
+ return;
+ }
+
+ _XEditResResetStream(stream);
+ /*
+ * Insert the number of widgets.
+ */
+ _XEditResPut16(stream, (unsigned short) tree_info->num_nodes);
+
+ for (i = 0; i < tree_info->num_nodes; i++)
+ InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
+
+ SetCommand(tree_info->tree_widget, LocalFlashWidget, NULL);
+}
+
+/* Function Name: HandleFlashWidget
+ * Description: Is called when client has returned geometry of all widget
+ * to flash.
+ * Arguments: event - the event containing the client info.
+ * Returns: none.
+ */
+
+char *
+HandleFlashWidget(event)
+Event * event;
+{
+ GetGeomEvent * geom_event = (GetGeomEvent *) event;
+ char * errors = NULL;
+ int i;
+
+ for (i = 0; i < (int)geom_event->num_entries; i++)
+ AddToFlashList(global_tree_info, geom_event->info + i, &errors);
+
+ FlashWidgets(global_tree_info);
+
+ return(errors);
+}
+
+/* Function Name: AddWidgetToFlashList
+ * Description: Adds a widget to the list of widget to flash.
+ * Arguments: tree_info - info about this tree.
+ * geom_info - the info from the client about this widget.
+ * errors - a string containing the errors.
+ * Returns: none
+ */
+
+static void
+AddToFlashList(tree_info, geom_info, errors)
+TreeInfo * tree_info;
+GetGeomInfo * geom_info;
+char ** errors;
+{
+ WNode * node;
+ char buf[BUFSIZ];
+
+ node = FindNode(tree_info->top_node,
+ geom_info->widgets.ids, geom_info->widgets.num_widgets);
+
+ if (node == NULL) {
+ sprintf(buf, "Editres Internal Error: Unable to FindNode.\n");
+ AddString(errors, buf);
+ return;
+ }
+
+ if (geom_info->error) {
+ AddString(errors, geom_info->message);
+ return;
+ }
+
+ if (!geom_info->visable) {
+ sprintf(buf, "%s(0x%lx) - This widget is not mapped\n",
+ node->name, node->id);
+ AddString(errors, buf);
+ return;
+ }
+
+ _AddToFlashList(tree_info, errors, node,
+ geom_info->x, geom_info->y,
+ geom_info->width + geom_info->border_width,
+ geom_info->height + geom_info->border_width);
+}
+
+/* Function Name: _AddToFlashList
+ * Description: adds the window to the current client's flash list.
+ * Arguments: errors - a string to stuff any errors encountered.
+ * node - the node associated with this object.
+ * x, y - location of the flash widget in root coords.
+ * width, height - size of the flash widget.
+ * Returns: none.
+ */
+
+static void
+_AddToFlashList(tree_info, errors, node, x, y, width, height)
+TreeInfo * tree_info;
+char ** errors;
+WNode * node;
+int x, y;
+unsigned int width, height;
+{
+ Display * dpy = XtDisplay(tree_info->tree_widget);
+ Window window = (Window) node->window;
+ XWindowAttributes attrs;
+
+ if (window == EDITRES_IS_OBJECT)
+ window = node->parent->window;
+
+ if (window == EDITRES_IS_UNREALIZED) {
+ char buf[BUFSIZ];
+
+ if (node->window == EDITRES_IS_OBJECT)
+ sprintf(buf, "%s(0x%lx) - This object's parent is unrealized\n",
+ node->name, node->id);
+ else
+ sprintf(buf, "%s(0x%lx) - This widget is unrealized\n",
+ node->name, node->id);
+
+ AddString(errors, buf);
+ return;
+ }
+
+ global_error_code = NO_ERROR; /* Reset Error code. */
+ global_old_error_handler = XSetErrorHandler(HandleXErrors);
+ global_serial_num = NextRequest(dpy);
+
+ XGetWindowAttributes(dpy, window, &attrs);
+
+ XSync(dpy, FALSE);
+ XSetErrorHandler(global_old_error_handler);
+ if (global_error_code == NO_WINDOW) {
+ char buf[BUFSIZ];
+
+ sprintf(buf, "%s(0x%lx) - This widget's window no longer exists.\n",
+ node->name, node->id);
+ AddString(errors, buf);
+ return;
+ }
+
+ if (attrs.map_state != IsViewable) {
+ char buf[BUFSIZ];
+
+ sprintf(buf, "%s(0x%lx) - This widget is not mapped.\n",
+ node->name, node->id);
+ AddString(errors, buf);
+ return;
+ }
+
+ CreateFlashWidget(tree_info, x, y, width, height);
+}
+
+/* Function Name: CreateFlashWidget
+ * Description: Creates a widget of the size specified that
+ * will flash on the display, and adds it to the list
+ * of widgets to flash.
+ * Arguments: tree_info - the tree information structure.
+ * x,y,width, height - size and location of the flash widget.
+ * Returns: none.
+ */
+
+#define MORE_FLASH_WIDGETS 5
+
+static void
+CreateFlashWidget(tree_info, x, y, width, height)
+TreeInfo * tree_info;
+int x, y;
+unsigned int width, height;
+{
+ Widget shell;
+ Arg args[3];
+ Cardinal num = 0;
+ Dimension bw;
+
+ XtSetArg(args[num], XtNx, x); num++;
+ XtSetArg(args[num], XtNy, y); num++;
+ XtSetArg(args[num], XtNbackground, global_resources.flash_color); num++;
+
+ shell = XtCreatePopupShell("flash", overrideShellWidgetClass,
+ tree_info->tree_widget, args, num);
+
+ num = 0;
+ XtSetArg(args[num], XtNborderWidth, &bw); num++;
+ XtGetValues(shell, args, num);
+
+ bw *= 2;
+
+ num = 0;
+ XtSetArg(args[num], XtNwidth, (width - bw)); num++;
+ XtSetArg(args[num], XtNheight, (height - bw)); num++;
+ XtSetValues(shell, args, num);
+
+ if (tree_info->num_flash_widgets + 1 > tree_info->alloc_flash_widgets) {
+ tree_info->alloc_flash_widgets += MORE_FLASH_WIDGETS;
+ tree_info->flash_widgets =
+ (Widget *) XtRealloc((char *)tree_info->flash_widgets,
+ sizeof(Widget) * tree_info->alloc_flash_widgets);
+ }
+
+ tree_info->flash_widgets[tree_info->num_flash_widgets] = shell;
+ tree_info->num_flash_widgets++;
+}
+
+/* Function Name: FlashWidgets
+ * Description: Starts the widgets flashing.
+ * Arguments: tree_info - the info about the tree (contains flash list)
+ * Returns: none
+ */
+
+static void
+FlashWidgets(tree_info)
+TreeInfo * tree_info;
+{
+ int i;
+ unsigned long wait, half_flash;
+ XtAppContext ac = XtWidgetToApplicationContext(tree_info->tree_widget);
+
+ if (tree_info->flash_widgets == NULL) /* no widgets to flash. */
+ return;
+
+ wait = half_flash = global_resources.flash_time/2;
+ for (i = 1; i < global_resources.num_flashes; i++) {
+ XtAppAddTimeOut(ac, wait, FlashWidgetsOff,(XtPointer)tree_info);
+ wait += half_flash;
+ XtAppAddTimeOut(ac, wait, FlashWidgetsOn,(XtPointer)tree_info);
+ wait += half_flash;
+ }
+
+ wait += half_flash;
+ XtAppAddTimeOut(ac, wait, FlashWidgetsCleanup, (XtPointer)tree_info);
+
+ FlashWidgetsOn((XtPointer) tree_info, (XtIntervalId *) NULL);
+}
+
+/* Function Name: FlashWidgetsOn
+ * Description: Turns on all the Flash Widgets.
+ * Arguments: info_ptr - pointer to the tree info.
+ * id - *** UNUSED ***.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+FlashWidgetsOn(info_ptr, id)
+XtPointer info_ptr;
+XtIntervalId * id;
+{
+
+ int i;
+ TreeInfo * tree_info = (TreeInfo *) info_ptr;
+
+ for (i = 0; i < tree_info->num_flash_widgets; i++) {
+ XtRealizeWidget(tree_info->flash_widgets[i]);
+ XMapRaised(XtDisplay(tree_info->flash_widgets[i]),
+ XtWindow(tree_info->flash_widgets[i]));
+ }
+}
+
+/* Function Name: FlashWidgetsOff
+ * Description: Turns off all the Flash Widgets.
+ * Arguments: info_ptr - pointer to the tree info.
+ * id - *** UNUSED ***.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+FlashWidgetsOff(info_ptr, id)
+XtPointer info_ptr;
+XtIntervalId * id;
+{
+ int i;
+ TreeInfo * tree_info = (TreeInfo *) info_ptr;
+
+ for (i = 0; i < tree_info->num_flash_widgets; i++)
+ XtUnmapWidget(tree_info->flash_widgets[i]);
+}
+
+/* Function Name: FlashWidgetsCleanup
+ * Description: Destroys all the Flash Widgets.
+ * Arguments: info_ptr - pointer to the tree info.
+ * id - *** UNUSED ***.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+FlashWidgetsCleanup(info_ptr, id)
+XtPointer info_ptr;
+XtIntervalId * id;
+{
+ int i;
+ TreeInfo * tree_info = (TreeInfo *) info_ptr;
+
+/*
+ * Unmap 'em first for consistency.
+ */
+
+ for (i = 0; i < tree_info->num_flash_widgets; i++)
+ XtUnmapWidget(tree_info->flash_widgets[i]);
+
+ XFlush(XtDisplay(tree_info->tree_widget));
+
+ for (i = 0; i < tree_info->num_flash_widgets; i++)
+ XtDestroyWidget(tree_info->flash_widgets[i]);
+
+ XtFree((char *)tree_info->flash_widgets);
+ tree_info->flash_widgets = NULL;
+ tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
+}
diff --git a/handler.c b/handler.c
new file mode 100644
index 0000000..2c3ebeb
--- /dev/null
+++ b/handler.c
@@ -0,0 +1,966 @@
+/*
+ * $Xorg: handler.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/Panner.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xos.h> /* for W_OK def */
+
+#include <stdio.h>
+
+#include "editresP.h"
+
+/*
+ * Function Definitions.
+ */
+
+extern void SetCommand(), PopupSetValues(), SetAndCenterTreeNode();
+extern void _TreeSelect(), _TreeRelabel(), _TreeActivate(), SetMessage();
+extern void _FlashActiveWidgets(), _DumpTreeToFile(), _PopupFileDialog();
+extern void AddString(), CreateResourceBox(), ExecuteOverAllNodes();
+extern void GetNamesAndClasses(), TreeToggle(), InsertWidgetFromNode();
+extern Boolean CheckDatabase();
+extern XrmQuarkList Quarkify();
+extern char *GetResourceValueForSetValues();
+
+void SetResourceString(), ActivateResourceWidgets();
+void ActivateWidgetsAndSetResourceString();
+static void SetOnlyMatchingWidgets();
+static void CreateSetValuesCommand();
+static void ObtainResource();
+
+/* Function Name: Quit
+ * Description: This function prints a message to stdout.
+ * Arguments: w - ** UNUSED **
+ * call_data - ** UNUSED **
+ * client_data - ** UNUSED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+Quit(w, client_data, call_data)
+Widget w;
+XtPointer call_data, client_data;
+{
+ XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
+ exit(0);
+}
+
+/* Function Name: SendTree
+ * Description: This function initiates the client communication.
+ * by getting the resource tree.
+ * Arguments: w - the widget that made the selection.
+ * value - a boolean value stored as a pointer.
+ * if True then get a new client, otherwise
+ * refresh the current client.
+ * call_data - ** UNUSED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+SendTree(w, value, call_data)
+Widget w;
+XtPointer value, call_data;
+{
+ if ((Boolean)(long) value)
+ global_client.window = None;
+
+ if (!XtIsWidget(w)) /* Make sure that we use a "Real" widget here. */
+ w = XtParent(w);
+
+ _XEditResResetStream(&(global_client.stream)); /* an empty message. */
+
+ SetCommand(w, LocalSendWidgetTree, NULL);
+}
+
+/* Function Name: FindWidget
+ * Description: Maps a widget in the client to one in the currently
+ * displayed widget tree.
+ * Arguments: w - the widget that invoked this action.
+ * call_data, client_data ** UNUSED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+FindWidget(w, client_data, call_data)
+Widget w;
+XtPointer client_data, call_data;
+{
+ void _FindWidget();
+
+ _FindWidget(XtParent(w)); /* Use parent since it is a "real"
+ widget not a rect_obj. */
+}
+
+/* Function Name: InitSetValues
+ * Description: This function pops up the setvalues dialog
+ * Arguments: w - the widget caused this action.
+ * call_data - ** UNUSED **
+ * client_data - ** UNUSED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+InitSetValues(w, client_data, call_data)
+Widget w;
+XtPointer call_data, client_data;
+{
+ if (!XtIsWidget(w)) /* Make sure that we use a "Real" widget here. */
+ w = XtParent(w);
+
+ PopupSetValues(w, NULL);
+}
+
+/* Function Name: TreeSelect
+ * Description: Selects all widgets.
+ * Arguments: w - the widget caused this action.
+ * call_data - ** UNUSED **
+ * client_data - The type of thing to select.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+TreeSelect(w, client_data, call_data)
+Widget w;
+XtPointer call_data, client_data;
+{
+ SelectTypes type = (SelectTypes) client_data;
+
+ _TreeSelect(global_tree_info, type);
+}
+
+/* Function Name: TreeRelabel
+ * Description: Relabels a tree to the type specified.
+ * Arguments: w - the widget caused this action.
+ * call_data - ** UNUSED **
+ * client_data - the type of label to assign to each node.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+TreeRelabel(w, client_data, call_data)
+Widget w;
+XtPointer call_data, client_data;
+{
+ LabelTypes type = (LabelTypes) client_data;
+
+ _TreeRelabel(global_tree_info, type);
+}
+
+/* Function Name: PannerCallback
+ * Description: called when the panner has moved.
+ * Arguments: panner - the panner widget.
+ * closure - *** NOT USED ***.
+ * report_ptr - the panner record.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+PannerCallback(w, closure, report_ptr)
+Widget w;
+XtPointer closure, report_ptr;
+{
+ Arg args[2];
+ XawPannerReport *report = (XawPannerReport *) report_ptr;
+
+ if (global_tree_info == NULL)
+ return;
+
+ XtSetArg (args[0], XtNx, -report->slider_x);
+ XtSetArg (args[1], XtNy, -report->slider_y);
+
+ XtSetValues(global_tree_info->tree_widget, args, TWO);
+}
+
+/* Function Name: PortholeCallback
+ * Description: called when the porthole or its child has
+ * changed
+ * Arguments: porthole - the porthole widget.
+ * panner_ptr - the panner widget.
+ * report_ptr - the porthole record.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+PortholeCallback(w, panner_ptr, report_ptr)
+Widget w;
+XtPointer panner_ptr, report_ptr;
+{
+ Arg args[10];
+ Cardinal n = 0;
+ XawPannerReport *report = (XawPannerReport *) report_ptr;
+ Widget panner = (Widget) panner_ptr;
+
+ XtSetArg (args[n], XtNsliderX, report->slider_x); n++;
+ XtSetArg (args[n], XtNsliderY, report->slider_y); n++;
+ if (report->changed != (XawPRSliderX | XawPRSliderY)) {
+ XtSetArg (args[n], XtNsliderWidth, report->slider_width); n++;
+ XtSetArg (args[n], XtNsliderHeight, report->slider_height); n++;
+ XtSetArg (args[n], XtNcanvasWidth, report->canvas_width); n++;
+ XtSetArg (args[n], XtNcanvasHeight, report->canvas_height); n++;
+ }
+ XtSetValues (panner, args, n);
+}
+
+/* Function Name: FlashActiveWidgets
+ * Description: called to flass all active widgets in the display.
+ * Arguments: *** NOT USED ***
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+FlashActiveWidgets(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ _FlashActiveWidgets(global_tree_info);
+}
+
+/* Function Name: GetResourceList
+ * Description: Gets the resources lists of all active widgets.
+ * Arguments: ** NOT USED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+GetResourceList(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ WNode * node;
+ ProtocolStream * stream = &(global_client.stream);
+
+ if (global_tree_info == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[17]);
+ return;
+ }
+
+ if (global_tree_info->num_nodes != 1) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[19]);
+ return;
+ }
+
+ node = global_tree_info->active_nodes[0];
+ if (node->resources != NULL) {
+ char * errors = NULL;
+ CreateResourceBox(node, &errors);
+ if (errors != NULL) {
+ SetMessage(global_screen_data.info_label, errors);
+ XtFree(errors);
+ }
+ return;
+ }
+
+ /*
+ * No resoruces, fetch them from the client.
+ */
+
+ _XEditResResetStream(stream);
+ _XEditResPut16(stream, (unsigned short) 1);
+ InsertWidgetFromNode(stream, node);
+ SetCommand(global_tree_info->tree_widget, LocalGetResources, NULL);
+}
+
+/* Function Name: DumpTreeToFile
+ * Description: Dumps all widgets in the tree to a file.
+ * Arguments: w - the widget that activated this callback.
+ * junk, garbage - ** NOT USED **.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+DumpTreeToFile(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ _PopupFileDialog(XtParent(w), "Enter the filename:", "",
+ _DumpTreeToFile, (XtPointer) global_tree_info);
+}
+
+/************************************************************
+ *
+ * Callbacks for the Resource Box.
+ *
+ ************************************************************/
+
+
+/* Function Name: AnyChosen
+ * Description: Callback that is called when the "any" widget
+ * is activated.
+ * Arguments: w - the "any" widget that activated this callback.
+ * any_info_ptr - pointer to struct containing
+ * dot and star widgets to lock.
+ * state_ptr - state of the any toggle.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+AnyChosen(w, any_info_ptr, state_ptr)
+Widget w;
+XtPointer any_info_ptr, state_ptr;
+{
+ AnyInfo * any_info = (AnyInfo *) any_info_ptr;
+ Boolean state = (Boolean)(long) state_ptr;
+ Arg args[1];
+
+ if (state) {
+
+ if (any_info->left_count == 0) {
+ XtSetSensitive(any_info->left_dot, FALSE);
+ XtSetSensitive(any_info->left_star, FALSE);
+
+ XtSetArg(args[0], XtNstate, TRUE);
+ XtSetValues(any_info->left_star, args, ONE);
+ }
+
+ if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
+ XtSetSensitive(any_info->right_dot, FALSE);
+ XtSetSensitive(any_info->right_star, FALSE);
+
+ XtSetArg(args[0], XtNstate, TRUE);
+ XtSetValues(any_info->right_star, args, ONE);
+ }
+ any_info->left_count++;
+
+ if (any_info->right_count != NULL)
+ (*any_info->right_count)++;
+ }
+ else { /* state == 0 */
+ if (any_info->left_count > 0)
+ any_info->left_count--;
+ if ((any_info->right_count != NULL)&&(*any_info->right_count > 0))
+ (*any_info->right_count)--;
+
+ if (any_info->left_count == 0) {
+ XtSetSensitive(any_info->left_dot, TRUE);
+ XtSetSensitive(any_info->left_star, TRUE);
+
+ XtSetArg(args[0], XtNstate, TRUE);
+ XtSetValues(any_info->left_dot, args, ONE);
+ }
+
+ if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
+ XtSetSensitive(any_info->right_dot, TRUE);
+ XtSetSensitive(any_info->right_star, TRUE);
+
+ XtSetArg(args[0], XtNstate, TRUE);
+ XtSetValues(any_info->right_dot, args, ONE);
+ }
+ }
+ SetResourceString(NULL, (XtPointer) any_info->node, NULL);
+ ActivateResourceWidgets(NULL, (XtPointer) any_info->node, NULL);
+}
+
+/* Function Name: GetResourceName
+ * Description: Gets the name of the current resource.
+ * Arguments: res_box - the resource box.
+ * Returns: the name of the currently selected resource.
+ */
+
+
+static char *
+GetResourceName(res_box)
+ResourceBoxInfo * res_box;
+{
+ XawListReturnStruct * list_info;
+ char * result;
+
+ list_info = XawListShowCurrent(res_box->norm_list);
+ if ((list_info->list_index == XAW_LIST_NONE) &&
+ (res_box->cons_list != NULL)) {
+ list_info = XawListShowCurrent(res_box->cons_list);
+ }
+
+ if (list_info->list_index == XAW_LIST_NONE)
+ result = "unknown";
+ else
+ result = list_info->string;
+
+ return(result);
+}
+
+
+/* Function Name: ActivateWidgetsAndSetResourceString
+ * Description: Sets the new resources string, then
+ * activates all widgets that match this resource,
+ * Arguments: w - the widget that activated this.
+ * node_ptr - the node that owns this resource box.
+ * call_data - passed on to other callbacks.
+ * Returns: none.
+ *
+ * NOTE: I cannot just have two callback routines, since I care which
+ * order that these are executed in, sigh...
+ */
+
+void
+ActivateWidgetsAndSetResourceString(w, node_ptr, call_data)
+Widget w;
+XtPointer node_ptr, call_data;
+{
+ SetResourceString(w, node_ptr, call_data);
+ ActivateResourceWidgets(w, node_ptr, call_data);
+}
+
+/* Function Name: SetResourceString
+ * Description: Sets the resource label to correspond to the currently
+ * chosen string.
+ * Arguments: w - The widget that invoked this callback, or NULL.
+ * node_ptr - pointer to widget node contating this res box.
+ * call_data - The call data for the action that invoked
+ * this callback.
+ * Returns: none.
+ */
+
+void
+SetResourceString(w, node_ptr, junk)
+Widget w;
+XtPointer node_ptr, junk;
+{
+ static char * malloc_string; /* These are both inited to zero. */
+ static Cardinal malloc_size;
+
+ WNode * node = (WNode *) node_ptr;
+ ResourceBoxInfo * res_box = node->resources->res_box;
+ char * temp, buf[BUFSIZ * 10]; /* here's hoping it's big enough. */
+ NameInfo * name_node = res_box->name_info;
+ Arg args[1];
+ int len;
+
+ if ((w != NULL) && XtIsSubclass(w, toggleWidgetClass)) {
+ /*
+ * Only set resources when toggles are activated, not when they are
+ * deactivated.
+ */
+ if (!((Boolean)(long) junk))
+ return;
+ }
+
+ buf[0] = '\0'; /* clear out string. */
+
+ /*
+ * Get the widget name/class info.
+ */
+
+ if ((temp = (char *) XawToggleGetCurrent(name_node->sep_leader)) != NULL)
+ strcat(buf, temp);
+
+ for ( ; name_node->next != NULL ; name_node = name_node->next) {
+ temp = (char *) XawToggleGetCurrent(name_node->name_leader);
+ if ( (temp != NULL) && !streq(temp, ANY_RADIO_DATA) ) {
+ strcat(buf, temp);
+ temp = (char *) XawToggleGetCurrent(name_node->next->sep_leader);
+ if (temp == NULL)
+ strcat(buf, "!");
+ else
+ strcat(buf, temp);
+ }
+ }
+
+ strcat(buf, GetResourceName(res_box));
+ len = strlen(buf) + 2; /* Leave space for ':' and '\0' */
+
+#ifdef notdef
+ XtSetArg(args[0], XtNstring, &temp);
+ XtGetValues(res_box->value_wid, args, ONE);
+ len += strlen(temp);
+#endif
+
+ if (len > malloc_size) {
+ malloc_string = XtRealloc(malloc_string, sizeof(char) * len);
+ malloc_size = len;
+ }
+
+ strcpy(malloc_string, buf);
+ strcat(malloc_string, ":");
+#ifdef notdef
+ strcat(malloc_string, temp);
+#endif
+
+ XtSetArg(args[0], XtNlabel, malloc_string);
+ XtSetValues(res_box->res_label, args, ONE);
+}
+
+/* Function Name: ResourceListCallback
+ * Description: Callback functions for the resource lists. This
+ * routine is essentialy called by the list widgets
+ * Notify action. If action EnableGetVal has been
+ * invoked, ResourceListCallback will perform a
+ * GetValues protocol request.
+ * Arguments: list - the list widget that we are dealing with.
+ * node_ptr - pointer to widget node contating this res box.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+extern Boolean do_get_values;
+
+void
+ResourceListCallback(list, node_ptr, junk)
+Widget list;
+XtPointer node_ptr, junk;
+{
+ Widget o_list;
+ WNode * node = (WNode *) node_ptr;
+ ResourceBoxInfo * res_box = node->resources->res_box;
+
+ if (list == res_box->norm_list)
+ o_list = res_box->cons_list;
+ else
+ o_list = res_box->norm_list;
+
+ if (o_list != NULL)
+ XawListUnhighlight(o_list);
+
+ SetResourceString(list, node_ptr, junk);
+
+ /* get the resource value from the application */
+ if (global_effective_protocol_version >=
+ PROTOCOL_VERSION_ONE_POINT_ONE && do_get_values) {
+ ObtainResource(node_ptr);
+ do_get_values = False;
+ }
+}
+
+/* Function Name: PopdownResBox
+ * Description: Pops down the resource box.
+ * Arguments: w - UNUSED
+ * shell_ptr - pointer to the shell to pop down.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+PopdownResBox(w, shell_ptr, junk)
+Widget w;
+XtPointer shell_ptr, junk;
+{
+ Widget shell = (Widget) shell_ptr;
+
+ XtPopdown(shell);
+ XtDestroyWidget(shell);
+}
+
+/* ARGSUSED */
+static void
+_AppendResourceString(w, res_box_ptr, filename_ptr)
+Widget w;
+XtPointer res_box_ptr, filename_ptr;
+{
+ Arg args[1];
+ FILE * fp;
+ char buf[BUFSIZ], * resource_string, *filename = (char *) filename_ptr;
+ ResourceBoxInfo * res_box = (ResourceBoxInfo *) res_box_ptr;
+ char *value_ptr;
+
+ if (filename != NULL) {
+ if (global_resources.allocated_save_resources_file)
+ XtFree(global_resources.save_resources_file);
+ else
+ global_resources.allocated_save_resources_file = TRUE;
+
+ global_resources.save_resources_file = XtNewString(filename);
+ }
+
+ if ((fp = fopen(global_resources.save_resources_file, "a+")) == NULL) {
+ sprintf(buf, "Unable to open this file for writing, would %s",
+ "you like To try again?");
+ _PopupFileDialog(global_toplevel ,buf,
+ global_resources.save_resources_file,
+ _AppendResourceString, res_box_ptr);
+ return;
+ }
+
+ XtSetArg(args[0], XtNlabel, &resource_string);
+ XtGetValues(res_box->res_label, args, ONE);
+
+ XtSetArg(args[0], XtNstring, &value_ptr);
+ XtGetValues(res_box->value_wid, args, ONE);
+
+ fprintf(fp, "%s %s\n", resource_string, value_ptr);
+
+ fclose(fp);
+}
+
+/* Function Name: SaveResource
+ * Description: Save the current resource to your resource file
+ * Arguments: w - any widget in the application.
+ * res_box_ptr - the resource box info.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+SaveResource(w, res_box_ptr, junk)
+Widget w;
+XtPointer res_box_ptr, junk;
+{
+ /*
+ * If there is no filename the ask for one, otherwise just save to
+ * current file.
+ */
+
+ if (streq(global_resources.save_resources_file, ""))
+ _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
+ global_resources.save_resources_file,
+ _AppendResourceString, res_box_ptr);
+ else
+ _AppendResourceString(w, res_box_ptr, NULL);
+}
+
+/* Function Name: _SetResourcesFile
+ * Description: Sets the filename of the file to save the resources to.
+ * Arguments: w - UNUSED
+ * junk - UNUSED
+ * filename_ptr - a pointer to the filename;
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+_SetResourcesFile(w, junk, filename_ptr)
+Widget w;
+XtPointer junk, filename_ptr;
+{
+ char *filename = (char *) filename_ptr;
+
+ if (global_resources.allocated_save_resources_file)
+ XtFree(global_resources.save_resources_file);
+ else
+ global_resources.allocated_save_resources_file = TRUE;
+
+ global_resources.save_resources_file = XtNewString(filename);
+}
+
+/* Function Name: SetFile
+ * Description: Changes the current save file
+ * Arguments: w - UNUSED.
+ * res_box_ptr - UNUSED.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+SetFile(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ /*
+ * If there is no filename the ask for one, otherwise just save to
+ * current file.
+ */
+
+ _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
+ global_resources.save_resources_file,
+ _SetResourcesFile, NULL);
+}
+
+/* Function Name: ApplyResource
+ * Description: Apply the current resource to the running application.
+ * Arguments: w - any widget in the application.
+ * node_ptr - a pointer to the node containing
+ * the current resouce box.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+ApplyResource(w, node_ptr, junk)
+Widget w;
+XtPointer node_ptr, junk;
+{
+ ProtocolStream * stream = &(global_client.stream);
+ ApplyResourcesInfo info;
+ WNode * node = (WNode *) node_ptr;
+ char * value;
+ unsigned short size, i;
+ long len;
+ Arg args[1];
+
+ info.name = GetResourceName(node->resources->res_box);
+ info.class = "IGNORE_ME"; /* Not currently used. */
+ info.stream = stream;
+ info.count = 0;
+
+ XtSetArg(args[0], XtNlabel, &value);
+ XtGetValues(node->resources->res_box->res_label, args, ONE);
+
+ info.database = NULL;
+ XrmPutLineResource(&(info.database), value);
+
+
+ _XEditResResetStream(stream);
+ _XEditResPutString8(stream, info.name); /* Insert name */
+ _XEditResPutString8(stream, XtRString); /* insert type */
+
+ /*
+ * Insert value.
+ */
+
+ value = GetResourceValueForSetValues(node, &size);
+ _XEditResPut16(stream, size);
+ for (i = 0; i < size; i++)
+ _XEditResPut8(stream, value[i]);
+ XtFree(value);
+ len = stream->current - stream->top;
+
+ /*
+ * Insert the widget count, overriden later.
+ */
+
+ _XEditResPut16(stream, 0);
+
+ ExecuteOverAllNodes(node->tree_info->top_node,
+ CreateSetValuesCommand, (XtPointer) &info);
+
+ if (info.count > 0) {
+ *(stream->top + len++) = info.count >> XER_NBBY; /* Set the correct */
+ *(stream->top + len) = info.count; /* count. */
+
+ SetCommand(node->tree_info->tree_widget, LocalSetValues, NULL);
+ }
+ else
+ SetMessage(global_screen_data.info_label,
+ res_labels[20]);
+
+ XrmDestroyDatabase(info.database);
+}
+
+/* Function Name: ObtainResource
+ * Description: Obtain the current resource from the running application.
+ * Arguments: node_ptr - a pointer to the node containing
+ * the current resouce box.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+ObtainResource(node_ptr)
+XtPointer node_ptr;
+{
+ ProtocolStream * stream = &(global_client.stream);
+ ObtainResourcesInfo info;
+ WNode * node = (WNode *) node_ptr;
+ char * value;
+ Arg args[1];
+
+ info.name = GetResourceName(node->resources->res_box);
+ info.class = "IGNORE_ME"; /* Not currently used. */
+ info.stream = stream;
+ info.count = 1;
+
+ XtSetArg(args[0], XtNlabel, &value);
+ XtGetValues(node->resources->res_box->res_label, args, ONE);
+
+ info.database = NULL;
+ XrmPutLineResource(&(info.database), value);
+
+ _XEditResResetStream(stream);
+ _XEditResPutString8(stream, info.name); /* insert name */
+
+ /*
+ * Insert the widget count, always 1
+ */
+
+ _XEditResPut16(stream, 1);
+
+ /*CreateGetValuesCommand(node, (XtPointer)&info); Inserts widget */
+
+ /* Insert widget */
+ _XEditResPut16(stream, 1);
+ _XEditResPut32(stream, node->id);
+
+ SetCommand(node->tree_info->tree_widget, LocalGetValues, NULL);
+}
+
+/* Function Name: CreateSetValuesCommand
+ * Description: Creates the SetValues command if this widget
+ * matches the resource string in the database.
+ * Arguments: node - the current node.
+ * info_ptr - the pointer to the apply info.
+ * Returns: none
+ */
+
+static void
+CreateSetValuesCommand(node, info_ptr)
+WNode * node;
+XtPointer info_ptr;
+{
+ ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
+ XrmNameList name_quarks;
+ XrmClassList class_quarks;
+ char ** names, **classes;
+
+ GetNamesAndClasses(node, &names, &classes);
+ name_quarks = (XrmNameList) Quarkify(names, info->name);
+ class_quarks = (XrmNameList) Quarkify(classes, info->class);
+
+ if (CheckDatabase(info->database, name_quarks, class_quarks)) {
+ InsertWidgetFromNode(info->stream, node);
+ info->count++;
+ }
+
+ XtFree((char *)names);
+ XtFree((char *)classes);
+ XtFree((char *)name_quarks);
+ XtFree((char *)class_quarks);
+}
+
+/* Function Name: CreateGetValuesCommand
+ * Description: Creates the GetValues command.
+ * Arguments: node - the current node.
+ * info_ptr - the pointer to the apply info.
+ * Returns: none
+ */
+
+/*****
+
+static void
+CreateGetValuesCommand(node, info_ptr)
+WNode * node;
+XtPointer info_ptr;
+{
+ ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
+ XrmNameList name_quarks;
+ XrmClassList class_quarks;
+ char ** names, **classes;
+
+ GetNamesAndClasses(node, &names, &classes);
+ name_quarks = (XrmNameList) Quarkify(names, info->name);
+ class_quarks = (XrmNameList) Quarkify(classes, info->class);
+
+ if (CheckDatabase(info->database, name_quarks, class_quarks)) {
+ InsertWidgetFromNode(info->stream, node);
+ info->count++;
+ }
+
+ XtFree((char *)names);
+ XtFree((char *)classes);
+ XtFree((char *)name_quarks);
+ XtFree((char *)class_quarks);
+}
+
+*****/
+
+/* Function Name: ActivateResourceWidgets
+ * Description: Activates all widgets that match this resource.
+ * Arguments: w - UNUSED.
+ * node_ptr - the node that owns this resource box.
+ * junk - UNUSED.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+ActivateResourceWidgets(w, node_ptr, junk)
+Widget w;
+XtPointer node_ptr, junk;
+{
+ WNode * node = (WNode *) node_ptr;
+ ApplyResourcesInfo info;
+ char * line;
+ Arg args[1];
+
+ info.name = GetResourceName(node->resources->res_box);
+ info.class = "IGNORE_ME"; /* Not currently used. */
+
+ /*
+ * Unused fields.
+ */
+
+ info.count = 0;
+ info.stream = NULL;
+
+ XtSetArg(args[0], XtNlabel, &line);
+ XtGetValues(node->resources->res_box->res_label, args, ONE);
+
+ info.database = NULL;
+ XrmPutLineResource(&(info.database), line);
+
+
+ ExecuteOverAllNodes(node->tree_info->top_node,
+ SetOnlyMatchingWidgets, (XtPointer) &info);
+
+ XrmDestroyDatabase(info.database);
+}
+
+/* Function Name: SetOnlyMatchingWidgets
+ * Description: Activates all widgets in the tree that match this
+ * resource specifiction.
+ * Arguments: node - the current node.
+ * info_ptr - the pointer to the apply info.
+ * Returns: none
+ */
+
+static void
+SetOnlyMatchingWidgets(node, info_ptr)
+WNode * node;
+XtPointer info_ptr;
+{
+ ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
+ XrmNameList name_quarks;
+ XrmClassList class_quarks;
+ char ** names, **classes;
+ Boolean state;
+ Arg args[1];
+
+ GetNamesAndClasses(node, &names, &classes);
+ name_quarks = (XrmNameList) Quarkify(names, info->name);
+ class_quarks = (XrmNameList) Quarkify(classes, info->class);
+
+ state = CheckDatabase(info->database, name_quarks, class_quarks);
+
+ XtSetArg(args[0], XtNstate, state);
+ XtSetValues(node->widget, args, ONE);
+ TreeToggle(node->widget, (XtPointer) node, (XtPointer)(long) state);
+
+ XtFree((char *)names);
+ XtFree((char *)classes);
+ XtFree((char *)name_quarks);
+ XtFree((char *)class_quarks);
+}
diff --git a/setvalues.c b/setvalues.c
new file mode 100644
index 0000000..602d639
--- /dev/null
+++ b/setvalues.c
@@ -0,0 +1,122 @@
+/*
+ * $Xorg: setvalues.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Chris D. Peterson, MIT X Consortium
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xresource.h>
+
+#include <stdio.h>
+
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xos.h>
+#include "editresP.h"
+
+extern WNode * FindNode();
+extern void AddString();
+
+#define RESOURCE_NAME ("name")
+#define RESOURCE_CLASS ("Class")
+
+/* Function Name: PrintSetValuesError
+ * Description: Allow the SetValues error to be printed.
+ * Arguments: event - the set values call that caused this event.
+ * Returns: str - a string contining the errors.
+ */
+
+char *
+PrintSetValuesError(event)
+Event * event;
+{
+ char * errors = NULL;
+ WNode * node;
+ int i;
+ SetValuesEvent * sv_event = (SetValuesEvent *) event;
+ char buf[BUFSIZ];
+
+ if (sv_event->num_entries == 0)
+ return(XtNewString("SetValues was Successful."));
+
+ for (i = 0 ; i < (int)sv_event->num_entries ; i++) {
+ node = FindNode(global_tree_info->top_node,
+ sv_event->info[i].widgets.ids,
+ sv_event->info[i].widgets.num_widgets);
+
+ if (node == NULL) {
+ sprintf(buf, "Editres Internal Error: Unable to FindNode.\n");
+ AddString(&errors, buf);
+ continue;
+ }
+
+ sprintf(buf, "%s(0x%lx) - %s\n", node->name, node->id,
+ sv_event->info[i].message);
+ AddString(&errors, buf);
+ }
+ return(errors);
+}
+
+/* Function Name: GetResourceValueForSetValues(node);
+ * Description: Returns the value that should be sent to SetValues.
+ * Arguments: node - the node which contains the resource box.
+ * Returns: value - allocated value.
+ */
+
+char *
+GetResourceValueForSetValues(node, size)
+WNode * node;
+unsigned short * size;
+{
+ Arg args[1];
+ char *ptr, *temp;
+ XrmDatabase db = NULL;
+ XrmValue value;
+
+ XtSetArg(args[0], XtNstring, &ptr);
+ XtGetValues(node->resources->res_box->value_wid, args, ONE);
+
+ /*
+ * This makes sure that exactly the same thing happens during a set
+ * values, that would happend of we were to insert this value into
+ * the resource database.
+ */
+
+ temp = XtMalloc(sizeof(char) * (strlen(ptr) + strlen(RESOURCE_NAME) + 2));
+ sprintf(temp, "%s:%s", RESOURCE_NAME, ptr);
+ XrmPutLineResource(&db, temp);
+ XtFree(temp);
+
+ XrmGetResource(db, RESOURCE_NAME, RESOURCE_CLASS, &temp, &value);
+
+ ptr = XtMalloc(sizeof(char) * value.size);
+ memmove( ptr, value.addr, value.size);
+ XrmDestroyDatabase(db);
+
+ *size = (unsigned short) value.size;
+ return(ptr);
+}
diff --git a/svpopup.c b/svpopup.c
new file mode 100644
index 0000000..cd0e504
--- /dev/null
+++ b/svpopup.c
@@ -0,0 +1,336 @@
+/*
+ * $Xorg: svpopup.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Chris D. Peterson, MIT X Consortium
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h> /* Get standard string definations. */
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#include <X11/Shell.h>
+
+#include "editresP.h"
+
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Command.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Label.h>
+
+#include <stdio.h>
+
+#ifdef XKB
+#include <X11/extensions/XKBbells.h>
+#endif
+
+extern void SetMessage(), SetCommand(), InsertWidgetFromNode();
+extern void GetAllStrings(), PopupCentered();
+
+static void _SetField(), CreateSetValuesPopup();
+static void DoSetValues(), CancelSetValues();
+
+/* Function Name: PopupSetValues
+ * Description: This function pops up the setvalues dialog
+ * Arguments: parent - the parent of the setvalues popup.
+ * event - the event that caused this popup, or NULL.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+PopupSetValues(parent, event)
+Widget parent;
+XEvent * event;
+{
+ Arg args[1];
+
+ if (global_tree_info == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[17]);
+ return;
+ }
+
+/*
+ * Check and possibly create the popup.
+ */
+
+ if (global_screen_data.set_values_popup == NULL)
+ CreateSetValuesPopup(parent, &global_screen_data);
+
+/*
+ * Clear out the old strings, and set the active widget to the name widget.
+ */
+
+ XtSetArg(args[0], XtNstring, "");
+ XtSetValues(global_screen_data.res_text, args, ONE);
+ XtSetValues(global_screen_data.val_text, args, ONE);
+
+ _SetField(global_screen_data.res_text, global_screen_data.val_text);
+
+/*
+ * Pop it up.
+ */
+
+ PopupCentered(event, global_screen_data.set_values_popup, XtGrabNone);
+}
+
+/* Function Name: ModifySVEntry
+ * Description: Action routine that can be bound to the set values
+ * dialog box's Text Widget that will send input to the
+ * field specified.
+ * Arguments: (Standard Action Routine args)
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+ModifySVEntry(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ Widget new, old;
+ char msg[BUFSIZ];
+
+ if (*num_params != 1) {
+ strcpy(msg,
+ res_labels[21]);
+ SetMessage(global_screen_data.info_label, msg);
+ return;
+ }
+
+ switch (params[0][0]) {
+ case 'r':
+ case 'R':
+ new = global_screen_data.res_text;
+ old = global_screen_data.val_text;
+ break;
+ case 'v':
+ case 'V':
+ new = global_screen_data.val_text;
+ old = global_screen_data.res_text;
+ break;
+ default:
+ sprintf(msg, res_labels[22]);
+ SetMessage(global_screen_data.info_label, msg);
+ return;
+ }
+
+ _SetField(new, old);
+}
+
+/************************************************************
+ *
+ * Private Functions
+ *
+ ************************************************************/
+
+/* Function Name: _SetField
+ * Description: Sets the current text entry field.
+ * Arguments: new, old - new and old text fields.
+ * Returns: none
+ */
+
+static void
+_SetField(new, old)
+Widget new, old;
+{
+ Arg args[2];
+ Pixel new_border, old_border, old_bg;
+
+ if (!XtIsSensitive(new)) {
+#if XKB
+ /* Don't set field to an inactive Widget. */
+ XkbStdBell(XtDisplay(old), XtWindow(new), 0, XkbBI_InvalidLocation);
+#else
+ XBell(XtDisplay(old), 0); /* Don't set field to an inactive Widget. */
+#endif
+ return;
+ }
+
+ XtSetKeyboardFocus(XtParent(new), new);
+
+ XtSetArg(args[0], XtNborderColor, &old_border);
+ XtSetArg(args[1], XtNbackground, &old_bg);
+ XtGetValues(new, args, TWO);
+
+ XtSetArg(args[0], XtNborderColor, &new_border);
+ XtGetValues(old, args, ONE);
+
+ if (old_border != old_bg) /* Colors are already correct, return. */
+ return;
+
+ XtSetArg(args[0], XtNborderColor, old_border);
+ XtSetValues(old, args, ONE);
+
+ XtSetArg(args[0], XtNborderColor, new_border);
+ XtSetValues(new, args, ONE);
+}
+
+/* Function Name: CreateSetValuesPopup
+ * Description: Creates the setvalues popup.
+ * Arguments: parent - the parent of the popup.
+ * scr_data - the data about this screen.
+ * Returns: the set values popup.
+ */
+
+static void
+CreateSetValuesPopup(parent, scr_data)
+Widget parent;
+ScreenData * scr_data;
+{
+ Widget form, cancel, do_it, label;
+ Widget res_label;
+ Arg args[10];
+ Cardinal num_args;
+
+ scr_data->set_values_popup = XtCreatePopupShell("setValuesPopup",
+ transientShellWidgetClass,
+ parent, NULL, ZERO);
+
+ form = XtCreateManagedWidget("form", formWidgetClass,
+ scr_data->set_values_popup, NULL, ZERO);
+
+ num_args = 0;
+ label = XtCreateManagedWidget("label", labelWidgetClass,
+ form, args, num_args);
+
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, label); num_args++;
+ res_label = XtCreateManagedWidget("resourceLabel", labelWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, label); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, res_label); num_args++;
+ scr_data->res_text = XtCreateManagedWidget("resourceText",
+ asciiTextWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, scr_data->res_text); num_args++;
+ (void) XtCreateManagedWidget("valueLabel", labelWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, res_label); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, scr_data->res_text); num_args++;
+ scr_data->val_text = XtCreateManagedWidget("valueText",
+ asciiTextWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, scr_data->val_text); num_args++;
+ do_it = XtCreateManagedWidget("setValues", commandWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, scr_data->val_text); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, do_it); num_args++;
+ cancel = XtCreateManagedWidget("cancel", commandWidgetClass,
+ form, args, num_args);
+
+ XtAddCallback(do_it, XtNcallback, DoSetValues, NULL);
+ XtAddCallback(cancel, XtNcallback, CancelSetValues, NULL);
+
+/*
+ * Initialize the text entry fields.
+ */
+
+ {
+ Pixel color;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNbackground, &color); num_args++;
+ XtGetValues(scr_data->val_text, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNborderColor, color); num_args++;
+ XtSetValues(scr_data->val_text, args, num_args);
+
+ XtSetKeyboardFocus(form, scr_data->res_text);
+ }
+}
+
+/* Function Name: DoSetValues
+ * Description: Performs a SetValues.
+ * Arguments: w - the widget that called this.
+ * junk, garbage - ** UNUSED **.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+DoSetValues(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ ProtocolStream * stream = &(global_client.stream);
+ char *res_name, *res_value;
+ Arg args[1];
+ Cardinal i;
+
+ if (global_tree_info->num_nodes == 0) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[23]);
+ return;
+ }
+
+ XtSetArg(args[0], XtNstring, &res_name);
+ XtGetValues(global_screen_data.res_text, args, ONE);
+
+ XtSetArg(args[0], XtNstring, &res_value);
+ XtGetValues(global_screen_data.val_text, args, ONE);
+
+ _XEditResResetStream(stream);
+ _XEditResPutString8(stream, res_name);
+ _XEditResPutString8(stream, XtRString);
+ _XEditResPutString8(stream, res_value);
+ _XEditResPut16(stream, global_tree_info->num_nodes);
+
+ for (i = 0; i < global_tree_info->num_nodes; i++)
+ InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
+
+ SetCommand(w, LocalSetValues, NULL);
+}
+
+/* Function Name: CancelSetValues
+ * Description: Pops down the setvalues popup.
+ * Arguments: w - any grandchild of the popup.
+ * junk, garbage - ** UNUSED **.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+CancelSetValues(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ XtPopdown(XtParent(XtParent(w)));
+}
diff --git a/utils.c b/utils.c
new file mode 100644
index 0000000..bcb9a1b
--- /dev/null
+++ b/utils.c
@@ -0,0 +1,915 @@
+/*
+ * $Xorg: utils.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Shell.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Dialog.h>
+
+#include <stdio.h>
+
+#include "editresP.h"
+
+static WidgetResources * ParseResources();
+static int CompareResourceEntries();
+static void FreeResources(), AddResource();
+static WNode * FindWidgetFromWindowGivenNode();
+
+void CreateResourceBox();
+
+extern void PopupCentered(), PerformTreeToFileDump();
+
+/* Function Name: SetMessage(w, str)
+ * Description: shows the message to the user.
+ * Arguments: w - a label widget to show the message in.
+ * str - the string to show.
+ * Returns: none.
+ */
+
+void
+SetMessage(w, str)
+Widget w;
+char * str;
+{
+ Arg args[1];
+
+ XtSetArg(args[0], XtNlabel, str);
+ XtSetValues(w, args, ONE);
+}
+
+/* Function Name: GetAllStrings
+ * Description: Returns a list of strings that have been borken up by
+ * the character specified.
+ * Arguments: in - the string to parse.
+ * sep - the separator character.
+ * out - the strings to send out.
+ * num - the number of strings in out.
+ * Returns: none
+ */
+
+void
+GetAllStrings(in, sep, out, num)
+char *in, sep, ***out;
+int * num;
+{
+ int size, i;
+ char * ptr;
+
+ if (*in == sep) /* jump over first char if it is the sep. */
+ in++;
+
+ /*
+ * count the number of strings.
+ */
+
+ for (*num = 1, ptr = in; (ptr = strchr(ptr, sep)) != NULL; (*num)++)
+ ptr++;
+
+/*
+ * Create Enough space for pointers and string.
+ */
+
+ size = (sizeof(char *) * *num) + (sizeof(char) * (strlen(in) + 1));
+ *out = (char **) XtMalloc( (Cardinal) size);
+
+ ptr = (char *) (*out + *num);
+ strcpy(ptr, in);
+
+/*
+ * Change all `sep' characters to '\0' and stuff the pointer into
+ * the next pointer slot.
+ */
+
+ i = 1;
+ (*out)[0] = ptr;
+ while (TRUE) {
+ if ((ptr = strchr(ptr, sep)) == NULL)
+ break;
+
+ *ptr++ = '\0';
+ (*out)[i++] = ptr;
+ }
+
+/*
+ * If last string is empty then strip it off.
+ */
+
+ if ( *((*out)[i - 1]) == '\0' )
+ (*num)--;
+}
+
+/* Function Name: AddString
+ * Description: Mallocs and strcats the string onto the end of
+ * the given string.
+ * Arguments: str - string to add on to.
+ * add - string to add.
+ * Returns: none.
+ */
+
+void
+AddString(str, add)
+char ** str, *add;
+{
+ int len_str, len_add;
+ char * ptr;
+
+ len_str = ((*str) ? strlen(*str) : 0);
+ len_add = strlen(add);
+
+ *str = XtRealloc(*str, sizeof(char) * (len_str + len_add + 1));
+ ptr = *str + len_str;
+ strcpy(ptr, add);
+}
+
+/* Function Name: FindNode
+ * Description: Finds a node give the top node, and a node id number.
+ * Arguments: top_node - the top node.
+ * id - the node id.
+ * Returns: node.
+ */
+
+WNode *
+FindNode(top_node, ids, number)
+WNode *top_node;
+unsigned long * ids;
+Cardinal number;
+{
+ int i, j;
+ WNode *node;
+
+ if (top_node == NULL)
+ return(NULL);
+
+ if (ids[0] != top_node->id)
+ return(NULL);
+
+ for (node = top_node, i = 1 ; i < number; i++) {
+ Boolean found_it = FALSE;
+
+ for (j = 0; j < node->num_children; j++) {
+ if (node->children[j]->id == ids[i]) {
+ node = node->children[j];
+ found_it = TRUE;
+ break;
+ }
+ }
+ if (!found_it)
+ return(NULL);
+ }
+ return(node);
+}
+
+/* Function Name: FindWidgetFromWindow
+ * Description: finds a widget in the current tree given its window id.
+ * Arguments: tree_info - information about this tree.
+ * win - window to search for.
+ * Returns: node - the node corrosponding to this widget.
+ */
+
+WNode *
+FindWidgetFromWindow(tree_info, win)
+TreeInfo * tree_info;
+Window win;
+{
+ if (tree_info == NULL)
+ return(NULL);
+
+ return(FindWidgetFromWindowGivenNode(tree_info->top_node, win));
+}
+
+/* Function Name: FindWidgetFromWindowGivenNode
+ * Description: finds a widget in the current tree given its window id.
+ * Arguments: node - current node.
+ * win - window to search for.
+ * Returns: node - the node corrosponding to this widget.
+ */
+
+static WNode *
+FindWidgetFromWindowGivenNode(node, win)
+WNode * node;
+Window win;
+{
+ int i;
+ WNode * ret_node;
+
+ if (node->window == win)
+ return(node);
+
+ for (i = 0; i < node->num_children; i++) {
+ ret_node = FindWidgetFromWindowGivenNode(node->children[i], win);
+ if (ret_node != NULL)
+ return(ret_node);
+ }
+ return(NULL);
+}
+
+/* Function Name: HandleXErrors
+ * Description: Handles error codes from the server.
+ * Arguments: display - the display.
+ * error - error information.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+int
+HandleXErrors(display, error)
+Display * display;
+XErrorEvent * error;
+{
+ if (error->serial != global_serial_num) {
+ (*global_old_error_handler) (display, error);
+ return(0);
+ }
+
+ if (error->error_code == BadWindow)
+ global_error_code = NO_WINDOW;
+ else {
+ if (XmuPrintDefaultErrorMessage(display, error, stderr) != 0)
+ exit(1);
+ }
+ return(0);
+}
+
+/* Function Name: _DumpTreeToFile
+ * Description: Dumps the widget tree to a file
+ * Arguments: w - a random widget in the application on the
+ * currently active display
+ * tree_ptr - pointer to the widget tree info.
+ * filename - name of the file.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+
+void
+_DumpTreeToFile(w, tree_ptr, filename)
+Widget w;
+XtPointer tree_ptr;
+char * filename;
+{
+ TreeInfo * tree_info = (TreeInfo *) tree_ptr;
+ FILE * fp;
+
+ if (tree_info == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[17]);
+ return;
+ }
+
+ if ( (fp = fopen(filename, "w")) == NULL ) {
+ char buf[BUFSIZ];
+
+ sprintf(buf, res_labels[24], filename);
+ SetMessage(global_screen_data.info_label, buf);
+ return;
+ }
+
+ PerformTreeToFileDump(tree_info->top_node, 0, fp);
+ fclose(fp);
+}
+
+/************************************************************
+ *
+ * The file dialog boxes are handled with this code.
+ *
+ * It automatically calls the function specified when the
+ * user selects okay, or hits <CR>.
+ *
+ * A translation is required in the app-defaults file.
+ *
+ ************************************************************/
+
+/* Function Name: _PopupFileDialog
+ * Description: Puts up a dialog box to get the filename.
+ * Arguments: str - message.
+ * default_value - the default value of the filename;
+ * func - function to call when filename has been entered.
+ * data - generic data to pass to func.
+ * Returns: none
+ */
+
+static XContext file_dialog_context = None;
+
+typedef struct _FileDialogInfo {
+ void (*func)();
+ XtPointer data;
+} FileDialogInfo;
+
+void
+_PopupFileDialog(w, str, default_value, func, data)
+Widget w;
+String str, default_value;
+void (*func)();
+XtPointer data;
+{
+ FileDialogInfo * file_info;
+ Widget shell, dialog;
+ Arg args[2];
+ Cardinal num_args;
+ void _PopdownFileDialog();
+
+ if (file_dialog_context == None)
+ file_dialog_context = XUniqueContext();
+
+ shell = XtCreatePopupShell("fileDialog", transientShellWidgetClass, w,
+ NULL, ZERO);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, str); num_args++;
+ XtSetArg(args[num_args], XtNvalue, default_value); num_args++;
+ dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
+ shell, args, num_args);
+
+ file_info = XtNew(FileDialogInfo);
+
+ file_info->func = func;
+ file_info->data = data;
+
+ if (XSaveContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
+ (XPointer) file_info) != 0) {
+ SetMessage(global_screen_data.info_label,
+ "Error while trying to save Context\nAborting file dialog popup.");
+ XtDestroyWidget(shell);
+ return;
+ }
+
+ XawDialogAddButton(dialog, "okay", _PopdownFileDialog, (XtPointer) TRUE);
+ XawDialogAddButton(dialog, "cancel", _PopdownFileDialog,(XtPointer) FALSE);
+
+ PopupCentered(NULL, shell, XtGrabNone);
+}
+
+/* Function Name: PopupCentered
+ * Description: Pops up the window specified under the location passed
+ * in the event, or under the cursor.
+ * Arguments: event - the event that we should use.
+ * w - widget to popup.
+ * mode - mode to pop it up in.
+ * Returns: none
+ */
+
+void
+PopupCentered(event, w, mode)
+XEvent * event;
+Widget w;
+XtGrabKind mode;
+{
+ Boolean get_from_cursor = FALSE;
+ Arg args[3];
+ Cardinal num_args;
+ Dimension width, height, b_width;
+ int x, y, max_x, max_y;
+
+ XtRealizeWidget(w);
+
+ if (event == NULL)
+ get_from_cursor = TRUE;
+ else {
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ x = event->xbutton.x_root;
+ y = event->xbutton.y_root;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ x = event->xkey.x_root;
+ y = event->xkey.y_root;
+ break;
+ default:
+ get_from_cursor = TRUE;
+ break;
+ }
+ }
+
+ if (get_from_cursor) {
+ Window root, child;
+ int win_x, win_y;
+ unsigned int mask;
+
+ XQueryPointer(XtDisplay(w), XtWindow(w),
+ &root, &child, &x, &y, &win_x, &win_y, &mask);
+ }
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &width); num_args++;
+ XtSetArg(args[num_args], XtNheight, &height); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
+ XtGetValues(w, args, num_args);
+
+ width += 2 * b_width;
+ height += 2 * b_width;
+
+ x -= ((int) width/2);
+ if (x < 0)
+ x = 0;
+ if ( x > (max_x = (int) (XtScreen(w)->width - width)) )
+ x = max_x;
+
+ y -= ( (Position) height/2 );
+ if (y < 0)
+ y = 0;
+ if ( y > (max_y = (int) (XtScreen(w)->height - height)) )
+ y = max_y;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNx, x); num_args++;
+ XtSetArg(args[num_args], XtNy, y); num_args++;
+ XtSetValues(w, args, num_args);
+
+ XtPopup(w, mode);
+}
+
+/* Function Name: _PopdownFileDialog
+ * Description: Destroys the file dialog, and calls the correct function.
+ * Arguments: w - a child of the dialog widget.
+ * client_data - TRUE if command was sucessful.
+ * junk - ** UNUSED **.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+
+void
+_PopdownFileDialog(w, client_data, junk)
+Widget w;
+XtPointer client_data, junk;
+{
+ Widget dialog = XtParent(w);
+ XPointer file_info_ptr;
+ FileDialogInfo * file_info;
+
+ if (XFindContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
+ &file_info_ptr) == XCNOENT) {
+ SetMessage(global_screen_data.info_label,
+ "Error while trying to find Context\nAborting...");
+ }
+
+ (void) XDeleteContext(XtDisplay(dialog), (Window)dialog,
+ file_dialog_context);
+
+ file_info = (FileDialogInfo *) file_info_ptr;
+
+ if ( ((Boolean)(long) client_data) == TRUE ) {
+ String filename = XawDialogGetValueString(dialog);
+
+ (*file_info->func)(w, file_info->data, filename); /* call handler */
+ }
+
+ XtFree( (XtPointer) file_info); /* Free data. */
+
+ XtPopdown(XtParent(dialog));
+ XtDestroyWidget(XtParent(dialog)); /* Remove file dialog. */
+}
+
+/************************************************************
+ *
+ * Functions for dealing with the Resource Box.
+ *
+ ************************************************************/
+
+/* Function Name: GetNamesAndClasses
+ * Description: Gets a list of names and classes for this widget.
+ * Arguments: node - this widget's node.
+ * names, classes - list of names and classes. ** RETURNED **
+ * Returns: none.
+ */
+
+void
+GetNamesAndClasses(node, names, classes)
+WNode * node;
+char *** names, ***classes;
+{
+ int i, total_widgets;
+ WNode * temp = node;
+
+ for (total_widgets = 1 ; temp->parent != NULL ;
+ total_widgets++, temp = temp->parent) {}
+
+ *names = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
+ *classes = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
+
+ (*names)[total_widgets] = (*classes)[total_widgets] = NULL;
+
+ for ( i = (total_widgets - 1); i >= 0 ; node = node->parent, i--) {
+ (*names)[i] = node->name;
+ (*classes)[i] = node->class;
+ }
+}
+
+/* Function Name: HandleGetResources
+ * Description: Gets the resources.
+ * Arguments: event - the information from the client.
+ * Returns: an error message to display.
+ */
+
+char *
+HandleGetResources(event)
+Event * event;
+{
+ GetResourcesEvent * get_event = (GetResourcesEvent *) event;
+ char buf[BUFSIZ], * errors = NULL;
+ int i;
+ WNode * node;
+
+ for (i = 0; i < (int)get_event->num_entries; i++) {
+ node = FindNode(global_tree_info->top_node,
+ get_event->info[i].widgets.ids,
+ get_event->info[i].widgets.num_widgets);
+
+ if (node == NULL) {
+ sprintf(buf, res_labels[16]);
+ AddString(&errors, buf);
+ continue;
+ }
+
+ if (node->resources != NULL)
+ FreeResources(node->resources);
+
+ if (!get_event->info[i].error) {
+ node->resources = ParseResources(get_event->info + i, &errors);
+ CreateResourceBox(node, &errors);
+ }
+ else {
+ AddString(&errors, get_event->info[i].message);
+ AddString(&errors, "\n");
+ }
+ }
+
+ return(errors);
+}
+
+/* Function Name: CreateResourceBox
+ * Description: Creates a resource box for the widget specified.
+ * Arguments: node - the node of the widget in question.
+ * errors - an error string.
+ * Returns: none.
+ */
+
+void
+CreateResourceBox(node, errors)
+WNode * node;
+char ** errors;
+{
+ void CreateResourceBoxWidgets();
+ WidgetResources * resources = node->resources;
+ char ** names, ** cons_names;
+ int i;
+
+ if (global_resource_box_up) {
+ AddString(errors, res_labels[34]);
+ return;
+ }
+ else
+ global_resource_box_up = TRUE;
+
+ if (resources->num_normal > 0) {
+ names = (char **) XtMalloc(sizeof(char *) *
+ (resources->num_normal + 1));
+ for (i = 0 ; i < resources->num_normal ; i++)
+ names[i] = resources->normal[i].name;
+ names[i] = NULL;
+ }
+ else
+ names = NULL;
+
+ if (resources->num_constraint > 0) {
+ cons_names = (char **) XtMalloc(sizeof(char *) *
+ (resources->num_constraint + 1));
+
+ for (i = 0 ; i < resources->num_constraint ; i++)
+ cons_names[i] = resources->constraint[i].name;
+ cons_names[i] = NULL;
+ }
+ else
+ cons_names = NULL;
+
+ CreateResourceBoxWidgets(node, names, cons_names);
+}
+
+/* Function Name: ParseResources
+ * Description: Parses the resource values returned from the client
+ * into a resources structure.
+ * Arguments: info - info about a widget's resources.
+ * error - where to place error info.
+ * Returns: The resource information.
+ */
+
+static WidgetResources *
+ParseResources(info, error)
+GetResourcesInfo * info;
+char **error;
+{
+ WidgetResources * resources;
+ WidgetResourceInfo * normal;
+ int i;
+
+ resources = (WidgetResources *) XtMalloc(sizeof(WidgetResources));
+
+ /*
+ * Allocate enough space for both the normal and constraint resources,
+ * then add the normal resources from the top, and the constraint resources
+ * from the bottom. This assures that enough memory is allocated, and
+ * that there is no overlap.
+ */
+
+ resources->normal = (WidgetResourceInfo *)
+ XtMalloc(sizeof(WidgetResourceInfo) * info->num_resources);
+
+ normal = resources->normal;
+ resources->constraint = resources->normal + info->num_resources - 1;
+
+ resources->num_constraint = resources->num_normal = 0;
+
+ for (i = 0; i < (int)info->num_resources; i++) {
+ switch((int) info->res_info[i].res_type) {
+ case NormalResource:
+ resources->num_normal++;
+ AddResource(info->res_info + i, normal++);
+ break;
+ case ConstraintResource:
+ resources->num_constraint++;
+ AddResource(info->res_info + i, resources->constraint--);
+ break;
+ default:
+ {
+ char buf[BUFSIZ];
+ sprintf(buf, "Unknown resource type %d\n",
+ info->res_info[i].res_type);
+ AddString(error, buf);
+ }
+ break;
+ }
+ }
+
+ /*
+ * Sort the resources alphabetically.
+ */
+
+ qsort(resources->normal, resources->num_normal,
+ sizeof(WidgetResourceInfo), CompareResourceEntries);
+
+ if (resources->num_constraint > 0) {
+ resources->constraint++;
+ qsort(resources->constraint, resources->num_constraint,
+ sizeof(WidgetResourceInfo), CompareResourceEntries);
+ }
+ else
+ resources->constraint = NULL;
+
+ return(resources);
+}
+
+/* Function Name: CompareResourceEntries
+ * Description: Compares two resource entries.
+ * Arguments: e1, e2 - the entries to compare.
+ * Returns: an integer >, < or = 0.
+ */
+
+static int
+CompareResourceEntries(e1, e2)
+WidgetResourceInfo *e1, *e2;
+{
+ return (strcmp(e1->name, e2->name));
+}
+
+/* Function Name: AddResource
+ * Description: Parses the resource string a stuffs in individual
+ * parts into the resource info struct.
+ * Arguments: res_info - the resource info from the event.
+ * resource - location to stuff the resource into.
+ * Returns: none.
+ */
+
+static void
+AddResource(res_info, resource)
+ResourceInfo * res_info;
+WidgetResourceInfo * resource;
+{
+ resource->name = res_info->name;
+ res_info->name = NULL; /* Keeps it from being deallocated. */
+ resource->class = res_info->class;
+ res_info->class = NULL; /* Keeps it from being deallocated. */
+ resource->type = res_info->type;
+ res_info->type = NULL; /* Keeps it from being deallocated. */
+}
+
+
+/* Function Name: FreeResources
+ * Description: frees the resource inforation.
+ * Arguments: resources.
+ * Returns: none.
+ */
+
+static void
+FreeResources(resources)
+WidgetResources * resources;
+{
+ int i;
+
+ if (resources->num_normal > 0) {
+ for (i = 0; i < resources->num_normal; i++) {
+ XtFree(resources->normal[i].name);
+ XtFree(resources->normal[i].class);
+ XtFree(resources->normal[i].type);
+ }
+ XFree((char *)resources->normal);
+ }
+
+ if (resources->num_constraint > 0) {
+ for (i = 0; i < resources->num_constraint; i++) {
+ XtFree(resources->constraint[i].name);
+ XtFree(resources->constraint[i].class);
+ XtFree(resources->constraint[i].type);
+ }
+ XFree((char *)resources->constraint);
+ }
+
+ XFree((char *)resources);
+}
+
+
+/* Function Name: CheckDatabase
+ * Description: Checks to see if the node is in the database.
+ * Arguments: db - the db to check
+ * names, clases - names and clases, represented as quarks.
+ * Returns: True if this entry is found.
+ */
+
+Boolean
+CheckDatabase(db, names, classes)
+XrmDatabase db;
+XrmQuarkList names, classes;
+{
+ XrmRepresentation junk;
+ XrmValue garbage;
+
+ return(XrmQGetResource(db, names, classes, &junk, &garbage));
+}
+
+/* Function Name: Quarkify
+ * Description: Quarkifies the string list specifed.
+ * Arguments: list - list of strings to quarkify
+ * ptr - an additional string to quarkify.
+ * Returns: none.
+ */
+
+XrmQuarkList
+Quarkify(list, ptr)
+char ** list;
+char * ptr;
+{
+ int i;
+ char ** tlist;
+ XrmQuarkList quarks, tquarks;
+
+ for (i = 0, tlist = list; *tlist != NULL; tlist++, i++) {}
+ if (ptr != NULL)
+ i++;
+ i++; /* leave space for NULLQUARK */
+
+ quarks = (XrmQuarkList) XtMalloc(sizeof(XrmQuark) * i);
+
+ for (tlist = list, tquarks = quarks; *tlist != NULL; tlist++, tquarks++)
+ *tquarks = XrmStringToQuark(*tlist);
+
+ if (ptr != NULL)
+ *tquarks++ = XrmStringToQuark(ptr);
+
+ *tquarks = NULLQUARK;
+ return(quarks);
+}
+
+/* Function Name: ExecuteOverAllNodes
+ * Description: Executes the given function over all nodes.
+ * Arguments: top_node - top node of the tree.
+ * func - the function to execute.
+ * data - a data pointer to pass to the function.
+ * Returns: none
+ */
+
+void
+ExecuteOverAllNodes(top_node, func, data)
+WNode * top_node;
+void (*func)();
+XtPointer data;
+{
+ int i;
+
+ (*func)(top_node, data);
+
+ for (i = 0; i < top_node->num_children; i++)
+ ExecuteOverAllNodes(top_node->children[i], func, data);
+}
+
+/* Function Name: InsertWidgetFromNode
+ * Description: Inserts the widget info for this widget represented
+ * by this node.
+ * Arguments: stream - the stream to insert it info into.
+ * none - the widget node to insert.
+ * Returns: none
+ */
+
+void
+InsertWidgetFromNode(stream, node)
+ProtocolStream * stream;
+WNode * node;
+{
+ WNode *temp;
+ unsigned long * widget_list;
+ register int i, num_widgets;
+
+ for (temp = node, i = 0; temp != 0; temp = temp->parent, i++) {}
+
+ num_widgets = i;
+ widget_list = (unsigned long *)
+ XtMalloc(sizeof(unsigned long) * num_widgets);
+
+ /*
+ * Put the widgets into the list.
+ * Make sure that they are inserted in the list from parent -> child.
+ */
+
+ for (i--, temp = node; temp != 0; temp = temp->parent, i--)
+ widget_list[i] = temp->id;
+
+ _XEditResPut16(stream, num_widgets); /* insert number of widgets. */
+ for (i = 0; i < num_widgets; i++) /* insert Widgets themselves. */
+ _XEditResPut32(stream, widget_list[i]);
+
+ XtFree((char *)widget_list);
+}
+
+/* Function Name: GetFailureMesssage
+ * Description: returns the message returned from a failed request.
+ * Arguments: stream - the protocol stream containing the message.
+ * Returns: message to show.
+ */
+
+char *
+GetFailureMessage(stream)
+ProtocolStream * stream;
+{
+ char * return_str;
+
+ if (_XEditResGetString8(stream, &return_str))
+ return(return_str);
+
+ return(XtNewString(res_labels[35]));
+}
+
+/* Function Name: ProtocolFailure
+ * Description: Gets the version of the protocol the client is
+ * willing to speak.
+ * Arguments: stream - the protocol stream containing the message.
+ * Returns: message to show.
+ */
+
+char *
+ProtocolFailure(stream)
+ProtocolStream * stream;
+{
+ char buf[BUFSIZ];
+ unsigned char version;
+ char* old_version_string;
+
+ if (!_XEditResGet8(stream, &version))
+ return(XtNewString(res_labels[35]));
+
+ switch ((int)version) {
+ case PROTOCOL_VERSION_ONE_POINT_ZERO: old_version_string = "1.0"; break;
+ default: old_version_string = "1.0";
+ }
+
+ sprintf(buf, res_labels[36],
+ CURRENT_PROTOCOL_VERSION_STRING, old_version_string);
+ return(XtNewString(buf));
+}
+
diff --git a/widgets.c b/widgets.c
new file mode 100644
index 0000000..2342e6a
--- /dev/null
+++ b/widgets.c
@@ -0,0 +1,1037 @@
+/*
+ * $Xorg: widgets.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+/*
+ * Code for creating all widgets used by EditRes.
+ */
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h> /* Get standard string definations. */
+
+#include <X11/Xaw/AsciiText.h>
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Label.h>
+#include <X11/Xaw/List.h>
+#include <X11/Xaw/MenuButton.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xaw/Panner.h>
+#include <X11/Xaw/Porthole.h>
+#include <X11/Xaw/SmeBSB.h>
+#include <X11/Xaw/SmeLine.h>
+#include <X11/Xaw/SimpleMenu.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/Tree.h>
+#include <X11/Xaw/Viewport.h>
+
+#include "editresP.h"
+
+
+
+/*
+ * functions.
+ */
+
+static void CreateResourceNameForm(), SetToggleGroupLeaders(), CreateLists();
+static void CreateCommandMenu(), CreateTreeCommandMenu(), FreeClientData();
+static void FreeResBox(), CreateValueWidget(), PopupOnNode();
+static Widget CreateTopArea();
+static void MakeBoxLookNice();
+
+extern void GetResourceList(), AnyChosen(), SetResourceString();
+extern void PannerCallback(), PortholeCallback(), DumpTreeToFile();
+extern void Quit(), SendTree(), FlashActiveWidgets();
+extern void TreeSelect(), TreeRelabel(), TreeActivate(), FindWidget();
+extern void ResourceListCallback(), PopdownResBox(), SaveResource();
+extern void GetNamesAndClasses(), ApplyResource(), ActivateResourceWidgets();
+extern void ActivateWidgetsAndSetResourceString(), SetFile();
+
+extern void InitSetValues();
+
+
+
+/* Function Name: RebuildMenusAndLabel
+ * Description: Determins if the user has selected an application
+ * which uses a different toolkit. Xt is the default.
+ * If this is so, destroys and recreates the menus and
+ * information label at the top of the application.
+ * Arguments: toolkit - name of the toolkit.
+ * Returns: none.
+ */
+
+static Widget box = NULL;
+static Widget hPane = NULL;
+
+#define Offset(index) sizeof(String) * index
+
+#define res_entry(index, name, class) \
+ {name, class, XtRString, sizeof(String), \
+ Offset(index), XtRString, (XtPointer)NULL}
+
+static XtResource resources[] = {
+ res_entry(0, "label0", "Label0"),
+ res_entry(1, "label1", "Label1"),
+ res_entry(2, "label2", "Label2"),
+ res_entry(3, "label3", "Label3"),
+ res_entry(4, "label4", "Label4"),
+ res_entry(5, "label5", "Label5"),
+ res_entry(6, "label6", "Label6"),
+ res_entry(7, "label7", "Label7"),
+ res_entry(8, "label8", "Label8"),
+ res_entry(9, "label9", "Label9"),
+ res_entry(11, "label11", "Label11"),
+ res_entry(12, "label12", "Label12"),
+ res_entry(13, "label13", "Label13"),
+ res_entry(14, "label14", "Label14"),
+ res_entry(15, "label15", "Label15"),
+ res_entry(16, "label16", "Label16"),
+ res_entry(17, "label17", "Label17"),
+ res_entry(18, "label18", "Label18"),
+ res_entry(19, "label19", "Label19"),
+ res_entry(20, "label20", "Label20"),
+ res_entry(21, "label21", "Label21"),
+ res_entry(22, "label22", "Label22"),
+ res_entry(23, "label23", "Label23"),
+ res_entry(24, "label24", "Label24"),
+ res_entry(25, "label25", "Label25"),
+ res_entry(26, "label26", "Label26"),
+ res_entry(27, "label27", "Label27"),
+ res_entry(28, "label28", "Label28"),
+ res_entry(29, "label29", "Label29"),
+ res_entry(30, "label30", "Label30"),
+ res_entry(31, "label31", "Label31"),
+ res_entry(32, "label32", "Label32"),
+ res_entry(33, "label33", "Label33"),
+ res_entry(34, "label34", "Label34"),
+ res_entry(35, "label35", "Label35"),
+ res_entry(36, "label36", "Label36")
+};
+
+#undef res_entry
+
+#undef Offset
+
+void
+RebuildMenusAndLabel(toolkit)
+ String toolkit;
+{
+ if (strcmp(global_effective_toolkit, toolkit)) {
+ CreateCommandMenu(box, toolkit);
+ CreateTreeCommandMenu(box, toolkit);
+ XtDestroyWidget(global_screen_data.info_label);
+ global_screen_data.info_label = XtCreateManagedWidget(toolkit,
+ labelWidgetClass,
+ hPane, NULL, ZERO);
+ /* get the new toolkit label application resources for info_label */
+ XtGetApplicationResources(global_screen_data.info_label,
+ res_labels, resources,
+ XtNumber(resources), NULL, 0);
+
+ global_effective_toolkit = toolkit;
+ }
+}
+
+
+
+/* Function Name: BuildWidgetTree
+ * Description: Creates all widgets for Editres.
+ * Arguments: parent - the shell to put them into.
+ * Returns: none.
+ */
+
+void
+BuildWidgetTree(parent)
+Widget parent;
+{
+ Widget paned, porthole, panner;
+
+ paned = XtCreateManagedWidget("paned", panedWidgetClass, parent,
+ NULL, ZERO);
+
+ panner = CreateTopArea(paned);
+
+ porthole = XtCreateManagedWidget("porthole", portholeWidgetClass,
+ paned, NULL, ZERO);
+
+/*
+ * Allow the panner and porthole to talk to each other.
+ */
+
+ XtAddCallback(porthole,
+ XtNreportCallback, PortholeCallback, (XtPointer) panner);
+ XtAddCallback(panner,
+ XtNreportCallback, PannerCallback, (XtPointer) porthole);
+
+ global_tree_parent = porthole;
+}
+
+
+
+
+/* Function Name: CreateTopArea
+ * Description: Creates the top part of the display
+ * Arguments: parent - widget to put this menu bar into.
+ * Returns: none.
+ */
+
+
+static Widget
+CreateTopArea(parent)
+Widget parent;
+{
+ Widget panner;
+
+ box = XtCreateManagedWidget("box", boxWidgetClass, parent, NULL, ZERO);
+
+ CreateCommandMenu(box, "xt");
+ CreateTreeCommandMenu(box, "xt");
+
+ hPane = XtCreateManagedWidget("hPane",panedWidgetClass, parent, NULL,ZERO);
+
+ {
+ panner = XtCreateManagedWidget("panner", pannerWidgetClass,
+ hPane, NULL, ZERO);
+
+ global_screen_data.info_label = XtCreateManagedWidget("xt",
+ labelWidgetClass,
+ hPane, NULL,ZERO);
+
+ /* get the "xt label" application resources for info_label */
+ XtGetApplicationResources(global_screen_data.info_label,
+ res_labels, resources,
+ XtNumber(resources), NULL, 0);
+
+ }
+
+ return(panner);
+}
+
+
+
+/* Function Name: SetEntriesInsensitive
+ * Description: Make menu entries unusable.
+ * Arguments: entries - address of widget array.
+ * num - number of widgets.
+ * sensitive - whether to sensitize or desensitize.
+ * Returns: none.
+ */
+void
+SetEntriesSensitive(entries, num, sensitive)
+Widget *entries;
+int num;
+Boolean sensitive;
+{
+int i; for (i=0; i<num; i++) XtSetSensitive(entries[i], sensitive);
+}
+
+
+
+/* Function Name: CreateCommandMenu
+ * Description: Creates the command menu.
+ * Arguments: parent - widget to put this menu into.
+ * toolkit - name given to the SimpleMenu widget.
+ * Returns: none.
+ */
+
+static Widget cmenu = NULL, cbutton = NULL;
+/* at first most menu entries are insensitive */
+static Boolean CM_set_insensitive = True;
+Widget CM_entries[NUM_CM_ENTRIES];
+
+static void
+CreateCommandMenu(parent, toolkit)
+Widget parent;
+String toolkit;
+{
+ Arg args[1];
+
+ if (cmenu) { XtDestroyWidget(cmenu); CM_set_insensitive = False; }
+ else
+ cbutton = XtCreateManagedWidget("commands", menuButtonWidgetClass,
+ parent, NULL, ZERO);
+
+ /* set the menu name to the toolkit name */
+ XtSetArg(args[0], XtNmenuName, toolkit);
+ XtSetValues(cbutton, args, ONE);
+
+ cmenu = XtCreatePopupShell(toolkit, simpleMenuWidgetClass, cbutton,
+ NULL, ZERO);
+
+ CM_entries[0] = XtCreateManagedWidget("sendTree", smeBSBObjectClass,cmenu,
+ NULL, ZERO);
+ XtAddCallback(CM_entries[0], XtNcallback, SendTree, (XtPointer) TRUE);
+
+ CM_entries[1]=XtCreateManagedWidget("refreshTree",smeBSBObjectClass,cmenu,
+ NULL, ZERO);
+ XtAddCallback(CM_entries[1], XtNcallback, SendTree, (XtPointer) FALSE);
+
+ CM_entries[2] = XtCreateManagedWidget("dumpTreeToFile",
+ smeBSBObjectClass,cmenu,
+ NULL, ZERO);
+ XtAddCallback(CM_entries[2], XtNcallback, DumpTreeToFile, NULL);
+
+ CM_entries[3] = XtCreateManagedWidget("line", smeLineObjectClass, cmenu,
+ NULL, ZERO);
+ CM_entries[4]= XtCreateManagedWidget("getResourceList",
+ smeBSBObjectClass,cmenu,
+ NULL, ZERO);
+ XtAddCallback(CM_entries[4], XtNcallback, GetResourceList, NULL);
+
+ CM_entries[5] = XtCreateManagedWidget("setValues", smeBSBObjectClass,
+ cmenu,
+ NULL, ZERO);
+ XtAddCallback(CM_entries[5], XtNcallback, InitSetValues, NULL);
+
+ CM_entries[6] = XtCreateManagedWidget("line", smeLineObjectClass, cmenu,
+ NULL, ZERO);
+
+ CM_entries[7] = XtCreateManagedWidget("quit", smeBSBObjectClass, cmenu,
+ NULL, ZERO);
+ XtAddCallback(CM_entries[7], XtNcallback, Quit, NULL);
+
+ if (CM_set_insensitive)
+ SetEntriesSensitive(&CM_entries[CM_OFFSET], CM_NUM, False);
+}
+
+
+
+/* Function Name: CreateTreeCommandMenu
+ * Description: Creats the command menu.
+ * Arguments: parent - widget to put this menu into.
+ * Returns: none.
+ */
+
+#define SELECT 0
+#define ACTIVATE 1
+#define LABEL 2
+#define LINE 3
+#define FIND 4
+#define FLASH 5
+
+struct tree_ops_menu {
+ char * name;
+ int type;
+ XtPointer data;
+};
+
+static Widget tmenu = NULL, tbutton = NULL;
+/* at first most menu entries are insensitive */
+static Boolean TM_set_insensitive = True;
+Widget TM_entries[NUM_TM_ENTRIES];
+
+static void
+CreateTreeCommandMenu(parent, toolkit)
+Widget parent;
+String toolkit;
+{
+ int i, number;
+ static struct tree_ops_menu tree_menu[] = {
+ { "showClientWidget", FIND, (XtPointer) NULL },
+ { "selectAll", SELECT, (XtPointer) SelectAll },
+ { "unselectAll", SELECT, (XtPointer) SelectNone },
+ { "invertAll", SELECT, (XtPointer) SelectInvert },
+ { "line", LINE, (XtPointer) NULL },
+ { "selectChildren", SELECT, (XtPointer) SelectChildren },
+ { "selectParent", SELECT, (XtPointer) SelectParent },
+ { "selectDescendants", SELECT, (XtPointer) SelectDescendants },
+ { "selectAncestors", SELECT, (XtPointer) SelectAncestors },
+ { "line", LINE, (XtPointer) NULL },
+ { "showWidgetNames", LABEL, (XtPointer) NameLabel },
+ { "showClassNames", LABEL, (XtPointer) ClassLabel },
+ { "showWidgetIDs", LABEL, (XtPointer) IDLabel},
+ { "showWidgetWindows", LABEL, (XtPointer) WindowLabel },
+ { "line", LINE, (XtPointer) NULL },
+ { "flashActiveWidgets", FLASH, (XtPointer) NULL }
+ };
+ Arg args[1];
+
+ if (tmenu) { XtDestroyWidget(tmenu); TM_set_insensitive = False; }
+ else
+ tbutton = XtCreateManagedWidget("treeCommands", menuButtonWidgetClass,
+ parent, NULL, ZERO);
+
+ XtSetArg(args[0], XtNmenuName, toolkit);
+ XtSetValues(tbutton, args, ONE);
+
+ tmenu = XtCreatePopupShell(toolkit, simpleMenuWidgetClass, tbutton,
+ NULL, ZERO);
+
+ for ( i = 0, number = XtNumber(tree_menu) ; i < number ; i++) {
+ void (*func)();
+ WidgetClass class = smeBSBObjectClass;
+
+ switch (tree_menu[i].type) {
+ case SELECT:
+ func = TreeSelect;
+ break;
+ case LABEL:
+ func = TreeRelabel;
+ break;
+ case LINE:
+ func = NULL;
+ class = smeLineObjectClass;
+ break;
+ case FIND:
+ func = FindWidget;
+ break;
+ case FLASH:
+ func = FlashActiveWidgets;
+ break;
+ default:
+ continue;
+ }
+
+ TM_entries[i] = XtCreateManagedWidget(tree_menu[i].name, class, tmenu,
+ NULL, ZERO);
+ if (func != NULL)
+ XtAddCallback(TM_entries[i], XtNcallback, func,tree_menu[i].data);
+ }
+ if (TM_set_insensitive) SetEntriesSensitive(&TM_entries[TM_OFFSET],
+ TM_NUM, False);
+}
+
+
+
+static Pixmap old_pixmap;
+
+/* Function Name: PrepareToLayoutTree
+ * Description: prepares the Tree widget to be layed out.
+ * Arguments: tree - the Tree widget.
+ * Returns: none
+ */
+
+void
+PrepareToLayoutTree(tree)
+Widget tree;
+{
+ Arg args[1];
+
+ XtSetArg(args[0], XtNbackgroundPixmap, &old_pixmap);
+ XtGetValues(XtParent(tree), args, ONE);
+
+ XtSetArg(args[0], XtNbackgroundPixmap, None);
+ XtSetValues(XtParent(tree), args, ONE);
+
+ XtUnmapWidget(tree);
+}
+
+
+
+/* Function Name: LayoutTree
+ * Description: Laysout the tree widget.
+ * Arguments: tree - the widget tree.
+ * Returns: none.
+ */
+
+void
+LayoutTree(tree)
+Widget tree;
+{
+ Arg args[1];
+
+ XawTreeForceLayout(tree);
+ XtMapWidget(tree);
+
+ XtSetArg(args[0], XtNbackgroundPixmap, old_pixmap);
+ XtSetValues(XtParent(tree), args, ONE);
+}
+
+
+
+/************************************************************
+ *
+ * Functions for creating the Resource Box.
+ *
+ ************************************************************/
+
+/* Function Name: CreateResourceBoxWidgets
+ * Description: Creates the widgets that make up the resource box.
+ * Arguments: node - the widget node.
+ * names - the list of names that make up the normal resources.
+ * cons_names - the list of names that make up
+ * the constraint resources.
+ * Returns: none.
+ */
+
+void
+CreateResourceBoxWidgets(node, names, cons_names)
+WNode * node;
+char **names, **cons_names;
+{
+ Widget pane, box, button;
+ ResourceBoxInfo * res_box;
+
+ res_box = (ResourceBoxInfo *) XtMalloc(sizeof(ResourceBoxInfo));
+ node->resources->res_box = res_box;
+
+ res_box->shell = XtCreatePopupShell(global_effective_toolkit,
+ /*RESOURCE_BOX,*/
+ transientShellWidgetClass,
+ node->widget, NULL, ZERO);
+ XtAddCallback(res_box->shell, XtNdestroyCallback,
+ FreeResBox, (XtPointer) node);
+
+ pane = XtCreateManagedWidget("pane", panedWidgetClass,
+ res_box->shell, NULL, ZERO);
+
+ res_box->res_label = XtCreateManagedWidget("resourceLabel",
+ labelWidgetClass,
+ pane, NULL, ZERO);
+
+ CreateResourceNameForm(pane, node);
+ CreateLists(pane, node, names, cons_names);
+ CreateValueWidget(pane, node);
+
+ XtSetKeyboardFocus(pane, res_box->value_wid); /* send keyboard to value. */
+
+ box = XtCreateManagedWidget("commandBox", boxWidgetClass,
+ pane, NULL, ZERO);
+
+ button = XtCreateManagedWidget("setFile", commandWidgetClass,
+ box, NULL, ZERO);
+ XtAddCallback(button, XtNcallback, SetFile, NULL);
+
+ button = XtCreateManagedWidget("save", commandWidgetClass,
+ box, NULL, ZERO);
+ XtAddCallback(button, XtNcallback, SaveResource,(XtPointer) res_box);
+
+ button = XtCreateManagedWidget("apply", commandWidgetClass,
+ box, NULL, ZERO);
+ XtAddCallback(button, XtNcallback, ApplyResource,(XtPointer) node);
+
+ button = XtCreateManagedWidget("saveAndApply", commandWidgetClass,
+ box, NULL, ZERO);
+ XtAddCallback(button, XtNcallback, SaveResource,(XtPointer) res_box);
+ XtAddCallback(button, XtNcallback, ApplyResource,(XtPointer) node);
+
+ button = XtCreateManagedWidget("cancel", commandWidgetClass,
+ box, NULL, ZERO);
+ XtAddCallback(button,XtNcallback,PopdownResBox,(XtPointer)res_box->shell);
+
+ SetToggleGroupLeaders(node);
+ PopupOnNode(node, res_box->shell);
+}
+
+
+
+/* Function Name: CreateResourceNameForm
+ * Description: Creates the Form widget with children that represent
+ * the full resource name for this object.
+ * Arguments: parent - parent of the form.
+ * node - the node corrosponding to this object.
+ * Returns: none
+ */
+
+static void
+CreateResourceNameForm(parent, node)
+Widget parent;
+WNode * node;
+{
+ ResourceBoxInfo * res_box = node->resources->res_box;
+ AnyInfo *new_info, *old_info;
+ char **names, **classes;
+ Widget form;
+ NameInfo * name_info = NULL;
+ Cardinal num_args;
+ Arg args[10];
+ int i;
+ Widget dot, star, name, class, single, any;
+
+ GetNamesAndClasses(node, &names, &classes);
+
+ form = XtCreateManagedWidget("namesAndClasses", formWidgetClass,
+ parent, NULL, ZERO);
+
+ name = class = any = NULL;
+ i = 0;
+ old_info = NULL;
+ while (TRUE) {
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, name); num_args++;
+ XtSetArg(args[num_args], XtNradioData, "."); num_args++;
+ dot = XtCreateManagedWidget("dot", toggleWidgetClass,
+ form, args, num_args);
+ XtAddCallback(dot, XtNcallback,
+ ActivateWidgetsAndSetResourceString,(XtPointer) node);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, class); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, dot); num_args++;
+ XtSetArg(args[num_args], XtNradioGroup, dot); num_args++;
+ XtSetArg(args[num_args], XtNradioData, "*"); num_args++;
+ star = XtCreateManagedWidget("star", toggleWidgetClass,
+ form, args, num_args);
+ XtAddCallback(star,XtNcallback,
+ ActivateWidgetsAndSetResourceString, (XtPointer) node);
+
+ if (name_info != NULL) {
+ name_info->next = (NameInfo *) XtMalloc(sizeof(NameInfo));
+ name_info = name_info->next;
+ }
+ else
+ res_box->name_info =
+ name_info = (NameInfo *) XtMalloc(sizeof(NameInfo));
+
+ name_info->sep_leader = dot;
+ name_info->name_leader = NULL;
+
+ if (names[i] != NULL) {
+ new_info = (AnyInfo *) XtMalloc(sizeof(AnyInfo));
+ new_info->node = node;
+ new_info->left_dot = dot;
+ new_info->left_star = star;
+ new_info->left_count = 0;
+ if (old_info != NULL)
+ old_info->right_count = &(new_info->left_count);
+ }
+ else if (old_info != NULL)
+ old_info->right_count = NULL;
+
+ if (old_info != NULL) {
+ old_info->right_dot = dot;
+ old_info->right_star = star;
+
+ XtAddCallback(any, XtNcallback, AnyChosen, (XtPointer) old_info);
+ XtAddCallback(any, XtNdestroyCallback,
+ FreeClientData, (XtPointer) old_info);
+ }
+
+ if ( names[i] == NULL) /* no more name and class boxes. */
+ break;
+
+ old_info = new_info;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, dot); num_args++;
+ XtSetArg(args[num_args], XtNlabel, names[i]); num_args++;
+ XtSetArg(args[num_args], XtNradioData, names[i]); num_args++;
+ name = XtCreateManagedWidget("name", toggleWidgetClass,
+ form, args, num_args);
+ XtAddCallback(name,XtNcallback,
+ ActivateWidgetsAndSetResourceString,(XtPointer) node);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, star); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, name); num_args++;
+ XtSetArg(args[num_args], XtNlabel, classes[i]); num_args++;
+ XtSetArg(args[num_args], XtNradioGroup, name); num_args++;
+ XtSetArg(args[num_args], XtNradioData, classes[i]); num_args++;
+ class = XtCreateManagedWidget("class", toggleWidgetClass,
+ form,args,num_args);
+ XtAddCallback(class, XtNcallback,
+ ActivateWidgetsAndSetResourceString,(XtPointer) node);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, star); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, class); num_args++;
+ XtSetArg(args[num_args], XtNradioData, "?"); num_args++;
+ XtSetArg(args[num_args], XtNradioGroup, name); num_args++;
+ single = XtCreateManagedWidget("single", toggleWidgetClass,
+ form, args, num_args);
+ XtAddCallback(single,XtNcallback,
+ ActivateWidgetsAndSetResourceString,(XtPointer) node);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, any); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, single); num_args++;
+ XtSetArg(args[num_args], XtNradioGroup, name); num_args++;
+ XtSetArg(args[num_args], XtNradioData, ANY_RADIO_DATA); num_args++;
+ any = XtCreateManagedWidget("any", toggleWidgetClass,
+ form, args, num_args);
+
+ name_info->name_leader = name;
+
+ MakeBoxLookNice(dot, star, any, single, name, class,
+ (i == 0 ? -1 : (names[i + 1] ? 0 : 1)));
+
+ i++;
+ }
+
+ name_info->next = NULL;
+ XtFree((char *)names); /* Free what you allocate... */
+ XtFree((char *)classes);
+}
+
+
+
+/* Function Name: SetToggleGroupLeaders
+ * Description: Sets the leaders of each toggle group.
+ * node - The widget node containing this res box.
+ * Returns: none
+ */
+
+static void
+SetToggleGroupLeaders(node)
+WNode * node;
+{
+ NameInfo *name;
+ ResourceBoxInfo * res_box = node->resources->res_box;
+ static Arg args[] = {
+ {XtNstate, (XtArgVal) TRUE}
+ };
+
+ for (name = res_box->name_info; name != NULL; name = name->next) {
+ XtSetValues(name->sep_leader, args, XtNumber(args));
+ if (name->name_leader != NULL)
+ XtSetValues(name->name_leader, args, XtNumber(args));
+ }
+ SetResourceString(NULL, (XtPointer) node, NULL);
+}
+
+
+
+/* Function Name: MakeBoxLookNice
+ * Description: Resizes the box that contains the resource names
+ * to look a bit nicer.
+ * Arguments: dot, star - the widgets containing the separator types.
+ * any, single, name, class - the widgets that contain the
+ * name and class of this object.
+ * Returns: none.
+ */
+
+static void
+MakeBoxLookNice(dot, star, any, single, name, class, endbox)
+Widget dot, star, any, single, name, class;
+int endbox;
+{
+
+#define MAX_HDIST 3
+
+ Arg args[10];
+ Cardinal num_args;
+ Dimension any_width, name_class_width, dot_star_width;
+ Dimension width_1, width_2;
+ int h_dist[MAX_HDIST];
+ int i;
+
+ /*
+ * Make sure that the dot and star widgets are the same size.
+ */
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[0])); num_args++;
+ XtSetArg(args[num_args], XtNwidth, &width_1); num_args++;
+ XtGetValues(dot, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++;
+ XtSetArg(args[num_args], XtNwidth, &width_2); num_args++;
+ XtGetValues(star, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[2])); num_args++;
+ XtSetArg(args[num_args], XtNwidth, &any_width); num_args++;
+ XtGetValues(any, args, num_args);
+
+ dot_star_width = (width_1 > width_2) ? width_1 : width_2;
+ for (i = 1 ; i < MAX_HDIST; i++) {
+ if (h_dist[i] > h_dist[0]) h_dist[0] = h_dist[i];
+ }
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNhorizDistance, h_dist[0]); num_args++;
+ XtSetValues(any, args, num_args);
+
+ /*
+ * Add a new arg, and continue...
+ */
+ XtSetArg(args[num_args], XtNwidth, dot_star_width); num_args++;
+ XtSetValues(star, args, num_args);
+ XtSetValues(dot, args, num_args);
+
+
+ /*
+ * Now make sure that the Any Widget is as wide as the longest
+ * of the name and class widgets, plus space for the dot and star widgets.
+ * Don't forget the Form widget's internal space.
+ */
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &width_1); num_args++;
+ XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[0])); num_args++;
+ XtGetValues(name, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &width_2); num_args++;
+ XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++;
+ XtGetValues(class, args, num_args);
+
+ if (width_2 > width_1) width_1 = width_2;
+ if (h_dist[1] > h_dist[0]) h_dist[0] = h_dist[1];
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &width_2); num_args++;
+ XtSetArg(args[num_args], XtNhorizDistance, &(h_dist[1])); num_args++;
+ XtGetValues(single, args, num_args);
+
+ name_class_width = (width_1 > width_2) ? width_1 : width_2;
+ if (h_dist[1] > h_dist[0]) h_dist[0] = h_dist[1];
+ if (any_width > name_class_width)
+ name_class_width = any_width;
+ any_width = dot_star_width + h_dist[0] + name_class_width;
+ if (endbox < 0)
+ any_width += dot_star_width / 2;
+ else if (endbox > 0)
+ any_width += (dot_star_width - dot_star_width / 2);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, any_width); num_args++;
+ XtSetValues(any, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, name_class_width); num_args++;
+ XtSetArg(args[num_args], XtNhorizDistance, h_dist[0]); num_args++;
+ XtSetValues(name, args, num_args);
+ XtSetValues(class, args, num_args);
+ XtSetValues(single, args, num_args);
+}
+
+
+
+/* Function Name: CreateLists
+ * Description: Creates the list widgets for the normal and constraint
+ * resources
+ * Arguments: parent - parent of the lists.
+ * node - The widget node containing this res box.
+ * names, cons_names - lists for norm and cons resource boxes.
+ * Returns: none
+ */
+
+static char* noneList[] = {"None"};
+
+static void
+CreateLists(parent, node, names, cons_names)
+Widget parent;
+WNode * node;
+char **names, **cons_names;
+{
+ Cardinal num_args;
+ ResourceBoxInfo * res_box = node->resources->res_box;
+ Arg args[3];
+
+ (void) XtCreateManagedWidget("namesLabel", labelWidgetClass,
+ parent, NULL, ZERO);
+
+ num_args = 0;
+ /* if the first list item is the widget name we want an empty
+ * list.
+ */
+ if (!names) {
+ XtSetArg(args[num_args], XtNlist, noneList); num_args++;
+ XtSetArg(args[num_args], XtNnumberStrings, 1); num_args++;
+ XtSetArg(args[num_args], XtNsensitive, False); num_args++;
+ }
+ else { XtSetArg(args[num_args], XtNlist, names); num_args++; }
+ res_box->norm_list = XtCreateManagedWidget("namesList", listWidgetClass,
+ parent, args, num_args);
+ XtAddCallback(res_box->norm_list, XtNcallback,
+ ResourceListCallback, (XtPointer) node);
+ XtAddCallback(res_box->norm_list, XtNdestroyCallback,
+ FreeClientData, (XtPointer) names);
+
+ if (cons_names != NULL) {
+ (void) XtCreateManagedWidget("constraintLabel", labelWidgetClass,
+ parent, NULL, ZERO);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlist, cons_names); num_args++;
+ res_box->cons_list = XtCreateManagedWidget("constraintList",
+ listWidgetClass,
+ parent, args, num_args);
+ XtAddCallback(res_box->cons_list, XtNcallback,
+ ResourceListCallback, (XtPointer) node);
+ XtAddCallback(res_box->cons_list, XtNdestroyCallback,
+ FreeClientData, (XtPointer) cons_names);
+ }
+ else
+ res_box->cons_list = NULL;
+}
+
+/* Function Name: CreateValueWidget
+ * Description: Creates the value widget for entering the resources value.
+ * Arguments: parent - parent of this widget.
+ * res_box - the resource box info.
+ * Returns: none.
+ */
+
+static void
+CreateValueWidget(parent, node)
+Widget parent;
+WNode * node;
+{
+ Widget form, label;
+ Cardinal num_args;
+ Arg args[10];
+ ResourceBoxInfo * res_box = node->resources->res_box;
+
+ form = XtCreateManagedWidget("valueForm", formWidgetClass,
+ parent, NULL, ZERO);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNleft, XawChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XawChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNtop, XawChainTop); num_args++;
+ XtSetArg(args[num_args], XtNbottom, XawChainBottom); num_args++;
+ label = XtCreateManagedWidget("valueLabel", labelWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, label); num_args++;
+ XtSetArg(args[num_args], XtNleft, XawChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XawChainRight); num_args++;
+ XtSetArg(args[num_args], XtNtop, XawChainTop); num_args++;
+ XtSetArg(args[num_args], XtNbottom, XawChainBottom); num_args++;
+ res_box->value_wid = XtCreateManagedWidget("valueText",
+ asciiTextWidgetClass,
+ form, args, num_args);
+#ifdef notdef
+ XtAddCallback(XawTextGetSource(res_box->value_wid), XtNcallback,
+ SetResourceString, (XtPointer) node);
+#endif
+}
+
+
+
+/* Function Name: PopupOnNode
+ * Description: Pops a shell widget up centered on the node specified.
+ * Arguments: node - the node.
+ * shell - the shell to popup.
+ * Returns: none.
+ */
+
+extern Atom wm_delete_window;
+
+static void
+PopupOnNode(node, shell)
+WNode * node;
+Widget shell;
+{
+ Arg args[3];
+ Cardinal num_args;
+ Position x, y;
+ Dimension width, height, bw;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &width); num_args++;
+ XtSetArg(args[num_args], XtNheight, &height); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, &bw); num_args++;
+ XtGetValues(node->widget, args, num_args);
+ XtTranslateCoords(node->widget,
+ (Position) (width/2 + bw), (Position) (height/2 + bw),
+ &x, &y);
+
+ XtOverrideTranslations
+ (shell, XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()"));
+ XtRealizeWidget(shell);
+ wm_delete_window = XInternAtom(XtDisplay(shell), "WM_DELETE_WINDOW",
+ False);
+ (void) XSetWMProtocols (XtDisplay(shell), XtWindow(shell),
+ &wm_delete_window, 1);
+ XtGetValues(shell, args, num_args); /* use same arg_list. */
+
+ x -= (Position) (width/2 + bw);
+ y -= (Position) (height/2 + bw);
+
+ if (x < 0)
+ x = 0;
+ else {
+ Position max_loc = WidthOfScreen(XtScreen(shell)) -
+ (Position) (width + 2 * bw);
+ if (x > max_loc)
+ x = max_loc;
+ }
+
+ if (y < 0)
+ y = 0;
+ else {
+ Position max_loc = HeightOfScreen(XtScreen(shell)) -
+ (Position) (height + 2 * bw);
+ if (y > max_loc)
+ y = max_loc;
+ }
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNx, x); num_args++;
+ XtSetArg(args[num_args], XtNy, y); num_args++;
+ XtSetValues(shell, args, num_args);
+
+ XtPopup(shell, XtGrabNone);
+}
+
+
+
+/* Function Name: FreeClientData
+ * Description: Frees the client data passed to this function.
+ * Arguments: w - UNUSED.
+ * list_ptr - pointer to the list to check.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+FreeClientData(w, ptr, junk)
+Widget w;
+XtPointer ptr, junk;
+{
+ XtFree(ptr);
+}
+
+
+
+/* Function Name: FreeResBox.
+ * Description: Frees resource box allocated memory.
+ * Arguments: w - UNUSED.
+ * ptr - pointer to the node that has this resources box.
+ * junk - UNUSED.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+FreeResBox(w, ptr, junk)
+Widget w;
+XtPointer ptr, junk;
+{
+ WNode * node = (WNode *) ptr;
+ NameInfo *old_name, *name = node->resources->res_box->name_info;
+
+ global_resource_box_up = FALSE;
+
+ XtFree((XtPointer) node->resources->res_box);
+ node->resources->res_box = NULL;
+
+ while (name != NULL) {
+ old_name = name;
+ name = name->next;
+ XtFree((XtPointer) old_name);
+ }
+}
+
+
+
diff --git a/wtree.c b/wtree.c
new file mode 100644
index 0000000..07a6920
--- /dev/null
+++ b/wtree.c
@@ -0,0 +1,733 @@
+/*
+ * $Xorg: wtree.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ */
+
+#include <stdio.h>
+#include <X11/Intrinsic.h>
+#include <X11/Xutil.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Toggle.h>
+#include <X11/Xaw/Viewport.h>
+#include <X11/Xaw/Tree.h>
+
+#include "editresP.h"
+
+extern ScreenData global_screen_data;
+extern void SetMessage();
+
+static Boolean IsActiveNode();
+static void AddChild(), FillNode();
+static void AddNode();
+static void AddNodeToActiveList(), RemoveNodeFromActiveList();
+
+extern void PrepareToLayoutTree(), LayoutTree();
+
+extern void _TreeSelectNode(), _TreeActivateNode(), _TreeRelabelNode();
+static WNode ** CopyActiveNodes();
+
+void TreeToggle();
+
+/* Function Name: BuildVisualTree
+ * Description: Creates the Tree and shows it.
+ * Arguments: tree_parent - parent of the tree widget.
+ * event - the event that caused this action.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+BuildVisualTree(tree_parent, event)
+Widget tree_parent;
+Event * event;
+{
+ WNode * top;
+ TreeInfo *CreateTree();
+ void AddTreeNode();
+ char msg[BUFSIZ];
+
+ if (global_tree_info != NULL) {
+ XtDestroyWidget(global_tree_info->tree_widget);
+ XtFree((char *)global_tree_info->active_nodes);
+ XtFree((char *)global_tree_info);
+ }
+
+ global_tree_info = CreateTree(event);
+ top = global_tree_info->top_node;
+
+ global_tree_info->tree_widget = XtCreateWidget("tree", treeWidgetClass,
+ tree_parent, NULL, ZERO);
+
+ if (top == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[27]);
+ return;
+ }
+
+ AddTreeNode(global_tree_info->tree_widget, top);
+
+ if (XtIsRealized(tree_parent)) /* hack around problems in Xt. */
+ XtRealizeWidget(global_tree_info->tree_widget);
+
+ XtManageChild(global_tree_info->tree_widget);
+
+ sprintf(msg, res_labels[11], top->name, top->class);
+ SetMessage(global_screen_data.info_label, msg);
+}
+
+/* Function Name: AddTreeNode
+ * Description: Adds all nodes below this to the Tree widget.
+ * Arguments: parent - parent of the tree widget.
+ * top - the top node of the tree.
+ * Returns: the tree widget.
+ *
+ * NOTE: This is a recursive function.
+ */
+
+void
+AddTreeNode(tree, top)
+Widget tree;
+WNode * top;
+{
+ int i;
+ Arg args[1];
+ Cardinal num_args = 0;
+ char msg[BUFSIZ];
+
+ if (top->parent != NULL) {
+ if (top->parent->widget == NULL) {
+ sprintf( msg, res_labels[28],
+ top->name, top->parent->name, "not been created yet");
+ SetMessage(global_screen_data.info_label, msg);
+ }
+ XtSetArg(args[num_args], XtNtreeParent, top->parent->widget);
+ num_args++;
+ }
+
+ top->widget = XtCreateManagedWidget(top->name, toggleWidgetClass, tree,
+ args, num_args);
+
+ if (XSaveContext(XtDisplay(top->widget), (Window) top->widget,
+ NODE_INFO, (XPointer) top) != 0) {
+ sprintf( msg, res_labels[29], top->name);
+ SetMessage(global_screen_data.info_label, msg);
+ }
+
+ XtAddCallback(top->widget, XtNcallback, TreeToggle, (XtPointer) top);
+
+ for (i = 0; i < top->num_children; i++)
+ AddTreeNode(tree, top->children[i]);
+}
+
+/* Function Name: TreeToggle
+ * Description: Called whenever a tree node is toggled.
+ * Arguments: w - the tree widget.
+ * node_ptr - pointer to this node's information.
+ * state_ptr - state of the toggle.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+TreeToggle(w, node_ptr, state_ptr)
+Widget w;
+XtPointer node_ptr, state_ptr;
+{
+ Boolean state = (Boolean)(long) state_ptr;
+ WNode * node = (WNode *) node_ptr;
+
+ if (state)
+ AddNodeToActiveList(node);
+ else
+ RemoveNodeFromActiveList(node);
+}
+
+/* Function Name: AddNodeToActiveList
+ * Description: Adds this node to the list of active toggles.
+ * Arguments: node - node to add.
+ * Returns: none.
+ */
+
+static void
+AddNodeToActiveList(node)
+WNode * node;
+{
+ TreeInfo * info = node->tree_info;
+
+ if (IsActiveNode(node)) /* node already active. */
+ return;
+
+ if (info->num_nodes >= info->alloc_nodes) {
+ info->alloc_nodes += NUM_INC;
+ info->active_nodes =(WNode **)XtRealloc((XtPointer) info->active_nodes,
+ sizeof(WNode *) *
+ info->alloc_nodes);
+ }
+
+ info->active_nodes[info->num_nodes++] = node;
+}
+
+/* Function Name: RemoveNodeFromActiveList
+ * Description: Removes a node from the active list.
+ * Arguments: node - node to remove.
+ * Returns: none.
+ */
+
+static void
+RemoveNodeFromActiveList(node)
+WNode * node;
+{
+ TreeInfo * info = node->tree_info;
+ Boolean found_node = FALSE;
+ int i;
+
+ if (!IsActiveNode(node)) /* This node is not active. */
+ return;
+
+ for (i = 0; i < info->num_nodes; i++) {
+ if (found_node)
+ info->active_nodes[i - 1] = info->active_nodes[i];
+ else if (info->active_nodes[i] == node)
+ found_node = TRUE;
+ }
+
+ info->num_nodes--;
+}
+
+/* Function Name: IsActiveNode
+ * Description: returns TRUE is this node is on the active list.
+ * Arguments: node - node to check.
+ * Returns: see above.
+ */
+
+static Boolean
+IsActiveNode(node)
+WNode * node;
+{
+ TreeInfo * info = node->tree_info;
+ int i;
+
+ for (i = 0; i < info->num_nodes; i++)
+ if (info->active_nodes[i] == node)
+ return(TRUE);
+
+ return(FALSE);
+}
+
+/* Function Name: CreateTree
+ * Description: Creates a widget tree give a list of names and classes.
+ * Arguments: event - the information from the client.
+ * Returns: The tree_info about this new tree.
+ */
+
+TreeInfo *
+CreateTree(event)
+Event * event;
+{
+ SendWidgetTreeEvent * send_event = (SendWidgetTreeEvent *) event;
+ int i;
+
+ TreeInfo * tree_info;
+
+ tree_info = (TreeInfo *) XtMalloc( (Cardinal) sizeof(TreeInfo));
+
+ tree_info->tree_widget = NULL;
+ tree_info->top_node = NULL;
+ tree_info->active_nodes = NULL;
+ tree_info->num_nodes = tree_info->alloc_nodes = 0;
+ tree_info->flash_widgets = NULL;
+ tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
+
+ for ( i = 0; i < (int)send_event->num_entries; i++)
+ AddNode(&(tree_info->top_node), (send_event->info + i), tree_info);
+
+ return(tree_info);
+}
+
+/* Function Name: PrintNodes
+ * Description: Prints all nodes.
+ * Arguments: top - the top node.
+ * Returns: none.
+ */
+
+void
+PrintNodes(top)
+WNode * top;
+{
+ int i;
+
+ if (top->parent == NULL)
+ printf("Top of Tree, Name: %10s, ID: %10ld, Class: %10s\n",
+ top->name, top->id, top->class);
+ else
+ printf("Parent %10s, Name: %10s, ID: %10ld, Class: %10s\n",
+ top->parent->name, top->name, top->id, top->class);
+
+ for (i = 0; i < top->num_children; i++)
+ PrintNodes(top->children[i]);
+}
+
+/* Function Name: _TreeRelabel
+ * Description: Modifies the selected elements of the tree
+ * Arguments: tree_info - the tree we are working on.
+ * type - type of selection to perform
+ * Returns: none.
+ */
+
+void
+_TreeRelabel(tree_info, type)
+TreeInfo * tree_info;
+LabelTypes type;
+{
+ WNode * top;
+
+ if (tree_info == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[17]);
+ return;
+ }
+
+ top = tree_info->top_node;
+
+ PrepareToLayoutTree(tree_info->tree_widget);
+ _TreeRelabelNode(top, type, TRUE);
+ LayoutTree(tree_info->tree_widget);
+}
+
+/* Function Name: _TreeSelect
+ * Description: Activates relatives of the active nodes, as specified
+ * by type, or Selects all nodes as specified by type.
+ * Arguments: tree_info - information about the tree to work on.
+ * type - type of activate to invode.
+ * Returns: none.
+ */
+
+void
+_TreeSelect(tree_info, type)
+TreeInfo * tree_info;
+SelectTypes type;
+{
+ WNode ** active_nodes;
+ Cardinal num_active_nodes;
+ int i;
+
+ if (tree_info == NULL) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[17]);
+ return;
+ }
+
+ switch(type) {
+ case SelectNone:
+ case SelectAll:
+ case SelectInvert:
+ _TreeSelectNode(tree_info->top_node, type, TRUE);
+ return;
+ default:
+ break; /* otherwise continue. */
+ }
+
+ if (tree_info->num_nodes == 0) {
+ SetMessage(global_screen_data.info_label,
+ res_labels[18]);
+ return;
+ }
+
+ active_nodes = CopyActiveNodes(tree_info);
+ num_active_nodes = tree_info->num_nodes;
+
+ for (i = 0; i < num_active_nodes; i++)
+ _TreeActivateNode(active_nodes[i], type);
+
+ XtFree((XtPointer) active_nodes);
+}
+
+/* Function Name: _TreeSelectNode
+ * Description: Modifies the state of a node and all its decendants.
+ * Arguments: node - node to operate on.
+ * type - type of selection to perform.
+ * recurse - whether to continue on down the tree.
+ * Returns: none.
+ */
+
+void
+_TreeSelectNode(node, type, recurse)
+WNode * node;
+SelectTypes type;
+Boolean recurse;
+{
+ int i;
+ Arg args[1];
+ Boolean state;
+
+ switch(type) {
+ case SelectAll:
+ state = TRUE;
+ break;
+ case SelectNone:
+ state = FALSE;
+ break;
+ case SelectInvert:
+ XtSetArg(args[0], XtNstate, &state);
+ XtGetValues(node->widget, args, ONE);
+
+ state = !state;
+ break;
+ default:
+ SetMessage(global_screen_data.info_label,
+ res_labels[16]);
+ return;
+ }
+
+ XtSetArg(args[0], XtNstate, state);
+ XtSetValues(node->widget, args, ONE);
+ TreeToggle(node->widget, (XtPointer) node, (XtPointer)(long) state);
+
+ if (!recurse)
+ return;
+
+ for (i = 0; i < node->num_children; i++)
+ _TreeSelectNode(node->children[i], type, recurse);
+}
+
+/* Function Name: _TreeRelabelNodes
+ * Description: Modifies the node and all its decendants label.
+ * Arguments: node - node to operate on.
+ * type - type of selection to perform.
+ * recurse - whether to continue on down the tree.
+ * Returns: none.
+ */
+
+void
+_TreeRelabelNode(node, type, recurse)
+WNode * node;
+LabelTypes type;
+Boolean recurse;
+{
+ int i;
+ Arg args[1];
+ char buf[30];
+ char *label;
+
+ switch(type) {
+ case ClassLabel:
+ XtSetArg(args[0], XtNlabel, node->class);
+ break;
+ case NameLabel:
+ XtSetArg(args[0], XtNlabel, node->name);
+ break;
+ case IDLabel:
+ sprintf(buf, "id: 0x%lx", node->id);
+ XtSetArg(args[0], XtNlabel, buf);
+ break;
+ case WindowLabel:
+ if (node->window == EDITRES_IS_UNREALIZED)
+ strcpy(buf, "unrealized widget");
+ else if (node->window == EDITRES_IS_OBJECT)
+ strcpy(buf, "non windowed object");
+ else
+ sprintf(buf, "win: 0x%lx", node->window);
+
+ XtSetArg(args[0], XtNlabel, buf);
+ break;
+ case ToggleLabel:
+ XtSetArg(args[0], XtNlabel, &label);
+ XtGetValues(node->widget, args, ONE);
+ if (label && !strcmp(label, node->name))
+ XtSetArg(args[0], XtNlabel, node->class);
+ else
+ XtSetArg(args[0], XtNlabel, node->name);
+ break;
+ default:
+ SetMessage(global_screen_data.info_label,
+ res_labels[32]);
+ return;
+ }
+
+ XtSetValues(node->widget, args, ONE);
+
+ if (!recurse)
+ return;
+
+ for (i = 0; i < node->num_children; i++)
+ _TreeRelabelNode(node->children[i], type, recurse);
+}
+
+/* Function Name: _TreeActivateNode
+ * Description: Activates relatives of the node specfied, as specified
+ * by type.
+ * Arguments: node - node to opererate on.
+ * type - type of activate to invode.
+ * Returns: none.
+ */
+
+void
+_TreeActivateNode(node, type)
+WNode * node;
+SelectTypes type;
+{
+ Arg args[1];
+ int i;
+
+ XtSetArg(args[0], XtNstate, TRUE);
+
+ if ((type == SelectParent) || (type == SelectAncestors)) {
+ node = node->parent;
+ if (node == NULL)
+ return;
+
+ XtSetValues(node->widget, args, ONE);
+ AddNodeToActiveList(node);
+
+ if (type == SelectAncestors)
+ _TreeActivateNode(node, type);
+ }
+ else if ((type == SelectChildren) || (type == SelectDescendants))
+ for (i = 0; i < node->num_children; i++) {
+ AddNodeToActiveList(node->children[i]);
+ XtSetValues(node->children[i]->widget, args, ONE);
+ if (type == SelectDescendants)
+ _TreeActivateNode(node->children[i], type);
+ }
+ else
+ SetMessage(global_screen_data.info_label,
+ res_labels[33]);
+}
+
+/************************************************************
+ *
+ * Non - Exported Functions.
+ *
+ ************************************************************/
+
+WNode * FindNode();
+
+/* Function Name: AddNode
+ * Description: adds a node to the widget tree.
+ * Arguments: top_node - a pointer to the current top node.
+ * info - the info from the client about the widget tree.
+ * tree_info - global information on this tree.
+ * Returns: none.
+ */
+
+static void
+AddNode(top_node, info, tree_info)
+WNode ** top_node;
+WidgetTreeInfo * info;
+TreeInfo * tree_info;
+{
+ WNode *node, *parent;
+ Boolean early_break = FALSE;
+ Cardinal number = info->widgets.num_widgets;
+
+ if ( (node = FindNode(*top_node, info->widgets.ids, number)) == NULL) {
+ node = (WNode *) XtCalloc(sizeof(WNode), ONE);
+
+ node->id = info->widgets.ids[number - 1];
+ FillNode(info, node, tree_info);
+
+ for ( number--; number > 0; number--, node = parent) {
+ parent = FindNode(*top_node, info->widgets.ids, number);
+ if (parent == NULL) {
+ parent = (WNode *) XtCalloc(sizeof(WNode), ONE);
+ parent->id = info->widgets.ids[number - 1];
+ }
+ else
+ early_break = TRUE;
+
+ AddChild(parent, node);
+
+ if (early_break)
+ break;
+ }
+
+ if (!early_break) {
+ if (node->parent == NULL)
+ *top_node = node;
+ else
+ *top_node = node->parent;
+ }
+ }
+ else
+ FillNode(info, node, tree_info);
+}
+
+/* Function Name: FillNode
+ * Description: Fills in everything but the node id in the node.
+ * Arguments: info - the info from the client.
+ * node - node to fill.
+ * tree_info - global information on this tree.
+ * Returns: none
+ */
+
+static void
+FillNode(info, node, tree_info)
+WidgetTreeInfo * info;
+WNode * node;
+TreeInfo * tree_info;
+{
+ node->class = info->class;
+ info->class = NULL; /* keeps it from deallocating. */
+ node->name = info->name;
+ info->name = NULL;
+ node->window = info->window;
+ node->tree_info = tree_info;
+}
+
+/* Function Name: AddChild
+ * Description: Adds a child to an existing node.
+ * Arguments: parent - parent node.
+ * child - child node to add.
+ * Returns: none.
+ */
+
+static void
+AddChild(parent, child)
+WNode * parent, * child;
+{
+ if (parent->num_children >= parent->alloc_children) {
+ parent->alloc_children += NUM_INC;
+ parent->children = (WNode **) XtRealloc((char *)parent->children,
+ sizeof(WNode *) * parent->alloc_children);
+ }
+
+ parent->children[parent->num_children] = child;
+ (parent->num_children)++;
+
+ child->parent = parent;
+}
+
+/************************************************************
+ *
+ * Functions that operate of the current tree.
+ *
+ ************************************************************/
+
+/* Function Name: CopyActiveNodes
+ * Description: returns a copy of the currently selected nodes.
+ * Arguments: tree_info - the tree info struct.
+ * Returns: a copy of the selected nodes.
+ */
+
+static WNode **
+CopyActiveNodes(tree_info)
+TreeInfo * tree_info;
+{
+ WNode ** list;
+ int i;
+
+ if ( (tree_info == NULL) || (tree_info->num_nodes == 0))
+ return(NULL);
+
+ list = (WNode **) XtMalloc(sizeof(WNode *) * tree_info->num_nodes);
+
+ for (i = 0; i < tree_info->num_nodes; i++)
+ list[i] = tree_info->active_nodes[i];
+
+ return(list);
+}
+
+/* Function Name: SetAndCenterTreeNode
+ * Description: Deactivates all nodes, activates the one specified, and
+ * and moves the tree to be centered on the current node.
+ * Arguments: node - node to use.
+ * Returns: none.
+ */
+
+void
+SetAndCenterTreeNode(node)
+WNode * node;
+{
+ Arg args[5];
+ Cardinal num_args;
+ Position node_x, node_y;
+ Dimension port_width, port_height;
+ Dimension node_width, node_height, node_bw;
+
+ _TreeSelect(node->tree_info, SelectNone); /* Unselect all nodes */
+ _TreeSelectNode(node, SelectAll, FALSE); /* Select this node */
+
+ /*
+ * Get porthole dimensions.
+ */
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &port_width); num_args++;
+ XtSetArg(args[num_args], XtNheight, &port_height); num_args++;
+ XtGetValues(XtParent(node->tree_info->tree_widget), args, num_args);
+
+ /*
+ * Get node widget dimensions.
+ */
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &node_width); num_args++;
+ XtSetArg(args[num_args], XtNheight, &node_height); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, &node_bw); num_args++;
+ XtSetArg(args[num_args], XtNx, &node_x); num_args++;
+ XtSetArg(args[num_args], XtNy, &node_y); num_args++;
+ XtGetValues(node->widget, args, num_args);
+
+ /*
+ * reset the node x and y location to be the new x and y location of
+ * the tree relative to the porthole.
+ */
+
+ node_x = port_width/2 - (node_x + node_width/2 + node_bw);
+ node_y = port_height/2 - (node_y + node_height/2 + node_bw);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNx, node_x); num_args++;
+ XtSetArg(args[num_args], XtNy, node_y); num_args++;
+ XtSetValues(node->tree_info->tree_widget, args, num_args);
+}
+
+/* Function Name: PerformTreeToFileDump
+ * Description: Dumps the contents of the current widget tree to
+ * the file specified.
+ * Arguments: node - node to dump.
+ * num_tabs - number of spaces to indent.
+ * fp - pointer to the file to write to.
+ * Returns: none.
+ */
+
+void
+PerformTreeToFileDump(node, num_tabs, fp)
+WNode * node;
+int num_tabs;
+FILE * fp;
+{
+ int i;
+
+ for (i = 0; i < num_tabs; i++)
+ fprintf(fp, "\t");
+ fprintf(fp, "%s %s\n", node->class, node->name);
+
+ num_tabs++;
+ for (i = 0; i < node->num_children; i++)
+ PerformTreeToFileDump(node->children[i], num_tabs, fp);
+}
+