1 /*
2 * bltConfig.c --
3 *
4 * This module implements custom configuration options for the BLT
5 * toolkit.
6 *
7 * Copyright 1991-1998 Lucent Technologies, Inc.
8 *
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby
11 * granted, provided that the above copyright notice appear in all
12 * copies and that both that the copyright notice and warranty
13 * disclaimer appear in supporting documentation, and that the names
14 * of Lucent Technologies any of their entities not be used in
15 * advertising or publicity pertaining to distribution of the software
16 * without specific, written prior permission.
17 *
18 * Lucent Technologies disclaims all warranties with regard to this
19 * software, including all implied warranties of merchantability and
20 * fitness. In no event shall Lucent Technologies be liable for any
21 * special, indirect or consequential damages or any damages
22 * whatsoever resulting from loss of use, data or profits, whether in
23 * an action of contract, negligence or other tortuous action, arising
24 * out of or in connection with the use or performance of this
25 * software.
26 */
27
28 #include "bltInt.h"
29 #if defined(__STDC__)
30 #include <stdarg.h>
31 #else
32 #include <varargs.h>
33 #endif
34
35 #include "bltTile.h"
36
37 static int StringToFill _ANSI_ARGS_((ClientData clientData,
38 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
39 int flags));
40 static char *FillToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
41 Tcl_FreeProc **));
42
43 Tk_CustomOption bltFillOption =
44 {
45 StringToFill, FillToString, (ClientData)0
46 };
47
48 static int StringToPad _ANSI_ARGS_((ClientData clientData,
49 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
50 int offset));
51 static char *PadToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
52 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
53
54 Tk_CustomOption bltPadOption =
55 {
56 StringToPad, PadToString, (ClientData)0
57 };
58
59 static int StringToDistance _ANSI_ARGS_((ClientData clientData,
60 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
61 int flags));
62 static char *DistanceToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
63 Tcl_FreeProc **));
64
65 Tk_CustomOption bltDistanceOption =
66 {
67 StringToDistance, DistanceToString, (ClientData)PIXELS_NONNEGATIVE
68 };
69
70 Tk_CustomOption bltPositiveDistanceOption =
71 {
72 StringToDistance, DistanceToString, (ClientData)PIXELS_POSITIVE
73 };
74
75 Tk_CustomOption bltAnyDistanceOption =
76 {
77 StringToDistance, DistanceToString, (ClientData)PIXELS_ANY
78 };
79
80 static int StringToCount _ANSI_ARGS_((ClientData clientData,
81 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
82 int flags));
83 static char *CountToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
84 Tcl_FreeProc **));
85
86 Tk_CustomOption bltCountOption =
87 {
88 StringToCount, CountToString, (ClientData)COUNT_NONNEGATIVE
89 };
90
91 Tk_CustomOption bltPositiveCountOption =
92 {
93 StringToCount, CountToString, (ClientData)COUNT_POSITIVE
94 };
95
96 static int StringToDashes _ANSI_ARGS_((ClientData, Tcl_Interp *, Tk_Window,
97 char *, char *, int));
98 static char *DashesToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
99 Tcl_FreeProc **));
100
101 Tk_CustomOption bltDashesOption =
102 {
103 StringToDashes, DashesToString, (ClientData)0
104 };
105
106 static int StringToShadow _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
107 Tk_Window tkwin, char *string, char *widgRec, int offset));
108 static char *ShadowToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
109 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
110
111 Tk_CustomOption bltShadowOption =
112 {
113 StringToShadow, ShadowToString, (ClientData)0
114 };
115
116 static int StringToGradient _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
117 Tk_Window tkwin, char *string, char *widgRec, int offset));
118 static char *GradientToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
119 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
120
121 Tk_CustomOption bltGradientOption =
122 {
123 StringToGradient, GradientToString, (ClientData)0
124 };
125
126 static int StringToUid _ANSI_ARGS_((ClientData clientData,
127 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
128 int flags));
129 static char *UidToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
130 Tcl_FreeProc **));
131
132 Tk_CustomOption bltUidOption =
133 {
134 StringToUid, UidToString, (ClientData)0
135 };
136
137 static int StringToState _ANSI_ARGS_((ClientData clientData,
138 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
139 int flags));
140 static char *StateToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
141 Tcl_FreeProc **));
142
143 Tk_CustomOption bltStateOption =
144 {
145 StringToState, StateToString, (ClientData)0
146 };
147
148 static int StringToList _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
149 Tk_Window tkwin, char *string, char *widgRec, int flags));
150 static char *ListToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
151 Tcl_FreeProc **));
152
153 Tk_CustomOption bltListOption =
154 {
155 StringToList, ListToString, (ClientData)0
156 };
157
158 static int StringToTile _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
159 Tk_Window tkwin, char *value, char *widgRec, int flags));
160 static char *TileToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
161 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
162
163 Tk_CustomOption bltTileOption =
164 {
165 StringToTile, TileToString, (ClientData)0
166 };
167
168 static int SetObjTile _ANSI_ARGS_((ClientData clientData,
169 Tcl_Interp *interp, Tk_Window tkwin,
170 Tcl_Obj **value, char *recordPtr, int internalOffset,
171 char *oldInternalPtr, int flags));
172 static Tcl_Obj *GetObjTile _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
173 char *recordPtr, int internalOffset));
174 static void RestoreObjTile _ANSI_ARGS_((ClientData clientData,
175 Tk_Window tkwin, char *internalPtr,
176 char *oldInternalPtr));
177 static void FreeObjTile _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
178 char *internalPtr));
179
180 Tk_ObjCustomOption bltCustomTileOption = {
181 "tile", /* name */
182 SetObjTile, /* setProc */
183 GetObjTile, /* getProc */
184 RestoreObjTile, /* restoreProc */
185 FreeObjTile, /* freeProc */
186 0
187 };
188
189
190 static void
FreeObjTile(clientData,tkwin,internalPtr)191 FreeObjTile(clientData, tkwin, internalPtr)
192 ClientData clientData;
193 Tk_Window tkwin;
194 char *internalPtr;
195 {
196 Blt_Tile tilePtr = (Blt_Tile)internalPtr;
197 if (tilePtr != NULL) Blt_FreeTile(tilePtr);
198 }
199
200 /*
201 *----------------------------------------------------------------------
202 *
203 * GetObjTile -
204 *
205 * Converts an internal boolean combination of "tile"into a
206 * a Tcl string obj.
207 *
208 * Results:
209 * Tcl_Obj containing the string representation of the tile value.
210 *
211 * Side effects:
212 * Creates a new Tcl_Obj.
213 *
214 *----------------------------------------------------------------------
215 */
216
217 static Tcl_Obj *
GetObjTile(clientData,tkwin,recordPtr,internalOffset)218 GetObjTile(clientData, tkwin, recordPtr, internalOffset)
219 ClientData clientData;
220 Tk_Window tkwin;
221 char *recordPtr; /* Pointer to widget record. */
222 int internalOffset; /* Offset within *recordPtr containing the
223 * tile value. */
224 {
225 Blt_Tile tile = *(Blt_Tile *)(recordPtr + internalOffset);
226 char * name;
227 name = Blt_NameOfTile(tile);
228 return Tcl_NewStringObj(name?name:"", -1);
229 }
230
231 /*
232 *----------------------------------------------------------------------
233 *
234 * SetObjTile --
235 *
236 * Converts a Tcl_Obj representing a widgets tile.
237 *
238 * Results:
239 * Standard Tcl result.
240 *
241 * Side effects:
242 * May store the integer value into the internal representation
243 * pointer. May change the pointer to the Tcl_Obj to NULL to indicate
244 * that the specified string was empty and that is acceptable.
245 *
246 *----------------------------------------------------------------------
247 */
248
249 static int
SetObjTile(clientData,interp,tkwin,value,recordPtr,internalOffset,oldInternalPtr,flags)250 SetObjTile(clientData, interp, tkwin, value, recordPtr, internalOffset,
251 oldInternalPtr, flags)
252 ClientData clientData;
253 Tcl_Interp *interp; /* Current interp; may be used for errors. */
254 Tk_Window tkwin; /* Window for which option is being set. */
255 Tcl_Obj **value; /* Pointer to the pointer to the value object.
256 * We use a pointer to the pointer because
257 * we may need to return a value (NULL). */
258 char *recordPtr; /* Pointer to storage for the widget record. */
259 int internalOffset; /* Offset within *recordPtr at which the
260 internal value is to be stored. */
261 char *oldInternalPtr; /* Pointer to storage for the old value. */
262 int flags; /* Flags for the option, set Tk_SetOptions. */
263 {
264 int length = 0;
265 char *string, *internalPtr;
266 Blt_Tile *tilePtr;
267 Blt_Tile tile, oldTile;
268
269 if (internalOffset<0 || *value == NULL) { return TCL_ERROR; }
270 string = Tcl_GetStringFromObj(*value, &length);
271
272 internalPtr = recordPtr+internalOffset;
273
274 if (length<=0 && (!(flags & TK_OPTION_NULL_OK))) {
275 return TCL_ERROR;
276 }
277 tilePtr = (Blt_Tile*)internalPtr;
278
279 oldTile = *tilePtr;
280 tile = NULL;
281 if ((string != NULL) && (*string != '\0')) {
282 if (Blt_GetTile(interp, tkwin, string, &tile) != TCL_OK) {
283 return TCL_ERROR;
284 }
285 }
286 if (oldTile != NULL && oldTile != *((Blt_Tile*)oldInternalPtr)) {
287 /* multiple -tile options. */
288 Blt_FreeTile(oldTile);
289 }
290 *tilePtr = tile;
291
292 return TCL_OK;
293 }
294
295 /*
296 *----------------------------------------------------------------------
297 *
298 * RestoreObjTile --
299 *
300 * Restore a tile option value from a saved value.
301 *
302 * Results:
303 * None.
304 *
305 * Side effects:
306 * Restores the old value.
307 *
308 *----------------------------------------------------------------------
309 */
310
311 static void
RestoreObjTile(clientData,tkwin,internalPtr,oldInternalPtr)312 RestoreObjTile(clientData, tkwin, internalPtr, oldInternalPtr)
313 ClientData clientData;
314 Tk_Window tkwin;
315 char *internalPtr; /* Pointer to storage for value. */
316 char *oldInternalPtr; /* Pointer to old value. */
317 {
318 Blt_Tile *tilePtr = (Blt_Tile *)internalPtr;
319 Blt_Tile *oldTilePtr = (Blt_Tile *)oldInternalPtr;
320 if (*tilePtr != NULL && *oldTilePtr != *tilePtr) {
321 Blt_FreeTile(*tilePtr);
322 }
323 *tilePtr = *oldTilePtr;
324 }
325 /*
326 *----------------------------------------------------------------------
327 *
328 * Blt_NameOfFill --
329 *
330 * Converts the integer representing the fill direction into a string.
331 *
332 *----------------------------------------------------------------------
333 */
334 char *
Blt_NameOfFill(fill)335 Blt_NameOfFill(fill)
336 int fill;
337 {
338 switch (fill) {
339 case FILL_X:
340 return "x";
341 case FILL_Y:
342 return "y";
343 case FILL_NONE:
344 return "none";
345 case FILL_BOTH:
346 return "both";
347 default:
348 return "unknown value";
349 }
350 }
351
352 /*
353 *----------------------------------------------------------------------
354 *
355 * StringToFill --
356 *
357 * Converts the fill style string into its numeric representation.
358 *
359 * Valid style strings are:
360 *
361 * "none" Use neither plane.
362 * "x" X-coordinate plane.
363 * "y" Y-coordinate plane.
364 * "both" Use both coordinate planes.
365 *
366 *----------------------------------------------------------------------
367 */
368 /*ARGSUSED*/
369 static int
StringToFill(clientData,interp,tkwin,string,widgRec,offset)370 StringToFill(clientData, interp, tkwin, string, widgRec, offset)
371 ClientData clientData; /* Not used. */
372 Tcl_Interp *interp; /* Interpreter to send results back to */
373 Tk_Window tkwin; /* Not used. */
374 char *string; /* Fill style string */
375 char *widgRec; /* Cubicle structure record */
376 int offset; /* Offset of style in record */
377 {
378 int *fillPtr = (int *)(widgRec + offset);
379 unsigned int length;
380 char c;
381
382 c = string[0];
383 length = strlen(string);
384 if ((c == 'n') && (strncmp(string, "none", length) == 0)) {
385 *fillPtr = FILL_NONE;
386 } else if ((c == 'x') && (strncmp(string, "x", length) == 0)) {
387 *fillPtr = FILL_X;
388 } else if ((c == 'y') && (strncmp(string, "y", length) == 0)) {
389 *fillPtr = FILL_Y;
390 } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) {
391 *fillPtr = FILL_BOTH;
392 } else {
393 Tcl_AppendResult(interp, "bad argument \"", string,
394 "\": should be \"none\", \"x\", \"y\", or \"both\"", (char *)NULL);
395 return TCL_ERROR;
396 }
397 return TCL_OK;
398 }
399
400 /*
401 *----------------------------------------------------------------------
402 *
403 * FillToString --
404 *
405 * Returns the fill style string based upon the fill flags.
406 *
407 * Results:
408 * The fill style string is returned.
409 *
410 *----------------------------------------------------------------------
411 */
412 /*ARGSUSED*/
413 static char *
FillToString(clientData,tkwin,widgRec,offset,freeProcPtr)414 FillToString(clientData, tkwin, widgRec, offset, freeProcPtr)
415 ClientData clientData; /* Not used. */
416 Tk_Window tkwin; /* Not used. */
417 char *widgRec; /* Widget structure record */
418 int offset; /* Offset of fill in widget record */
419 Tcl_FreeProc **freeProcPtr; /* Not used. */
420 {
421 int fill = *(int *)(widgRec + offset);
422
423 return Blt_NameOfFill(fill);
424 }
425
426 /*
427 *----------------------------------------------------------------------
428 *
429 * Blt_StringToFlag --
430 *
431 * Converts the fill style string into its numeric representation.
432 *
433 *----------------------------------------------------------------------
434 */
435 /*ARGSUSED*/
436 int
Blt_StringToFlag(clientData,interp,tkwin,string,widgRec,offset)437 Blt_StringToFlag(clientData, interp, tkwin, string, widgRec, offset)
438 ClientData clientData; /* Bit mask to be tested in status word */
439 Tcl_Interp *interp; /* Interpreter to send results back to */
440 Tk_Window tkwin; /* Not used. */
441 char *string; /* Fill style string */
442 char *widgRec; /* Cubicle structure record */
443 int offset; /* Offset of style in record */
444 {
445 unsigned int mask = (unsigned int)clientData; /* Bit to be tested */
446 int *flagPtr = (int *)(widgRec + offset);
447 int bool;
448
449 if (Tcl_GetBoolean(interp, string, &bool) != TCL_OK) {
450 return TCL_ERROR;
451 }
452 if (bool) {
453 *flagPtr |= mask;
454 } else {
455 *flagPtr &= ~mask;
456 }
457 return TCL_OK;
458 }
459
460 /*
461 *----------------------------------------------------------------------
462 *
463 * Blt_FlagToString --
464 *
465 * Returns the fill style string based upon the fill flags.
466 *
467 * Results:
468 * The fill style string is returned.
469 *
470 *----------------------------------------------------------------------
471 */
472 /*ARGSUSED*/
473 char *
Blt_FlagToString(clientData,tkwin,widgRec,offset,freeProcPtr)474 Blt_FlagToString(clientData, tkwin, widgRec, offset, freeProcPtr)
475 ClientData clientData; /* Bit mask to be test in status word */
476 Tk_Window tkwin; /* Not used. */
477 char *widgRec; /* Widget structure record */
478 int offset; /* Offset of fill in widget record */
479 Tcl_FreeProc **freeProcPtr; /* Not Used. */
480 {
481 unsigned int mask = (unsigned int)clientData; /* Bit to be tested */
482 unsigned int bool = *(unsigned int *)(widgRec + offset);
483
484 return (bool & mask) ? "1" : "0";
485 }
486
487
488 /*
489 *----------------------------------------------------------------------
490 *
491 * Blt_GetPixels --
492 *
493 * Like Tk_GetPixels, but checks for negative, zero.
494 *
495 * Results:
496 * A standard Tcl result.
497 *
498 *----------------------------------------------------------------------
499 */
500 int
Blt_GetPixels(interp,tkwin,string,check,valuePtr)501 Blt_GetPixels(interp, tkwin, string, check, valuePtr)
502 Tcl_Interp *interp;
503 Tk_Window tkwin;
504 char *string;
505 int check; /* Can be PIXELS_POSITIVE, PIXELS_NONNEGATIVE,
506 * or PIXELS_ANY, */
507 int *valuePtr;
508 {
509 int length;
510
511 if (Tk_GetPixels(interp, tkwin, string, &length) != TCL_OK) {
512 return TCL_ERROR;
513 }
514 if (length >= SHRT_MAX) {
515 Tcl_AppendResult(interp, "bad distance \"", string, "\": ",
516 "too big to represent", (char *)NULL);
517 return TCL_ERROR;
518 }
519 switch (check) {
520 case PIXELS_NONNEGATIVE:
521 if (length < 0) {
522 Tcl_AppendResult(interp, "bad distance \"", string, "\": ",
523 "can't be negative", (char *)NULL);
524 return TCL_ERROR;
525 }
526 break;
527 case PIXELS_POSITIVE:
528 if (length <= 0) {
529 Tcl_AppendResult(interp, "bad distance \"", string, "\": ",
530 "must be positive", (char *)NULL);
531 return TCL_ERROR;
532 }
533 break;
534 case PIXELS_ANY:
535 break;
536 }
537 *valuePtr = length;
538 return TCL_OK;
539 }
540
541 /*
542 *----------------------------------------------------------------------
543 *
544 * StringToDistance --
545 *
546 * Like TK_CONFIG_PIXELS, but adds an extra check for negative
547 * values.
548 *
549 *----------------------------------------------------------------------
550 */
551 /*ARGSUSED*/
552 static int
StringToDistance(clientData,interp,tkwin,string,widgRec,offset)553 StringToDistance(clientData, interp, tkwin, string, widgRec, offset)
554 ClientData clientData; /* Indicated how to check distance */
555 Tcl_Interp *interp; /* Interpreter to send results back to */
556 Tk_Window tkwin; /* Window */
557 char *string; /* Pixel value string */
558 char *widgRec; /* Widget record */
559 int offset; /* Offset of pixel size in record */
560 {
561 int *valuePtr = (int *)(widgRec + offset);
562 return Blt_GetPixels(interp, tkwin, string, (int)clientData, valuePtr);
563 }
564
565 /*
566 *----------------------------------------------------------------------
567 *
568 * DistanceToString --
569 *
570 * Returns the string representing the positive pixel size.
571 *
572 * Results:
573 * The pixel size string is returned.
574 *
575 *----------------------------------------------------------------------
576 */
577 /*ARGSUSED*/
578 static char *
DistanceToString(clientData,tkwin,widgRec,offset,freeProcPtr)579 DistanceToString(clientData, tkwin, widgRec, offset, freeProcPtr)
580 ClientData clientData; /* Not used. */
581 Tk_Window tkwin; /* Not used. */
582 char *widgRec; /* Widget structure record */
583 int offset; /* Offset in widget record */
584 Tcl_FreeProc **freeProcPtr; /* Not used. */
585 {
586 int value = *(int *)(widgRec + offset);
587 char *result;
588
589 result = Blt_Strdup(Blt_Itoa(value));
590 assert(result);
591 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
592 return result;
593 }
594
595 int
Blt_GetInt(interp,string,check,valuePtr)596 Blt_GetInt(interp, string, check, valuePtr)
597 Tcl_Interp *interp;
598 char *string;
599 int check; /* Can be COUNT_POSITIVE, COUNT_NONNEGATIVE,
600 * or COUNT_ANY, */
601 int *valuePtr;
602 {
603 int count;
604
605 if (Tcl_GetInt(interp, string, &count) != TCL_OK) {
606 return TCL_ERROR;
607 }
608 switch (check) {
609 case COUNT_NONNEGATIVE:
610 if (count < 0) {
611 Tcl_AppendResult(interp, "bad value \"", string, "\": ",
612 "can't be negative", (char *)NULL);
613 return TCL_ERROR;
614 }
615 break;
616 case COUNT_POSITIVE:
617 if (count <= 0) {
618 Tcl_AppendResult(interp, "bad value \"", string, "\": ",
619 "must be positive", (char *)NULL);
620 return TCL_ERROR;
621 }
622 break;
623 case COUNT_ANY:
624 break;
625 }
626 *valuePtr = count;
627 return TCL_OK;
628 }
629
630 /*
631 *----------------------------------------------------------------------
632 *
633 * StringToCount --
634 *
635 * Like TK_CONFIG_PIXELS, but adds an extra check for negative
636 * values.
637 *
638 *----------------------------------------------------------------------
639 */
640 /*ARGSUSED*/
641 static int
StringToCount(clientData,interp,tkwin,string,widgRec,offset)642 StringToCount(clientData, interp, tkwin, string, widgRec, offset)
643 ClientData clientData; /* Indicated how to check distance */
644 Tcl_Interp *interp; /* Interpreter to send results back to */
645 Tk_Window tkwin; /* Not used. */
646 char *string; /* Pixel value string */
647 char *widgRec; /* Widget record */
648 int offset; /* Offset of pixel size in record */
649 {
650 int *valuePtr = (int *)(widgRec + offset);
651 return Blt_GetInt(interp, string, (int)clientData, valuePtr);
652 }
653
654 /*
655 *----------------------------------------------------------------------
656 *
657 * CountToString --
658 *
659 * Returns the string representing the positive pixel size.
660 *
661 * Results:
662 * The pixel size string is returned.
663 *
664 *----------------------------------------------------------------------
665 */
666 /*ARGSUSED*/
667 static char *
CountToString(clientData,tkwin,widgRec,offset,freeProcPtr)668 CountToString(clientData, tkwin, widgRec, offset, freeProcPtr)
669 ClientData clientData; /* Not used. */
670 Tk_Window tkwin; /* Not used. */
671 char *widgRec; /* Widget structure record */
672 int offset; /* Offset in widget record */
673 Tcl_FreeProc **freeProcPtr; /* Not used. */
674 {
675 int value = *(int *)(widgRec + offset);
676 char *result;
677
678 result = Blt_Strdup(Blt_Itoa(value));
679 assert(result);
680 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
681 return result;
682 }
683
684 /*
685 *----------------------------------------------------------------------
686 *
687 * StringToPad --
688 *
689 * Convert a string into two pad values. The string may be in one of
690 * the following forms:
691 *
692 * n - n is a non-negative integer. This sets both
693 * pad values to n.
694 * {n m} - both n and m are non-negative integers. side1
695 * is set to n, side2 is set to m.
696 *
697 * Results:
698 * If the string is successfully converted, TCL_OK is returned.
699 * Otherwise, TCL_ERROR is returned and an error message is left in
700 * interp->result.
701 *
702 * Side Effects:
703 * The padding structure passed is updated with the new values.
704 *
705 *----------------------------------------------------------------------
706 */
707 /*ARGSUSED*/
708 static int
StringToPad(clientData,interp,tkwin,string,widgRec,offset)709 StringToPad(clientData, interp, tkwin, string, widgRec, offset)
710 ClientData clientData; /* Not used. */
711 Tcl_Interp *interp; /* Interpreter to send results back to */
712 Tk_Window tkwin; /* Window */
713 char *string; /* Pixel value string */
714 char *widgRec; /* Widget record */
715 int offset; /* Offset of pad in widget */
716 {
717 Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset);
718 int nElem;
719 int pad, result;
720 char **padArr;
721
722 if (Tcl_SplitList(interp, string, &nElem, &padArr) != TCL_OK) {
723 return TCL_ERROR;
724 }
725 result = TCL_ERROR;
726 if ((nElem < 1) || (nElem > 2)) {
727 Tcl_AppendResult(interp, "wrong # elements in padding list",
728 (char *)NULL);
729 goto error;
730 }
731 if (Blt_GetPixels(interp, tkwin, padArr[0], PIXELS_NONNEGATIVE, &pad)
732 != TCL_OK) {
733 goto error;
734 }
735 padPtr->side1 = pad;
736 if ((nElem > 1) &&
737 (Blt_GetPixels(interp, tkwin, padArr[1], PIXELS_NONNEGATIVE, &pad)
738 != TCL_OK)) {
739 goto error;
740 }
741 padPtr->side2 = pad;
742 result = TCL_OK;
743
744 error:
745 Blt_Free(padArr);
746 return result;
747 }
748
749 /*
750 *----------------------------------------------------------------------
751 *
752 * PadToString --
753 *
754 * Converts the two pad values into a Tcl list. Each pad has two
755 * pixel values. For vertical pads, they represent the top and bottom
756 * margins. For horizontal pads, they're the left and right margins.
757 * All pad values are non-negative integers.
758 *
759 * Results:
760 * The padding list is returned.
761 *
762 *----------------------------------------------------------------------
763 */
764 /*ARGSUSED*/
765 static char *
PadToString(clientData,tkwin,widgRec,offset,freeProcPtr)766 PadToString(clientData, tkwin, widgRec, offset, freeProcPtr)
767 ClientData clientData; /* Not used. */
768 Tk_Window tkwin; /* Not used. */
769 char *widgRec; /* Structure record */
770 int offset; /* Offset of pad in record */
771 Tcl_FreeProc **freeProcPtr; /* Not used. */
772 {
773 Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset);
774 char *result;
775 char string[200];
776
777 sprintf(string, "%d %d", padPtr->side1, padPtr->side2);
778 result = Blt_Strdup(string);
779 if (result == NULL) {
780 return "out of memory";
781 }
782 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
783 return result;
784 }
785
786 /*
787 *----------------------------------------------------------------------
788 *
789 * StringToShadow --
790 *
791 * Convert a string into two pad values. The string may be in one of
792 * the following forms:
793 *
794 * n - n is a non-negative integer. This sets both
795 * pad values to n.
796 * {n m} - both n and m are non-negative integers. side1
797 * is set to n, side2 is set to m.
798 *
799 * Results:
800 * If the string is successfully converted, TCL_OK is returned.
801 * Otherwise, TCL_ERROR is returned and an error message is left in
802 * interp->result.
803 *
804 * Side Effects:
805 * The padding structure passed is updated with the new values.
806 *
807 * TODO: all users of this need to free color on widget exit.
808 *----------------------------------------------------------------------
809 */
810 /*ARGSUSED*/
811 static int
StringToShadow(clientData,interp,tkwin,string,widgRec,offset)812 StringToShadow(clientData, interp, tkwin, string, widgRec, offset)
813 ClientData clientData; /* Not used. */
814 Tcl_Interp *interp; /* Interpreter to send results back to */
815 Tk_Window tkwin; /* Window */
816 char *string; /* Pixel value string */
817 char *widgRec; /* Widget record */
818 int offset; /* Offset of pad in widget */
819 {
820 Shadow *shadowPtr = (Shadow *) (widgRec + offset);
821 XColor *colorPtr;
822 int dropOffset;
823
824 colorPtr = NULL;
825 dropOffset = 0;
826 if ((string != NULL) && (string[0] != '\0')) {
827 int nElem;
828 char **elemArr;
829
830 if (Tcl_SplitList(interp, string, &nElem, &elemArr) != TCL_OK) {
831 return TCL_ERROR;
832 }
833 if ((nElem < 1) || (nElem > 2)) {
834 Tcl_AppendResult(interp, "wrong # elements in drop shadow value",
835 (char *)NULL);
836 Blt_Free(elemArr);
837 return TCL_ERROR;
838 }
839 colorPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(elemArr[0]));
840 if (colorPtr == NULL) {
841 Blt_Free(elemArr);
842 return TCL_ERROR;
843 }
844 dropOffset = 1;
845 if (nElem == 2) {
846 if (Blt_GetPixels(interp, tkwin, elemArr[1], PIXELS_NONNEGATIVE,
847 &dropOffset) != TCL_OK) {
848 Tk_FreeColor(colorPtr);
849 Blt_Free(elemArr);
850 return TCL_ERROR;
851 }
852 }
853 Blt_Free(elemArr);
854 }
855 if (shadowPtr->color != NULL) {
856 Tk_FreeColor(shadowPtr->color);
857 }
858 shadowPtr->color = colorPtr;
859 shadowPtr->offset = dropOffset;
860 return TCL_OK;
861 }
862
863
864 /*
865 *----------------------------------------------------------------------
866 *
867 * ShadowToString --
868 *
869 * Converts the two pad values into a Tcl list. Each pad has two
870 * pixel values. For vertical pads, they represent the top and bottom
871 * margins. For horizontal pads, they're the left and right margins.
872 * All pad values are non-negative integers.
873 *
874 * Results:
875 * The padding list is returned.
876 *
877 *----------------------------------------------------------------------
878 */
879 /*ARGSUSED*/
880 static char *
ShadowToString(clientData,tkwin,widgRec,offset,freeProcPtr)881 ShadowToString(clientData, tkwin, widgRec, offset, freeProcPtr)
882 ClientData clientData; /* Not used. */
883 Tk_Window tkwin; /* Not used. */
884 char *widgRec; /* Structure record */
885 int offset; /* Offset of pad in record */
886 Tcl_FreeProc **freeProcPtr; /* Not used. */
887 {
888 Shadow *shadowPtr = (Shadow *) (widgRec + offset);
889 char *result;
890
891 result = "";
892 if (shadowPtr->color != NULL) {
893 char string[200];
894
895 sprintf(string, "%s %d", Tk_NameOfColor(shadowPtr->color),
896 shadowPtr->offset);
897 result = Blt_Strdup(string);
898 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
899 }
900 return result;
901 }
902
903 /*
904 *----------------------------------------------------------------------
905 *
906 * GradientToString --
907 *
908 * Converts the two pad values into a Tcl list. Each pad has two
909 * pixel values. For vertical pads, they represent the top and bottom
910 * margins. For horizontal pads, they're the left and right margins.
911 * All pad values are non-negative integers.
912 *
913 * Results:
914 * The padding list is returned.
915 *
916 *----------------------------------------------------------------------
917 */
918 /*ARGSUSED*/
919 static char *
GradientToString(clientData,tkwin,widgRec,offset,freeProcPtr)920 GradientToString(clientData, tkwin, widgRec, offset, freeProcPtr)
921 ClientData clientData; /* Not used. */
922 Tk_Window tkwin; /* Not used. */
923 char *widgRec; /* Structure record */
924 int offset; /* Offset of pad in record */
925 Tcl_FreeProc **freeProcPtr; /* Not used. */
926 {
927 Gradient *gradientPtr = (Gradient *) (widgRec + offset);
928 char *result;
929
930 result = "";
931 if (gradientPtr->color != NULL) {
932 char string[200];
933
934 sprintf(string, "%s %s %d", Tk_NameOfColor(gradientPtr->color), Tk_NameOfColor(gradientPtr->color2), gradientPtr->width);
935 result = Blt_Strdup(string);
936 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
937 }
938 return result;
939 }
940
941
942 /*
943 *----------------------------------------------------------------------
944 *
945 * StringToGradient --
946 *
947 * Convert a string into two pad values. The string may be in one of
948 * the following forms:
949 *
950 * n - n is a non-negative integer. This sets both
951 * pad values to n.
952 * {n m} - both n and m are non-negative integers. side1
953 * is set to n, side2 is set to m.
954 *
955 * Results:
956 * If the string is successfully converted, TCL_OK is returned.
957 * Otherwise, TCL_ERROR is returned and an error message is left in
958 * interp->result.
959 *
960 * Side Effects:
961 * The padding structure passed is updated with the new values.
962 *
963 *----------------------------------------------------------------------
964 */
965 /*ARGSUSED*/
966 static int
StringToGradient(clientData,interp,tkwin,string,widgRec,offset)967 StringToGradient(clientData, interp, tkwin, string, widgRec, offset)
968 ClientData clientData; /* Not used. */
969 Tcl_Interp *interp; /* Interpreter to send results back to */
970 Tk_Window tkwin; /* Window */
971 char *string; /* Pixel value string */
972 char *widgRec; /* Widget record */
973 int offset; /* Offset of pad in widget */
974 {
975 Gradient *gradientPtr = (Gradient *) (widgRec + offset);
976 XColor *colorPtr, *color2Ptr;
977 int dropOffset;
978
979 colorPtr = NULL;
980 dropOffset = 0;
981 if ((string != NULL) && (string[0] != '\0')) {
982 int nElem;
983 char **elemArr;
984
985 if (Tcl_SplitList(interp, string, &nElem, &elemArr) != TCL_OK) {
986 return TCL_ERROR;
987 }
988 if (nElem != 3) {
989 Tcl_AppendResult(interp, "expected \"color1 color2 length\" for gradient value",
990 (char *)NULL);
991 Blt_Free(elemArr);
992 return TCL_ERROR;
993 }
994 colorPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(elemArr[0]));
995 if (colorPtr == NULL) {
996 Blt_Free(elemArr);
997 return TCL_ERROR;
998 }
999 color2Ptr = Tk_GetColor(interp, tkwin, Tk_GetUid(elemArr[1]));
1000 if (color2Ptr == NULL) {
1001 Blt_Free(elemArr);
1002 return TCL_ERROR;
1003 }
1004 dropOffset = 1;
1005 if (Blt_GetPixels(interp, tkwin, elemArr[2], PIXELS_NONNEGATIVE,
1006 &dropOffset) != TCL_OK) {
1007 Tk_FreeColor(colorPtr);
1008 Tk_FreeColor(color2Ptr);
1009 Blt_Free(elemArr);
1010 return TCL_ERROR;
1011 }
1012 Blt_Free(elemArr);
1013 }
1014 if (gradientPtr->color != NULL) {
1015 Tk_FreeColor(gradientPtr->color);
1016 }
1017 if (gradientPtr->color2 != NULL) {
1018 Tk_FreeColor(gradientPtr->color2);
1019 }
1020 gradientPtr->color = colorPtr;
1021 gradientPtr->color2 = color2Ptr;
1022 gradientPtr->width = dropOffset;
1023 return TCL_OK;
1024 }
1025
1026 /*
1027 *----------------------------------------------------------------------
1028 *
1029 * GetDashes --
1030 *
1031 * Converts a Tcl list of dash values into a dash list ready for
1032 * use with XSetDashes.
1033 *
1034 * A valid list dash values can have zero through 11 elements
1035 * (PostScript limit). Values must be between 1 and 255. Although
1036 * a list of 0 (like the empty string) means no dashes.
1037 *
1038 * Results:
1039 * A standard Tcl result. If the list represented a valid dash
1040 * list TCL_OK is returned and *dashesPtr* will contain the
1041 * valid dash list. Otherwise, TCL_ERROR is returned and
1042 * interp->result will contain an error message.
1043 *
1044 *
1045 *----------------------------------------------------------------------
1046 */
1047 static int
GetDashes(interp,string,dashesPtr)1048 GetDashes(interp, string, dashesPtr)
1049 Tcl_Interp *interp;
1050 char *string;
1051 Blt_Dashes *dashesPtr;
1052 {
1053 if ((string == NULL) || (*string == '\0')) {
1054 dashesPtr->values[0] = 0;
1055 } else if (strcmp(string, "dash") == 0) { /* 5 2 */
1056 dashesPtr->values[0] = 5;
1057 dashesPtr->values[1] = 2;
1058 dashesPtr->values[2] = 0;
1059 } else if (strcmp(string, "dot") == 0) { /* 1 */
1060 dashesPtr->values[0] = 1;
1061 dashesPtr->values[1] = 0;
1062 } else if (strcmp(string, "dashdot") == 0) { /* 2 4 2 */
1063 dashesPtr->values[0] = 2;
1064 dashesPtr->values[1] = 4;
1065 dashesPtr->values[2] = 2;
1066 dashesPtr->values[3] = 0;
1067 } else if (strcmp(string, "dashdotdot") == 0) { /* 2 4 2 2 */
1068 dashesPtr->values[0] = 2;
1069 dashesPtr->values[1] = 4;
1070 dashesPtr->values[2] = 2;
1071 dashesPtr->values[3] = 2;
1072 dashesPtr->values[4] = 0;
1073 } else {
1074 int nValues;
1075 char **strArr;
1076 long int value;
1077 register int i;
1078
1079 if (Tcl_SplitList(interp, string, &nValues, &strArr) != TCL_OK) {
1080 return TCL_ERROR;
1081 }
1082 if (nValues > 11) { /* This is the postscript limit */
1083 Tcl_AppendResult(interp, "too many values in dash list \"",
1084 string, "\"", (char *)NULL);
1085 Blt_Free(strArr);
1086 return TCL_ERROR;
1087 }
1088 for (i = 0; i < nValues; i++) {
1089 if (Tcl_ExprLong(interp, strArr[i], &value) != TCL_OK) {
1090 Blt_Free(strArr);
1091 return TCL_ERROR;
1092 }
1093 /*
1094 * Backward compatibility:
1095 * Allow list of 0 to turn off dashes
1096 */
1097 if ((value == 0) && (nValues == 1)) {
1098 break;
1099 }
1100 if ((value < 1) || (value > 255)) {
1101 Tcl_AppendResult(interp, "dash value \"", strArr[i],
1102 "\" is out of range", (char *)NULL);
1103 Blt_Free(strArr);
1104 return TCL_ERROR;
1105 }
1106 dashesPtr->values[i] = (unsigned char)value;
1107 }
1108 /* Make sure the array ends with a NUL byte */
1109 dashesPtr->values[i] = 0;
1110 Blt_Free(strArr);
1111 }
1112 return TCL_OK;
1113
1114 }
1115
1116 /*
1117 *----------------------------------------------------------------------
1118 *
1119 * StringToDashes --
1120 *
1121 * Convert the list of dash values into a dashes array.
1122 *
1123 * Results:
1124 * The return value is a standard Tcl result.
1125 *
1126 * Side Effects:
1127 * The Dashes structure is updated with the new dash list.
1128 *
1129 *----------------------------------------------------------------------
1130 */
1131 /*ARGSUSED*/
1132 static int
StringToDashes(clientData,interp,tkwin,string,widgRec,offset)1133 StringToDashes(clientData, interp, tkwin, string, widgRec, offset)
1134 ClientData clientData; /* Not used. */
1135 Tcl_Interp *interp; /* Interpreter to send results back to */
1136 Tk_Window tkwin; /* Not used. */
1137 char *string; /* New dash value list */
1138 char *widgRec; /* Widget record */
1139 int offset; /* offset to Dashes structure */
1140 {
1141 Blt_Dashes *dashesPtr = (Blt_Dashes *)(widgRec + offset);
1142
1143 return GetDashes(interp, string, dashesPtr);
1144 }
1145
1146 /*
1147 *----------------------------------------------------------------------
1148 *
1149 * DashesToString --
1150 *
1151 * Convert the dashes array into a list of values.
1152 *
1153 * Results:
1154 * The string representing the dashes returned.
1155 *
1156 *----------------------------------------------------------------------
1157 */
1158 /*ARGSUSED*/
1159 static char *
DashesToString(clientData,tkwin,widgRec,offset,freeProcPtr)1160 DashesToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1161 ClientData clientData; /* Not used. */
1162 Tk_Window tkwin; /* Not used. */
1163 char *widgRec; /* Widget record */
1164 int offset; /* offset of Dashes in record */
1165 Tcl_FreeProc **freeProcPtr; /* Memory deallocation scheme to use */
1166 {
1167 Blt_Dashes *dashesPtr = (Blt_Dashes *)(widgRec + offset);
1168 Tcl_DString dString;
1169 unsigned char *p;
1170 char *result;
1171
1172 if (dashesPtr->values[0] == 0) {
1173 return "";
1174 }
1175 Tcl_DStringInit(&dString);
1176 for (p = dashesPtr->values; *p != 0; p++) {
1177 Tcl_DStringAppendElement(&dString, Blt_Itoa(*p));
1178 }
1179 result = Tcl_DStringValue(&dString);
1180 if (result == dString.staticSpace) {
1181 result = Blt_Strdup(result);
1182 }
1183 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
1184 return result;
1185 }
1186
1187 /*
1188 *----------------------------------------------------------------------
1189 *
1190 * StringToUid --
1191 *
1192 * Converts the string to a BLT Uid. Blt Uid's are hashed, reference
1193 * counted strings.
1194 *
1195 *----------------------------------------------------------------------
1196 */
1197 /*ARGSUSED*/
1198 static int
StringToUid(clientData,interp,tkwin,string,widgRec,offset)1199 StringToUid(clientData, interp, tkwin, string, widgRec, offset)
1200 ClientData clientData; /* Not used. */
1201 Tcl_Interp *interp; /* Interpreter to send results back to */
1202 Tk_Window tkwin; /* Not used. */
1203 char *string; /* Fill style string */
1204 char *widgRec; /* Cubicle structure record */
1205 int offset; /* Offset of style in record */
1206 {
1207 Blt_Uid *uidPtr = (Blt_Uid *)(widgRec + offset);
1208 Blt_Uid newId;
1209
1210 newId = NULL;
1211 if ((string != NULL) && (*string != '\0')) {
1212 newId = Blt_GetUid(string);
1213 }
1214 if (*uidPtr != NULL) {
1215 Blt_FreeUid(*uidPtr);
1216 }
1217 *uidPtr = newId;
1218 return TCL_OK;
1219 }
1220
1221 /*
1222 *----------------------------------------------------------------------
1223 *
1224 * UidToString --
1225 *
1226 * Returns the fill style string based upon the fill flags.
1227 *
1228 * Results:
1229 * The fill style string is returned.
1230 *
1231 *----------------------------------------------------------------------
1232 */
1233 /*ARGSUSED*/
1234 static char *
UidToString(clientData,tkwin,widgRec,offset,freeProcPtr)1235 UidToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1236 ClientData clientData; /* Not used. */
1237 Tk_Window tkwin; /* Not used. */
1238 char *widgRec; /* Widget structure record */
1239 int offset; /* Offset of fill in widget record */
1240 Tcl_FreeProc **freeProcPtr; /* Not used. */
1241 {
1242 Blt_Uid uid = *(Blt_Uid *)(widgRec + offset);
1243
1244 return (uid == NULL) ? "" : uid;
1245 }
1246
1247 /*
1248 *----------------------------------------------------------------------
1249 *
1250 * StringToState --
1251 *
1252 * Converts the string to a state value. Valid states are
1253 * disabled, normal.
1254 *
1255 *----------------------------------------------------------------------
1256 */
1257 /*ARGSUSED*/
1258 static int
StringToState(clientData,interp,tkwin,string,widgRec,offset)1259 StringToState(clientData, interp, tkwin, string, widgRec, offset)
1260 ClientData clientData; /* Not used. */
1261 Tcl_Interp *interp; /* Interpreter to send results back to */
1262 Tk_Window tkwin; /* Not used. */
1263 char *string; /* String representation of option value */
1264 char *widgRec; /* Widget structure record */
1265 int offset; /* Offset of field in record */
1266 {
1267 int *statePtr = (int *)(widgRec + offset);
1268
1269 if (strcmp(string, "normal") == 0) {
1270 *statePtr = STATE_NORMAL;
1271 } else if (strcmp(string, "disabled") == 0) {
1272 *statePtr = STATE_DISABLED;
1273 } else if (strcmp(string, "active") == 0) {
1274 *statePtr = STATE_ACTIVE;
1275 } else {
1276 Tcl_AppendResult(interp, "bad state \"", string,
1277 "\": should be normal, active, or disabled", (char *)NULL);
1278 return TCL_ERROR;
1279 }
1280 return TCL_OK;
1281 }
1282
1283 /*
1284 *----------------------------------------------------------------------
1285 *
1286 * StateToString --
1287 *
1288 * Returns the string representation of the state configuration field
1289 *
1290 * Results:
1291 * The string is returned.
1292 *
1293 *----------------------------------------------------------------------
1294 */
1295 /*ARGSUSED*/
1296 static char *
StateToString(clientData,tkwin,widgRec,offset,freeProcPtr)1297 StateToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1298 ClientData clientData; /* Not used. */
1299 Tk_Window tkwin; /* Not used. */
1300 char *widgRec; /* Widget structure record */
1301 int offset; /* Offset of fill in widget record */
1302 Tcl_FreeProc **freeProcPtr; /* Not used. */
1303 {
1304 int state = *(int *)(widgRec + offset);
1305
1306 switch (state) {
1307 case STATE_ACTIVE:
1308 return "active";
1309 case STATE_DISABLED:
1310 return "disabled";
1311 case STATE_NORMAL:
1312 return "normal";
1313 default:
1314 return "???";
1315 }
1316 }
1317
1318 /*
1319 *----------------------------------------------------------------------
1320 *
1321 * StringToList --
1322 *
1323 * Converts the string to a list.
1324 *
1325 *----------------------------------------------------------------------
1326 */
1327 /*ARGSUSED*/
1328 static int
StringToList(clientData,interp,tkwin,string,widgRec,offset)1329 StringToList(clientData, interp, tkwin, string, widgRec, offset)
1330 ClientData clientData; /* Not used. */
1331 Tcl_Interp *interp; /* Interpreter to send results back to */
1332 Tk_Window tkwin; /* Not used. */
1333 char *string; /* String representation of option value */
1334 char *widgRec; /* Widget structure record */
1335 int offset; /* Offset of field in record */
1336 {
1337 char ***listPtr = (char ***)(widgRec + offset);
1338 char **elemArr;
1339 int nElem;
1340
1341 if (*listPtr != NULL) {
1342 Blt_Free(*listPtr);
1343 *listPtr = NULL;
1344 }
1345 if ((string == NULL) || (*string == '\0')) {
1346 return TCL_OK;
1347 }
1348 if (Tcl_SplitList(interp, string, &nElem, &elemArr) != TCL_OK) {
1349 return TCL_ERROR;
1350 }
1351 if (nElem > 0) {
1352 *listPtr = elemArr;
1353 }
1354 return TCL_OK;
1355 }
1356
1357 /*
1358 *----------------------------------------------------------------------
1359 *
1360 * ListToString --
1361 *
1362 * Returns the string representation of the state configuration field
1363 *
1364 * Results:
1365 * The string is returned.
1366 *
1367 *----------------------------------------------------------------------
1368 */
1369 /*ARGSUSED*/
1370 static char *
ListToString(clientData,tkwin,widgRec,offset,freeProcPtr)1371 ListToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1372 ClientData clientData; /* Not used. */
1373 Tk_Window tkwin; /* Not used. */
1374 char *widgRec; /* Widget structure record. */
1375 int offset; /* Offset of fill in widget record. */
1376 Tcl_FreeProc **freeProcPtr; /* Not used. */
1377 {
1378 char **list = *(char ***)(widgRec + offset);
1379 register char **p;
1380 char *result;
1381 Tcl_DString dString;
1382
1383 if (list == NULL) {
1384 return "";
1385 }
1386 Tcl_DStringInit(&dString);
1387 for (p = list; *p != NULL; p++) {
1388 Tcl_DStringAppendElement(&dString, *p);
1389 }
1390 result = Tcl_DStringValue(&dString);
1391 if (result == dString.staticSpace) {
1392 result = Blt_Strdup(result);
1393 }
1394 Tcl_DStringFree(&dString);
1395 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
1396 return result;
1397 }
1398
1399
1400 /*
1401 *----------------------------------------------------------------------
1402 *
1403 * StringToTile --
1404 *
1405 * Converts the name of an image into a tile.
1406 *
1407 *----------------------------------------------------------------------
1408 */
1409 /*ARGSUSED*/
1410 static int
StringToTile(clientData,interp,tkwin,string,widgRec,offset)1411 StringToTile(clientData, interp, tkwin, string, widgRec, offset)
1412 ClientData clientData; /* Not used. */
1413 Tcl_Interp *interp; /* Interpreter to send results back to */
1414 Tk_Window tkwin; /* Window on same display as tile */
1415 char *string; /* Name of image */
1416 char *widgRec; /* Widget structure record */
1417 int offset; /* Offset of tile in record */
1418 {
1419 Blt_Tile *tilePtr = (Blt_Tile *)(widgRec + offset);
1420 Blt_Tile tile, oldTile;
1421
1422 oldTile = *tilePtr;
1423 tile = NULL;
1424 if ((string != NULL) && (*string != '\0')) {
1425 if (Blt_GetTile(interp, tkwin, string, &tile) != TCL_OK) {
1426 return TCL_ERROR;
1427 }
1428 }
1429 /* Don't delete the information for the old tile, until we know
1430 * that we successfully allocated a new one. */
1431 if (oldTile != NULL) {
1432 Blt_FreeTile(oldTile);
1433 }
1434 *tilePtr = tile;
1435 return TCL_OK;
1436 }
1437
1438 /*
1439 *----------------------------------------------------------------------
1440 *
1441 * TileToString --
1442 *
1443 * Returns the name of the tile.
1444 *
1445 * Results:
1446 * The name of the tile is returned.
1447 *
1448 *----------------------------------------------------------------------
1449 */
1450 /*ARGSUSED*/
1451 static char *
TileToString(clientData,tkwin,widgRec,offset,freeProcPtr)1452 TileToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1453 ClientData clientData; /* Not used. */
1454 Tk_Window tkwin; /* Not used. */
1455 char *widgRec; /* Widget structure record */
1456 int offset; /* Offset of tile in record */
1457 Tcl_FreeProc **freeProcPtr; /* Not used. */
1458 {
1459 Blt_Tile tile = *(Blt_Tile *)(widgRec + offset);
1460
1461 return Blt_NameOfTile(tile);
1462 }
1463
1464 /*
1465 *----------------------------------------------------------------------
1466 *
1467 * Blt_ConfigModified --
1468 *
1469 * Given the configuration specifications and one or more option
1470 * patterns (terminated by a NULL), indicate if any of the matching
1471 * configuration options has been reset.
1472 *
1473 * Results:
1474 * Returns 1 if one of the options has changed, 0 otherwise.
1475 *
1476 *----------------------------------------------------------------------
1477 */
1478 int Blt_ConfigModified
TCL_VARARGS_DEF(Tk_ConfigSpec *,arg1)1479 TCL_VARARGS_DEF(Tk_ConfigSpec *, arg1)
1480 {
1481 va_list argList;
1482 Tk_ConfigSpec *specs;
1483 register Tk_ConfigSpec *specPtr;
1484 register char *option;
1485 Tcl_Interp *interp;
1486
1487 specs = TCL_VARARGS_START(Tk_ConfigSpec *, arg1, argList);
1488 interp = va_arg(argList, Tcl_Interp *);
1489 specs = Blt_GetCachedSpecs(interp, specs);
1490 while ((option = va_arg(argList, char *)) != NULL) {
1491 for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
1492 if ((Tcl_StringMatch(specPtr->argvName, option)) &&
1493 (specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)) {
1494 va_end(argList);
1495 return 1;
1496 }
1497 }
1498 }
1499 va_end(argList);
1500 return 0;
1501 }
1502
1503 /*
1504 *----------------------------------------------------------------------
1505 *
1506 * Blt_ConfigureWidgetComponent --
1507 *
1508 * Configures a component of a widget. This is useful for
1509 * widgets that have multiple components which aren't uniquely
1510 * identified by a Tk_Window. It allows us, for example, set
1511 * resources for axes of the graph widget. The graph really has
1512 * only one window, but its convenient to specify components in a
1513 * hierarchy of options.
1514 *
1515 * *graph.x.logScale yes
1516 * *graph.Axis.logScale yes
1517 * *graph.temperature.scaleSymbols yes
1518 * *graph.Element.scaleSymbols yes
1519 *
1520 * This is really a hack to work around the limitations of the Tk
1521 * resource database. It creates a temporary window, needed to
1522 * call Tk_ConfigureWidget, using the name of the component.
1523 *
1524 * Results:
1525 * A standard Tcl result.
1526 *
1527 * Side Effects:
1528 * A temporary window is created merely to pass to Tk_ConfigureWidget.
1529 *
1530 *----------------------------------------------------------------------
1531 */
1532 int
Blt_ConfigureWidgetComponent(interp,parent,resName,className,specsPtr,argc,argv,widgRec,flags)1533 Blt_ConfigureWidgetComponent(interp, parent, resName, className, specsPtr,
1534 argc, argv, widgRec, flags)
1535 Tcl_Interp *interp;
1536 Tk_Window parent; /* Window to associate with component */
1537 char resName[]; /* Name of component */
1538 char className[];
1539 Tk_ConfigSpec *specsPtr;
1540 int argc;
1541 char *argv[];
1542 char *widgRec;
1543 int flags;
1544 {
1545 Tk_Window tkwin;
1546 int result;
1547 char *tempName;
1548 char *oldClass;
1549 int isTemporary = FALSE;
1550
1551 tempName = Blt_Strdup(resName);
1552
1553 /* Window name can't start with an upper case letter */
1554 tempName[0] = tolower(resName[0]);
1555
1556 /*
1557 * Create component if a child window by the component's name
1558 * doesn't already exist.
1559 */
1560 tkwin = Blt_FindChild(parent, tempName);
1561 if (tkwin == NULL) {
1562 tkwin = Tk_CreateWindow(interp, parent, tempName, (char *)NULL);
1563 isTemporary = TRUE;
1564 } else {
1565 oldClass = Tk_Class(tkwin);
1566 }
1567 if (tkwin == NULL) {
1568 Tcl_AppendResult(interp, "can't find window in \"",
1569 Tk_PathName(parent), "\"", (char *)NULL);
1570 return TCL_ERROR;
1571 }
1572 assert(Tk_Depth(tkwin) == Tk_Depth(parent));
1573 Blt_Free(tempName);
1574
1575 Tk_SetClass(tkwin, className);
1576 result = Tk_ConfigureWidget(interp, tkwin, specsPtr, argc, argv, widgRec,
1577 flags);
1578 if (isTemporary) {
1579 Tk_DestroyWindow(tkwin);
1580 } else if (oldClass != NULL) {
1581 Tk_SetClass(tkwin, oldClass);
1582 }
1583 return result;
1584 }
1585
1586
1587 /*
1588 *----------------------------------------------------------------------
1589 *
1590 * Blt_StringToEnum --
1591 *
1592 * Converts the string into its enumerated type.
1593 *
1594 *----------------------------------------------------------------------
1595 */
1596 /*ARGSUSED*/
1597 int
Blt_StringToEnum(clientData,interp,tkwin,string,widgRec,offset)1598 Blt_StringToEnum(clientData, interp, tkwin, string, widgRec, offset)
1599 ClientData clientData; /* Vectors of valid strings. */
1600 Tcl_Interp *interp; /* Interpreter to send results back to */
1601 Tk_Window tkwin; /* Not used. */
1602 char *string; /* String to match. */
1603 char *widgRec; /* Widget record. */
1604 int offset; /* Offset of field in record */
1605 {
1606 int *enumPtr = (int *)(widgRec + offset);
1607 char c;
1608 register char **p;
1609 register int i;
1610 int count;
1611
1612 c = string[0];
1613 count = 0;
1614 for (p = (char **)clientData; *p != NULL; p++) {
1615 if ((c == p[0][0]) && (strcmp(string, *p) == 0)) {
1616 *enumPtr = count;
1617 return TCL_OK;
1618 }
1619 count++;
1620 }
1621 *enumPtr = -1;
1622
1623 Tcl_AppendResult(interp, "bad value \"", string, "\": should be ",
1624 (char *)NULL);
1625 p = (char **)clientData;
1626 if (count > 0) {
1627 Tcl_AppendResult(interp, p[0], (char *)NULL);
1628 }
1629 for (i = 1; i < (count - 1); i++) {
1630 Tcl_AppendResult(interp, " ", p[i], ", ", (char *)NULL);
1631 }
1632 if (count > 1) {
1633 Tcl_AppendResult(interp, " or ", p[count - 1], ".", (char *)NULL);
1634 }
1635 return TCL_ERROR;
1636 }
1637
1638 /*
1639 *----------------------------------------------------------------------
1640 *
1641 * Blt_EnumToString --
1642 *
1643 * Returns the string associated with the enumerated type.
1644 *
1645 *----------------------------------------------------------------------
1646 */
1647 /*ARGSUSED*/
1648 char *
Blt_EnumToString(clientData,tkwin,widgRec,offset,freeProcPtr)1649 Blt_EnumToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1650 ClientData clientData; /* List of strings. */
1651 Tk_Window tkwin; /* Not used. */
1652 char *widgRec; /* Widget record */
1653 int offset; /* Offset of field in widget record */
1654 Tcl_FreeProc **freeProcPtr; /* Not used. */
1655 {
1656 int value = *(int *)(widgRec + offset);
1657 char **p;
1658 int count;
1659
1660 count = 0;
1661 for (p = (char **)clientData; *p != NULL; p++) {
1662 count++;
1663 }
1664 if ((value >= count) || (value < 0)) {
1665 return "unknown value";
1666 }
1667 p = (char **)clientData;
1668 return p[value];
1669 }
1670
1671 #include "bltOldConfig.c"
1672