/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkutil.c
ViewVC logotype

Contents of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkutil.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 71 - (show annotations) (download)
Sat Nov 5 11:07:06 2016 UTC (7 years, 11 months ago) by dashley
File MIME type: text/plain
File size: 28526 byte(s)
Set EOL properties appropriately to facilitate simultaneous Linux and Windows development.
1 /* $Header$ */
2
3 /*
4 * tkUtil.c --
5 *
6 * This file contains miscellaneous utility procedures that
7 * are used by the rest of Tk, such as a procedure for drawing
8 * a focus highlight.
9 *
10 * Copyright (c) 1994 The Regents of the University of California.
11 * Copyright (c) 1994-1997 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: tkutil.c,v 1.1.1.1 2001/06/13 05:11:37 dtashley Exp $
17 */
18
19 #include "tkInt.h"
20 #include "tkPort.h"
21
22 /*
23 * The structure below defines the implementation of the "statekey"
24 * Tcl object, used for quickly finding a mapping in a TkStateMap.
25 */
26
27 static Tcl_ObjType stateKeyType = {
28 "statekey", /* name */
29 (Tcl_FreeInternalRepProc *) NULL, /* freeIntRepProc */
30 (Tcl_DupInternalRepProc *) NULL, /* dupIntRepProc */
31 (Tcl_UpdateStringProc *) NULL, /* updateStringProc */
32 (Tcl_SetFromAnyProc *) NULL /* setFromAnyProc */
33 };
34
35
36 /*
37 *--------------------------------------------------------------
38 *
39 * TkStateParseProc --
40 *
41 * This procedure is invoked during option processing to handle
42 * the "-state" and "-default" options.
43 *
44 * Results:
45 * A standard Tcl return value.
46 *
47 * Side effects:
48 * The state for a given item gets replaced by the state
49 * indicated in the value argument.
50 *
51 *--------------------------------------------------------------
52 */
53
54 int
55 TkStateParseProc(clientData, interp, tkwin, value, widgRec, offset)
56 ClientData clientData; /* some flags.*/
57 Tcl_Interp *interp; /* Used for reporting errors. */
58 Tk_Window tkwin; /* Window containing canvas widget. */
59 CONST char *value; /* Value of option. */
60 char *widgRec; /* Pointer to record for item. */
61 int offset; /* Offset into item. */
62 {
63 int c;
64 int flags = (int)clientData;
65 size_t length;
66
67 register Tk_State *statePtr = (Tk_State *) (widgRec + offset);
68
69 if(value == NULL || *value == 0) {
70 *statePtr = TK_STATE_NULL;
71 return TCL_OK;
72 }
73
74 c = value[0];
75 length = strlen(value);
76
77 if ((c == 'n') && (strncmp(value, "normal", length) == 0)) {
78 *statePtr = TK_STATE_NORMAL;
79 return TCL_OK;
80 }
81 if ((c == 'd') && (strncmp(value, "disabled", length) == 0)) {
82 *statePtr = TK_STATE_DISABLED;
83 return TCL_OK;
84 }
85 if ((c == 'a') && (flags&1) && (strncmp(value, "active", length) == 0)) {
86 *statePtr = TK_STATE_ACTIVE;
87 return TCL_OK;
88 }
89 if ((c == 'h') && (flags&2) && (strncmp(value, "hidden", length) == 0)) {
90 *statePtr = TK_STATE_HIDDEN;
91 return TCL_OK;
92 }
93
94 Tcl_AppendResult(interp, "bad ", (flags&4)?"-default" : "state",
95 " value \"", value, "\": must be normal",
96 (char *) NULL);
97 if (flags&1) {
98 Tcl_AppendResult(interp, ", active",(char *) NULL);
99 }
100 if (flags&2) {
101 Tcl_AppendResult(interp, ", hidden",(char *) NULL);
102 }
103 if (flags&3) {
104 Tcl_AppendResult(interp, ",",(char *) NULL);
105 }
106 Tcl_AppendResult(interp, " or disabled",(char *) NULL);
107 *statePtr = TK_STATE_NORMAL;
108 return TCL_ERROR;
109 }
110
111 /*
112 *--------------------------------------------------------------
113 *
114 * TkStatePrintProc --
115 *
116 * This procedure is invoked by the Tk configuration code
117 * to produce a printable string for the "-state"
118 * configuration option.
119 *
120 * Results:
121 * The return value is a string describing the state for
122 * the item referred to by "widgRec". In addition, *freeProcPtr
123 * is filled in with the address of a procedure to call to free
124 * the result string when it's no longer needed (or NULL to
125 * indicate that the string doesn't need to be freed).
126 *
127 * Side effects:
128 * None.
129 *
130 *--------------------------------------------------------------
131 */
132
133 char *
134 TkStatePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
135 ClientData clientData; /* Ignored. */
136 Tk_Window tkwin; /* Window containing canvas widget. */
137 char *widgRec; /* Pointer to record for item. */
138 int offset; /* Offset into item. */
139 Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
140 * information about how to reclaim
141 * storage for return string. */
142 {
143 register Tk_State *statePtr = (Tk_State *) (widgRec + offset);
144
145 if (*statePtr==TK_STATE_NORMAL) {
146 return "normal";
147 } else if (*statePtr==TK_STATE_DISABLED) {
148 return "disabled";
149 } else if (*statePtr==TK_STATE_HIDDEN) {
150 return "hidden";
151 } else if (*statePtr==TK_STATE_ACTIVE) {
152 return "active";
153 } else {
154 return "";
155 }
156 }
157
158 /*
159 *--------------------------------------------------------------
160 *
161 * TkOrientParseProc --
162 *
163 * This procedure is invoked during option processing to handle
164 * the "-orient" option.
165 *
166 * Results:
167 * A standard Tcl return value.
168 *
169 * Side effects:
170 * The orientation for a given item gets replaced by the orientation
171 * indicated in the value argument.
172 *
173 *--------------------------------------------------------------
174 */
175
176 int
177 TkOrientParseProc(clientData, interp, tkwin, value, widgRec, offset)
178 ClientData clientData; /* some flags.*/
179 Tcl_Interp *interp; /* Used for reporting errors. */
180 Tk_Window tkwin; /* Window containing canvas widget. */
181 CONST char *value; /* Value of option. */
182 char *widgRec; /* Pointer to record for item. */
183 int offset; /* Offset into item. */
184 {
185 int c;
186 size_t length;
187
188 register int *orientPtr = (int *) (widgRec + offset);
189
190 if(value == NULL || *value == 0) {
191 *orientPtr = 0;
192 return TCL_OK;
193 }
194
195 c = value[0];
196 length = strlen(value);
197
198 if ((c == 'h') && (strncmp(value, "horizontal", length) == 0)) {
199 *orientPtr = 0;
200 return TCL_OK;
201 }
202 if ((c == 'v') && (strncmp(value, "vertical", length) == 0)) {
203 *orientPtr = 1;
204 return TCL_OK;
205 }
206 Tcl_AppendResult(interp, "bad orientation \"", value,
207 "\": must be vertical or horizontal",
208 (char *) NULL);
209 *orientPtr = 0;
210 return TCL_ERROR;
211 }
212
213 /*
214 *--------------------------------------------------------------
215 *
216 * TkOrientPrintProc --
217 *
218 * This procedure is invoked by the Tk configuration code
219 * to produce a printable string for the "-orient"
220 * configuration option.
221 *
222 * Results:
223 * The return value is a string describing the orientation for
224 * the item referred to by "widgRec". In addition, *freeProcPtr
225 * is filled in with the address of a procedure to call to free
226 * the result string when it's no longer needed (or NULL to
227 * indicate that the string doesn't need to be freed).
228 *
229 * Side effects:
230 * None.
231 *
232 *--------------------------------------------------------------
233 */
234
235 char *
236 TkOrientPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
237 ClientData clientData; /* Ignored. */
238 Tk_Window tkwin; /* Window containing canvas widget. */
239 char *widgRec; /* Pointer to record for item. */
240 int offset; /* Offset into item. */
241 Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
242 * information about how to reclaim
243 * storage for return string. */
244 {
245 register int *statePtr = (int *) (widgRec + offset);
246
247 if (*statePtr) {
248 return "vertical";
249 } else {
250 return "horizontal";
251 }
252 }
253
254 /*
255 *----------------------------------------------------------------------
256 *
257 * TkOffsetParseProc --
258 *
259 * Converts the offset of a stipple or tile into the Tk_TSOffset structure.
260 *
261 *----------------------------------------------------------------------
262 */
263
264 int
265 TkOffsetParseProc(clientData, interp, tkwin, value, widgRec, offset)
266 ClientData clientData; /* not used */
267 Tcl_Interp *interp; /* Interpreter to send results back to */
268 Tk_Window tkwin; /* Window on same display as tile */
269 CONST char *value; /* Name of image */
270 char *widgRec; /* Widget structure record */
271 int offset; /* Offset of tile in record */
272 {
273 Tk_TSOffset *offsetPtr = (Tk_TSOffset *)(widgRec + offset);
274 Tk_TSOffset tsoffset;
275 CONST char *q, *p;
276 int result;
277
278 if ((value == NULL) || (*value == 0)) {
279 tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
280 goto goodTSOffset;
281 }
282 tsoffset.flags = 0;
283 p = value;
284
285 switch(value[0]) {
286 case '#':
287 if (((int)clientData) & TK_OFFSET_RELATIVE) {
288 tsoffset.flags = TK_OFFSET_RELATIVE;
289 p++; break;
290 }
291 goto badTSOffset;
292 case 'e':
293 switch(value[1]) {
294 case '\0':
295 tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_MIDDLE;
296 goto goodTSOffset;
297 case 'n':
298 if (value[2]!='d' || value[3]!='\0') {goto badTSOffset;}
299 tsoffset.flags = INT_MAX;
300 goto goodTSOffset;
301 }
302 case 'w':
303 if (value[1] != '\0') {goto badTSOffset;}
304 tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_MIDDLE;
305 goto goodTSOffset;
306 case 'n':
307 if ((value[1] != '\0') && (value[2] != '\0')) {
308 goto badTSOffset;
309 }
310 switch(value[1]) {
311 case '\0': tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_TOP;
312 goto goodTSOffset;
313 case 'w': tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_TOP;
314 goto goodTSOffset;
315 case 'e': tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_TOP;
316 goto goodTSOffset;
317 }
318 goto badTSOffset;
319 case 's':
320 if ((value[1] != '\0') && (value[2] != '\0')) {
321 goto badTSOffset;
322 }
323 switch(value[1]) {
324 case '\0': tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_BOTTOM;
325 goto goodTSOffset;
326 case 'w': tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_BOTTOM;
327 goto goodTSOffset;
328 case 'e': tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_BOTTOM;
329 goto goodTSOffset;
330 }
331 goto badTSOffset;
332 case 'c':
333 if (strncmp(value, "center", strlen(value)) != 0) {
334 goto badTSOffset;
335 }
336 tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE;
337 goto goodTSOffset;
338 }
339 if ((q = strchr(p,',')) == NULL) {
340 if (((int)clientData) & TK_OFFSET_INDEX) {
341 if (Tcl_GetInt(interp, (char *) p, &tsoffset.flags) != TCL_OK) {
342 Tcl_ResetResult(interp);
343 goto badTSOffset;
344 }
345 tsoffset.flags |= TK_OFFSET_INDEX;
346 goto goodTSOffset;
347 }
348 goto badTSOffset;
349 }
350 *((char *) q) = 0;
351 result = Tk_GetPixels(interp, tkwin, (char *) p, &tsoffset.xoffset);
352 *((char *) q) = ',';
353 if (result != TCL_OK) {
354 return TCL_ERROR;
355 }
356 if (Tk_GetPixels(interp, tkwin, (char *) q+1, &tsoffset.yoffset) != TCL_OK) {
357 return TCL_ERROR;
358 }
359
360
361 goodTSOffset:
362 /* below is a hack to allow the stipple/tile offset to be stored
363 * in the internal tile structure. Most of the times, offsetPtr
364 * is a pointer to an already existing tile structure. However
365 * if this structure is not already created, we must do it
366 * with Tk_GetTile()!!!!;
367 */
368
369 memcpy(offsetPtr,&tsoffset, sizeof(Tk_TSOffset));
370 return TCL_OK;
371
372 badTSOffset:
373 Tcl_AppendResult(interp, "bad offset \"", value,
374 "\": expected \"x,y\"", (char *) NULL);
375 if (((int) clientData) & TK_OFFSET_RELATIVE) {
376 Tcl_AppendResult(interp, ", \"#x,y\"", (char *) NULL);
377 }
378 if (((int) clientData) & TK_OFFSET_INDEX) {
379 Tcl_AppendResult(interp, ", <index>", (char *) NULL);
380 }
381 Tcl_AppendResult(interp, ", n, ne, e, se, s, sw, w, nw, or center",
382 (char *) NULL);
383 return TCL_ERROR;
384 }
385
386 /*
387 *----------------------------------------------------------------------
388 *
389 * TkOffsetPrintProc --
390 *
391 * Returns the offset of the tile.
392 *
393 * Results:
394 * The offset of the tile is returned.
395 *
396 *----------------------------------------------------------------------
397 */
398
399 char *
400 TkOffsetPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
401 ClientData clientData; /* not used */
402 Tk_Window tkwin; /* not used */
403 char *widgRec; /* Widget structure record */
404 int offset; /* Offset of tile in record */
405 Tcl_FreeProc **freeProcPtr; /* not used */
406 {
407 Tk_TSOffset *offsetPtr = (Tk_TSOffset *)(widgRec + offset);
408 char *p, *q;
409
410 if ((offsetPtr->flags) & TK_OFFSET_INDEX) {
411 if ((offsetPtr->flags) >= INT_MAX) {
412 return "end";
413 }
414 p = (char *) ckalloc(32);
415 sprintf(p, "%d",(offsetPtr->flags & (~TK_OFFSET_INDEX)));
416 *freeProcPtr = TCL_DYNAMIC;
417 return p;
418 }
419 if ((offsetPtr->flags) & TK_OFFSET_TOP) {
420 if ((offsetPtr->flags) & TK_OFFSET_LEFT) {
421 return "nw";
422 } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) {
423 return "n";
424 } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) {
425 return "ne";
426 }
427 } else if ((offsetPtr->flags) & TK_OFFSET_MIDDLE) {
428 if ((offsetPtr->flags) & TK_OFFSET_LEFT) {
429 return "w";
430 } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) {
431 return "center";
432 } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) {
433 return "e";
434 }
435 } else if ((offsetPtr->flags) & TK_OFFSET_BOTTOM) {
436 if ((offsetPtr->flags) & TK_OFFSET_LEFT) {
437 return "sw";
438 } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) {
439 return "s";
440 } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) {
441 return "se";
442 }
443 }
444 q = p = (char *) ckalloc(32);
445 if ((offsetPtr->flags) & TK_OFFSET_RELATIVE) {
446 *q++ = '#';
447 }
448 sprintf(q, "%d,%d",offsetPtr->xoffset, offsetPtr->yoffset);
449 *freeProcPtr = TCL_DYNAMIC;
450 return p;
451 }
452
453
454 /*
455 *----------------------------------------------------------------------
456 *
457 * TkPixelParseProc --
458 *
459 * Converts the name of an image into a tile.
460 *
461 *----------------------------------------------------------------------
462 */
463
464 int
465 TkPixelParseProc(clientData, interp, tkwin, value, widgRec, offset)
466 ClientData clientData; /* if non-NULL, negative values are
467 * allowed as well */
468 Tcl_Interp *interp; /* Interpreter to send results back to */
469 Tk_Window tkwin; /* Window on same display as tile */
470 CONST char *value; /* Name of image */
471 char *widgRec; /* Widget structure record */
472 int offset; /* Offset of tile in record */
473 {
474 double *doublePtr = (double *)(widgRec + offset);
475 int result;
476
477 result = TkGetDoublePixels(interp, tkwin, value, doublePtr);
478
479 if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) {
480 Tcl_AppendResult(interp, "bad screen distance \"", value,
481 "\"", (char *) NULL);
482 return TCL_ERROR;
483 }
484 return result;
485 }
486
487 /*
488 *----------------------------------------------------------------------
489 *
490 * TkPixelPrintProc --
491 *
492 * Returns the name of the tile.
493 *
494 * Results:
495 * The name of the tile is returned.
496 *
497 *----------------------------------------------------------------------
498 */
499
500 char *
501 TkPixelPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
502 ClientData clientData; /* not used */
503 Tk_Window tkwin; /* not used */
504 char *widgRec; /* Widget structure record */
505 int offset; /* Offset of tile in record */
506 Tcl_FreeProc **freeProcPtr; /* not used */
507 {
508 double *doublePtr = (double *)(widgRec + offset);
509 char *p;
510
511 p = (char *) ckalloc(24);
512 Tcl_PrintDouble((Tcl_Interp *) NULL, *doublePtr, p);
513 *freeProcPtr = TCL_DYNAMIC;
514 return p;
515 }
516
517 /*
518 *----------------------------------------------------------------------
519 *
520 * TkDrawInsetFocusHighlight --
521 *
522 * This procedure draws a rectangular ring around the outside of
523 * a widget to indicate that it has received the input focus. It
524 * takes an additional padding argument that specifies how much
525 * padding is present outside th widget.
526 *
527 * Results:
528 * None.
529 *
530 * Side effects:
531 * A rectangle "width" pixels wide is drawn in "drawable",
532 * corresponding to the outer area of "tkwin".
533 *
534 *----------------------------------------------------------------------
535 */
536
537 void
538 TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, padding)
539 Tk_Window tkwin; /* Window whose focus highlight ring is
540 * to be drawn. */
541 GC gc; /* Graphics context to use for drawing
542 * the highlight ring. */
543 int width; /* Width of the highlight ring, in pixels. */
544 Drawable drawable; /* Where to draw the ring (typically a
545 * pixmap for double buffering). */
546 int padding; /* Width of padding outside of widget. */
547 {
548 XRectangle rects[4];
549
550 rects[0].x = padding;
551 rects[0].y = padding;
552 rects[0].width = Tk_Width(tkwin) - (2 * padding);
553 rects[0].height = width;
554 rects[1].x = padding;
555 rects[1].y = Tk_Height(tkwin) - width - padding;
556 rects[1].width = Tk_Width(tkwin) - (2 * padding);
557 rects[1].height = width;
558 rects[2].x = padding;
559 rects[2].y = width + padding;
560 rects[2].width = width;
561 rects[2].height = Tk_Height(tkwin) - 2*width - 2*padding;
562 rects[3].x = Tk_Width(tkwin) - width - padding;
563 rects[3].y = rects[2].y;
564 rects[3].width = width;
565 rects[3].height = rects[2].height;
566 XFillRectangles(Tk_Display(tkwin), drawable, gc, rects, 4);
567 }
568
569 /*
570 *----------------------------------------------------------------------
571 *
572 * Tk_DrawFocusHighlight --
573 *
574 * This procedure draws a rectangular ring around the outside of
575 * a widget to indicate that it has received the input focus.
576 *
577 * This function is now deprecated. Use TkpDrawHighlightBorder instead,
578 * since this function does not handle drawing the Focus ring properly
579 * on the Macintosh - you need to know the background GC as well
580 * as the foreground since the Mac focus ring separated from the widget
581 * by a 1 pixel border.
582 *
583 * Results:
584 * None.
585 *
586 * Side effects:
587 * A rectangle "width" pixels wide is drawn in "drawable",
588 * corresponding to the outer area of "tkwin".
589 *
590 *----------------------------------------------------------------------
591 */
592
593 void
594 Tk_DrawFocusHighlight(tkwin, gc, width, drawable)
595 Tk_Window tkwin; /* Window whose focus highlight ring is
596 * to be drawn. */
597 GC gc; /* Graphics context to use for drawing
598 * the highlight ring. */
599 int width; /* Width of the highlight ring, in pixels. */
600 Drawable drawable; /* Where to draw the ring (typically a
601 * pixmap for double buffering). */
602 {
603 TkDrawInsetFocusHighlight(tkwin, gc, width, drawable, 0);
604 }
605
606 /*
607 *----------------------------------------------------------------------
608 *
609 * Tk_GetScrollInfo --
610 *
611 * This procedure is invoked to parse "xview" and "yview"
612 * scrolling commands for widgets using the new scrolling
613 * command syntax ("moveto" or "scroll" options).
614 *
615 * Results:
616 * The return value is either TK_SCROLL_MOVETO, TK_SCROLL_PAGES,
617 * TK_SCROLL_UNITS, or TK_SCROLL_ERROR. This indicates whether
618 * the command was successfully parsed and what form the command
619 * took. If TK_SCROLL_MOVETO, *dblPtr is filled in with the
620 * desired position; if TK_SCROLL_PAGES or TK_SCROLL_UNITS,
621 * *intPtr is filled in with the number of lines to move (may be
622 * negative); if TK_SCROLL_ERROR, the interp's result contains an
623 * error message.
624 *
625 * Side effects:
626 * None.
627 *
628 *----------------------------------------------------------------------
629 */
630
631 int
632 Tk_GetScrollInfo(interp, argc, argv, dblPtr, intPtr)
633 Tcl_Interp *interp; /* Used for error reporting. */
634 int argc; /* # arguments for command. */
635 char **argv; /* Arguments for command. */
636 double *dblPtr; /* Filled in with argument "moveto"
637 * option, if any. */
638 int *intPtr; /* Filled in with number of pages
639 * or lines to scroll, if any. */
640 {
641 int c;
642 size_t length;
643
644 length = strlen(argv[2]);
645 c = argv[2][0];
646 if ((c == 'm') && (strncmp(argv[2], "moveto", length) == 0)) {
647 if (argc != 4) {
648 Tcl_AppendResult(interp, "wrong # args: should be \"",
649 argv[0], " ", argv[1], " moveto fraction\"",
650 (char *) NULL);
651 return TK_SCROLL_ERROR;
652 }
653 if (Tcl_GetDouble(interp, argv[3], dblPtr) != TCL_OK) {
654 return TK_SCROLL_ERROR;
655 }
656 return TK_SCROLL_MOVETO;
657 } else if ((c == 's')
658 && (strncmp(argv[2], "scroll", length) == 0)) {
659 if (argc != 5) {
660 Tcl_AppendResult(interp, "wrong # args: should be \"",
661 argv[0], " ", argv[1], " scroll number units|pages\"",
662 (char *) NULL);
663 return TK_SCROLL_ERROR;
664 }
665 if (Tcl_GetInt(interp, argv[3], intPtr) != TCL_OK) {
666 return TK_SCROLL_ERROR;
667 }
668 length = strlen(argv[4]);
669 c = argv[4][0];
670 if ((c == 'p') && (strncmp(argv[4], "pages", length) == 0)) {
671 return TK_SCROLL_PAGES;
672 } else if ((c == 'u')
673 && (strncmp(argv[4], "units", length) == 0)) {
674 return TK_SCROLL_UNITS;
675 } else {
676 Tcl_AppendResult(interp, "bad argument \"", argv[4],
677 "\": must be units or pages", (char *) NULL);
678 return TK_SCROLL_ERROR;
679 }
680 }
681 Tcl_AppendResult(interp, "unknown option \"", argv[2],
682 "\": must be moveto or scroll", (char *) NULL);
683 return TK_SCROLL_ERROR;
684 }
685
686 /*
687 *----------------------------------------------------------------------
688 *
689 * Tk_GetScrollInfoObj --
690 *
691 * This procedure is invoked to parse "xview" and "yview"
692 * scrolling commands for widgets using the new scrolling
693 * command syntax ("moveto" or "scroll" options).
694 *
695 * Results:
696 * The return value is either TK_SCROLL_MOVETO, TK_SCROLL_PAGES,
697 * TK_SCROLL_UNITS, or TK_SCROLL_ERROR. This indicates whether
698 * the command was successfully parsed and what form the command
699 * took. If TK_SCROLL_MOVETO, *dblPtr is filled in with the
700 * desired position; if TK_SCROLL_PAGES or TK_SCROLL_UNITS,
701 * *intPtr is filled in with the number of lines to move (may be
702 * negative); if TK_SCROLL_ERROR, the interp's result contains an
703 * error message.
704 *
705 * Side effects:
706 * None.
707 *
708 *----------------------------------------------------------------------
709 */
710
711 int
712 Tk_GetScrollInfoObj(interp, objc, objv, dblPtr, intPtr)
713 Tcl_Interp *interp; /* Used for error reporting. */
714 int objc; /* # arguments for command. */
715 Tcl_Obj *CONST objv[]; /* Arguments for command. */
716 double *dblPtr; /* Filled in with argument "moveto"
717 * option, if any. */
718 int *intPtr; /* Filled in with number of pages
719 * or lines to scroll, if any. */
720 {
721 int c;
722 size_t length;
723 char *arg2, *arg4;
724
725 arg2 = Tcl_GetString(objv[2]);
726 length = strlen(arg2);
727 c = arg2[0];
728 if ((c == 'm') && (strncmp(arg2, "moveto", length) == 0)) {
729 if (objc != 4) {
730 Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
731 return TK_SCROLL_ERROR;
732 }
733 if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
734 return TK_SCROLL_ERROR;
735 }
736 return TK_SCROLL_MOVETO;
737 } else if ((c == 's')
738 && (strncmp(arg2, "scroll", length) == 0)) {
739 if (objc != 5) {
740 Tcl_WrongNumArgs(interp, 2, objv, "scroll number units|pages");
741 return TK_SCROLL_ERROR;
742 }
743 if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) {
744 return TK_SCROLL_ERROR;
745 }
746 arg4 = Tcl_GetString(objv[4]);
747 length = (strlen(arg4));
748 c = arg4[0];
749 if ((c == 'p') && (strncmp(arg4, "pages", length) == 0)) {
750 return TK_SCROLL_PAGES;
751 } else if ((c == 'u')
752 && (strncmp(arg4, "units", length) == 0)) {
753 return TK_SCROLL_UNITS;
754 } else {
755 Tcl_AppendResult(interp, "bad argument \"", arg4,
756 "\": must be units or pages", (char *) NULL);
757 return TK_SCROLL_ERROR;
758 }
759 }
760 Tcl_AppendResult(interp, "unknown option \"", arg2,
761 "\": must be moveto or scroll", (char *) NULL);
762 return TK_SCROLL_ERROR;
763 }
764
765 /*
766 *---------------------------------------------------------------------------
767 *
768 * TkComputeAnchor --
769 *
770 * Determine where to place a rectangle so that it will be properly
771 * anchored with respect to the given window. Used by widgets
772 * to align a box of text inside a window. When anchoring with
773 * respect to one of the sides, the rectangle be placed inside of
774 * the internal border of the window.
775 *
776 * Results:
777 * *xPtr and *yPtr set to the upper-left corner of the rectangle
778 * anchored in the window.
779 *
780 * Side effects:
781 * None.
782 *
783 *---------------------------------------------------------------------------
784 */
785 void
786 TkComputeAnchor(anchor, tkwin, padX, padY, innerWidth, innerHeight, xPtr, yPtr)
787 Tk_Anchor anchor; /* Desired anchor. */
788 Tk_Window tkwin; /* Anchored with respect to this window. */
789 int padX, padY; /* Use this extra padding inside window, in
790 * addition to the internal border. */
791 int innerWidth, innerHeight;/* Size of rectangle to anchor in window. */
792 int *xPtr, *yPtr; /* Returns upper-left corner of anchored
793 * rectangle. */
794 {
795 switch (anchor) {
796 case TK_ANCHOR_NW:
797 case TK_ANCHOR_W:
798 case TK_ANCHOR_SW:
799 *xPtr = Tk_InternalBorderWidth(tkwin) + padX;
800 break;
801
802 case TK_ANCHOR_N:
803 case TK_ANCHOR_CENTER:
804 case TK_ANCHOR_S:
805 *xPtr = (Tk_Width(tkwin) - innerWidth) / 2;
806 break;
807
808 default:
809 *xPtr = Tk_Width(tkwin) - (Tk_InternalBorderWidth(tkwin) + padX)
810 - innerWidth;
811 break;
812 }
813
814 switch (anchor) {
815 case TK_ANCHOR_NW:
816 case TK_ANCHOR_N:
817 case TK_ANCHOR_NE:
818 *yPtr = Tk_InternalBorderWidth(tkwin) + padY;
819 break;
820
821 case TK_ANCHOR_W:
822 case TK_ANCHOR_CENTER:
823 case TK_ANCHOR_E:
824 *yPtr = (Tk_Height(tkwin) - innerHeight) / 2;
825 break;
826
827 default:
828 *yPtr = Tk_Height(tkwin) - Tk_InternalBorderWidth(tkwin) - padY
829 - innerHeight;
830 break;
831 }
832 }
833
834 /*
835 *---------------------------------------------------------------------------
836 *
837 * TkFindStateString --
838 *
839 * Given a lookup table, map a number to a string in the table.
840 *
841 * Results:
842 * If numKey was equal to the numeric key of one of the elements
843 * in the table, returns the string key of that element.
844 * Returns NULL if numKey was not equal to any of the numeric keys
845 * in the table.
846 *
847 * Side effects.
848 * None.
849 *
850 *---------------------------------------------------------------------------
851 */
852
853 char *
854 TkFindStateString(mapPtr, numKey)
855 CONST TkStateMap *mapPtr; /* The state table. */
856 int numKey; /* The key to try to find in the table. */
857 {
858 for ( ; mapPtr->strKey != NULL; mapPtr++) {
859 if (numKey == mapPtr->numKey) {
860 return mapPtr->strKey;
861 }
862 }
863 return NULL;
864 }
865
866 /*
867 *---------------------------------------------------------------------------
868 *
869 * TkFindStateNum --
870 *
871 * Given a lookup table, map a string to a number in the table.
872 *
873 * Results:
874 * If strKey was equal to the string keys of one of the elements
875 * in the table, returns the numeric key of that element.
876 * Returns the numKey associated with the last element (the NULL
877 * string one) in the table if strKey was not equal to any of the
878 * string keys in the table. In that case, an error message is
879 * also left in the interp's result (if interp is not NULL).
880 *
881 * Side effects.
882 * None.
883 *
884 *---------------------------------------------------------------------------
885 */
886
887 int
888 TkFindStateNum(interp, option, mapPtr, strKey)
889 Tcl_Interp *interp; /* Interp for error reporting. */
890 CONST char *option; /* String to use when constructing error. */
891 CONST TkStateMap *mapPtr; /* Lookup table. */
892 CONST char *strKey; /* String to try to find in lookup table. */
893 {
894 CONST TkStateMap *mPtr;
895
896 for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
897 if (strcmp(strKey, mPtr->strKey) == 0) {
898 return mPtr->numKey;
899 }
900 }
901 if (interp != NULL) {
902 mPtr = mapPtr;
903 Tcl_AppendResult(interp, "bad ", option, " value \"", strKey,
904 "\": must be ", mPtr->strKey, (char *) NULL);
905 for (mPtr++; mPtr->strKey != NULL; mPtr++) {
906 Tcl_AppendResult(interp,
907 ((mPtr[1].strKey != NULL) ? ", " : ", or "),
908 mPtr->strKey, (char *) NULL);
909 }
910 }
911 return mPtr->numKey;
912 }
913
914 int
915 TkFindStateNumObj(interp, optionPtr, mapPtr, keyPtr)
916 Tcl_Interp *interp; /* Interp for error reporting. */
917 Tcl_Obj *optionPtr; /* String to use when constructing error. */
918 CONST TkStateMap *mapPtr; /* Lookup table. */
919 Tcl_Obj *keyPtr; /* String key to find in lookup table. */
920 {
921 CONST TkStateMap *mPtr;
922 CONST char *key;
923 CONST Tcl_ObjType *typePtr;
924
925 if ((keyPtr->typePtr == &stateKeyType)
926 && (keyPtr->internalRep.twoPtrValue.ptr1 == (VOID *) mapPtr)) {
927 return (int) keyPtr->internalRep.twoPtrValue.ptr2;
928 }
929
930 key = Tcl_GetStringFromObj(keyPtr, NULL);
931 for (mPtr = mapPtr; mPtr->strKey != NULL; mPtr++) {
932 if (strcmp(key, mPtr->strKey) == 0) {
933 typePtr = keyPtr->typePtr;
934 if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
935 (*typePtr->freeIntRepProc)(keyPtr);
936 }
937 keyPtr->internalRep.twoPtrValue.ptr1 = (VOID *) mapPtr;
938 keyPtr->internalRep.twoPtrValue.ptr2 = (VOID *) mPtr->numKey;
939 keyPtr->typePtr = &stateKeyType;
940 return mPtr->numKey;
941 }
942 }
943 if (interp != NULL) {
944 mPtr = mapPtr;
945 Tcl_AppendResult(interp, "bad ",
946 Tcl_GetStringFromObj(optionPtr, NULL), " value \"", key,
947 "\": must be ", mPtr->strKey, (char *) NULL);
948 for (mPtr++; mPtr->strKey != NULL; mPtr++) {
949 Tcl_AppendResult(interp,
950 ((mPtr[1].strKey != NULL) ? ", " : ", or "),
951 mPtr->strKey, (char *) NULL);
952 }
953 }
954 return mPtr->numKey;
955 }
956
957 /* End of tkutil.c */

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25