diff options
Diffstat (limited to 'tk8.6/generic/tkFrame.c')
-rw-r--r-- | tk8.6/generic/tkFrame.c | 2038 |
1 files changed, 0 insertions, 2038 deletions
diff --git a/tk8.6/generic/tkFrame.c b/tk8.6/generic/tkFrame.c deleted file mode 100644 index 0f1a1b3..0000000 --- a/tk8.6/generic/tkFrame.c +++ /dev/null @@ -1,2038 +0,0 @@ -/* - * tkFrame.c -- - * - * This module implements "frame", "labelframe" and "toplevel" widgets - * for the Tk toolkit. Frames are windows with a background color and - * possibly a 3-D effect, but not much else in the way of attributes. - * - * Copyright (c) 1990-1994 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "default.h" -#include "tkInt.h" - -/* - * The following enum is used to define the type of the frame. - */ - -enum FrameType { - TYPE_FRAME, TYPE_TOPLEVEL, TYPE_LABELFRAME -}; - -/* - * A data structure of the following type is kept for each - * frame that currently exists for this process: - */ - -typedef struct { - Tk_Window tkwin; /* Window that embodies the frame. NULL means - * that the window has been destroyed but the - * data structures haven't yet been cleaned - * up. */ - Display *display; /* Display containing widget. Used, among - * other things, so that resources can be - * freed even after tkwin has gone away. */ - Tcl_Interp *interp; /* Interpreter associated with widget. Used to - * delete widget command. */ - Tcl_Command widgetCmd; /* Token for frame's widget command. */ - Tk_OptionTable optionTable; /* Table that defines configuration options - * available for this widget. */ - char *className; /* Class name for widget (from configuration - * option). Malloc-ed. */ - enum FrameType type; /* Type of widget, such as TYPE_FRAME. */ - char *screenName; /* Screen on which widget is created. Non-null - * only for top-levels. Malloc-ed, may be - * NULL. */ - char *visualName; /* Textual description of visual for window, - * from -visual option. Malloc-ed, may be - * NULL. */ - char *colormapName; /* Textual description of colormap for window, - * from -colormap option. Malloc-ed, may be - * NULL. */ - char *menuName; /* Textual description of menu to use for - * menubar. Malloc-ed, may be NULL. */ - Colormap colormap; /* If not None, identifies a colormap - * allocated for this window, which must be - * freed when the window is deleted. */ - Tk_3DBorder border; /* Structure used to draw 3-D border and - * background. NULL means no background or - * border. */ - int borderWidth; /* Width of 3-D border (if any). */ - int relief; /* 3-d effect: TK_RELIEF_RAISED etc. */ - int highlightWidth; /* Width in pixels of highlight to draw around - * widget when it has the focus. 0 means don't - * draw a highlight. */ - XColor *highlightBgColorPtr; - /* Color for drawing traversal highlight area - * when highlight is off. */ - XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ - int width; /* Width to request for window. <= 0 means - * don't request any size. */ - int height; /* Height to request for window. <= 0 means - * don't request any size. */ - Tk_Cursor cursor; /* Current cursor for window, or None. */ - char *takeFocus; /* Value of -takefocus option; not used in the - * C code, but used by keyboard traversal - * scripts. Malloc'ed, but may be NULL. */ - int isContainer; /* 1 means this window is a container, 0 means - * that it isn't. */ - char *useThis; /* If the window is embedded, this points to - * the name of the window in which it is - * embedded (malloc'ed). For non-embedded - * windows this is NULL. */ - int flags; /* Various flags; see below for - * definitions. */ - Tcl_Obj *padXPtr; /* Value of -padx option: specifies how many - * pixels of extra space to leave on left and - * right of child area. */ - int padX; /* Integer value corresponding to padXPtr. */ - Tcl_Obj *padYPtr; /* Value of -padx option: specifies how many - * pixels of extra space to leave above and - * below child area. */ - int padY; /* Integer value corresponding to padYPtr. */ -} Frame; - -/* - * A data structure of the following type is kept for each labelframe widget - * managed by this file: - */ - -typedef struct { - Frame frame; /* A pointer to the generic frame structure. - * This must be the first element of the - * Labelframe. */ - /* - * Labelframe specific configuration settings. - */ - Tcl_Obj *textPtr; /* Value of -text option: specifies text to - * display in button. */ - Tk_Font tkfont; /* Value of -font option: specifies font to - * use for display text. */ - XColor *textColorPtr; /* Value of -fg option: specifies foreground - * color in normal mode. */ - int labelAnchor; /* Value of -labelanchor option: specifies - * where to place the label. */ - Tk_Window labelWin; /* Value of -labelwidget option: Window to use - * as label for the frame. */ - /* - * Labelframe specific fields for use with configuration settings above. - */ - GC textGC; /* GC for drawing text in normal mode. */ - Tk_TextLayout textLayout; /* Stored text layout information. */ - XRectangle labelBox; /* The label's actual size and position. */ - int labelReqWidth; /* The label's requested width. */ - int labelReqHeight; /* The label's requested height. */ - int labelTextX, labelTextY; /* Position of the text to be drawn. */ -} Labelframe; - -/* - * The following macros define how many extra pixels to leave around a label's - * text. - */ - -#define LABELSPACING 1 -#define LABELMARGIN 4 - -/* - * Flag bits for frames: - * - * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has - * already been queued to redraw this window. - * GOT_FOCUS: Non-zero means this widget currently has the - * input focus. - */ - -#define REDRAW_PENDING 1 -#define GOT_FOCUS 4 - -/* - * The following enum is used to define a type for the -labelanchor option of - * the Labelframe widget. These values are used as indices into the string - * table below. - */ - -enum labelanchor { - LABELANCHOR_E, LABELANCHOR_EN, LABELANCHOR_ES, - LABELANCHOR_N, LABELANCHOR_NE, LABELANCHOR_NW, - LABELANCHOR_S, LABELANCHOR_SE, LABELANCHOR_SW, - LABELANCHOR_W, LABELANCHOR_WN, LABELANCHOR_WS -}; - -static const char *const labelAnchorStrings[] = { - "e", "en", "es", "n", "ne", "nw", "s", "se", "sw", "w", "wn", "ws", - NULL -}; - -/* - * Information used for parsing configuration options. There are one common - * table used by all and one table for each widget class. - */ - -static const Tk_OptionSpec commonOptSpec[] = { - {TK_OPTION_BORDER, "-background", "background", "Background", - DEF_FRAME_BG_COLOR, -1, Tk_Offset(Frame, border), - TK_OPTION_NULL_OK, DEF_FRAME_BG_MONO, 0}, - {TK_OPTION_SYNONYM, "-bg", NULL, NULL, - NULL, 0, -1, 0, "-background", 0}, - {TK_OPTION_STRING, "-colormap", "colormap", "Colormap", - DEF_FRAME_COLORMAP, -1, Tk_Offset(Frame, colormapName), - TK_OPTION_NULL_OK, 0, 0}, - /* - * Having -container is useless in a labelframe since a container has - * no border. It should be deprecated. - */ - {TK_OPTION_BOOLEAN, "-container", "container", "Container", - DEF_FRAME_CONTAINER, -1, Tk_Offset(Frame, isContainer), 0, 0, 0}, - {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", - DEF_FRAME_CURSOR, -1, Tk_Offset(Frame, cursor), - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_PIXELS, "-height", "height", "Height", - DEF_FRAME_HEIGHT, -1, Tk_Offset(Frame, height), 0, 0, 0}, - {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", - "HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, -1, - Tk_Offset(Frame, highlightBgColorPtr), 0, 0, 0}, - {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", - DEF_FRAME_HIGHLIGHT, -1, Tk_Offset(Frame, highlightColorPtr), - 0, 0, 0}, - {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, -1, - Tk_Offset(Frame, highlightWidth), 0, 0, 0}, - {TK_OPTION_PIXELS, "-padx", "padX", "Pad", - DEF_FRAME_PADX, Tk_Offset(Frame, padXPtr), - Tk_Offset(Frame, padX), 0, 0, 0}, - {TK_OPTION_PIXELS, "-pady", "padY", "Pad", - DEF_FRAME_PADY, Tk_Offset(Frame, padYPtr), - Tk_Offset(Frame, padY), 0, 0, 0}, - {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_FRAME_TAKE_FOCUS, -1, Tk_Offset(Frame, takeFocus), - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-visual", "visual", "Visual", - DEF_FRAME_VISUAL, -1, Tk_Offset(Frame, visualName), - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_PIXELS, "-width", "width", "Width", - DEF_FRAME_WIDTH, -1, Tk_Offset(Frame, width), 0, 0, 0}, - {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} -}; - -static const Tk_OptionSpec frameOptSpec[] = { - {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, "-borderwidth", 0}, - {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0}, - {TK_OPTION_STRING, "-class", "class", "Class", - DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, - {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0}, - {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, 0, 0, commonOptSpec, 0} -}; - -static const Tk_OptionSpec toplevelOptSpec[] = { - {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, "-borderwidth", 0}, - {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0}, - {TK_OPTION_STRING, "-class", "class", "Class", - DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, - {TK_OPTION_STRING, "-menu", "menu", "Menu", - DEF_TOPLEVEL_MENU, -1, Tk_Offset(Frame, menuName), - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0}, - {TK_OPTION_STRING, "-screen", "screen", "Screen", - DEF_TOPLEVEL_SCREEN, -1, Tk_Offset(Frame, screenName), - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-use", "use", "Use", - DEF_TOPLEVEL_USE, -1, Tk_Offset(Frame, useThis), - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, 0, 0, commonOptSpec, 0} -}; - -static const Tk_OptionSpec labelframeOptSpec[] = { - {TK_OPTION_SYNONYM, "-bd", NULL, NULL, - NULL, 0, -1, 0, "-borderwidth", 0}, - {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_LABELFRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), - 0, 0, 0}, - {TK_OPTION_STRING, "-class", "class", "Class", - DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, - {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, - NULL, 0, -1, 0, "-foreground", 0}, - {TK_OPTION_FONT, "-font", "font", "Font", - DEF_LABELFRAME_FONT, -1, Tk_Offset(Labelframe, tkfont), 0, 0, 0}, - {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", - DEF_LABELFRAME_FG, -1, Tk_Offset(Labelframe, textColorPtr), 0, 0, 0}, - {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor", - DEF_LABELFRAME_LABELANCHOR, -1, Tk_Offset(Labelframe, labelAnchor), - 0, labelAnchorStrings, 0}, - {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", - NULL, -1, Tk_Offset(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_LABELFRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0}, - {TK_OPTION_STRING, "-text", "text", "Text", - DEF_LABELFRAME_TEXT, Tk_Offset(Labelframe, textPtr), -1, - TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_END, NULL, NULL, NULL, - NULL, 0, 0, 0, commonOptSpec, 0} -}; - -/* - * Class names for widgets, indexed by FrameType. - */ - -static const char *const classNames[] = {"Frame", "Toplevel", "Labelframe"}; - -/* - * The following table maps from FrameType to the option template for that - * class of widgets. - */ - -static const Tk_OptionSpec *const optionSpecs[] = { - frameOptSpec, - toplevelOptSpec, - labelframeOptSpec, -}; - -/* - * Forward declarations for functions defined later in this file: - */ - -static void ComputeFrameGeometry(Frame *framePtr); -static int ConfigureFrame(Tcl_Interp *interp, Frame *framePtr, - int objc, Tcl_Obj *const objv[]); -static int CreateFrame(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const argv[], - enum FrameType type, const char *appName); -static void DestroyFrame(void *memPtr); -static void DestroyFramePartly(Frame *framePtr); -static void DisplayFrame(ClientData clientData); -static void FrameCmdDeletedProc(ClientData clientData); -static void FrameEventProc(ClientData clientData, - XEvent *eventPtr); -static void FrameLostSlaveProc(ClientData clientData, - Tk_Window tkwin); -static void FrameRequestProc(ClientData clientData, - Tk_Window tkwin); -static void FrameStructureProc(ClientData clientData, - XEvent *eventPtr); -static int FrameWidgetObjCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); -static void FrameWorldChanged(ClientData instanceData); -static void MapFrame(ClientData clientData); - -/* - * The structure below defines frame class behavior by means of functions that - * can be invoked from generic window code. - */ - -static const Tk_ClassProcs frameClass = { - sizeof(Tk_ClassProcs), /* size */ - FrameWorldChanged, /* worldChangedProc */ - NULL, /* createProc */ - NULL /* modalProc */ -}; - -/* - * The structure below defines the official type record for the labelframe's - * geometry manager: - */ - -static const Tk_GeomMgr frameGeomType = { - "labelframe", /* name */ - FrameRequestProc, /* requestProc */ - FrameLostSlaveProc /* lostSlaveProc */ -}; - -/* - *-------------------------------------------------------------- - * - * Tk_FrameObjCmd, Tk_ToplevelObjCmd, Tk_LabelframeObjCmd -- - * - * These functions are invoked to process the "frame", "toplevel" and - * "labelframe" Tcl commands. See the user documentation for details on - * what they do. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. These functions are just wrappers; they - * call CreateFrame to do all of the real work. - * - *-------------------------------------------------------------- - */ - -int -Tk_FrameObjCmd( - ClientData clientData, /* Either NULL or pointer to option table. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME, NULL); -} - -int -Tk_ToplevelObjCmd( - ClientData clientData, /* Either NULL or pointer to option table. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, NULL); -} - -int -Tk_LabelframeObjCmd( - ClientData clientData, /* Either NULL or pointer to option table. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - return CreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME, NULL); -} - -/* - *-------------------------------------------------------------- - * - * TkCreateFrame -- - * - * This function is the old command function for the "frame" and - * "toplevel" commands. Now it is used directly by Tk_Init to create a - * new main window. See the user documentation for the "frame" and - * "toplevel" commands for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *-------------------------------------------------------------- - */ - -int -TkCreateFrame( - ClientData clientData, /* Either NULL or pointer to option table. */ - Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char *const *argv, /* Argument strings. */ - int toplevel, /* Non-zero means create a toplevel window, - * zero means create a frame. */ - const char *appName) /* Should only be non-NULL if there is no main - * window associated with the interpreter. - * Gives the base name to use for the new - * application. */ -{ - int result, i; - Tcl_Obj **objv = ckalloc((argc+1) * sizeof(Tcl_Obj **)); - - for (i=0; i<argc; i++) { - objv[i] = Tcl_NewStringObj(argv[i], -1); - Tcl_IncrRefCount(objv[i]); - } - objv[argc] = NULL; - result = CreateFrame(clientData, interp, argc, objv, - toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, appName); - for (i=0; i<argc; i++) { - Tcl_DecrRefCount(objv[i]); - } - ckfree(objv); - return result; -} - -int -TkListCreateFrame( - ClientData clientData, /* Either NULL or pointer to option table. */ - Tcl_Interp *interp, /* Current interpreter. */ - Tcl_Obj *listObj, /* List of arguments. */ - int toplevel, /* Non-zero means create a toplevel window, - * zero means create a frame. */ - Tcl_Obj *nameObj) /* Should only be non-NULL if there is no main - * window associated with the interpreter. - * Gives the base name to use for the new - * application. */ -{ - int objc; - Tcl_Obj **objv; - - if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) { - return TCL_ERROR; - } - return CreateFrame(clientData, interp, objc, objv, - toplevel ? TYPE_TOPLEVEL : TYPE_FRAME, - nameObj ? Tcl_GetString(nameObj) : NULL); -} - -static int -CreateFrame( - ClientData clientData, /* NULL. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[], /* Argument objects. */ - enum FrameType type, /* What widget type to create. */ - const char *appName) /* Should only be non-NULL if there are no - * Main window associated with the - * interpreter. Gives the base name to use for - * the new application. */ -{ - Tk_Window tkwin; - Frame *framePtr; - Tk_OptionTable optionTable; - Tk_Window newWin; - const char *className, *screenName, *visualName, *colormapName; - const char *arg, *useOption; - int i, length, depth; - unsigned int mask; - Colormap colormap; - Visual *visual; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?"); - return TCL_ERROR; - } - - /* - * Create the option table for this widget class. If it has already been - * created, the cached pointer will be returned. - */ - - optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]); - - /* - * Pre-process the argument list. Scan through it to find any "-class", - * "-screen", "-visual", and "-colormap" options. These arguments need to - * be processed specially, before the window is configured using the usual - * Tk mechanisms. - */ - - className = colormapName = screenName = visualName = useOption = NULL; - colormap = None; - for (i = 2; i < objc; i += 2) { - arg = Tcl_GetStringFromObj(objv[i], &length); - if (length < 2) { - continue; - } - if ((arg[1] == 'c') && (length >= 3) - && (strncmp(arg, "-class", (unsigned) length) == 0)) { - className = Tcl_GetString(objv[i+1]); - } else if ((arg[1] == 'c') && (length >= 3) - && (strncmp(arg, "-colormap", (unsigned) length) == 0)) { - colormapName = Tcl_GetString(objv[i+1]); - } else if ((arg[1] == 's') && (type == TYPE_TOPLEVEL) - && (strncmp(arg, "-screen", (unsigned) length) == 0)) { - screenName = Tcl_GetString(objv[i+1]); - } else if ((arg[1] == 'u') && (type == TYPE_TOPLEVEL) - && (strncmp(arg, "-use", (unsigned) length) == 0)) { - useOption = Tcl_GetString(objv[i+1]); - } else if ((arg[1] == 'v') - && (strncmp(arg, "-visual", (unsigned) length) == 0)) { - visualName = Tcl_GetString(objv[i+1]); - } - } - - /* - * Create the window, and deal with the special options -use, -classname, - * -colormap, -screenname, and -visual. These options must be handle - * before calling ConfigureFrame below, and they must also be processed in - * a particular order, for the following reasons: - * 1. Must set the window's class before calling ConfigureFrame, so that - * unspecified options are looked up in the option database using the - * correct class. - * 2. Must set visual information before calling ConfigureFrame so that - * colors are allocated in a proper colormap. - * 3. Must call TkpUseWindow before setting non-default visual - * information, since TkpUseWindow changes the defaults. - */ - - if (screenName == NULL) { - screenName = (type == TYPE_TOPLEVEL) ? "" : NULL; - } - - /* - * Main window associated with interpreter. If we're called by Tk_Init to - * create a new application, then this is NULL. - */ - - tkwin = Tk_MainWindow(interp); - if (tkwin != NULL) { - newWin = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), - screenName); - } else if (appName == NULL) { - /* - * This occurs when someone tried to create a frame/toplevel while we - * are being destroyed. Let an error be thrown. - */ - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unable to create widget \"%s\"", Tcl_GetString(objv[1]))); - Tcl_SetErrorCode(interp, "TK", "APPLICATION_GONE", NULL); - return TCL_ERROR; - } else { - /* - * We were called from Tk_Init; create a new application. - */ - - newWin = TkCreateMainWindow(interp, screenName, appName); - } - if (newWin == NULL) { - goto error; - } - - /* - * Mark Tk frames as suitable candidates for [wm manage]. - */ - - ((TkWindow *) newWin)->flags |= TK_WM_MANAGEABLE; - - if (className == NULL) { - className = Tk_GetOption(newWin, "class", "Class"); - if (className == NULL) { - className = classNames[type]; - } - } - Tk_SetClass(newWin, className); - if (useOption == NULL) { - useOption = Tk_GetOption(newWin, "use", "Use"); - } - if ((useOption != NULL) && (*useOption != 0) - && (TkpUseWindow(interp, newWin, useOption) != TCL_OK)) { - goto error; - } - if (visualName == NULL) { - visualName = Tk_GetOption(newWin, "visual", "Visual"); - } - if (colormapName == NULL) { - colormapName = Tk_GetOption(newWin, "colormap", "Colormap"); - } - if ((colormapName != NULL) && (*colormapName == 0)) { - colormapName = NULL; - } - if (visualName != NULL) { - visual = Tk_GetVisual(interp, newWin, visualName, &depth, - (colormapName == NULL) ? &colormap : NULL); - if (visual == NULL) { - goto error; - } - Tk_SetWindowVisual(newWin, visual, depth, colormap); - } - if (colormapName != NULL) { - colormap = Tk_GetColormap(interp, newWin, colormapName); - if (colormap == None) { - goto error; - } - Tk_SetWindowColormap(newWin, colormap); - } - - /* - * For top-level windows, provide an initial geometry request of 200x200, - * just so the window looks nicer on the screen if it doesn't request a - * size for itself. - */ - - if (type == TYPE_TOPLEVEL) { - Tk_GeometryRequest(newWin, 200, 200); - } - - /* - * Create the widget record, process configuration options, and create - * event handlers. Then fill in a few additional fields in the widget - * record from the special options. - */ - - if (type == TYPE_LABELFRAME) { - framePtr = ckalloc(sizeof(Labelframe)); - memset(framePtr, 0, sizeof(Labelframe)); - } else { - framePtr = ckalloc(sizeof(Frame)); - memset(framePtr, 0, sizeof(Frame)); - } - framePtr->tkwin = newWin; - framePtr->display = Tk_Display(newWin); - framePtr->interp = interp; - framePtr->widgetCmd = Tcl_CreateObjCommand(interp, Tk_PathName(newWin), - FrameWidgetObjCmd, framePtr, FrameCmdDeletedProc); - framePtr->optionTable = optionTable; - framePtr->type = type; - framePtr->colormap = colormap; - framePtr->relief = TK_RELIEF_FLAT; - framePtr->cursor = None; - - if (framePtr->type == TYPE_LABELFRAME) { - Labelframe *labelframePtr = (Labelframe *) framePtr; - - labelframePtr->labelAnchor = LABELANCHOR_NW; - labelframePtr->textGC = None; - } - - /* - * Store backreference to frame widget in window structure. - */ - - Tk_SetClassProcs(newWin, &frameClass, framePtr); - - mask = ExposureMask | StructureNotifyMask | FocusChangeMask; - if (type == TYPE_TOPLEVEL) { - mask |= ActivateMask; - } - Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr); - if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, newWin) - != TCL_OK) || - (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) { - goto error; - } - if (framePtr->isContainer) { - if (framePtr->useThis != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "windows cannot have both the -use and the -container" - " option set", -1)); - Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL); - goto error; - } - TkpMakeContainer(framePtr->tkwin); - } - if (type == TYPE_TOPLEVEL) { - Tcl_DoWhenIdle(MapFrame, framePtr); - } - Tcl_SetObjResult(interp, TkNewWindowObj(newWin)); - return TCL_OK; - - error: - if (newWin != NULL) { - Tk_DestroyWindow(newWin); - } - return TCL_ERROR; -} - -/* - *-------------------------------------------------------------- - * - * FrameWidgetObjCmd -- - * - * This function is invoked to process the Tcl command that corresponds - * to a frame widget. See the user documentation for details on what it - * does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *-------------------------------------------------------------- - */ - -static int -FrameWidgetObjCmd( - ClientData clientData, /* Information about frame widget. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - static const char *const frameOptions[] = { - "cget", "configure", NULL - }; - enum options { - FRAME_CGET, FRAME_CONFIGURE - }; - register Frame *framePtr = clientData; - int result = TCL_OK, index; - int c, i, length; - Tcl_Obj *objPtr; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); - return TCL_ERROR; - } - if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions, - sizeof(char *), "option", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - Tcl_Preserve(framePtr); - switch ((enum options) index) { - case FRAME_CGET: - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option"); - result = TCL_ERROR; - goto done; - } - objPtr = Tk_GetOptionValue(interp, (char *) framePtr, - framePtr->optionTable, objv[2], framePtr->tkwin); - if (objPtr == NULL) { - result = TCL_ERROR; - goto done; - } - Tcl_SetObjResult(interp, objPtr); - break; - case FRAME_CONFIGURE: - if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) framePtr, - framePtr->optionTable, (objc == 3) ? objv[2] : NULL, - framePtr->tkwin); - if (objPtr == NULL) { - result = TCL_ERROR; - goto done; - } - Tcl_SetObjResult(interp, objPtr); - } else { - /* - * Don't allow the options -class, -colormap, -container, -screen, - * -use, or -visual to be changed. - */ - - for (i = 2; i < objc; i++) { - const char *arg = Tcl_GetStringFromObj(objv[i], &length); - - if (length < 2) { - continue; - } - c = arg[1]; - if (((c == 'c') && (length >= 2) - && (strncmp(arg, "-class", (unsigned)length) == 0)) - || ((c == 'c') && (length >= 3) - && (strncmp(arg, "-colormap", (unsigned)length) == 0)) - || ((c == 'c') && (length >= 3) - && (strncmp(arg, "-container", (unsigned)length) == 0)) - || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL) - && (strncmp(arg, "-screen", (unsigned)length) == 0)) - || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL) - && (strncmp(arg, "-use", (unsigned)length) == 0)) - || ((c == 'v') - && (strncmp(arg, "-visual", (unsigned)length) == 0))) { - -#ifdef SUPPORT_CONFIG_EMBEDDED - if (c == 'u') { - const char *string = Tcl_GetString(objv[i+1]); - - if (TkpUseWindow(interp, framePtr->tkwin, - string) != TCL_OK) { - result = TCL_ERROR; - goto done; - } - continue; - } -#endif - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't modify %s option after widget is created", - arg)); - Tcl_SetErrorCode(interp, "TK", "FRAME", "CREATE_ONLY", - NULL); - result = TCL_ERROR; - goto done; - } - } - result = ConfigureFrame(interp, framePtr, objc-2, objv+2); - } - break; - } - - done: - Tcl_Release(framePtr); - return result; -} - -/* - *---------------------------------------------------------------------- - * - * DestroyFrame -- - * - * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean - * up the internal structure of a frame at a safe time (when no-one is - * using it anymore). - * - * Results: - * None. - * - * Side effects: - * Everything associated with the frame is freed up. - * - *---------------------------------------------------------------------- - */ - -static void -DestroyFrame( - void *memPtr) /* Info about frame widget. */ -{ - register Frame *framePtr = memPtr; - register Labelframe *labelframePtr = memPtr; - - if (framePtr->type == TYPE_LABELFRAME) { - Tk_FreeTextLayout(labelframePtr->textLayout); - if (labelframePtr->textGC != None) { - Tk_FreeGC(framePtr->display, labelframePtr->textGC); - } - } - if (framePtr->colormap != None) { - Tk_FreeColormap(framePtr->display, framePtr->colormap); - } - ckfree(framePtr); -} - -/* - *---------------------------------------------------------------------- - * - * DestroyFramePartly -- - * - * This function is invoked to clean up everything that needs tkwin to be - * defined when deleted. During the destruction process tkwin is always - * set to NULL and this function must be called before that happens. - * - * Results: - * None. - * - * Side effects: - * Some things associated with the frame are freed up. - * - *---------------------------------------------------------------------- - */ - -static void -DestroyFramePartly( - Frame *framePtr) /* Info about frame widget. */ -{ - register Labelframe *labelframePtr = (Labelframe *) framePtr; - - if (framePtr->type == TYPE_LABELFRAME && labelframePtr->labelWin != NULL) { - Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask, - FrameStructureProc, framePtr); - Tk_ManageGeometry(labelframePtr->labelWin, NULL, NULL); - if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) { - Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin); - } - Tk_UnmapWindow(labelframePtr->labelWin); - labelframePtr->labelWin = NULL; - } - - Tk_FreeConfigOptions((char *) framePtr, framePtr->optionTable, - framePtr->tkwin); -} - -/* - *---------------------------------------------------------------------- - * - * ConfigureFrame -- - * - * This function is called to process an objv/objc list, plus the Tk - * option database, in order to configure (or reconfigure) a frame - * widget. - * - * Results: - * The return value is a standard Tcl result. If TCL_ERROR is returned, - * then the interp's result contains an error message. - * - * Side effects: - * Configuration information, such as text string, colors, font, etc. get - * set for framePtr; old resources get freed, if there were any. - * - *---------------------------------------------------------------------- - */ - -static int -ConfigureFrame( - Tcl_Interp *interp, /* Used for error reporting. */ - register Frame *framePtr, /* Information about widget; may or may not - * already have values for some fields. */ - int objc, /* Number of valid entries in objv. */ - Tcl_Obj *const objv[]) /* Arguments. */ -{ - Tk_SavedOptions savedOptions; - char *oldMenuName; - Tk_Window oldWindow = NULL; - Labelframe *labelframePtr = (Labelframe *) framePtr; - - /* - * Need the old menubar name for the menu code to delete it. - */ - - if (framePtr->menuName == NULL) { - oldMenuName = NULL; - } else { - oldMenuName = ckalloc(strlen(framePtr->menuName) + 1); - strcpy(oldMenuName, framePtr->menuName); - } - - if (framePtr->type == TYPE_LABELFRAME) { - oldWindow = labelframePtr->labelWin; - } - if (Tk_SetOptions(interp, (char *) framePtr, - framePtr->optionTable, objc, objv, - framePtr->tkwin, &savedOptions, NULL) != TCL_OK) { - if (oldMenuName != NULL) { - ckfree(oldMenuName); - } - return TCL_ERROR; - } - Tk_FreeSavedOptions(&savedOptions); - - /* - * A few of the options require additional processing. - */ - - if ((((oldMenuName == NULL) && (framePtr->menuName != NULL)) - || ((oldMenuName != NULL) && (framePtr->menuName == NULL)) - || ((oldMenuName != NULL) && (framePtr->menuName != NULL) - && strcmp(oldMenuName, framePtr->menuName) != 0)) - && framePtr->type == TYPE_TOPLEVEL) { - TkSetWindowMenuBar(interp, framePtr->tkwin, oldMenuName, - framePtr->menuName); - } - - if (oldMenuName != NULL) { - ckfree(oldMenuName); - } - - if (framePtr->border != NULL) { - Tk_SetBackgroundFromBorder(framePtr->tkwin, framePtr->border); - } else { - Tk_SetWindowBackgroundPixmap(framePtr->tkwin, None); - } - - if (framePtr->highlightWidth < 0) { - framePtr->highlightWidth = 0; - } - if (framePtr->padX < 0) { - framePtr->padX = 0; - } - if (framePtr->padY < 0) { - framePtr->padY = 0; - } - - /* - * If a -labelwidget is specified, check that it is valid and set up - * geometry management for it. - */ - - if (framePtr->type == TYPE_LABELFRAME) { - if (oldWindow != labelframePtr->labelWin) { - if (oldWindow != NULL) { - Tk_DeleteEventHandler(oldWindow, StructureNotifyMask, - FrameStructureProc, framePtr); - Tk_ManageGeometry(oldWindow, NULL, NULL); - Tk_UnmaintainGeometry(oldWindow, framePtr->tkwin); - Tk_UnmapWindow(oldWindow); - } - if (labelframePtr->labelWin != NULL) { - Tk_Window ancestor, parent, sibling = NULL; - - /* - * Make sure that the frame is either the parent of the window - * used as label or a descendant of that parent. Also, don't - * allow a top-level window to be managed inside the frame. - */ - - parent = Tk_Parent(labelframePtr->labelWin); - for (ancestor = framePtr->tkwin; ; - ancestor = Tk_Parent(ancestor)) { - if (ancestor == parent) { - break; - } - sibling = ancestor; - if (Tk_IsTopLevel(ancestor)) { - goto badLabelWindow; - } - } - if (Tk_IsTopLevel(labelframePtr->labelWin)) { - goto badLabelWindow; - } - if (labelframePtr->labelWin == framePtr->tkwin) { - goto badLabelWindow; - } - Tk_CreateEventHandler(labelframePtr->labelWin, - StructureNotifyMask, FrameStructureProc, framePtr); - Tk_ManageGeometry(labelframePtr->labelWin, &frameGeomType, - framePtr); - - /* - * If the frame is not parent to the label, make sure the - * label is above its sibling in the stacking order. - */ - - if (sibling != NULL) { - Tk_RestackWindow(labelframePtr->labelWin, Above, sibling); - } - } - } - } - - FrameWorldChanged(framePtr); - return TCL_OK; - - badLabelWindow: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use %s as label in this frame", - Tk_PathName(labelframePtr->labelWin))); - Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL); - labelframePtr->labelWin = NULL; - return TCL_ERROR; -} - -/* - *--------------------------------------------------------------------------- - * - * FrameWorldChanged -- - * - * This function is called when the world has changed in some way and the - * widget needs to recompute all its graphics contexts and determine its - * new geometry. - * - * Results: - * None. - * - * Side effects: - * Frame will be relayed out and redisplayed. - * - *--------------------------------------------------------------------------- - */ - -static void -FrameWorldChanged( - ClientData instanceData) /* Information about widget. */ -{ - Frame *framePtr = instanceData; - Labelframe *labelframePtr = instanceData; - Tk_Window tkwin = framePtr->tkwin; - XGCValues gcValues; - GC gc; - int anyTextLabel, anyWindowLabel; - int bWidthLeft, bWidthRight, bWidthTop, bWidthBottom; - const char *labelText; - - anyTextLabel = (framePtr->type == TYPE_LABELFRAME) && - (labelframePtr->textPtr != NULL) && - (labelframePtr->labelWin == NULL); - anyWindowLabel = (framePtr->type == TYPE_LABELFRAME) && - (labelframePtr->labelWin != NULL); - - if (framePtr->type == TYPE_LABELFRAME) { - /* - * The textGC is needed even in the labelWin case, so it's always - * created for a labelframe. - */ - - gcValues.font = Tk_FontId(labelframePtr->tkfont); - gcValues.foreground = labelframePtr->textColorPtr->pixel; - gcValues.graphics_exposures = False; - gc = Tk_GetGC(tkwin, GCForeground | GCFont | GCGraphicsExposures, - &gcValues); - if (labelframePtr->textGC != None) { - Tk_FreeGC(framePtr->display, labelframePtr->textGC); - } - labelframePtr->textGC = gc; - - /* - * Calculate label size. - */ - - labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0; - - if (anyTextLabel) { - labelText = Tcl_GetString(labelframePtr->textPtr); - Tk_FreeTextLayout(labelframePtr->textLayout); - labelframePtr->textLayout = - Tk_ComputeTextLayout(labelframePtr->tkfont, - labelText, -1, 0, TK_JUSTIFY_CENTER, 0, - &labelframePtr->labelReqWidth, - &labelframePtr->labelReqHeight); - labelframePtr->labelReqWidth += 2 * LABELSPACING; - labelframePtr->labelReqHeight += 2 * LABELSPACING; - } else if (anyWindowLabel) { - labelframePtr->labelReqWidth = Tk_ReqWidth(labelframePtr->labelWin); - labelframePtr->labelReqHeight = - Tk_ReqHeight(labelframePtr->labelWin); - } - - /* - * Make sure label size is at least as big as the border. This - * simplifies later calculations and gives a better appearance with - * thick borders. - */ - - if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && - (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { - if (labelframePtr->labelReqHeight < framePtr->borderWidth) { - labelframePtr->labelReqHeight = framePtr->borderWidth; - } - } else { - if (labelframePtr->labelReqWidth < framePtr->borderWidth) { - labelframePtr->labelReqWidth = framePtr->borderWidth; - } - } - } - - /* - * Calculate individual border widths. - */ - - bWidthBottom = bWidthTop = bWidthRight = bWidthLeft = - framePtr->borderWidth + framePtr->highlightWidth; - - bWidthLeft += framePtr->padX; - bWidthRight += framePtr->padX; - bWidthTop += framePtr->padY; - bWidthBottom += framePtr->padY; - - if (anyTextLabel || anyWindowLabel) { - switch (labelframePtr->labelAnchor) { - case LABELANCHOR_E: - case LABELANCHOR_EN: - case LABELANCHOR_ES: - bWidthRight += labelframePtr->labelReqWidth - - framePtr->borderWidth; - break; - case LABELANCHOR_N: - case LABELANCHOR_NE: - case LABELANCHOR_NW: - bWidthTop += labelframePtr->labelReqHeight - framePtr->borderWidth; - break; - case LABELANCHOR_S: - case LABELANCHOR_SE: - case LABELANCHOR_SW: - bWidthBottom += labelframePtr->labelReqHeight - - framePtr->borderWidth; - break; - default: - bWidthLeft += labelframePtr->labelReqWidth - framePtr->borderWidth; - break; - } - } - - Tk_SetInternalBorderEx(tkwin, bWidthLeft, bWidthRight, bWidthTop, - bWidthBottom); - - ComputeFrameGeometry(framePtr); - - /* - * A labelframe should request size for its label. - */ - - if (framePtr->type == TYPE_LABELFRAME) { - int minwidth = labelframePtr->labelReqWidth; - int minheight = labelframePtr->labelReqHeight; - int padding = framePtr->highlightWidth; - - if (framePtr->borderWidth > 0) { - padding += framePtr->borderWidth + LABELMARGIN; - } - padding *= 2; - if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && - (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { - minwidth += padding; - minheight += framePtr->borderWidth + framePtr->highlightWidth; - } else { - minheight += padding; - minwidth += framePtr->borderWidth + framePtr->highlightWidth; - } - Tk_SetMinimumRequestSize(tkwin, minwidth, minheight); - } - - if ((framePtr->width > 0) || (framePtr->height > 0)) { - Tk_GeometryRequest(tkwin, framePtr->width, framePtr->height); - } - - if (Tk_IsMapped(tkwin)) { - if (!(framePtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayFrame, framePtr); - } - framePtr->flags |= REDRAW_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * ComputeFrameGeometry -- - * - * This function is called to compute various geometrical information for - * a frame, such as where various things get displayed. It's called when - * the window is reconfigured. - * - * Results: - * None. - * - * Side effects: - * Display-related numbers get changed in *framePtr. - * - *---------------------------------------------------------------------- - */ - -static void -ComputeFrameGeometry( - register Frame *framePtr) /* Information about widget. */ -{ - int otherWidth, otherHeight, otherWidthT, otherHeightT, padding; - int maxWidth, maxHeight; - Tk_Window tkwin; - Labelframe *labelframePtr = (Labelframe *) framePtr; - - /* - * We have nothing to do here unless there is a label. - */ - - if (framePtr->type != TYPE_LABELFRAME) { - return; - } - if (labelframePtr->textPtr == NULL && labelframePtr->labelWin == NULL) { - return; - } - - tkwin = framePtr->tkwin; - - /* - * Calculate the available size for the label - */ - - labelframePtr->labelBox.width = labelframePtr->labelReqWidth; - labelframePtr->labelBox.height = labelframePtr->labelReqHeight; - - padding = framePtr->highlightWidth; - if (framePtr->borderWidth > 0) { - padding += framePtr->borderWidth + LABELMARGIN; - } - padding *= 2; - - maxHeight = Tk_Height(tkwin); - maxWidth = Tk_Width(tkwin); - - if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && - (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { - maxWidth -= padding; - if (maxWidth < 1) { - maxWidth = 1; - } - } else { - maxHeight -= padding; - if (maxHeight < 1) { - maxHeight = 1; - } - } - if (labelframePtr->labelBox.width > maxWidth) { - labelframePtr->labelBox.width = maxWidth; - } - if (labelframePtr->labelBox.height > maxHeight) { - labelframePtr->labelBox.height = maxHeight; - } - - /* - * Calculate label and text position. The text's position is based on the - * requested size (= the text's real size) to get proper alignment if the - * text does not fit. - */ - - otherWidth = Tk_Width(tkwin) - labelframePtr->labelBox.width; - otherHeight = Tk_Height(tkwin) - labelframePtr->labelBox.height; - otherWidthT = Tk_Width(tkwin) - labelframePtr->labelReqWidth; - otherHeightT = Tk_Height(tkwin) - labelframePtr->labelReqHeight; - padding = framePtr->highlightWidth; - - switch (labelframePtr->labelAnchor) { - case LABELANCHOR_E: - case LABELANCHOR_EN: - case LABELANCHOR_ES: - labelframePtr->labelTextX = otherWidthT - padding; - labelframePtr->labelBox.x = otherWidth - padding; - break; - case LABELANCHOR_N: - case LABELANCHOR_NE: - case LABELANCHOR_NW: - labelframePtr->labelTextY = padding; - labelframePtr->labelBox.y = padding; - break; - case LABELANCHOR_S: - case LABELANCHOR_SE: - case LABELANCHOR_SW: - labelframePtr->labelTextY = otherHeightT - padding; - labelframePtr->labelBox.y = otherHeight - padding; - break; - default: - labelframePtr->labelTextX = padding; - labelframePtr->labelBox.x = padding; - break; - } - - if (framePtr->borderWidth > 0) { - padding += framePtr->borderWidth + LABELMARGIN; - } - - switch (labelframePtr->labelAnchor) { - case LABELANCHOR_NW: - case LABELANCHOR_SW: - labelframePtr->labelTextX = padding; - labelframePtr->labelBox.x = padding; - break; - case LABELANCHOR_N: - case LABELANCHOR_S: - labelframePtr->labelTextX = otherWidthT / 2; - labelframePtr->labelBox.x = otherWidth / 2; - break; - case LABELANCHOR_NE: - case LABELANCHOR_SE: - labelframePtr->labelTextX = otherWidthT - padding; - labelframePtr->labelBox.x = otherWidth - padding; - break; - case LABELANCHOR_EN: - case LABELANCHOR_WN: - labelframePtr->labelTextY = padding; - labelframePtr->labelBox.y = padding; - break; - case LABELANCHOR_E: - case LABELANCHOR_W: - labelframePtr->labelTextY = otherHeightT / 2; - labelframePtr->labelBox.y = otherHeight / 2; - break; - default: - labelframePtr->labelTextY = otherHeightT - padding; - labelframePtr->labelBox.y = otherHeight - padding; - break; - } -} - -/* - *---------------------------------------------------------------------- - * - * DisplayFrame -- - * - * This function is invoked to display a frame widget. - * - * Results: - * None. - * - * Side effects: - * Commands are output to X to display the frame in its current mode. - * - *---------------------------------------------------------------------- - */ - -static void -DisplayFrame( - ClientData clientData) /* Information about widget. */ -{ - register Frame *framePtr = clientData; - register Tk_Window tkwin = framePtr->tkwin; - int bdX1, bdY1, bdX2, bdY2, hlWidth; - Pixmap pixmap; - TkRegion clipRegion = NULL; - - framePtr->flags &= ~REDRAW_PENDING; - if ((framePtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; - } - - /* - * Highlight shall always be drawn if it exists, so do that first. - */ - - hlWidth = framePtr->highlightWidth; - - if (hlWidth != 0) { - GC fgGC, bgGC; - - bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr, - Tk_WindowId(tkwin)); - if (framePtr->flags & GOT_FOCUS) { - fgGC = Tk_GCForColor(framePtr->highlightColorPtr, - Tk_WindowId(tkwin)); - TkpDrawHighlightBorder(tkwin, fgGC, bgGC, hlWidth, - Tk_WindowId(tkwin)); - } else { - TkpDrawHighlightBorder(tkwin, bgGC, bgGC, hlWidth, - Tk_WindowId(tkwin)); - } - } - - /* - * If -background is set to "", no interior is drawn. - */ - - if (framePtr->border == NULL) { - return; - } - - if (framePtr->type != TYPE_LABELFRAME) { - /* - * Pass to platform specific draw function. In general, it just draws - * a simple rectangle, but it may "theme" the background. - */ - - noLabel: - TkpDrawFrame(tkwin, framePtr->border, hlWidth, - framePtr->borderWidth, framePtr->relief); - } else { - Labelframe *labelframePtr = (Labelframe *) framePtr; - - if ((labelframePtr->textPtr == NULL) && - (labelframePtr->labelWin == NULL)) { - goto noLabel; - } - -#ifndef TK_NO_DOUBLE_BUFFERING - /* - * In order to avoid screen flashes, this function redraws the frame - * into off-screen memory, then copies it back on-screen in a single - * operation. This means there's no point in time where the on-screen - * image has been cleared. - */ - - pixmap = Tk_GetPixmap(framePtr->display, Tk_WindowId(tkwin), - Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); -#else - pixmap = Tk_WindowId(tkwin); -#endif /* TK_NO_DOUBLE_BUFFERING */ - - /* - * Clear the pixmap. - */ - - Tk_Fill3DRectangle(tkwin, pixmap, framePtr->border, 0, 0, - Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT); - - /* - * Calculate how the label affects the border's position. - */ - - bdX1 = bdY1 = hlWidth; - bdX2 = Tk_Width(tkwin) - hlWidth; - bdY2 = Tk_Height(tkwin) - hlWidth; - - switch (labelframePtr->labelAnchor) { - case LABELANCHOR_E: - case LABELANCHOR_EN: - case LABELANCHOR_ES: - bdX2 -= (labelframePtr->labelBox.width-framePtr->borderWidth) / 2; - break; - case LABELANCHOR_N: - case LABELANCHOR_NE: - case LABELANCHOR_NW: - /* - * Since the glyphs of the text tend to be in the lower part we - * favor a lower border position by rounding up. - */ - - bdY1 += (labelframePtr->labelBox.height-framePtr->borderWidth+1)/2; - break; - case LABELANCHOR_S: - case LABELANCHOR_SE: - case LABELANCHOR_SW: - bdY2 -= (labelframePtr->labelBox.height-framePtr->borderWidth) / 2; - break; - default: - bdX1 += (labelframePtr->labelBox.width-framePtr->borderWidth) / 2; - break; - } - - /* - * Draw border - */ - - Tk_Draw3DRectangle(tkwin, pixmap, framePtr->border, bdX1, bdY1, - bdX2 - bdX1, bdY2 - bdY1, framePtr->borderWidth, - framePtr->relief); - - if (labelframePtr->labelWin == NULL) { - /* - * Clear behind the label - */ - - Tk_Fill3DRectangle(tkwin, pixmap, - framePtr->border, labelframePtr->labelBox.x, - labelframePtr->labelBox.y, labelframePtr->labelBox.width, - labelframePtr->labelBox.height, 0, TK_RELIEF_FLAT); - - /* - * Draw label. If there is not room for the entire label, use - * clipping to get a nice appearance. - */ - - if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth) - || (labelframePtr->labelBox.height < - labelframePtr->labelReqHeight)) { - clipRegion = TkCreateRegion(); - TkUnionRectWithRegion(&labelframePtr->labelBox, clipRegion, - clipRegion); - TkSetRegion(framePtr->display, labelframePtr->textGC, - clipRegion); - } - - Tk_DrawTextLayout(framePtr->display, pixmap, - labelframePtr->textGC, labelframePtr->textLayout, - labelframePtr->labelTextX + LABELSPACING, - labelframePtr->labelTextY + LABELSPACING, 0, -1); - - if (clipRegion != NULL) { - XSetClipMask(framePtr->display, labelframePtr->textGC, None); - TkDestroyRegion(clipRegion); - } - } else { - /* - * Reposition and map the window (but in different ways depending - * on whether the frame is the window's parent). - */ - - if (framePtr->tkwin == Tk_Parent(labelframePtr->labelWin)) { - if ((labelframePtr->labelBox.x != Tk_X(labelframePtr->labelWin)) - || (labelframePtr->labelBox.y != - Tk_Y(labelframePtr->labelWin)) - || (labelframePtr->labelBox.width != - Tk_Width(labelframePtr->labelWin)) - || (labelframePtr->labelBox.height != - Tk_Height(labelframePtr->labelWin))) { - Tk_MoveResizeWindow(labelframePtr->labelWin, - labelframePtr->labelBox.x, - labelframePtr->labelBox.y, - labelframePtr->labelBox.width, - labelframePtr->labelBox.height); - } - Tk_MapWindow(labelframePtr->labelWin); - } else { - Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin, - labelframePtr->labelBox.x, labelframePtr->labelBox.y, - labelframePtr->labelBox.width, - labelframePtr->labelBox.height); - } - } - -#ifndef TK_NO_DOUBLE_BUFFERING - /* - * Everything's been redisplayed; now copy the pixmap onto the screen - * and free up the pixmap. - */ - - XCopyArea(framePtr->display, pixmap, Tk_WindowId(tkwin), - labelframePtr->textGC, hlWidth, hlWidth, - (unsigned) (Tk_Width(tkwin) - 2 * hlWidth), - (unsigned) (Tk_Height(tkwin) - 2 * hlWidth), - hlWidth, hlWidth); - Tk_FreePixmap(framePtr->display, pixmap); -#endif /* TK_NO_DOUBLE_BUFFERING */ - } - -} - -/* - *-------------------------------------------------------------- - * - * FrameEventProc -- - * - * This function is invoked by the Tk dispatcher on structure changes to - * a frame. For frames with 3D borders, this function is also invoked for - * exposures. - * - * Results: - * None. - * - * Side effects: - * When the window gets deleted, internal structures get cleaned up. - * When it gets exposed, it is redisplayed. - * - *-------------------------------------------------------------- - */ - -static void -FrameEventProc( - ClientData clientData, /* Information about window. */ - register XEvent *eventPtr) /* Information about event. */ -{ - register Frame *framePtr = clientData; - - if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { - goto redraw; - } else if (eventPtr->type == ConfigureNotify) { - ComputeFrameGeometry(framePtr); - goto redraw; - } else if (eventPtr->type == DestroyNotify) { - if (framePtr->menuName != NULL) { - TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, - framePtr->menuName, NULL); - ckfree(framePtr->menuName); - framePtr->menuName = NULL; - } - if (framePtr->tkwin != NULL) { - /* - * If this window is a container, then this event could be coming - * from the embedded application, in which case Tk_DestroyWindow - * hasn't been called yet. When Tk_DestroyWindow is called later, - * then another destroy event will be generated. We need to be - * sure we ignore the second event, since the frame could be gone - * by then. To do so, delete the event handler explicitly - * (normally it's done implicitly by Tk_DestroyWindow). - */ - - /* - * Since the tkwin pointer will be gone when we reach - * DestroyFrame, we must free all options now. - */ - - DestroyFramePartly(framePtr); - - Tk_DeleteEventHandler(framePtr->tkwin, - ExposureMask|StructureNotifyMask|FocusChangeMask, - FrameEventProc, framePtr); - framePtr->tkwin = NULL; - Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd); - } - if (framePtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayFrame, framePtr); - } - Tcl_CancelIdleCall(MapFrame, framePtr); - Tcl_EventuallyFree(framePtr, (Tcl_FreeProc *) DestroyFrame); - } else if (eventPtr->type == FocusIn) { - if (eventPtr->xfocus.detail != NotifyInferior) { - framePtr->flags |= GOT_FOCUS; - if (framePtr->highlightWidth > 0) { - goto redraw; - } - } - } else if (eventPtr->type == FocusOut) { - if (eventPtr->xfocus.detail != NotifyInferior) { - framePtr->flags &= ~GOT_FOCUS; - if (framePtr->highlightWidth > 0) { - goto redraw; - } - } - } else if (eventPtr->type == ActivateNotify) { - TkpSetMainMenubar(framePtr->interp, framePtr->tkwin, - framePtr->menuName); - } - return; - - redraw: - if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) { - Tcl_DoWhenIdle(DisplayFrame, framePtr); - framePtr->flags |= REDRAW_PENDING; - } -} - -/* - *---------------------------------------------------------------------- - * - * FrameCmdDeletedProc -- - * - * This function is invoked when a widget command is deleted. If the - * widget isn't already in the process of being destroyed, this command - * destroys it. - * - * Results: - * None. - * - * Side effects: - * The widget is destroyed. - * - *---------------------------------------------------------------------- - */ - -static void -FrameCmdDeletedProc( - ClientData clientData) /* Pointer to widget record for widget. */ -{ - Frame *framePtr = clientData; - Tk_Window tkwin = framePtr->tkwin; - - if (framePtr->menuName != NULL) { - TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, - framePtr->menuName, NULL); - ckfree(framePtr->menuName); - framePtr->menuName = NULL; - } - - /* - * This function could be invoked either because the window was destroyed - * and the command was then deleted (in which case tkwin is NULL) or - * because the command was deleted, and then this function destroys the - * widget. - */ - - if (tkwin != NULL) { - /* - * Some options need tkwin to be freed, so we free them here, before - * setting tkwin to NULL. - */ - - DestroyFramePartly(framePtr); - - framePtr->tkwin = NULL; - Tk_DestroyWindow(tkwin); - } -} - -/* - *---------------------------------------------------------------------- - * - * MapFrame -- - * - * This function is invoked as a when-idle handler to map a newly-created - * top-level frame. - * - * Results: - * None. - * - * Side effects: - * The frame given by the clientData argument is mapped. - * - *---------------------------------------------------------------------- - */ - -static void -MapFrame( - ClientData clientData) /* Pointer to frame structure. */ -{ - Frame *framePtr = clientData; - - /* - * Wait for all other background events to be processed before mapping - * window. This ensures that the window's correct geometry will have been - * determined before it is first mapped, so that the window manager - * doesn't get a false idea of its desired geometry. - */ - - Tcl_Preserve(framePtr); - while (1) { - if (Tcl_DoOneEvent(TCL_IDLE_EVENTS) == 0) { - break; - } - - /* - * After each event, make sure that the window still exists and quit - * if the window has been destroyed. - */ - - if (framePtr->tkwin == NULL) { - Tcl_Release(framePtr); - return; - } - } - Tk_MapWindow(framePtr->tkwin); - Tcl_Release(framePtr); -} - -/* - *-------------------------------------------------------------- - * - * TkInstallFrameMenu -- - * - * This function is needed when a Windows HWND is created and a menubar - * has been set to the window with a system menu. It notifies the menu - * package so that the system menu can be rebuilt. - * - * Results: - * None. - * - * Side effects: - * The system menu (if any) is created for the menubar associated with - * this frame. - * - *-------------------------------------------------------------- - */ - -void -TkInstallFrameMenu( - Tk_Window tkwin) /* The window that was just created. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - - if (winPtr->mainPtr != NULL) { - Frame *framePtr = winPtr->instanceData; - - if (framePtr == NULL) { - Tcl_Panic("TkInstallFrameMenu couldn't get frame pointer"); - } - TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp, - framePtr->menuName); - } -} - -/* - *-------------------------------------------------------------- - * - * FrameStructureProc -- - * - * This function is invoked whenever StructureNotify events occur for a - * window that's managed as label for the frame. This procudure's only - * purpose is to clean up when windows are deleted. - * - * Results: - * None. - * - * Side effects: - * The window is disassociated from the frame when it is deleted. - * - *-------------------------------------------------------------- - */ - -static void -FrameStructureProc( - ClientData clientData, /* Pointer to record describing frame. */ - XEvent *eventPtr) /* Describes what just happened. */ -{ - Labelframe *labelframePtr = clientData; - - if (eventPtr->type == DestroyNotify) { - /* - * This should only happen in a labelframe but it doesn't hurt to be - * careful. - */ - - if (labelframePtr->frame.type == TYPE_LABELFRAME) { - labelframePtr->labelWin = NULL; - FrameWorldChanged(labelframePtr); - } - } -} - -/* - *-------------------------------------------------------------- - * - * FrameRequestProc -- - * - * This function is invoked whenever a window that's associated with a - * frame changes its requested dimensions. - * - * Results: - * None. - * - * Side effects: - * The size and location on the screen of the window may change depending - * on the options specified for the frame. - * - *-------------------------------------------------------------- - */ - -static void -FrameRequestProc( - ClientData clientData, /* Pointer to record for frame. */ - Tk_Window tkwin) /* Window that changed its desired size. */ -{ - Frame *framePtr = clientData; - - FrameWorldChanged(framePtr); -} - -/* - *-------------------------------------------------------------- - * - * FrameLostSlaveProc -- - * - * This function is invoked by Tk whenever some other geometry claims - * control over a slave that used to be managed by us. - * - * Results: - * None. - * - * Side effects: - * Forgets all frame-related information about the slave. - * - *-------------------------------------------------------------- - */ - -static void -FrameLostSlaveProc( - ClientData clientData, /* Frame structure for slave window that was - * stolen away. */ - Tk_Window tkwin) /* Tk's handle for the slave window. */ -{ - Frame *framePtr = clientData; - Labelframe *labelframePtr = clientData; - - /* - * This should only happen in a labelframe but it doesn't hurt to be - * careful. - */ - - if (labelframePtr->frame.type == TYPE_LABELFRAME) { - Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask, - FrameStructureProc, labelframePtr); - if (framePtr->tkwin != Tk_Parent(labelframePtr->labelWin)) { - Tk_UnmaintainGeometry(labelframePtr->labelWin, framePtr->tkwin); - } - Tk_UnmapWindow(labelframePtr->labelWin); - labelframePtr->labelWin = NULL; - } - FrameWorldChanged(framePtr); -} - -void -TkMapTopFrame( - Tk_Window tkwin) -{ - Frame *framePtr = ((TkWindow *) tkwin)->instanceData; - Tk_OptionTable optionTable; - - if (Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_FRAME) { - framePtr->type = TYPE_TOPLEVEL; - Tcl_DoWhenIdle(MapFrame, framePtr); - if (framePtr->menuName != NULL) { - TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin, NULL, - framePtr->menuName); - } - } else if (!Tk_IsTopLevel(tkwin) && framePtr->type == TYPE_TOPLEVEL) { - framePtr->type = TYPE_FRAME; - } else { - /* - * Not a frame or toplevel, skip it. - */ - - return; - } - - /* - * The option table has already been created so the cached pointer will be - * returned. - */ - - optionTable = Tk_CreateOptionTable(framePtr->interp, - optionSpecs[framePtr->type]); - framePtr->optionTable = optionTable; -} - -/* - *-------------------------------------------------------------- - * - * TkToplevelWindowFromCommandToken -- - * - * If the given command name to the command for a toplevel window in the - * given interpreter, return the tkwin for that toplevel window. Note - * that this lookup can't be done using the standard tkwin internal table - * because the command might have been renamed. - * - * Results: - * A Tk_Window token, or NULL if the name does not refer to a toplevel - * window. - * - * Side effects: - * None. - * - *-------------------------------------------------------------- - */ - -Tk_Window -TkToplevelWindowForCommand( - Tcl_Interp *interp, - const char *cmdName) -{ - Tcl_CmdInfo cmdInfo; - Frame *framePtr; - - if (Tcl_GetCommandInfo(interp, cmdName, &cmdInfo) == 0) { - return NULL; - } - if (cmdInfo.objProc != FrameWidgetObjCmd) { - return NULL; - } - framePtr = cmdInfo.objClientData; - if (framePtr->type != TYPE_TOPLEVEL) { - return NULL; - } - return framePtr->tkwin; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |