source: trunk/third/wcl/Wc/WcInvoke.c @ 8837

Revision 8837, 8.0 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8836, which included commits to RCS files with non-trunk default branches.
Line 
1#include <X11/Wc/COPY.h>
2
3/*
4* SCCS_data: %Z% %M% %I% %E% %U%
5*
6* Widget Creation Library - WcInvoke.c
7*
8* This module implements functions which allow an action to easily invoke
9* an equivalent callback, and a callback to easily invoke an equivalent
10* action.
11
12* WcInvokeCallback converts action arguments (params and num_params) into
13* callback arguments (a single string).  Any params with whitespace are
14* enclosed in double quotes( "like this").  The params are separated by single
15* blanks.  It then invokes the XtCallbackProc.
16
17* WcInvokeAction converts callback arguments (a single string) into action
18* arguments (params[] and num_params).  It then invokes the XtActionProc.
19* The clientData string is broken up on whitespace and commas.  Repeated
20* commas with only whitespace between causes NULL params.
21
22* WcInvokeNamedAction does the same, but it invokes XtCallAction to
23* allow actions to be named, rather than requiring a pointer to an
24* XtActionProc.
25
26*******************************************************************************
27*/
28
29#include <X11/Intrinsic.h>
30#include <X11/StringDefs.h>
31#include <X11/Wc/WcCreateP.h>
32
33/*  -- Conversion Methods
34=========================
35*/
36
37static char* WcxCvtParamsToClientData ( params, num_params )
38    char**    params;
39    Cardinal* num_params;
40{
41    char *cp, *pp, *clientData;
42    int  len, par, needToQuote;
43
44    if ( *num_params == 0 || params == (char**)0 )
45        return (char*)0;
46
47    /* Compute the total length of the required equivalent string.
48    ** Note that we need a separating blank, and we may need to
49    ** quote the arg, hence the `+ 3' as we increment the len.
50    */
51    for ( len = par = 0  ;  par < *num_params  ;  par++ )
52        if ( *(pp = params[par]) != '\0' )
53            for ( len +=3  ;  *pp  ;  pp++ )
54                ++len; /*looking for end of each parameter*/
55
56    clientData = cp = (char*)XtMalloc( len+1 );
57
58    /* Concatenate and possibly quote parameters into the clientData.
59    */
60    for ( par = 0  ;  par < *num_params  ;  par++ )
61    {
62        /* See if there are any special chars in
63        ** the param[par] which will require quoting.
64        */
65        for ( needToQuote = 0, pp = params[par]  ;  *pp  ;  pp++ )
66        {
67            if ( *pp == '\t' || *pp == ')' || *pp == ' '
68              || *pp == '\n' || *pp == ',' )
69            {
70                needToQuote++;
71                break;
72            }
73        }
74        if ( needToQuote ) *cp++ = '"';
75
76        for ( pp = params[par]  ;  *pp  ;  pp++ )
77            *cp++ = *pp;
78
79        if ( needToQuote ) *cp++ = '"';
80
81        *cp++ = ' ';
82    }
83    *--cp = '\0';       /* change final blank character to NUL */
84
85    return clientData;
86}
87
88typedef struct _WcxParamsStruct {
89    char**      params;
90    Cardinal    num_params;
91} WcxParamsStruct, *WcxParams;
92
93static void WcxCvtClientDataToParams ( widget, clientData, wcxParams )
94    Widget      widget;
95    char*       clientData;
96    WcxParams   wcxParams;      /* values filled in and returned */
97{
98    char*       params[MAX_ARGS];       /* must copy into alloc'd params[] */
99    Cardinal    num_params      = 0;
100    char*       data            = clientData;
101    int         len;
102    char        *cp, *end, quote;
103
104    /* Skip initial whitespace.
105    */
106    while ( *data && (*data  == ' ' || *data == '\t' || *data == '\n') )
107        data++;
108
109    while ( *data && num_params < MAX_ARGS )
110    {
111        /* Check first character of each argument.
112        */
113        switch (*data)
114        {
115        case ',' :
116            /* -- Null Argument is NULL param - NOT XtMalloc'd !!
117            */
118            params[num_params] = (char*)0;
119            data++;                             /* eat the comma */
120            break;
121
122        case '\"' : case '\'' :
123            /* -- Quoted argument: drop the quotes.
124            */
125            quote = *data;
126            data++;                             /* skip quote */
127
128            for ( len = 0, end = data ; *end && *end != quote ; end++ )
129                ++len; /* find length and end of quoted string */
130
131            if (len == 0)
132            {
133                /* nothing inside quotes is same as null argument.
134                */
135                params[num_params] = (char*)0;
136            }
137            else
138            {
139                /* end points to either the quote or the NULL terminator.
140                */
141                cp = params[num_params] = XtMalloc( len+1 );
142                while ( data < end )
143                    *cp++ = *data++;
144                *cp = '\0';
145            }
146
147            /* Now data points to either the quote or the NULL terminator.
148            */
149            if ( *data == '\0' )
150            {
151                WcWARN1( widget, "WcInvokeAction", "unbalQuote",
152                        "Wcl Warning: SomeCallback(%s) - unbalanced quotes.",
153                        clientData );
154            }
155            else
156            {
157                /* Skip trailing quote, whitespace, optional comma:
158                */
159                data++;
160                while (*data && *data  == ' ' || *data == '\t' || *data == '\n')
161                    data++;
162                if ( *data == ',')
163                    data++;
164            }
165
166            break;
167
168        default:
169            /* -- Non-quoted, non-null argument.  Always take first character,
170            ** then everything up to whitespace or parens as the parameter.
171            */
172            for  ( len = 1, end = data, end++ ;
173                   *end && *end != '\t' && *end != '\n' && *end != ' '
174                        && *end != ','  && *end != '('  && *end != ')' ; )
175                end++, len++;
176            cp = params[num_params] = XtMalloc( len+1 );
177            while ( data < end )
178                *cp++ = *data++;
179            *cp = '\0';
180
181            /* skip whitespace, optional comma
182            */
183            while (*data && *data  == ' ' || *data == '\t' || *data == '\n')
184                data++;
185            if ( *data == ',')
186                data++;
187
188            break;
189        }
190
191        /* skip whitespace which may follow optional comma we've already skipped
192        */
193        while (*data && *data  == ' ' || *data == '\t' || *data == '\n')
194            data++;
195
196        ++num_params;
197    }
198    wcxParams->num_params = num_params;
199
200    if ( 0 == num_params )
201        wcxParams->params = (char**)0;
202    else
203    {
204        /* Malloc storage for params, and copy from automatic params.
205        */
206        wcxParams->params = (char**)XtMalloc(sizeof(char*) * num_params);
207
208        while( num_params-- )
209        wcxParams->params[num_params] = params[num_params];
210    }
211}
212
213/*
214*******************************************************************************
215* Public definitions of WcInvokeCallback, WcInvokeAction, WcInvokeNamedAction
216*******************************************************************************
217*/
218
219/*  -- Invoke XtActionProc from XtCallbackProc
220*******************************************************************************
221*/
222
223void WcInvokeCallback( Callback, widget, params, num_params )
224    XtCallbackProc      Callback;
225    Widget              widget;
226    char**              params;
227    Cardinal*           num_params;
228{
229    if ( *num_params == 0 )
230        Callback( widget, (XtPointer)0, (XtPointer)0 );
231    else if ( *num_params == 1 )
232        Callback( widget, (XtPointer)params[0], (XtPointer)0 );
233    else
234    {
235        char* clientData = WcxCvtParamsToClientData( params, num_params );
236
237        Callback( widget, clientData, (XtPointer)0 );
238
239        if ( (char*)0 != clientData )
240            XtFree( clientData );
241    }
242}
243
244/*  -- Invoke XtActionProc from XtCallbackProc
245*******************************************************************************
246*/
247
248void WcInvokeAction( Action, widget, clientData )
249    XtActionProc Action;
250    Widget       widget;
251    char*        clientData;
252{
253    WcxParamsStruct     wcxParams;
254    Cardinal            num_params;     /* must copy cuz Action can change */
255
256    WcxCvtClientDataToParams( widget, clientData, &wcxParams );
257    num_params = wcxParams.num_params;
258
259    Action( widget, (XEvent*)0, wcxParams.params, &num_params );
260
261    if ( (char**)0 != wcxParams.params )
262    {
263        while ( wcxParams.num_params-- )
264            if ( (char*)0 != wcxParams.params[wcxParams.num_params] )
265                XtFree( wcxParams.params[wcxParams.num_params] );
266        XtFree( (char*)wcxParams.params );
267    }
268}
269
270/*  -- Invoke Named XtActionProc from XtCallbackProc
271*******************************************************************************
272*/
273
274void WcInvokeNamedAction( actionName, widget, clientData )
275    char*  actionName;
276    Widget widget;
277    char*  clientData;
278{
279#ifdef XtSpecificationRelease
280    WcxParamsStruct     wcxParams;
281    Cardinal            num_params;     /* must copy cuz Action can change */
282
283    WcxCvtClientDataToParams( widget, clientData, &wcxParams );
284    num_params = wcxParams.num_params;
285
286    XtCallActionProc( widget, actionName,
287                      (XEvent*)0, wcxParams.params, num_params );
288
289    if ( (char**)0 != wcxParams.params )
290    {
291        while ( wcxParams.num_params-- )
292            if ( (char*)0 != wcxParams.params[wcxParams.num_params] )
293                XtFree( wcxParams.params[wcxParams.num_params] );
294        XtFree( (char*)wcxParams.params );
295    }
296#else
297    WcWARN1( widget, "WcInvokeNamedAction", "oldXt",
298        "Wcl Warning: WcInvokeNamedAction(%s) requires Xt release 4 or later",
299        actionName );
300#endif
301}
Note: See TracBrowser for help on using the repository browser.