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

📄 tclxtnotify.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 2 页
字号:
 * *---------------------------------------------------------------------- */static voidCreateFileHandler(fd, mask, proc, clientData)    int fd;			/* Handle of stream to watch. */    int mask;			/* OR'ed combination of TCL_READABLE,				 * TCL_WRITABLE, and TCL_EXCEPTION:				 * indicates conditions under which				 * proc should be called. */    Tcl_FileProc *proc;		/* Procedure to call for each				 * selected event. */    ClientData clientData;	/* Arbitrary data to pass to proc. */{    FileHandler *filePtr;    if (!initialized) {	InitNotifier();    }    TclSetAppContext(NULL);    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;	    filePtr = filePtr->nextPtr) {	if (filePtr->fd == fd) {	    break;	}    }    if (filePtr == NULL) {	filePtr = (FileHandler*) ckalloc(sizeof(FileHandler));	filePtr->fd = fd;	filePtr->read = 0;	filePtr->write = 0;	filePtr->except = 0;	filePtr->readyMask = 0;	filePtr->mask = 0;	filePtr->nextPtr = notifier.firstFileHandlerPtr;	notifier.firstFileHandlerPtr = filePtr;    }    filePtr->proc = proc;    filePtr->clientData = clientData;    /*     * Register the file with the Xt notifier, if it hasn't been done yet.     */    if (mask & TCL_READABLE) {	if (!(filePtr->mask & TCL_READABLE)) {	    filePtr->read =                XtAppAddInput(notifier.appContext, fd, XtInputReadMask,                        FileProc, filePtr);	}    } else {	if (filePtr->mask & TCL_READABLE) {	    XtRemoveInput(filePtr->read);	}    }    if (mask & TCL_WRITABLE) {	if (!(filePtr->mask & TCL_WRITABLE)) {	    filePtr->write =                XtAppAddInput(notifier.appContext, fd, XtInputWriteMask,                        FileProc, filePtr);	}    } else {	if (filePtr->mask & TCL_WRITABLE) {	    XtRemoveInput(filePtr->write);	}    }    if (mask & TCL_EXCEPTION) {	if (!(filePtr->mask & TCL_EXCEPTION)) {	    filePtr->except =                XtAppAddInput(notifier.appContext, fd, XtInputExceptMask,                        FileProc, filePtr);	}    } else {	if (filePtr->mask & TCL_EXCEPTION) {	    XtRemoveInput(filePtr->except);	}    }    filePtr->mask = mask;}/* *---------------------------------------------------------------------- * * DeleteFileHandler -- * *	Cancel a previously-arranged callback arrangement for *	a file. * * Results: *	None. * * Side effects: *	If a callback was previously registered on file, remove it. * *---------------------------------------------------------------------- */static voidDeleteFileHandler(fd)    int fd;			/* Stream id for which to remove				 * callback procedure. */{    FileHandler *filePtr, *prevPtr;    if (!initialized) {	InitNotifier();    }    TclSetAppContext(NULL);    /*     * Find the entry for the given file (and return if there     * isn't one).     */    for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ;	    prevPtr = filePtr, filePtr = filePtr->nextPtr) {	if (filePtr == NULL) {	    return;	}	if (filePtr->fd == fd) {	    break;	}    }    /*     * Clean up information in the callback record.     */    if (prevPtr == NULL) {	notifier.firstFileHandlerPtr = filePtr->nextPtr;    } else {	prevPtr->nextPtr = filePtr->nextPtr;    }    if (filePtr->mask & TCL_READABLE) {	XtRemoveInput(filePtr->read);    }    if (filePtr->mask & TCL_WRITABLE) {	XtRemoveInput(filePtr->write);    }    if (filePtr->mask & TCL_EXCEPTION) {	XtRemoveInput(filePtr->except);    }    ckfree((char *) filePtr);}/* *---------------------------------------------------------------------- * * FileProc -- * *	These procedures are called by Xt when a file becomes readable, *	writable, or has an exception. * * Results: *	None. * * Side effects: *	Makes an entry on the Tcl event queue if the event is *	interesting. * *---------------------------------------------------------------------- */static voidFileProc(clientData, fd, id)    caddr_t clientData;    int *fd;    XtInputId *id;{    FileHandler *filePtr = (FileHandler *)clientData;    FileHandlerEvent *fileEvPtr;    int mask = 0;    /*     * Determine which event happened.     */    if (*id == filePtr->read) {	mask = TCL_READABLE;    } else if (*id == filePtr->write) {	mask = TCL_WRITABLE;    } else if (*id == filePtr->except) {	mask = TCL_EXCEPTION;    }    /*     * Ignore unwanted or duplicate events.     */    if (!(filePtr->mask & mask) || (filePtr->readyMask & mask)) {	return;    }        /*     * This is an interesting event, so put it onto the event queue.     */    filePtr->readyMask |= mask;    fileEvPtr = (FileHandlerEvent *) ckalloc(sizeof(FileHandlerEvent));    fileEvPtr->header.proc = FileHandlerEventProc;    fileEvPtr->fd = filePtr->fd;    Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);    /*     * Process events on the Tcl event queue before returning to Xt.     */    Tcl_ServiceAll();}/* *---------------------------------------------------------------------- * * FileHandlerEventProc -- * *	This procedure is called by Tcl_ServiceEvent when a file event *	reaches the front of the event queue.  This procedure is *	responsible for actually handling the event by invoking the *	callback for the file handler. * * Results: *	Returns 1 if the event was handled, meaning it should be removed *	from the queue.  Returns 0 if the event was not handled, meaning *	it should stay on the queue.  The only time the event isn't *	handled is if the TCL_FILE_EVENTS flag bit isn't set. * * Side effects: *	Whatever the file handler's callback procedure does. * *---------------------------------------------------------------------- */static intFileHandlerEventProc(evPtr, flags)    Tcl_Event *evPtr;		/* Event to service. */    int flags;			/* Flags that indicate what events to				 * handle, such as TCL_FILE_EVENTS. */{    FileHandler *filePtr;    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;    int mask;    if (!(flags & TCL_FILE_EVENTS)) {	return 0;    }    /*     * Search through the file handlers to find the one whose handle matches     * the event.  We do this rather than keeping a pointer to the file     * handler directly in the event, so that the handler can be deleted     * while the event is queued without leaving a dangling pointer.     */    for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;	    filePtr = filePtr->nextPtr) {	if (filePtr->fd != fileEvPtr->fd) {	    continue;	}	/*	 * The code is tricky for two reasons:	 * 1. The file handler's desired events could have changed	 *    since the time when the event was queued, so AND the	 *    ready mask with the desired mask.	 * 2. The file could have been closed and re-opened since	 *    the time when the event was queued.  This is why the	 *    ready mask is stored in the file handler rather than	 *    the queued event:  it will be zeroed when a new	 *    file handler is created for the newly opened file.	 */	mask = filePtr->readyMask & filePtr->mask;	filePtr->readyMask = 0;	if (mask != 0) {	    (*filePtr->proc)(filePtr->clientData, mask);	}	break;    }    return 1;}/* *---------------------------------------------------------------------- * * WaitForEvent -- * *	This function is called by Tcl_DoOneEvent to wait for new *	events on the message queue.  If the block time is 0, then *	Tcl_WaitForEvent just polls without blocking. * * Results: *	Returns 1 if an event was found, else 0.  This ensures that *	Tcl_DoOneEvent will return 1, even if the event is handled *	by non-Tcl code. * * Side effects: *	Queues file events that are detected by the select. * *---------------------------------------------------------------------- */static intWaitForEvent(    Tcl_Time *timePtr)		/* Maximum block time, or NULL. */{    int timeout;    if (!initialized) {	InitNotifier();    }    TclSetAppContext(NULL);    if (timePtr) {        timeout = timePtr->sec * 1000 + timePtr->usec / 1000;        if (timeout == 0) {            if (XtAppPending(notifier.appContext)) {                goto process;            } else {                return 0;            }        } else {            Tcl_SetTimer(timePtr);        }    }process:    XtAppProcessEvent(notifier.appContext, XtIMAll);    return 1;}

⌨️ 快捷键说明

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