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

📄 tkselect.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
 *	None. * * Side effects: *	Frees up memory associated with the selection. * *---------------------------------------------------------------------- */voidTkSelDeadWindow(winPtr)    register TkWindow *winPtr;	/* Window that's being deleted. */{    register TkSelHandler *selPtr;    register TkSelInProgress *ipPtr;    TkSelectionInfo *infoPtr, *prevPtr, *nextPtr;    /*     * While deleting all the handlers, be careful to check whether     * ConvertSelection or TkSelPropProc are about to process one of the     * deleted handlers.     */    while (winPtr->selHandlerList != NULL) {	selPtr = winPtr->selHandlerList;	winPtr->selHandlerList = selPtr->nextPtr;	for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {	    if (ipPtr->selPtr == selPtr) {		ipPtr->selPtr = NULL;	    }	}	if (selPtr->proc == HandleTclCommand) {	    ckfree((char *) selPtr->clientData);	}	ckfree((char *) selPtr);    }    /*     * Remove selections owned by window being deleted.     */    for (infoPtr = winPtr->dispPtr->selectionInfoPtr, prevPtr = NULL;	     infoPtr != NULL; infoPtr = nextPtr) {	nextPtr = infoPtr->nextPtr;	if (infoPtr->owner == (Tk_Window) winPtr) {	    if (infoPtr->clearProc == LostSelection) {		ckfree((char *) infoPtr->clearData);	    }	    ckfree((char *) infoPtr);	    infoPtr = prevPtr;	    if (prevPtr == NULL) {		winPtr->dispPtr->selectionInfoPtr = nextPtr;	    } else {		prevPtr->nextPtr = nextPtr;	    }	}	prevPtr = infoPtr;    }}/* *---------------------------------------------------------------------- * * TkSelInit -- * *	Initialize selection-related information for a display. * * Results: *	None. * * Side effects: *	Selection-related information is initialized. * *---------------------------------------------------------------------- */voidTkSelInit(tkwin)    Tk_Window tkwin;		/* Window token (used to find				 * display to initialize). */{    register TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;    /*     * Fetch commonly-used atoms.     */    dispPtr->multipleAtom = Tk_InternAtom(tkwin, "MULTIPLE");    dispPtr->incrAtom = Tk_InternAtom(tkwin, "INCR");    dispPtr->targetsAtom = Tk_InternAtom(tkwin, "TARGETS");    dispPtr->timestampAtom = Tk_InternAtom(tkwin, "TIMESTAMP");    dispPtr->textAtom = Tk_InternAtom(tkwin, "TEXT");    dispPtr->compoundTextAtom = Tk_InternAtom(tkwin, "COMPOUND_TEXT");    dispPtr->applicationAtom = Tk_InternAtom(tkwin, "TK_APPLICATION");    dispPtr->windowAtom = Tk_InternAtom(tkwin, "TK_WINDOW");    dispPtr->clipboardAtom = Tk_InternAtom(tkwin, "CLIPBOARD");}/* *---------------------------------------------------------------------- * * TkSelClearSelection -- * *	This procedure is invoked to process a SelectionClear event. * * Results: *	None. * * Side effects: *	Invokes the clear procedure for the window which lost the *	selection. * *---------------------------------------------------------------------- */voidTkSelClearSelection(tkwin, eventPtr)    Tk_Window tkwin;		/* Window for which event was targeted. */    register XEvent *eventPtr;	/* X SelectionClear event. */{    register TkWindow *winPtr = (TkWindow *) tkwin;    TkDisplay *dispPtr = winPtr->dispPtr;    TkSelectionInfo *infoPtr;    TkSelectionInfo *prevPtr;    /*     * Invoke clear procedure for window that just lost the selection.  This     * code is a bit tricky, because any callbacks due to selection changes     * between windows managed by the process have already been made.  Thus,     * ignore the event unless it refers to the window that's currently the     * selection owner and the event was generated after the server saw the     * SetSelectionOwner request.     */    for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;	 infoPtr != NULL; infoPtr = infoPtr->nextPtr) {	if (infoPtr->selection == eventPtr->xselectionclear.selection) {	    break;	}	prevPtr = infoPtr;    }    if (infoPtr != NULL && (infoPtr->owner == tkwin)	    && (eventPtr->xselectionclear.serial >= (unsigned) infoPtr->serial)) {	if (prevPtr == NULL) {	    dispPtr->selectionInfoPtr = infoPtr->nextPtr;	} else {	    prevPtr->nextPtr = infoPtr->nextPtr;	}	/*	 * Because of reentrancy problems, calling clearProc must be done	 * after the infoPtr has been removed from the selectionInfoPtr	 * list (clearProc could modify the list, e.g. by creating	 * a new selection).	 */	if (infoPtr->clearProc != NULL) {	    (*infoPtr->clearProc)(infoPtr->clearData);	}	ckfree((char *) infoPtr);    }}/* *-------------------------------------------------------------- * * SelGetProc -- * *	This procedure is invoked to process pieces of the selection *	as they arrive during "selection get" commands. * * Results: *	Always returns TCL_OK. * * Side effects: *	Bytes get appended to the dynamic string pointed to by the *	clientData argument. * *-------------------------------------------------------------- */	/* ARGSUSED */static intSelGetProc(clientData, interp, portion)    ClientData clientData;	/* Dynamic string holding partially				 * assembled selection. */    Tcl_Interp *interp;		/* Interpreter used for error				 * reporting (not used). */    char *portion;		/* New information to be appended. */{    Tcl_DStringAppend((Tcl_DString *) clientData, portion, -1);    return TCL_OK;}/* *---------------------------------------------------------------------- * * HandleTclCommand -- * *	This procedure acts as selection handler for handlers created *	by the "selection handle" command.  It invokes a Tcl command to *	retrieve the selection. * * Results: *	The return value is a count of the number of bytes actually *	stored at buffer, or -1 if an error occurs while executing *	the Tcl command to retrieve the selection. * * Side effects: *	None except for things done by the Tcl command. * *---------------------------------------------------------------------- */static intHandleTclCommand(clientData, offset, buffer, maxBytes)    ClientData clientData;	/* Information about command to execute. */    int offset;			/* Return selection bytes starting at this				 * offset. */    char *buffer;		/* Place to store converted selection. */    int maxBytes;		/* Maximum # of bytes to store at buffer. */{    CommandInfo *cmdInfoPtr = (CommandInfo *) clientData;    int spaceNeeded, length;#define MAX_STATIC_SIZE 100    char staticSpace[MAX_STATIC_SIZE];    char *command;    Tcl_Interp *interp;    Tcl_DString oldResult;    /*     * We must copy the interpreter pointer from CommandInfo because the     * command could delete the handler, freeing the CommandInfo data before we     * are done using it. We must also protect the interpreter from being     * deleted too soo.     */    interp = cmdInfoPtr->interp;    Tcl_Preserve((ClientData) interp);    /*     * First, generate a command by taking the command string     * and appending the offset and maximum # of bytes.     */    spaceNeeded = cmdInfoPtr->cmdLength + 30;    if (spaceNeeded < MAX_STATIC_SIZE) {	command = staticSpace;    } else {	command = (char *) ckalloc((unsigned) spaceNeeded);    }    sprintf(command, "%s %d %d", cmdInfoPtr->command, offset, maxBytes);    /*     * Execute the command.  Be sure to restore the state of the     * interpreter after executing the command.     */    Tcl_DStringInit(&oldResult);    Tcl_DStringGetResult(interp, &oldResult);    if (TkCopyAndGlobalEval(interp, command) == TCL_OK) {	length = strlen(interp->result);	if (length > maxBytes) {	    length = maxBytes;	}	memcpy((VOID *) buffer, (VOID *) interp->result, (size_t) length);	buffer[length] = '\0';    } else {	length = -1;    }    Tcl_DStringResult(interp, &oldResult);    if (command != staticSpace) {	ckfree(command);    }    Tcl_Release((ClientData) interp);    return length;}/* *---------------------------------------------------------------------- * * TkSelDefaultSelection -- * *	This procedure is called to generate selection information *	for a few standard targets such as TIMESTAMP and TARGETS. *	It is invoked only if no handler has been declared by the *	application. * * Results: *	If "target" is a standard target understood by this procedure, *	the selection is converted to that form and stored as a *	character string in buffer.  The type of the selection (e.g. *	STRING or ATOM) is stored in *typePtr, and the return value is *	a count of the # of non-NULL bytes at buffer.  If the target *	wasn't understood, or if there isn't enough space at buffer *	to hold the entire selection (no INCR-mode transfers for this *	stuff!), then -1 is returned. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTkSelDefaultSelection(infoPtr, target, buffer, maxBytes, typePtr)    TkSelectionInfo *infoPtr;	/* Info about selection being retrieved. */    Atom target;		/* Desired form of selection. */    char *buffer;		/* Place to put selection characters. */    int maxBytes;		/* Maximum # of bytes to store at buffer. */    Atom *typePtr;		/* Store here the type of the selection,				 * for use in converting to proper X format. */{    register TkWindow *winPtr = (TkWindow *) infoPtr->owner;    TkDisplay *dispPtr = winPtr->dispPtr;    if (target == dispPtr->timestampAtom) {	if (maxBytes < 20) {	    return -1;	}	sprintf(buffer, "0x%x", (unsigned int) infoPtr->time);	*typePtr = XA_INTEGER;	return strlen(buffer);    }    if (target == dispPtr->targetsAtom) {	register TkSelHandler *selPtr;	char *atomString;	int length, atomLength;	if (maxBytes < 50) {	    return -1;	}	strcpy(buffer, "MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW");	length = strlen(buffer);	for (selPtr = winPtr->selHandlerList; selPtr != NULL;		selPtr = selPtr->nextPtr) {	    if ((selPtr->selection == infoPtr->selection)		    && (selPtr->target != dispPtr->applicationAtom)		    && (selPtr->target != dispPtr->windowAtom)) {		atomString = Tk_GetAtomName((Tk_Window) winPtr,			selPtr->target);		atomLength = strlen(atomString) + 1;		if ((length + atomLength) >= maxBytes) {		    return -1;		}		sprintf(buffer+length, " %s", atomString);		length += atomLength;	    }	}	*typePtr = XA_ATOM;	return length;    }    if (target == dispPtr->applicationAtom) {	int length;	char *name = winPtr->mainPtr->winPtr->nameUid;	length = strlen(name);	if (maxBytes <= length) {	    return -1;	}	strcpy(buffer, name);	*typePtr = XA_STRING;	return length;    }    if (target == dispPtr->windowAtom) {	int length;	char *name = winPtr->pathName;	length = strlen(name);	if (maxBytes <= length) {	    return -1;	}	strcpy(buffer, name);	*typePtr = XA_STRING;	return length;    }    return -1;}/* *---------------------------------------------------------------------- * * LostSelection -- * *	This procedure is invoked when a window has lost ownership of *	the selection and the ownership was claimed with the command *	"selection own". * * Results: *	None. * * Side effects: *	A Tcl script is executed;  it can do almost anything. * *---------------------------------------------------------------------- */static voidLostSelection(clientData)    ClientData clientData;		/* Pointer to CommandInfo structure. */{    LostCommand *lostPtr = (LostCommand *) clientData;    char *oldResultString;    Tcl_FreeProc *oldFreeProc;    Tcl_Interp *interp;    interp = lostPtr->interp;    Tcl_Preserve((ClientData) interp);        /*     * Execute the command.  Save the interpreter's result, if any, and     * restore it after executing the command.     */    oldFreeProc = interp->freeProc;    if (oldFreeProc != TCL_STATIC) {	oldResultString = interp->result;    } else {	oldResultString = (char *) ckalloc((unsigned)		(strlen(interp->result) + 1));	strcpy(oldResultString, interp->result);	oldFreeProc = TCL_DYNAMIC;    }    interp->freeProc = TCL_STATIC;    if (TkCopyAndGlobalEval(interp, lostPtr->command) != TCL_OK) {	Tcl_BackgroundError(interp);    }    Tcl_FreeResult(interp);    interp->result = oldResultString;    interp->freeProc = oldFreeProc;    Tcl_Release((ClientData) interp);        /*     * Free the storage for the command, since we're done with it now.     */    ckfree((char *) lostPtr);}

⌨️ 快捷键说明

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