4 * This file contains a number of "Ck_GetXXX" procedures, which
5 * parse text strings into useful forms for Ck.
7 * Copyright (c) 1990-1994 The Regents of the University of California.
8 * Copyright (c) 1994-1995 Sun Microsystems, Inc.
9 * Copyright (c) 1995 Christian Werner
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
22 static CPair *cPairs = NULL;
23 static int numPairs, newPair;
26 * The hash table below is used to keep track of all the Ck_Uids created
30 static Tcl_HashTable uidTable;
31 static int initialized = 0;
37 { "black", COLOR_BLACK },
38 { "blue", COLOR_BLUE },
39 { "cyan", COLOR_CYAN },
40 { "green", COLOR_GREEN },
41 { "magenta", COLOR_MAGENTA },
43 { "white", COLOR_WHITE },
44 { "yellow", COLOR_YELLOW }
54 { "normal", A_NORMAL },
55 { "reverse", A_REVERSE },
56 { "standout", A_STANDOUT },
57 { "underline", A_UNDERLINE }
61 *----------------------------------------------------------------------
65 * Given a string, this procedure returns a unique identifier
69 * This procedure returns a Ck_Uid corresponding to the "string"
70 * argument. The Ck_Uid has a string value identical to string
71 * (strcmp will return 0), but it's guaranteed that any other
72 * calls to this procedure with a string equal to "string" will
73 * return exactly the same result (i.e. can compare Ck_Uid
74 * *values* directly, without having to call strcmp on what they
78 * New information may be entered into the identifier table.
80 *----------------------------------------------------------------------
85 char *string; /* String to convert. */
90 Tcl_InitHashTable(&uidTable, TCL_STRING_KEYS);
93 return (Ck_Uid) Tcl_GetHashKey(&uidTable,
94 Tcl_CreateHashEntry(&uidTable, string, &dummy));
98 *------------------------------------------------------------------------
102 * Given a color specification, return curses color value.
105 * TCL_OK if color found, curses color in *colorPtr.
106 * TCL_ERROR if color not found; interp->result contains an
112 *------------------------------------------------------------------------
116 Ck_GetColor(interp, name, colorPtr)
125 for (i = 0; i < sizeof (ctab) / sizeof (ctab[0]); i++)
126 if (strncmp(name, ctab[i].name, len) == 0) {
127 if (colorPtr != NULL)
128 *colorPtr = ctab[i].value;
131 Tcl_AppendResult(interp, "bad color \"", name, "\"", (char *) NULL);
136 *------------------------------------------------------------------------
140 * Given a curses color, return its name.
143 * String: name of color, or NULL if no valid color.
148 *------------------------------------------------------------------------
152 Ck_NameOfColor(color)
153 int color; /* Curses color to get name for */
157 for (i = 0; i < sizeof (ctab) / sizeof (ctab[0]); i++)
158 if (ctab[i].value == color)
164 *------------------------------------------------------------------------
168 * Given an attribute specification, return attribute value.
171 * TCL_OK if color found, curses color in *colorPtr.
172 * TCL_ERROR if color not found; interp->result contains an
178 *------------------------------------------------------------------------
182 Ck_GetAttr(interp, name, attrPtr)
187 int i, k, len, largc;
190 if (Tcl_SplitList(interp, name, &largc, &largv) != TCL_OK)
194 if (largc > 1 || (largc == 1 && largv[0][0] != '\0')) {
195 for (i = 0; i < largc; i++) {
196 len = strlen(largv[i]);
198 for (k = 0; k < sizeof (atab) / sizeof (atab[0]); k++)
199 if (strncmp(largv[i], atab[k].name, len) == 0) {
201 *attrPtr |= atab[k].value;
204 if (k >= sizeof (atab) / sizeof (atab[0])) {
205 Tcl_AppendResult(interp, "bad attribute \"",
206 name, "\"", (char *) NULL);
207 ckfree((char *) largv);
213 ckfree((char *) largv);
218 *------------------------------------------------------------------------
222 * Given an attribute value, return its textual specification.
225 * interp->result contains result or message.
230 *------------------------------------------------------------------------
241 Tcl_DStringInit(&list);
242 if (attr == -1 || attr == A_NORMAL)
243 Tcl_DStringAppendElement(&list, "normal");
245 for (i = 0; i < sizeof (atab) / sizeof (atab[0]); i++)
246 if (attr & atab[i].value)
247 Tcl_DStringAppendElement(&list, atab[i].name);
249 result = ckalloc(Tcl_DStringLength(&list) + 1);
250 strcpy(result, Tcl_DStringValue(&list));
251 Tcl_DStringFree(&list);
255 *------------------------------------------------------------------------
259 * Given background/foreground curses colors, a color pair
260 * is allocated and returned.
263 * TCL_OK if color found, curses color in *colorPtr.
264 * TCL_ERROR if color not found; interp->result contains an
270 *------------------------------------------------------------------------
274 Ck_GetPair(winPtr, fg, bg)
280 if (!(winPtr->mainPtr->flags & CK_HAS_COLOR))
281 return COLOR_PAIR(0);
282 if (cPairs == NULL) {
283 cPairs = (CPair *) ckalloc(sizeof (CPair) * (COLOR_PAIRS + 2));
287 for (i = 1; i < numPairs; i++)
288 if (cPairs[i].fg == fg && cPairs[i].bg == bg)
289 return COLOR_PAIR(i);
293 init_pair((short) i, (short) fg, (short) bg);
294 if (++newPair >= COLOR_PAIRS)
298 return COLOR_PAIR(i);
302 *--------------------------------------------------------------
306 * Given a string, return the corresponding Ck_Anchor.
309 * The return value is a standard Tcl return result. If
310 * TCL_OK is returned, then everything went well and the
311 * position is stored at *anchorPtr; otherwise TCL_ERROR
312 * is returned and an error message is left in
318 *--------------------------------------------------------------
322 Ck_GetAnchor(interp, string, anchorPtr)
323 Tcl_Interp *interp; /* Use this for error reporting. */
324 char *string; /* String describing a direction. */
325 Ck_Anchor *anchorPtr; /* Where to store Ck_Anchor corresponding
330 if (string[1] == 0) {
331 *anchorPtr = CK_ANCHOR_N;
333 } else if ((string[1] == 'e') && (string[2] == 0)) {
334 *anchorPtr = CK_ANCHOR_NE;
336 } else if ((string[1] == 'w') && (string[2] == 0)) {
337 *anchorPtr = CK_ANCHOR_NW;
342 if (string[1] == 0) {
343 *anchorPtr = CK_ANCHOR_S;
345 } else if ((string[1] == 'e') && (string[2] == 0)) {
346 *anchorPtr = CK_ANCHOR_SE;
348 } else if ((string[1] == 'w') && (string[2] == 0)) {
349 *anchorPtr = CK_ANCHOR_SW;
355 if (string[1] == 0) {
356 *anchorPtr = CK_ANCHOR_E;
361 if (string[1] == 0) {
362 *anchorPtr = CK_ANCHOR_W;
367 if (strncmp(string, "center", strlen(string)) == 0) {
368 *anchorPtr = CK_ANCHOR_CENTER;
375 Tcl_AppendResult(interp, "bad anchor position \"", string,
376 "\": must be n, ne, e, se, s, sw, w, nw, or center",
382 *--------------------------------------------------------------
386 * Given a Ck_Anchor, return the string that corresponds
395 *--------------------------------------------------------------
399 Ck_NameOfAnchor(anchor)
400 Ck_Anchor anchor; /* Anchor for which identifying string
404 case CK_ANCHOR_N: return "n";
405 case CK_ANCHOR_NE: return "ne";
406 case CK_ANCHOR_E: return "e";
407 case CK_ANCHOR_SE: return "se";
408 case CK_ANCHOR_S: return "s";
409 case CK_ANCHOR_SW: return "sw";
410 case CK_ANCHOR_W: return "w";
411 case CK_ANCHOR_NW: return "nw";
412 case CK_ANCHOR_CENTER: return "center";
414 return "unknown anchor position";
418 *--------------------------------------------------------------
422 * Given a string, return the corresponding Ck_Justify.
425 * The return value is a standard Tcl return result. If
426 * TCL_OK is returned, then everything went well and the
427 * justification is stored at *justifyPtr; otherwise
428 * TCL_ERROR is returned and an error message is left in
434 *--------------------------------------------------------------
438 Ck_GetJustify(interp, string, justifyPtr)
439 Tcl_Interp *interp; /* Use this for error reporting. */
440 char *string; /* String describing a justification style. */
441 Ck_Justify *justifyPtr; /* Where to store Ck_Justify corresponding
447 length = strlen(string);
449 if ((c == 'l') && (strncmp(string, "left", length) == 0)) {
450 *justifyPtr = CK_JUSTIFY_LEFT;
453 if ((c == 'r') && (strncmp(string, "right", length) == 0)) {
454 *justifyPtr = CK_JUSTIFY_RIGHT;
457 if ((c == 'c') && (strncmp(string, "center", length) == 0)) {
458 *justifyPtr = CK_JUSTIFY_CENTER;
461 if ((c == 'f') && (strncmp(string, "fill", length) == 0)) {
462 *justifyPtr = CK_JUSTIFY_FILL;
466 Tcl_AppendResult(interp, "bad justification \"", string,
467 "\": must be left, right, center, or fill",
473 *--------------------------------------------------------------
475 * Ck_NameOfJustify --
477 * Given a Ck_Justify, return the string that corresponds
486 *--------------------------------------------------------------
490 Ck_NameOfJustify(justify)
491 Ck_Justify justify; /* Justification style for which
492 * identifying string is desired. */
495 case CK_JUSTIFY_LEFT: return "left";
496 case CK_JUSTIFY_RIGHT: return "right";
497 case CK_JUSTIFY_CENTER: return "center";
498 case CK_JUSTIFY_FILL: return "fill";
500 return "unknown justification style";
504 *--------------------------------------------------------------
508 * Given a string, return the coordinate that corresponds
517 *--------------------------------------------------------------
521 Ck_GetCoord(interp, winPtr, string, intPtr)
522 Tcl_Interp *interp; /* Use this for error reporting. */
523 CkWindow *winPtr; /* Window (not used). */
524 char *string; /* String to convert. */
525 int *intPtr; /* Place to store converted result. */
529 if (Tcl_GetInt(interp, string, &value) != TCL_OK)
532 Tcl_AppendResult(interp, "coordinate may not be negative",