diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2018-01-02 20:34:49 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2018-01-02 20:34:49 (GMT) |
commit | 89c1ac99d375fbd73892aa659f06ef5e2c5ea56e (patch) | |
tree | e76ce80d68d11f1ea137bc33a42f71a1d1f32028 /tk8.6/generic/tkMenuDraw.c | |
parent | 01e4cd2ef2ff59418766b2259fbc99771646aba6 (diff) | |
download | blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.zip blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.tar.gz blt-89c1ac99d375fbd73892aa659f06ef5e2c5ea56e.tar.bz2 |
upgrade to tcl/tk 8.6.8
Diffstat (limited to 'tk8.6/generic/tkMenuDraw.c')
-rw-r--r-- | tk8.6/generic/tkMenuDraw.c | 1051 |
1 files changed, 0 insertions, 1051 deletions
diff --git a/tk8.6/generic/tkMenuDraw.c b/tk8.6/generic/tkMenuDraw.c deleted file mode 100644 index 1abe1c4..0000000 --- a/tk8.6/generic/tkMenuDraw.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* - * tkMenuDraw.c -- - * - * 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. - */ - -#include "tkInt.h" -#include "tkMenu.h" - -/* - * Forward declarations for functions defined later in this file: - */ - -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. - * - * Results: - * None. - * - * Side effects: - * menuPtr fields are initialized. - * - *---------------------------------------------------------------------- - */ - -void -TkMenuInitializeDrawingFields( - TkMenu *menuPtr) /* The menu we are initializing. */ -{ - menuPtr->textGC = None; - menuPtr->gray = None; - menuPtr->disabledGC = None; - menuPtr->activeGC = None; - menuPtr->indicatorGC = None; - menuPtr->disabledImageGC = None; - menuPtr->totalWidth = menuPtr->totalHeight = 0; -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuInitializeEntryDrawingFields -- - * - * Fills in drawing fields of a new menu entry. Called when an entry is - * created. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TkMenuInitializeEntryDrawingFields( - TkMenuEntry *mePtr) /* The menu we are initializing. */ -{ - mePtr->width = 0; - mePtr->height = 0; - mePtr->x = 0; - mePtr->y = 0; - mePtr->indicatorSpace = 0; - mePtr->labelWidth = 0; - mePtr->textGC = None; - mePtr->activeGC = None; - mePtr->disabledGC = None; - mePtr->indicatorGC = None; -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuFreeDrawOptions -- - * - * Frees up any structures allocated for the drawing of a menu. Called - * when menu is deleted. - * - * Results: - * None. - * - * Side effects: - * Storage is released. - * - *---------------------------------------------------------------------- - */ - -void -TkMenuFreeDrawOptions( - TkMenu *menuPtr) -{ - if (menuPtr->textGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->textGC); - } - if (menuPtr->disabledImageGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->disabledImageGC); - } - if (menuPtr->gray != None) { - Tk_FreeBitmap(menuPtr->display, menuPtr->gray); - } - if (menuPtr->disabledGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->disabledGC); - } - if (menuPtr->activeGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->activeGC); - } - if (menuPtr->indicatorGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->indicatorGC); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuEntryFreeDrawOptions -- - * - * Frees up drawing structures for a menu entry. Called when menu entry - * is freed. - * - * RESULTS: - * None. - * - * Side effects: - * Storage is freed. - * - *---------------------------------------------------------------------- - */ - -void -TkMenuEntryFreeDrawOptions( - TkMenuEntry *mePtr) -{ - if (mePtr->textGC != None) { - Tk_FreeGC(mePtr->menuPtr->display, mePtr->textGC); - } - if (mePtr->disabledGC != None) { - Tk_FreeGC(mePtr->menuPtr->display, mePtr->disabledGC); - } - if (mePtr->activeGC != None) { - Tk_FreeGC(mePtr->menuPtr->display, mePtr->activeGC); - } - if (mePtr->indicatorGC != None) { - Tk_FreeGC(mePtr->menuPtr->display, mePtr->indicatorGC); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuConfigureDrawOptions -- - * - * Sets the menu's drawing attributes in preparation for drawing the - * menu. - * - * RESULTS: - * None. - * - * Side effects: - * Storage is allocated. - * - *---------------------------------------------------------------------- - */ - -void -TkMenuConfigureDrawOptions( - TkMenu *menuPtr) /* The menu we are configuring. */ -{ - XGCValues gcValues; - GC newGC; - unsigned long mask; - 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. - */ - - border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - Tk_SetBackgroundFromBorder(menuPtr->tkwin, border); - - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - gcValues.font = Tk_FontId(tkfont); - fg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->fgPtr); - gcValues.foreground = fg->pixel; - gcValues.background = Tk_3DBorderColor(border)->pixel; - newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, - &gcValues); - if (menuPtr->textGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->textGC); - } - menuPtr->textGC = newGC; - - gcValues.font = Tk_FontId(tkfont); - gcValues.background = Tk_3DBorderColor(border)->pixel; - if (menuPtr->disabledFgPtr != NULL) { - XColor *disabledFg; - - disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, - menuPtr->disabledFgPtr); - gcValues.foreground = disabledFg->pixel; - mask = GCForeground|GCBackground|GCFont; - } else { - gcValues.foreground = gcValues.background; - mask = GCForeground; - if (menuPtr->gray == None) { - menuPtr->gray = Tk_GetBitmap(menuPtr->interp, menuPtr->tkwin, - "gray50"); - } - if (menuPtr->gray != None) { - gcValues.fill_style = FillStippled; - gcValues.stipple = menuPtr->gray; - mask = GCForeground|GCFillStyle|GCStipple; - } - } - newGC = Tk_GetGC(menuPtr->tkwin, mask, &gcValues); - if (menuPtr->disabledGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->disabledGC); - } - menuPtr->disabledGC = newGC; - - gcValues.foreground = Tk_3DBorderColor(border)->pixel; - if (menuPtr->gray == None) { - menuPtr->gray = Tk_GetBitmap(menuPtr->interp, menuPtr->tkwin, - "gray50"); - } - if (menuPtr->gray != None) { - gcValues.fill_style = FillStippled; - gcValues.stipple = menuPtr->gray; - newGC = Tk_GetGC(menuPtr->tkwin, - GCForeground|GCFillStyle|GCStipple, &gcValues); - } - if (menuPtr->disabledImageGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->disabledImageGC); - } - menuPtr->disabledImageGC = newGC; - - gcValues.font = Tk_FontId(tkfont); - activeFg = Tk_GetColorFromObj(menuPtr->tkwin, menuPtr->activeFgPtr); - gcValues.foreground = activeFg->pixel; - activeBorder = Tk_Get3DBorderFromObj(menuPtr->tkwin, - menuPtr->activeBorderPtr); - gcValues.background = Tk_3DBorderColor(activeBorder)->pixel; - newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, - &gcValues); - if (menuPtr->activeGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->activeGC); - } - menuPtr->activeGC = newGC; - - indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, - menuPtr->indicatorFgPtr); - gcValues.foreground = indicatorFg->pixel; - gcValues.background = Tk_3DBorderColor(border)->pixel; - newGC = Tk_GetGC(menuPtr->tkwin, GCForeground|GCBackground|GCFont, - &gcValues); - if (menuPtr->indicatorGC != None) { - Tk_FreeGC(menuPtr->display, menuPtr->indicatorGC); - } - menuPtr->indicatorGC = newGC; -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuConfigureEntryDrawOptions -- - * - * Calculates any entry-specific draw options for the given menu entry. - * - * Results: - * Returns a standard Tcl error. - * - * Side effects: - * Storage may be allocated. - * - *---------------------------------------------------------------------- - */ - -int -TkMenuConfigureEntryDrawOptions( - TkMenuEntry *mePtr, - int index) -{ - XGCValues gcValues; - GC newGC, newActiveGC, newDisabledGC, newIndicatorGC; - unsigned long mask; - Tk_Font tkfont; - TkMenu *menuPtr = mePtr->menuPtr; - - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, - (mePtr->fontPtr != NULL) ? mePtr->fontPtr : menuPtr->fontPtr); - - if (mePtr->state == ENTRY_ACTIVE) { - if (index != menuPtr->active) { - TkActivateMenuEntry(menuPtr, index); - } - } else { - if (index == menuPtr->active) { - TkActivateMenuEntry(menuPtr, -1); - } - } - - if ((mePtr->fontPtr != NULL) - || (mePtr->borderPtr != NULL) - || (mePtr->fgPtr != NULL) - || (mePtr->activeBorderPtr != NULL) - || (mePtr->activeFgPtr != NULL) - || (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 - : 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. - */ - - gcValues.graphics_exposures = False; - newGC = Tk_GetGC(menuPtr->tkwin, - GCForeground|GCBackground|GCFont|GCGraphicsExposures, - &gcValues); - - indicatorFg = Tk_GetColorFromObj(menuPtr->tkwin, - (mePtr->indicatorFgPtr != NULL) ? mePtr->indicatorFgPtr - : menuPtr->indicatorFgPtr); - gcValues.foreground = indicatorFg->pixel; - newIndicatorGC = Tk_GetGC(menuPtr->tkwin, - GCForeground|GCBackground|GCGraphicsExposures, - &gcValues); - - if ((menuPtr->disabledFgPtr != NULL) || (mePtr->image != NULL)) { - XColor *disabledFg; - - disabledFg = Tk_GetColorFromObj(menuPtr->tkwin, - menuPtr->disabledFgPtr); - gcValues.foreground = disabledFg->pixel; - mask = GCForeground|GCBackground|GCFont|GCGraphicsExposures; - } else { - gcValues.foreground = gcValues.background; - gcValues.fill_style = FillStippled; - gcValues.stipple = menuPtr->gray; - mask = GCForeground|GCFillStyle|GCStipple; - } - newDisabledGC = Tk_GetGC(menuPtr->tkwin, mask, &gcValues); - - activeFg = Tk_GetColorFromObj(menuPtr->tkwin, - (mePtr->activeFgPtr != NULL) ? mePtr->activeFgPtr - : menuPtr->activeFgPtr); - 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, - GCForeground|GCBackground|GCFont|GCGraphicsExposures, - &gcValues); - } else { - newGC = None; - newActiveGC = None; - newDisabledGC = None; - newIndicatorGC = None; - } - if (mePtr->textGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->textGC); - } - mePtr->textGC = newGC; - if (mePtr->activeGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->activeGC); - } - mePtr->activeGC = newActiveGC; - if (mePtr->disabledGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->disabledGC); - } - mePtr->disabledGC = newDisabledGC; - if (mePtr->indicatorGC != None) { - Tk_FreeGC(menuPtr->display, mePtr->indicatorGC); - } - mePtr->indicatorGC = newIndicatorGC; - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkEventuallyRecomputeMenu -- - * - * Tells Tcl to redo the geometry because this menu has changed. - * - * Results: - * None. - * - * Side effects: - * Menu geometry is recomputed at idle time, and the menu will be - * redisplayed. - * - *---------------------------------------------------------------------- - */ - -void -TkEventuallyRecomputeMenu( - TkMenu *menuPtr) -{ - if (!(menuPtr->menuFlags & RESIZE_PENDING)) { - menuPtr->menuFlags |= RESIZE_PENDING; - Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkRecomputeMenu -- - * - * Tells Tcl to redo the geometry because this menu has changed. Does it - * now; removes any ComputeMenuGeometries from the idler. - * - * Results: - * None. - * - * Side effects: - * Menu geometry is immediately reconfigured. - * - *---------------------------------------------------------------------- - */ - -void -TkRecomputeMenu( - TkMenu *menuPtr) -{ - if (menuPtr->menuFlags & RESIZE_PENDING) { - Tcl_CancelIdleCall(ComputeMenuGeometry, menuPtr); - ComputeMenuGeometry(menuPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkEventuallyRedrawMenu -- - * - * 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. - * - *---------------------------------------------------------------------- - */ - -void -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; - } - if (mePtr != NULL) { - mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY; - } else { - for (i = 0; i < menuPtr->numEntries; i++) { - menuPtr->entries[i]->entryFlags |= ENTRY_NEEDS_REDISPLAY; - } - } - if (!Tk_IsMapped(menuPtr->tkwin) - || (menuPtr->menuFlags & REDRAW_PENDING)) { - return; - } - Tcl_DoWhenIdle(DisplayMenu, menuPtr); - menuPtr->menuFlags |= REDRAW_PENDING; -} - -/* - *-------------------------------------------------------------- - * - * ComputeMenuGeometry -- - * - * 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. - * - *-------------------------------------------------------------- - */ - -static void -ComputeMenuGeometry( - ClientData clientData) /* Structure describing menu. */ -{ - TkMenu *menuPtr = clientData; - - if (menuPtr->tkwin == NULL) { - return; - } - - if (menuPtr->menuType == MENUBAR) { - TkpComputeMenubarGeometry(menuPtr); - } else { - TkpComputeStandardMenuGeometry(menuPtr); - } - - if ((menuPtr->totalWidth != Tk_ReqWidth(menuPtr->tkwin)) || - (menuPtr->totalHeight != Tk_ReqHeight(menuPtr->tkwin))) { - 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. - */ - - TkEventuallyRedrawMenu(menuPtr, NULL); - - menuPtr->menuFlags &= ~RESIZE_PENDING; -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuSelectImageProc -- - * - * 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. - * - * Side effects: - * Arranges for the menu to get redisplayed. - * - *---------------------------------------------------------------------- - */ - -void -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 = clientData; - - if ((mePtr->entryFlags & ENTRY_SELECTED) - && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) { - mePtr->menuPtr->menuFlags |= REDRAW_PENDING; - Tcl_DoWhenIdle(DisplayMenu, mePtr->menuPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * DisplayMenu -- - * - * 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. - * - *---------------------------------------------------------------------- - */ - -static void -DisplayMenu( - ClientData clientData) /* Information about widget. */ -{ - register TkMenu *menuPtr = clientData; - register TkMenuEntry *mePtr; - register Tk_Window tkwin = menuPtr->tkwin; - int index, strictMotif; - Tk_Font tkfont; - Tk_FontMetrics menuMetrics; - int width; - int borderWidth; - Tk_3DBorder border; - int activeBorderWidth; - int relief; - - - menuPtr->menuFlags &= ~REDRAW_PENDING; - if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { - return; - } - - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, - &borderWidth); - border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - - if (menuPtr->menuType == MENUBAR) { - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, - borderWidth, Tk_Width(tkwin) - 2 * borderWidth, - Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT); - } - - strictMotif = Tk_StrictMotif(menuPtr->tkwin); - - /* - * See note in ComputeMenuGeometry. We don't want to be doing font metrics - * all of the time. - */ - - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(tkfont, &menuMetrics); - - /* - * Loop through all of the entries, drawing them one at a time. - */ - - for (index = 0; index < menuPtr->numEntries; index++) { - mePtr = menuPtr->entries[index]; - if (menuPtr->menuType != MENUBAR) { - if (!(mePtr->entryFlags & ENTRY_NEEDS_REDISPLAY)) { - continue; - } - } - mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY; - - if (menuPtr->menuType == MENUBAR) { - width = mePtr->width; - } else { - if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { - width = Tk_Width(menuPtr->tkwin) - mePtr->x - - activeBorderWidth; - } else { - width = mePtr->width + borderWidth; - } - } - TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont, - &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->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - activeBorderWidth, 0, - TK_RELIEF_FLAT); - } - } - - if (menuPtr->menuType != MENUBAR) { - int x, y, height; - - if (menuPtr->numEntries == 0) { - x = y = borderWidth; - width = Tk_Width(tkwin) - 2 * activeBorderWidth; - height = Tk_Height(tkwin) - 2 * activeBorderWidth; - } else { - mePtr = menuPtr->entries[menuPtr->numEntries - 1]; - Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), - border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - activeBorderWidth, 0, - TK_RELIEF_FLAT); - x = mePtr->x + mePtr->width; - y = mePtr->y + mePtr->height; - width = Tk_Width(tkwin) - x - activeBorderWidth; - height = Tk_Height(tkwin) - y - activeBorderWidth; - } - 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, - relief); -} - -/* - *-------------------------------------------------------------- - * - * TkMenuEventProc -- - * - * 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. - * - *-------------------------------------------------------------- - */ - -void -TkMenuEventProc( - ClientData clientData, /* Information about window. */ - XEvent *eventPtr) /* Information about event. */ -{ - TkMenu *menuPtr = clientData; - - if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) { - TkEventuallyRedrawMenu(menuPtr, NULL); - } else if (eventPtr->type == ConfigureNotify) { - TkEventuallyRecomputeMenu(menuPtr); - TkEventuallyRedrawMenu(menuPtr, NULL); - } else if (eventPtr->type == ActivateNotify) { - if (menuPtr->menuType == TEAROFF_MENU) { - TkpSetMainMenubar(menuPtr->interp, menuPtr->tkwin, NULL); - } - } else if (eventPtr->type == DestroyNotify) { - if (menuPtr->tkwin != NULL) { - if (!(menuPtr->menuFlags & MENU_DELETION_PENDING)) { - TkDestroyMenu(menuPtr); - } - menuPtr->tkwin = NULL; - } - if (menuPtr->menuFlags & MENU_WIN_DESTRUCTION_PENDING) { - return; - } - menuPtr->menuFlags |= MENU_WIN_DESTRUCTION_PENDING; - if (menuPtr->widgetCmd != NULL) { - Tcl_DeleteCommandFromToken(menuPtr->interp, menuPtr->widgetCmd); - menuPtr->widgetCmd = NULL; - } - if (menuPtr->menuFlags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayMenu, menuPtr); - menuPtr->menuFlags &= ~REDRAW_PENDING; - } - if (menuPtr->menuFlags & RESIZE_PENDING) { - Tcl_CancelIdleCall(ComputeMenuGeometry, menuPtr); - menuPtr->menuFlags &= ~RESIZE_PENDING; - } - Tcl_EventuallyFree(menuPtr, TCL_DYNAMIC); - } -} - -/* - *---------------------------------------------------------------------- - * - * TkMenuImageProc -- - * - * 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. - * - * Side effects: - * Arranges for the menu to get redisplayed. - * - *---------------------------------------------------------------------- - */ - -void -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)) { - menuPtr->menuFlags |= RESIZE_PENDING; - Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr); - } -} - -/* - *---------------------------------------------------------------------- - * - * 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. - * - * Results: - * Returns a standard Tcl Error. - * - * Side effects: - * The menu is posted. - * - *---------------------------------------------------------------------- - */ - -int -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 result; - - TkActivateMenuEntry(menuPtr, -1); - TkRecomputeMenu(menuPtr); - result = TkPostCommand(menuPtr); - if (result != TCL_OK) { - return result; - } - - /* - * The post commands could have deleted the menu, which means we are dead - * and should go away. - */ - - if (menuPtr->tkwin == NULL) { - return TCL_OK; - } - - /* - * 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. - */ - - Tk_GetVRootGeometry(Tk_Parent(menuPtr->tkwin), &vRootX, &vRootY, - &vRootWidth, &vRootHeight); - vRootWidth -= Tk_ReqWidth(menuPtr->tkwin); - if (x > vRootX + vRootWidth) { - x = vRootX + vRootWidth; - } - if (x < vRootX) { - x = vRootX; - } - vRootHeight -= Tk_ReqHeight(menuPtr->tkwin); - if (y > vRootY + vRootHeight) { - y = vRootY + vRootHeight; - } - if (y < vRootY) { - y = vRootY; - } - Tk_MoveToplevelWindow(menuPtr->tkwin, x, y); - if (!Tk_IsMapped(menuPtr->tkwin)) { - Tk_MapWindow(menuPtr->tkwin); - } - TkWmRestackToplevel((TkWindow *) menuPtr->tkwin, Above, NULL); - return TCL_OK; -} - -/* - *-------------------------------------------------------------- - * - * TkPostSubmenu -- - * - * 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. - * - * Side effects: - * If there is already a submenu posted, it is unposted. The new submenu - * is then posted. - * - *-------------------------------------------------------------- - */ - -int -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. */ -{ - int result, x, y; - Tcl_Obj *subary[4]; - - if (mePtr == menuPtr->postedCascade) { - return TCL_OK; - } - - if (menuPtr->postedCascade != NULL) { - /* - * 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. - */ - - 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; - } - } - - 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). - * - * 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] - */ - - Tk_GetRootCoords(menuPtr->tkwin, &x, &y); - AdjustMenuCoords(menuPtr, mePtr, &x, &y); - - menuPtr->postedCascade = mePtr; - 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; - } - TkEventuallyRedrawMenu(menuPtr, mePtr); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * AdjustMenuCoords -- - * - * Adjusts the given coordinates down and the left to give a Motif look. - * - * Results: - * None. - * - * Side effects: - * The menu is eventually redrawn if necessary. - * - *---------------------------------------------------------------------- - */ - -static void -AdjustMenuCoords( - TkMenu *menuPtr, - TkMenuEntry *mePtr, - int *xPtr, - int *yPtr) -{ - if (menuPtr->menuType == MENUBAR) { - *xPtr += mePtr->x; - *yPtr += mePtr->y + mePtr->height; - } else { - int borderWidth, activeBorderWidth; - - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, - &borderWidth); - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); - *xPtr += Tk_Width(menuPtr->tkwin) - borderWidth - activeBorderWidth - - 2; - *yPtr += mePtr->y + activeBorderWidth + 2; - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |