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

Diff of /projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkutil.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25