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

📄 tkunixsend.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
	if ((*p == 'c') && (p[1] == 0)) {	    Window commWindow;	    char *interpName, *script, *serial, *end;	    Tcl_DString reply;	    RegisteredInterp *riPtr;	    /*	     *----------------------------------------------------------	     * This is an incoming command from some other application.	     * Iterate over all of its options.  Stop when we reach	     * the end of the property or something that doesn't look	     * like an option.	     *----------------------------------------------------------	     */	    p += 2;	    interpName = NULL;	    commWindow = None;	    serial = "";	    script = NULL;	    while (((p-propInfo) < (int) numItems) && (*p == '-')) {		switch (p[1]) {		    case 'r':			commWindow = (Window) strtoul(p+2, &end, 16);			if ((end == p+2) || (*end != ' ')) {			    commWindow = None;			} else {			    p = serial = end+1;			}			break;		    case 'n':			if (p[2] == ' ') {			    interpName = p+3;			}			break;		    case 's':			if (p[2] == ' ') {			    script = p+3;			}			break;		}		while (*p != 0) {		    p++;		}		p++;	    }	    if ((script == NULL) || (interpName == NULL)) {		continue;	    }	    /*	     * Initialize the result property, so that we're ready at any	     * time if we need to return an error.	     */	    if (commWindow != None) {		Tcl_DStringInit(&reply);		Tcl_DStringAppend(&reply, "\0r\0-s ", 6);		Tcl_DStringAppend(&reply, serial, -1);		Tcl_DStringAppend(&reply, "\0-r ", 4);	    }	    if (!ServerSecure(dispPtr)) {		if (commWindow != None) {		    Tcl_DStringAppend(&reply, "X server insecure (must use xauth-style authorization); command ignored", -1);		}		result = TCL_ERROR;		goto returnResult;	    }	    /*	     * Locate the application, then execute the script.	     */	    for (riPtr = registry; ; riPtr = riPtr->nextPtr) {		if (riPtr == NULL) {		    if (commWindow != None) {			Tcl_DStringAppend(&reply,				"receiver never heard of interpreter \"", -1);			Tcl_DStringAppend(&reply, interpName, -1);			Tcl_DStringAppend(&reply, "\"", 1);		    }		    result = TCL_ERROR;		    goto returnResult;		}		if (strcmp(riPtr->name, interpName) == 0) {		    break;		}	    }	    Tcl_Preserve((ClientData) riPtr);            /*             * We must protect the interpreter because the script may             * enter another event loop, which might call Tcl_DeleteInterp.             */            remoteInterp = riPtr->interp;            Tcl_Preserve((ClientData) remoteInterp);            result = Tcl_GlobalEval(remoteInterp, script);            /*             * The call to Tcl_Release may have released the interpreter             * which will cause the "send" command for that interpreter             * to be deleted. The command deletion callback will set the             * riPtr->interp field to NULL, hence the check below for NULL.             */	    if (commWindow != None) {		Tcl_DStringAppend(&reply, remoteInterp->result, -1);		if (result == TCL_ERROR) {		    char *varValue;    		    varValue = Tcl_GetVar2(remoteInterp, "errorInfo",			    (char *) NULL, TCL_GLOBAL_ONLY);		    if (varValue != NULL) {			Tcl_DStringAppend(&reply, "\0-i ", 4);			Tcl_DStringAppend(&reply, varValue, -1);		    }		    varValue = Tcl_GetVar2(remoteInterp, "errorCode",			    (char *) NULL, TCL_GLOBAL_ONLY);		    if (varValue != NULL) {			Tcl_DStringAppend(&reply, "\0-e ", 4);			Tcl_DStringAppend(&reply, varValue, -1);		    }		}	    }            Tcl_Release((ClientData) remoteInterp);	    Tcl_Release((ClientData) riPtr);	    /*	     * Return the result to the sender if a commWindow was	     * specified (if none was specified then this is an asynchronous	     * call).  Right now reply has everything but the completion	     * code, but it needs the NULL to terminate the current option.	     */	    returnResult:	    if (commWindow != None) {		if (result != TCL_OK) {		    char buffer[20];    		    sprintf(buffer, "%d", result);		    Tcl_DStringAppend(&reply, "\0-c ", 4);		    Tcl_DStringAppend(&reply, buffer, -1);		}		(void) AppendPropCarefully(dispPtr->display, commWindow,			dispPtr->commProperty, Tcl_DStringValue(&reply),			Tcl_DStringLength(&reply) + 1,			(PendingCommand *) NULL);		XFlush(dispPtr->display);		Tcl_DStringFree(&reply);	    }	} else if ((*p == 'r') && (p[1] == 0)) {	    int serial, code, gotSerial;	    char *errorInfo, *errorCode, *resultString;	    PendingCommand *pcPtr;	    /*	     *----------------------------------------------------------	     * This is a reply to some command that we sent out.  Iterate	     * over all of its options.  Stop when we reach the end of the	     * property or something that doesn't look like an option.	     *----------------------------------------------------------	     */	    p += 2;	    code = TCL_OK;	    gotSerial = 0;	    errorInfo = NULL;	    errorCode = NULL;	    resultString = "";	    while (((p-propInfo) < (int) numItems) && (*p == '-')) {		switch (p[1]) {		    case 'c':			if (sscanf(p+2, " %d", &code) != 1) {			    code = TCL_OK;			}			break;		    case 'e':			if (p[2] == ' ') {			    errorCode = p+3;			}			break;		    case 'i':			if (p[2] == ' ') {			    errorInfo = p+3;			}			break;		    case 'r':			if (p[2] == ' ') {			    resultString = p+3;			}			break;		    case 's':			if (sscanf(p+2, " %d", &serial) == 1) {			    gotSerial = 1;			}			break;		}		while (*p != 0) {		    p++;		}		p++;	    }	    if (!gotSerial) {		continue;	    }	    /*	     * Give the result information to anyone who's	     * waiting for it.	     */	    for (pcPtr = pendingCommands; pcPtr != NULL;		    pcPtr = pcPtr->nextPtr) {		if ((serial != pcPtr->serial) || (pcPtr->result != NULL)) {		    continue;		}		pcPtr->code = code;		if (resultString != NULL) {		    pcPtr->result = (char *) ckalloc((unsigned)			    (strlen(resultString) + 1));		    strcpy(pcPtr->result, resultString);		}		if (code == TCL_ERROR) {		    if (errorInfo != NULL) {			pcPtr->errorInfo = (char *) ckalloc((unsigned)				(strlen(errorInfo) + 1));			strcpy(pcPtr->errorInfo, errorInfo);		    }		    if (errorCode != NULL) {			pcPtr->errorCode = (char *) ckalloc((unsigned)				(strlen(errorCode) + 1));			strcpy(pcPtr->errorCode, errorCode);		    }		}		pcPtr->gotResponse = 1;		break;	    }	} else {	    /*	     * Didn't recognize this thing.  Just skip through the next	     * null character and try again.	     */	    while (*p != 0) {		p++;	    }	    p++;	}    }    XFree(propInfo);}/* *-------------------------------------------------------------- * * AppendPropCarefully -- * *	Append a given property to a given window, but set up *	an X error handler so that if the append fails this *	procedure can return an error code rather than having *	Xlib panic. * * Results: *	None. * * Side effects: *	The given property on the given window is appended to. *	If this operation fails and if pendingPtr is non-NULL, *	then the pending operation is marked as complete with *	an error. * *-------------------------------------------------------------- */static voidAppendPropCarefully(display, window, property, value, length, pendingPtr)    Display *display;		/* Display on which to operate. */    Window window;		/* Window whose property is to				 * be modified. */    Atom property;		/* Name of property. */    char *value;		/* Characters to append to property. */    int length;			/* Number of bytes to append. */    PendingCommand *pendingPtr;	/* Pending command to mark complete				 * if an error occurs during the				 * property op.  NULL means just				 * ignore the error. */{    Tk_ErrorHandler handler;    handler = Tk_CreateErrorHandler(display, -1, -1, -1, AppendErrorProc,	(ClientData) pendingPtr);    XChangeProperty(display, window, property, XA_STRING, 8,	    PropModeAppend, (unsigned char *) value, length);    Tk_DeleteErrorHandler(handler);}/* * The procedure below is invoked if an error occurs during * the XChangeProperty operation above. */	/* ARGSUSED */static intAppendErrorProc(clientData, errorPtr)    ClientData clientData;	/* Command to mark complete, or NULL. */    XErrorEvent *errorPtr;	/* Information about error. */{    PendingCommand *pendingPtr = (PendingCommand *) clientData;    register PendingCommand *pcPtr;    if (pendingPtr == NULL) {	return 0;    }    /*     * Make sure this command is still pending.     */    for (pcPtr = pendingCommands; pcPtr != NULL;	    pcPtr = pcPtr->nextPtr) {	if ((pcPtr == pendingPtr) && (pcPtr->result == NULL)) {	    pcPtr->result = (char *) ckalloc((unsigned)		    (strlen(pcPtr->target) + 50));	    sprintf(pcPtr->result, "no application named \"%s\"",		    pcPtr->target);	    pcPtr->code = TCL_ERROR;	    pcPtr->gotResponse = 1;	    break;	}    }    return 0;}/* *-------------------------------------------------------------- * * DeleteProc -- * *	This procedure is invoked by Tcl when the "send" command *	is deleted in an interpreter.  It unregisters the interpreter. * * Results: *	None. * * Side effects: *	The interpreter given by riPtr is unregistered. * *-------------------------------------------------------------- */static voidDeleteProc(clientData)    ClientData clientData;	/* Info about registration, passed				 * as ClientData. */{    RegisteredInterp *riPtr = (RegisteredInterp *) clientData;    register RegisteredInterp *riPtr2;    NameRegistry *regPtr;    regPtr = RegOpen(riPtr->interp, riPtr->dispPtr, 1);    RegDeleteName(regPtr, riPtr->name);    RegClose(regPtr);    if (registry == riPtr) {	registry = riPtr->nextPtr;    } else {	for (riPtr2 = registry; riPtr2 != NULL;		riPtr2 = riPtr2->nextPtr) {	    if (riPtr2->nextPtr == riPtr) {		riPtr2->nextPtr = riPtr->nextPtr;		break;	    }	}    }    ckfree((char *) riPtr->name);    riPtr->interp = NULL;    UpdateCommWindow(riPtr->dispPtr);    Tcl_EventuallyFree((ClientData) riPtr, TCL_DYNAMIC);}/* *---------------------------------------------------------------------- * * SendRestrictProc -- * *	This procedure filters incoming events when a "send" command *	is outstanding.  It defers all events except those containing *	send commands and results. * * Results: *	False is returned except for property-change events on a *	commWindow. * * Side effects: *	None. * *---------------------------------------------------------------------- */    /* ARGSUSED */static Tk_RestrictActionSendRestrictProc(clientData, eventPtr)    ClientData clientData;		/* Not used. */    register XEvent *eventPtr;		/* Event that just arrived. */{    TkDisplay *dispPtr;    if (eventPtr->type != PropertyNotify) {	return TK_DEFER_EVENT;    }    for (dispPtr = tkDisplayList; dispPtr != NULL; dispPtr = dispPtr->nextPtr) {	if ((eventPtr->xany.display == dispPtr->display)		&& (eventPtr->xproperty.window		== Tk_WindowId(dispPtr->commTkwin))) {	    return TK_PROCESS_EVENT;	}    }    return TK_DEFER_EVENT;}/* *---------------------------------------------------------------------- * * UpdateCommWindow -- * *	This procedure updates the list of application names stored *	on our commWindow.  It is typically called when interpreters *	are registered and unregistered. * * Results: *	None. * * Side effects: *	The TK_APPLICATION property on the comm window is updated. * *---------------------------------------------------------------------- */static voidUpdateCommWindow(dispPtr)    TkDisplay *dispPtr;		/* Display whose commWindow is to be				 * updated. */{    Tcl_DString names;    RegisteredInterp *riPtr;    Tcl_DStringInit(&names);    for (riPtr = registry; riPtr != NULL; riPtr = riPtr->nextPtr) {	Tcl_DStringAppendElement(&names, riPtr->name);    }    XChangeProperty(dispPtr->display, Tk_WindowId(dispPtr->commTkwin),	    dispPtr->appNameProperty, XA_STRING, 8, PropModeReplace,	    (unsigned char *) Tcl_DStringValue(&names),	    Tcl_DStringLength(&names));    Tcl_DStringFree(&names);}

⌨️ 快捷键说明

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