diff options
Diffstat (limited to 'generic/tkMenuDraw.c')
-rw-r--r-- | generic/tkMenuDraw.c | 450 |
1 files changed, 224 insertions, 226 deletions
diff --git a/generic/tkMenuDraw.c b/generic/tkMenuDraw.c index 33dadc1..d2a66d3 100644 --- a/generic/tkMenuDraw.c +++ b/generic/tkMenuDraw.c @@ -1,35 +1,34 @@ -/* +/* * tkMenuDraw.c -- * - * This module implements the platform-independent drawing and - * geometry calculations of menu widgets. + * This module implements the platform-independent drawing and geometry + * calculations of menu widgets. * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#include "tkInt.h" #include "tkMenu.h" /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static void AdjustMenuCoords _ANSI_ARGS_ ((TkMenu *menuPtr, - TkMenuEntry *mePtr, int *xPtr, int *yPtr, - char *string)); -static void ComputeMenuGeometry _ANSI_ARGS_(( - ClientData clientData)); -static void DisplayMenu _ANSI_ARGS_((ClientData clientData)); +static void AdjustMenuCoords(TkMenu *menuPtr, TkMenuEntry *mePtr, + int *xPtr, int *yPtr); +static void ComputeMenuGeometry(ClientData clientData); +static void DisplayMenu(ClientData clientData); /* *---------------------------------------------------------------------- * * TkMenuInitializeDrawingFields -- * - * Fills in drawing fields of a new menu. Called when new menu is - * created by MenuCmd. + * Fills in drawing fields of a new menu. Called when new menu is created + * by MenuCmd. * * Results: * None. @@ -41,8 +40,8 @@ static void DisplayMenu _ANSI_ARGS_((ClientData clientData)); */ void -TkMenuInitializeDrawingFields(menuPtr) - TkMenu *menuPtr; /* The menu we are initializing. */ +TkMenuInitializeDrawingFields( + TkMenu *menuPtr) /* The menu we are initializing. */ { menuPtr->textGC = None; menuPtr->gray = None; @@ -58,8 +57,8 @@ TkMenuInitializeDrawingFields(menuPtr) * * TkMenuInitializeEntryDrawingFields -- * - * Fills in drawing fields of a new menu entry. Called when an - * entry is created. + * Fills in drawing fields of a new menu entry. Called when an entry is + * created. * * Results: * None. @@ -71,8 +70,8 @@ TkMenuInitializeDrawingFields(menuPtr) */ void -TkMenuInitializeEntryDrawingFields(mePtr) - TkMenuEntry *mePtr; /* The menu we are initializing. */ +TkMenuInitializeEntryDrawingFields( + TkMenuEntry *mePtr) /* The menu we are initializing. */ { mePtr->width = 0; mePtr->height = 0; @@ -91,8 +90,8 @@ TkMenuInitializeEntryDrawingFields(mePtr) * * TkMenuFreeDrawOptions -- * - * Frees up any structures allocated for the drawing of a menu. - * Called when menu is deleted. + * Frees up any structures allocated for the drawing of a menu. Called + * when menu is deleted. * * Results: * None. @@ -104,8 +103,8 @@ TkMenuInitializeEntryDrawingFields(mePtr) */ void -TkMenuFreeDrawOptions(menuPtr) - TkMenu *menuPtr; +TkMenuFreeDrawOptions( + TkMenu *menuPtr) { if (menuPtr->textGC != None) { Tk_FreeGC(menuPtr->display, menuPtr->textGC); @@ -132,8 +131,8 @@ TkMenuFreeDrawOptions(menuPtr) * * TkMenuEntryFreeDrawOptions -- * - * Frees up drawing structures for a menu entry. Called when - * menu entry is freed. + * Frees up drawing structures for a menu entry. Called when menu entry + * is freed. * * RESULTS: * None. @@ -145,8 +144,8 @@ TkMenuFreeDrawOptions(menuPtr) */ void -TkMenuEntryFreeDrawOptions(mePtr) - TkMenuEntry *mePtr; +TkMenuEntryFreeDrawOptions( + TkMenuEntry *mePtr) { if (mePtr->textGC != None) { Tk_FreeGC(mePtr->menuPtr->display, mePtr->textGC); @@ -167,8 +166,8 @@ TkMenuEntryFreeDrawOptions(mePtr) * * TkMenuConfigureDrawOptions -- * - * Sets the menu's drawing attributes in preparation for drawing - * the menu. + * Sets the menu's drawing attributes in preparation for drawing the + * menu. * * RESULTS: * None. @@ -180,8 +179,8 @@ TkMenuEntryFreeDrawOptions(mePtr) */ void -TkMenuConfigureDrawOptions(menuPtr) - TkMenu *menuPtr; /* The menu we are configuring. */ +TkMenuConfigureDrawOptions( + TkMenu *menuPtr) /* The menu we are configuring. */ { XGCValues gcValues; GC newGC; @@ -189,11 +188,11 @@ TkMenuConfigureDrawOptions(menuPtr) Tk_3DBorder border, activeBorder; Tk_Font tkfont; XColor *fg, *activeFg, *indicatorFg; - + /* - * A few options need special processing, such as setting the - * background from a 3-D border, or filling in complicated - * defaults that couldn't be specified to Tk_ConfigureWidget. + * A few options need special processing, such as setting the background + * from a 3-D border, or filling in complicated defaults that couldn't be + * specified to Tk_ConfigureWidget. */ border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); @@ -216,7 +215,7 @@ TkMenuConfigureDrawOptions(menuPtr) if (menuPtr->disabledFgPtr != NULL) { XColor *disabledFg; - disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, + disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->disabledFgPtr); gcValues.foreground = disabledFg->pixel; mask = GCForeground|GCBackground|GCFont; @@ -247,7 +246,7 @@ TkMenuConfigureDrawOptions(menuPtr) if (menuPtr->gray != None) { gcValues.fill_style = FillStippled; gcValues.stipple = menuPtr->gray; - newGC = Tk_GetGC(menuPtr->tkwin, + newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCFillStyle|GCStipple, &gcValues); } if (menuPtr->disabledImageGC != None) { @@ -258,7 +257,7 @@ TkMenuConfigureDrawOptions(menuPtr) gcValues.font = Tk_FontId(tkfont); activeFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->activeFgPtr); gcValues.foreground = activeFg->pixel; - activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, + activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->activeBorderPtr); gcValues.background = Tk_3DBorderColor(activeBorder)->pixel; newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, @@ -268,7 +267,7 @@ TkMenuConfigureDrawOptions(menuPtr) } menuPtr->activeGC = newGC; - indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, + indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->indicatorFgPtr); gcValues.foreground = indicatorFg->pixel; gcValues.background = Tk_3DBorderColor(border)->pixel; @@ -285,8 +284,7 @@ TkMenuConfigureDrawOptions(menuPtr) * * TkMenuConfigureEntryDrawOptions -- * - * Calculates any entry-specific draw options for the given menu - * entry. + * Calculates any entry-specific draw options for the given menu entry. * * Results: * Returns a standard Tcl error. @@ -298,11 +296,10 @@ TkMenuConfigureDrawOptions(menuPtr) */ int -TkMenuConfigureEntryDrawOptions(mePtr, index) - TkMenuEntry *mePtr; - int index; +TkMenuConfigureEntryDrawOptions( + TkMenuEntry *mePtr, + int index) { - XGCValues gcValues; GC newGC, newActiveGC, newDisabledGC, newIndicatorGC; unsigned long mask; @@ -311,7 +308,7 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) tkfont = Tk_GetFontFromObj(menuPtr->tkwin, (mePtr->fontPtr != NULL) ? mePtr->fontPtr : menuPtr->fontPtr); - + if (mePtr->state == ENTRY_ACTIVE) { if (index != menuPtr->active) { TkActivateMenuEntry(menuPtr, index); @@ -330,21 +327,21 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) || (mePtr->indicatorFgPtr != NULL)) { XColor *fg, *indicatorFg, *activeFg; Tk_3DBorder border, activeBorder; - + fg = Tk_GetColorFromObj(menuPtr->tkwin, (mePtr->fgPtr != NULL) ? mePtr->fgPtr : menuPtr->fgPtr); gcValues.foreground = fg->pixel; - border = Tk_Get3DBorderFromObj(menuPtr->tkwin, - (mePtr->borderPtr != NULL) ? mePtr->borderPtr + border = Tk_Get3DBorderFromObj(menuPtr->tkwin, + (mePtr->borderPtr != NULL) ? mePtr->borderPtr : menuPtr->borderPtr); gcValues.background = Tk_3DBorderColor(border)->pixel; gcValues.font = Tk_FontId(tkfont); /* - * Note: disable GraphicsExpose events; we know there won't be - * obscured areas when copying from an off-screen pixmap to the - * screen and this gets rid of unnecessary events. + * Note: disable GraphicsExpose events; we know there won't be + * obscured areas when copying from an off-screen pixmap to the screen + * and this gets rid of unnecessary events. */ gcValues.graphics_exposures = False; @@ -352,7 +349,7 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues); - indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, + indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, (mePtr->indicatorFgPtr != NULL) ? mePtr->indicatorFgPtr : menuPtr->indicatorFgPtr); gcValues.foreground = indicatorFg->pixel; @@ -363,7 +360,7 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) if ((menuPtr->disabledFgPtr != NULL) || (mePtr->image != NULL)) { XColor *disabledFg; - disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, + disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->disabledFgPtr); gcValues.foreground = disabledFg->pixel; mask = GCForeground|GCBackground|GCFont|GCGraphicsExposures; @@ -375,13 +372,13 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) } newDisabledGC = Tk_GetGC(menuPtr->tkwin, mask, &gcValues); - activeFg = Tk_GetColorFromObj(menuPtr->tkwin, + activeFg = Tk_GetColorFromObj(menuPtr->tkwin, (mePtr->activeFgPtr != NULL) ? mePtr->activeFgPtr : menuPtr->activeFgPtr); - activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, - (mePtr->activeBorderPtr != NULL) ? mePtr->activeBorderPtr + activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, + (mePtr->activeBorderPtr != NULL) ? mePtr->activeBorderPtr : menuPtr->activeBorderPtr); - + gcValues.foreground = activeFg->pixel; gcValues.background = Tk_3DBorderColor(activeBorder)->pixel; newActiveGC = Tk_GetGC(menuPtr->tkwin, @@ -394,15 +391,15 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) newIndicatorGC = None; } if (mePtr->textGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->textGC); + Tk_FreeGC(menuPtr->display, mePtr->textGC); } mePtr->textGC = newGC; if (mePtr->activeGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->activeGC); + Tk_FreeGC(menuPtr->display, mePtr->activeGC); } mePtr->activeGC = newActiveGC; if (mePtr->disabledGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->disabledGC); + Tk_FreeGC(menuPtr->display, mePtr->disabledGC); } mePtr->disabledGC = newDisabledGC; if (mePtr->indicatorGC != None) { @@ -430,8 +427,8 @@ TkMenuConfigureEntryDrawOptions(mePtr, index) */ void -TkEventuallyRecomputeMenu(menuPtr) - TkMenu *menuPtr; +TkEventuallyRecomputeMenu( + TkMenu *menuPtr) { if (!(menuPtr->menuFlags & RESIZE_PENDING)) { menuPtr->menuFlags |= RESIZE_PENDING; @@ -444,8 +441,8 @@ TkEventuallyRecomputeMenu(menuPtr) * * TkRecomputeMenu -- * - * Tells Tcl to redo the geometry because this menu has changed. - * Does it now; removes any ComputeMenuGeometries from the idler. + * Tells Tcl to redo the geometry because this menu has changed. Does it + * now; removes any ComputeMenuGeometries from the idler. * * Results: * None. @@ -457,9 +454,9 @@ TkEventuallyRecomputeMenu(menuPtr) */ void -TkRecomputeMenu(menuPtr) - TkMenu *menuPtr; -{ +TkRecomputeMenu( + TkMenu *menuPtr) +{ if (menuPtr->menuFlags & RESIZE_PENDING) { Tcl_CancelIdleCall(ComputeMenuGeometry, (ClientData) menuPtr); ComputeMenuGeometry((ClientData) menuPtr); @@ -471,27 +468,27 @@ TkRecomputeMenu(menuPtr) * * TkEventuallyRedrawMenu -- * - * Arrange for an entry of a menu, or the whole menu, to be - * redisplayed at some point in the future. + * Arrange for an entry of a menu, or the whole menu, to be redisplayed + * at some point in the future. * * Results: * None. * * Side effects: - * A when-idle hander is scheduled to do the redisplay, if there - * isn't one already scheduled. + * A when-idle hander is scheduled to do the redisplay, if there isn't + * one already scheduled. * *---------------------------------------------------------------------- */ void -TkEventuallyRedrawMenu(menuPtr, mePtr) - register TkMenu *menuPtr; /* Information about menu to redraw. */ - register TkMenuEntry *mePtr;/* Entry to redraw. NULL means redraw - * all the entries in the menu. */ +TkEventuallyRedrawMenu( + register TkMenu *menuPtr, /* Information about menu to redraw. */ + register TkMenuEntry *mePtr)/* Entry to redraw. NULL means redraw all the + * entries in the menu. */ { int i; - + if (menuPtr->tkwin == NULL) { return; } @@ -515,25 +512,23 @@ TkEventuallyRedrawMenu(menuPtr, mePtr) * * ComputeMenuGeometry -- * - * This procedure is invoked to recompute the size and - * layout of a menu. It is called as a when-idle handler so - * that it only gets done once, even if a group of changes is - * made to the menu. + * This function is invoked to recompute the size and layout of a menu. + * It is called as a when-idle handler so that it only gets done once, + * even if a group of changes is made to the menu. * * Results: * None. * * Side effects: - * Fields of menu entries are changed to reflect their - * current positions, and the size of the menu window - * itself may be changed. + * Fields of menu entries are changed to reflect their current positions, + * and the size of the menu window itself may be changed. * *-------------------------------------------------------------- */ static void -ComputeMenuGeometry(clientData) - ClientData clientData; /* Structure describing menu. */ +ComputeMenuGeometry( + ClientData clientData) /* Structure describing menu. */ { TkMenu *menuPtr = (TkMenu *) clientData; @@ -552,16 +547,15 @@ ComputeMenuGeometry(clientData) Tk_GeometryRequest(menuPtr->tkwin, menuPtr->totalWidth, menuPtr->totalHeight); } - + /* - * Must always force a redisplay here if the window is mapped - * (even if the size didn't change, something else might have - * changed in the menu, such as a label or accelerator). The - * resize will force a redisplay above. + * Must always force a redisplay here if the window is mapped (even if the + * size didn't change, something else might have changed in the menu, such + * as a label or accelerator). The resize will force a redisplay above. */ - - TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL); - + + TkEventuallyRedrawMenu(menuPtr, NULL); + menuPtr->menuFlags &= ~RESIZE_PENDING; } @@ -570,9 +564,9 @@ ComputeMenuGeometry(clientData) * * TkMenuSelectImageProc -- * - * This procedure is invoked by the image code whenever the manager - * for an image does something that affects the size of contents - * of an image displayed in a menu entry when it is selected. + * This function is invoked by the image code whenever the manager for an + * image does something that affects the size of contents of an image + * displayed in a menu entry when it is selected. * * Results: * None. @@ -584,20 +578,18 @@ ComputeMenuGeometry(clientData) */ void -TkMenuSelectImageProc(clientData, x, y, width, height, imgWidth, - imgHeight) - ClientData clientData; /* Pointer to widget record. */ - int x, y; /* Upper left pixel (within image) - * that must be redisplayed. */ - int width, height; /* Dimensions of area to redisplay - * (may be <= 0). */ - int imgWidth, imgHeight; /* New dimensions of image. */ +TkMenuSelectImageProc( + ClientData clientData, /* Pointer to widget record. */ + int x, int y, /* Upper left pixel (within image) that must + * be redisplayed. */ + int width, int height, /* Dimensions of area to redisplay (may be + * <=0). */ + int imgWidth, int imgHeight)/* New dimensions of image. */ { register TkMenuEntry *mePtr = (TkMenuEntry *) clientData; if ((mePtr->entryFlags & ENTRY_SELECTED) - && !(mePtr->menuPtr->menuFlags & - REDRAW_PENDING)) { + && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) { mePtr->menuPtr->menuFlags |= REDRAW_PENDING; Tcl_DoWhenIdle(DisplayMenu, (ClientData) mePtr->menuPtr); } @@ -608,21 +600,20 @@ TkMenuSelectImageProc(clientData, x, y, width, height, imgWidth, * * DisplayMenu -- * - * This procedure is invoked to display a menu widget. + * This function is invoked to display a menu widget. * * Results: * None. * * Side effects: - * Commands are output to X to display the menu in its - * current mode. + * Commands are output to X to display the menu in its current mode. * *---------------------------------------------------------------------- */ static void -DisplayMenu(clientData) - ClientData clientData; /* Information about widget. */ +DisplayMenu( + ClientData clientData) /* Information about widget. */ { register TkMenu *menuPtr = (TkMenu *) clientData; register TkMenuEntry *mePtr; @@ -649,8 +640,8 @@ DisplayMenu(clientData) menuPtr->activeBorderWidthPtr, &activeBorderWidth); if (menuPtr->menuType == MENUBAR) { - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, - borderWidth, Tk_Width(tkwin) - 2 * borderWidth, + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, + borderWidth, Tk_Width(tkwin) - 2 * borderWidth, Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT); } @@ -688,15 +679,15 @@ DisplayMenu(clientData) } } TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont, - &menuMetrics, mePtr->x, mePtr->y, width, + &menuMetrics, mePtr->x, mePtr->y, width, mePtr->height, strictMotif, 1); if ((index > 0) && (menuPtr->menuType != MENUBAR) && mePtr->columnBreak) { mePtr = menuPtr->entries[index - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, - mePtr->x, mePtr->y + mePtr->height, + mePtr->x, mePtr->y + mePtr->height, mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - + Tk_Height(tkwin) - mePtr->y - mePtr->height - activeBorderWidth, 0, TK_RELIEF_FLAT); } @@ -712,7 +703,7 @@ DisplayMenu(clientData) } else { mePtr = menuPtr->entries[menuPtr->numEntries - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), - border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, + border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, Tk_Height(tkwin) - mePtr->y - mePtr->height - activeBorderWidth, 0, TK_RELIEF_FLAT); @@ -721,13 +712,13 @@ DisplayMenu(clientData) width = Tk_Width(tkwin) - x - activeBorderWidth; height = Tk_Height(tkwin) - y - activeBorderWidth; } - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y, + Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y, width, height, 0, TK_RELIEF_FLAT); } Tk_GetReliefFromObj(NULL, menuPtr->reliefPtr, &relief); Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin), - border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth, + border, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), borderWidth, relief); } @@ -736,31 +727,31 @@ DisplayMenu(clientData) * * TkMenuEventProc -- * - * This procedure is invoked by the Tk dispatcher for various - * events on menus. + * This function is invoked by the Tk dispatcher for various events on + * menus. * * Results: * None. * * Side effects: - * When the window gets deleted, internal structures get - * cleaned up. When it gets exposed, it is redisplayed. + * When the window gets deleted, internal structures get cleaned up. When + * it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ void -TkMenuEventProc(clientData, eventPtr) - ClientData clientData; /* Information about window. */ - XEvent *eventPtr; /* Information about event. */ +TkMenuEventProc( + ClientData clientData, /* Information about window. */ + XEvent *eventPtr) /* Information about event. */ { TkMenu *menuPtr = (TkMenu *) clientData; - + if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { - TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL); + TkEventuallyRedrawMenu(menuPtr, NULL); } else if (eventPtr->type == ConfigureNotify) { TkEventuallyRecomputeMenu(menuPtr); - TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL); + TkEventuallyRedrawMenu(menuPtr, NULL); } else if (eventPtr->type == ActivateNotify) { if (menuPtr->menuType == TEAROFF_MENU) { TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL); @@ -797,9 +788,9 @@ TkMenuEventProc(clientData, eventPtr) * * TkMenuImageProc -- * - * This procedure is invoked by the image code whenever the manager - * for an image does something that affects the size of contents - * of an image displayed in a menu entry. + * This function is invoked by the image code whenever the manager for an + * image does something that affects the size of contents of an image + * displayed in a menu entry. * * Results: * None. @@ -811,19 +802,17 @@ TkMenuEventProc(clientData, eventPtr) */ void -TkMenuImageProc(clientData, x, y, width, height, imgWidth, - imgHeight) - ClientData clientData; /* Pointer to widget record. */ - int x, y; /* Upper left pixel (within image) - * that must be redisplayed. */ - int width, height; /* Dimensions of area to redisplay - * (may be <= 0). */ - int imgWidth, imgHeight; /* New dimensions of image. */ +TkMenuImageProc( + ClientData clientData, /* Pointer to widget record. */ + int x, int y, /* Upper left pixel (within image) that must + * be redisplayed. */ + int width, int height, /* Dimensions of area to redisplay (may be + * <=0). */ + int imgWidth, int imgHeight)/* New dimensions of image. */ { register TkMenu *menuPtr = ((TkMenuEntry *)clientData)->menuPtr; - if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags - & RESIZE_PENDING)) { + if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) { menuPtr->menuFlags |= RESIZE_PENDING; Tcl_DoWhenIdle(ComputeMenuGeometry, (ClientData) menuPtr); } @@ -834,9 +823,9 @@ TkMenuImageProc(clientData, x, y, width, height, imgWidth, * * TkPostTearoffMenu -- * - * Posts a menu on the screen. Used to post tearoff menus. On Unix, - * all menus are posted this way. Adjusts the menu's position - * so that it fits on the screen, and maps and raises the menu. + * Posts a menu on the screen. Used to post tearoff menus. On Unix, all + * menus are posted this way. Adjusts the menu's position so that it fits + * on the screen, and maps and raises the menu. * * Results: * Returns a standard Tcl Error. @@ -848,13 +837,11 @@ TkMenuImageProc(clientData, x, y, width, height, imgWidth, */ int -TkPostTearoffMenu(interp, menuPtr, x, y) - Tcl_Interp *interp; /* The interpreter of the menu */ - TkMenu *menuPtr; /* The menu we are posting */ - int x; /* The root X coordinate where we - * are posting */ - int y; /* The root Y coordinate where we - * are posting */ +TkPostTearoffMenu( + Tcl_Interp *interp, /* The interpreter of the menu */ + TkMenu *menuPtr, /* The menu we are posting */ + int x, int y) /* The root X,Y coordinates where we are + * posting */ { int vRootX, vRootY, vRootWidth, vRootHeight; int tmp, result; @@ -867,8 +854,8 @@ TkPostTearoffMenu(interp, menuPtr, x, y) } /* - * The post commands could have deleted the menu, which means - * we are dead and should go away. + * The post commands could have deleted the menu, which means we are dead + * and should go away. */ if (menuPtr->tkwin == NULL) { @@ -876,27 +863,24 @@ TkPostTearoffMenu(interp, menuPtr, x, y) } /* - * Adjust the position of the menu if necessary to keep it - * visible on the screen. There are two special tricks to - * make this work right: + * Adjust the position of the menu if necessary to keep it visible on the + * screen. There are two special tricks to make this work right: * - * 1. If a virtual root window manager is being used then - * the coordinates are in the virtual root window of - * menuPtr's parent; since the menu uses override-redirect - * mode it will be in the *real* root window for the screen, - * so we have to map the coordinates from the virtual root - * (if any) to the real root. Can't get the virtual root - * from the menu itself (it will never be seen by the wm) - * so use its parent instead (it would be better to have an - * an option that names a window to use for this...). - * 2. The menu may not have been mapped yet, so its current size - * might be the default 1x1. To compute how much space it - * needs, use its requested size, not its actual size. + * 1. If a virtual root window manager is being used then the coordinates + * are in the virtual root window of menuPtr's parent; since the menu + * uses override-redirect mode it will be in the *real* root window for + * the screen, so we have to map the coordinates from the virtual root + * (if any) to the real root. Can't get the virtual root from the menu + * itself (it will never be seen by the wm) so use its parent instead + * (it would be better to have an an option that names a window to use + * for this...). + * 2. The menu may not have been mapped yet, so its current size might be + * the default 1x1. To compute how much space it needs, use its + * requested size, not its actual size. * - * Note that this code assumes square screen regions and all - * positive coordinates. This does not work on a Mac with - * multiple monitors. But then again, Tk has other problems - * with this. + * Note that this code assumes square screen regions and all positive + * coordinates. This does not work on a Mac with multiple monitors. But + * then again, Tk has other problems with this. */ Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY, @@ -932,59 +916,58 @@ TkPostTearoffMenu(interp, menuPtr, x, y) * * TkPostSubmenu -- * - * This procedure arranges for a particular submenu (i.e. the - * menu corresponding to a given cascade entry) to be - * posted. + * This function arranges for a particular submenu (i.e. the menu + * corresponding to a given cascade entry) to be posted. * * Results: - * A standard Tcl return result. Errors may occur in the - * Tcl commands generated to post and unpost submenus. + * A standard Tcl return result. Errors may occur in the Tcl commands + * generated to post and unpost submenus. * * Side effects: - * If there is already a submenu posted, it is unposted. - * The new submenu is then posted. + * If there is already a submenu posted, it is unposted. The new submenu + * is then posted. * *-------------------------------------------------------------- */ int -TkPostSubmenu(interp, menuPtr, mePtr) - Tcl_Interp *interp; /* Used for invoking sub-commands and +TkPostSubmenu( + Tcl_Interp *interp, /* Used for invoking sub-commands and * reporting errors. */ - register TkMenu *menuPtr; /* Information about menu as a whole. */ - register TkMenuEntry *mePtr; /* Info about submenu that is to be - * posted. NULL means make sure that - * no submenu is posted. */ + register TkMenu *menuPtr, /* Information about menu as a whole. */ + register TkMenuEntry *mePtr)/* Info about submenu that is to be posted. + * NULL means make sure that no submenu is + * posted. */ { int result, x, y; + Tcl_Obj *subary[4]; if (mePtr == menuPtr->postedCascade) { return TCL_OK; } if (menuPtr->postedCascade != NULL) { - char *name = Tcl_GetStringFromObj(menuPtr->postedCascade->namePtr, - NULL); - /* - * Note: when unposting a submenu, we have to redraw the entire - * parent menu. This is because of a combination of the following - * things: + * Note: when unposting a submenu, we have to redraw the entire parent + * menu. This is because of a combination of the following things: * (a) the submenu partially overlaps the parent. - * (b) the submenu specifies "save under", which causes the X - * server to make a copy of the information under it when it - * is posted. When the submenu is unposted, the X server - * copies this data back and doesn't generate any Expose - * events for the parent. - * (c) the parent may have redisplayed itself after the submenu - * was posted, in which case the saved information is no - * longer correct. - * The simplest solution is just force a complete redisplay of - * the parent. + * (b) the submenu specifies "save under", which causes the X server + * to make a copy of the information under it when it is posted. + * When the submenu is unposted, the X server copies this data + * back and doesn't generate any Expose events for the parent. + * (c) the parent may have redisplayed itself after the submenu was + * posted, in which case the saved information is no longer + * correct. + * The simplest solution is just force a complete redisplay of the + * parent. */ - TkEventuallyRedrawMenu(menuPtr, (TkMenuEntry *) NULL); - result = Tcl_VarEval(interp, "{", name, "} unpost", (char *) NULL); + subary[0] = menuPtr->postedCascade->namePtr; + subary[1] = Tcl_NewStringObj("unpost", -1); + Tcl_IncrRefCount(subary[1]); + TkEventuallyRedrawMenu(menuPtr, NULL); + result = Tcl_EvalObjv(interp, 2, subary, 0); + Tcl_DecrRefCount(subary[1]); menuPtr->postedCascade = NULL; if (result != TCL_OK) { return result; @@ -994,21 +977,31 @@ TkPostSubmenu(interp, menuPtr, mePtr) if ((mePtr != NULL) && (mePtr->namePtr != NULL) && Tk_IsMapped(menuPtr->tkwin)) { /* - * Position the cascade with its upper left corner slightly - * below and to the left of the upper right corner of the - * menu entry (this is an attempt to match Motif behavior). + * Position the cascade with its upper left corner slightly below and + * to the left of the upper right corner of the menu entry (this is an + * attempt to match Motif behavior). * * The menu has to redrawn so that the entry can change relief. + * + * Set postedCascade early to ensure tear-off submenus work on + * Windows. [Bug 873613] */ - char string[TCL_INTEGER_SPACE * 2]; - char *name; - - name = Tcl_GetStringFromObj(mePtr->namePtr, NULL); Tk_GetRootCoords(menuPtr->tkwin, &x, &y); - AdjustMenuCoords(menuPtr, mePtr, &x, &y, string); + AdjustMenuCoords(menuPtr, mePtr, &x, &y); + menuPtr->postedCascade = mePtr; - result = Tcl_VarEval(interp, "{", name, "} post ", string, (char *) NULL); + subary[0] = mePtr->namePtr; + subary[1] = Tcl_NewStringObj("post", -1); + subary[2] = Tcl_NewIntObj(x); + subary[3] = Tcl_NewIntObj(y); + Tcl_IncrRefCount(subary[1]); + Tcl_IncrRefCount(subary[2]); + Tcl_IncrRefCount(subary[3]); + result = Tcl_EvalObjv(interp, 4, subary, 0); + Tcl_DecrRefCount(subary[1]); + Tcl_DecrRefCount(subary[2]); + Tcl_DecrRefCount(subary[3]); if (result != TCL_OK) { menuPtr->postedCascade = NULL; return result; @@ -1023,8 +1016,7 @@ TkPostSubmenu(interp, menuPtr, mePtr) * * AdjustMenuCoords -- * - * Adjusts the given coordinates down and the left to give a Motif - * look. + * Adjusts the given coordinates down and the left to give a Motif look. * * Results: * None. @@ -1036,12 +1028,11 @@ TkPostSubmenu(interp, menuPtr, mePtr) */ static void -AdjustMenuCoords(menuPtr, mePtr, xPtr, yPtr, string) - TkMenu *menuPtr; - TkMenuEntry *mePtr; - int *xPtr; - int *yPtr; - char *string; +AdjustMenuCoords( + TkMenu *menuPtr, + TkMenuEntry *mePtr, + int *xPtr, + int *yPtr) { if (menuPtr->menuType == MENUBAR) { *xPtr += mePtr->x; @@ -1051,11 +1042,18 @@ AdjustMenuCoords(menuPtr, mePtr, xPtr, yPtr, string) Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, &borderWidth); - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, + Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->activeBorderWidthPtr, &activeBorderWidth); - *xPtr += Tk_Width(menuPtr->tkwin) - borderWidth - activeBorderWidth + *xPtr += Tk_Width(menuPtr->tkwin) - borderWidth - activeBorderWidth - 2; *yPtr += mePtr->y + activeBorderWidth + 2; } - sprintf(string, "%d %d", *xPtr, *yPtr); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |