VarGet.c revision fdf6a26f
1/*
2
3Copyright (c) 1993, Oracle and/or its affiliates.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8the rights to use, copy, modify, merge, publish, distribute, sublicense,
9and/or sell copies of the Software, and to permit persons to whom the
10Software is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice (including the next
13paragraph) shall be included in all copies or substantial portions of the
14Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22DEALINGS IN THE SOFTWARE.
23
24*/
25
26/*
27
28Copyright 1985, 1986, 1987, 1988, 1989, 1998  The Open Group
29
30Permission to use, copy, modify, distribute, and sell this software and its
31documentation for any purpose is hereby granted without fee, provided that
32the above copyright notice appear in all copies and that both that
33copyright notice and this permission notice appear in supporting
34documentation.
35
36The above copyright notice and this permission notice shall be included in
37all copies or substantial portions of the Software.
38
39THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
42OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
43AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
44CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45
46Except as contained in this notice, the name of The Open Group shall not be
47used in advertising or otherwise to promote the sale, use or other dealings
48in this Software without prior written authorization from The Open Group.
49
50*/
51
52#ifdef HAVE_CONFIG_H
53#include <config.h>
54#endif
55#include "IntrinsicI.h"
56#include "VarargsI.h"
57#include "StringDefs.h"
58
59static String XtNxtGetTypedArg = "xtGetTypedArg";
60
61void
62XtVaGetSubresources(Widget widget,
63                    XtPointer base,
64                    _Xconst char *name,
65                    _Xconst char *class,
66                    XtResourceList resources,
67                    Cardinal num_resources,
68                    ...)
69{
70    va_list var;
71    XtTypedArgList args;
72    Cardinal num_args;
73    int total_count, typed_count;
74
75    WIDGET_TO_APPCON(widget);
76
77    LOCK_APP(app);
78    va_start(var, num_resources);
79    _XtCountVaList(var, &total_count, &typed_count);
80    va_end(var);
81
82    va_start(var, num_resources);
83
84    _XtVaToTypedArgList(var, total_count, &args, &num_args);
85
86    _XtGetSubresources(widget, base, name, class, resources, num_resources,
87                       NULL, 0, args, num_args);
88
89    XtFree((XtPointer) args);
90
91    va_end(var);
92    UNLOCK_APP(app);
93}
94
95void
96XtVaGetApplicationResources(Widget widget,
97                            XtPointer base,
98                            XtResourceList resources,
99                            Cardinal num_resources,
100                            ...)
101{
102    va_list var;
103    XtTypedArgList args;
104    Cardinal num_args;
105    int total_count, typed_count;
106
107    WIDGET_TO_APPCON(widget);
108
109    LOCK_APP(app);
110    va_start(var, num_resources);
111    _XtCountVaList(var, &total_count, &typed_count);
112    va_end(var);
113
114    va_start(var, num_resources);
115
116    _XtVaToTypedArgList(var, total_count, &args, &num_args);
117
118    _XtGetApplicationResources(widget, base, resources, num_resources,
119                               NULL, 0, args, num_args);
120
121    XtFree((XtPointer) args);
122
123    va_end(var);
124    UNLOCK_APP(app);
125}
126
127static void
128GetTypedArg(Widget widget,
129            XtTypedArgList typed_arg,
130            XtResourceList resources,
131            Cardinal num_resources)
132{
133    String from_type = NULL;
134    Cardinal from_size = 0;
135    XrmValue from_val, to_val;
136    register Cardinal i;
137    Arg arg;
138    XtPointer value;
139
140    /* note we presume that the XtResourceList to be un-compiled */
141
142    for (i = 0; i < num_resources; i++) {
143        if (StringToName(typed_arg->name) ==
144            StringToName(resources[i].resource_name)) {
145            from_type = resources[i].resource_type;
146            from_size = resources[i].resource_size;
147            break;
148        }
149    }
150
151    if (i == num_resources) {
152        XtAppWarningMsg(XtWidgetToApplicationContext(widget),
153                        "unknownType", XtNxtGetTypedArg, XtCXtToolkitError,
154                        "Unable to find type of resource for conversion",
155                        NULL, NULL);
156        return;
157    }
158
159    value = ALLOCATE_LOCAL(from_size);
160    if (value == NULL)
161        _XtAllocError(NULL);
162    XtSetArg(arg, typed_arg->name, value);
163    XtGetValues(widget, &arg, 1);
164
165    from_val.size = from_size;
166    from_val.addr = (XPointer) value;
167    to_val.addr = (XPointer) typed_arg->value;
168    to_val.size = (unsigned) typed_arg->size;
169
170    if (!XtConvertAndStore(widget, from_type, &from_val,
171                           typed_arg->type, &to_val)) {
172        if (to_val.size > (unsigned) typed_arg->size) {
173            String params[2];
174            Cardinal num_params = 2;
175
176            params[0] = typed_arg->type;
177            params[1] = XtName(widget);
178            XtAppWarningMsg(XtWidgetToApplicationContext(widget),
179                            "insufficientSpace", XtNxtGetTypedArg,
180                            XtCXtToolkitError,
181                            "Insufficient space for converted type '%s' in widget '%s'",
182                            params, &num_params);
183        }
184        else {
185            String params[3];
186            Cardinal num_params = 3;
187
188            params[0] = from_type;
189            params[1] = typed_arg->type;
190            params[2] = XtName(widget);
191            XtAppWarningMsg(XtWidgetToApplicationContext(widget),
192                            "conversionFailed", XtNxtGetTypedArg,
193                            XtCXtToolkitError,
194                            "Type conversion (%s to %s) failed for widget '%s'",
195                            params, &num_params);
196        }
197    }
198    DEALLOCATE_LOCAL(value);
199}
200
201static int
202GetNestedArg(Widget widget,
203             XtTypedArgList avlist,
204             ArgList args,
205             XtResourceList resources,
206             Cardinal num_resources)
207{
208    int count = 0;
209
210    for (; avlist->name != NULL; avlist++) {
211        if (avlist->type != NULL) {
212            GetTypedArg(widget, avlist, resources, num_resources);
213        }
214        else if (strcmp(avlist->name, XtVaNestedList) == 0) {
215            count += GetNestedArg(widget, (XtTypedArgList) avlist->value,
216                                  args, resources, num_resources);
217        }
218        else {
219            (args + count)->name = avlist->name;
220            (args + count)->value = avlist->value;
221            ++count;
222        }
223    }
224
225    return (count);
226}
227
228void
229XtVaGetValues(Widget widget, ...)
230{
231    va_list var;
232    String attr;
233    ArgList args;
234    XtTypedArg typed_arg;
235    XtResourceList resources = (XtResourceList) NULL;
236    Cardinal num_resources;
237    int count, total_count, typed_count;
238
239    WIDGET_TO_APPCON(widget);
240
241    LOCK_APP(app);
242    va_start(var, widget);
243
244    _XtCountVaList(var, &total_count, &typed_count);
245
246    if (total_count != typed_count) {
247        size_t limit = (size_t) (total_count - typed_count);
248
249        args = XtMallocArray((Cardinal) limit, (Cardinal) sizeof(Arg));
250    }
251    else
252        args = NULL;            /* for lint; really unused */
253    va_end(var);
254
255    if (args != NULL) {
256        va_start(var, widget);
257        for (attr = va_arg(var, String), count = 0; attr != NULL;
258             attr = va_arg(var, String)) {
259            if (strcmp(attr, XtVaTypedArg) == 0) {
260                typed_arg.name = va_arg(var, String);
261                typed_arg.type = va_arg(var, String);
262                typed_arg.value = va_arg(var, XtArgVal);
263                typed_arg.size = va_arg(var, int);
264
265                if (resources == NULL) {
266                    XtGetResourceList(XtClass(widget), &resources,
267                                      &num_resources);
268                }
269
270                GetTypedArg(widget, &typed_arg, resources, num_resources);
271            }
272            else if (strcmp(attr, XtVaNestedList) == 0) {
273                if (resources == NULL) {
274                    XtGetResourceList(XtClass(widget), &resources,
275                                      &num_resources);
276                }
277
278                count += GetNestedArg(widget, va_arg(var, XtTypedArgList),
279                                      (args + count), resources, num_resources);
280            }
281            else {
282                args[count].name = attr;
283                args[count].value = va_arg(var, XtArgVal);
284                count++;
285            }
286        }
287        va_end(var);
288    }
289
290    XtFree((XtPointer) resources);
291
292    if (args != NULL) {
293        XtGetValues(widget, args, (Cardinal) count);
294        XtFree((XtPointer) args);
295    }
296    UNLOCK_APP(app);
297}
298
299void
300XtVaGetSubvalues(XtPointer base,
301                 XtResourceList resources,
302                 Cardinal num_resources,
303                 ...)
304{
305    va_list var;
306    ArgList args;
307    Cardinal num_args;
308    int total_count, typed_count;
309
310    va_start(var, num_resources);
311
312    _XtCountVaList(var, &total_count, &typed_count);
313
314    if (typed_count != 0) {
315        XtWarning
316            ("XtVaTypedArg is an invalid argument to XtVaGetSubvalues()\n");
317    }
318    va_end(var);
319
320    va_start(var, num_resources);
321    _XtVaToArgList((Widget) NULL, var, total_count, &args, &num_args);
322    va_end(var);
323
324    XtGetSubvalues(base, resources, num_resources, args, num_args);
325
326    XtFree((XtPointer) args);
327}
328