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

Annotation of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkframe.c

Parent Directory Parent Directory | Revision Log Revision Log


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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25