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

📄 tkmenu.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
 *---------------------------------------------------------------------- */static intConfigureMenuCloneEntries(interp, menuPtr, index, argc, argv, flags)    Tcl_Interp *interp;			/* Used for error reporting. */    TkMenu *menuPtr;			/* Information about whole menu. */    int index;				/* Index of mePtr within menuPtr's					 * entries. */    int argc;				/* Number of valid entries in argv. */    char **argv;			/* Arguments. */    int flags;				/* Additional flags to pass to					 * Tk_ConfigureWidget. */{    TkMenuEntry *mePtr;    TkMenu *menuListPtr;    char *oldCascadeName = NULL, *newMenuName = NULL;    int cascadeEntryChanged;    TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL;         /*     * Cascades are kind of tricky here. This is special case #3 in the comment     * at the top of this file. Basically, if a menu is the master menu of a     * clone chain, and has an entry with a cascade menu, the clones of     * the menu will point to clones of the cascade menu. We have     * to destroy the clones of the cascades, clone the new cascade     * menu, and configure the entry to point to the new clone.     */    mePtr = menuPtr->masterMenuPtr->entries[index];    if (mePtr->type == CASCADE_ENTRY) {	oldCascadeName = mePtr->name;    }    if (ConfigureMenuEntry(mePtr, argc, argv, flags) != TCL_OK) {	return TCL_ERROR;    }    cascadeEntryChanged = (mePtr->type == CASCADE_ENTRY)	    && (oldCascadeName != mePtr->name);    if (cascadeEntryChanged) {	newMenuName = mePtr->name;	if (newMenuName != NULL) {	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,		    mePtr->name);	}    }    for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;     	    menuListPtr != NULL;	    menuListPtr = menuListPtr->nextInstancePtr) {  	    	mePtr = menuListPtr->entries[index];	if (cascadeEntryChanged && (mePtr->name != NULL)) {	    oldCascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp, 		    mePtr->name);	    if ((oldCascadeMenuRefPtr != NULL)		    && (oldCascadeMenuRefPtr->menuPtr != NULL)) {		RecursivelyDeleteMenu(oldCascadeMenuRefPtr->menuPtr);	    }	}    	if (ConfigureMenuEntry(mePtr, argc, argv, flags) != TCL_OK) {    	    return TCL_ERROR;    	}		if (cascadeEntryChanged && (newMenuName != NULL)) {	    if (cascadeMenuRefPtr->menuPtr != NULL) {		char *newArgV[2];		char *newCloneName;		newCloneName = TkNewMenuName(menuPtr->interp,			Tk_PathName(menuListPtr->tkwin), 			cascadeMenuRefPtr->menuPtr);		CloneMenu(cascadeMenuRefPtr->menuPtr, newCloneName,			"normal");		newArgV[0] = "-menu";		newArgV[1] = newCloneName;		ConfigureMenuEntry(mePtr, 2, newArgV, flags);		ckfree(newCloneName);	    }	}    }    return TCL_OK;}/* *-------------------------------------------------------------- * * TkGetMenuIndex -- * *	Parse a textual index into a menu and return the numerical *	index of the indicated entry. * * Results: *	A standard Tcl result.  If all went well, then *indexPtr is *	filled in with the entry index corresponding to string *	(ranges from -1 to the number of entries in the menu minus *	one).  Otherwise an error message is left in interp->result. * * Side effects: *	None. * *-------------------------------------------------------------- */intTkGetMenuIndex(interp, menuPtr, string, lastOK, indexPtr)    Tcl_Interp *interp;		/* For error messages. */    TkMenu *menuPtr;		/* Menu for which the index is being				 * specified. */    char *string;		/* Specification of an entry in menu.  See				 * manual entry for valid .*/    int lastOK;			/* Non-zero means its OK to return index				 * just *after* last entry. */    int *indexPtr;		/* Where to store converted relief. */{    int i;    if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {	*indexPtr = menuPtr->active;	return TCL_OK;    }    if (((string[0] == 'l') && (strcmp(string, "last") == 0))	    || ((string[0] == 'e') && (strcmp(string, "end") == 0))) {	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);	return TCL_OK;    }    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {	*indexPtr = -1;	return TCL_OK;    }    if (string[0] == '@') {	if (GetIndexFromCoords(interp, menuPtr, string, indexPtr)		== TCL_OK) {	    return TCL_OK;	}    }    if (isdigit(UCHAR(string[0]))) {	if (Tcl_GetInt(interp, string,  &i) == TCL_OK) {	    if (i >= menuPtr->numEntries) {		if (lastOK) {		    i = menuPtr->numEntries;		} else {		    i = menuPtr->numEntries-1;		}	    } else if (i < 0) {		i = -1;	    }	    *indexPtr = i;	    return TCL_OK;	}	Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);    }    for (i = 0; i < menuPtr->numEntries; i++) {	char *label;	label = menuPtr->entries[i]->label;	if ((label != NULL)		&& (Tcl_StringMatch(menuPtr->entries[i]->label, string))) {	    *indexPtr = i;	    return TCL_OK;	}    }    Tcl_AppendResult(interp, "bad menu entry index \"",	    string, "\"", (char *) NULL);    return TCL_ERROR;}/* *---------------------------------------------------------------------- * * MenuCmdDeletedProc -- * *	This procedure 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 voidMenuCmdDeletedProc(clientData)    ClientData clientData;	/* Pointer to widget record for widget. */{    TkMenu *menuPtr = (TkMenu *) clientData;    Tk_Window tkwin = menuPtr->tkwin;    /*     * This procedure 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 procedure     * destroys the widget.     */    if (tkwin != NULL) {	menuPtr->tkwin = NULL;	Tk_DestroyWindow(tkwin);    }}/* *---------------------------------------------------------------------- * * MenuNewEntry -- * *	This procedure allocates and initializes a new menu entry. * * Results: *	The return value is a pointer to a new menu entry structure, *	which has been malloc-ed, initialized, and entered into the *	entry array for the  menu. * * Side effects: *	Storage gets allocated. * *---------------------------------------------------------------------- */static TkMenuEntry *MenuNewEntry(menuPtr, index, type)    TkMenu *menuPtr;		/* Menu that will hold the new entry. */    int index;			/* Where in the menu the new entry is to				 * go. */    int type;			/* The type of the new entry. */{    TkMenuEntry *mePtr;    TkMenuEntry **newEntries;    int i;    /*     * Create a new array of entries with an empty slot for the     * new entry.     */    newEntries = (TkMenuEntry **) ckalloc((unsigned)	    ((menuPtr->numEntries+1)*sizeof(TkMenuEntry *)));    for (i = 0; i < index; i++) {	newEntries[i] = menuPtr->entries[i];    }    for (  ; i < menuPtr->numEntries; i++) {	newEntries[i+1] = menuPtr->entries[i];	newEntries[i+1]->index = i + 1;    }    if (menuPtr->numEntries != 0) {	ckfree((char *) menuPtr->entries);    }    menuPtr->entries = newEntries;    menuPtr->numEntries++;    mePtr = (TkMenuEntry *) ckalloc(sizeof(TkMenuEntry));    menuPtr->entries[index] = mePtr;    mePtr->type = type;    mePtr->menuPtr = menuPtr;    mePtr->label = NULL;    mePtr->labelLength = 0;    mePtr->underline = -1;    mePtr->bitmap = None;    mePtr->imageString = NULL;    mePtr->image = NULL;    mePtr->selectImageString  = NULL;    mePtr->selectImage = NULL;    mePtr->accel = NULL;    mePtr->accelLength = 0;    mePtr->state = tkNormalUid;    mePtr->border = NULL;    mePtr->fg = NULL;    mePtr->activeBorder = NULL;    mePtr->activeFg = NULL;    mePtr->tkfont = NULL;    mePtr->indicatorOn = 1;    mePtr->indicatorFg = NULL;    mePtr->columnBreak = 0;    mePtr->hideMargin = 0;    mePtr->command = NULL;    mePtr->name = NULL;    mePtr->childMenuRefPtr = NULL;    mePtr->onValue = NULL;    mePtr->offValue = NULL;    mePtr->entryFlags = 0;    mePtr->index = index;    mePtr->nextCascadePtr = NULL;    TkMenuInitializeEntryDrawingFields(mePtr);    if (TkpMenuNewEntry(mePtr) != TCL_OK) {    	ckfree((char *) mePtr);    	return NULL;    }        return mePtr;}/* *---------------------------------------------------------------------- * * MenuAddOrInsert -- * *	This procedure does all of the work of the "add" and "insert" *	widget commands, allowing the code for these to be shared. * * Results: *	A standard Tcl return value. * * Side effects: *	A new menu entry is created in menuPtr. * *---------------------------------------------------------------------- */static intMenuAddOrInsert(interp, menuPtr, indexString, argc, argv)    Tcl_Interp *interp;			/* Used for error reporting. */    TkMenu *menuPtr;			/* Widget in which to create new					 * entry. */    char *indexString;			/* String describing index at which					 * to insert.  NULL means insert at					 * end. */    int argc;				/* Number of elements in argv. */    char **argv;			/* Arguments to command:  first arg					 * is type of entry, others are					 * config options. */{    int c, type, index;    size_t length;    TkMenuEntry *mePtr;    TkMenu *menuListPtr;    if (indexString != NULL) {	if (TkGetMenuIndex(interp, menuPtr, indexString, 1, &index)		!= TCL_OK) {	    return TCL_ERROR;	}    } else {	index = menuPtr->numEntries;    }    if (index < 0) {	Tcl_AppendResult(interp, "bad index \"", indexString, "\"",		 (char *) NULL);	return TCL_ERROR;    }    if (menuPtr->tearOff && (index == 0)) {	index = 1;    }    /*     * Figure out the type of the new entry.     */    c = argv[0][0];    length = strlen(argv[0]);    if ((c == 'c') && (strncmp(argv[0], "cascade", length) == 0)	    && (length >= 2)) {	type = CASCADE_ENTRY;    } else if ((c == 'c') && (strncmp(argv[0], "checkbutton", length) == 0)	    && (length >= 2)) {	type = CHECK_BUTTON_ENTRY;    } else if ((c == 'c') && (strncmp(argv[0], "command", length) == 0)	    && (length >= 2)) {	type = COMMAND_ENTRY;    } else if ((c == 'r')	    && (strncmp(argv[0], "radiobutton", length) == 0)) {	type = RADIO_BUTTON_ENTRY;    } else if ((c == 's')	    && (strncmp(argv[0], "separator", length) == 0)) {	type = SEPARATOR_ENTRY;    } else {	Tcl_AppendResult(interp, "bad menu entry type \"",		argv[0], "\": must be cascade, checkbutton, ",		"command, radiobutton, or separator", (char *) NULL);	return TCL_ERROR;    }        /*     * Now we have to add an entry for every instance related to this menu.     */    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;     	    menuListPtr = menuListPtr->nextInstancePtr) {    	    	mePtr = MenuNewEntry(menuListPtr, index, type);    	if (mePtr == NULL) {    	    return TCL_ERROR;    	}    	if (ConfigureMenuEntry(mePtr, argc-1, argv+1, 0) != TCL_OK) {	    TkMenu *errorMenuPtr;	    int i; 	    for (errorMenuPtr = menuPtr->masterMenuPtr;		    errorMenuPtr != NULL;		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {    		Tcl_EventuallyFree((Clie

⌨️ 快捷键说明

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