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

Diff of /projs/dtats/trunk/shared_source/c_tk_base_7_5_w_mods/tkframe.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   * tkFrame.c --   * tkFrame.c --
5   *   *
6   *      This module implements "frame"  and "toplevel" widgets for   *      This module implements "frame"  and "toplevel" widgets for
7   *      the Tk toolkit.  Frames are windows with a background color   *      the Tk toolkit.  Frames are windows with a background color
8   *      and possibly a 3-D effect, but not much else in the way of   *      and possibly a 3-D effect, but not much else in the way of
9   *      attributes.   *      attributes.
10   *   *
11   * Copyright (c) 1990-1994 The Regents of the University of California.   * Copyright (c) 1990-1994 The Regents of the University of California.
12   * Copyright (c) 1994-1997 Sun Microsystems, Inc.   * Copyright (c) 1994-1997 Sun Microsystems, Inc.
13   *   *
14   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
15   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
16   *   *
17   * RCS: @(#) $Id: tkframe.c,v 1.1.1.1 2001/06/13 05:01:10 dtashley Exp $   * RCS: @(#) $Id: tkframe.c,v 1.1.1.1 2001/06/13 05:01:10 dtashley Exp $
18   */   */
19    
20  #include "default.h"  #include "default.h"
21  #include "tkPort.h"  #include "tkPort.h"
22  #include "tkInt.h"  #include "tkInt.h"
23    
24  /*  /*
25   * A data structure of the following type is kept for each   * A data structure of the following type is kept for each
26   * frame that currently exists for this process:   * frame that currently exists for this process:
27   */   */
28    
29  typedef struct {  typedef struct {
30      Tk_Window tkwin;            /* Window that embodies the frame.  NULL      Tk_Window tkwin;            /* Window that embodies the frame.  NULL
31                                   * means that the window has been destroyed                                   * means that the window has been destroyed
32                                   * but the data structures haven't yet been                                   * but the data structures haven't yet been
33                                   * cleaned up. */                                   * cleaned up. */
34      Display *display;           /* Display containing widget.  Used, among      Display *display;           /* Display containing widget.  Used, among
35                                   * other things, so that resources can be                                   * other things, so that resources can be
36                                   * freed even after tkwin has gone away. */                                   * freed even after tkwin has gone away. */
37      Tcl_Interp *interp;         /* Interpreter associated with widget.  Used      Tcl_Interp *interp;         /* Interpreter associated with widget.  Used
38                                   * to delete widget command. */                                   * to delete widget command. */
39      Tcl_Command widgetCmd;      /* Token for frame's widget command. */      Tcl_Command widgetCmd;      /* Token for frame's widget command. */
40      char *className;            /* Class name for widget (from configuration      char *className;            /* Class name for widget (from configuration
41                                   * option).  Malloc-ed. */                                   * option).  Malloc-ed. */
42      int mask;                   /* Either FRAME or TOPLEVEL;  used to select      int mask;                   /* Either FRAME or TOPLEVEL;  used to select
43                                   * which configuration options are valid for                                   * which configuration options are valid for
44                                   * widget. */                                   * widget. */
45      char *screenName;           /* Screen on which widget is created.  Non-null      char *screenName;           /* Screen on which widget is created.  Non-null
46                                   * only for top-levels.  Malloc-ed, may be                                   * only for top-levels.  Malloc-ed, may be
47                                   * NULL. */                                   * NULL. */
48      char *visualName;           /* Textual description of visual for window,      char *visualName;           /* Textual description of visual for window,
49                                   * from -visual option.  Malloc-ed, may be                                   * from -visual option.  Malloc-ed, may be
50                                   * NULL. */                                   * NULL. */
51      char *colormapName;         /* Textual description of colormap for window,      char *colormapName;         /* Textual description of colormap for window,
52                                   * from -colormap option.  Malloc-ed, may be                                   * from -colormap option.  Malloc-ed, may be
53                                   * NULL. */                                   * NULL. */
54      char *menuName;             /* Textual description of menu to use for      char *menuName;             /* Textual description of menu to use for
55                                   * menubar. Malloc-ed, may be NULL. */                                   * menubar. Malloc-ed, may be NULL. */
56      Colormap colormap;          /* If not None, identifies a colormap      Colormap colormap;          /* If not None, identifies a colormap
57                                   * allocated for this window, which must be                                   * allocated for this window, which must be
58                                   * freed when the window is deleted. */                                   * freed when the window is deleted. */
59      Tk_3DBorder border;         /* Structure used to draw 3-D border and      Tk_3DBorder border;         /* Structure used to draw 3-D border and
60                                   * background.  NULL means no background                                   * background.  NULL means no background
61                                   * or border. */                                   * or border. */
62      int borderWidth;            /* Width of 3-D border (if any). */      int borderWidth;            /* Width of 3-D border (if any). */
63      int relief;                 /* 3-d effect: TK_RELIEF_RAISED etc. */      int relief;                 /* 3-d effect: TK_RELIEF_RAISED etc. */
64      int highlightWidth;         /* Width in pixels of highlight to draw      int highlightWidth;         /* Width in pixels of highlight to draw
65                                   * around widget when it has the focus.                                   * around widget when it has the focus.
66                                   * 0 means don't draw a highlight. */                                   * 0 means don't draw a highlight. */
67      XColor *highlightBgColorPtr;      XColor *highlightBgColorPtr;
68                                  /* Color for drawing traversal highlight                                  /* Color for drawing traversal highlight
69                                   * area when highlight is off. */                                   * area when highlight is off. */
70      XColor *highlightColorPtr;  /* Color for drawing traversal highlight. */      XColor *highlightColorPtr;  /* Color for drawing traversal highlight. */
71      int width;                  /* Width to request for window.  <= 0 means      int width;                  /* Width to request for window.  <= 0 means
72                                   * don't request any size. */                                   * don't request any size. */
73      int height;                 /* Height to request for window.  <= 0 means      int height;                 /* Height to request for window.  <= 0 means
74                                   * don't request any size. */                                   * don't request any size. */
75      Tk_Cursor cursor;           /* Current cursor for window, or None. */      Tk_Cursor cursor;           /* Current cursor for window, or None. */
76      char *takeFocus;            /* Value of -takefocus option;  not used in      char *takeFocus;            /* Value of -takefocus option;  not used in
77                                   * the C code, but used by keyboard traversal                                   * the C code, but used by keyboard traversal
78                                   * scripts.  Malloc'ed, but may be NULL. */                                   * scripts.  Malloc'ed, but may be NULL. */
79      int isContainer;            /* 1 means this window is a container, 0 means      int isContainer;            /* 1 means this window is a container, 0 means
80                                   * that it isn't. */                                   * that it isn't. */
81      char *useThis;              /* If the window is embedded, this points to      char *useThis;              /* If the window is embedded, this points to
82                                   * the name of the window in which it is                                   * the name of the window in which it is
83                                   * embedded (malloc'ed).  For non-embedded                                   * embedded (malloc'ed).  For non-embedded
84                                   * windows this is NULL. */                                   * windows this is NULL. */
85      int flags;                  /* Various flags;  see below for      int flags;                  /* Various flags;  see below for
86                                   * definitions. */                                   * definitions. */
87  } Frame;  } Frame;
88    
89  /*  /*
90   * Flag bits for frames:   * Flag bits for frames:
91   *   *
92   * REDRAW_PENDING:              Non-zero means a DoWhenIdle handler   * REDRAW_PENDING:              Non-zero means a DoWhenIdle handler
93   *                              has already been queued to redraw   *                              has already been queued to redraw
94   *                              this window.   *                              this window.
95   * GOT_FOCUS:                   Non-zero means this widget currently   * GOT_FOCUS:                   Non-zero means this widget currently
96   *                              has the input focus.   *                              has the input focus.
97   */   */
98    
99  #define REDRAW_PENDING          1  #define REDRAW_PENDING          1
100  #define GOT_FOCUS               4  #define GOT_FOCUS               4
101    
102  /*  /*
103   * The following flag bits are used so that there can be separate   * The following flag bits are used so that there can be separate
104   * defaults for some configuration options for frames and toplevels.   * defaults for some configuration options for frames and toplevels.
105   */   */
106    
107  #define FRAME           TK_CONFIG_USER_BIT  #define FRAME           TK_CONFIG_USER_BIT
108  #define TOPLEVEL        (TK_CONFIG_USER_BIT << 1)  #define TOPLEVEL        (TK_CONFIG_USER_BIT << 1)
109  #define BOTH            (FRAME | TOPLEVEL)  #define BOTH            (FRAME | TOPLEVEL)
110    
111  static Tk_ConfigSpec configSpecs[] = {  static Tk_ConfigSpec configSpecs[] = {
112      {TK_CONFIG_BORDER, "-background", "background", "Background",      {TK_CONFIG_BORDER, "-background", "background", "Background",
113          DEF_FRAME_BG_COLOR, Tk_Offset(Frame, border),          DEF_FRAME_BG_COLOR, Tk_Offset(Frame, border),
114          BOTH|TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK},          BOTH|TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK},
115      {TK_CONFIG_BORDER, "-background", "background", "Background",      {TK_CONFIG_BORDER, "-background", "background", "Background",
116          DEF_FRAME_BG_MONO, Tk_Offset(Frame, border),          DEF_FRAME_BG_MONO, Tk_Offset(Frame, border),
117          BOTH|TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK},          BOTH|TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK},
118      {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,      {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
119          (char *) NULL, 0, BOTH},          (char *) NULL, 0, BOTH},
120      {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,      {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
121          (char *) NULL, 0, BOTH},          (char *) NULL, 0, BOTH},
122      {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",      {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
123          DEF_FRAME_BORDER_WIDTH, Tk_Offset(Frame, borderWidth), BOTH},          DEF_FRAME_BORDER_WIDTH, Tk_Offset(Frame, borderWidth), BOTH},
124      {TK_CONFIG_STRING, "-class", "class", "Class",      {TK_CONFIG_STRING, "-class", "class", "Class",
125          DEF_FRAME_CLASS, Tk_Offset(Frame, className), FRAME},          DEF_FRAME_CLASS, Tk_Offset(Frame, className), FRAME},
126      {TK_CONFIG_STRING, "-class", "class", "Class",      {TK_CONFIG_STRING, "-class", "class", "Class",
127          DEF_TOPLEVEL_CLASS, Tk_Offset(Frame, className), TOPLEVEL},          DEF_TOPLEVEL_CLASS, Tk_Offset(Frame, className), TOPLEVEL},
128      {TK_CONFIG_STRING, "-colormap", "colormap", "Colormap",      {TK_CONFIG_STRING, "-colormap", "colormap", "Colormap",
129          DEF_FRAME_COLORMAP, Tk_Offset(Frame, colormapName),          DEF_FRAME_COLORMAP, Tk_Offset(Frame, colormapName),
130          BOTH|TK_CONFIG_NULL_OK},          BOTH|TK_CONFIG_NULL_OK},
131      {TK_CONFIG_BOOLEAN, "-container", "container", "Container",      {TK_CONFIG_BOOLEAN, "-container", "container", "Container",
132          DEF_FRAME_CONTAINER, Tk_Offset(Frame, isContainer), BOTH},          DEF_FRAME_CONTAINER, Tk_Offset(Frame, isContainer), BOTH},
133      {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",      {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
134          DEF_FRAME_CURSOR, Tk_Offset(Frame, cursor), BOTH|TK_CONFIG_NULL_OK},          DEF_FRAME_CURSOR, Tk_Offset(Frame, cursor), BOTH|TK_CONFIG_NULL_OK},
135      {TK_CONFIG_PIXELS, "-height", "height", "Height",      {TK_CONFIG_PIXELS, "-height", "height", "Height",
136          DEF_FRAME_HEIGHT, Tk_Offset(Frame, height), BOTH},          DEF_FRAME_HEIGHT, Tk_Offset(Frame, height), BOTH},
137      {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",      {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
138          "HighlightBackground", DEF_FRAME_HIGHLIGHT_BG,          "HighlightBackground", DEF_FRAME_HIGHLIGHT_BG,
139          Tk_Offset(Frame, highlightBgColorPtr), BOTH},          Tk_Offset(Frame, highlightBgColorPtr), BOTH},
140      {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",      {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
141          DEF_FRAME_HIGHLIGHT, Tk_Offset(Frame, highlightColorPtr), BOTH},          DEF_FRAME_HIGHLIGHT, Tk_Offset(Frame, highlightColorPtr), BOTH},
142      {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",      {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
143          "HighlightThickness",          "HighlightThickness",
144          DEF_FRAME_HIGHLIGHT_WIDTH, Tk_Offset(Frame, highlightWidth), BOTH},          DEF_FRAME_HIGHLIGHT_WIDTH, Tk_Offset(Frame, highlightWidth), BOTH},
145      {TK_CONFIG_STRING, "-menu", "menu", "Menu",      {TK_CONFIG_STRING, "-menu", "menu", "Menu",
146          DEF_TOPLEVEL_MENU, Tk_Offset(Frame, menuName),          DEF_TOPLEVEL_MENU, Tk_Offset(Frame, menuName),
147          TOPLEVEL|TK_CONFIG_NULL_OK},          TOPLEVEL|TK_CONFIG_NULL_OK},
148      {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",      {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
149          DEF_FRAME_RELIEF, Tk_Offset(Frame, relief), BOTH},          DEF_FRAME_RELIEF, Tk_Offset(Frame, relief), BOTH},
150      {TK_CONFIG_STRING, "-screen", "screen", "Screen",      {TK_CONFIG_STRING, "-screen", "screen", "Screen",
151          DEF_TOPLEVEL_SCREEN, Tk_Offset(Frame, screenName),          DEF_TOPLEVEL_SCREEN, Tk_Offset(Frame, screenName),
152          TOPLEVEL|TK_CONFIG_NULL_OK},          TOPLEVEL|TK_CONFIG_NULL_OK},
153      {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",      {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
154          DEF_FRAME_TAKE_FOCUS, Tk_Offset(Frame, takeFocus),          DEF_FRAME_TAKE_FOCUS, Tk_Offset(Frame, takeFocus),
155          BOTH|TK_CONFIG_NULL_OK},          BOTH|TK_CONFIG_NULL_OK},
156      {TK_CONFIG_STRING, "-use", "use", "Use",      {TK_CONFIG_STRING, "-use", "use", "Use",
157          DEF_FRAME_USE, Tk_Offset(Frame, useThis), TOPLEVEL|TK_CONFIG_NULL_OK},          DEF_FRAME_USE, Tk_Offset(Frame, useThis), TOPLEVEL|TK_CONFIG_NULL_OK},
158      {TK_CONFIG_STRING, "-visual", "visual", "Visual",      {TK_CONFIG_STRING, "-visual", "visual", "Visual",
159          DEF_FRAME_VISUAL, Tk_Offset(Frame, visualName),          DEF_FRAME_VISUAL, Tk_Offset(Frame, visualName),
160          BOTH|TK_CONFIG_NULL_OK},          BOTH|TK_CONFIG_NULL_OK},
161      {TK_CONFIG_PIXELS, "-width", "width", "Width",      {TK_CONFIG_PIXELS, "-width", "width", "Width",
162          DEF_FRAME_WIDTH, Tk_Offset(Frame, width), BOTH},          DEF_FRAME_WIDTH, Tk_Offset(Frame, width), BOTH},
163      {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,      {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
164          (char *) NULL, 0, 0}          (char *) NULL, 0, 0}
165  };  };
166    
167  /*  /*
168   * Forward declarations for procedures defined later in this file:   * Forward declarations for procedures defined later in this file:
169   */   */
170    
171  static int              ConfigureFrame _ANSI_ARGS_((Tcl_Interp *interp,  static int              ConfigureFrame _ANSI_ARGS_((Tcl_Interp *interp,
172                              Frame *framePtr, int objc, Tcl_Obj *CONST objv[],                              Frame *framePtr, int objc, Tcl_Obj *CONST objv[],
173                              int flags));                              int flags));
174  static int              CreateFrame _ANSI_ARGS_((ClientData clientData,  static int              CreateFrame _ANSI_ARGS_((ClientData clientData,
175                              Tcl_Interp *interp, int objc, Tcl_Obj *CONST argv[],                              Tcl_Interp *interp, int objc, Tcl_Obj *CONST argv[],
176                              int toplevel, char *appName));                              int toplevel, char *appName));
177  static void             DestroyFrame _ANSI_ARGS_((char *memPtr));  static void             DestroyFrame _ANSI_ARGS_((char *memPtr));
178  static void             DisplayFrame _ANSI_ARGS_((ClientData clientData));  static void             DisplayFrame _ANSI_ARGS_((ClientData clientData));
179  static void             FrameCmdDeletedProc _ANSI_ARGS_((  static void             FrameCmdDeletedProc _ANSI_ARGS_((
180                              ClientData clientData));                              ClientData clientData));
181  static void             FrameEventProc _ANSI_ARGS_((ClientData clientData,  static void             FrameEventProc _ANSI_ARGS_((ClientData clientData,
182                              XEvent *eventPtr));                              XEvent *eventPtr));
183  static int              FrameWidgetObjCmd _ANSI_ARGS_((ClientData clientData,  static int              FrameWidgetObjCmd _ANSI_ARGS_((ClientData clientData,
184                              Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));                              Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]));
185  static void             MapFrame _ANSI_ARGS_((ClientData clientData));  static void             MapFrame _ANSI_ARGS_((ClientData clientData));
186    
187  /*  /*
188   *--------------------------------------------------------------   *--------------------------------------------------------------
189   *   *
190   * Tk_FrameObjCmd, Tk_ToplevelObjCmd --   * Tk_FrameObjCmd, Tk_ToplevelObjCmd --
191   *   *
192   *      These procedures are invoked to process the "frame" and   *      These procedures are invoked to process the "frame" and
193   *      "toplevel" Tcl commands.  See the user documentation for   *      "toplevel" Tcl commands.  See the user documentation for
194   *      details on what they do.   *      details on what they do.
195   *   *
196   * Results:   * Results:
197   *      A standard Tcl result.   *      A standard Tcl result.
198   *   *
199   * Side effects:   * Side effects:
200   *      See the user documentation.  These procedures are just wrappers;   *      See the user documentation.  These procedures are just wrappers;
201   *      they call ButtonCreate to do all of the real work.   *      they call ButtonCreate to do all of the real work.
202   *   *
203   *--------------------------------------------------------------   *--------------------------------------------------------------
204   */   */
205    
206  int  int
207  Tk_FrameObjCmd(clientData, interp, objc, objv)  Tk_FrameObjCmd(clientData, interp, objc, objv)
208      ClientData clientData;      /* Main window associated with      ClientData clientData;      /* Main window associated with
209                                   * interpreter. */                                   * interpreter. */
210      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
211      int objc;                   /* Number of arguments. */      int objc;                   /* Number of arguments. */
212      Tcl_Obj *CONST objv[];      /* Argument objects. */      Tcl_Obj *CONST objv[];      /* Argument objects. */
213  {  {
214      return CreateFrame(clientData, interp, objc, objv, 0, (char *) NULL);      return CreateFrame(clientData, interp, objc, objv, 0, (char *) NULL);
215  }  }
216    
217  int  int
218  Tk_ToplevelObjCmd(clientData, interp, objc, objv)  Tk_ToplevelObjCmd(clientData, interp, objc, objv)
219      ClientData clientData;      /* Main window associated with      ClientData clientData;      /* Main window associated with
220                                   * interpreter. */                                   * interpreter. */
221      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
222      int objc;                   /* Number of arguments. */      int objc;                   /* Number of arguments. */
223      Tcl_Obj *CONST objv[];      /* Argument objects. */      Tcl_Obj *CONST objv[];      /* Argument objects. */
224  {  {
225      return CreateFrame(clientData, interp, objc, objv, 1, (char *) NULL);      return CreateFrame(clientData, interp, objc, objv, 1, (char *) NULL);
226  }  }
227    
228  /*  /*
229   *--------------------------------------------------------------   *--------------------------------------------------------------
230   *   *
231   * TkCreateFrame --   * TkCreateFrame --
232   *   *
233   *      This procedure is invoked to process the "frame" and "toplevel"   *      This procedure is invoked to process the "frame" and "toplevel"
234   *      Tcl commands;  it is also invoked directly by Tk_Init to create   *      Tcl commands;  it is also invoked directly by Tk_Init to create
235   *      a new main window.  See the user documentation for the "frame"   *      a new main window.  See the user documentation for the "frame"
236   *      and "toplevel" commands for details on what it does.   *      and "toplevel" commands for details on what it does.
237   *   *
238   * Results:   * Results:
239   *      A standard Tcl result.   *      A standard Tcl result.
240   *   *
241   * Side effects:   * Side effects:
242   *      See the user documentation.   *      See the user documentation.
243   *   *
244   *--------------------------------------------------------------   *--------------------------------------------------------------
245   */   */
246    
247  int  int
248  TkCreateFrame(clientData, interp, argc, argv, toplevel, appName)  TkCreateFrame(clientData, interp, argc, argv, toplevel, appName)
249      ClientData clientData;      /* Main window associated with interpreter.      ClientData clientData;      /* Main window associated with interpreter.
250                                   * If we're called by Tk_Init to create a                                   * If we're called by Tk_Init to create a
251                                   * new application, then this is NULL. */                                   * new application, then this is NULL. */
252      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
253      int argc;                   /* Number of arguments. */      int argc;                   /* Number of arguments. */
254      char **argv;                /* Argument strings. */      char **argv;                /* Argument strings. */
255      int toplevel;               /* Non-zero means create a toplevel window,      int toplevel;               /* Non-zero means create a toplevel window,
256                                   * zero means create a frame. */                                   * zero means create a frame. */
257      char *appName;              /* Should only be non-NULL if clientData is      char *appName;              /* Should only be non-NULL if clientData is
258                                   * NULL:  gives the base name to use for the                                   * NULL:  gives the base name to use for the
259                                   * new application. */                                   * new application. */
260  {  {
261      int result, i;      int result, i;
262      Tcl_Obj **objv = (Tcl_Obj **) ckalloc((argc+1) * sizeof(Tcl_Obj **));      Tcl_Obj **objv = (Tcl_Obj **) ckalloc((argc+1) * sizeof(Tcl_Obj **));
263      for (i=0; i<argc; i++) {      for (i=0; i<argc; i++) {
264          objv[i] = Tcl_NewStringObj(argv[i], -1);          objv[i] = Tcl_NewStringObj(argv[i], -1);
265          Tcl_IncrRefCount(objv[i]);          Tcl_IncrRefCount(objv[i]);
266      }      }
267      objv[argc] = NULL;      objv[argc] = NULL;
268      result = CreateFrame(clientData, interp, argc, objv, toplevel, appName);      result = CreateFrame(clientData, interp, argc, objv, toplevel, appName);
269      for (i=0; i<argc; i++) {      for (i=0; i<argc; i++) {
270          Tcl_DecrRefCount(objv[i]);          Tcl_DecrRefCount(objv[i]);
271      }      }
272      ckfree((char *) objv);      ckfree((char *) objv);
273      return result;      return result;
274  }  }
275    
276  static int  static int
277  CreateFrame(clientData, interp, objc, objv, toplevel, appName)  CreateFrame(clientData, interp, objc, objv, toplevel, appName)
278      ClientData clientData;      /* Main window associated with interpreter.      ClientData clientData;      /* Main window associated with interpreter.
279                                   * If we're called by Tk_Init to create a                                   * If we're called by Tk_Init to create a
280                                   * new application, then this is NULL. */                                   * new application, then this is NULL. */
281      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
282      int objc;                   /* Number of arguments. */      int objc;                   /* Number of arguments. */
283      Tcl_Obj *CONST objv[];      /* Argument objects. */      Tcl_Obj *CONST objv[];      /* Argument objects. */
284      int toplevel;               /* Non-zero means create a toplevel window,      int toplevel;               /* Non-zero means create a toplevel window,
285                                   * zero means create a frame. */                                   * zero means create a frame. */
286      char *appName;              /* Should only be non-NULL if clientData is      char *appName;              /* Should only be non-NULL if clientData is
287                                   * NULL:  gives the base name to use for the                                   * NULL:  gives the base name to use for the
288                                   * new application. */                                   * new application. */
289  {  {
290      Tk_Window tkwin = (Tk_Window) clientData;      Tk_Window tkwin = (Tk_Window) clientData;
291      Frame *framePtr;      Frame *framePtr;
292      Tk_Window new;      Tk_Window new;
293      char *className, *screenName, *visualName, *colormapName, *arg, *useOption;      char *className, *screenName, *visualName, *colormapName, *arg, *useOption;
294      int i, c, depth;      int i, c, depth;
295      size_t length;      size_t length;
296      unsigned int mask;      unsigned int mask;
297      Colormap colormap;      Colormap colormap;
298      Visual *visual;      Visual *visual;
299    
300      if (objc < 2) {      if (objc < 2) {
301          Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");          Tcl_WrongNumArgs(interp, 1, objv, "pathName ?options?");
302          return TCL_ERROR;          return TCL_ERROR;
303      }      }
304    
305      /*      /*
306       * Pre-process the argument list.  Scan through it to find any       * Pre-process the argument list.  Scan through it to find any
307       * "-class", "-screen", "-visual", and "-colormap" options.  These       * "-class", "-screen", "-visual", and "-colormap" options.  These
308       * arguments need to be processed specially, before the window       * arguments need to be processed specially, before the window
309       * is configured using the usual Tk mechanisms.       * is configured using the usual Tk mechanisms.
310       */       */
311    
312      className = colormapName = screenName = visualName = useOption = NULL;      className = colormapName = screenName = visualName = useOption = NULL;
313      colormap = None;      colormap = None;
314      for (i = 2; i < objc; i += 2) {      for (i = 2; i < objc; i += 2) {
315          arg = Tcl_GetStringFromObj(objv[i], (int *) &length);          arg = Tcl_GetStringFromObj(objv[i], (int *) &length);
316          if (length < 2) {          if (length < 2) {
317              continue;              continue;
318          }          }
319          c = arg[1];          c = arg[1];
320          if ((c == 'c') && (strncmp(arg, "-class", length) == 0)          if ((c == 'c') && (strncmp(arg, "-class", length) == 0)
321                  && (length >= 3)) {                  && (length >= 3)) {
322              className = Tcl_GetString(objv[i+1]);              className = Tcl_GetString(objv[i+1]);
323          } else if ((c == 'c')          } else if ((c == 'c')
324                  && (strncmp(arg, "-colormap", length) == 0)) {                  && (strncmp(arg, "-colormap", length) == 0)) {
325              colormapName = Tcl_GetString(objv[i+1]);              colormapName = Tcl_GetString(objv[i+1]);
326          } else if ((c == 's') && toplevel          } else if ((c == 's') && toplevel
327                  && (strncmp(arg, "-screen", length) == 0)) {                  && (strncmp(arg, "-screen", length) == 0)) {
328              screenName = Tcl_GetString(objv[i+1]);              screenName = Tcl_GetString(objv[i+1]);
329          } else if ((c == 'u') && toplevel          } else if ((c == 'u') && toplevel
330                  && (strncmp(arg, "-use", length) == 0)) {                  && (strncmp(arg, "-use", length) == 0)) {
331              useOption = Tcl_GetString(objv[i+1]);              useOption = Tcl_GetString(objv[i+1]);
332          } else if ((c == 'v')          } else if ((c == 'v')
333                  && (strncmp(arg, "-visual", length) == 0)) {                  && (strncmp(arg, "-visual", length) == 0)) {
334              visualName = Tcl_GetString(objv[i+1]);              visualName = Tcl_GetString(objv[i+1]);
335          }          }
336      }      }
337    
338      /*      /*
339       * Create the window, and deal with the special options -use,       * Create the window, and deal with the special options -use,
340       * -classname, -colormap, -screenname, and -visual.  These options       * -classname, -colormap, -screenname, and -visual.  These options
341       * must be handle before calling ConfigureFrame below, and they must       * must be handle before calling ConfigureFrame below, and they must
342       * also be processed in a particular order, for the following       * also be processed in a particular order, for the following
343       * reasons:       * reasons:
344       * 1. Must set the window's class before calling ConfigureFrame,       * 1. Must set the window's class before calling ConfigureFrame,
345       *    so that unspecified options are looked up in the option       *    so that unspecified options are looked up in the option
346       *    database using the correct class.       *    database using the correct class.
347       * 2. Must set visual information before calling ConfigureFrame       * 2. Must set visual information before calling ConfigureFrame
348       *    so that colors are allocated in a proper colormap.       *    so that colors are allocated in a proper colormap.
349       * 3. Must call TkpUseWindow before setting non-default visual       * 3. Must call TkpUseWindow before setting non-default visual
350       *    information, since TkpUseWindow changes the defaults.       *    information, since TkpUseWindow changes the defaults.
351       */       */
352    
353      if (screenName == NULL) {      if (screenName == NULL) {
354          screenName = (toplevel) ? "" : NULL;          screenName = (toplevel) ? "" : NULL;
355      }      }
356      if (tkwin != NULL) {      if (tkwin != NULL) {
357          new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]),          new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]),
358                  screenName);                  screenName);
359      } else {      } else {
360          /*          /*
361           * We were called from Tk_Init;  create a new application.           * We were called from Tk_Init;  create a new application.
362           */           */
363    
364          if (appName == NULL) {          if (appName == NULL) {
365              panic("TkCreateFrame didn't get application name");              panic("TkCreateFrame didn't get application name");
366          }          }
367          new = TkCreateMainWindow(interp, screenName, appName);          new = TkCreateMainWindow(interp, screenName, appName);
368      }      }
369      if (new == NULL) {      if (new == NULL) {
370          goto error;          goto error;
371      }      }
372      if (className == NULL) {      if (className == NULL) {
373          className = Tk_GetOption(new, "class", "Class");          className = Tk_GetOption(new, "class", "Class");
374          if (className == NULL) {          if (className == NULL) {
375              className = (toplevel) ? "Toplevel" : "Frame";              className = (toplevel) ? "Toplevel" : "Frame";
376          }          }
377      }      }
378      Tk_SetClass(new, className);      Tk_SetClass(new, className);
379      if (useOption == NULL) {      if (useOption == NULL) {
380          useOption = Tk_GetOption(new, "use", "Use");          useOption = Tk_GetOption(new, "use", "Use");
381      }      }
382      if (useOption != NULL) {      if (useOption != NULL) {
383          if (TkpUseWindow(interp, new, useOption) != TCL_OK) {          if (TkpUseWindow(interp, new, useOption) != TCL_OK) {
384              goto error;              goto error;
385          }          }
386      }      }
387      if (visualName == NULL) {      if (visualName == NULL) {
388          visualName = Tk_GetOption(new, "visual", "Visual");          visualName = Tk_GetOption(new, "visual", "Visual");
389      }      }
390      if (colormapName == NULL) {      if (colormapName == NULL) {
391          colormapName = Tk_GetOption(new, "colormap", "Colormap");          colormapName = Tk_GetOption(new, "colormap", "Colormap");
392      }      }
393      if (visualName != NULL) {      if (visualName != NULL) {
394          visual = Tk_GetVisual(interp, new, visualName, &depth,          visual = Tk_GetVisual(interp, new, visualName, &depth,
395                  (colormapName == NULL) ? &colormap : (Colormap *) NULL);                  (colormapName == NULL) ? &colormap : (Colormap *) NULL);
396          if (visual == NULL) {          if (visual == NULL) {
397              goto error;              goto error;
398          }          }
399          Tk_SetWindowVisual(new, visual, depth, colormap);          Tk_SetWindowVisual(new, visual, depth, colormap);
400      }      }
401      if (colormapName != NULL) {      if (colormapName != NULL) {
402          colormap = Tk_GetColormap(interp, new, colormapName);          colormap = Tk_GetColormap(interp, new, colormapName);
403          if (colormap == None) {          if (colormap == None) {
404              goto error;              goto error;
405          }          }
406          Tk_SetWindowColormap(new, colormap);          Tk_SetWindowColormap(new, colormap);
407      }      }
408    
409      /*      /*
410       * For top-level windows, provide an initial geometry request of       * For top-level windows, provide an initial geometry request of
411       * 200x200,  just so the window looks nicer on the screen if it       * 200x200,  just so the window looks nicer on the screen if it
412       * doesn't request a size for itself.       * doesn't request a size for itself.
413       */       */
414    
415      if (toplevel) {      if (toplevel) {
416          Tk_GeometryRequest(new, 200, 200);          Tk_GeometryRequest(new, 200, 200);
417      }      }
418    
419      /*      /*
420       * Create the widget record, process configuration options, and       * Create the widget record, process configuration options, and
421       * create event handlers.  Then fill in a few additional fields       * create event handlers.  Then fill in a few additional fields
422       * in the widget record from the special options.       * in the widget record from the special options.
423       */       */
424    
425      framePtr = (Frame *) ckalloc(sizeof(Frame));      framePtr = (Frame *) ckalloc(sizeof(Frame));
426      framePtr->tkwin = new;      framePtr->tkwin = new;
427      framePtr->display = Tk_Display(new);      framePtr->display = Tk_Display(new);
428      framePtr->interp = interp;      framePtr->interp = interp;
429      framePtr->widgetCmd = Tcl_CreateObjCommand(interp,      framePtr->widgetCmd = Tcl_CreateObjCommand(interp,
430              Tk_PathName(new), FrameWidgetObjCmd,              Tk_PathName(new), FrameWidgetObjCmd,
431              (ClientData) framePtr, FrameCmdDeletedProc);              (ClientData) framePtr, FrameCmdDeletedProc);
432      framePtr->className = NULL;      framePtr->className = NULL;
433      framePtr->mask = (toplevel) ? TOPLEVEL : FRAME;      framePtr->mask = (toplevel) ? TOPLEVEL : FRAME;
434      framePtr->screenName = NULL;      framePtr->screenName = NULL;
435      framePtr->visualName = NULL;      framePtr->visualName = NULL;
436      framePtr->colormapName = NULL;      framePtr->colormapName = NULL;
437      framePtr->colormap = colormap;      framePtr->colormap = colormap;
438      framePtr->border = NULL;      framePtr->border = NULL;
439      framePtr->borderWidth = 0;      framePtr->borderWidth = 0;
440      framePtr->relief = TK_RELIEF_FLAT;      framePtr->relief = TK_RELIEF_FLAT;
441      framePtr->highlightWidth = 0;      framePtr->highlightWidth = 0;
442      framePtr->highlightBgColorPtr = NULL;      framePtr->highlightBgColorPtr = NULL;
443      framePtr->highlightColorPtr = NULL;      framePtr->highlightColorPtr = NULL;
444      framePtr->width = 0;      framePtr->width = 0;
445      framePtr->height = 0;      framePtr->height = 0;
446      framePtr->cursor = None;      framePtr->cursor = None;
447      framePtr->takeFocus = NULL;      framePtr->takeFocus = NULL;
448      framePtr->isContainer = 0;      framePtr->isContainer = 0;
449      framePtr->useThis = NULL;      framePtr->useThis = NULL;
450      framePtr->flags = 0;      framePtr->flags = 0;
451      framePtr->menuName = NULL;      framePtr->menuName = NULL;
452    
453      /*      /*
454       * Store backreference to frame widget in window structure.       * Store backreference to frame widget in window structure.
455       */       */
456      TkSetClassProcs(new, NULL, (ClientData) framePtr);      TkSetClassProcs(new, NULL, (ClientData) framePtr);
457    
458      mask = ExposureMask | StructureNotifyMask | FocusChangeMask;      mask = ExposureMask | StructureNotifyMask | FocusChangeMask;
459      if (toplevel) {      if (toplevel) {
460          mask |= ActivateMask;          mask |= ActivateMask;
461      }      }
462      Tk_CreateEventHandler(new, mask, FrameEventProc, (ClientData) framePtr);      Tk_CreateEventHandler(new, mask, FrameEventProc, (ClientData) framePtr);
463      if (ConfigureFrame(interp, framePtr, objc-2, objv+2, 0) != TCL_OK) {      if (ConfigureFrame(interp, framePtr, objc-2, objv+2, 0) != TCL_OK) {
464          goto error;          goto error;
465      }      }
466      if ((framePtr->isContainer)) {      if ((framePtr->isContainer)) {
467          if (framePtr->useThis == NULL) {          if (framePtr->useThis == NULL) {
468              TkpMakeContainer(framePtr->tkwin);              TkpMakeContainer(framePtr->tkwin);
469          } else {          } else {
470              Tcl_AppendResult(interp,"A window cannot have both the -use ",              Tcl_AppendResult(interp,"A window cannot have both the -use ",
471                      "and the -container option set.");                      "and the -container option set.");
472              return TCL_ERROR;              return TCL_ERROR;
473          }          }
474      }      }
475      if (toplevel) {      if (toplevel) {
476          Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr);          Tcl_DoWhenIdle(MapFrame, (ClientData) framePtr);
477      }      }
478      Tcl_SetResult(interp, Tk_PathName(new), TCL_STATIC);      Tcl_SetResult(interp, Tk_PathName(new), TCL_STATIC);
479      return TCL_OK;      return TCL_OK;
480    
481      error:      error:
482      if (new != NULL) {      if (new != NULL) {
483          Tk_DestroyWindow(new);          Tk_DestroyWindow(new);
484      }      }
485      return TCL_ERROR;      return TCL_ERROR;
486  }  }
487    
488  /*  /*
489   *--------------------------------------------------------------   *--------------------------------------------------------------
490   *   *
491   * FrameWidgetObjCmd --   * FrameWidgetObjCmd --
492   *   *
493   *      This procedure is invoked to process the Tcl command   *      This procedure is invoked to process the Tcl command
494   *      that corresponds to a frame widget.  See the user   *      that corresponds to a frame widget.  See the user
495   *      documentation for details on what it does.   *      documentation for details on what it does.
496   *   *
497   * Results:   * Results:
498   *      A standard Tcl result.   *      A standard Tcl result.
499   *   *
500   * Side effects:   * Side effects:
501   *      See the user documentation.   *      See the user documentation.
502   *   *
503   *--------------------------------------------------------------   *--------------------------------------------------------------
504   */   */
505    
506  static int  static int
507  FrameWidgetObjCmd(clientData, interp, objc, objv)  FrameWidgetObjCmd(clientData, interp, objc, objv)
508      ClientData clientData;      /* Information about frame widget. */      ClientData clientData;      /* Information about frame widget. */
509      Tcl_Interp *interp;         /* Current interpreter. */      Tcl_Interp *interp;         /* Current interpreter. */
510      int objc;                   /* Number of arguments. */      int objc;                   /* Number of arguments. */
511      Tcl_Obj *CONST objv[];      /* Argument objects. */      Tcl_Obj *CONST objv[];      /* Argument objects. */
512  {  {
513      static char *frameOptions[] = {      static char *frameOptions[] = {
514          "cget", "configure", (char *) NULL          "cget", "configure", (char *) NULL
515      };      };
516      enum options {      enum options {
517          FRAME_CGET, FRAME_CONFIGURE          FRAME_CGET, FRAME_CONFIGURE
518      };      };
519      register Frame *framePtr = (Frame *) clientData;      register Frame *framePtr = (Frame *) clientData;
520      int result = TCL_OK, index;      int result = TCL_OK, index;
521      size_t length;      size_t length;
522      int c, i;      int c, i;
523    
524      if (objc < 2) {      if (objc < 2) {
525          Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");          Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?");
526          return TCL_ERROR;          return TCL_ERROR;
527      }      }
528      if (Tcl_GetIndexFromObj(interp, objv[1], frameOptions, "option", 0,      if (Tcl_GetIndexFromObj(interp, objv[1], frameOptions, "option", 0,
529              &index) != TCL_OK) {              &index) != TCL_OK) {
530          return TCL_ERROR;          return TCL_ERROR;
531      }      }
532      Tcl_Preserve((ClientData) framePtr);      Tcl_Preserve((ClientData) framePtr);
533      switch ((enum options) index) {      switch ((enum options) index) {
534        case FRAME_CGET: {        case FRAME_CGET: {
535          if (objc != 3) {          if (objc != 3) {
536              Tcl_WrongNumArgs(interp, 2, objv, "option");              Tcl_WrongNumArgs(interp, 2, objv, "option");
537              result = TCL_ERROR;              result = TCL_ERROR;
538              goto done;              goto done;
539          }          }
540          result = Tk_ConfigureValue(interp, framePtr->tkwin, configSpecs,          result = Tk_ConfigureValue(interp, framePtr->tkwin, configSpecs,
541                  (char *) framePtr, Tcl_GetString(objv[2]), framePtr->mask);                  (char *) framePtr, Tcl_GetString(objv[2]), framePtr->mask);
542          break;          break;
543        }        }
544        case FRAME_CONFIGURE: {        case FRAME_CONFIGURE: {
545          if (objc == 2) {          if (objc == 2) {
546              result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs,              result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs,
547                      (char *) framePtr, (char *) NULL, framePtr->mask);                      (char *) framePtr, (char *) NULL, framePtr->mask);
548          } else if (objc == 3) {          } else if (objc == 3) {
549              result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs,              result = Tk_ConfigureInfo(interp, framePtr->tkwin, configSpecs,
550                      (char *) framePtr, Tcl_GetString(objv[2]), framePtr->mask);                      (char *) framePtr, Tcl_GetString(objv[2]), framePtr->mask);
551          } else {          } else {
552              /*              /*
553               * Don't allow the options -class, -colormap, -container,               * Don't allow the options -class, -colormap, -container,
554               * -newcmap, -screen, -use, or -visual to be changed.               * -newcmap, -screen, -use, or -visual to be changed.
555               */               */
556    
557              for (i = 2; i < objc; i++) {              for (i = 2; i < objc; i++) {
558                  char *arg = Tcl_GetStringFromObj(objv[i], (int *) &length);                  char *arg = Tcl_GetStringFromObj(objv[i], (int *) &length);
559                  if (length < 2) {                  if (length < 2) {
560                      continue;                      continue;
561                  }                  }
562                  c = arg[1];                  c = arg[1];
563                  if (((c == 'c') && (strncmp(arg, "-class", length) == 0)                  if (((c == 'c') && (strncmp(arg, "-class", length) == 0)
564                          && (length >= 2))                          && (length >= 2))
565                          || ((c == 'c') && (framePtr->mask == TOPLEVEL)                          || ((c == 'c') && (framePtr->mask == TOPLEVEL)
566                          && (strncmp(arg, "-colormap", length) == 0)                          && (strncmp(arg, "-colormap", length) == 0)
567                          && (length >= 3))                          && (length >= 3))
568                          || ((c == 'c')                          || ((c == 'c')
569                          && (strncmp(arg, "-container", length) == 0)                          && (strncmp(arg, "-container", length) == 0)
570                          && (length >= 3))                          && (length >= 3))
571                          || ((c == 's') && (framePtr->mask == TOPLEVEL)                          || ((c == 's') && (framePtr->mask == TOPLEVEL)
572                          && (strncmp(arg, "-screen", length) == 0))                          && (strncmp(arg, "-screen", length) == 0))
573                          || ((c == 'u') && (framePtr->mask == TOPLEVEL)                          || ((c == 'u') && (framePtr->mask == TOPLEVEL)
574                          && (strncmp(arg, "-use", length) == 0))                          && (strncmp(arg, "-use", length) == 0))
575                          || ((c == 'v') && (framePtr->mask == TOPLEVEL)                          || ((c == 'v') && (framePtr->mask == TOPLEVEL)
576                          && (strncmp(arg, "-visual", length) == 0))) {                          && (strncmp(arg, "-visual", length) == 0))) {
577                      Tcl_AppendResult(interp, "can't modify ", arg,                      Tcl_AppendResult(interp, "can't modify ", arg,
578                              " option after widget is created", (char *) NULL);                              " option after widget is created", (char *) NULL);
579                      result = TCL_ERROR;                      result = TCL_ERROR;
580                      goto done;                      goto done;
581                  }                  }
582              }              }
583              result = ConfigureFrame(interp, framePtr, objc-2, objv+2,              result = ConfigureFrame(interp, framePtr, objc-2, objv+2,
584                      TK_CONFIG_ARGV_ONLY);                      TK_CONFIG_ARGV_ONLY);
585          }          }
586          break;          break;
587        }        }
588      }      }
589    
590      done:      done:
591      Tcl_Release((ClientData) framePtr);      Tcl_Release((ClientData) framePtr);
592      return result;      return result;
593  }  }
594    
595  /*  /*
596   *----------------------------------------------------------------------   *----------------------------------------------------------------------
597   *   *
598   * DestroyFrame --   * DestroyFrame --
599   *   *
600   *      This procedure is invoked by Tcl_EventuallyFree or Tcl_Release   *      This procedure is invoked by Tcl_EventuallyFree or Tcl_Release
601   *      to clean up the internal structure of a frame at a safe time   *      to clean up the internal structure of a frame at a safe time
602   *      (when no-one is using it anymore).   *      (when no-one is using it anymore).
603   *   *
604   * Results:   * Results:
605   *      None.   *      None.
606   *   *
607   * Side effects:   * Side effects:
608   *      Everything associated with the frame is freed up.   *      Everything associated with the frame is freed up.
609   *   *
610   *----------------------------------------------------------------------   *----------------------------------------------------------------------
611   */   */
612    
613  static void  static void
614  DestroyFrame(memPtr)  DestroyFrame(memPtr)
615      char *memPtr;               /* Info about frame widget. */      char *memPtr;               /* Info about frame widget. */
616  {  {
617      register Frame *framePtr = (Frame *) memPtr;      register Frame *framePtr = (Frame *) memPtr;
618    
619      Tk_FreeOptions(configSpecs, (char *) framePtr, framePtr->display,      Tk_FreeOptions(configSpecs, (char *) framePtr, framePtr->display,
620              framePtr->mask);              framePtr->mask);
621      if (framePtr->colormap != None) {      if (framePtr->colormap != None) {
622          Tk_FreeColormap(framePtr->display, framePtr->colormap);          Tk_FreeColormap(framePtr->display, framePtr->colormap);
623      }      }
624      ckfree((char *) framePtr);      ckfree((char *) framePtr);
625  }  }
626    
627  /*  /*
628   *----------------------------------------------------------------------   *----------------------------------------------------------------------
629   *   *
630   * ConfigureFrame --   * ConfigureFrame --
631   *   *
632   *      This procedure is called to process an objv/objc list, plus   *      This procedure is called to process an objv/objc list, plus
633   *      the Tk option database, in order to configure (or   *      the Tk option database, in order to configure (or
634   *      reconfigure) a frame widget.   *      reconfigure) a frame widget.
635   *   *
636   * Results:   * Results:
637   *      The return value is a standard Tcl result.  If TCL_ERROR is   *      The return value is a standard Tcl result.  If TCL_ERROR is
638   *      returned, then the interp's result contains an error message.   *      returned, then the interp's result contains an error message.
639   *   *
640   * Side effects:   * Side effects:
641   *      Configuration information, such as text string, colors, font,   *      Configuration information, such as text string, colors, font,
642   *      etc. get set for framePtr;  old resources get freed, if there   *      etc. get set for framePtr;  old resources get freed, if there
643   *      were any.   *      were any.
644   *   *
645   *----------------------------------------------------------------------   *----------------------------------------------------------------------
646   */   */
647    
648  static int  static int
649  ConfigureFrame(interp, framePtr, objc, objv, flags)  ConfigureFrame(interp, framePtr, objc, objv, flags)
650      Tcl_Interp *interp;         /* Used for error reporting. */      Tcl_Interp *interp;         /* Used for error reporting. */
651      register Frame *framePtr;   /* Information about widget;  may or may      register Frame *framePtr;   /* Information about widget;  may or may
652                                   * not already have values for some fields. */                                   * not already have values for some fields. */
653      int objc;                   /* Number of valid entries in objv. */      int objc;                   /* Number of valid entries in objv. */
654      Tcl_Obj *CONST objv[];      /* Arguments. */      Tcl_Obj *CONST objv[];      /* Arguments. */
655      int flags;                  /* Flags to pass to Tk_ConfigureWidget. */      int flags;                  /* Flags to pass to Tk_ConfigureWidget. */
656  {  {
657      char *oldMenuName;      char *oldMenuName;
658            
659      /*      /*
660       * Need the old menubar name for the menu code to delete it.       * Need the old menubar name for the menu code to delete it.
661       */       */
662            
663      if (framePtr->menuName == NULL) {      if (framePtr->menuName == NULL) {
664          oldMenuName = NULL;          oldMenuName = NULL;
665      } else {      } else {
666          oldMenuName = ckalloc(strlen(framePtr->menuName) + 1);          oldMenuName = ckalloc(strlen(framePtr->menuName) + 1);
667          strcpy(oldMenuName, framePtr->menuName);          strcpy(oldMenuName, framePtr->menuName);
668      }      }
669            
670      if (Tk_ConfigureWidget(interp, framePtr->tkwin, configSpecs,      if (Tk_ConfigureWidget(interp, framePtr->tkwin, configSpecs,
671              objc, (char **) objv, (char *) framePtr,              objc, (char **) objv, (char *) framePtr,
672              flags | framePtr->mask | TK_CONFIG_OBJS) != TCL_OK) {              flags | framePtr->mask | TK_CONFIG_OBJS) != TCL_OK) {
673          return TCL_ERROR;          return TCL_ERROR;
674      }      }
675    
676      if (((oldMenuName == NULL) && (framePtr->menuName != NULL))      if (((oldMenuName == NULL) && (framePtr->menuName != NULL))
677              || ((oldMenuName != NULL) && (framePtr->menuName == NULL))              || ((oldMenuName != NULL) && (framePtr->menuName == NULL))
678              || ((oldMenuName != NULL) && (framePtr->menuName != NULL)              || ((oldMenuName != NULL) && (framePtr->menuName != NULL)
679              && strcmp(oldMenuName, framePtr->menuName) != 0)) {              && strcmp(oldMenuName, framePtr->menuName) != 0)) {
680          TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName,          TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName,
681                  framePtr->menuName);                  framePtr->menuName);
682      }      }
683            
684      if (framePtr->border != NULL) {      if (framePtr->border != NULL) {
685          Tk_SetBackgroundFromBorder(framePtr->tkwin, framePtr->border);          Tk_SetBackgroundFromBorder(framePtr->tkwin, framePtr->border);
686      } else {      } else {
687          Tk_SetWindowBackgroundPixmap(framePtr->tkwin, None);          Tk_SetWindowBackgroundPixmap(framePtr->tkwin, None);
688      }      }
689    
690      if (framePtr->highlightWidth < 0) {      if (framePtr->highlightWidth < 0) {
691          framePtr->highlightWidth = 0;          framePtr->highlightWidth = 0;
692      }      }
693      Tk_SetInternalBorder(framePtr->tkwin,      Tk_SetInternalBorder(framePtr->tkwin,
694              framePtr->borderWidth + framePtr->highlightWidth);              framePtr->borderWidth + framePtr->highlightWidth);
695      if ((framePtr->width > 0) || (framePtr->height > 0)) {      if ((framePtr->width > 0) || (framePtr->height > 0)) {
696          Tk_GeometryRequest(framePtr->tkwin, framePtr->width,          Tk_GeometryRequest(framePtr->tkwin, framePtr->width,
697                  framePtr->height);                  framePtr->height);
698      }      }
699    
700      if (oldMenuName != NULL) {      if (oldMenuName != NULL) {
701          ckfree(oldMenuName);          ckfree(oldMenuName);
702      }      }
703    
704      if (Tk_IsMapped(framePtr->tkwin)) {      if (Tk_IsMapped(framePtr->tkwin)) {
705          if (!(framePtr->flags & REDRAW_PENDING)) {          if (!(framePtr->flags & REDRAW_PENDING)) {
706              Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);              Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);
707          }          }
708          framePtr->flags |= REDRAW_PENDING;          framePtr->flags |= REDRAW_PENDING;
709      }      }
710      return TCL_OK;      return TCL_OK;
711  }  }
712    
713  /*  /*
714   *----------------------------------------------------------------------   *----------------------------------------------------------------------
715   *   *
716   * DisplayFrame --   * DisplayFrame --
717   *   *
718   *      This procedure is invoked to display a frame widget.   *      This procedure is invoked to display a frame widget.
719   *   *
720   * Results:   * Results:
721   *      None.   *      None.
722   *   *
723   * Side effects:   * Side effects:
724   *      Commands are output to X to display the frame in its   *      Commands are output to X to display the frame in its
725   *      current mode.   *      current mode.
726   *   *
727   *----------------------------------------------------------------------   *----------------------------------------------------------------------
728   */   */
729    
730  static void  static void
731  DisplayFrame(clientData)  DisplayFrame(clientData)
732      ClientData clientData;      /* Information about widget. */      ClientData clientData;      /* Information about widget. */
733  {  {
734      register Frame *framePtr = (Frame *) clientData;      register Frame *framePtr = (Frame *) clientData;
735      register Tk_Window tkwin = framePtr->tkwin;      register Tk_Window tkwin = framePtr->tkwin;
736      void (* drawFunction) _ANSI_ARGS_((Tk_Window, Drawable, Tk_3DBorder,      void (* drawFunction) _ANSI_ARGS_((Tk_Window, Drawable, Tk_3DBorder,
737              int, int, int, int, int, int)) = Tk_Fill3DRectangle;              int, int, int, int, int, int)) = Tk_Fill3DRectangle;
738    
739      framePtr->flags &= ~REDRAW_PENDING;      framePtr->flags &= ~REDRAW_PENDING;
740      if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)      if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)
741          || framePtr->isContainer) {          || framePtr->isContainer) {
742          return;          return;
743      }      }
744    
745      if (framePtr->border != NULL) {      if (framePtr->border != NULL) {
746          drawFunction(tkwin, Tk_WindowId(tkwin),          drawFunction(tkwin, Tk_WindowId(tkwin),
747                  framePtr->border, framePtr->highlightWidth,                  framePtr->border, framePtr->highlightWidth,
748                  framePtr->highlightWidth,                  framePtr->highlightWidth,
749                  Tk_Width(tkwin) - 2*framePtr->highlightWidth,                  Tk_Width(tkwin) - 2*framePtr->highlightWidth,
750                  Tk_Height(tkwin) - 2*framePtr->highlightWidth,                  Tk_Height(tkwin) - 2*framePtr->highlightWidth,
751                  framePtr->borderWidth, framePtr->relief);                  framePtr->borderWidth, framePtr->relief);
752      }      }
753      if (framePtr->highlightWidth != 0) {      if (framePtr->highlightWidth != 0) {
754          GC fgGC, bgGC;          GC fgGC, bgGC;
755                    
756          bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr,          bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr,
757                  Tk_WindowId(tkwin));                  Tk_WindowId(tkwin));
758          if (framePtr->flags & GOT_FOCUS) {          if (framePtr->flags & GOT_FOCUS) {
759              fgGC = Tk_GCForColor(framePtr->highlightColorPtr,              fgGC = Tk_GCForColor(framePtr->highlightColorPtr,
760                      Tk_WindowId(tkwin));                      Tk_WindowId(tkwin));
761              TkpDrawHighlightBorder(tkwin, fgGC, bgGC, framePtr->highlightWidth,              TkpDrawHighlightBorder(tkwin, fgGC, bgGC, framePtr->highlightWidth,
762                      Tk_WindowId(tkwin));                      Tk_WindowId(tkwin));
763          } else {          } else {
764              TkpDrawHighlightBorder(tkwin, bgGC, bgGC, framePtr->highlightWidth,              TkpDrawHighlightBorder(tkwin, bgGC, bgGC, framePtr->highlightWidth,
765                      Tk_WindowId(tkwin));                      Tk_WindowId(tkwin));
766          }          }
767      }      }
768  }  }
769    
770  /*  /*
771   *--------------------------------------------------------------   *--------------------------------------------------------------
772   *   *
773   * FrameEventProc --   * FrameEventProc --
774   *   *
775   *      This procedure is invoked by the Tk dispatcher on   *      This procedure is invoked by the Tk dispatcher on
776   *      structure changes to a frame.  For frames with 3D   *      structure changes to a frame.  For frames with 3D
777   *      borders, this procedure is also invoked for exposures.   *      borders, this procedure is also invoked for exposures.
778   *   *
779   * Results:   * Results:
780   *      None.   *      None.
781   *   *
782   * Side effects:   * Side effects:
783   *      When the window gets deleted, internal structures get   *      When the window gets deleted, internal structures get
784   *      cleaned up.  When it gets exposed, it is redisplayed.   *      cleaned up.  When it gets exposed, it is redisplayed.
785   *   *
786   *--------------------------------------------------------------   *--------------------------------------------------------------
787   */   */
788    
789  static void  static void
790  FrameEventProc(clientData, eventPtr)  FrameEventProc(clientData, eventPtr)
791      ClientData clientData;      /* Information about window. */      ClientData clientData;      /* Information about window. */
792      register XEvent *eventPtr;  /* Information about event. */      register XEvent *eventPtr;  /* Information about event. */
793  {  {
794      register Frame *framePtr = (Frame *) clientData;      register Frame *framePtr = (Frame *) clientData;
795    
796      if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))      if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
797              || (eventPtr->type == ConfigureNotify)) {              || (eventPtr->type == ConfigureNotify)) {
798          goto redraw;          goto redraw;
799      } else if (eventPtr->type == DestroyNotify) {      } else if (eventPtr->type == DestroyNotify) {
800          if (framePtr->menuName != NULL) {          if (framePtr->menuName != NULL) {
801              TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,              TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
802                      framePtr->menuName, NULL);                      framePtr->menuName, NULL);
803              ckfree(framePtr->menuName);              ckfree(framePtr->menuName);
804              framePtr->menuName = NULL;              framePtr->menuName = NULL;
805          }          }
806          if (framePtr->tkwin != NULL) {          if (framePtr->tkwin != NULL) {
807    
808              /*              /*
809               * If this window is a container, then this event could be               * If this window is a container, then this event could be
810               * coming from the embedded application, in which case               * coming from the embedded application, in which case
811               * Tk_DestroyWindow hasn't been called yet.  When Tk_DestroyWindow               * Tk_DestroyWindow hasn't been called yet.  When Tk_DestroyWindow
812               * is called later, then another destroy event will be generated.               * is called later, then another destroy event will be generated.
813               * We need to be sure we ignore the second event, since the frame               * We need to be sure we ignore the second event, since the frame
814               * could be gone by then.  To do so, delete the event handler               * could be gone by then.  To do so, delete the event handler
815               * explicitly (normally it's done implicitly by Tk_DestroyWindow).               * explicitly (normally it's done implicitly by Tk_DestroyWindow).
816               */               */
817            
818              Tk_DeleteEventHandler(framePtr->tkwin,              Tk_DeleteEventHandler(framePtr->tkwin,
819                      ExposureMask|StructureNotifyMask|FocusChangeMask,                      ExposureMask|StructureNotifyMask|FocusChangeMask,
820                      FrameEventProc, (ClientData) framePtr);                      FrameEventProc, (ClientData) framePtr);
821              framePtr->tkwin = NULL;              framePtr->tkwin = NULL;
822              Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);              Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
823          }          }
824          if (framePtr->flags & REDRAW_PENDING) {          if (framePtr->flags & REDRAW_PENDING) {
825              Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr);              Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr);
826          }          }
827          Tcl_CancelIdleCall(MapFrame, (ClientData) framePtr);          Tcl_CancelIdleCall(MapFrame, (ClientData) framePtr);
828          Tcl_EventuallyFree((ClientData) framePtr, DestroyFrame);          Tcl_EventuallyFree((ClientData) framePtr, DestroyFrame);
829      } else if (eventPtr->type == FocusIn) {      } else if (eventPtr->type == FocusIn) {
830          if (eventPtr->xfocus.detail != NotifyInferior) {          if (eventPtr->xfocus.detail != NotifyInferior) {
831              framePtr->flags |= GOT_FOCUS;              framePtr->flags |= GOT_FOCUS;
832              if (framePtr->highlightWidth > 0) {              if (framePtr->highlightWidth > 0) {
833                  goto redraw;                  goto redraw;
834              }              }
835          }          }
836      } else if (eventPtr->type == FocusOut) {      } else if (eventPtr->type == FocusOut) {
837          if (eventPtr->xfocus.detail != NotifyInferior) {          if (eventPtr->xfocus.detail != NotifyInferior) {
838              framePtr->flags &= ~GOT_FOCUS;              framePtr->flags &= ~GOT_FOCUS;
839              if (framePtr->highlightWidth > 0) {              if (framePtr->highlightWidth > 0) {
840                  goto redraw;                  goto redraw;
841              }              }
842          }          }
843      } else if (eventPtr->type == ActivateNotify) {      } else if (eventPtr->type == ActivateNotify) {
844          TkpSetMainMenubar(framePtr->interp, framePtr->tkwin,          TkpSetMainMenubar(framePtr->interp, framePtr->tkwin,
845                  framePtr->menuName);                  framePtr->menuName);
846      }      }
847      return;      return;
848    
849      redraw:      redraw:
850      if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {      if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) {
851          Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);          Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr);
852          framePtr->flags |= REDRAW_PENDING;          framePtr->flags |= REDRAW_PENDING;
853      }      }
854  }  }
855    
856  /*  /*
857   *----------------------------------------------------------------------   *----------------------------------------------------------------------
858   *   *
859   * FrameCmdDeletedProc --   * FrameCmdDeletedProc --
860   *   *
861   *      This procedure is invoked when a widget command is deleted.  If   *      This procedure is invoked when a widget command is deleted.  If
862   *      the widget isn't already in the process of being destroyed,   *      the widget isn't already in the process of being destroyed,
863   *      this command destroys it.   *      this command destroys it.
864   *   *
865   * Results:   * Results:
866   *      None.   *      None.
867   *   *
868   * Side effects:   * Side effects:
869   *      The widget is destroyed.   *      The widget is destroyed.
870   *   *
871   *----------------------------------------------------------------------   *----------------------------------------------------------------------
872   */   */
873    
874  static void  static void
875  FrameCmdDeletedProc(clientData)  FrameCmdDeletedProc(clientData)
876      ClientData clientData;      /* Pointer to widget record for widget. */      ClientData clientData;      /* Pointer to widget record for widget. */
877  {  {
878      Frame *framePtr = (Frame *) clientData;      Frame *framePtr = (Frame *) clientData;
879      Tk_Window tkwin = framePtr->tkwin;      Tk_Window tkwin = framePtr->tkwin;
880    
881      if (framePtr->menuName != NULL) {      if (framePtr->menuName != NULL) {
882          TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,          TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
883                  framePtr->menuName, NULL);                  framePtr->menuName, NULL);
884          ckfree(framePtr->menuName);          ckfree(framePtr->menuName);
885          framePtr->menuName = NULL;          framePtr->menuName = NULL;
886      }      }
887    
888      /*      /*
889       * This procedure could be invoked either because the window was       * This procedure could be invoked either because the window was
890       * destroyed and the command was then deleted (in which case tkwin       * destroyed and the command was then deleted (in which case tkwin
891       * is NULL) or because the command was deleted, and then this procedure       * is NULL) or because the command was deleted, and then this procedure
892       * destroys the widget.       * destroys the widget.
893       */       */
894    
895      if (tkwin != NULL) {      if (tkwin != NULL) {
896          framePtr->tkwin = NULL;          framePtr->tkwin = NULL;
897          Tk_DestroyWindow(tkwin);          Tk_DestroyWindow(tkwin);
898      }      }
899  }  }
900    
901  /*  /*
902   *----------------------------------------------------------------------   *----------------------------------------------------------------------
903   *   *
904   * MapFrame --   * MapFrame --
905   *   *
906   *      This procedure is invoked as a when-idle handler to map a   *      This procedure is invoked as a when-idle handler to map a
907   *      newly-created top-level frame.   *      newly-created top-level frame.
908   *   *
909   * Results:   * Results:
910   *      None.   *      None.
911   *   *
912   * Side effects:   * Side effects:
913   *      The frame given by the clientData argument is mapped.   *      The frame given by the clientData argument is mapped.
914   *   *
915   *----------------------------------------------------------------------   *----------------------------------------------------------------------
916   */   */
917    
918  static void  static void
919  MapFrame(clientData)  MapFrame(clientData)
920      ClientData clientData;              /* Pointer to frame structure. */      ClientData clientData;              /* Pointer to frame structure. */
921  {  {
922      Frame *framePtr = (Frame *) clientData;      Frame *framePtr = (Frame *) clientData;
923    
924      /*      /*
925       * Wait for all other background events to be processed before       * Wait for all other background events to be processed before
926       * mapping window.  This ensures that the window's correct geometry       * mapping window.  This ensures that the window's correct geometry
927       * will have been determined before it is first mapped, so that the       * will have been determined before it is first mapped, so that the
928       * window manager doesn't get a false idea of its desired geometry.       * window manager doesn't get a false idea of its desired geometry.
929       */       */
930    
931      Tcl_Preserve((ClientData) framePtr);      Tcl_Preserve((ClientData) framePtr);
932      while (1) {      while (1) {
933          if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) {          if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) {
934              break;              break;
935          }          }
936    
937          /*          /*
938           * After each event, make sure that the window still exists           * After each event, make sure that the window still exists
939           * and quit if the window has been destroyed.           * and quit if the window has been destroyed.
940           */           */
941    
942          if (framePtr->tkwin == NULL) {          if (framePtr->tkwin == NULL) {
943              Tcl_Release((ClientData) framePtr);              Tcl_Release((ClientData) framePtr);
944              return;              return;
945          }          }
946      }      }
947      Tk_MapWindow(framePtr->tkwin);      Tk_MapWindow(framePtr->tkwin);
948      Tcl_Release((ClientData) framePtr);      Tcl_Release((ClientData) framePtr);
949  }  }
950    
951  /*  /*
952   *--------------------------------------------------------------   *--------------------------------------------------------------
953   *   *
954   * TkInstallFrameMenu --   * TkInstallFrameMenu --
955   *   *
956   *      This function is needed when a Windows HWND is created   *      This function is needed when a Windows HWND is created
957   *      and a menubar has been set to the window with a system   *      and a menubar has been set to the window with a system
958   *      menu. It notifies the menu package so that the system   *      menu. It notifies the menu package so that the system
959   *      menu can be rebuilt.   *      menu can be rebuilt.
960   *   *
961   * Results:   * Results:
962   *      None.   *      None.
963   *   *
964   * Side effects:   * Side effects:
965   *      The system menu (if any) is created for the menubar   *      The system menu (if any) is created for the menubar
966   *      associated with this frame.   *      associated with this frame.
967   *   *
968   *--------------------------------------------------------------   *--------------------------------------------------------------
969   */   */
970    
971  void  void
972  TkInstallFrameMenu(tkwin)  TkInstallFrameMenu(tkwin)
973      Tk_Window tkwin;            /* The window that was just created. */      Tk_Window tkwin;            /* The window that was just created. */
974  {  {
975      TkWindow *winPtr = (TkWindow *) tkwin;      TkWindow *winPtr = (TkWindow *) tkwin;
976    
977      if (winPtr->mainPtr != NULL) {      if (winPtr->mainPtr != NULL) {
978          Frame *framePtr;          Frame *framePtr;
979          framePtr = (Frame*) winPtr->instanceData;          framePtr = (Frame*) winPtr->instanceData;
980          if (framePtr == NULL) {          if (framePtr == NULL) {
981              panic("TkInstallFrameMenu couldn't get frame pointer");              panic("TkInstallFrameMenu couldn't get frame pointer");
982          }          }
983          TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp,          TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp,
984                  framePtr->menuName);                  framePtr->menuName);
985      }      }
986  }  }
987    
988  /* End of tkframe.c */  /* End of tkframe.c */

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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25