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

📄 tkunixselect.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
			    Tk_GetAtomName(tkwin, retrPtr->target),			    "\" not defined", (char *) NULL);		    retrPtr->result = TCL_ERROR;		    return;		}	    }	}	propInfo = NULL;	result = XGetWindowProperty(eventPtr->xselection.display,		eventPtr->xselection.requestor, retrPtr->property,		0, MAX_PROP_WORDS, False, (Atom) AnyPropertyType,		&type, &format, &numItems, &bytesAfter,		(unsigned char **) &propInfo);	if ((result != Success) || (type == None)) {	    return;	}	if (bytesAfter != 0) {	    Tcl_SetResult(retrPtr->interp, "selection property too large",		TCL_STATIC);	    retrPtr->result = TCL_ERROR;	    XFree(propInfo);	    return;	}	if ((type == XA_STRING) || (type == dispPtr->textAtom)		|| (type == dispPtr->compoundTextAtom)) {	    if (format != 8) {		sprintf(retrPtr->interp->result,		    "bad format for string selection: wanted \"8\", got \"%d\"",		    format);		retrPtr->result = TCL_ERROR;		return;	    }            interp = retrPtr->interp;            Tcl_Preserve((ClientData) interp);	    retrPtr->result = (*retrPtr->proc)(retrPtr->clientData,		    interp, propInfo);            Tcl_Release((ClientData) interp);	} else if (type == dispPtr->incrAtom) {	    /*	     * It's a !?#@!?!! INCR-style reception.  Arrange to receive	     * the selection in pieces, using the ICCCM protocol, then	     * hang around until either the selection is all here or a	     * timeout occurs.	     */	    retrPtr->idleTime = 0;	    Tk_CreateEventHandler(tkwin, PropertyChangeMask, SelRcvIncrProc,		    (ClientData) retrPtr);	    XDeleteProperty(Tk_Display(tkwin), Tk_WindowId(tkwin),		    retrPtr->property);	    while (retrPtr->result == -1) {		Tcl_DoOneEvent(0);	    }	    Tk_DeleteEventHandler(tkwin, PropertyChangeMask, SelRcvIncrProc,		    (ClientData) retrPtr);	} else {	    char *string;	    if (format != 32) {		sprintf(retrPtr->interp->result,		    "bad format for selection: wanted \"32\", got \"%d\"",		    format);		retrPtr->result = TCL_ERROR;		return;	    }	    string = SelCvtFromX((long *) propInfo, (int) numItems, type,		    (Tk_Window) winPtr);            interp = retrPtr->interp;            Tcl_Preserve((ClientData) interp);	    retrPtr->result = (*retrPtr->proc)(retrPtr->clientData,		    interp, string);            Tcl_Release((ClientData) interp);	    ckfree(string);	}	XFree(propInfo);	return;    }    /*     * Case #3: SelectionRequest events.  Call ConvertSelection to     * do the dirty work.     */    if (eventPtr->type == SelectionRequest) {	ConvertSelection(winPtr, &eventPtr->xselectionrequest);	return;    }}/* *---------------------------------------------------------------------- * * SelTimeoutProc -- * *	This procedure is invoked once every second while waiting for *	the selection to be returned.  After a while it gives up and *	aborts the selection retrieval. * * Results: *	None. * * Side effects: *	A new timer callback is created to call us again in another *	second, unless time has expired, in which case an error is *	recorded for the retrieval. * *---------------------------------------------------------------------- */static voidSelTimeoutProc(clientData)    ClientData clientData;		/* Information about retrieval					 * in progress. */{    register TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *) clientData;    /*     * Make sure that the retrieval is still in progress.  Then     * see how long it's been since any sort of response was received     * from the other side.     */    if (retrPtr->result != -1) {	return;    }    retrPtr->idleTime++;    if (retrPtr->idleTime >= 5) {	/*	 * Use a careful procedure to store the error message, because	 * the result could already be partially filled in with a partial	 * selection return.	 */	Tcl_SetResult(retrPtr->interp, "selection owner didn't respond",		TCL_STATIC);	retrPtr->result = TCL_ERROR;    } else {	retrPtr->timeout = Tcl_CreateTimerHandler(1000, SelTimeoutProc,	    (ClientData) retrPtr);    }}/* *---------------------------------------------------------------------- * * ConvertSelection -- * *	This procedure is invoked to handle SelectionRequest events. *	It responds to the requests, obeying the ICCCM protocols. * * Results: *	None. * * Side effects: *	Properties are created for the selection requestor, and a *	SelectionNotify event is generated for the selection *	requestor.  In the event of long selections, this procedure *	implements INCR-mode transfers, using the ICCCM protocol. * *---------------------------------------------------------------------- */static voidConvertSelection(winPtr, eventPtr)    TkWindow *winPtr;			/* Window that received the					 * conversion request;  may not be					 * selection's current owner, be we					 * set it to the current owner. */    register XSelectionRequestEvent *eventPtr;					/* Event describing request. */{    XSelectionEvent reply;		/* Used to notify requestor that					 * selection info is ready. */    int multiple;			/* Non-zero means a MULTIPLE request					 * is being handled. */    IncrInfo incr;			/* State of selection conversion. */    Atom singleInfo[2];			/* incr.multAtoms points here except					 * for multiple conversions. */    int i;    Tk_ErrorHandler errorHandler;    TkSelectionInfo *infoPtr;    TkSelInProgress ip;    errorHandler = Tk_CreateErrorHandler(eventPtr->display, -1, -1,-1,	    (int (*)()) NULL, (ClientData) NULL);    /*     * Initialize the reply event.     */    reply.type = SelectionNotify;    reply.serial = 0;    reply.send_event = True;    reply.display = eventPtr->display;    reply.requestor = eventPtr->requestor;    reply.selection = eventPtr->selection;    reply.target = eventPtr->target;    reply.property = eventPtr->property;    if (reply.property == None) {	reply.property = reply.target;    }    reply.time = eventPtr->time;    for (infoPtr = winPtr->dispPtr->selectionInfoPtr; infoPtr != NULL;	    infoPtr = infoPtr->nextPtr) {	if (infoPtr->selection == eventPtr->selection)	    break;    }    if (infoPtr == NULL) {	goto refuse;    }    winPtr = (TkWindow *) infoPtr->owner;    /*     * Figure out which kind(s) of conversion to perform.  If handling     * a MULTIPLE conversion, then read the property describing which     * conversions to perform.     */    incr.winPtr = winPtr;    incr.selection = eventPtr->selection;    if (eventPtr->target != winPtr->dispPtr->multipleAtom) {	multiple = 0;	singleInfo[0] = reply.target;	singleInfo[1] = reply.property;	incr.multAtoms = singleInfo;	incr.numConversions = 1;    } else {	Atom type;	int format, result;	unsigned long bytesAfter;	multiple = 1;	incr.multAtoms = NULL;	if (eventPtr->property == None) {	    goto refuse;	}	result = XGetWindowProperty(eventPtr->display,		eventPtr->requestor, eventPtr->property,		0, MAX_PROP_WORDS, False, XA_ATOM,		&type, &format, &incr.numConversions, &bytesAfter,		(unsigned char **) &incr.multAtoms);	if ((result != Success) || (bytesAfter != 0) || (format != 32)		|| (type == None)) {	    if (incr.multAtoms != NULL) {		XFree((char *) incr.multAtoms);	    }	    goto refuse;	}	incr.numConversions /= 2;		/* Two atoms per conversion. */    }    /*     * Loop through all of the requested conversions, and either return     * the entire converted selection, if it can be returned in a single     * bunch, or return INCR information only (the actual selection will     * be returned below).     */    incr.offsets = (int *) ckalloc((unsigned)	    (incr.numConversions*sizeof(int)));    incr.numIncrs = 0;    for (i = 0; i < incr.numConversions; i++) {	Atom target, property, type;	long buffer[TK_SEL_WORDS_AT_ONCE];	register TkSelHandler *selPtr;	int numItems, format;	char *propPtr;	target = incr.multAtoms[2*i];	property = incr.multAtoms[2*i + 1];	incr.offsets[i] = -1;	for (selPtr = winPtr->selHandlerList; selPtr != NULL;		selPtr = selPtr->nextPtr) {	    if ((selPtr->target == target)		    && (selPtr->selection == eventPtr->selection)) {		break;	    }	}	if (selPtr == NULL) {	    /*	     * Nobody seems to know about this kind of request.  If	     * it's of a sort that we can handle without any help, do	     * it.  Otherwise mark the request as an errror.	     */	    numItems = TkSelDefaultSelection(infoPtr, target, (char *) buffer,		    TK_SEL_BYTES_AT_ONCE, &type);	    if (numItems < 0) {		incr.multAtoms[2*i + 1] = None;		continue;	    }	} else {	    ip.selPtr = selPtr;	    ip.nextPtr = pendingPtr;	    pendingPtr = &ip;	    type = selPtr->format;	    numItems = (*selPtr->proc)(selPtr->clientData, 0,		    (char *) buffer, TK_SEL_BYTES_AT_ONCE);	    pendingPtr = ip.nextPtr;	    if ((ip.selPtr == NULL) || (numItems < 0)) {		incr.multAtoms[2*i + 1] = None;		continue;	    }	    if (numItems > TK_SEL_BYTES_AT_ONCE) {		panic("selection handler returned too many bytes");	    }	    ((char *) buffer)[numItems] = '\0';	}	/*	 * Got the selection;  store it back on the requestor's property.	 */	if (numItems == TK_SEL_BYTES_AT_ONCE) {	    /*	     * Selection is too big to send at once;  start an	     * INCR-mode transfer.	     */	    incr.numIncrs++;	    type = winPtr->dispPtr->incrAtom;	    buffer[0] = SelectionSize(selPtr);	    if (buffer[0] == 0) {		incr.multAtoms[2*i + 1] = None;		continue;	    }	    numItems = 1;	    propPtr = (char *) buffer;	    format = 32;	    incr.offsets[i] = 0;	} else if (type == XA_STRING) {	    propPtr = (char *) buffer;	    format = 8;	} else {	    propPtr = (char *) SelCvtToX((char *) buffer,		    type, (Tk_Window) winPtr, &numItems);	    format = 32;	}	XChangeProperty(reply.display, reply.requestor,		property, type, format, PropModeReplace,		(unsigned char *) propPtr, numItems);	if (propPtr != (char *) buffer) {	    ckfree(propPtr);	}    }    /*     * Send an event back to the requestor to indicate that the     * first stage of conversion is complete (everything is done     * except for long conversions that have to be done in INCR     * mode).     */    if (incr.numIncrs > 0) {	XSelectInput(reply.display, reply.requestor, PropertyChangeMask);	incr.timeout = Tcl_CreateTimerHandler(1000, IncrTimeoutProc,	    (ClientData) &incr);	incr.idleTime = 0;	incr.reqWindow = reply.requestor;	incr.time = infoPtr->time;	incr.nextPtr = pendingIncrs;	pendingIncrs = &incr;    }    if (multiple) {	XChangeProperty(reply.display, reply.requestor, reply.property,		XA_ATOM, 32, PropModeReplace,		(unsigned char *) incr.multAtoms,		(int) incr.numConversions*2);    } else {	/*	 * Not a MULTIPLE request.  The first property in "multAtoms"	 * got set to None if there was an error in conversion.	 */	reply.property = incr.multAtoms[1];    }    XSendEvent(reply.display, reply.requestor, False, 0, (XEvent *) &reply);    Tk_DeleteErrorHandler(errorHandler);    /*     * Handle any remaining INCR-mode transfers.  This all happens     * in callbacks to TkSelPropProc, so just wait until the number     * of uncompleted INCR transfers drops to zero.     */    if (incr.numIncrs > 0) {	IncrInfo *incrPtr2;	while (incr.numIncrs > 0) {	    Tcl_DoOneEvent(0);

⌨️ 快捷键说明

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