OSDN Git Service

Initial revision
[pf3gnuchains/pf3gnuchains4x.git] / tk / generic / tkGet.c
1 /* 
2  * tkGet.c --
3  *
4  *      This file contains a number of "Tk_GetXXX" procedures, which
5  *      parse text strings into useful forms for Tk.  This file has
6  *      the simpler procedures, like Tk_GetDirection and Tk_GetUid.
7  *      The more complex procedures like Tk_GetColor are in separate
8  *      files.
9  *
10  * Copyright (c) 1991-1994 The Regents of the University of California.
11  * Copyright (c) 1994-1995 Sun Microsystems, Inc.
12  *
13  * See the file "license.terms" for information on usage and redistribution
14  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
15  *
16  * RCS: @(#) $Id$
17  */
18
19 #include "tkInt.h"
20 #include "tkPort.h"
21
22 /*
23  * The hash table below is used to keep track of all the Tk_Uids created
24  * so far.
25  */
26
27 static Tcl_HashTable uidTable;
28 static int initialized = 0;
29 \f
30 /*
31  *--------------------------------------------------------------
32  *
33  * Tk_GetAnchor --
34  *
35  *      Given a string, return the corresponding Tk_Anchor.
36  *
37  * Results:
38  *      The return value is a standard Tcl return result.  If
39  *      TCL_OK is returned, then everything went well and the
40  *      position is stored at *anchorPtr;  otherwise TCL_ERROR
41  *      is returned and an error message is left in
42  *      interp->result.
43  *
44  * Side effects:
45  *      None.
46  *
47  *--------------------------------------------------------------
48  */
49
50 int
51 Tk_GetAnchor(interp, string, anchorPtr)
52     Tcl_Interp *interp;         /* Use this for error reporting. */
53     char *string;               /* String describing a direction. */
54     Tk_Anchor *anchorPtr;       /* Where to store Tk_Anchor corresponding
55                                  * to string. */
56 {
57     switch (string[0]) {
58         case 'n':
59             if (string[1] == 0) {
60                 *anchorPtr = TK_ANCHOR_N;
61                 return TCL_OK;
62             } else if ((string[1] == 'e') && (string[2] == 0)) {
63                 *anchorPtr = TK_ANCHOR_NE;
64                 return TCL_OK;
65             } else if ((string[1] == 'w') && (string[2] == 0)) {
66                 *anchorPtr = TK_ANCHOR_NW;
67                 return TCL_OK;
68             }
69             goto error;
70         case 's':
71             if (string[1] == 0) {
72                 *anchorPtr = TK_ANCHOR_S;
73                 return TCL_OK;
74             } else if ((string[1] == 'e') && (string[2] == 0)) {
75                 *anchorPtr = TK_ANCHOR_SE;
76                 return TCL_OK;
77             } else if ((string[1] == 'w') && (string[2] == 0)) {
78                 *anchorPtr = TK_ANCHOR_SW;
79                 return TCL_OK;
80             } else {
81                 goto error;
82             }
83         case 'e':
84             if (string[1] == 0) {
85                 *anchorPtr = TK_ANCHOR_E;
86                 return TCL_OK;
87             }
88             goto error;
89         case 'w':
90             if (string[1] == 0) {
91                 *anchorPtr = TK_ANCHOR_W;
92                 return TCL_OK;
93             }
94             goto error;
95         case 'c':
96             if (strncmp(string, "center", strlen(string)) == 0) {
97                 *anchorPtr = TK_ANCHOR_CENTER;
98                 return TCL_OK;
99             }
100             goto error;
101     }
102
103     error:
104     Tcl_AppendResult(interp, "bad anchor position \"", string,
105             "\": must be n, ne, e, se, s, sw, w, nw, or center",
106             (char *) NULL);
107     return TCL_ERROR;
108 }
109 \f
110 /*
111  *--------------------------------------------------------------
112  *
113  * Tk_NameOfAnchor --
114  *
115  *      Given a Tk_Anchor, return the string that corresponds
116  *      to it.
117  *
118  * Results:
119  *      None.
120  *
121  * Side effects:
122  *      None.
123  *
124  *--------------------------------------------------------------
125  */
126
127 char *
128 Tk_NameOfAnchor(anchor)
129     Tk_Anchor anchor;           /* Anchor for which identifying string
130                                  * is desired. */
131 {
132     switch (anchor) {
133         case TK_ANCHOR_N: return "n";
134         case TK_ANCHOR_NE: return "ne";
135         case TK_ANCHOR_E: return "e";
136         case TK_ANCHOR_SE: return "se";
137         case TK_ANCHOR_S: return "s";
138         case TK_ANCHOR_SW: return "sw";
139         case TK_ANCHOR_W: return "w";
140         case TK_ANCHOR_NW: return "nw";
141         case TK_ANCHOR_CENTER: return "center";
142     }
143     return "unknown anchor position";
144 }
145 \f
146 /*
147  *--------------------------------------------------------------
148  *
149  * Tk_GetJoinStyle --
150  *
151  *      Given a string, return the corresponding Tk_JoinStyle.
152  *
153  * Results:
154  *      The return value is a standard Tcl return result.  If
155  *      TCL_OK is returned, then everything went well and the
156  *      justification is stored at *joinPtr;  otherwise
157  *      TCL_ERROR is returned and an error message is left in
158  *      interp->result.
159  *
160  * Side effects:
161  *      None.
162  *
163  *--------------------------------------------------------------
164  */
165
166 int
167 Tk_GetJoinStyle(interp, string, joinPtr)
168     Tcl_Interp *interp;         /* Use this for error reporting. */
169     char *string;               /* String describing a justification style. */
170     int *joinPtr;               /* Where to store join style corresponding
171                                  * to string. */
172 {
173     int c;
174     size_t length;
175
176     c = string[0];
177     length = strlen(string);
178
179     if ((c == 'b') && (strncmp(string, "bevel", length) == 0)) {
180         *joinPtr = JoinBevel;
181         return TCL_OK;
182     }
183     if ((c == 'm') && (strncmp(string, "miter", length) == 0)) {
184         *joinPtr = JoinMiter;
185         return TCL_OK;
186     }
187     if ((c == 'r') && (strncmp(string, "round", length) == 0)) {
188         *joinPtr = JoinRound;
189         return TCL_OK;
190     }
191
192     Tcl_AppendResult(interp, "bad join style \"", string,
193             "\": must be bevel, miter, or round",
194             (char *) NULL);
195     return TCL_ERROR;
196 }
197 \f
198 /*
199  *--------------------------------------------------------------
200  *
201  * Tk_NameOfJoinStyle --
202  *
203  *      Given a Tk_JoinStyle, return the string that corresponds
204  *      to it.
205  *
206  * Results:
207  *      None.
208  *
209  * Side effects:
210  *      None.
211  *
212  *--------------------------------------------------------------
213  */
214
215 char *
216 Tk_NameOfJoinStyle(join)
217     int join;                   /* Join style for which identifying string
218                                  * is desired. */
219 {
220     switch (join) {
221         case JoinBevel: return "bevel";
222         case JoinMiter: return "miter";
223         case JoinRound: return "round";
224     }
225     return "unknown join style";
226 }
227 \f
228 /*
229  *--------------------------------------------------------------
230  *
231  * Tk_GetCapStyle --
232  *
233  *      Given a string, return the corresponding Tk_CapStyle.
234  *
235  * Results:
236  *      The return value is a standard Tcl return result.  If
237  *      TCL_OK is returned, then everything went well and the
238  *      justification is stored at *capPtr;  otherwise
239  *      TCL_ERROR is returned and an error message is left in
240  *      interp->result.
241  *
242  * Side effects:
243  *      None.
244  *
245  *--------------------------------------------------------------
246  */
247
248 int
249 Tk_GetCapStyle(interp, string, capPtr)
250     Tcl_Interp *interp;         /* Use this for error reporting. */
251     char *string;               /* String describing a justification style. */
252     int *capPtr;                /* Where to store cap style corresponding
253                                  * to string. */
254 {
255     int c;
256     size_t length;
257
258     c = string[0];
259     length = strlen(string);
260
261     if ((c == 'b') && (strncmp(string, "butt", length) == 0)) {
262         *capPtr = CapButt;
263         return TCL_OK;
264     }
265     if ((c == 'p') && (strncmp(string, "projecting", length) == 0)) {
266         *capPtr = CapProjecting;
267         return TCL_OK;
268     }
269     if ((c == 'r') && (strncmp(string, "round", length) == 0)) {
270         *capPtr = CapRound;
271         return TCL_OK;
272     }
273
274     Tcl_AppendResult(interp, "bad cap style \"", string,
275             "\": must be butt, projecting, or round",
276             (char *) NULL);
277     return TCL_ERROR;
278 }
279 \f
280 /*
281  *--------------------------------------------------------------
282  *
283  * Tk_NameOfCapStyle --
284  *
285  *      Given a Tk_CapStyle, return the string that corresponds
286  *      to it.
287  *
288  * Results:
289  *      None.
290  *
291  * Side effects:
292  *      None.
293  *
294  *--------------------------------------------------------------
295  */
296
297 char *
298 Tk_NameOfCapStyle(cap)
299     int cap;                    /* Cap style for which identifying string
300                                  * is desired. */
301 {
302     switch (cap) {
303         case CapButt: return "butt";
304         case CapProjecting: return "projecting";
305         case CapRound: return "round";
306     }
307     return "unknown cap style";
308 }
309 \f
310 /*
311  *--------------------------------------------------------------
312  *
313  * Tk_GetJustify --
314  *
315  *      Given a string, return the corresponding Tk_Justify.
316  *
317  * Results:
318  *      The return value is a standard Tcl return result.  If
319  *      TCL_OK is returned, then everything went well and the
320  *      justification is stored at *justifyPtr;  otherwise
321  *      TCL_ERROR is returned and an error message is left in
322  *      interp->result.
323  *
324  * Side effects:
325  *      None.
326  *
327  *--------------------------------------------------------------
328  */
329
330 int
331 Tk_GetJustify(interp, string, justifyPtr)
332     Tcl_Interp *interp;         /* Use this for error reporting. */
333     char *string;               /* String describing a justification style. */
334     Tk_Justify *justifyPtr;     /* Where to store Tk_Justify corresponding
335                                  * to string. */
336 {
337     int c;
338     size_t length;
339
340     c = string[0];
341     length = strlen(string);
342
343     if ((c == 'l') && (strncmp(string, "left", length) == 0)) {
344         *justifyPtr = TK_JUSTIFY_LEFT;
345         return TCL_OK;
346     }
347     if ((c == 'r') && (strncmp(string, "right", length) == 0)) {
348         *justifyPtr = TK_JUSTIFY_RIGHT;
349         return TCL_OK;
350     }
351     if ((c == 'c') && (strncmp(string, "center", length) == 0)) {
352         *justifyPtr = TK_JUSTIFY_CENTER;
353         return TCL_OK;
354     }
355
356     Tcl_AppendResult(interp, "bad justification \"", string,
357             "\": must be left, right, or center",
358             (char *) NULL);
359     return TCL_ERROR;
360 }
361 \f
362 /*
363  *--------------------------------------------------------------
364  *
365  * Tk_NameOfJustify --
366  *
367  *      Given a Tk_Justify, return the string that corresponds
368  *      to it.
369  *
370  * Results:
371  *      None.
372  *
373  * Side effects:
374  *      None.
375  *
376  *--------------------------------------------------------------
377  */
378
379 char *
380 Tk_NameOfJustify(justify)
381     Tk_Justify justify;         /* Justification style for which
382                                  * identifying string is desired. */
383 {
384     switch (justify) {
385         case TK_JUSTIFY_LEFT: return "left";
386         case TK_JUSTIFY_RIGHT: return "right";
387         case TK_JUSTIFY_CENTER: return "center";
388     }
389     return "unknown justification style";
390 }
391 \f
392 /*
393  *----------------------------------------------------------------------
394  *
395  * Tk_GetUid --
396  *
397  *      Given a string, this procedure returns a unique identifier
398  *      for the string.
399  *
400  * Results:
401  *      This procedure returns a Tk_Uid corresponding to the "string"
402  *      argument.  The Tk_Uid has a string value identical to string
403  *      (strcmp will return 0), but it's guaranteed that any other
404  *      calls to this procedure with a string equal to "string" will
405  *      return exactly the same result (i.e. can compare Tk_Uid
406  *      *values* directly, without having to call strcmp on what they
407  *      point to).
408  *
409  * Side effects:
410  *      New information may be entered into the identifier table.
411  *
412  *----------------------------------------------------------------------
413  */
414
415 Tk_Uid
416 Tk_GetUid(string)
417     CONST char *string;         /* String to convert. */
418 {
419     int dummy;
420
421     if (!initialized) {
422         Tcl_InitHashTable(&uidTable, TCL_STRING_KEYS);
423         initialized = 1;
424     }
425     return (Tk_Uid) Tcl_GetHashKey(&uidTable,
426             Tcl_CreateHashEntry(&uidTable, string, &dummy));
427 }
428 \f
429 /*
430  *--------------------------------------------------------------
431  *
432  * Tk_GetScreenMM --
433  *
434  *      Given a string, returns the number of screen millimeters
435  *      corresponding to that string.
436  *
437  * Results:
438  *      The return value is a standard Tcl return result.  If
439  *      TCL_OK is returned, then everything went well and the
440  *      screen distance is stored at *doublePtr;  otherwise
441  *      TCL_ERROR is returned and an error message is left in
442  *      interp->result.
443  *
444  * Side effects:
445  *      None.
446  *
447  *--------------------------------------------------------------
448  */
449
450 int
451 Tk_GetScreenMM(interp, tkwin, string, doublePtr)
452     Tcl_Interp *interp;         /* Use this for error reporting. */
453     Tk_Window tkwin;            /* Window whose screen determines conversion
454                                  * from centimeters and other absolute
455                                  * units. */
456     char *string;               /* String describing a screen distance. */
457     double *doublePtr;          /* Place to store converted result. */
458 {
459     char *end;
460     double d;
461
462     d = strtod(string, &end);
463     if (end == string) {
464         error:
465         Tcl_AppendResult(interp, "bad screen distance \"", string,
466                 "\"", (char *) NULL);
467         return TCL_ERROR;
468     }
469     while ((*end != '\0') && isspace(UCHAR(*end))) {
470         end++;
471     }
472     switch (*end) {
473         case 0:
474             d /= WidthOfScreen(Tk_Screen(tkwin));
475             d *= WidthMMOfScreen(Tk_Screen(tkwin));
476             break;
477         case 'c':
478             d *= 10;
479             end++;
480             break;
481         case 'i':
482             d *= 25.4;
483             end++;
484             break;
485         case 'm':
486             end++;
487             break;
488         case 'p':
489             d *= 25.4/72.0;
490             end++;
491             break;
492         default:
493             goto error;
494     }
495     while ((*end != '\0') && isspace(UCHAR(*end))) {
496         end++;
497     }
498     if (*end != 0) {
499         goto error;
500     }
501     *doublePtr = d;
502     return TCL_OK;
503 }
504 \f
505 /*
506  *--------------------------------------------------------------
507  *
508  * Tk_GetPixels --
509  *
510  *      Given a string, returns the number of pixels corresponding
511  *      to that string.
512  *
513  * Results:
514  *      The return value is a standard Tcl return result.  If
515  *      TCL_OK is returned, then everything went well and the
516  *      rounded pixel distance is stored at *intPtr;  otherwise
517  *      TCL_ERROR is returned and an error message is left in
518  *      interp->result.
519  *
520  * Side effects:
521  *      None.
522  *
523  *--------------------------------------------------------------
524  */
525
526 int
527 Tk_GetPixels(interp, tkwin, string, intPtr)
528     Tcl_Interp *interp;         /* Use this for error reporting. */
529     Tk_Window tkwin;            /* Window whose screen determines conversion
530                                  * from centimeters and other absolute
531                                  * units. */
532     char *string;               /* String describing a justification style. */
533     int *intPtr;                /* Place to store converted result. */
534 {
535     char *end;
536     double d;
537
538     d = strtod(string, &end);
539     if (end == string) {
540         error:
541         Tcl_AppendResult(interp, "bad screen distance \"", string,
542                 "\"", (char *) NULL);
543         return TCL_ERROR;
544     }
545     while ((*end != '\0') && isspace(UCHAR(*end))) {
546         end++;
547     }
548     switch (*end) {
549         case 0:
550             break;
551         case 'c':
552             d *= 10*WidthOfScreen(Tk_Screen(tkwin));
553             d /= WidthMMOfScreen(Tk_Screen(tkwin));
554             end++;
555             break;
556         case 'i':
557             d *= 25.4*WidthOfScreen(Tk_Screen(tkwin));
558             d /= WidthMMOfScreen(Tk_Screen(tkwin));
559             end++;
560             break;
561         case 'm':
562             d *= WidthOfScreen(Tk_Screen(tkwin));
563             d /= WidthMMOfScreen(Tk_Screen(tkwin));
564             end++;
565             break;
566         case 'p':
567             d *= (25.4/72.0)*WidthOfScreen(Tk_Screen(tkwin));
568             d /= WidthMMOfScreen(Tk_Screen(tkwin));
569             end++;
570             break;
571         default:
572             goto error;
573     }
574     while ((*end != '\0') && isspace(UCHAR(*end))) {
575         end++;
576     }
577     if (*end != 0) {
578         goto error;
579     }
580     if (d < 0) {
581         *intPtr = (int) (d - 0.5);
582     } else {
583         *intPtr = (int) (d + 0.5);
584     }
585     return TCL_OK;
586 }