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

📄 tktexttag.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    if (tagPtr->spacing1String != NULL) {	ckfree(tagPtr->spacing1String);    }    if (tagPtr->spacing2String != NULL) {	ckfree(tagPtr->spacing2String);    }    if (tagPtr->spacing3String != NULL) {	ckfree(tagPtr->spacing3String);    }    if (tagPtr->tabString != NULL) {	ckfree(tagPtr->tabString);    }    if (tagPtr->tabArrayPtr != NULL) {	ckfree((char *) tagPtr->tabArrayPtr);    }    if (tagPtr->underlineString != NULL) {	ckfree(tagPtr->underlineString);    }    ckfree((char *) tagPtr);}/* *---------------------------------------------------------------------- * * SortTags -- * *	This procedure sorts an array of tag pointers in increasing *	order of priority, optimizing for the common case where the *	array is small. * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------- */static voidSortTags(numTags, tagArrayPtr)    int numTags;		/* Number of tag pointers at *tagArrayPtr. */    TkTextTag **tagArrayPtr;	/* Pointer to array of pointers. */{    int i, j, prio;    register TkTextTag **tagPtrPtr;    TkTextTag **maxPtrPtr, *tmp;    if (numTags < 2) {	return;    }    if (numTags < 20) {	for (i = numTags-1; i > 0; i--, tagArrayPtr++) {	    maxPtrPtr = tagPtrPtr = tagArrayPtr;	    prio = tagPtrPtr[0]->priority;	    for (j = i, tagPtrPtr++; j > 0; j--, tagPtrPtr++) {		if (tagPtrPtr[0]->priority < prio) {		    prio = tagPtrPtr[0]->priority;		    maxPtrPtr = tagPtrPtr;		}	    }	    tmp = *maxPtrPtr;	    *maxPtrPtr = *tagArrayPtr;	    *tagArrayPtr = tmp;	}    } else {	qsort((VOID *) tagArrayPtr, (unsigned) numTags, sizeof (TkTextTag *),		    TagSortProc);    }}/* *---------------------------------------------------------------------- * * TagSortProc -- * *	This procedure is called by qsort when sorting an array of *	tags in priority order. * * Results: *	The return value is -1 if the first argument should be before *	the second element (i.e. it has lower priority), 0 if it's *	equivalent (this should never happen!), and 1 if it should be *	after the second element. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intTagSortProc(first, second)    CONST VOID *first, *second;		/* Elements to be compared. */{    TkTextTag *tagPtr1, *tagPtr2;    tagPtr1 = * (TkTextTag **) first;    tagPtr2 = * (TkTextTag **) second;    return tagPtr1->priority - tagPtr2->priority;}/* *---------------------------------------------------------------------- * * ChangeTagPriority -- * *	This procedure changes the priority of a tag by modifying *	its priority and the priorities of other tags that are affected *	by the change. * * Results: *	None. * * Side effects: *	Priorities may be changed for some or all of the tags in *	textPtr.  The tags will be arranged so that there is exactly *	one tag at each priority level between 0 and textPtr->numTags-1, *	with tagPtr at priority "prio". * *---------------------------------------------------------------------- */static voidChangeTagPriority(textPtr, tagPtr, prio)    TkText *textPtr;			/* Information about text widget. */    TkTextTag *tagPtr;			/* Tag whose priority is to be					 * changed. */    int prio;				/* New priority for tag. */{    int low, high, delta;    register TkTextTag *tagPtr2;    Tcl_HashEntry *hPtr;    Tcl_HashSearch search;    if (prio < 0) {	prio = 0;    }    if (prio >= textPtr->numTags) {	prio = textPtr->numTags-1;    }    if (prio == tagPtr->priority) {	return;    } else if (prio < tagPtr->priority) {	low = prio;	high = tagPtr->priority-1;	delta = 1;    } else {	low = tagPtr->priority+1;	high = prio;	delta = -1;    }    for (hPtr = Tcl_FirstHashEntry(&textPtr->tagTable, &search);	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {	tagPtr2 = (TkTextTag *) Tcl_GetHashValue(hPtr);	if ((tagPtr2->priority >= low) && (tagPtr2->priority <= high)) {	    tagPtr2->priority += delta;	}    }    tagPtr->priority = prio;}/* *-------------------------------------------------------------- * * TkTextBindProc -- * *	This procedure is invoked by the Tk dispatcher to handle *	events associated with bindings on items. * * Results: *	None. * * Side effects: *	Depends on the command invoked as part of the binding *	(if there was any). * *-------------------------------------------------------------- */voidTkTextBindProc(clientData, eventPtr)    ClientData clientData;		/* Pointer to canvas structure. */    XEvent *eventPtr;			/* Pointer to X event that just					 * happened. */{    TkText *textPtr = (TkText *) clientData;    int repick  = 0;# define AnyButtonMask (Button1Mask|Button2Mask|Button3Mask\	|Button4Mask|Button5Mask)    Tcl_Preserve((ClientData) textPtr);    /*     * This code simulates grabs for mouse buttons by keeping track     * of whether a button is pressed and refusing to pick a new current     * character while a button is pressed.     */    if (eventPtr->type == ButtonPress) {	textPtr->flags |= BUTTON_DOWN;    } else if (eventPtr->type == ButtonRelease) {	int mask;	switch (eventPtr->xbutton.button) {	    case Button1:		mask = Button1Mask;		break;	    case Button2:		mask = Button2Mask;		break;	    case Button3:		mask = Button3Mask;		break;	    case Button4:		mask = Button4Mask;		break;	    case Button5:		mask = Button5Mask;		break;	    default:		mask = 0;		break;	}	if ((eventPtr->xbutton.state & AnyButtonMask) == (unsigned) mask) {	    textPtr->flags &= ~BUTTON_DOWN;	    repick = 1;	}    } else if ((eventPtr->type == EnterNotify)	    || (eventPtr->type == LeaveNotify)) {	if (eventPtr->xcrossing.state & AnyButtonMask)  {	    textPtr->flags |= BUTTON_DOWN;	} else {	    textPtr->flags &= ~BUTTON_DOWN;	}	TkTextPickCurrent(textPtr, eventPtr);	goto done;    } else if (eventPtr->type == MotionNotify) {	if (eventPtr->xmotion.state & AnyButtonMask)  {	    textPtr->flags |= BUTTON_DOWN;	} else {	    textPtr->flags &= ~BUTTON_DOWN;	}	TkTextPickCurrent(textPtr, eventPtr);    }    if ((textPtr->numCurTags > 0) && (textPtr->bindingTable != NULL)	    && (textPtr->tkwin != NULL)) {	Tk_BindEvent(textPtr->bindingTable, eventPtr, textPtr->tkwin,		textPtr->numCurTags, (ClientData *) textPtr->curTagArrayPtr);    }    if (repick) {	unsigned int oldState;	oldState = eventPtr->xbutton.state;	eventPtr->xbutton.state &= ~(Button1Mask|Button2Mask		|Button3Mask|Button4Mask|Button5Mask);	TkTextPickCurrent(textPtr, eventPtr);	eventPtr->xbutton.state = oldState;    }    done:    Tcl_Release((ClientData) textPtr);}/* *-------------------------------------------------------------- * * TkTextPickCurrent -- * *	Find the character containing the coordinates in an event *	and place the "current" mark on that character.  If the *	"current" mark has moved then generate a fake leave event *	on the old current character and a fake enter event on the new *	current character. * * Results: *	None. * * Side effects: *	The current mark for textPtr may change.  If it does, *	then the commands associated with character entry and leave *	could do just about anything.  For example, the text widget *	might be deleted.  It is up to the caller to protect itself *	with calls to Tcl_Preserve and Tcl_Release. * *-------------------------------------------------------------- */voidTkTextPickCurrent(textPtr, eventPtr)    register TkText *textPtr;		/* Text widget in which to select					 * current character. */    XEvent *eventPtr;			/* Event describing location of					 * mouse cursor.  Must be EnterWindow,					 * LeaveWindow, ButtonRelease, or					 * MotionNotify. */{    TkTextIndex index;    TkTextTag **oldArrayPtr, **newArrayPtr;    TkTextTag **copyArrayPtr = NULL;	/* Initialization needed to prevent					 * compiler warning. */    int numOldTags, numNewTags, i, j, size;    XEvent event;    /*     * If a button is down, then don't do anything at all;  we'll be     * called again when all buttons are up, and we can repick then.     * This implements a form of mouse grabbing.     */    if (textPtr->flags & BUTTON_DOWN) {	if (((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify))		&& ((eventPtr->xcrossing.mode == NotifyGrab)		|| (eventPtr->xcrossing.mode == NotifyUngrab))) {	    /*	     * Special case:  the window is being entered or left because	     * of a grab or ungrab.  In this case, repick after all.	     * Furthermore, clear BUTTON_DOWN to release the simulated	     * grab.	     */	    textPtr->flags &= ~BUTTON_DOWN;	} else {	    return;	}    }    /*     * Save information about this event in the widget in case we have     * to synthesize more enter and leave events later (e.g. because a     * character was deleted, causing a new character to be underneath     * the mouse cursor).  Also translate MotionNotify events into     * EnterNotify events, since that's what gets reported to event     * handlers when the current character changes.     */    if (eventPtr != &textPtr->pickEvent) {	if ((eventPtr->type == MotionNotify)		|| (eventPtr->type == ButtonRelease)) {	    textPtr->pickEvent.xcrossing.type = EnterNotify;	    textPtr->pickEvent.xcrossing.serial = eventPtr->xmotion.serial;	    textPtr->pickEvent.xcrossing.send_event		    = eventPtr->xmotion.send_event;	    textPtr->pickEvent.xcrossing.display = eventPtr->xmotion.display;	    textPtr->pickEvent.xcrossing.window = eventPtr->xmotion.window;	    textPtr->pickEvent.xcrossing.root = eventPtr->xmotion.root;	    textPtr->pickEvent.xcrossing.subwindow = None;	    textPtr->pickEvent.xcrossing.time = eventPtr->xmotion.time;	    textPtr->pickEvent.xcrossing.x = eventPtr->xmotion.x;	    textPtr->pickEvent.xcrossing.y = eventPtr->xmotion.y;	    textPtr->pickEvent.xcrossing.x_root = eventPtr->xmotion.x_root;	    textPtr->pickEvent.xcrossing.y_root = eventPtr->xmotion.y_root;	    textPtr->pickEvent.xcrossing.mode = NotifyNormal;	    textPtr->pickEvent.xcrossing.detail = NotifyNonlinear;	    textPtr->pickEvent.xcrossing.same_screen		    = eventPtr->xmotion.same_screen;	    textPtr->pickEvent.xcrossing.focus = False;	    textPtr->pickEvent.xcrossing.state = eventPtr->xmotion.state;	} else  {	    textPtr->pickEvent = *eventPtr;	}    }    /*     * Find the new current character, then find and sort all of the     * tags associated with it.     */    if (textPtr->pickEvent.type != LeaveNotify) {	TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x,		textPtr->pickEvent.xcrossing.y, &index);	newArrayPtr = TkBTreeGetTags(&index, &numNewTags);	SortTags(numNewTags, newArrayPtr);    } else {	newArrayPtr = NULL;	numNewTags = 0;    }    /*     * Resort the tags associated with the previous marked character     * (the priorities might have changed), then make a copy of the     * new tags, and compare the old tags to the copy, nullifying     * any tags that are present in both groups (i.e. the tags that     * haven't changed).     */    SortTags(textPtr->numCurTags, textPtr->curTagArrayPtr);    if (numNewTags > 0) {	size = numNewTags * sizeof(TkTextTag *);	copyArrayPtr = (TkTextTag **) ckalloc((unsigned) size);	memcpy((VOID *) copyArrayPtr, (VOID *) newArrayPtr, (size_t) size);	for (i = 0; i < textPtr->numCurTags; i++) {	    for (j = 0; j < numNewTags; j++) {		if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) {		    textPtr->curTagArrayPtr[i] = NULL;		    copyArrayPtr[j] = NULL;		    break;		}	    }	}    }    /*     * Invoke the binding system with a LeaveNotify event for all of     * the tags that have gone away.  We have to be careful here,     * because it's possible that the binding could do something     * (like calling tkwait) that eventually modifies     * textPtr->curTagArrayPtr.  To avoid problems in situations like     * this, update curTagArrayPtr to its new value before invoking     * any bindings, and don't use it any more here.     */    numOldTags = textPtr->numCurTags;    textPtr->numCurTags = numNewTags;    oldArrayPtr = textPtr->curTagArrayPtr;    textPtr->curTagArrayPtr = newArrayPtr;    if (numOldTags != 0) {	if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)) {	    event = textPtr->pickEvent;	    event.type = LeaveNotify;	    /*	     * Always use a detail of NotifyAncestor.  Besides being	     * consistent, this avoids problems where the binding code	     * will discard NotifyInferior events.	     */	    event.xcrossing.detail = NotifyAncestor;	    Tk_BindEvent(textPtr->bindingTable, &event, textPtr->tkwin,		    numOldTags, (ClientData *) oldArrayPtr);	}	ckfree((char *) oldArrayPtr);    }    /*     * Reset the "current" mark (be careful to recompute its location,     * since it might have changed during an event binding).  Then     * invoke the binding system with an EnterNotify event for all of     * the tags that have just appeared.     */    TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x,	    textPtr->pickEvent.xcrossing.y, &index);    TkTextSetMark(textPtr, "current", &index);    if (numNewTags != 0) {	if ((textPtr->bindingTable != NULL) && (textPtr->tkwin != NULL)) {	    event = textPtr->pickEvent;	    event.type = EnterNotify;	    event.xcrossing.detail = NotifyAncestor;	    Tk_BindEvent(textPtr->bindingTable, &event, textPtr->tkwin,		    numNewTags, (ClientData *) copyArrayPtr);	}	ckfree((char *) copyArrayPtr);    }}

⌨️ 快捷键说明

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