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

📄 tkmenu.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
	    case CHECK_BUTTON_ENTRY:		interp->result = "checkbutton";		break;	    case RADIO_BUTTON_ENTRY:		interp->result = "radiobutton";		break;	    case CASCADE_ENTRY:		interp->result = "cascade";		break;	    case TEAROFF_ENTRY:		interp->result = "tearoff";		break;	}    } else if ((c == 'u') && (strncmp(argv[1], "unpost", length) == 0)) {	if (argc != 2) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",		    argv[0], " unpost\"", (char *) NULL);	    goto error;	}	Tk_UnmapWindow(menuPtr->tkwin);	result = TkPostSubmenu(interp, menuPtr, (TkMenuEntry *) NULL);    } else if ((c == 'y') && (strncmp(argv[1], "yposition", length) == 0)) {	if (argc != 3) {	    Tcl_AppendResult(interp, "wrong # args: should be \"",		    argv[0], " yposition index\"", (char *) NULL);	    goto error;	}	result = MenuDoYPosition(interp, menuPtr, argv[2]);    } else {	Tcl_AppendResult(interp, "bad option \"", argv[1],		"\": must be activate, add, cget, clone, configure, delete, ",		"entrycget, entryconfigure, index, insert, invoke, ",		"post, postcascade, type, unpost, or yposition",		(char *) NULL);	goto error;    }    done:    Tcl_Release((ClientData) menuPtr);    return result;    error:    Tcl_Release((ClientData) menuPtr);    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * TkInvokeMenu -- * *	Given a menu and an index, takes the appropriate action for the *	entry associated with that index. * * Results: *	Standard Tcl result. * * Side effects: *	Commands may get excecuted; variables may get set; sub-menus may *	get posted. * *---------------------------------------------------------------------- */intTkInvokeMenu(interp, menuPtr, index)    Tcl_Interp *interp;		/* The interp that the menu lives in. */    TkMenu *menuPtr;		/* The menu we are invoking. */    int index;			/* The zero based index of the item we    				 * are invoking */{    int result = TCL_OK;    TkMenuEntry *mePtr;        if (index < 0) {    	goto done;    }    mePtr = menuPtr->entries[index];    if (mePtr->state == tkDisabledUid) {	goto done;    }    Tcl_Preserve((ClientData) mePtr);    if (mePtr->type == TEAROFF_ENTRY) {    	Tcl_DString commandDString;    	    	Tcl_DStringInit(&commandDString);    	Tcl_DStringAppendElement(&commandDString, "tkTearOffMenu");    	Tcl_DStringAppendElement(&commandDString, Tk_PathName(menuPtr->tkwin));    	result = Tcl_Eval(interp, Tcl_DStringValue(&commandDString));    	Tcl_DStringFree(&commandDString);    } else if (mePtr->type == CHECK_BUTTON_ENTRY) {	if (mePtr->entryFlags & ENTRY_SELECTED) {	    if (Tcl_SetVar(interp, mePtr->name, mePtr->offValue,		    TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {		result = TCL_ERROR;	    }	} else {	    if (Tcl_SetVar(interp, mePtr->name, mePtr->onValue,		    TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {		result = TCL_ERROR;	    }	}    } else if (mePtr->type == RADIO_BUTTON_ENTRY) {	if (Tcl_SetVar(interp, mePtr->name, mePtr->onValue,		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {	    result = TCL_ERROR;	}    }    if ((result == TCL_OK) && (mePtr->command != NULL)) {	result = TkCopyAndGlobalEval(interp, mePtr->command);    }    Tcl_Release((ClientData) mePtr);    done:    return result; }/* *---------------------------------------------------------------------- * * DestroyMenuInstance -- * *	This procedure is invoked by TkDestroyMenu *	to clean up the internal structure of a menu at a safe time *	(when no-one is using it anymore). Only takes care of one instance *	of the menu. * * Results: *	None. * * Side effects: *	Everything associated with the menu is freed up. * *---------------------------------------------------------------------- */static voidDestroyMenuInstance(menuPtr)    TkMenu *menuPtr;	/* Info about menu widget. */{    int i, numEntries = menuPtr->numEntries;    TkMenu *menuInstancePtr;    TkMenuEntry *cascadePtr, *nextCascadePtr;    char *newArgv[2];    TkMenu *parentMasterMenuPtr;    TkMenuEntry *parentMasterEntryPtr;    TkMenu *parentMenuPtr;        /*     * If the menu has any cascade menu entries pointing to it, the cascade     * entries need to be told that the menu is going away. We need to clear     * the menu ptr field in the menu reference at this point in the code     * so that everything else can forget about this menu properly. We also     * need to reset -menu field of all entries that are not master menus     * back to this entry name if this is a master menu pointed to by another     * master menu. If there is a clone menu that points to this menu,     * then this menu is itself a clone, so when this menu goes away,     * the -menu field of the pointing entry must be set back to this     * menu's master menu name so that later if another menu is created     * the cascade hierarchy can be maintained.     */    TkpDestroyMenu(menuPtr);    cascadePtr = menuPtr->menuRefPtr->parentEntryPtr;    menuPtr->menuRefPtr->menuPtr = NULL;    TkFreeMenuReferences(menuPtr->menuRefPtr);    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {    	parentMenuPtr = cascadePtr->menuPtr;    	nextCascadePtr = cascadePtr->nextCascadePtr;    	    	if (menuPtr->masterMenuPtr != menuPtr) {	    parentMasterMenuPtr = cascadePtr->menuPtr->masterMenuPtr;	    parentMasterEntryPtr =		    parentMasterMenuPtr->entries[cascadePtr->index];	    newArgv[0] = "-menu";	    newArgv[1] = parentMasterEntryPtr->name;    	    ConfigureMenuEntry(cascadePtr, 2, newArgv, TK_CONFIG_ARGV_ONLY);    	} else {    	    ConfigureMenuEntry(cascadePtr, 0, (char **) NULL, 0);    	}    }        if (menuPtr->masterMenuPtr != menuPtr) {        for (menuInstancePtr = menuPtr->masterMenuPtr;         	menuInstancePtr != NULL;        	menuInstancePtr = menuInstancePtr->nextInstancePtr) {            if (menuInstancePtr->nextInstancePtr == menuPtr) {                menuInstancePtr->nextInstancePtr =                 	menuInstancePtr->nextInstancePtr->nextInstancePtr;                break;            }        }   } else if (menuPtr->nextInstancePtr != NULL) {       panic("Attempting to delete master menu when there are still clones.");   }    /*     * Free up all the stuff that requires special handling, then     * let Tk_FreeOptions handle all the standard option-related     * stuff.     */    for (i = numEntries - 1; i >= 0; i--) {	DestroyMenuEntry((char *) menuPtr->entries[i]);    }    if (menuPtr->entries != NULL) {	ckfree((char *) menuPtr->entries);    }    TkMenuFreeDrawOptions(menuPtr);    Tk_FreeOptions(tkMenuConfigSpecs, (char *) menuPtr, menuPtr->display, 0);    Tcl_EventuallyFree((ClientData) menuPtr, TCL_DYNAMIC);}/* *---------------------------------------------------------------------- * * TkDestroyMenu -- * *	This procedure is invoked by Tcl_EventuallyFree or Tcl_Release *	to clean up the internal structure of a menu at a safe time *	(when no-one is using it anymore).  If called on a master instance, *	destroys all of the slave instances. If called on a non-master *	instance, just destroys that instance. * * Results: *	None. * * Side effects: *	Everything associated with the menu is freed up. * *---------------------------------------------------------------------- */voidTkDestroyMenu(menuPtr)    TkMenu *menuPtr;	/* Info about menu widget. */{    TkMenu *menuInstancePtr;    TkMenuTopLevelList *topLevelListPtr, *nextTopLevelPtr;    if (menuPtr->menuFlags & MENU_DELETION_PENDING) {    	return;    }        /*     * Now destroy all non-tearoff instances of this menu if this is a      * parent menu. Is this loop safe enough? Are there going to be     * destroy bindings on child menus which kill the parent? If not,     * we have to do a slightly more complex scheme.     */        if (menuPtr->masterMenuPtr == menuPtr) {    	menuPtr->menuFlags |= MENU_DELETION_PENDING;	while (menuPtr->nextInstancePtr != NULL) {	    menuInstancePtr = menuPtr->nextInstancePtr;	    menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;    	    if (menuInstancePtr->tkwin != NULL) {	     	Tk_DestroyWindow(menuInstancePtr->tkwin);	    }	}    	menuPtr->menuFlags &= ~MENU_DELETION_PENDING;    }    /*     * If any toplevel widgets have this menu as their menubar,     * the geometry of the window may have to be recalculated.     */        topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;    while (topLevelListPtr != NULL) {         nextTopLevelPtr = topLevelListPtr->nextPtr;         TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);    	 topLevelListPtr = nextTopLevelPtr;    }       DestroyMenuInstance(menuPtr);}/* *---------------------------------------------------------------------- * * UnhookCascadeEntry -- * *	This entry is removed from the list of entries that point to the *	cascade menu. This is done in preparation for changing the menu *	that this entry points to. * * Results: *	None * * Side effects: *	The appropriate lists are modified. * *---------------------------------------------------------------------- */static voidUnhookCascadeEntry(mePtr)    TkMenuEntry *mePtr;			/* The cascade entry we are removing					 * from the cascade list. */{    TkMenuEntry *cascadeEntryPtr;    TkMenuEntry *prevCascadePtr;    TkMenuReferences *menuRefPtr;    menuRefPtr = mePtr->childMenuRefPtr;    if (menuRefPtr == NULL) {        return;    }        cascadeEntryPtr = menuRefPtr->parentEntryPtr;    if (cascadeEntryPtr == NULL) {    	return;    }        /*     * Singularly linked list deletion. The two special cases are     * 1. one element; 2. The first element is the one we want.     */     if (cascadeEntryPtr == mePtr) {    	if (cascadeEntryPtr->nextCascadePtr == NULL) {	    /*	     * This is the last menu entry which points to this	     * menu, so we need to clear out the list pointer in the	     * cascade itself.	     */		    menuRefPtr->parentEntryPtr = NULL;	    TkFreeMenuReferences(menuRefPtr);    	} else {    	    menuRefPtr->parentEntryPtr = cascadeEntryPtr->nextCascadePtr;    	}    	mePtr->nextCascadePtr = NULL;    } else {	for (prevCascadePtr = cascadeEntryPtr,		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr;		cascadeEntryPtr != NULL;	        prevCascadePtr = cascadeEntryPtr,		cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) {    	    if (cascadeEntryPtr == mePtr){    	    	prevCascadePtr->nextCascadePtr =            	    	cascadeEntryPtr->nextCascadePtr;    	    	cascadeEntryPtr->nextCascadePtr = NULL;    	    	break;    	    }        }    }    mePtr->childMenuRefPtr = NULL;}/* *---------------------------------------------------------------------- * * DestroyMenuEntry -- * *	This procedure is invoked by Tcl_EventuallyFree or Tcl_Release *	to clean up the internal structure of a menu entry at a safe time *	(when no-one is using it anymore). * * Results: *	None. * * Side effects: *	Everything associated with the menu entry is freed. * *---------------------------------------------------------------------- */static voidDestroyMenuEntry(memPtr)    char *memPtr;		/* Pointer to entry to be freed. */{    register TkMenuEntry *mePtr = (TkMenuEntry *) memPtr;    TkMenu *menuPtr = mePtr->menuPtr;    if (menuPtr->postedCascade == mePtr) {	    	/*	 * Ignore errors while unposting the menu, since it's possible	 * that the menu has already been deleted and the unpost will	 * generate an error.	 */	TkPostSubmenu(menuPtr->interp, menuPtr, (TkMenuEntry *) NULL);    }    /*     * Free up all the stuff that requires special handling, then     * let Tk_FreeOptions handle all the standard option-related     * stuff.     */    if (mePtr->type == CASCADE_ENTRY) {        UnhookCascadeEntry(mePtr);    }    if (mePtr->image != NULL) {	Tk_FreeImage(mePtr->image);    }    if (mePtr->selectImage != NULL) {	Tk_FreeImage(mePtr->selectImage);    }    if (mePtr->name != NULL) {

⌨️ 快捷键说明

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