[175] | 1 |
|
---|
| 2 | /*
|
---|
| 3 | * bltGrPen.c --
|
---|
| 4 | *
|
---|
| 5 | * This module implements pens for the BLT graph widget.
|
---|
| 6 | *
|
---|
| 7 | * Copyright 1996-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 "bltGraph.h"
|
---|
| 29 | #include <X11/Xutil.h>
|
---|
| 30 |
|
---|
| 31 | static Tk_OptionParseProc StringToColor;
|
---|
| 32 | static Tk_OptionPrintProc ColorToString;
|
---|
| 33 | static Tk_OptionParseProc StringToPen;
|
---|
| 34 | static Tk_OptionPrintProc PenToString;
|
---|
| 35 | Tk_CustomOption bltColorOption =
|
---|
| 36 | {
|
---|
| 37 | StringToColor, ColorToString, (ClientData)0
|
---|
| 38 | };
|
---|
| 39 | Tk_CustomOption bltPenOption =
|
---|
| 40 | {
|
---|
| 41 | StringToPen, PenToString, (ClientData)0
|
---|
| 42 | };
|
---|
| 43 | Tk_CustomOption bltBarPenOption =
|
---|
| 44 | {
|
---|
| 45 | StringToPen, PenToString, (ClientData)&bltBarElementUid
|
---|
| 46 | };
|
---|
| 47 | Tk_CustomOption bltLinePenOption =
|
---|
| 48 | {
|
---|
| 49 | StringToPen, PenToString, (ClientData)&bltLineElementUid
|
---|
| 50 | };
|
---|
| 51 |
|
---|
| 52 | /*
|
---|
| 53 | *----------------------------------------------------------------------
|
---|
| 54 |
|
---|
| 55 | * StringToColor --
|
---|
| 56 | *
|
---|
| 57 | * Convert the string representation of a color into a XColor pointer.
|
---|
| 58 | *
|
---|
| 59 | * Results:
|
---|
| 60 | * The return value is a standard Tcl result. The color pointer is
|
---|
| 61 | * written into the widget record.
|
---|
| 62 | *
|
---|
| 63 | *----------------------------------------------------------------------
|
---|
| 64 | */
|
---|
| 65 | /*ARGSUSED*/
|
---|
| 66 | static int
|
---|
| 67 | StringToColor(clientData, interp, tkwin, string, widgRec, offset)
|
---|
| 68 | ClientData clientData; /* Not used. */
|
---|
| 69 | Tcl_Interp *interp; /* Interpreter to send results back to */
|
---|
| 70 | Tk_Window tkwin; /* Not used. */
|
---|
| 71 | char *string; /* String representing color */
|
---|
| 72 | char *widgRec; /* Widget record */
|
---|
| 73 | int offset; /* Offset of color field in record */
|
---|
| 74 | {
|
---|
| 75 | XColor **colorPtrPtr = (XColor **)(widgRec + offset);
|
---|
| 76 | XColor *colorPtr;
|
---|
| 77 | unsigned int length;
|
---|
| 78 | char c;
|
---|
| 79 |
|
---|
| 80 | if ((string == NULL) || (*string == '\0')) {
|
---|
| 81 | *colorPtrPtr = NULL;
|
---|
| 82 | return TCL_OK;
|
---|
| 83 | }
|
---|
| 84 | c = string[0];
|
---|
| 85 | length = strlen(string);
|
---|
| 86 |
|
---|
| 87 | if ((c == 'd') && (strncmp(string, "defcolor", length) == 0)) {
|
---|
| 88 | colorPtr = COLOR_DEFAULT;
|
---|
| 89 | } else {
|
---|
| 90 | colorPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(string));
|
---|
| 91 | if (colorPtr == NULL) {
|
---|
| 92 | return TCL_ERROR;
|
---|
| 93 | }
|
---|
| 94 | }
|
---|
| 95 | *colorPtrPtr = colorPtr;
|
---|
| 96 | return TCL_OK;
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | /*
|
---|
| 100 | *----------------------------------------------------------------------
|
---|
| 101 | *
|
---|
| 102 | * NameOfColor --
|
---|
| 103 | *
|
---|
| 104 | * Convert the color option value into a string.
|
---|
| 105 | *
|
---|
| 106 | * Results:
|
---|
| 107 | * The static string representing the color option is returned.
|
---|
| 108 | *
|
---|
| 109 | *----------------------------------------------------------------------
|
---|
| 110 | */
|
---|
| 111 | static char *
|
---|
| 112 | NameOfColor(colorPtr)
|
---|
| 113 | XColor *colorPtr;
|
---|
| 114 | {
|
---|
| 115 | if (colorPtr == NULL) {
|
---|
| 116 | return "";
|
---|
| 117 | } else if (colorPtr == COLOR_DEFAULT) {
|
---|
| 118 | return "defcolor";
|
---|
| 119 | } else {
|
---|
| 120 | return Tk_NameOfColor(colorPtr);
|
---|
| 121 | }
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | /*
|
---|
| 125 | *----------------------------------------------------------------------
|
---|
| 126 | *
|
---|
| 127 | * ColorToString --
|
---|
| 128 | *
|
---|
| 129 | * Convert the color value into a string.
|
---|
| 130 | *
|
---|
| 131 | * Results:
|
---|
| 132 | * The string representing the symbol color is returned.
|
---|
| 133 | *
|
---|
| 134 | *----------------------------------------------------------------------
|
---|
| 135 | */
|
---|
| 136 | /*ARGSUSED*/
|
---|
| 137 | static char *
|
---|
| 138 | ColorToString(clientData, tkwin, widgRec, offset, freeProcPtr)
|
---|
| 139 | ClientData clientData; /* Not used. */
|
---|
| 140 | Tk_Window tkwin; /* Not used. */
|
---|
| 141 | char *widgRec; /* Widget information record */
|
---|
| 142 | int offset; /* Offset of symbol type in record */
|
---|
| 143 | Tcl_FreeProc **freeProcPtr; /* Not used. */
|
---|
| 144 | {
|
---|
| 145 | XColor *colorPtr = *(XColor **)(widgRec + offset);
|
---|
| 146 |
|
---|
| 147 | return NameOfColor(colorPtr);
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | /*
|
---|
| 151 | *----------------------------------------------------------------------
|
---|
| 152 | *
|
---|
| 153 | * StringToPen --
|
---|
| 154 | *
|
---|
| 155 | * Convert the color value into a string.
|
---|
| 156 | *
|
---|
| 157 | * Results:
|
---|
| 158 | * The string representing the symbol color is returned.
|
---|
| 159 | *
|
---|
| 160 | *----------------------------------------------------------------------
|
---|
| 161 | */
|
---|
| 162 | /*ARGSUSED*/
|
---|
| 163 | static int
|
---|
| 164 | StringToPen(clientData, interp, tkwin, string, widgRec, offset)
|
---|
| 165 | ClientData clientData; /* Not used. */
|
---|
| 166 | Tcl_Interp *interp; /* Interpreter to send results back to */
|
---|
| 167 | Tk_Window tkwin; /* Not used. */
|
---|
| 168 | char *string; /* String representing pen */
|
---|
| 169 | char *widgRec; /* Widget record */
|
---|
| 170 | int offset; /* Offset of pen field in record */
|
---|
| 171 | {
|
---|
| 172 | Blt_Uid classUid = *(Blt_Uid *)clientData; /* Element type. */
|
---|
| 173 | Pen **penPtrPtr = (Pen **)(widgRec + offset);
|
---|
| 174 | Pen *penPtr;
|
---|
| 175 | Graph *graphPtr;
|
---|
| 176 |
|
---|
| 177 | penPtr = NULL;
|
---|
| 178 | graphPtr = Blt_GetGraphFromWindowData(tkwin);
|
---|
| 179 |
|
---|
| 180 | if (classUid == NULL) {
|
---|
| 181 | classUid = graphPtr->classUid;
|
---|
| 182 | }
|
---|
| 183 | if ((string != NULL) && (string[0] != '\0')) {
|
---|
| 184 | if (Blt_GetPen(graphPtr, string, classUid, &penPtr) != TCL_OK) {
|
---|
| 185 | return TCL_ERROR;
|
---|
| 186 | }
|
---|
| 187 | }
|
---|
| 188 | /* Release the old pen */
|
---|
| 189 | if (*penPtrPtr != NULL) {
|
---|
| 190 | Blt_FreePen(graphPtr, *penPtrPtr);
|
---|
| 191 | }
|
---|
| 192 | *penPtrPtr = penPtr;
|
---|
| 193 | return TCL_OK;
|
---|
| 194 | }
|
---|
| 195 |
|
---|
| 196 | /*
|
---|
| 197 | *----------------------------------------------------------------------
|
---|
| 198 | *
|
---|
| 199 | * PenToString --
|
---|
| 200 | *
|
---|
| 201 | * Parse the name of the name.
|
---|
| 202 | *
|
---|
| 203 | * Results:
|
---|
| 204 | * The return value is a standard Tcl result.
|
---|
| 205 | *
|
---|
| 206 | *----------------------------------------------------------------------
|
---|
| 207 | */
|
---|
| 208 | /*ARGSUSED*/
|
---|
| 209 | static char *
|
---|
| 210 | PenToString(clientData, tkwin, widgRec, offset, freeProcPtr)
|
---|
| 211 | ClientData clientData; /* Not used. */
|
---|
| 212 | Tk_Window tkwin; /* Not used. */
|
---|
| 213 | char *widgRec; /* Widget information record */
|
---|
| 214 | int offset; /* Offset of pen in record */
|
---|
| 215 | Tcl_FreeProc **freeProcPtr; /* Not used. */
|
---|
| 216 | {
|
---|
| 217 | Pen *penPtr = *(Pen **)(widgRec + offset);
|
---|
| 218 |
|
---|
| 219 | return penPtr->name;
|
---|
| 220 | }
|
---|
| 221 | |
---|
| 222 |
|
---|
| 223 | /*
|
---|
| 224 | *----------------------------------------------------------------------
|
---|
| 225 | *
|
---|
| 226 | * NameToPen --
|
---|
| 227 | *
|
---|
| 228 | * Find and return the pen style from a given name.
|
---|
| 229 | *
|
---|
| 230 | * Results:
|
---|
| 231 | * A standard TCL result.
|
---|
| 232 | *
|
---|
| 233 | *----------------------------------------------------------------------
|
---|
| 234 | */
|
---|
| 235 | static Pen *
|
---|
| 236 | NameToPen(graphPtr, name)
|
---|
| 237 | Graph *graphPtr;
|
---|
| 238 | char *name;
|
---|
| 239 | {
|
---|
| 240 | Blt_HashEntry *hPtr;
|
---|
| 241 | Pen *penPtr;
|
---|
| 242 |
|
---|
| 243 | hPtr = Blt_FindHashEntry(&(graphPtr->penTable), name);
|
---|
| 244 | if (hPtr == NULL) {
|
---|
| 245 | notFound:
|
---|
| 246 | Tcl_AppendResult(graphPtr->interp, "can't find pen \"", name,
|
---|
| 247 | "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
|
---|
| 248 | return NULL;
|
---|
| 249 | }
|
---|
| 250 | penPtr = (Pen *)Blt_GetHashValue(hPtr);
|
---|
| 251 | if (penPtr->flags & PEN_DELETE_PENDING) {
|
---|
| 252 | goto notFound;
|
---|
| 253 | }
|
---|
| 254 | return penPtr;
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | static void
|
---|
| 258 | DestroyPen(graphPtr, penPtr)
|
---|
| 259 | Graph *graphPtr;
|
---|
| 260 | Pen *penPtr;
|
---|
| 261 | {
|
---|
| 262 | Tk_FreeOptions(penPtr->configSpecs, (char *)penPtr, graphPtr->display, 0);
|
---|
| 263 | (*penPtr->destroyProc) (graphPtr, penPtr);
|
---|
| 264 | if ((penPtr->name != NULL) && (penPtr->name[0] != '\0')) {
|
---|
| 265 | Blt_Free(penPtr->name);
|
---|
| 266 | }
|
---|
| 267 | if (penPtr->hashPtr != NULL) {
|
---|
| 268 | Blt_DeleteHashEntry(&(graphPtr->penTable), penPtr->hashPtr);
|
---|
| 269 | }
|
---|
| 270 | Blt_Free(penPtr);
|
---|
| 271 | }
|
---|
| 272 |
|
---|
| 273 | void
|
---|
| 274 | Blt_FreePen(graphPtr, penPtr)
|
---|
| 275 | Graph *graphPtr;
|
---|
| 276 | Pen *penPtr;
|
---|
| 277 | {
|
---|
| 278 | penPtr->refCount--;
|
---|
| 279 | if ((penPtr->refCount == 0) && (penPtr->flags & PEN_DELETE_PENDING)) {
|
---|
| 280 | DestroyPen(graphPtr, penPtr);
|
---|
| 281 | }
|
---|
| 282 | }
|
---|
| 283 |
|
---|
| 284 | Pen *
|
---|
| 285 | Blt_CreatePen(graphPtr, penName, classUid, nOpts, options)
|
---|
| 286 | Graph *graphPtr;
|
---|
| 287 | char *penName;
|
---|
| 288 | Blt_Uid classUid;
|
---|
| 289 | int nOpts;
|
---|
| 290 | char **options;
|
---|
| 291 | {
|
---|
| 292 |
|
---|
| 293 | Pen *penPtr;
|
---|
| 294 | Blt_HashEntry *hPtr;
|
---|
| 295 | unsigned int length, configFlags;
|
---|
| 296 | int isNew;
|
---|
| 297 | register int i;
|
---|
| 298 |
|
---|
| 299 | /*
|
---|
| 300 | * Scan the option list for a "-type" entry. This will indicate
|
---|
| 301 | * what type of pen we are creating. Otherwise we'll default to the
|
---|
| 302 | * suggested type. Last -type option wins.
|
---|
| 303 | */
|
---|
| 304 | for (i = 0; i < nOpts; i += 2) {
|
---|
| 305 | length = strlen(options[i]);
|
---|
| 306 | if ((length > 2) && (strncmp(options[i], "-type", length) == 0)) {
|
---|
| 307 | char *arg;
|
---|
| 308 |
|
---|
| 309 | arg = options[i + 1];
|
---|
| 310 | if (strcmp(arg, "bar") == 0) {
|
---|
| 311 | classUid = bltBarElementUid;
|
---|
| 312 | } else if (strcmp(arg, "line") != 0) {
|
---|
| 313 | classUid = bltLineElementUid;
|
---|
| 314 | } else if (strcmp(arg, "strip") != 0) {
|
---|
| 315 | classUid = bltLineElementUid;
|
---|
| 316 | } else {
|
---|
| 317 | Tcl_AppendResult(graphPtr->interp, "unknown pen type \"",
|
---|
| 318 | arg, "\" specified", (char *)NULL);
|
---|
| 319 | return NULL;
|
---|
| 320 | }
|
---|
| 321 | }
|
---|
| 322 | }
|
---|
| 323 | if (classUid == bltStripElementUid) {
|
---|
| 324 | classUid = bltLineElementUid;
|
---|
| 325 | }
|
---|
| 326 | hPtr = Blt_CreateHashEntry(&(graphPtr->penTable), penName, &isNew);
|
---|
| 327 | if (!isNew) {
|
---|
| 328 | penPtr = (Pen *)Blt_GetHashValue(hPtr);
|
---|
| 329 | if (!(penPtr->flags & PEN_DELETE_PENDING)) {
|
---|
| 330 | Tcl_AppendResult(graphPtr->interp, "pen \"", penName,
|
---|
| 331 | "\" already exists in \"", Tk_PathName(graphPtr->tkwin), "\"",
|
---|
| 332 | (char *)NULL);
|
---|
| 333 | return NULL;
|
---|
| 334 | }
|
---|
| 335 | if (penPtr->classUid != classUid) {
|
---|
| 336 | Tcl_AppendResult(graphPtr->interp, "pen \"", penName,
|
---|
| 337 | "\" in-use: can't change pen type from \"", penPtr->classUid,
|
---|
| 338 | "\" to \"", classUid, "\"", (char *)NULL);
|
---|
| 339 | return NULL;
|
---|
| 340 | }
|
---|
| 341 | penPtr->flags &= ~PEN_DELETE_PENDING;
|
---|
| 342 | } else {
|
---|
| 343 | if (classUid == bltBarElementUid) {
|
---|
| 344 | penPtr = Blt_BarPen(penName);
|
---|
| 345 | } else {
|
---|
| 346 | penPtr = Blt_LinePen(penName);
|
---|
| 347 | }
|
---|
| 348 | penPtr->classUid = classUid;
|
---|
| 349 | penPtr->hashPtr = hPtr;
|
---|
| 350 | Blt_SetHashValue(hPtr, penPtr);
|
---|
| 351 | }
|
---|
| 352 |
|
---|
| 353 | configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN));
|
---|
| 354 | if (Blt_ConfigureWidgetComponent(graphPtr->interp, graphPtr->tkwin,
|
---|
| 355 | penPtr->name, "Pen", penPtr->configSpecs, nOpts, options,
|
---|
| 356 | (char *)penPtr, configFlags) != TCL_OK) {
|
---|
| 357 | if (isNew) {
|
---|
| 358 | DestroyPen(graphPtr, penPtr);
|
---|
| 359 | }
|
---|
| 360 | return NULL;
|
---|
| 361 | }
|
---|
| 362 | (*penPtr->configProc) (graphPtr, penPtr);
|
---|
| 363 | return penPtr;
|
---|
| 364 | }
|
---|
| 365 |
|
---|
| 366 | int
|
---|
| 367 | Blt_GetPen(graphPtr, name, classUid, penPtrPtr)
|
---|
| 368 | Graph *graphPtr;
|
---|
| 369 | char *name;
|
---|
| 370 | Blt_Uid classUid;
|
---|
| 371 | Pen **penPtrPtr;
|
---|
| 372 | {
|
---|
| 373 | Pen *penPtr;
|
---|
| 374 |
|
---|
| 375 | penPtr = NameToPen(graphPtr, name);
|
---|
| 376 | if (penPtr == NULL) {
|
---|
| 377 | return TCL_ERROR;
|
---|
| 378 | }
|
---|
| 379 | if (classUid == bltStripElementUid) {
|
---|
| 380 | classUid = bltLineElementUid;
|
---|
| 381 | }
|
---|
| 382 | if (penPtr->classUid != classUid) {
|
---|
| 383 | Tcl_AppendResult(graphPtr->interp, "pen \"", name,
|
---|
| 384 | "\" is the wrong type (is \"", penPtr->classUid, "\"",
|
---|
| 385 | ", wanted \"", classUid, "\")", (char *)NULL);
|
---|
| 386 | return TCL_ERROR;
|
---|
| 387 | }
|
---|
| 388 | penPtr->refCount++;
|
---|
| 389 | *penPtrPtr = penPtr;
|
---|
| 390 | return TCL_OK;
|
---|
| 391 | }
|
---|
| 392 |
|
---|
| 393 | /*
|
---|
| 394 | *----------------------------------------------------------------------
|
---|
| 395 | *
|
---|
| 396 | * Blt_DestroyPens --
|
---|
| 397 | *
|
---|
| 398 | * Release memory and resources allocated for the style.
|
---|
| 399 | *
|
---|
| 400 | * Results:
|
---|
| 401 | * None.
|
---|
| 402 | *
|
---|
| 403 | * Side effects:
|
---|
| 404 | * Everything associated with the pen style is freed up.
|
---|
| 405 | *
|
---|
| 406 | *----------------------------------------------------------------------
|
---|
| 407 | */
|
---|
| 408 | void
|
---|
| 409 | Blt_DestroyPens(graphPtr)
|
---|
| 410 | Graph *graphPtr;
|
---|
| 411 | {
|
---|
| 412 | Blt_HashEntry *hPtr;
|
---|
| 413 | Blt_HashSearch cursor;
|
---|
| 414 | Pen *penPtr;
|
---|
| 415 |
|
---|
| 416 | for (hPtr = Blt_FirstHashEntry(&(graphPtr->penTable), &cursor);
|
---|
| 417 | hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
|
---|
| 418 | penPtr = (Pen *)Blt_GetHashValue(hPtr);
|
---|
| 419 | penPtr->hashPtr = NULL;
|
---|
| 420 | DestroyPen(graphPtr, penPtr);
|
---|
| 421 | }
|
---|
| 422 | Blt_DeleteHashTable(&(graphPtr->penTable));
|
---|
| 423 | }
|
---|
| 424 |
|
---|
| 425 | /*
|
---|
| 426 | * ----------------------------------------------------------------------
|
---|
| 427 | *
|
---|
| 428 | * CgetOp --
|
---|
| 429 | *
|
---|
| 430 | * Queries axis attributes (font, line width, label, etc).
|
---|
| 431 | *
|
---|
| 432 | * Results:
|
---|
| 433 | * A standard Tcl result. If querying configuration values,
|
---|
| 434 | * interp->result will contain the results.
|
---|
| 435 | *
|
---|
| 436 | * ----------------------------------------------------------------------
|
---|
| 437 | */
|
---|
| 438 | /* ARGSUSED */
|
---|
| 439 | static int
|
---|
| 440 | CgetOp(interp, graphPtr, argc, argv)
|
---|
| 441 | Tcl_Interp *interp;
|
---|
| 442 | Graph *graphPtr;
|
---|
| 443 | int argc; /* Not used. */
|
---|
| 444 | char *argv[];
|
---|
| 445 | {
|
---|
| 446 | Pen *penPtr;
|
---|
| 447 | unsigned int configFlags;
|
---|
| 448 |
|
---|
| 449 | penPtr = NameToPen(graphPtr, argv[3]);
|
---|
| 450 | if (penPtr == NULL) {
|
---|
| 451 | return TCL_ERROR;
|
---|
| 452 | }
|
---|
| 453 | configFlags = (penPtr->flags & (ACTIVE_PEN | NORMAL_PEN));
|
---|
| 454 | return Tk_ConfigureValue(interp, graphPtr->tkwin, penPtr->configSpecs,
|
---|
| 455 | (char *)penPtr, argv[4], configFlags);
|
---|
| 456 | }
|
---|
| 457 |
|
---|
| 458 | /*
|
---|
| 459 | * ----------------------------------------------------------------------
|
---|
| 460 | *
|
---|
| 461 | * ConfigureOp --
|
---|
| 462 | *
|
---|
| 463 | * Queries or resets pen attributes (font, line width, color, etc).
|
---|
| 464 | *
|
---|
| 465 | * Results:
|
---|
| 466 | * A standard Tcl result. If querying configuration values,
|
---|
| 467 | * interp->result will contain the results.
|
---|
| 468 | *
|
---|
| 469 | * Side Effects:
|
---|
| 470 | * Pen resources are possibly allocated (GC, font).
|
---|
| 471 | *
|
---|
| 472 | * ----------------------------------------------------------------------
|
---|
| 473 | */
|
---|
| 474 | static int
|
---|
| 475 | ConfigureOp(interp, graphPtr, argc, argv)
|
---|
| 476 | Tcl_Interp *interp;
|
---|
| 477 | Graph *graphPtr;
|
---|
| 478 | int argc;
|
---|
| 479 | char *argv[];
|
---|
| 480 | {
|
---|
| 481 | int flags;
|
---|
| 482 | Pen *penPtr;
|
---|
| 483 | int nNames, nOpts;
|
---|
| 484 | int redraw;
|
---|
| 485 | char **options;
|
---|
| 486 | register int i;
|
---|
| 487 |
|
---|
| 488 | /* Figure out where the option value pairs begin */
|
---|
| 489 | argc -= 3;
|
---|
| 490 | argv += 3;
|
---|
| 491 | for (i = 0; i < argc; i++) {
|
---|
| 492 | if (argv[i][0] == '-') {
|
---|
| 493 | break;
|
---|
| 494 | }
|
---|
| 495 | if (NameToPen(graphPtr, argv[i]) == NULL) {
|
---|
| 496 | return TCL_ERROR;
|
---|
| 497 | }
|
---|
| 498 | }
|
---|
| 499 | nNames = i; /* Number of pen names specified */
|
---|
| 500 | nOpts = argc - i; /* Number of options specified */
|
---|
| 501 | options = argv + i; /* Start of options in argv */
|
---|
| 502 |
|
---|
| 503 | redraw = 0;
|
---|
| 504 | for (i = 0; i < nNames; i++) {
|
---|
| 505 | penPtr = NameToPen(graphPtr, argv[i]);
|
---|
| 506 | flags = TK_CONFIG_ARGV_ONLY | (penPtr->flags & (ACTIVE_PEN|NORMAL_PEN));
|
---|
| 507 | if (nOpts == 0) {
|
---|
| 508 | return Tk_ConfigureInfo(interp, graphPtr->tkwin,
|
---|
| 509 | penPtr->configSpecs, (char *)penPtr, (char *)NULL, flags);
|
---|
| 510 | } else if (nOpts == 1) {
|
---|
| 511 | return Tk_ConfigureInfo(interp, graphPtr->tkwin,
|
---|
| 512 | penPtr->configSpecs, (char *)penPtr, options[0], flags);
|
---|
| 513 | }
|
---|
| 514 | if (Tk_ConfigureWidget(interp, graphPtr->tkwin, penPtr->configSpecs,
|
---|
| 515 | nOpts, options, (char *)penPtr, flags) != TCL_OK) {
|
---|
| 516 | break;
|
---|
| 517 | }
|
---|
| 518 | (*penPtr->configProc) (graphPtr, penPtr);
|
---|
| 519 | if (penPtr->refCount > 0) {
|
---|
| 520 | redraw++;
|
---|
| 521 | }
|
---|
| 522 | }
|
---|
| 523 | if (redraw) {
|
---|
| 524 | graphPtr->flags |= REDRAW_BACKING_STORE | DRAW_MARGINS;
|
---|
| 525 | Blt_EventuallyRedrawGraph(graphPtr);
|
---|
| 526 | }
|
---|
| 527 | if (i < nNames) {
|
---|
| 528 | return TCL_ERROR;
|
---|
| 529 | }
|
---|
| 530 | return TCL_OK;
|
---|
| 531 | }
|
---|
| 532 |
|
---|
| 533 | /*
|
---|
| 534 | *----------------------------------------------------------------------
|
---|
| 535 | *
|
---|
| 536 | * CreateOp --
|
---|
| 537 | *
|
---|
| 538 | * Adds a new penstyle to the graph.
|
---|
| 539 | *
|
---|
| 540 | * Results:
|
---|
| 541 | * A standard Tcl result.
|
---|
| 542 | *
|
---|
| 543 | *----------------------------------------------------------------------
|
---|
| 544 | */
|
---|
| 545 | static int
|
---|
| 546 | CreateOp(interp, graphPtr, argc, argv)
|
---|
| 547 | Tcl_Interp *interp;
|
---|
| 548 | Graph *graphPtr;
|
---|
| 549 | int argc;
|
---|
| 550 | char **argv;
|
---|
| 551 | {
|
---|
| 552 | Pen *penPtr;
|
---|
| 553 |
|
---|
| 554 | penPtr = Blt_CreatePen(graphPtr, argv[3], graphPtr->classUid, argc - 4,
|
---|
| 555 | argv + 4);
|
---|
| 556 | if (penPtr == NULL) {
|
---|
| 557 | return TCL_ERROR;
|
---|
| 558 | }
|
---|
| 559 | Tcl_SetResult(interp, penPtr->name, TCL_VOLATILE);
|
---|
| 560 | return TCL_OK;
|
---|
| 561 | }
|
---|
| 562 |
|
---|
| 563 | /*
|
---|
| 564 | *--------------------------------------------------------------
|
---|
| 565 | *
|
---|
| 566 | * DeleteOp --
|
---|
| 567 | *
|
---|
| 568 | * Delete the given pen.
|
---|
| 569 | *
|
---|
| 570 | * Results:
|
---|
| 571 | * Always returns TCL_OK. The interp->result field is
|
---|
| 572 | * a list of the graph axis limits.
|
---|
| 573 | *
|
---|
| 574 | *--------------------------------------------------------------
|
---|
| 575 | */
|
---|
| 576 |
|
---|
| 577 | /*ARGSUSED*/
|
---|
| 578 | static int
|
---|
| 579 | DeleteOp(interp, graphPtr, argc, argv)
|
---|
| 580 | Tcl_Interp *interp;
|
---|
| 581 | Graph *graphPtr;
|
---|
| 582 | int argc;
|
---|
| 583 | char **argv;
|
---|
| 584 | {
|
---|
| 585 | Pen *penPtr;
|
---|
| 586 | int i;
|
---|
| 587 |
|
---|
| 588 | for (i = 3; i < argc; i++) {
|
---|
| 589 | penPtr = NameToPen(graphPtr, argv[i]);
|
---|
| 590 | if (penPtr == NULL) {
|
---|
| 591 | return TCL_ERROR;
|
---|
| 592 | }
|
---|
| 593 | if (penPtr->flags & PEN_DELETE_PENDING) {
|
---|
| 594 | Tcl_AppendResult(graphPtr->interp, "can't find pen \"", argv[i],
|
---|
| 595 | "\" in \"", Tk_PathName(graphPtr->tkwin), "\"", (char *)NULL);
|
---|
| 596 | return TCL_ERROR;
|
---|
| 597 | }
|
---|
| 598 | penPtr->flags |= PEN_DELETE_PENDING;
|
---|
| 599 | if (penPtr->refCount == 0) {
|
---|
| 600 | DestroyPen(graphPtr, penPtr);
|
---|
| 601 | }
|
---|
| 602 | }
|
---|
| 603 | return TCL_OK;
|
---|
| 604 | }
|
---|
| 605 |
|
---|
| 606 | /*
|
---|
| 607 | * ----------------------------------------------------------------------
|
---|
| 608 | *
|
---|
| 609 | * NamesOp --
|
---|
| 610 | *
|
---|
| 611 | * Return a list of the names of all the axes.
|
---|
| 612 | *
|
---|
| 613 | * Results:
|
---|
| 614 | * Returns a standard Tcl result.
|
---|
| 615 | *
|
---|
| 616 | * ----------------------------------------------------------------------
|
---|
| 617 | */
|
---|
| 618 | /*ARGSUSED*/
|
---|
| 619 | static int
|
---|
| 620 | NamesOp(interp, graphPtr, argc, argv)
|
---|
| 621 | Tcl_Interp *interp;
|
---|
| 622 | Graph *graphPtr;
|
---|
| 623 | int argc;
|
---|
| 624 | char **argv;
|
---|
| 625 | {
|
---|
| 626 | Blt_HashSearch cursor;
|
---|
| 627 | Pen *penPtr;
|
---|
| 628 | register int i;
|
---|
| 629 | register Blt_HashEntry *hPtr;
|
---|
| 630 |
|
---|
| 631 | for (hPtr = Blt_FirstHashEntry(&(graphPtr->penTable), &cursor);
|
---|
| 632 | hPtr != NULL; hPtr = Blt_NextHashEntry(&cursor)) {
|
---|
| 633 | penPtr = (Pen *)Blt_GetHashValue(hPtr);
|
---|
| 634 | if (penPtr->flags & PEN_DELETE_PENDING) {
|
---|
| 635 | continue;
|
---|
| 636 | }
|
---|
| 637 | if (argc == 3) {
|
---|
| 638 | Tcl_AppendElement(interp, penPtr->name);
|
---|
| 639 | continue;
|
---|
| 640 | }
|
---|
| 641 | for (i = 3; i < argc; i++) {
|
---|
| 642 | if (Tcl_StringMatch(penPtr->name, argv[i])) {
|
---|
| 643 | Tcl_AppendElement(interp, penPtr->name);
|
---|
| 644 | break;
|
---|
| 645 | }
|
---|
| 646 | }
|
---|
| 647 | }
|
---|
| 648 | return TCL_OK;
|
---|
| 649 | }
|
---|
| 650 |
|
---|
| 651 | /*
|
---|
| 652 | * ----------------------------------------------------------------------
|
---|
| 653 | *
|
---|
| 654 | * TypeOp --
|
---|
| 655 | *
|
---|
| 656 | * Return the type of pen.
|
---|
| 657 | *
|
---|
| 658 | * Results:
|
---|
| 659 | * Returns a standard Tcl result.
|
---|
| 660 | *
|
---|
| 661 | * ----------------------------------------------------------------------
|
---|
| 662 | */
|
---|
| 663 | /*ARGSUSED*/
|
---|
| 664 | static int
|
---|
| 665 | TypeOp(interp, graphPtr, argc, argv)
|
---|
| 666 | Tcl_Interp *interp;
|
---|
| 667 | Graph *graphPtr;
|
---|
| 668 | int argc;
|
---|
| 669 | char **argv;
|
---|
| 670 | {
|
---|
| 671 | Pen *penPtr;
|
---|
| 672 |
|
---|
| 673 | penPtr = NameToPen(graphPtr, argv[3]);
|
---|
| 674 | if (penPtr == NULL) {
|
---|
| 675 | return TCL_ERROR;
|
---|
| 676 | }
|
---|
| 677 | Tcl_SetResult(interp, penPtr->classUid, TCL_STATIC);
|
---|
| 678 | return TCL_OK;
|
---|
| 679 | }
|
---|
| 680 |
|
---|
| 681 | static Blt_OpSpec penOps[] =
|
---|
| 682 | {
|
---|
| 683 | {"cget", 2, (Blt_Op)CgetOp, 5, 5, "penName option",},
|
---|
| 684 | {"configure", 2, (Blt_Op)ConfigureOp, 4, 0,
|
---|
| 685 | "penName ?penName?... ?option value?...",},
|
---|
| 686 | {"create", 2, (Blt_Op)CreateOp, 4, 0, "penName ?option value?...",},
|
---|
| 687 | {"delete", 2, (Blt_Op)DeleteOp, 3, 0, "?penName?...",},
|
---|
| 688 | {"names", 1, (Blt_Op)NamesOp, 3, 0, "?pattern?...",},
|
---|
| 689 | {"type", 1, (Blt_Op)TypeOp, 4, 4, "penName",},
|
---|
| 690 | };
|
---|
| 691 | static int nPenOps = sizeof(penOps) / sizeof(Blt_OpSpec);
|
---|
| 692 |
|
---|
| 693 | int
|
---|
| 694 | Blt_PenOp(graphPtr, interp, argc, argv)
|
---|
| 695 | Graph *graphPtr;
|
---|
| 696 | Tcl_Interp *interp;
|
---|
| 697 | int argc;
|
---|
| 698 | char **argv;
|
---|
| 699 | {
|
---|
| 700 | Blt_Op proc;
|
---|
| 701 |
|
---|
| 702 | proc = Blt_GetOp(interp, nPenOps, penOps, BLT_OP_ARG2, argc, argv, 0);
|
---|
| 703 | if (proc == NULL) {
|
---|
| 704 | return TCL_ERROR;
|
---|
| 705 | }
|
---|
| 706 | return (*proc) (interp, graphPtr, argc, argv);
|
---|
| 707 | }
|
---|