source: trunk/kitgen/8.x/blt/generic/bltConfig.c@ 201

Last change on this file since 201 was 175, checked in by demin, 12 years ago

initial commit

File size: 37.4 KB
RevLine 
[175]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
37static int StringToFill _ANSI_ARGS_((ClientData clientData,
38 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
39 int flags));
40static char *FillToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
41 Tcl_FreeProc **));
42
43Tk_CustomOption bltFillOption =
44{
45 StringToFill, FillToString, (ClientData)0
46};
47
48static int StringToPad _ANSI_ARGS_((ClientData clientData,
49 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
50 int offset));
51static char *PadToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
52 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
53
54Tk_CustomOption bltPadOption =
55{
56 StringToPad, PadToString, (ClientData)0
57};
58
59static int StringToDistance _ANSI_ARGS_((ClientData clientData,
60 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
61 int flags));
62static char *DistanceToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
63 Tcl_FreeProc **));
64
65Tk_CustomOption bltDistanceOption =
66{
67 StringToDistance, DistanceToString, (ClientData)PIXELS_NONNEGATIVE
68};
69
70Tk_CustomOption bltPositiveDistanceOption =
71{
72 StringToDistance, DistanceToString, (ClientData)PIXELS_POSITIVE
73};
74
75Tk_CustomOption bltAnyDistanceOption =
76{
77 StringToDistance, DistanceToString, (ClientData)PIXELS_ANY
78};
79
80static int StringToCount _ANSI_ARGS_((ClientData clientData,
81 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
82 int flags));
83static char *CountToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
84 Tcl_FreeProc **));
85
86Tk_CustomOption bltCountOption =
87{
88 StringToCount, CountToString, (ClientData)COUNT_NONNEGATIVE
89};
90
91Tk_CustomOption bltPositiveCountOption =
92{
93 StringToCount, CountToString, (ClientData)COUNT_POSITIVE
94};
95
96static int StringToDashes _ANSI_ARGS_((ClientData, Tcl_Interp *, Tk_Window,
97 char *, char *, int));
98static char *DashesToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
99 Tcl_FreeProc **));
100
101Tk_CustomOption bltDashesOption =
102{
103 StringToDashes, DashesToString, (ClientData)0
104};
105
106static int StringToShadow _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
107 Tk_Window tkwin, char *string, char *widgRec, int offset));
108static char *ShadowToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
109 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
110
111Tk_CustomOption bltShadowOption =
112{
113 StringToShadow, ShadowToString, (ClientData)0
114};
115
116static int StringToUid _ANSI_ARGS_((ClientData clientData,
117 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
118 int flags));
119static char *UidToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
120 Tcl_FreeProc **));
121
122Tk_CustomOption bltUidOption =
123{
124 StringToUid, UidToString, (ClientData)0
125};
126
127static int StringToState _ANSI_ARGS_((ClientData clientData,
128 Tcl_Interp *interp, Tk_Window tkwin, char *string, char *widgRec,
129 int flags));
130static char *StateToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
131 Tcl_FreeProc **));
132
133Tk_CustomOption bltStateOption =
134{
135 StringToState, StateToString, (ClientData)0
136};
137
138static int StringToList _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
139 Tk_Window tkwin, char *string, char *widgRec, int flags));
140static char *ListToString _ANSI_ARGS_((ClientData, Tk_Window, char *, int,
141 Tcl_FreeProc **));
142
143Tk_CustomOption bltListOption =
144{
145 StringToList, ListToString, (ClientData)0
146};
147
148static int StringToTile _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp,
149 Tk_Window tkwin, char *value, char *widgRec, int flags));
150static char *TileToString _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin,
151 char *widgRec, int offset, Tcl_FreeProc **freeProcPtr));
152
153Tk_CustomOption bltTileOption =
154{
155 StringToTile, TileToString, (ClientData)0
156};
157
158/*
159 *----------------------------------------------------------------------
160 *
161 * Blt_NameOfFill --
162 *
163 * Converts the integer representing the fill direction into a string.
164 *
165 *----------------------------------------------------------------------
166 */
167char *
168Blt_NameOfFill(fill)
169 int fill;
170{
171 switch (fill) {
172 case FILL_X:
173 return "x";
174 case FILL_Y:
175 return "y";
176 case FILL_NONE:
177 return "none";
178 case FILL_BOTH:
179 return "both";
180 default:
181 return "unknown value";
182 }
183}
184
185/*
186 *----------------------------------------------------------------------
187 *
188 * StringToFill --
189 *
190 * Converts the fill style string into its numeric representation.
191 *
192 * Valid style strings are:
193 *
194 * "none" Use neither plane.
195 * "x" X-coordinate plane.
196 * "y" Y-coordinate plane.
197 * "both" Use both coordinate planes.
198 *
199 *----------------------------------------------------------------------
200 */
201/*ARGSUSED*/
202static int
203StringToFill(clientData, interp, tkwin, string, widgRec, offset)
204 ClientData clientData; /* Not used. */
205 Tcl_Interp *interp; /* Interpreter to send results back to */
206 Tk_Window tkwin; /* Not used. */
207 char *string; /* Fill style string */
208 char *widgRec; /* Cubicle structure record */
209 int offset; /* Offset of style in record */
210{
211 int *fillPtr = (int *)(widgRec + offset);
212 unsigned int length;
213 char c;
214
215 c = string[0];
216 length = strlen(string);
217 if ((c == 'n') && (strncmp(string, "none", length) == 0)) {
218 *fillPtr = FILL_NONE;
219 } else if ((c == 'x') && (strncmp(string, "x", length) == 0)) {
220 *fillPtr = FILL_X;
221 } else if ((c == 'y') && (strncmp(string, "y", length) == 0)) {
222 *fillPtr = FILL_Y;
223 } else if ((c == 'b') && (strncmp(string, "both", length) == 0)) {
224 *fillPtr = FILL_BOTH;
225 } else {
226 Tcl_AppendResult(interp, "bad argument \"", string,
227 "\": should be \"none\", \"x\", \"y\", or \"both\"", (char *)NULL);
228 return TCL_ERROR;
229 }
230 return TCL_OK;
231}
232
233/*
234 *----------------------------------------------------------------------
235 *
236 * FillToString --
237 *
238 * Returns the fill style string based upon the fill flags.
239 *
240 * Results:
241 * The fill style string is returned.
242 *
243 *----------------------------------------------------------------------
244 */
245/*ARGSUSED*/
246static char *
247FillToString(clientData, tkwin, widgRec, offset, freeProcPtr)
248 ClientData clientData; /* Not used. */
249 Tk_Window tkwin; /* Not used. */
250 char *widgRec; /* Widget structure record */
251 int offset; /* Offset of fill in widget record */
252 Tcl_FreeProc **freeProcPtr; /* Not used. */
253{
254 int fill = *(int *)(widgRec + offset);
255
256 return Blt_NameOfFill(fill);
257}
258
259/*
260 *----------------------------------------------------------------------
261 *
262 * Blt_StringToFlag --
263 *
264 * Converts the fill style string into its numeric representation.
265 *
266 *----------------------------------------------------------------------
267 */
268/*ARGSUSED*/
269int
270Blt_StringToFlag(clientData, interp, tkwin, string, widgRec, offset)
271 ClientData clientData; /* Bit mask to be tested in status word */
272 Tcl_Interp *interp; /* Interpreter to send results back to */
273 Tk_Window tkwin; /* Not used. */
274 char *string; /* Fill style string */
275 char *widgRec; /* Cubicle structure record */
276 int offset; /* Offset of style in record */
277{
278 unsigned int mask = (unsigned int)clientData; /* Bit to be tested */
279 int *flagPtr = (int *)(widgRec + offset);
280 int bool;
281
282 if (Tcl_GetBoolean(interp, string, &bool) != TCL_OK) {
283 return TCL_ERROR;
284 }
285 if (bool) {
286 *flagPtr |= mask;
287 } else {
288 *flagPtr &= ~mask;
289 }
290 return TCL_OK;
291}
292
293/*
294 *----------------------------------------------------------------------
295 *
296 * Blt_FlagToString --
297 *
298 * Returns the fill style string based upon the fill flags.
299 *
300 * Results:
301 * The fill style string is returned.
302 *
303 *----------------------------------------------------------------------
304 */
305/*ARGSUSED*/
306char *
307Blt_FlagToString(clientData, tkwin, widgRec, offset, freeProcPtr)
308 ClientData clientData; /* Bit mask to be test in status word */
309 Tk_Window tkwin; /* Not used. */
310 char *widgRec; /* Widget structure record */
311 int offset; /* Offset of fill in widget record */
312 Tcl_FreeProc **freeProcPtr; /* Not Used. */
313{
314 unsigned int mask = (unsigned int)clientData; /* Bit to be tested */
315 unsigned int bool = *(unsigned int *)(widgRec + offset);
316
317 return (bool & mask) ? "1" : "0";
318}
319
320
321/*
322 *----------------------------------------------------------------------
323 *
324 * Blt_GetPixels --
325 *
326 * Like Tk_GetPixels, but checks for negative, zero.
327 *
328 * Results:
329 * A standard Tcl result.
330 *
331 *----------------------------------------------------------------------
332 */
333int
334Blt_GetPixels(interp, tkwin, string, check, valuePtr)
335 Tcl_Interp *interp;
336 Tk_Window tkwin;
337 char *string;
338 int check; /* Can be PIXELS_POSITIVE, PIXELS_NONNEGATIVE,
339 * or PIXELS_ANY, */
340 int *valuePtr;
341{
342 int length;
343
344 if (Tk_GetPixels(interp, tkwin, string, &length) != TCL_OK) {
345 return TCL_ERROR;
346 }
347 if (length >= SHRT_MAX) {
348 Tcl_AppendResult(interp, "bad distance \"", string, "\": ",
349 "too big to represent", (char *)NULL);
350 return TCL_ERROR;
351 }
352 switch (check) {
353 case PIXELS_NONNEGATIVE:
354 if (length < 0) {
355 Tcl_AppendResult(interp, "bad distance \"", string, "\": ",
356 "can't be negative", (char *)NULL);
357 return TCL_ERROR;
358 }
359 break;
360 case PIXELS_POSITIVE:
361 if (length <= 0) {
362 Tcl_AppendResult(interp, "bad distance \"", string, "\": ",
363 "must be positive", (char *)NULL);
364 return TCL_ERROR;
365 }
366 break;
367 case PIXELS_ANY:
368 break;
369 }
370 *valuePtr = length;
371 return TCL_OK;
372}
373
374/*
375 *----------------------------------------------------------------------
376 *
377 * StringToDistance --
378 *
379 * Like TK_CONFIG_PIXELS, but adds an extra check for negative
380 * values.
381 *
382 *----------------------------------------------------------------------
383 */
384/*ARGSUSED*/
385static int
386StringToDistance(clientData, interp, tkwin, string, widgRec, offset)
387 ClientData clientData; /* Indicated how to check distance */
388 Tcl_Interp *interp; /* Interpreter to send results back to */
389 Tk_Window tkwin; /* Window */
390 char *string; /* Pixel value string */
391 char *widgRec; /* Widget record */
392 int offset; /* Offset of pixel size in record */
393{
394 int *valuePtr = (int *)(widgRec + offset);
395 return Blt_GetPixels(interp, tkwin, string, (int)clientData, valuePtr);
396}
397
398/*
399 *----------------------------------------------------------------------
400 *
401 * DistanceToString --
402 *
403 * Returns the string representing the positive pixel size.
404 *
405 * Results:
406 * The pixel size string is returned.
407 *
408 *----------------------------------------------------------------------
409 */
410/*ARGSUSED*/
411static char *
412DistanceToString(clientData, tkwin, widgRec, offset, freeProcPtr)
413 ClientData clientData; /* Not used. */
414 Tk_Window tkwin; /* Not used. */
415 char *widgRec; /* Widget structure record */
416 int offset; /* Offset in widget record */
417 Tcl_FreeProc **freeProcPtr; /* Not used. */
418{
419 int value = *(int *)(widgRec + offset);
420 char *result;
421
422 result = Blt_Strdup(Blt_Itoa(value));
423 assert(result);
424 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
425 return result;
426}
427
428int
429Blt_GetInt(interp, string, check, valuePtr)
430 Tcl_Interp *interp;
431 char *string;
432 int check; /* Can be COUNT_POSITIVE, COUNT_NONNEGATIVE,
433 * or COUNT_ANY, */
434 int *valuePtr;
435{
436 int count;
437
438 if (Tcl_GetInt(interp, string, &count) != TCL_OK) {
439 return TCL_ERROR;
440 }
441 switch (check) {
442 case COUNT_NONNEGATIVE:
443 if (count < 0) {
444 Tcl_AppendResult(interp, "bad value \"", string, "\": ",
445 "can't be negative", (char *)NULL);
446 return TCL_ERROR;
447 }
448 break;
449 case COUNT_POSITIVE:
450 if (count <= 0) {
451 Tcl_AppendResult(interp, "bad value \"", string, "\": ",
452 "must be positive", (char *)NULL);
453 return TCL_ERROR;
454 }
455 break;
456 case COUNT_ANY:
457 break;
458 }
459 *valuePtr = count;
460 return TCL_OK;
461}
462
463/*
464 *----------------------------------------------------------------------
465 *
466 * StringToCount --
467 *
468 * Like TK_CONFIG_PIXELS, but adds an extra check for negative
469 * values.
470 *
471 *----------------------------------------------------------------------
472 */
473/*ARGSUSED*/
474static int
475StringToCount(clientData, interp, tkwin, string, widgRec, offset)
476 ClientData clientData; /* Indicated how to check distance */
477 Tcl_Interp *interp; /* Interpreter to send results back to */
478 Tk_Window tkwin; /* Not used. */
479 char *string; /* Pixel value string */
480 char *widgRec; /* Widget record */
481 int offset; /* Offset of pixel size in record */
482{
483 int *valuePtr = (int *)(widgRec + offset);
484 return Blt_GetInt(interp, string, (int)clientData, valuePtr);
485}
486
487/*
488 *----------------------------------------------------------------------
489 *
490 * CountToString --
491 *
492 * Returns the string representing the positive pixel size.
493 *
494 * Results:
495 * The pixel size string is returned.
496 *
497 *----------------------------------------------------------------------
498 */
499/*ARGSUSED*/
500static char *
501CountToString(clientData, tkwin, widgRec, offset, freeProcPtr)
502 ClientData clientData; /* Not used. */
503 Tk_Window tkwin; /* Not used. */
504 char *widgRec; /* Widget structure record */
505 int offset; /* Offset in widget record */
506 Tcl_FreeProc **freeProcPtr; /* Not used. */
507{
508 int value = *(int *)(widgRec + offset);
509 char *result;
510
511 result = Blt_Strdup(Blt_Itoa(value));
512 assert(result);
513 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
514 return result;
515}
516
517/*
518 *----------------------------------------------------------------------
519 *
520 * StringToPad --
521 *
522 * Convert a string into two pad values. The string may be in one of
523 * the following forms:
524 *
525 * n - n is a non-negative integer. This sets both
526 * pad values to n.
527 * {n m} - both n and m are non-negative integers. side1
528 * is set to n, side2 is set to m.
529 *
530 * Results:
531 * If the string is successfully converted, TCL_OK is returned.
532 * Otherwise, TCL_ERROR is returned and an error message is left in
533 * interp->result.
534 *
535 * Side Effects:
536 * The padding structure passed is updated with the new values.
537 *
538 *----------------------------------------------------------------------
539 */
540/*ARGSUSED*/
541static int
542StringToPad(clientData, interp, tkwin, string, widgRec, offset)
543 ClientData clientData; /* Not used. */
544 Tcl_Interp *interp; /* Interpreter to send results back to */
545 Tk_Window tkwin; /* Window */
546 char *string; /* Pixel value string */
547 char *widgRec; /* Widget record */
548 int offset; /* Offset of pad in widget */
549{
550 Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset);
551 int nElem;
552 int pad, result;
553 char **padArr;
554
555 if (Tcl_SplitList(interp, string, &nElem, &padArr) != TCL_OK) {
556 return TCL_ERROR;
557 }
558 result = TCL_ERROR;
559 if ((nElem < 1) || (nElem > 2)) {
560 Tcl_AppendResult(interp, "wrong # elements in padding list",
561 (char *)NULL);
562 goto error;
563 }
564 if (Blt_GetPixels(interp, tkwin, padArr[0], PIXELS_NONNEGATIVE, &pad)
565 != TCL_OK) {
566 goto error;
567 }
568 padPtr->side1 = pad;
569 if ((nElem > 1) &&
570 (Blt_GetPixels(interp, tkwin, padArr[1], PIXELS_NONNEGATIVE, &pad)
571 != TCL_OK)) {
572 goto error;
573 }
574 padPtr->side2 = pad;
575 result = TCL_OK;
576
577 error:
578 Blt_Free(padArr);
579 return result;
580}
581
582/*
583 *----------------------------------------------------------------------
584 *
585 * PadToString --
586 *
587 * Converts the two pad values into a Tcl list. Each pad has two
588 * pixel values. For vertical pads, they represent the top and bottom
589 * margins. For horizontal pads, they're the left and right margins.
590 * All pad values are non-negative integers.
591 *
592 * Results:
593 * The padding list is returned.
594 *
595 *----------------------------------------------------------------------
596 */
597/*ARGSUSED*/
598static char *
599PadToString(clientData, tkwin, widgRec, offset, freeProcPtr)
600 ClientData clientData; /* Not used. */
601 Tk_Window tkwin; /* Not used. */
602 char *widgRec; /* Structure record */
603 int offset; /* Offset of pad in record */
604 Tcl_FreeProc **freeProcPtr; /* Not used. */
605{
606 Blt_Pad *padPtr = (Blt_Pad *)(widgRec + offset);
607 char *result;
608 char string[200];
609
610 sprintf(string, "%d %d", padPtr->side1, padPtr->side2);
611 result = Blt_Strdup(string);
612 if (result == NULL) {
613 return "out of memory";
614 }
615 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
616 return result;
617}
618
619/*
620 *----------------------------------------------------------------------
621 *
622 * StringToShadow --
623 *
624 * Convert a string into two pad values. The string may be in one of
625 * the following forms:
626 *
627 * n - n is a non-negative integer. This sets both
628 * pad values to n.
629 * {n m} - both n and m are non-negative integers. side1
630 * is set to n, side2 is set to m.
631 *
632 * Results:
633 * If the string is successfully converted, TCL_OK is returned.
634 * Otherwise, TCL_ERROR is returned and an error message is left in
635 * interp->result.
636 *
637 * Side Effects:
638 * The padding structure passed is updated with the new values.
639 *
640 *----------------------------------------------------------------------
641 */
642/*ARGSUSED*/
643static int
644StringToShadow(clientData, interp, tkwin, string, widgRec, offset)
645 ClientData clientData; /* Not used. */
646 Tcl_Interp *interp; /* Interpreter to send results back to */
647 Tk_Window tkwin; /* Window */
648 char *string; /* Pixel value string */
649 char *widgRec; /* Widget record */
650 int offset; /* Offset of pad in widget */
651{
652 Shadow *shadowPtr = (Shadow *) (widgRec + offset);
653 XColor *colorPtr;
654 int dropOffset;
655
656 colorPtr = NULL;
657 dropOffset = 0;
658 if ((string != NULL) && (string[0] != '\0')) {
659 int nElem;
660 char **elemArr;
661
662 if (Tcl_SplitList(interp, string, &nElem, &elemArr) != TCL_OK) {
663 return TCL_ERROR;
664 }
665 if ((nElem < 1) || (nElem > 2)) {
666 Tcl_AppendResult(interp, "wrong # elements in drop shadow value",
667 (char *)NULL);
668 Blt_Free(elemArr);
669 return TCL_ERROR;
670 }
671 colorPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(elemArr[0]));
672 if (colorPtr == NULL) {
673 Blt_Free(elemArr);
674 return TCL_ERROR;
675 }
676 dropOffset = 1;
677 if (nElem == 2) {
678 if (Blt_GetPixels(interp, tkwin, elemArr[1], PIXELS_NONNEGATIVE,
679 &dropOffset) != TCL_OK) {
680 Tk_FreeColor(colorPtr);
681 Blt_Free(elemArr);
682 return TCL_ERROR;
683 }
684 }
685 Blt_Free(elemArr);
686 }
687 if (shadowPtr->color != NULL) {
688 Tk_FreeColor(shadowPtr->color);
689 }
690 shadowPtr->color = colorPtr;
691 shadowPtr->offset = dropOffset;
692 return TCL_OK;
693}
694
695/*
696 *----------------------------------------------------------------------
697 *
698 * ShadowToString --
699 *
700 * Converts the two pad values into a Tcl list. Each pad has two
701 * pixel values. For vertical pads, they represent the top and bottom
702 * margins. For horizontal pads, they're the left and right margins.
703 * All pad values are non-negative integers.
704 *
705 * Results:
706 * The padding list is returned.
707 *
708 *----------------------------------------------------------------------
709 */
710/*ARGSUSED*/
711static char *
712ShadowToString(clientData, tkwin, widgRec, offset, freeProcPtr)
713 ClientData clientData; /* Not used. */
714 Tk_Window tkwin; /* Not used. */
715 char *widgRec; /* Structure record */
716 int offset; /* Offset of pad in record */
717 Tcl_FreeProc **freeProcPtr; /* Not used. */
718{
719 Shadow *shadowPtr = (Shadow *) (widgRec + offset);
720 char *result;
721
722 result = "";
723 if (shadowPtr->color != NULL) {
724 char string[200];
725
726 sprintf(string, "%s %d", Tk_NameOfColor(shadowPtr->color),
727 shadowPtr->offset);
728 result = Blt_Strdup(string);
729 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
730 }
731 return result;
732}
733
734/*
735 *----------------------------------------------------------------------
736 *
737 * GetDashes --
738 *
739 * Converts a Tcl list of dash values into a dash list ready for
740 * use with XSetDashes.
741 *
742 * A valid list dash values can have zero through 11 elements
743 * (PostScript limit). Values must be between 1 and 255. Although
744 * a list of 0 (like the empty string) means no dashes.
745 *
746 * Results:
747 * A standard Tcl result. If the list represented a valid dash
748 * list TCL_OK is returned and *dashesPtr* will contain the
749 * valid dash list. Otherwise, TCL_ERROR is returned and
750 * interp->result will contain an error message.
751 *
752 *
753 *----------------------------------------------------------------------
754 */
755static int
756GetDashes(interp, string, dashesPtr)
757 Tcl_Interp *interp;
758 char *string;
759 Blt_Dashes *dashesPtr;
760{
761 if ((string == NULL) || (*string == '\0')) {
762 dashesPtr->values[0] = 0;
763 } else if (strcmp(string, "dash") == 0) { /* 5 2 */
764 dashesPtr->values[0] = 5;
765 dashesPtr->values[1] = 2;
766 dashesPtr->values[2] = 0;
767 } else if (strcmp(string, "dot") == 0) { /* 1 */
768 dashesPtr->values[0] = 1;
769 dashesPtr->values[1] = 0;
770 } else if (strcmp(string, "dashdot") == 0) { /* 2 4 2 */
771 dashesPtr->values[0] = 2;
772 dashesPtr->values[1] = 4;
773 dashesPtr->values[2] = 2;
774 dashesPtr->values[3] = 0;
775 } else if (strcmp(string, "dashdotdot") == 0) { /* 2 4 2 2 */
776 dashesPtr->values[0] = 2;
777 dashesPtr->values[1] = 4;
778 dashesPtr->values[2] = 2;
779 dashesPtr->values[3] = 2;
780 dashesPtr->values[4] = 0;
781 } else {
782 int nValues;
783 char **strArr;
784 long int value;
785 register int i;
786
787 if (Tcl_SplitList(interp, string, &nValues, &strArr) != TCL_OK) {
788 return TCL_ERROR;
789 }
790 if (nValues > 11) { /* This is the postscript limit */
791 Tcl_AppendResult(interp, "too many values in dash list \"",
792 string, "\"", (char *)NULL);
793 Blt_Free(strArr);
794 return TCL_ERROR;
795 }
796 for (i = 0; i < nValues; i++) {
797 if (Tcl_ExprLong(interp, strArr[i], &value) != TCL_OK) {
798 Blt_Free(strArr);
799 return TCL_ERROR;
800 }
801 /*
802 * Backward compatibility:
803 * Allow list of 0 to turn off dashes
804 */
805 if ((value == 0) && (nValues == 1)) {
806 break;
807 }
808 if ((value < 1) || (value > 255)) {
809 Tcl_AppendResult(interp, "dash value \"", strArr[i],
810 "\" is out of range", (char *)NULL);
811 Blt_Free(strArr);
812 return TCL_ERROR;
813 }
814 dashesPtr->values[i] = (unsigned char)value;
815 }
816 /* Make sure the array ends with a NUL byte */
817 dashesPtr->values[i] = 0;
818 Blt_Free(strArr);
819 }
820 return TCL_OK;
821
822}
823
824/*
825 *----------------------------------------------------------------------
826 *
827 * StringToDashes --
828 *
829 * Convert the list of dash values into a dashes array.
830 *
831 * Results:
832 * The return value is a standard Tcl result.
833 *
834 * Side Effects:
835 * The Dashes structure is updated with the new dash list.
836 *
837 *----------------------------------------------------------------------
838 */
839/*ARGSUSED*/
840static int
841StringToDashes(clientData, interp, tkwin, string, widgRec, offset)
842 ClientData clientData; /* Not used. */
843 Tcl_Interp *interp; /* Interpreter to send results back to */
844 Tk_Window tkwin; /* Not used. */
845 char *string; /* New dash value list */
846 char *widgRec; /* Widget record */
847 int offset; /* offset to Dashes structure */
848{
849 Blt_Dashes *dashesPtr = (Blt_Dashes *)(widgRec + offset);
850
851 return GetDashes(interp, string, dashesPtr);
852}
853
854/*
855 *----------------------------------------------------------------------
856 *
857 * DashesToString --
858 *
859 * Convert the dashes array into a list of values.
860 *
861 * Results:
862 * The string representing the dashes returned.
863 *
864 *----------------------------------------------------------------------
865 */
866/*ARGSUSED*/
867static char *
868DashesToString(clientData, tkwin, widgRec, offset, freeProcPtr)
869 ClientData clientData; /* Not used. */
870 Tk_Window tkwin; /* Not used. */
871 char *widgRec; /* Widget record */
872 int offset; /* offset of Dashes in record */
873 Tcl_FreeProc **freeProcPtr; /* Memory deallocation scheme to use */
874{
875 Blt_Dashes *dashesPtr = (Blt_Dashes *)(widgRec + offset);
876 Tcl_DString dString;
877 unsigned char *p;
878 char *result;
879
880 if (dashesPtr->values[0] == 0) {
881 return "";
882 }
883 Tcl_DStringInit(&dString);
884 for (p = dashesPtr->values; *p != 0; p++) {
885 Tcl_DStringAppendElement(&dString, Blt_Itoa(*p));
886 }
887 result = Tcl_DStringValue(&dString);
888 if (result == dString.staticSpace) {
889 result = Blt_Strdup(result);
890 }
891 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
892 return result;
893}
894
895/*
896 *----------------------------------------------------------------------
897 *
898 * StringToUid --
899 *
900 * Converts the string to a BLT Uid. Blt Uid's are hashed, reference
901 * counted strings.
902 *
903 *----------------------------------------------------------------------
904 */
905/*ARGSUSED*/
906static int
907StringToUid(clientData, interp, tkwin, string, widgRec, offset)
908 ClientData clientData; /* Not used. */
909 Tcl_Interp *interp; /* Interpreter to send results back to */
910 Tk_Window tkwin; /* Not used. */
911 char *string; /* Fill style string */
912 char *widgRec; /* Cubicle structure record */
913 int offset; /* Offset of style in record */
914{
915 Blt_Uid *uidPtr = (Blt_Uid *)(widgRec + offset);
916 Blt_Uid newId;
917
918 newId = NULL;
919 if ((string != NULL) && (*string != '\0')) {
920 newId = Blt_GetUid(string);
921 }
922 if (*uidPtr != NULL) {
923 Blt_FreeUid(*uidPtr);
924 }
925 *uidPtr = newId;
926 return TCL_OK;
927}
928
929/*
930 *----------------------------------------------------------------------
931 *
932 * UidToString --
933 *
934 * Returns the fill style string based upon the fill flags.
935 *
936 * Results:
937 * The fill style string is returned.
938 *
939 *----------------------------------------------------------------------
940 */
941/*ARGSUSED*/
942static char *
943UidToString(clientData, tkwin, widgRec, offset, freeProcPtr)
944 ClientData clientData; /* Not used. */
945 Tk_Window tkwin; /* Not used. */
946 char *widgRec; /* Widget structure record */
947 int offset; /* Offset of fill in widget record */
948 Tcl_FreeProc **freeProcPtr; /* Not used. */
949{
950 Blt_Uid uid = *(Blt_Uid *)(widgRec + offset);
951
952 return (uid == NULL) ? "" : uid;
953}
954
955/*
956 *----------------------------------------------------------------------
957 *
958 * StringToState --
959 *
960 * Converts the string to a state value. Valid states are
961 * disabled, normal.
962 *
963 *----------------------------------------------------------------------
964 */
965/*ARGSUSED*/
966static int
967StringToState(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; /* Not used. */
971 char *string; /* String representation of option value */
972 char *widgRec; /* Widget structure record */
973 int offset; /* Offset of field in record */
974{
975 int *statePtr = (int *)(widgRec + offset);
976
977 if (strcmp(string, "normal") == 0) {
978 *statePtr = STATE_NORMAL;
979 } else if (strcmp(string, "disabled") == 0) {
980 *statePtr = STATE_DISABLED;
981 } else if (strcmp(string, "active") == 0) {
982 *statePtr = STATE_ACTIVE;
983 } else {
984 Tcl_AppendResult(interp, "bad state \"", string,
985 "\": should be normal, active, or disabled", (char *)NULL);
986 return TCL_ERROR;
987 }
988 return TCL_OK;
989}
990
991/*
992 *----------------------------------------------------------------------
993 *
994 * StateToString --
995 *
996 * Returns the string representation of the state configuration field
997 *
998 * Results:
999 * The string is returned.
1000 *
1001 *----------------------------------------------------------------------
1002 */
1003/*ARGSUSED*/
1004static char *
1005StateToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1006 ClientData clientData; /* Not used. */
1007 Tk_Window tkwin; /* Not used. */
1008 char *widgRec; /* Widget structure record */
1009 int offset; /* Offset of fill in widget record */
1010 Tcl_FreeProc **freeProcPtr; /* Not used. */
1011{
1012 int state = *(int *)(widgRec + offset);
1013
1014 switch (state) {
1015 case STATE_ACTIVE:
1016 return "active";
1017 case STATE_DISABLED:
1018 return "disabled";
1019 case STATE_NORMAL:
1020 return "normal";
1021 default:
1022 return "???";
1023 }
1024}
1025
1026/*
1027 *----------------------------------------------------------------------
1028 *
1029 * StringToList --
1030 *
1031 * Converts the string to a list.
1032 *
1033 *----------------------------------------------------------------------
1034 */
1035/*ARGSUSED*/
1036static int
1037StringToList(clientData, interp, tkwin, string, widgRec, offset)
1038 ClientData clientData; /* Not used. */
1039 Tcl_Interp *interp; /* Interpreter to send results back to */
1040 Tk_Window tkwin; /* Not used. */
1041 char *string; /* String representation of option value */
1042 char *widgRec; /* Widget structure record */
1043 int offset; /* Offset of field in record */
1044{
1045 char ***listPtr = (char ***)(widgRec + offset);
1046 char **elemArr;
1047 int nElem;
1048
1049 if (*listPtr != NULL) {
1050 Blt_Free(*listPtr);
1051 *listPtr = NULL;
1052 }
1053 if ((string == NULL) || (*string == '\0')) {
1054 return TCL_OK;
1055 }
1056 if (Tcl_SplitList(interp, string, &nElem, &elemArr) != TCL_OK) {
1057 return TCL_ERROR;
1058 }
1059 if (nElem > 0) {
1060 *listPtr = elemArr;
1061 }
1062 return TCL_OK;
1063}
1064
1065/*
1066 *----------------------------------------------------------------------
1067 *
1068 * ListToString --
1069 *
1070 * Returns the string representation of the state configuration field
1071 *
1072 * Results:
1073 * The string is returned.
1074 *
1075 *----------------------------------------------------------------------
1076 */
1077/*ARGSUSED*/
1078static char *
1079ListToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1080 ClientData clientData; /* Not used. */
1081 Tk_Window tkwin; /* Not used. */
1082 char *widgRec; /* Widget structure record. */
1083 int offset; /* Offset of fill in widget record. */
1084 Tcl_FreeProc **freeProcPtr; /* Not used. */
1085{
1086 char **list = *(char ***)(widgRec + offset);
1087 register char **p;
1088 char *result;
1089 Tcl_DString dString;
1090
1091 if (list == NULL) {
1092 return "";
1093 }
1094 Tcl_DStringInit(&dString);
1095 for (p = list; *p != NULL; p++) {
1096 Tcl_DStringAppendElement(&dString, *p);
1097 }
1098 result = Tcl_DStringValue(&dString);
1099 if (result == dString.staticSpace) {
1100 result = Blt_Strdup(result);
1101 }
1102 Tcl_DStringFree(&dString);
1103 *freeProcPtr = (Tcl_FreeProc *)Blt_Free;
1104 return result;
1105}
1106
1107
1108/*
1109 *----------------------------------------------------------------------
1110 *
1111 * StringToTile --
1112 *
1113 * Converts the name of an image into a tile.
1114 *
1115 *----------------------------------------------------------------------
1116 */
1117/*ARGSUSED*/
1118static int
1119StringToTile(clientData, interp, tkwin, string, widgRec, offset)
1120 ClientData clientData; /* Not used. */
1121 Tcl_Interp *interp; /* Interpreter to send results back to */
1122 Tk_Window tkwin; /* Window on same display as tile */
1123 char *string; /* Name of image */
1124 char *widgRec; /* Widget structure record */
1125 int offset; /* Offset of tile in record */
1126{
1127 Blt_Tile *tilePtr = (Blt_Tile *)(widgRec + offset);
1128 Blt_Tile tile, oldTile;
1129
1130 oldTile = *tilePtr;
1131 tile = NULL;
1132 if ((string != NULL) && (*string != '\0')) {
1133 if (Blt_GetTile(interp, tkwin, string, &tile) != TCL_OK) {
1134 return TCL_ERROR;
1135 }
1136 }
1137 /* Don't delete the information for the old tile, until we know
1138 * that we successfully allocated a new one. */
1139 if (oldTile != NULL) {
1140 Blt_FreeTile(oldTile);
1141 }
1142 *tilePtr = tile;
1143 return TCL_OK;
1144}
1145
1146/*
1147 *----------------------------------------------------------------------
1148 *
1149 * TileToString --
1150 *
1151 * Returns the name of the tile.
1152 *
1153 * Results:
1154 * The name of the tile is returned.
1155 *
1156 *----------------------------------------------------------------------
1157 */
1158/*ARGSUSED*/
1159static char *
1160TileToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1161 ClientData clientData; /* Not used. */
1162 Tk_Window tkwin; /* Not used. */
1163 char *widgRec; /* Widget structure record */
1164 int offset; /* Offset of tile in record */
1165 Tcl_FreeProc **freeProcPtr; /* Not used. */
1166{
1167 Blt_Tile tile = *(Blt_Tile *)(widgRec + offset);
1168
1169 return Blt_NameOfTile(tile);
1170}
1171
1172/*
1173 *----------------------------------------------------------------------
1174 *
1175 * Blt_ConfigModified --
1176 *
1177 * Given the configuration specifications and one or more option
1178 * patterns (terminated by a NULL), indicate if any of the matching
1179 * configuration options has been reset.
1180 *
1181 * Results:
1182 * Returns 1 if one of the options has changed, 0 otherwise.
1183 *
1184 *----------------------------------------------------------------------
1185 */
1186int Blt_ConfigModified
1187TCL_VARARGS_DEF(Tk_ConfigSpec *, arg1)
1188{
1189 va_list argList;
1190 Tk_ConfigSpec *specs;
1191 register Tk_ConfigSpec *specPtr;
1192 register char *option;
1193
1194 specs = TCL_VARARGS_START(Tk_ConfigSpec *, arg1, argList);
1195 while ((option = va_arg(argList, char *)) != NULL) {
1196 for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
1197 if ((Tcl_StringMatch(specPtr->argvName, option)) &&
1198 (specPtr->specFlags & TK_CONFIG_OPTION_SPECIFIED)) {
1199 va_end(argList);
1200 return 1;
1201 }
1202 }
1203 }
1204 va_end(argList);
1205 return 0;
1206}
1207
1208/*
1209 *----------------------------------------------------------------------
1210 *
1211 * Blt_ConfigureWidgetComponent --
1212 *
1213 * Configures a component of a widget. This is useful for
1214 * widgets that have multiple components which aren't uniquely
1215 * identified by a Tk_Window. It allows us, for example, set
1216 * resources for axes of the graph widget. The graph really has
1217 * only one window, but its convenient to specify components in a
1218 * hierarchy of options.
1219 *
1220 * *graph.x.logScale yes
1221 * *graph.Axis.logScale yes
1222 * *graph.temperature.scaleSymbols yes
1223 * *graph.Element.scaleSymbols yes
1224 *
1225 * This is really a hack to work around the limitations of the Tk
1226 * resource database. It creates a temporary window, needed to
1227 * call Tk_ConfigureWidget, using the name of the component.
1228 *
1229 * Results:
1230 * A standard Tcl result.
1231 *
1232 * Side Effects:
1233 * A temporary window is created merely to pass to Tk_ConfigureWidget.
1234 *
1235 *----------------------------------------------------------------------
1236 */
1237int
1238Blt_ConfigureWidgetComponent(interp, parent, resName, className, specsPtr,
1239 argc, argv, widgRec, flags)
1240 Tcl_Interp *interp;
1241 Tk_Window parent; /* Window to associate with component */
1242 char resName[]; /* Name of component */
1243 char className[];
1244 Tk_ConfigSpec *specsPtr;
1245 int argc;
1246 char *argv[];
1247 char *widgRec;
1248 int flags;
1249{
1250 Tk_Window tkwin;
1251 int result;
1252 char *tempName;
1253 int isTemporary = FALSE;
1254
1255 tempName = Blt_Strdup(resName);
1256
1257 /* Window name can't start with an upper case letter */
1258 tempName[0] = tolower(resName[0]);
1259
1260 /*
1261 * Create component if a child window by the component's name
1262 * doesn't already exist.
1263 */
1264 tkwin = Blt_FindChild(parent, tempName);
1265 if (tkwin == NULL) {
1266 tkwin = Tk_CreateWindow(interp, parent, tempName, (char *)NULL);
1267 isTemporary = TRUE;
1268 }
1269 if (tkwin == NULL) {
1270 Tcl_AppendResult(interp, "can't find window in \"",
1271 Tk_PathName(parent), "\"", (char *)NULL);
1272 return TCL_ERROR;
1273 }
1274 assert(Tk_Depth(tkwin) == Tk_Depth(parent));
1275 Blt_Free(tempName);
1276
1277 Tk_SetClass(tkwin, className);
1278 result = Tk_ConfigureWidget(interp, tkwin, specsPtr, argc, argv, widgRec,
1279 flags);
1280 if (isTemporary) {
1281 Tk_DestroyWindow(tkwin);
1282 }
1283 return result;
1284}
1285
1286
1287/*
1288 *----------------------------------------------------------------------
1289 *
1290 * Blt_StringToEnum --
1291 *
1292 * Converts the string into its enumerated type.
1293 *
1294 *----------------------------------------------------------------------
1295 */
1296/*ARGSUSED*/
1297int
1298Blt_StringToEnum(clientData, interp, tkwin, string, widgRec, offset)
1299 ClientData clientData; /* Vectors of valid strings. */
1300 Tcl_Interp *interp; /* Interpreter to send results back to */
1301 Tk_Window tkwin; /* Not used. */
1302 char *string; /* String to match. */
1303 char *widgRec; /* Widget record. */
1304 int offset; /* Offset of field in record */
1305{
1306 int *enumPtr = (int *)(widgRec + offset);
1307 char c;
1308 register char **p;
1309 register int i;
1310 int count;
1311
1312 c = string[0];
1313 count = 0;
1314 for (p = (char **)clientData; *p != NULL; p++) {
1315 if ((c == p[0][0]) && (strcmp(string, *p) == 0)) {
1316 *enumPtr = count;
1317 return TCL_OK;
1318 }
1319 count++;
1320 }
1321 *enumPtr = -1;
1322
1323 Tcl_AppendResult(interp, "bad value \"", string, "\": should be ",
1324 (char *)NULL);
1325 p = (char **)clientData;
1326 if (count > 0) {
1327 Tcl_AppendResult(interp, p[0], (char *)NULL);
1328 }
1329 for (i = 1; i < (count - 1); i++) {
1330 Tcl_AppendResult(interp, " ", p[i], ", ", (char *)NULL);
1331 }
1332 if (count > 1) {
1333 Tcl_AppendResult(interp, " or ", p[count - 1], ".", (char *)NULL);
1334 }
1335 return TCL_ERROR;
1336}
1337
1338/*
1339 *----------------------------------------------------------------------
1340 *
1341 * Blt_EnumToString --
1342 *
1343 * Returns the string associated with the enumerated type.
1344 *
1345 *----------------------------------------------------------------------
1346 */
1347/*ARGSUSED*/
1348char *
1349Blt_EnumToString(clientData, tkwin, widgRec, offset, freeProcPtr)
1350 ClientData clientData; /* List of strings. */
1351 Tk_Window tkwin; /* Not used. */
1352 char *widgRec; /* Widget record */
1353 int offset; /* Offset of field in widget record */
1354 Tcl_FreeProc **freeProcPtr; /* Not used. */
1355{
1356 int value = *(int *)(widgRec + offset);
1357 char **p;
1358 int count;
1359
1360 count = 0;
1361 for (p = (char **)clientData; *p != NULL; p++) {
1362 count++;
1363 }
1364 if ((value >= count) || (value < 0)) {
1365 return "unknown value";
1366 }
1367 p = (char **)clientData;
1368 return p[value];
1369}
1370
Note: See TracBrowser for help on using the repository browser.