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

📄 tkunixsend.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
 * * Side effects: *	The open registry is expanded;  it is marked as modified so that *	it will be written back when closed. * *---------------------------------------------------------------------- */static voidRegAddName(regPtr, name, commWindow)    NameRegistry *regPtr;	/* Pointer to a registry opened with a				 * previous call to RegOpen. */    char *name;			/* Name of an application.  The caller				 * must ensure that this name isn't				 * already registered. */    Window commWindow;		/* X identifier for comm. window of				 * application.  */{    char id[30];    char *newProp;    int idLength, newBytes;    sprintf(id, "%x ", (unsigned int) commWindow);    idLength = strlen(id);    newBytes = idLength + strlen(name) + 1;    newProp = (char *) ckalloc((unsigned) (regPtr->propLength + newBytes));    strcpy(newProp, id);    strcpy(newProp+idLength, name);    if (regPtr->property != NULL) {	memcpy((VOID *) (newProp + newBytes), (VOID *) regPtr->property,		regPtr->propLength);	if (regPtr->allocedByX) {	    XFree(regPtr->property);	} else {	    ckfree(regPtr->property);	}    }    regPtr->modified = 1;    regPtr->propLength += newBytes;    regPtr->property = newProp;    regPtr->allocedByX = 0;}/* *---------------------------------------------------------------------- * * RegClose -- * *	This procedure is called to end a series of operations on *	a name registry. * * Results: *	None. * * Side effects: *	The registry is written back if it has been modified, and the *	X server is unlocked if it was locked.  Memory for the *	registry is freed, so the caller should never use regPtr *	again. * *---------------------------------------------------------------------- */static voidRegClose(regPtr)    NameRegistry *regPtr;	/* Pointer to a registry opened with a				 * previous call to RegOpen. */{    if (regPtr->modified) {	if (!regPtr->locked && !sendDebug) {	    panic("The name registry was modified without being locked!");	}	XChangeProperty(regPtr->dispPtr->display,		RootWindow(regPtr->dispPtr->display, 0),		regPtr->dispPtr->registryProperty, XA_STRING, 8,		PropModeReplace, (unsigned char *) regPtr->property,		(int) regPtr->propLength);    }    if (regPtr->locked) {	XUngrabServer(regPtr->dispPtr->display);    }    /*     * After ungrabbing the server, it's important to flush the output     * immediately so that the server sees the ungrab command.  Otherwise     * we might do something else that needs to communicate with the     * server (such as invoking a subprocess that needs to do I/O to     * the screen); if the ungrab command is still sitting in our     * output buffer, we could deadlock.     */    XFlush(regPtr->dispPtr->display);    if (regPtr->property != NULL) {	if (regPtr->allocedByX) {	    XFree(regPtr->property);	} else {	    ckfree(regPtr->property);	}    }    ckfree((char *) regPtr);}/* *---------------------------------------------------------------------- * * ValidateName -- * *	This procedure checks to see if an entry in the registry *	is still valid. * * Results: *	The return value is 1 if the given commWindow exists and its *	name is "name".  Otherwise 0 is returned. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intValidateName(dispPtr, name, commWindow, oldOK)    TkDisplay *dispPtr;		/* Display for which to perform the				 * validation. */    char *name;			/* The name of an application. */    Window commWindow;		/* X identifier for the application's				 * comm. window. */    int oldOK;			/* Non-zero means that we should consider				 * an application to be valid even if it				 * looks like an old-style (pre-4.0) one;				 * 0 means consider these invalid. */{    int result, actualFormat, argc, i;    unsigned long length, bytesAfter;    Atom actualType;    char *property;    Tk_ErrorHandler handler;    char **argv;    property = NULL;    /*     * Ignore X errors when reading the property (e.g., the window     * might not exist).  If an error occurs, result will be some     * value other than Success.     */    handler = Tk_CreateErrorHandler(dispPtr->display, -1, -1, -1,	    (Tk_ErrorProc *) NULL, (ClientData) NULL);    result = XGetWindowProperty(dispPtr->display, commWindow,	    dispPtr->appNameProperty, 0, MAX_PROP_WORDS,	    False, XA_STRING, &actualType, &actualFormat,	    &length, &bytesAfter, (unsigned char **) &property);    if ((result == Success) && (actualType == None)) {	XWindowAttributes atts;	/*	 * The comm. window exists but the property we're looking for	 * doesn't exist.  This probably means that the application	 * comes from an older version of Tk (< 4.0) that didn't set the	 * property;  if this is the case, then assume for compatibility's	 * sake that everything's OK.  However, it's also possible that	 * some random application has re-used the window id for something	 * totally unrelated.  Check a few characteristics of the window,	 * such as its dimensions and mapped state, to be sure that it	 * still "smells" like a commWindow.	 */	if (!oldOK		|| !XGetWindowAttributes(dispPtr->display, commWindow, &atts)		|| (atts.width != 1) || (atts.height != 1)		|| (atts.map_state != IsUnmapped)) {	    result = 0;	} else {	    result = 1;	}    } else if ((result == Success) && (actualFormat == 8)	   && (actualType == XA_STRING)) {	result = 0;	if (Tcl_SplitList((Tcl_Interp *) NULL, property, &argc, &argv)		== TCL_OK) {	    for (i = 0; i < argc; i++) {		if (strcmp(argv[i], name) == 0) {		    result = 1;		    break;		}	    }	    ckfree((char *) argv);	}    } else {       result = 0;    }    Tk_DeleteErrorHandler(handler);    if (property != NULL) {	XFree(property);    }    return result;}/* *---------------------------------------------------------------------- * * ServerSecure -- * *	Check whether a server is secure enough for us to trust *	Tcl scripts arriving via that server. * * Results: *	The return value is 1 if the server is secure, which means *	that host-style authentication is turned on but there are *	no hosts in the enabled list.  This means that some other *	form of authorization (presumably more secure, such as xauth) *	is in use. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intServerSecure(dispPtr)    TkDisplay *dispPtr;		/* Display to check. */{#ifdef TK_NO_SECURITY    return 1;#else    XHostAddress *addrPtr;    int numHosts, secure;    Bool enabled;    secure = 0;    addrPtr = XListHosts(dispPtr->display, &numHosts, &enabled);    if (enabled && (numHosts == 0)) {	secure = 1;    }    if (addrPtr != NULL) {	XFree((char *) addrPtr);    }    return secure;#endif /* TK_NO_SECURITY */}/* *-------------------------------------------------------------- * * Tk_SetAppName -- * *	This procedure is called to associate an ASCII name with a Tk *	application.  If the application has already been named, the *	name replaces the old one. * * Results: *	The return value is the name actually given to the application. *	This will normally be the same as name, but if name was already *	in use for an application then a name of the form "name #2" will *	be chosen,  with a high enough number to make the name unique. * * Side effects: *	Registration info is saved, thereby allowing the "send" command *	to be used later to invoke commands in the application.  In *	addition, the "send" command is created in the application's *	interpreter.  The registration will be removed automatically *	if the interpreter is deleted or the "send" command is removed. * *-------------------------------------------------------------- */char *Tk_SetAppName(tkwin, name)    Tk_Window tkwin;		/* Token for any window in the application				 * to be named:  it is just used to identify				 * the application and the display.  */    char *name;			/* The name that will be used to				 * refer to the interpreter in later				 * "send" commands.  Must be globally				 * unique. */{    RegisteredInterp *riPtr, *riPtr2;    Window w;    TkWindow *winPtr = (TkWindow *) tkwin;    TkDisplay *dispPtr;    NameRegistry *regPtr;    Tcl_Interp *interp;    char *actualName;    Tcl_DString dString;    int offset, i;#ifdef __WIN32__    return name;#endif /* __WIN32__ */        dispPtr = winPtr->dispPtr;    interp = winPtr->mainPtr->interp;    if (dispPtr->commTkwin == NULL) {	SendInit(interp, winPtr->dispPtr);    }    /*     * See if the application is already registered;  if so, remove its     * current name from the registry.     */    regPtr = RegOpen(interp, winPtr->dispPtr, 1);    for (riPtr = registry; ; riPtr = riPtr->nextPtr) {	if (riPtr == NULL) {	    /*	     * This interpreter isn't currently registered;  create	     * the data structure that will be used to register it locally,	     * plus add the "send" command to the interpreter.	     */	    riPtr = (RegisteredInterp *) ckalloc(sizeof(RegisteredInterp));	    riPtr->interp = interp;	    riPtr->dispPtr = winPtr->dispPtr;	    riPtr->nextPtr = registry;	    registry = riPtr;	    Tcl_CreateCommand(interp, "send", Tk_SendCmd, (ClientData) riPtr,		    DeleteProc);            if (Tcl_IsSafe(interp)) {                Tcl_HideCommand(interp, "send", "send");            }	    break;	}	if (riPtr->interp == interp) {	    /*	     * The interpreter is currently registered;  remove it from	     * the name registry.	     */	    RegDeleteName(regPtr, riPtr->name);	    ckfree(riPtr->name);	    break;	}    }    /*     * Pick a name to use for the application.  Use "name" if it's not     * already in use.  Otherwise add a suffix such as " #2", trying     * larger and larger numbers until we eventually find one that is     * unique.     */    actualName = name;    offset = 0;				/* Needed only to avoid "used before					 * set" compiler warnings. */    for (i = 1; ; i++) {	if (i > 1) {	    if (i == 2) {		Tcl_DStringInit(&dString);		Tcl_DStringAppend(&dString, name, -1);		Tcl_DStringAppend(&dString, " #", 2);		offset = Tcl_DStringLength(&dString);		Tcl_DStringSetLength(&dString, offset+10);		actualName = Tcl_DStringValue(&dString);	    }	    sprintf(actualName + offset, "%d", i);	}	w = RegFindName(regPtr, actualName);	if (w == None) {	    break;	}    	/*	 * The name appears to be in use already, but double-check to	 * be sure (perhaps the application died without removing its	 * name from the registry?).	 */	if (w == Tk_WindowId(dispPtr->commTkwin)) {	    for (riPtr2 = registry; riPtr2 != NULL; riPtr2 = riPtr2->nextPtr) {		if ((riPtr2->interp != interp) &&			(strcmp(riPtr2->name, actualName) == 0)) {		    goto nextSuffix;		}	    }	    RegDeleteName(regPtr, actualName);	    break;	} else if (!ValidateName(winPtr->dispPtr, actualName, w, 1)) {	    RegDeleteName(regPtr, actualName);	    break;	}	nextSuffix:	continue;    }    /*     * We've now got a name to use.  Store it in the name registry and     * in the local entry for this application, plus put it in a property     * on the commWindow.     */    RegAddName(regPtr, actualName, Tk_WindowId(dispPtr->commTkwin));    RegClose(regPtr);    riPtr->name = (char *) ckalloc((unsigned) (strlen(actualName) + 1));    strcpy(riPtr->name, actualName);    if (actualName != name) {	Tcl_DStringFree(&dString);    }    UpdateCommWindow(dispPtr);    return riPtr->name;}/* *-------------------------------------------------------------- * * Tk_SendCmd -- * *	This procedure is invoked to process the "send" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *-------------------------------------------------------------- */intTk_SendCmd(clientData, interp, argc, argv)    ClientData clientData;		/* Information about sender (only					 * dispPtr field is used). */    Tcl_Interp *interp;			/* Current interpreter. */    int argc;				/* Number of arguments. */    char **argv;			/* Argument strings. */{    TkWindow *winPtr;    Window commWindow;    PendingCommand pending;    register RegisteredInterp *riPtr;    char *destName, buffer[30];    int result, c, async, i, firstArg;    size_t length;    Tk_RestrictProc *prevRestrictProc;    ClientData prevArg;    TkDisplay *dispPtr;    Tcl_Time timeout;    NameRegistry *regPtr;    Tcl_DString request;    Tcl_Interp *localInterp;		/* Used when the interpreter to                                         * send the command to is within                                         * the same process. */    /*     * Process options, if any.     */    async = 0;    winPtr = (TkWindow *) Tk_MainWindow(interp);    if (winPtr == NULL) {	return TCL_ERROR;    }    for (i = 1; i < (argc-1); ) {	if (argv[i][0] != '-') {	    break;	}

⌨️ 快捷键说明

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