home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / tcl / tk3.3b1 / tkGet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-16  |  14.7 KB  |  605 lines

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