static void GenerateFocusEvents( TkWindow *sourcePtr, /* Window that used to have the focus (may be * NULL). */ TkWindow *destPtr) /* New window to have the focus (may be * NULL). */ { XEvent event; TkWindow *winPtr; winPtr = sourcePtr; if (winPtr == NULL) { winPtr = destPtr; if (winPtr == NULL) { return; } } event.xfocus.serial = LastKnownRequestProcessed(winPtr->display); event.xfocus.send_event = GENERATED_FOCUS_EVENT_MAGIC; event.xfocus.display = winPtr->display; event.xfocus.mode = NotifyNormal; TkInOutEvents(&event, sourcePtr, destPtr, FocusOut, FocusIn, TCL_QUEUE_MARK); }
static void MovePointer2( TkWindow *sourcePtr, /* Window currently containing pointer (NULL * means it's not one managed by this * process). */ TkWindow *destPtr, /* Window that is to end up containing the * pointer (NULL means it's not one managed by * this process). */ int mode, /* Mode for enter/leave events, such as * NotifyNormal or NotifyUngrab. */ int leaveEvents, /* Non-zero means generate leave events for * the windows being left. Zero means don't * generate leave events. */ int enterEvents) /* Non-zero means generate enter events for * the windows being entered. Zero means don't * generate enter events. */ { XEvent event; Window dummy1, dummy2; int dummy3, dummy4; TkWindow *winPtr; winPtr = sourcePtr; if ((winPtr == NULL) || (winPtr->window == None)) { winPtr = destPtr; if ((winPtr == NULL) || (winPtr->window == None)) { return; } } event.xcrossing.serial = LastKnownRequestProcessed(winPtr->display); event.xcrossing.send_event = GENERATED_GRAB_EVENT_MAGIC; event.xcrossing.display = winPtr->display; event.xcrossing.root = RootWindow(winPtr->display, winPtr->screenNum); event.xcrossing.time = TkCurrentTime(winPtr->dispPtr); XQueryPointer(winPtr->display, winPtr->window, &dummy1, &dummy2, &event.xcrossing.x_root, &event.xcrossing.y_root, &dummy3, &dummy4, &event.xcrossing.state); event.xcrossing.mode = mode; event.xcrossing.focus = False; TkInOutEvents(&event, sourcePtr, destPtr, (leaveEvents) ? LeaveNotify : 0, (enterEvents) ? EnterNotify : 0, TCL_QUEUE_MARK); }
static int GenerateEnterLeave( TkWindow *winPtr, /* Current Tk window (or NULL). */ int x, int y, /* Current mouse position in root coords. */ int state) /* State flags. */ { int crossed = 0; /* 1 if mouse crossed a window boundary */ ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); TkWindow *restrictWinPtr = tsdPtr->restrictWinPtr; TkWindow *lastWinPtr = tsdPtr->lastWinPtr; if (winPtr != tsdPtr->lastWinPtr) { if (restrictWinPtr) { int newPos, oldPos; newPos = TkPositionInTree(winPtr, restrictWinPtr); oldPos = TkPositionInTree(lastWinPtr, restrictWinPtr); /* * Check if the mouse crossed into or out of the restrict window. * If so, we need to generate an Enter or Leave event. */ if ((newPos != oldPos) && ((newPos == TK_GRAB_IN_TREE) || (oldPos == TK_GRAB_IN_TREE))) { XEvent event; int type, detail; if (newPos == TK_GRAB_IN_TREE) { type = EnterNotify; } else { type = LeaveNotify; } if ((oldPos == TK_GRAB_ANCESTOR) || (newPos == TK_GRAB_ANCESTOR)) { detail = NotifyAncestor; } else { detail = NotifyVirtual; } InitializeEvent(&event, restrictWinPtr, type, x, y, state, detail); Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } } else { TkWindow *targetPtr; if ((lastWinPtr == NULL) || (lastWinPtr->window == None)) { targetPtr = winPtr; } else { targetPtr = lastWinPtr; } if (targetPtr && (targetPtr->window != None)) { XEvent event; /* * Generate appropriate Enter/Leave events. */ InitializeEvent(&event, targetPtr, LeaveNotify, x, y, state, NotifyNormal); TkInOutEvents(&event, lastWinPtr, winPtr, LeaveNotify, EnterNotify, TCL_QUEUE_TAIL); crossed = 1; } } tsdPtr->lastWinPtr = winPtr; } return crossed; }