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

📄 tkevent.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    if (winPtr->mainPtr != NULL) {        /*         * Protect interpreter for this window from possible deletion         * while we are dealing with the event for this window. Thus,         * widget writers do not have to worry about protecting the         * interpreter in their own code.         */                interp = winPtr->mainPtr->interp;        Tcl_Preserve((ClientData) interp);        	/*	 * Call focus-related code to look at FocusIn, FocusOut, Enter,	 * and Leave events;  depending on its return value, ignore the	 * event.	 */    	if ((mask & (FocusChangeMask|EnterWindowMask|LeaveWindowMask))		&& !TkFocusFilterEvent(winPtr, eventPtr)) {            Tcl_Release((ClientData) interp);	    return;	}    	/*	 * Redirect KeyPress and KeyRelease events to the focus window,	 * or ignore them entirely if there is no focus window.	 */    	if (mask & (KeyPressMask|KeyReleaseMask)) {	    winPtr->dispPtr->lastEventTime = eventPtr->xkey.time;	    winPtr = TkFocusKeyEvent(winPtr, eventPtr);	    if (winPtr == NULL) {                Tcl_Release((ClientData) interp);		return;	    }	}    	/*	 * Call a grab-related procedure to do special processing on	 * pointer events.	 */    	if (mask & (ButtonPressMask|ButtonReleaseMask|PointerMotionMask		|EnterWindowMask|LeaveWindowMask)) {	    if (mask & (ButtonPressMask|ButtonReleaseMask)) {		winPtr->dispPtr->lastEventTime = eventPtr->xbutton.time;	    } else if (mask & PointerMotionMask) {		winPtr->dispPtr->lastEventTime = eventPtr->xmotion.time;	    } else {		winPtr->dispPtr->lastEventTime = eventPtr->xcrossing.time;	    }	    if (TkPointerEvent(eventPtr, winPtr) == 0) {                goto done;	    }	}    }#ifdef TK_USE_INPUT_METHODS    /*     * Pass the event to the input method(s), if there are any, and     * discard the event if the input method(s) insist.  Create the     * input context for the window if it hasn't already been done     * (XFilterEvent needs this context).     */    if (!(winPtr->flags & TK_CHECKED_IC)) {	if (winPtr->dispPtr->inputMethod != NULL) {	    winPtr->inputContext = XCreateIC(		    winPtr->dispPtr->inputMethod, XNInputStyle,		    XIMPreeditNothing|XIMStatusNothing,		    XNClientWindow, winPtr->window,		    XNFocusWindow, winPtr->window, NULL);	}	winPtr->flags |= TK_CHECKED_IC;    }    if (XFilterEvent(eventPtr, None)) {        goto done;    }#endif /* TK_USE_INPUT_METHODS */    /*     * For events where it hasn't already been done, update the current     * time in the display.     */    if (eventPtr->type == PropertyNotify) {	winPtr->dispPtr->lastEventTime = eventPtr->xproperty.time;    }    /*     * There's a potential interaction here with Tk_DeleteEventHandler.     * Read the documentation for pendingPtr.     */    ip.eventPtr = eventPtr;    ip.winPtr = winPtr;    ip.nextHandler = NULL;    ip.nextPtr = pendingPtr;    pendingPtr = &ip;    if (mask == 0) {	if ((eventPtr->type == SelectionClear)		|| (eventPtr->type == SelectionRequest)		|| (eventPtr->type == SelectionNotify)) {	    TkSelEventProc((Tk_Window) winPtr, eventPtr);	} else if ((eventPtr->type == ClientMessage)		&& (eventPtr->xclient.message_type ==		    Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS"))) {	    TkWmProtocolEventProc(winPtr, eventPtr);	}    } else {	for (handlerPtr = winPtr->handlerList; handlerPtr != NULL; ) {	    if ((handlerPtr->mask & mask) != 0) {		ip.nextHandler = handlerPtr->nextPtr;		(*(handlerPtr->proc))(handlerPtr->clientData, eventPtr);		handlerPtr = ip.nextHandler;	    } else {		handlerPtr = handlerPtr->nextPtr;	    }	}	/*	 * Pass the event to the "bind" command mechanism.  But, don't	 * do this for SubstructureNotify events.  The "bind" command	 * doesn't support them anyway, and it's easier to filter out	 * these events here than in the lower-level procedures.	 */	if ((ip.winPtr != None) && (mask != SubstructureNotifyMask)) {	    TkBindEventProc(winPtr, eventPtr);	}    }    pendingPtr = ip.nextPtr;done:    /*     * Release the interpreter for this window so that it can be potentially     * deleted if requested.     */        if (interp != (Tcl_Interp *) NULL) {        Tcl_Release((ClientData) interp);    }}/* *-------------------------------------------------------------- * * TkEventDeadWindow -- * *	This procedure is invoked when it is determined that *	a window is dead.  It cleans up event-related information *	about the window. * * Results: *	None. * * Side effects: *	Various things get cleaned up and recycled. * *-------------------------------------------------------------- */voidTkEventDeadWindow(winPtr)    TkWindow *winPtr;		/* Information about the window				 * that is being deleted. */{    register TkEventHandler *handlerPtr;    register InProgress *ipPtr;    /*     * While deleting all the handlers, be careful to check for     * Tk_HandleEvent being about to process one of the deleted     * handlers.  If it is, tell it to quit (all of the handlers     * are being deleted).     */    while (winPtr->handlerList != NULL) {	handlerPtr = winPtr->handlerList;	winPtr->handlerList = handlerPtr->nextPtr;	for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {	    if (ipPtr->nextHandler == handlerPtr) {		ipPtr->nextHandler = NULL;	    }	    if (ipPtr->winPtr == winPtr) {		ipPtr->winPtr = None;	    }	}	ckfree((char *) handlerPtr);    }}/* *---------------------------------------------------------------------- * * TkCurrentTime -- * *	Try to deduce the current time.  "Current time" means the time *	of the event that led to the current code being executed, which *	means the time in the most recently-nested invocation of *	Tk_HandleEvent. * * Results: *	The return value is the time from the current event, or *	CurrentTime if there is no current event or if the current *	event contains no time. * * Side effects: *	None. * *---------------------------------------------------------------------- */TimeTkCurrentTime(dispPtr)    TkDisplay *dispPtr;		/* Display for which the time is desired. */{    register XEvent *eventPtr;    if (pendingPtr == NULL) {	return dispPtr->lastEventTime;    }    eventPtr = pendingPtr->eventPtr;    switch (eventPtr->type) {	case ButtonPress:	case ButtonRelease:	    return eventPtr->xbutton.time;	case KeyPress:	case KeyRelease:	    return eventPtr->xkey.time;	case MotionNotify:	    return eventPtr->xmotion.time;	case EnterNotify:	case LeaveNotify:	    return eventPtr->xcrossing.time;	case PropertyNotify:	    return eventPtr->xproperty.time;    }    return dispPtr->lastEventTime;}/* *---------------------------------------------------------------------- * * Tk_RestrictEvents -- * *	This procedure is used to globally restrict the set of events *	that will be dispatched.  The restriction is done by filtering *	all incoming X events through a procedure that determines *	whether they are to be processed immediately, deferred, or *	discarded. * * Results: *	The return value is the previous restriction procedure in effect, *	if there was one, or NULL if there wasn't. * * Side effects: *	From now on, proc will be called to determine whether to process, *	defer or discard each incoming X event. * *---------------------------------------------------------------------- */Tk_RestrictProc *Tk_RestrictEvents(proc, arg, prevArgPtr)    Tk_RestrictProc *proc;	/* Procedure to call for each incoming				 * event. */    ClientData arg;		/* Arbitrary argument to pass to proc. */    ClientData *prevArgPtr;	/* Place to store information about previous				 * argument. */{    Tk_RestrictProc *prev;    prev = restrictProc;    *prevArgPtr = restrictArg;    restrictProc = proc;    restrictArg = arg;    return prev;}/* *---------------------------------------------------------------------- * * Tk_QueueWindowEvent -- * *	Given an X-style window event, this procedure adds it to the *	Tcl event queue at the given position.  This procedure also *	performs mouse motion event collapsing if possible. * * Results: *	None. * * Side effects: *	Adds stuff to the event queue, which will eventually be *	processed. * *---------------------------------------------------------------------- */voidTk_QueueWindowEvent(eventPtr, position)    XEvent *eventPtr;			/* Event to add to queue.  This					 * procedures copies it before adding					 * it to the queue. */    Tcl_QueuePosition position;		/* Where to put it on the queue:					 * TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,					 * or TCL_QUEUE_MARK. */{    TkWindowEvent *wevPtr;    TkDisplay *dispPtr;    /*     * Find our display structure for the event's display.     */    for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) {	if (dispPtr == NULL) {	    return;	}	if (dispPtr->display == eventPtr->xany.display) {	    break;	}    }    if ((dispPtr->delayedMotionPtr != NULL) && (position == TCL_QUEUE_TAIL)) {	if ((eventPtr->type == MotionNotify) && (eventPtr->xmotion.window		== dispPtr->delayedMotionPtr->event.xmotion.window)) {	    /*	     * The new event is a motion event in the same window as the	     * saved motion event.  Just replace the saved event with the	     * new one.	     */	    dispPtr->delayedMotionPtr->event = *eventPtr;	    return;	} else if ((eventPtr->type != GraphicsExpose)		&& (eventPtr->type != NoExpose)		&& (eventPtr->type != Expose)) {	    /*	     * The new event may conflict with the saved motion event.  Queue	     * the saved motion event now so that it will be processed before	     * the new event.	     */	    Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, position);	    dispPtr->delayedMotionPtr = NULL;	    Tcl_CancelIdleCall(DelayedMotionProc, (ClientData) dispPtr);	}    }    wevPtr = (TkWindowEvent *) ckalloc(sizeof(TkWindowEvent));    wevPtr->header.proc = WindowEventProc;    wevPtr->event = *eventPtr;    if ((eventPtr->type == MotionNotify) && (position == TCL_QUEUE_TAIL)) {	/*	 * The new event is a motion event so don't queue it immediately;	 * save it around in case another motion event arrives that it can	 * be collapsed with.	 */	if (dispPtr->delayedMotionPtr != NULL) {	    panic("Tk_QueueWindowEvent found unexpected delayed motion event");	}	dispPtr->delayedMotionPtr = wevPtr;	Tcl_DoWhenIdle(DelayedMotionProc, (ClientData) dispPtr);    } else {	Tcl_QueueEvent(&wevPtr->header, position);    }}/* *--------------------------------------------------------------------------- * * TkQueueEventForAllChildren -- * *	Given an XEvent, recursively queue the event for this window and *	all non-toplevel children of the given window.   * * Results: *	None. * * Side effects: *	Events queued. * *--------------------------------------------------------------------------- */voidTkQueueEventForAllChildren(winPtr, eventPtr)    TkWindow *winPtr;	    /* Window to which event is sent. */    XEvent *eventPtr;	    /* The event to be sent. */{    TkWindow *childPtr;    eventPtr->xany.window = winPtr->window;    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_TAIL);        childPtr = winPtr->childList;    while (childPtr != NULL) {	if (!Tk_IsTopLevel(childPtr)) {	    TkQueueEventForAllChildren(childPtr, eventPtr);	}	childPtr = childPtr->nextPtr;    }}/* *---------------------------------------------------------------------- * * WindowEventProc -- * *	This procedure is called by Tcl_DoOneEvent when a window event *	reaches the front of the event queue.  This procedure is responsible *	for actually handling the event. * * 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 event isn't handled if the *	TCL_WINDOW_EVENTS bit isn't set in flags, if a restrict proc *	prevents the event from being handled. * * Side effects: *	Whatever the event handlers for the event do. * *---------------------------------------------------------------------- */static intWindowEventProc(evPtr, flags)    Tcl_Event *evPtr;		/* Event to service. */    int flags;			/* Flags that indicate what events to				 * handle, such as TCL_WINDOW_EVENTS. */{    TkWindowEvent *wevPtr = (TkWindowEvent *) evPtr;    Tk_RestrictAction result;    if (!(flags & TCL_WINDOW_EVENTS)) {	return 0;    }    if (restrictProc != NULL) {	result = (*restrictProc)(restrictArg, &wevPtr->event);	if (result != TK_PROCESS_EVENT) {	    if (result == TK_DEFER_EVENT) {		return 0;	    } else {		/*		 * TK_DELETE_EVENT: return and say we processed the event,		 * even though we didn't do anything at all.		 */		return 1;	    }	}    }    Tk_HandleEvent(&wevPtr->event);    return 1;}/* *---------------------------------------------------------------------- * * DelayedMotionProc -- * *	This procedure is invoked as an idle handler when a mouse motion *	event has been delayed.  It queues the delayed event so that it *	will finally be serviced. * * Results: *	None. * * Side effects: *	The delayed mouse motion event gets added to the Tcl event *	queue for servicing. * *---------------------------------------------------------------------- */static voidDelayedMotionProc(clientData)    ClientData clientData;	/* Pointer to display containing a delayed				 * motion event to be serviced. */{    TkDisplay *dispPtr = (TkDisplay *) clientData;    if (dispPtr->delayedMotionPtr == NULL) {	panic("DelayedMotionProc found no delayed mouse motion event");    }    Tcl_QueueEvent(&dispPtr->delayedMotionPtr->header, TCL_QUEUE_TAIL);    dispPtr->delayedMotionPtr = NULL;}/* *-------------------------------------------------------------- * * Tk_MainLoop -- * *	Call Tcl_DoOneEvent over and over again in an infinite *	loop as long as there exist any main windows. * * Results: *	None. * * Side effects: *	Arbitrary;  depends on handlers for events. * *-------------------------------------------------------------- */voidTk_MainLoop(){    while (Tk_GetNumMainWindows() > 0) {	Tcl_DoOneEvent(0);    }}

⌨️ 快捷键说明

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