diff options
-rw-r--r-- | Editres-color.ad | 37 | ||||
-rw-r--r-- | Editres.ad | 254 | ||||
-rw-r--r-- | actions.c | 358 | ||||
-rw-r--r-- | comm.c | 962 | ||||
-rw-r--r-- | editres.c | 153 | ||||
-rw-r--r-- | editres.man | 433 | ||||
-rw-r--r-- | editresP.h | 352 | ||||
-rw-r--r-- | geometry.c | 490 | ||||
-rw-r--r-- | handler.c | 966 | ||||
-rw-r--r-- | setvalues.c | 122 | ||||
-rw-r--r-- | svpopup.c | 336 | ||||
-rw-r--r-- | utils.c | 915 | ||||
-rw-r--r-- | widgets.c | 1037 | ||||
-rw-r--r-- | wtree.c | 733 |
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); +} + @@ -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))); +} @@ -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); + } +} + + + @@ -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); +} + |