⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tkmenu.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
	Tcl_UntraceVar(menuPtr->interp, mePtr->name,		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,		MenuVarProc, (ClientData) mePtr);    }    TkpDestroyMenuEntry(mePtr);    TkMenuEntryFreeDrawOptions(mePtr);    Tk_FreeOptions(tkMenuEntryConfigSpecs, (char *) mePtr, menuPtr->display, 	    (COMMAND_MASK << mePtr->type));    ckfree((char *) mePtr);}/* *--------------------------------------------------------------------------- * * MenuWorldChanged -- * *      This procedure is called when the world has changed in some *      way (such as the fonts in the system changing) and the widget needs *	to recompute all its graphics contexts and determine its new geometry. * * Results: *      None. * * Side effects: *      Menu will be relayed out and redisplayed. * *--------------------------------------------------------------------------- */ static voidMenuWorldChanged(instanceData)    ClientData instanceData;	/* Information about widget. */{    TkMenu *menuPtr = (TkMenu *) instanceData;    int i;        TkMenuConfigureDrawOptions(menuPtr);    for (i = 0; i < menuPtr->numEntries; i++) {    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],		menuPtr->entries[i]->index);	TkpConfigureMenuEntry(menuPtr->entries[i]);	    }}/* *---------------------------------------------------------------------- * * ConfigureMenu -- * *	This procedure is called to process an argv/argc list, plus *	the Tk option database, in order to configure (or *	reconfigure) a menu widget. * * Results: *	The return value is a standard Tcl result.  If TCL_ERROR is *	returned, then interp->result contains an error message. * * Side effects: *	Configuration information, such as colors, font, etc. get set *	for menuPtr;  old resources get freed, if there were any. * *---------------------------------------------------------------------- */static intConfigureMenu(interp, menuPtr, argc, argv, flags)    Tcl_Interp *interp;		/* Used for error reporting. */    register TkMenu *menuPtr;	/* Information about widget;  may or may				 * not already have values for some fields. */    int argc;			/* Number of valid entries in argv. */    char **argv;		/* Arguments. */    int flags;			/* Flags to pass to Tk_ConfigureWidget. */{    int i;    TkMenu* menuListPtr;        for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;	    menuListPtr = menuListPtr->nextInstancePtr) {    	if (Tk_ConfigureWidget(interp, menuListPtr->tkwin,		tkMenuConfigSpecs, argc, argv, (char *) menuListPtr,		flags) != TCL_OK) {	    return TCL_ERROR;	}	/*	 * When a menu is created, the type is in all of the arguments	 * to the menu command. Let Tk_ConfigureWidget take care of	 * parsing them, and then set the type after we can look at	 * the type string. Once set, a menu's type cannot be changed	 */		if (menuListPtr->menuType == UNKNOWN_TYPE) {	    if (strcmp(menuListPtr->menuTypeName, "menubar") == 0) {	    	menuListPtr->menuType = MENUBAR;	    } else if (strcmp(menuListPtr->menuTypeName, "tearoff") == 0) {	    	menuListPtr->menuType = TEAROFF_MENU;	    } else {	    	menuListPtr->menuType = MASTER_MENU;	    }	}		/*	 * Depending on the -tearOff option, make sure that there is or	 * isn't an initial tear-off entry at the beginning of the menu.	 */		if (menuListPtr->tearOff) {	    if ((menuListPtr->numEntries == 0)		    || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) {		if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) {		    return TCL_ERROR;		}	    }	} else if ((menuListPtr->numEntries > 0)		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {	    int i;	    Tcl_EventuallyFree((ClientData) menuListPtr->entries[0],	    	    DestroyMenuEntry);	    for (i = 0; i < menuListPtr->numEntries - 1; i++) {		menuListPtr->entries[i] = menuListPtr->entries[i + 1];		menuListPtr->entries[i]->index = i;	    }	    menuListPtr->numEntries--;	    if (menuListPtr->numEntries == 0) {		ckfree((char *) menuListPtr->entries);		menuListPtr->entries = NULL;	    }	}	TkMenuConfigureDrawOptions(menuListPtr);	/*	 * Configure the new window to be either a pop-up menu	 * or a tear-off menu.	 * We don't do this for menubars since they are not toplevel	 * windows. Also, since this gets called before CloneMenu has	 * a chance to set the menuType field, we have to look at the	 * menuTypeName field to tell that this is a menu bar.	 */		if (strcmp(menuListPtr->menuTypeName, "normal") == 0) {	    TkpMakeMenuWindow(menuListPtr->tkwin, 1);	} else if (strcmp(menuListPtr->menuTypeName, "tearoff") == 0) {	    TkpMakeMenuWindow(menuListPtr->tkwin, 0);	}		/*	 * After reconfiguring a menu, we need to reconfigure all of the	 * entries in the menu, since some of the things in the children	 * (such as graphics contexts) may have to change to reflect changes	 * in the parent.	 */		for (i = 0; i < menuListPtr->numEntries; i++) {	    TkMenuEntry *mePtr;		    mePtr = menuListPtr->entries[i];	    ConfigureMenuEntry(mePtr, 0,	    	    (char **) NULL, TK_CONFIG_ARGV_ONLY 	    	    | COMMAND_MASK << mePtr->type);	}		TkEventuallyRecomputeMenu(menuListPtr);    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * ConfigureMenuEntry -- * *	This procedure is called to process an argv/argc list in order *	to configure (or reconfigure) one entry in a menu. * * Results: *	The return value is a standard Tcl result.  If TCL_ERROR is *	returned, then interp->result contains an error message. * * Side effects: *	Configuration information such as label and accelerator get *	set for mePtr;  old resources get freed, if there were any. * *---------------------------------------------------------------------- */static intConfigureMenuEntry(mePtr, argc, argv, flags)    register TkMenuEntry *mePtr;		/* Information about menu entry;  may					 * or may not already have values for					 * some fields. */    int argc;				/* Number of valid entries in argv. */    char **argv;			/* Arguments. */    int flags;				/* Additional flags to pass to					 * Tk_ConfigureWidget. */{    TkMenu *menuPtr = mePtr->menuPtr;    int index = mePtr->index;    Tk_Image image;    /*     * If this entry is a check button or radio button, then remove     * its old trace procedure.     */    if ((mePtr->name != NULL)    	    && ((mePtr->type == CHECK_BUTTON_ENTRY)	    || (mePtr->type == RADIO_BUTTON_ENTRY))) {	Tcl_UntraceVar(menuPtr->interp, mePtr->name,		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,		MenuVarProc, (ClientData) mePtr);    }        if (menuPtr->tkwin != NULL) {	if (Tk_ConfigureWidget(menuPtr->interp, menuPtr->tkwin, 		tkMenuEntryConfigSpecs, argc, argv, (char *) mePtr,		flags | (COMMAND_MASK << mePtr->type)) != TCL_OK) {	    return TCL_ERROR;	}    }    /*     * The code below handles special configuration stuff not taken     * care of by Tk_ConfigureWidget, such as special processing for     * defaults, sizing strings, graphics contexts, etc.     */    if (mePtr->label == NULL) {	mePtr->labelLength = 0;    } else {	mePtr->labelLength = strlen(mePtr->label);    }    if (mePtr->accel == NULL) {	mePtr->accelLength = 0;    } else {	mePtr->accelLength = strlen(mePtr->accel);    }    /*     * If this is a cascade entry, the platform-specific data of the child     * menu has to be updated. Also, the links that point to parents and     * cascades have to be updated.     */    if ((mePtr->type == CASCADE_ENTRY) && (mePtr->name != NULL)) { 	TkMenuEntry *cascadeEntryPtr; 	TkMenu *cascadeMenuPtr;	int alreadyThere;	TkMenuReferences *menuRefPtr;	char *oldHashKey = NULL;	/* Initialization only needed to					 * prevent compiler warning. */	/*	 * This is a cascade entry. If the menu that the cascade entry	 * is pointing to has changed, we need to remove this entry	 * from the list of entries pointing to the old menu, and add a	 * cascade reference to the list of entries pointing to the	 * new menu.	 *	 * BUG: We are not recloning for special case #3 yet.	 */		if (mePtr->childMenuRefPtr != NULL) {	    oldHashKey = Tcl_GetHashKey(TkGetMenuHashTable(menuPtr->interp),		    mePtr->childMenuRefPtr->hashEntryPtr);	    if (strcmp(oldHashKey, mePtr->name) != 0) {		UnhookCascadeEntry(mePtr);	    }	}	if ((mePtr->childMenuRefPtr == NULL) 		|| (strcmp(oldHashKey, mePtr->name) != 0)) {	    menuRefPtr = TkCreateMenuReferences(menuPtr->interp,		    mePtr->name);	    cascadeMenuPtr = menuRefPtr->menuPtr;	    mePtr->childMenuRefPtr = menuRefPtr;	    if (menuRefPtr->parentEntryPtr == NULL) {		menuRefPtr->parentEntryPtr = mePtr;	    } else {		alreadyThere = 0;		for (cascadeEntryPtr = menuRefPtr->parentEntryPtr;			cascadeEntryPtr != NULL;			cascadeEntryPtr =			cascadeEntryPtr->nextCascadePtr) {		    if (cascadeEntryPtr == mePtr) {			alreadyThere = 1;			break;		    }		}    		/*		 * Put the item at the front of the list.		 */	    		if (!alreadyThere) {		    mePtr->nextCascadePtr = menuRefPtr->parentEntryPtr;		    menuRefPtr->parentEntryPtr = mePtr;		}	    }	}    }        if (TkMenuConfigureEntryDrawOptions(mePtr, index) != TCL_OK) {    	return TCL_ERROR;    }    if (TkpConfigureMenuEntry(mePtr) != TCL_OK) {    	return TCL_ERROR;    }        if ((mePtr->type == CHECK_BUTTON_ENTRY)	    || (mePtr->type == RADIO_BUTTON_ENTRY)) {	char *value;	if (mePtr->name == NULL) {	    mePtr->name =		    (char *) ckalloc((unsigned) (mePtr->labelLength + 1));	    strcpy(mePtr->name, (mePtr->label == NULL) ? "" : mePtr->label);	}	if (mePtr->onValue == NULL) {	    mePtr->onValue = (char *) ckalloc((unsigned)		    (mePtr->labelLength + 1));	    strcpy(mePtr->onValue, (mePtr->label == NULL) ? "" : mePtr->label);	}	/*	 * Select the entry if the associated variable has the	 * appropriate value, initialize the variable if it doesn't	 * exist, then set a trace on the variable to monitor future	 * changes to its value.	 */	value = Tcl_GetVar(menuPtr->interp, mePtr->name, TCL_GLOBAL_ONLY);	mePtr->entryFlags &= ~ENTRY_SELECTED;	if (value != NULL) {	    if (strcmp(value, mePtr->onValue) == 0) {		mePtr->entryFlags |= ENTRY_SELECTED;	    }	} else {	    Tcl_SetVar(menuPtr->interp, mePtr->name,		    (mePtr->type == CHECK_BUTTON_ENTRY) ? mePtr->offValue : "",		    TCL_GLOBAL_ONLY);	}	Tcl_TraceVar(menuPtr->interp, mePtr->name,		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,		MenuVarProc, (ClientData) mePtr);    }    /*     * Get the images for the entry, if there are any.  Allocate the     * new images before freeing the old ones, so that the reference     * counts don't go to zero and cause image data to be discarded.     */    if (mePtr->imageString != NULL) {	image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, mePtr->imageString,		TkMenuImageProc, (ClientData) mePtr);	if (image == NULL) {	    return TCL_ERROR;	}    } else {	image = NULL;    }    if (mePtr->image != NULL) {	Tk_FreeImage(mePtr->image);    }    mePtr->image = image;    if (mePtr->selectImageString != NULL) {	image = Tk_GetImage(menuPtr->interp, menuPtr->tkwin, mePtr->selectImageString,		TkMenuSelectImageProc, (ClientData) mePtr);	if (image == NULL) {	    return TCL_ERROR;	}    } else {	image = NULL;    }    if (mePtr->selectImage != NULL) {	Tk_FreeImage(mePtr->selectImage);    }    mePtr->selectImage = image;    TkEventuallyRecomputeMenu(menuPtr);        return TCL_OK;}/* *---------------------------------------------------------------------- * * ConfigureMenuCloneEntries -- * *	Calls ConfigureMenuEntry for each menu in the clone chain. * * Results: *	The return value is a standard Tcl result.  If TCL_ERROR is *	returned, then interp->result contains an error message. * * Side effects: *	Configuration information such as label and accelerator get *	set for mePtr;  old resources get freed, if there were any. *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -