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 | }
|
---|