1/*
2
3Copyright 1994, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25*/
26
27/*
28 * XmuCvtStringToWidget
29 *
30 * static XtConvertArgRec parentCvtArgs[] = {
31 *   {XtBaseOffset, (XtPointer)XtOffset(Widget, core.parent), sizeof(Widget)},
32 * };
33 *
34 * matches the string against the name of the immediate children (normal
35 * or popup) of the parent.  If none match, compares string to classname
36 * & returns first match.  Case is significant.
37 */
38#ifdef HAVE_CONFIG_H
39#include <config.h>
40#endif
41#include <X11/IntrinsicP.h>
42#include <X11/StringDefs.h>
43#include <X11/ObjectP.h>
44#include <X11/Xmu/Converters.h>
45
46#define	done(address, type) \
47{						\
48  toVal->size = sizeof(type);			\
49  toVal->addr = (XPointer)address;		\
50	  return; \
51}
52
53/*ARGSUSED*/
54void
55XmuCvtStringToWidget(XrmValuePtr args, Cardinal *num_args,
56                     XrmValuePtr fromVal, XrmValuePtr toVal)
57{
58    static Widget widget, *widgetP, parent;
59    XrmName name = XrmStringToName(fromVal->addr);
60    Cardinal i;
61
62    if (*num_args != 1) {
63        i = 0;
64        XtErrorMsg("wrongParameters", "cvtStringToWidget", "xtToolkitError",
65                   "StringToWidget conversion needs parent arg", NULL, &i);
66    }
67
68    parent = *(Widget *) args[0].addr;
69    /* try to match names of normal children */
70    if (XtIsComposite(parent)) {
71        i = ((CompositeWidget) parent)->composite.num_children;
72        for (widgetP = ((CompositeWidget) parent)->composite.children;
73             i; i--, widgetP++) {
74            if ((*widgetP)->core.xrm_name == name) {
75                widget = *widgetP;
76                done(&widget, Widget);
77            }
78        }
79    }
80
81    /* try to match names of popup children */
82    i = parent->core.num_popups;
83    for (widgetP = parent->core.popup_list; i; i--, widgetP++) {
84        if ((*widgetP)->core.xrm_name == name) {
85            widget = *widgetP;
86            done(&widget, Widget);
87        }
88    }
89
90    /* try to match classes of normal children */
91    if (XtIsComposite(parent)) {
92        i = ((CompositeWidget) parent)->composite.num_children;
93        for (widgetP = ((CompositeWidget) parent)->composite.children;
94             i; i--, widgetP++) {
95            if ((*widgetP)->core.widget_class->core_class.xrm_class == name) {
96                widget = *widgetP;
97                done(&widget, Widget);
98            }
99        }
100    }
101
102    /* try to match classes of popup children */
103    i = parent->core.num_popups;
104    for (widgetP = parent->core.popup_list; i; i--, widgetP++) {
105        if ((*widgetP)->core.widget_class->core_class.xrm_class == name) {
106            widget = *widgetP;
107            done(&widget, Widget);
108        }
109    }
110
111    XtStringConversionWarning(fromVal->addr, XtRWidget);
112    toVal->addr = NULL;
113    toVal->size = 0;
114}
115
116#undef done
117
118#define newDone(type, value) \
119        {                                                       \
120            if (toVal->addr != NULL) {                          \
121                if (toVal->size < sizeof(type)) {               \
122                    toVal->size = sizeof(type);                 \
123                    return False;                               \
124                }                                               \
125                *(type*)(toVal->addr) = (value);                \
126            }                                                   \
127            else {                                              \
128                static type static_val;                         \
129                static_val = (value);                           \
130                toVal->addr = (XtPointer)&static_val;           \
131            }                                                   \
132            toVal->size = sizeof(type);                         \
133            return True;                                        \
134        }
135
136
137/*ARGSUSED*/
138Boolean
139XmuNewCvtStringToWidget(Display *dpy, XrmValue *args, Cardinal *num_args,
140                        XrmValue *fromVal, XrmValue *toVal,
141                        XtPointer *converter_data)
142{
143    Widget *widgetP, parent;
144    XrmName name = XrmStringToName(fromVal->addr);
145    int i;
146
147    if (*num_args != 1)
148        XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
149                        "wrongParameters", "cvtStringToWidget",
150                        "xtToolkitError",
151                        "String To Widget conversion needs parent argument",
152                        (String *) NULL, (Cardinal *) NULL);
153
154    parent = *(Widget *) args[0].addr;
155    /* try to match names of normal children */
156    if (XtIsComposite(parent)) {
157        i = ((CompositeWidget) parent)->composite.num_children;
158        for (widgetP = ((CompositeWidget) parent)->composite.children;
159             i; i--, widgetP++) {
160            if ((*widgetP)->core.xrm_name == name)
161                newDone(Widget, *widgetP);
162        }
163    }
164
165    /* try to match names of popup children */
166    i = parent->core.num_popups;
167    for (widgetP = parent->core.popup_list; i; i--, widgetP++) {
168        if ((*widgetP)->core.xrm_name == name)
169            newDone(Widget, *widgetP);
170    }
171
172    /* try to match classes of normal children */
173    if (XtIsComposite(parent)) {
174        i = ((CompositeWidget) parent)->composite.num_children;
175        for (widgetP = ((CompositeWidget) parent)->composite.children;
176             i; i--, widgetP++) {
177            if ((*widgetP)->core.widget_class->core_class.xrm_class == name)
178                newDone(Widget, *widgetP);
179        }
180    }
181
182    /* try to match classes of popup children */
183    i = parent->core.num_popups;
184    for (widgetP = parent->core.popup_list; i; i--, widgetP++) {
185        if ((*widgetP)->core.widget_class->core_class.xrm_class == name)
186            newDone(Widget, *widgetP);
187    }
188
189    XtDisplayStringConversionWarning(dpy, (String) fromVal->addr, XtRWidget);
190    return (False);
191}
192
193/*ARGSUSED*/
194Boolean
195XmuCvtWidgetToString(Display *dpy, XrmValuePtr args, Cardinal *num_args,
196                     XrmValuePtr fromVal, XrmValuePtr toVal, XtPointer *data)
197{
198    static String buffer;
199    Cardinal size;
200    Widget widget;
201
202    widget = *(Widget *) fromVal->addr;
203
204    if (widget)
205        buffer = XrmQuarkToString(widget->core.xrm_name);
206    else
207        buffer = "(null)";
208
209    size = strlen(buffer) + 1;
210    if (toVal->addr != NULL) {
211        if (toVal->size < size) {
212            toVal->size = size;
213            return (False);
214        }
215        strcpy((char *) toVal->addr, buffer);
216    }
217    else {
218        toVal->addr = (XPointer) buffer;
219    }
220    toVal->size = sizeof(String);
221
222    return (True);
223}
224