1 /*
2 * Motif
3 *
4 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5 *
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
16 * details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27
28 #ifdef REV_INFO
29 #ifndef lint
30 static char rcsid[] = "$XConsortium: Mrmwrefs.c /main/14 1996/11/13 14:07:43 drk $"
31 #endif
32 #endif
33
34
35 /*
36 *++
37 * FACILITY:
38 *
39 * UIL Resource Manager (URM):
40 *
41 * ABSTRACT:
42 *
43 * This module contains all routines which manage references to
44 * widgets which must be handled during or immediately after
45 * widget creation.
46 *
47 *--
48 */
49
50
51 /*
52 *
53 * INCLUDE FILES
54 *
55 */
56
57 #include <stdio.h>
58 #include <Mrm/MrmAppl.h>
59 #include <Mrm/Mrm.h>
60 #include "MrmMsgI.h"
61
62
63 /*
64 *++
65 *
66 * PROCEDURE DESCRIPTION:
67 *
68 * routine acquires a resource context, and initializes
69 * it for use a a widget reference structure.
70 *
71 * FORMAL PARAMETERS:
72 *
73 * wref_id to return pointer to initialized context
74 *
75 * IMPLICIT INPUTS:
76 *
77 * IMPLICIT OUTPUTS:
78 *
79 * FUNCTION VALUE:
80 *
81 * See UrmGetResourceContext
82 *
83 * SIDE EFFECTS:
84 *
85 *--
86 */
87
88 Cardinal
89 Urm__CW_InitWRef (URMResourceContextPtr *wref_id)
90 {
91 Cardinal result; /* function results */
92 URMWRefStructPtr refdsc; /* buffer as reference structure */
93
94
95 /*
96 * Acquire and initialize resource context
97 */
98 result = UrmGetResourceContext ((char *(*)())NULL,(void(*)())NULL,
99 500, wref_id);
100 if ( result != MrmSUCCESS ) return result;
101
102 refdsc = (URMWRefStructPtr) UrmRCBuffer (*wref_id);
103 refdsc->num_refs = 0;
104 refdsc->heap_size = 0;
105
106 return MrmSUCCESS;
107
108 }
109
110
111
112 /*
113 *++
114 *
115 * PROCEDURE DESCRIPTION:
116 *
117 * This routine adds a widget definition to the widget reference structure
118 *
119 * FORMAL PARAMETERS:
120 *
121 * wref_id widget reference structure
122 * w_name name of the widget to enter
123 * w_id widget id
124 *
125 * IMPLICIT INPUTS:
126 *
127 * IMPLICIT OUTPUTS:
128 *
129 * FUNCTION VALUE:
130 *
131 * See UrmResizeResourceContext
132 *
133 * SIDE EFFECTS:
134 *
135 *--
136 */
137
138 Cardinal
Urm__CW_AddWRef(URMResourceContextPtr wref_id,String w_name,Widget w_id)139 Urm__CW_AddWRef (URMResourceContextPtr wref_id,
140 String w_name,
141 Widget w_id)
142 {
143 /*
144 * Local variables
145 */
146 Cardinal result; /* function results */
147 URMWRefStructPtr refdsc; /* buffer as reference structure */
148 MrmCount name_bytes; /* # bytes for name & NULL */
149 MrmCount bytes_needed; /* # bytes for whole ref */
150 Cardinal ndx; /* entry index in structure */
151 MrmOffset new_offs; /* new offset in heap */
152 Cardinal old_size; /* old buffer size */
153 Cardinal new_size; /* new buffer size */
154 Cardinal delta; /* difference in size */
155 char *old_heap; /* old heap address */
156 char *new_heap; /* new heap address */
157
158
159 /*
160 * Set up pointers. Compute size needed and available, and resize structure
161 * if required. Name need not be entered if it is compiler-generated
162 * (contains non-legal character '-')
163 */
164 refdsc = (URMWRefStructPtr) UrmRCBuffer (wref_id);
165 name_bytes = strlen(w_name);
166 for ( ndx=0 ; ndx<name_bytes ; ndx++ )
167 if ( w_name[ndx] == '-' ) return MrmFAILURE;
168 name_bytes += 1;
169
170 bytes_needed = sizeof(URMWRef) + name_bytes;
171 bytes_needed = _FULLWORD(bytes_needed);
172 if ( bytes_needed > (UrmRCBufSize(wref_id)-UrmWRefBytesUsed(refdsc)) )
173 {
174 old_size = UrmRCBufSize (wref_id);
175 new_size = 2 * old_size;
176 delta = new_size - old_size;
177 result = UrmResizeResourceContext (wref_id, new_size);
178 if ( result != MrmSUCCESS ) return result;
179 refdsc = (URMWRefStructPtr) UrmRCBuffer (wref_id);
180 old_heap = (char *) refdsc+old_size-refdsc->heap_size;
181 new_heap = (char *) (old_heap+delta);
182 UrmBCopy (old_heap, new_heap, refdsc->heap_size);
183 for ( ndx=0 ; ndx<refdsc->num_refs ; ndx++ )
184 refdsc->refs[ndx].w_name_offs += delta;
185 }
186
187 /*
188 * There is enough space. Copy in the name, and set up the descriptor.
189 */
190 new_offs = UrmRCBufSize(wref_id) - refdsc->heap_size - name_bytes;
191 ndx = refdsc->num_refs;
192 refdsc->refs[ndx].w_id = w_id;
193 refdsc->refs[ndx].w_name_offs = new_offs;
194 refdsc->num_refs += 1;
195 refdsc->heap_size += name_bytes;
196 strcpy ((String)refdsc+new_offs, w_name);
197
198 return MrmSUCCESS;
199 }
200
201
202
203 /*
204 *++
205 *
206 * PROCEDURE DESCRIPTION:
207 *
208 * This routine searches the widget reference structure for a widget,
209 * and returns its id if found.
210 *
211 * FORMAL PARAMETERS:
212 *
213 * wref_id widget reference structure
214 * w_name name of widget to be found
215 * w_id_return to return widget id
216 *
217 * IMPLICIT INPUTS:
218 *
219 * IMPLICIT OUTPUTS:
220 *
221 * FUNCTION VALUE:
222 *
223 * MrmSUCCESS - found, id is returned
224 * MrmNOT_FOUND - not found
225 *
226 * SIDE EFFECTS:
227 *
228 *--
229 */
230
231 Cardinal
Urm__CW_FindWRef(URMResourceContextPtr wref_id,String w_name,Widget * w_id_return)232 Urm__CW_FindWRef (URMResourceContextPtr wref_id,
233 String w_name,
234 Widget *w_id_return)
235 {
236 /*
237 * Local variables
238 */
239 URMWRefStructPtr refdsc; /* buffer as reference structure */
240 int ndx; /* loop index */
241
242
243 /*
244 * Search the vector for the name, returning the id if found. Search
245 * backwards, so the most recent definitions are searched first.
246 */
247 refdsc = (URMWRefStructPtr) UrmRCBuffer (wref_id);
248 for ( ndx=refdsc->num_refs-1 ; ndx>=0 ; ndx-- )
249 if ( strcmp(w_name,UrmWRefNameN(refdsc,ndx)) == 0 )
250 {
251 *w_id_return = UrmWRefIdN (refdsc, ndx);
252 return MrmSUCCESS;
253 }
254 return MrmNOT_FOUND;
255
256 }
257
258
259
260 /*
261 *++
262 *
263 * PROCEDURE DESCRIPTION:
264 *
265 * This routine creates a SetValues descriptor, initializes it from
266 * the resource descriptor, and appends it to the list. The id of the
267 * widget to be modified is set NULL to identify this descriptor as
268 * one to be set.
269 *
270 * FORMAL PARAMETERS:
271 *
272 * file_id file from which to uncompress argtag
273 * svlist list of SetValues of descriptor
274 * w_name widget name
275 * argtag Argument tag code
276 * argname Argument tag name if code is URMcUnknown
277 *
278 * IMPLICIT INPUTS:
279 *
280 * IMPLICIT OUTPUTS:
281 *
282 * FUNCTION VALUE:
283 *
284 * SIDE EFFECTS:
285 *
286 *--
287 */
288
289 void
Urm__CW_AppendSVWidgetRef(IDBFile file_id,URMPointerListPtr * svlist,String w_name,MrmCode argtag,String argname)290 Urm__CW_AppendSVWidgetRef (IDBFile file_id,
291 URMPointerListPtr *svlist,
292 String w_name,
293 MrmCode argtag,
294 String argname)
295 {
296 /*
297 * Local variables
298 */
299 URMSetValuesDescPtr svdesc ; /* new descriptor */
300 Cardinal uncmp_res; /* function result */
301 char errmsg[300];
302
303
304 /*
305 * Initialize the pointer list if required
306 */
307 if ( *svlist == NULL )
308 UrmPlistInit (10, svlist) ;
309
310 /*
311 * Create and set the new descriptor. The argument tag must be uncompressed
312 * into its string now, when the compression code for it is available from the
313 * file. If the tag code is unknown, then the string must be copied into
314 * allocated memory.
315 */
316 svdesc = (URMSetValuesDescPtr) XtMalloc (sizeof(URMSetValuesDesc)) ;
317 svdesc->setw = NULL ;
318 svdesc->type = URMsvWidgetRef ;
319 svdesc->tagcode = argtag ;
320 if ( argtag == UilMrmUnknownCode )
321 {
322 svdesc->tagname = (String) XtMalloc (strlen(argname)+1);
323 strcpy (svdesc->tagname, argname);
324 }
325 else
326 {
327 uncmp_res = Urm__UncompressCode (file_id, argtag, &svdesc->tagname);
328 if ( uncmp_res != MrmSUCCESS )
329 {
330 sprintf (errmsg, _MrmMMsg_0108, argtag);
331 XtFree ((char *)svdesc);
332 Urm__UT_Error ("Urm__CW_AppendSVWidgetRef", errmsg,
333 NULL, NULL, MrmNOT_FOUND);
334 return;
335 }
336 }
337 svdesc->done = FALSE ;
338 svdesc->sv.wname = Urm__UT_AllocString (w_name) ;
339 UrmPlistAppendPointer (( URMPointerListPtr)*svlist, (XtPointer) svdesc) ;
340
341 }
342
343
344
345 /*
346 *++
347 *
348 * PROCEDURE DESCRIPTION:
349 *
350 * This routine creates a SetValues descriptor, initializes it from
351 * the resource descriptor, adds the callback list and appends it to the
352 * list. The id of the
353 * widget to be modified is set NULL to identify this descriptor as
354 * one to be set.
355 *
356 * FORMAL PARAMETERS:
357 *
358 * file_id file from which to uncompress argtag
359 * svlist list of SetValues of descriptor
360 * w_name widget name
361 * argtag Argument tag code
362 * argname Argument tag name if code is URMcUnknown
363 * cbptr Callback description pointer
364 *
365 * IMPLICIT INPUTS:
366 *
367 * IMPLICIT OUTPUTS:
368 *
369 * FUNCTION VALUE:
370 *
371 * SIDE EFFECTS:
372 *
373 *--
374 */
375
376 void
Urm__CW_AppendCBSVWidgetRef(IDBFile file_id,URMPointerListPtr * svlist,RGMCallbackDescPtr cbptr,MrmCode argtag,String argname)377 Urm__CW_AppendCBSVWidgetRef (IDBFile file_id,
378 URMPointerListPtr *svlist,
379 RGMCallbackDescPtr cbptr,
380 MrmCode argtag,
381 String argname)
382 {
383 URMSetValuesDescPtr svdesc ; /* new descriptor */
384 RGMCallbackDescPtr cbdesc; /* Copy of descriptor */
385 MrmSize descsize; /* Size of descriptor to be copied */
386 Cardinal uncmp_res; /* function result */
387 char errmsg[300];
388
389
390 /*
391 * Initialize the pointer list if required
392 */
393 if ( *svlist == NULL )
394 UrmPlistInit (10, svlist) ;
395
396 /*
397 * Create and set the new descriptor. The argument tag must be uncompressed
398 * into its string now, when the compression code for it is available from the
399 * file. If the tag code is unknown, then the string must be copied into
400 * allocated memory.
401 */
402 svdesc = (URMSetValuesDescPtr) XtMalloc (sizeof(URMSetValuesDesc)) ;
403 svdesc->setw = NULL ;
404 svdesc->type = URMsvCallBackList ;
405 svdesc->tagcode = argtag ;
406 if ( argtag == UilMrmUnknownCode )
407 {
408 svdesc->tagname = (String) XtMalloc (strlen(argname)+1);
409 strcpy (svdesc->tagname, argname);
410 }
411 else
412 {
413 uncmp_res = Urm__UncompressCode (file_id, argtag, &svdesc->tagname);
414 if ( uncmp_res != MrmSUCCESS )
415 {
416 sprintf (errmsg, _MrmMMsg_0108, argtag);
417 XtFree ((char *)svdesc);
418 Urm__UT_Error ("Urm__CW_AppendCBSVWidgetRef", errmsg,
419 NULL, NULL, MrmNOT_FOUND);
420 return;
421 }
422 }
423 svdesc->done = FALSE ;
424 /* Copy callback descriptor */
425 descsize = sizeof(RGMCallbackDesc) + (cbptr->count)*sizeof(RGMCallbackItem);
426 cbdesc = (RGMCallbackDescPtr)XtMalloc(descsize);
427 memcpy(cbdesc, cbptr, descsize);
428 svdesc->sv.callbacks = cbdesc ;
429 UrmPlistAppendPointer (( URMPointerListPtr)*svlist, (XtPointer) svdesc) ;
430 }
431
432
433
434 /*
435 *++
436 *
437 * PROCEDURE DESCRIPTION:
438 *
439 * This routine updates a SetValues list from a just-created widget.
440 * Any entry whose modified widget field is NULL is has the modified
441 * widget set to the given widget.
442 *
443 * FORMAL PARAMETERS:
444 *
445 * svlist List of SetValues descriptors
446 * cur_id current widget to be entered in descriptors
447 *
448 * IMPLICIT INPUTS:
449 *
450 * IMPLICIT OUTPUTS:
451 *
452 * FUNCTION VALUE:
453 *
454 * SIDE EFFECTS:
455 *
456 *--
457 */
458
459 void
Urm__CW_UpdateSVWidgetRef(URMPointerListPtr * svlist,Widget cur_id)460 Urm__CW_UpdateSVWidgetRef (URMPointerListPtr *svlist,
461 Widget cur_id)
462 {
463 /*
464 * Local variables
465 */
466 int ndx ; /* loop index */
467 URMSetValuesDescPtr svdesc ; /* current SetValues descriptor */
468
469 /*
470 * Loop over all descriptors. Enter the current widget as appropriate.
471 * Since each descriptor is used only once, immediately free any
472 * allocated tag string.
473 */
474 for ( ndx=0 ; ndx<UrmPlistNum(*svlist) ; ndx++ )
475 {
476 svdesc = (URMSetValuesDescPtr) UrmPlistPtrN(*svlist,ndx) ;
477 if ( svdesc->done ) continue ;
478 if ( svdesc->setw == NULL )
479 svdesc->setw = cur_id ;
480 }
481 }
482
483 /*
484 *++
485 *
486 * PROCEDURE DESCRIPTION:
487 *
488 * This routine updates a SetValues list from a just-created widget.
489 * Any entry whose modified widget field is NULL is has the modified
490 * widget set to the given widget. It also uses this widget to
491 * immediately update any previously saved widget which can be
492 * resolved with this new widget and to update widget references
493 * in callback items.
494 *
495 * FORMAL PARAMETERS:
496 *
497 * svlist List of SetValues descriptors
498 * cur_name current widget's name
499 * cur_id current widget to be entered in descriptors
500 *
501 * IMPLICIT INPUTS:
502 *
503 * IMPLICIT OUTPUTS:
504 *
505 * FUNCTION VALUE:
506 *
507 * SIDE EFFECTS:
508 *
509 *--
510 */
511
512 void
Urm__CW_ResolveSVWidgetRef(URMPointerListPtr * svlist,String cur_name,Widget cur_id)513 Urm__CW_ResolveSVWidgetRef (URMPointerListPtr *svlist,
514 String cur_name,
515 Widget cur_id)
516 {
517 /*
518 * Local variables
519 */
520 int ndx ; /* loop index */
521 int cbndx; /* callback list index */
522 URMSetValuesDescPtr svdesc ; /* current SetValues descriptor */
523 Arg args[1] ; /* SetValues argument list */
524 RGMCallbackDescPtr cbdesc; /* Current callback descriptor */
525 RGMCallbackItemPtr items; /* Array of callback items */
526
527 /*
528 * Loop over all descriptors. Enter the current widget as appropriate.
529 * Since each descriptor is used only once, immediately free any
530 * allocated tag string.
531 */
532 for ( ndx=0 ; ndx<UrmPlistNum(*svlist) ; ndx++ )
533 {
534 svdesc = (URMSetValuesDescPtr) UrmPlistPtrN(*svlist,ndx) ;
535 if ( svdesc->done ) continue ;
536 if ( svdesc->setw == NULL )
537 {
538 svdesc->setw = cur_id ;
539 continue ;
540 }
541 switch (svdesc->type)
542 {
543 case URMsvWidgetRef:
544 if ( strcmp(cur_name,svdesc->sv.wname) == 0 )
545 {
546 args[0].name = svdesc->tagname ;
547 args[0].value = (XtArgVal) cur_id ;
548 XtSetValues (svdesc->setw, args, 1) ;
549 svdesc->done = TRUE ;
550 if ( svdesc->tagcode == UilMrmUnknownCode )
551 {
552 XtFree ((char *)svdesc->tagname);
553 svdesc->tagname = NULL;
554 }
555 /* Does this really need to be freed here? */
556 XtFree(svdesc->sv.wname);
557 svdesc->sv.wname = NULL;
558 }
559 break;
560
561 case URMsvCallBackList:
562 cbdesc = (RGMCallbackDescPtr)svdesc->sv.callbacks;
563 items = cbdesc->item;
564
565 /* Loop through callback items, resolving where possible */
566 for (cbndx = 0; cbndx < cbdesc->count; cbndx++)
567 {
568 if (items[cbndx].runtime.resolved) continue;
569
570 if (strcmp(cur_name, items[cbndx].runtime.wname) == 0)
571 /* Finish resolving the callback item. */
572 {
573 items[cbndx].runtime.callback.closure = (XtPointer)cur_id;
574 items[cbndx].runtime.resolved = TRUE;
575 cbdesc->unres_ref_count--;
576 /* Free the widget name. */
577 XtFree(items[cbndx].runtime.wname);
578 items[cbndx].runtime.wname = NULL;
579 }
580 }
581
582 if (cbdesc->unres_ref_count == 0)
583 {
584 /* Move individual items so array functions as callback list */
585 XtCallbackRec *callbacks = (XtCallbackRec *)items;
586
587 for (cbndx = 0; cbndx <= cbdesc->count; cbndx++)
588 /* <= so that null item is copied. */
589 {
590 callbacks[cbndx].callback = (XtCallbackProc)
591 items[cbndx].runtime.callback.callback;
592 callbacks[cbndx].closure = (XtPointer)
593 items[cbndx].runtime.callback.closure;
594 }
595
596
597 args[0].name = svdesc->tagname;
598 args[0].value = (XtArgVal)items;
599 XtSetValues(svdesc->setw, args, 1);
600 svdesc->done = TRUE;
601
602 /* Free memory. */
603 if ( svdesc->tagcode == UilMrmUnknownCode )
604 {
605 XtFree ((char *)svdesc->tagname);
606 svdesc->tagname = NULL;
607 }
608
609 XtFree((char *)svdesc->sv.callbacks);
610 svdesc->sv.callbacks = NULL;
611 }
612 break;
613
614 default:
615 continue;
616 }
617 }
618 }
619
620 /*
621 *++
622 *
623 * PROCEDURE DESCRIPTION:
624 *
625 * This routine frees a SetValues descriptor.
626 *
627 * FORMAL PARAMETERS:
628 *
629 * svdesc SetValues descriptor
630 *
631 * IMPLICIT INPUTS:
632 *
633 * IMPLICIT OUTPUTS:
634 *
635 * FUNCTION VALUE:
636 *
637 * SIDE EFFECTS:
638 *
639 *--
640 */
641
642 void
Urm__CW_FreeSetValuesDesc(URMSetValuesDescPtr svdesc)643 Urm__CW_FreeSetValuesDesc (URMSetValuesDescPtr svdesc)
644 {
645 if ( (svdesc->type == URMsvWidgetRef) && (svdesc->sv.wname != NULL) )
646 XtFree ((char *)svdesc->sv.wname);
647
648 XtFree ((char *)svdesc);
649 }
650