static void BringWindowForward( WindowRef wRef, int isFrontProcess, int frontWindowOnly) { if (wRef && !TkpIsWindowFloating(wRef) && IsValidWindowPtr(wRef)) { WindowRef frontWindow = FrontNonFloatingWindow(); WindowModality frontWindowModality = kWindowModalityNone; if (frontWindow && frontWindow != wRef) { ChkErr(GetWindowModality, frontWindow, &frontWindowModality, NULL); } if (frontWindowModality != kWindowModalityAppModal) { Window window = TkMacOSXGetXWindow(wRef); if (window != None) { TkDisplay *dispPtr = TkGetDisplayList(); TkWindow * winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, window); if (winPtr && winPtr->wmInfoPtr && winPtr->wmInfoPtr->master != None) { TkWindow *masterWinPtr = (TkWindow *)Tk_IdToWindow( dispPtr->display, winPtr->wmInfoPtr->master); if (masterWinPtr && masterWinPtr->window != None && TkMacOSXHostToplevelExists(masterWinPtr)) { WindowRef masterMacWin = TkMacOSXDrawableWindow(masterWinPtr->window); if (masterMacWin) { BringToFront(masterMacWin); } } } } SelectWindow(wRef); } else { frontWindowOnly = 0; } } if (!isFrontProcess) { ProcessSerialNumber ourPsn = {0, kCurrentProcess}; ChkErr(SetFrontProcessWithOptions, &ourPsn, frontWindowOnly ? kSetFrontProcessFrontWindowOnly : 0); } }
static int GenerateButtonEvent(MouseEventData * medPtr) { Tk_Window tkwin; int dummy; TkDisplay *dispPtr; #if UNUSED /* * ButtonDown events will always occur in the front * window. ButtonUp events, however, may occur anywhere * on the screen. ButtonUp events should only be sent * to Tk if in the front window or during an implicit grab. */ if ((medPtr->activeNonFloating == NULL) || ((!(TkpIsWindowFloating(medPtr->whichWin)) && (medPtr->activeNonFloating != medPtr->whichWin)) && TkMacOSXGetCapture() == NULL)) { return false; } #endif dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (tkwin != NULL) { tkwin = Tk_TopCoordsToWindow(tkwin, medPtr->local.h, medPtr->local.v, &dummy, &dummy); } Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state); return true; }
int XGrabPointer( Display *display, Window grab_window, Bool owner_events, unsigned int event_mask, int pointer_mode, int keyboard_mode, Window confine_to, Cursor cursor, Time time) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); display->request++; tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window); tsdPtr->restrictWinPtr = NULL; TkpSetCapture(tsdPtr->grabWinPtr); if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr) != TK_GRAB_IN_TREE) { UpdateCursor(tsdPtr->grabWinPtr); } return GrabSuccess; }
static void GenerateEditEvent( int flag) { XVirtualEvent event; Point where; Tk_Window tkwin; Window window; TkDisplay *dispPtr; if (TkMacHaveAppearance() >= 0x110) { window = TkMacGetXWindow(FrontNonFloatingWindow()); } else { window = TkMacGetXWindow(FrontWindow()); } dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; if (tkwin == NULL) { return; } event.type = VirtualEvent; event.serial = Tk_Display(tkwin)->request; event.send_event = false; event.display = Tk_Display(tkwin); event.event = Tk_WindowId(tkwin); event.root = XRootWindow(Tk_Display(tkwin), 0); event.subwindow = None; event.time = TkpGetMS(); GetMouse(&where); tkwin = Tk_TopCoordsToWindow(tkwin, where.h, where.v, &event.x, &event.y); LocalToGlobal(&where); event.x_root = where.h; event.y_root = where.v; event.state = TkMacButtonKeyState(); event.same_screen = true; switch (flag) { case EDIT_CUT: event.name = Tk_GetUid("Cut"); break; case EDIT_COPY: event.name = Tk_GetUid("Copy"); break; case EDIT_PASTE: event.name = Tk_GetUid("Paste"); break; case EDIT_CLEAR: event.name = Tk_GetUid("Clear"); break; } Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); }
static int GrabWinEventProc( Tcl_Event *evPtr, /* Event of type NewGrabWinEvent. */ int flags) /* Flags argument to Tk_DoOneEvent: indicates * what kinds of events are being processed * right now. */ { NewGrabWinEvent *grabEvPtr = (NewGrabWinEvent *) evPtr; grabEvPtr->dispPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow( grabEvPtr->dispPtr->display, grabEvPtr->grabWindow); return 1; }
void TkMacOSXBringWindowForward( WindowRef wRef) { TkDisplay *dispPtr = TkGetDisplayList(); Tk_Window tkwin = Tk_IdToWindow(dispPtr->display,TkMacOSXGetXWindow(wRef)); Tk_Window grabWin = GetGrabWindowForWindow(tkwin); if (grabWin && grabWin != tkwin) { wRef = TkMacOSXDrawableWindow(((TkWindow*)grabWin)->window); } TkMacOSXSetEatButtonUp(true); BringWindowForward(wRef, Tk_MacOSXIsAppInFront(), !grabWin); }
static int GeneratePollingEvents(MouseEventData * medPtr) { Tk_Window tkwin, rootwin, grabWin; int local_x, local_y; TkDisplay *dispPtr; grabWin = TkMacOSXGetCapture(); if ((!TkpIsWindowFloating(medPtr->whichWin) && (medPtr->activeNonFloating != medPtr->whichWin))) { /* * If the window for this event is not floating, and is not the * active non-floating window, don't generate polling events. * We don't send events to backgrounded windows. So either send * it to the grabWin, or NULL if there is no grabWin. */ tkwin = grabWin; } else { /* * First check whether the toplevel containing this mouse * event is the grab window. If not, then send the event * to the grab window. Otherwise, set tkWin to the subwindow * which most closely contains the mouse event. */ dispPtr = TkGetDisplayList(); rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if ((rootwin == NULL) || ((grabWin != NULL) && (rootwin != grabWin))) { tkwin = grabWin; } else { tkwin = Tk_TopCoordsToWindow(rootwin, medPtr->local.h, medPtr->local.v, &local_x, &local_y); } } /* * The following call will generate the appropiate X events and * adjust any state that Tk must remember. */ Tk_UpdatePointer(tkwin, medPtr->global.h, medPtr->global.v, medPtr->state); return true; }
static void GenerateEditEvent( int flag) { XVirtualEvent event; int x, y; Tk_Window tkwin; Window window; TkDisplay *dispPtr; window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); tkwin = (Tk_Window) ((TkWindow *) tkwin)->dispPtr->focusPtr; if (tkwin == NULL) { return; } bzero(&event, sizeof(XVirtualEvent)); event.type = VirtualEvent; event.serial = Tk_Display(tkwin)->request; event.send_event = false; event.display = Tk_Display(tkwin); event.event = Tk_WindowId(tkwin); event.root = XRootWindow(Tk_Display(tkwin), 0); event.subwindow = None; event.time = TkpGetMS(); XQueryPointer(NULL, None, NULL, NULL, &event.x_root, &event.y_root, &x, &y, &event.state); Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y); event.same_screen = true; switch (flag) { case EDIT_CUT: event.name = Tk_GetUid("Cut"); break; case EDIT_COPY: event.name = Tk_GetUid("Copy"); break; case EDIT_PASTE: event.name = Tk_GetUid("Paste"); break; case EDIT_CLEAR: event.name = Tk_GetUid("Clear"); break; } Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); }
void XDefineCursor( Display *display, Window w, Cursor cursor) { TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w); ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->cursorWinPtr == winPtr) { UpdateCursor(winPtr); } display->request++; }
int TkpChangeFocus( TkWindow *winPtr, /* Window that is to receive the X focus. */ int force) /* Non-zero means claim the focus even if it * didn't originally belong to topLevelPtr's * application. */ { TkDisplay *dispPtr = winPtr->dispPtr; Window focusWindow; int dummy, serial; TkWindow *winPtr2; if (!force) { XGetInputFocus(dispPtr->display, &focusWindow, &dummy); winPtr2 = (TkWindow *) Tk_IdToWindow(dispPtr->display, focusWindow); if ((winPtr2 == NULL) || (winPtr2->mainPtr != winPtr->mainPtr)) { return 0; } } if (winPtr->window == None) { Tcl_Panic("ChangeXFocus got null X window"); } /* * Change the foreground window so the focus window is raised to the top * of the system stacking order and gets the keyboard focus. */ if (force) { TkWinSetForegroundWindow(winPtr); } XSetInputFocus(dispPtr->display, winPtr->window, RevertToParent, CurrentTime); /* * Remember the current serial number for the X server and issue a dummy * server request. This marks the position at which we changed the focus, * so we can distinguish FocusIn and FocusOut events on either side of the * mark. */ serial = NextRequest(winPtr->display); XNoOp(winPtr->display); return serial; }
static int GenerateMouseWheelEvent(MouseEventData * medPtr) { Tk_Window tkwin, rootwin; TkDisplay *dispPtr; TkWindow *winPtr; XEvent xEvent; dispPtr = TkGetDisplayList(); rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (rootwin == NULL) { tkwin = NULL; } else { tkwin = Tk_TopCoordsToWindow(rootwin, medPtr->local.h, medPtr->local.v, &xEvent.xbutton.x, &xEvent.xbutton.y); } /* * The following call will generate the appropiate X events and * adjust any state that Tk must remember. */ if (!tkwin) { tkwin = TkMacOSXGetCapture(); } if (!tkwin) { return false; } winPtr = (TkWindow *) tkwin; xEvent.type = MouseWheelEvent; xEvent.xkey.keycode = medPtr->delta; xEvent.xbutton.x_root = medPtr->global.h; xEvent.xbutton.y_root = medPtr->global.v; xEvent.xbutton.state = medPtr->state; xEvent.xany.serial = LastKnownRequestProcessed(winPtr->display); xEvent.xany.send_event = false; xEvent.xany.display = winPtr->display; xEvent.xany.window = Tk_WindowId(winPtr); Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); return true; }
static int GenerateToolbarButtonEvent( MouseEventData *medPtr) { Tk_Window rootwin, tkwin = NULL; TkDisplay *dispPtr; TkWindow *winPtr; XVirtualEvent event; dispPtr = TkGetDisplayList(); rootwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (rootwin) { tkwin = Tk_TopCoordsToWindow(rootwin, medPtr->local.h, medPtr->local.v, &event.x, &event.y); } if (!tkwin) { return true; } winPtr = (TkWindow *) tkwin; bzero(&event, sizeof(XVirtualEvent)); event.type = VirtualEvent; event.serial = LastKnownRequestProcessed(winPtr->display); event.send_event = false; event.display = winPtr->display; event.event = winPtr->window; event.root = XRootWindow(winPtr->display, 0); event.subwindow = None; event.time = TkpGetMS(); event.x_root = medPtr->global.h; event.y_root = medPtr->global.v; event.state = medPtr->state; event.same_screen = true; event.name = Tk_GetUid("ToolbarButton"); Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); return true; }
int TkpUseWindow( Tcl_Interp *interp, /* If not NULL, used for error reporting * if string is bogus. */ Tk_Window tkwin, /* Tk window that does not yet have an * associated X window. */ CONST char *string) /* String identifying an X window to use * for tkwin; must be an integer value. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *usePtr; MacDrawable *parent, *macWin; Container *containerPtr; XEvent event; int result; if (winPtr->window != None) { panic("TkpUseWindow: X window already assigned"); } /* * Decode the container pointer, and look for it among the *list of available containers. * * N.B. For now, we are limiting the containers to be in the same Tk * application as tkwin, since otherwise they would not be in our list * of containers. * */ if (Tcl_GetInt(interp, string, &result) != TCL_OK) { return TCL_ERROR; } usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, (Window) result); if (usePtr == NULL) { Tcl_AppendResult(interp, "Tk window does not correspond to id \"", string, "\"", (char *) NULL); return TCL_ERROR; } else { if (!(usePtr->flags & TK_CONTAINER)) { Tcl_AppendResult(interp, "window \"", usePtr->pathName, "\" doesn't have -container option set", (char *) NULL); return TCL_ERROR; } } parent = (MacDrawable *) result; /* * Save information about the container and the embedded window * in a Container structure. Currently, there must already be an existing * Container structure, since we only allow the case where both container * and embedded app. are in the same process. */ for (containerPtr = firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { if (containerPtr->parent == (Window) parent) { winPtr->flags |= TK_BOTH_HALVES; containerPtr->parentPtr->flags |= TK_BOTH_HALVES; break; } } /* * Make the embedded window. */ macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable)); if (macWin == NULL) { winPtr->privatePtr = NULL; return TCL_ERROR; } macWin->winPtr = winPtr; winPtr->privatePtr = macWin; /* * The portPtr will be NULL for a Tk in Tk embedded window. * It is none of our business what it is for a Tk not in Tk embedded window, * but we will initialize it to NULL, and let the registerWinProc * set it. In any case, you must always use TkMacGetDrawablePort * to get the portPtr. It will correctly find the container's port. */ macWin->portPtr = (GWorldPtr) NULL; macWin->clipRgn = NewRgn(); macWin->aboveClipRgn = NewRgn(); macWin->referenceCount = 0; macWin->flags = TK_CLIP_INVALID; macWin->toplevel = macWin; macWin->toplevel->referenceCount++; winPtr->flags |= TK_EMBEDDED; /* * Make a copy of the TK_EMBEDDED flag, since sometimes * we need this to get the port after the TkWindow structure * has been freed. */ macWin->flags |= TK_EMBEDDED; /* * Now check whether it is embedded in another Tk widget. If not (the first * case below) we see if there is an in-process embedding handler registered, * and if so, let that fill in the rest of the macWin. */ if (containerPtr == NULL) { /* * If someone has registered an in process embedding handler, then * see if it can handle this window... */ if (gMacEmbedHandler == NULL || gMacEmbedHandler->registerWinProc(result, (Tk_Window) winPtr) != TCL_OK) { Tcl_AppendResult(interp, "The window ID ", string, " does not correspond to a valid Tk Window.", (char *) NULL); return TCL_ERROR; } else { containerPtr = (Container *) ckalloc(sizeof(Container)); containerPtr->parentPtr = NULL; containerPtr->embedded = (Window) macWin; containerPtr->embeddedPtr = macWin->winPtr; containerPtr->nextPtr = firstContainerPtr; firstContainerPtr = containerPtr; } } else { /* * The window is embedded in another Tk window. */ macWin->xOff = parent->winPtr->privatePtr->xOff + parent->winPtr->changes.border_width + winPtr->changes.x; macWin->yOff = parent->winPtr->privatePtr->yOff + parent->winPtr->changes.border_width + winPtr->changes.y; /* * Finish filling up the container structure with the embedded window's * information. */ containerPtr->embedded = (Window) macWin; containerPtr->embeddedPtr = macWin->winPtr; /* * Create an event handler to clean up the Container structure when * tkwin is eventually deleted. */ Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc, (ClientData) winPtr); } /* * TODO: need general solution for visibility events. */ event.xany.serial = Tk_Display(winPtr)->request; event.xany.send_event = False; event.xany.display = Tk_Display(winPtr); event.xvisibility.type = VisibilityNotify; event.xvisibility.window = (Window) macWin;; event.xvisibility.state = VisibilityUnobscured; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); /* * TODO: need general solution for visibility events. */ event.xany.serial = Tk_Display(winPtr)->request; event.xany.send_event = False; event.xany.display = Tk_Display(winPtr); event.xvisibility.type = VisibilityNotify; event.xvisibility.window = (Window) macWin;; event.xvisibility.state = VisibilityUnobscured; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); return TCL_OK; }
void XDestroyWindow( Display *display, /* Display. */ Window window) /* Window. */ { MacDrawable *macWin = (MacDrawable *) window; WindowRef winRef; /* * Remove any dangling pointers that may exist if the window we are * deleting is being tracked by the grab code. */ TkPointerDeadWindow(macWin->winPtr); macWin->toplevel->referenceCount--; if (!Tk_IsTopLevel(macWin->winPtr)) { TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); if (macWin->winPtr->parentPtr != NULL) { TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr); } if (macWin->visRgn) { CFRelease(macWin->visRgn); } if (macWin->aboveVisRgn) { CFRelease(macWin->aboveVisRgn); } if (macWin->toplevel->referenceCount == 0) { ckfree((char *) macWin->toplevel); } ckfree((char *) macWin); return; } /* * We are relying on the Activate Mac OS event to pass the focus away from * a window that is getting Destroyed to the Front non-floating window. BUT * we don't get activate events when a floating window is destroyed, since * the front non-floating window doesn't in fact get activated... So maybe * we can check here and if we are destroying a floating window, we can * pass the focus back to the front non-floating window... */ if (macWin->grafPtr != NULL) { TkWindow *focusPtr = TkGetFocusWin(macWin->winPtr); if (focusPtr == NULL || (focusPtr->mainPtr->winPtr == macWin->winPtr)) { winRef = TkMacOSXDrawableWindow(window); if (TkpIsWindowFloating (winRef)) { Window window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); if (window != None) { TkMacOSXGenerateFocusEvent(window, 1); } } } } if (macWin->visRgn) { CFRelease(macWin->visRgn); } if (macWin->aboveVisRgn) { CFRelease(macWin->aboveVisRgn); } /* * Delete the Mac window and remove it from the windowTable. The window * could be NULL if the window was never mapped. However, we don't do this * for embedded windows, they don't go in the window list, and they do not * own their portPtr's. */ if (!Tk_IsEmbedded(macWin->winPtr)) { WindowRef winRef = TkMacOSXDrawableWindow(window); if (winRef) { TkMacOSXWindowList *listPtr, *prevPtr; WindowGroupRef group; if (GetWindowProperty(winRef, 'Tk ', 'TsGp', sizeof(group), NULL, &group) == noErr) { TkDisplay *dispPtr = TkGetDisplayList(); ItemCount i = CountWindowGroupContents(group, kWindowGroupContentsReturnWindows); WindowRef macWin; WindowGroupRef newGroup; Window window; while (i > 0) { ChkErr(GetIndexedWindow, group, i--, 0, &macWin); if (!macWin) { continue; } window = TkMacOSXGetXWindow(macWin); newGroup = NULL; if (window != None) { TkWindow *winPtr = (TkWindow *) Tk_IdToWindow(dispPtr->display, window); if (winPtr && winPtr->wmInfoPtr) { newGroup = GetWindowGroupOfClass( winPtr->wmInfoPtr->macClass); } } if (!newGroup) { newGroup = GetWindowGroupOfClass(kDocumentWindowClass); } ChkErr(SetWindowGroup, macWin, newGroup); } ChkErr(SetWindowGroupOwner, group, NULL); ChkErr(ReleaseWindowGroup, group); } TkMacOSXUnregisterMacWindow(winRef); DisposeWindow(winRef); for (listPtr=tkMacOSXWindowListPtr, prevPtr=NULL; tkMacOSXWindowListPtr != NULL; prevPtr=listPtr, listPtr=listPtr->nextPtr) { if (listPtr->winPtr == macWin->winPtr) { if (prevPtr == NULL) { tkMacOSXWindowListPtr = listPtr->nextPtr; } else { prevPtr->nextPtr = listPtr->nextPtr; } ckfree((char *) listPtr); break; } } } } macWin->grafPtr = NULL; /* * Delay deletion of a toplevel data structure untill all children have * been deleted. */ if (macWin->toplevel->referenceCount == 0) { ckfree((char *) macWin->toplevel); } }
MODULE_SCOPE int TkMacOSXProcessMouseEvent(TkMacOSXEvent *eventPtr, MacEventStatus * statusPtr) { Tk_Window tkwin; Point where, where2; int result; TkDisplay * dispPtr; OSStatus err; MouseEventData mouseEventData, * medPtr = &mouseEventData; int isFrontProcess; switch (eventPtr->eKind) { case kEventMouseDown: case kEventMouseUp: case kEventMouseMoved: case kEventMouseDragged: case kEventMouseWheelMoved: break; default: return false; break; } err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(where), NULL, &where); if (err != noErr) { GetGlobalMouse(&where); } err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowRef, typeWindowRef, NULL, sizeof(WindowRef), NULL, &medPtr->whichWin); if (err == noErr) { err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowPartCode, typeWindowPartCode, NULL, sizeof(WindowPartCode), NULL, &medPtr->windowPart); } if (err != noErr) { medPtr->windowPart = FindWindow(where, &medPtr->whichWin); } medPtr->window = TkMacOSXGetXWindow(medPtr->whichWin); if (medPtr->whichWin != NULL && medPtr->window == None) { return false; } if (eventPtr->eKind == kEventMouseDown) { if (IsWindowActive(medPtr->whichWin) && IsWindowPathSelectEvent( medPtr->whichWin, eventPtr->eventRef)) { ChkErr(WindowPathSelect, medPtr->whichWin, NULL, NULL); return false; } if (medPtr->windowPart == inProxyIcon) { TkMacOSXTrackingLoop(1); err = ChkErr(TrackWindowProxyDrag, medPtr->whichWin, where); TkMacOSXTrackingLoop(0); if (err == errUserWantsToDragWindow) { medPtr->windowPart = inDrag; } else { return false; } } } isFrontProcess = Tk_MacOSXIsAppInFront(); if (isFrontProcess) { medPtr->state = ButtonModifiers2State(GetCurrentEventButtonState(), GetCurrentEventKeyModifiers()); } else { medPtr->state = ButtonModifiers2State(GetCurrentButtonState(), GetCurrentKeyModifiers()); } medPtr->global = where; err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamWindowMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &medPtr->local); if (err == noErr) { if (medPtr->whichWin) { Rect widths; GetWindowStructureWidths(medPtr->whichWin, &widths); medPtr->local.h -= widths.left; medPtr->local.v -= widths.top; } } else { medPtr->local = where; if (medPtr->whichWin) { QDGlobalToLocalPoint(GetWindowPort(medPtr->whichWin), &medPtr->local); } } medPtr->activeNonFloating = ActiveNonFloatingWindow(); dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, medPtr->window); if (eventPtr->eKind != kEventMouseDown) { int res = false; switch (eventPtr->eKind) { case kEventMouseUp: /* * The window manager only needs to know about mouse down * events and sometimes we need to "eat" the mouse up. * Otherwise, we just pass the event to Tk. */ if (TkMacOSXGetEatButtonUp()) { TkMacOSXSetEatButtonUp(false); } else { res = GenerateButtonEvent(medPtr); } break; case kEventMouseWheelMoved: err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &medPtr->delta); if (err != noErr ) { statusPtr->err = 1; } else { EventMouseWheelAxis axis; err = ChkErr(GetEventParameter, eventPtr->eventRef, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis); if (err == noErr && axis == kEventMouseWheelAxisX) { medPtr->state |= ShiftMask; } res = GenerateMouseWheelEvent(medPtr); } break; case kEventMouseMoved: case kEventMouseDragged: res = GeneratePollingEvents(medPtr); break; default: Tcl_Panic("Unknown mouse event !"); } if (res) { statusPtr->stopProcessing = 1; } return res; } TkMacOSXSetEatButtonUp(false); if (medPtr->whichWin) { /* * We got a mouse down in a window * See if this is the activate click * This click moves the window forward. We don't want * the corresponding mouse-up to be reported to the application * or else it will mess up some Tk scripts. */ if (!(TkpIsWindowFloating(medPtr->whichWin)) && (medPtr->whichWin != medPtr->activeNonFloating || !isFrontProcess)) { int frontWindowOnly = 1; int cmdDragGrow = ((medPtr->windowPart == inDrag || medPtr->windowPart == inGrow) && medPtr->state & Mod1Mask); if (!cmdDragGrow) { Tk_Window grabWin = GetGrabWindowForWindow(tkwin); frontWindowOnly = !grabWin; if (grabWin && grabWin != tkwin) { TkMacOSXSetEatButtonUp(true); BringWindowForward(TkMacOSXDrawableWindow( ((TkWindow*)grabWin)->window), isFrontProcess, frontWindowOnly); return false; } } /* * Clicks in the titlebar widgets are handled without bringing the * window forward. */ if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { statusPtr->stopProcessing = 1; return result; } else { /* * Only windows with the kWindowNoActivatesAttribute can * receive mouse events in the background. */ if (!(((TkWindow *)tkwin)->wmInfoPtr->attributes & kWindowNoActivatesAttribute)) { /* * Allow background window dragging & growing with Command * down. */ if (!cmdDragGrow) { TkMacOSXSetEatButtonUp(true); BringWindowForward(medPtr->whichWin, isFrontProcess, frontWindowOnly); } /* * Allow dragging & growing of windows that were/are in the * background. */ if (!(medPtr->windowPart == inDrag || medPtr->windowPart == inGrow)) { return false; } } } } else { if ((result = HandleWindowTitlebarMouseDown(medPtr, tkwin)) != -1) { statusPtr->stopProcessing = 1; return result; } } switch (medPtr->windowPart) { case inDrag: { WindowAttributes attributes; GetWindowAttributes(medPtr->whichWin, &attributes); if (!(attributes & kWindowAsyncDragAttribute)) { TkMacOSXTrackingLoop(1); DragWindow(medPtr->whichWin, where, NULL); TkMacOSXTrackingLoop(0); where2.h = where2.v = 0; QDLocalToGlobalPoint(GetWindowPort(medPtr->whichWin), &where2); if (EqualPt(where, where2)) { return false; } return true; } break; } case inGrow: /* * Generally the content region is the domain of Tk * sub-windows. However, one exception is the grow * region. A button down in this area will be handled * by the window manager. Note: this means that Tk * may not get button down events in this area! */ if (TkMacOSXGrowToplevel(medPtr->whichWin, where) == true) { statusPtr->stopProcessing = 1; return true; } else { return GenerateButtonEvent(medPtr); } break; case inContent: return GenerateButtonEvent(medPtr); break; default: return false; break; } } return false; }
void TkMacOSXHandleMenuSelect( MenuID theMenu, MenuItemIndex theItem, int optionKeyPressed) { Tk_Window tkwin; Window window; TkDisplay *dispPtr; Tcl_CmdInfo dummy; int code; if (theItem == 0) { TkMacOSXClearMenubarActive(); return; } switch (theMenu) { case kAppleMenu: switch (theItem) { case kAppleAboutItem: if (optionKeyPressed || gInterp == NULL || Tcl_GetCommandInfo(gInterp, "tkAboutDialog", &dummy) == 0) { TkAboutDlg(); } else { code = Tcl_EvalEx(gInterp, "tkAboutDialog", -1, TCL_EVAL_GLOBAL); if (code != TCL_OK) { Tcl_BackgroundException(gInterp, code); } Tcl_ResetResult(gInterp); } break; } break; case kFileMenu: switch (theItem) { case kSourceItem: if (gInterp) { if (Tcl_EvalEx(gInterp, "tk_getOpenFile -filetypes {" "{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}", -1, TCL_EVAL_GLOBAL) == TCL_OK) { Tcl_Obj *path = Tcl_GetObjResult(gInterp); int len; Tcl_GetStringFromObj(path, &len); if (len) { Tcl_IncrRefCount(path); code = Tcl_FSEvalFile(gInterp, path); if (code != TCL_OK) { Tcl_BackgroundException(gInterp, code); } Tcl_DecrRefCount(path); } } Tcl_ResetResult(gInterp); } break; case kDemoItem: if (gInterp) { Tcl_Obj *path = GetWidgetDemoPath(gInterp); if (path) { Tcl_IncrRefCount(path); code = Tcl_FSEvalFile(gInterp, path); if (code != TCL_OK) { Tcl_BackgroundException(gInterp, code); } Tcl_DecrRefCount(path); Tcl_ResetResult(gInterp); } } break; case kCloseItem: /* Send close event */ window = TkMacOSXGetXWindow(ActiveNonFloatingWindow()); dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); TkGenWMDestroyEvent(tkwin); break; } break; case kEditMenu: /* * This implementation just send the keysyms Tk thinks are associated * with function keys that do Cut, Copy & Paste on a Sun keyboard. */ GenerateEditEvent(theItem); break; default: TkMacOSXDispatchMenuEvent(theMenu, theItem); break; } /* * Finally we unhighlight the menu. */ HiliteMenu(0); }
void TkMacHandleMenuSelect( long mResult, int optionKeyPressed) { short theItem = LoWord(mResult); short theMenu = HiWord(mResult); Str255 name; Tk_Window tkwin; Window window; TkDisplay *dispPtr; if (mResult == 0) { TkMacHandleTearoffMenu(); TkMacClearMenubarActive(); return; } switch (theMenu) { case kAppleMenu: switch (theItem) { case kAppleAboutItem: { Tcl_CmdInfo dummy; if (optionKeyPressed || gInterp == NULL || Tcl_GetCommandInfo(gInterp, "tkAboutDialog", &dummy) == 0) { TkAboutDlg(); } else { Tcl_Eval(gInterp, "tkAboutDialog"); } break; } default: GetMenuItemText(tkAppleMenu, theItem, name); HiliteMenu(0); OpenDeskAcc(name); return; } break; case kFileMenu: switch (theItem) { case kSourceItem: /* TODO: source script */ SourceDialog(); break; case kCloseItem: /* Send close event */ if (TkMacHaveAppearance() >= 0x110) { window = TkMacGetXWindow(FrontNonFloatingWindow()); } else { window = TkMacGetXWindow(FrontWindow()); } dispPtr = TkGetDisplayList(); tkwin = Tk_IdToWindow(dispPtr->display, window); TkGenWMDestroyEvent(tkwin); break; case kQuitItem: /* Exit */ if (optionKeyPressed || gInterp == NULL) { Tcl_Exit(0); } else { Tcl_Eval(gInterp, "exit"); } break; } break; case kEditMenu: /* * This implementation just send keysyms * the Tk thinks are associated with function keys that * do Cut, Copy & Paste on a Sun keyboard. */ GenerateEditEvent(theItem); break; default: TkMacDispatchMenuEvent(theMenu, theItem); TkMacClearMenubarActive(); break; } /* * Finally we unhighlight the menu. */ HiliteMenu(0); } /* TkMacHandleMenuSelect */
int TkpUseWindow( Tcl_Interp *interp, /* If not NULL, used for error reporting if * string is bogus. */ Tk_Window tkwin, /* Tk window that does not yet have an * associated X window. */ const char *string) /* String identifying an X window to use for * tkwin; must be an integer value. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *usePtr; int id, anyError; Window parent; Tk_ErrorHandler handler; Container *containerPtr; XWindowAttributes parentAtts; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->window != None) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't modify container after widget is created", -1)); Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, string, &id) != TCL_OK) { return TCL_ERROR; } parent = (Window) id; usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, parent); if (usePtr != NULL && !(usePtr->flags & TK_CONTAINER)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "window \"%s\" doesn't have -container option set", usePtr->pathName)); Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL); return TCL_ERROR; } /* * Tk sets the window colormap to the screen default colormap in * tkWindow.c:AllocWindow. This doesn't work well for embedded windows. So * we override the colormap and visual settings to be the same as the * parent window (which is in the container app). */ anyError = 0; handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, EmbedErrorProc, &anyError); if (!XGetWindowAttributes(winPtr->display, parent, &parentAtts)) { anyError = 1; } XSync(winPtr->display, False); Tk_DeleteErrorHandler(handler); if (anyError) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't create child of window \"%s\"", string)); Tcl_SetErrorCode(interp, "TK", "EMBED", "NO_TARGET", NULL); } return TCL_ERROR; } Tk_SetWindowVisual(tkwin, parentAtts.visual, parentAtts.depth, parentAtts.colormap); /* * Create an event handler to clean up the Container structure when tkwin * is eventually deleted. */ Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc, winPtr); /* * Save information about the container and the embedded window in a * Container structure. If there is already an existing Container * structure, it means that both container and embedded app. are in the * same process. */ for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { if (containerPtr->parent == parent) { winPtr->flags |= TK_BOTH_HALVES; containerPtr->parentPtr->flags |= TK_BOTH_HALVES; break; } } if (containerPtr == NULL) { containerPtr = ckalloc(sizeof(Container)); containerPtr->parent = parent; containerPtr->parentRoot = parentAtts.root; containerPtr->parentPtr = NULL; containerPtr->wrapper = None; containerPtr->nextPtr = tsdPtr->firstContainerPtr; tsdPtr->firstContainerPtr = containerPtr; } containerPtr->embeddedPtr = winPtr; winPtr->flags |= TK_EMBEDDED; return TCL_OK; }
global.y = tkMacOSXZeroScreenHeight - global.y; } else { /* local will be in screen coordinates. */ if (_windowWithMouse ) { win = _windowWithMouse; global = local; local = [nswindow convertPointFromScreen: local]; local.y = [win frame].size.height - local.y; global.y = tkMacOSXZeroScreenHeight - global.y; } else { /* We have no window. Use the screen???*/ local.y = tkMacOSXZeroScreenHeight - local.y; global = local; } } Window window = TkMacOSXGetXWindow(win); Tk_Window tkwin = window ? Tk_IdToWindow(TkGetDisplayList()->display, window) : NULL; if (!tkwin) { tkwin = TkMacOSXGetCapture(); } if (!tkwin) { return theEvent; /* Give up. No window for this event. */ } TkWindow *winPtr = (TkWindow *) tkwin; local.x -= winPtr->wmInfoPtr->xInParent; local.y -= winPtr->wmInfoPtr->yInParent; int win_x, win_y; tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y);
int TkpUseWindow( Tcl_Interp *interp, /* If not NULL, used for error reporting if * string is bogus. */ Tk_Window tkwin, /* Tk window that does not yet have an * associated X window. */ const char *string) /* String identifying an X window to use for * tkwin; must be an integer value. */ { TkWindow *winPtr = (TkWindow *) tkwin; TkWindow *usePtr; MacDrawable *parent, *macWin; Container *containerPtr; if (winPtr->window != None) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't modify container after widget is created", -1)); Tcl_SetErrorCode(interp, "TK", "EMBED", "POST_CREATE", NULL); return TCL_ERROR; } /* * Decode the container window ID, and look for it among the list of * available containers. * * N.B. For now, we are limiting the containers to be in the same Tk * application as tkwin, since otherwise they would not be in our list of * containers. */ if (TkpScanWindowId(interp, string, (Window *)&parent) != TCL_OK) { return TCL_ERROR; } usePtr = (TkWindow *) Tk_IdToWindow(winPtr->display, (Window) parent); if (usePtr != NULL && !(usePtr->flags & TK_CONTAINER)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "window \"%s\" doesn't have -container option set", usePtr->pathName)); Tcl_SetErrorCode(interp, "TK", "EMBED", "CONTAINER", NULL); return TCL_ERROR; } /* * The code below can probably be simplified given we have already * discovered 'usePtr' above. */ /* * Save information about the container and the embedded window in a * Container structure. Currently, there must already be an existing * Container structure, since we only allow the case where both container * and embedded app. are in the same process. */ for (containerPtr = firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { if (containerPtr->parent == (Window) parent) { winPtr->flags |= TK_BOTH_HALVES; containerPtr->parentPtr->flags |= TK_BOTH_HALVES; break; } } /* * Make the embedded window. */ macWin = ckalloc(sizeof(MacDrawable)); if (macWin == NULL) { winPtr->privatePtr = NULL; return TCL_ERROR; } macWin->winPtr = winPtr; winPtr->privatePtr = macWin; /* * The grafPtr will be NULL for a Tk in Tk embedded window. It is none of * our business what it is for a Tk not in Tk embedded window, but we will * initialize it to NULL, and let the registerWinProc set it. In any case, * you must always use TkMacOSXGetDrawablePort to get the portPtr. It will * correctly find the container's port. */ macWin->view = nil; macWin->context = NULL; macWin->size = CGSizeZero; macWin->visRgn = NULL; macWin->aboveVisRgn = NULL; macWin->drawRgn = NULL; macWin->referenceCount = 0; macWin->flags = TK_CLIP_INVALID; macWin->toplevel = macWin; macWin->toplevel->referenceCount++; winPtr->flags |= TK_EMBEDDED; /* * Make a copy of the TK_EMBEDDED flag, since sometimes we need this to * get the port after the TkWindow structure has been freed. */ macWin->flags |= TK_EMBEDDED; /* * Now check whether it is embedded in another Tk widget. If not (the * first case below) we see if there is an in-process embedding handler * registered, and if so, let that fill in the rest of the macWin. */ if (containerPtr == NULL) { /* * If someone has registered an in-process embedding handler, then * see if it can handle this window... */ if (tkMacOSXEmbedHandler == NULL || tkMacOSXEmbedHandler->registerWinProc((long) parent, (Tk_Window) winPtr) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "The window ID %s does not correspond to a valid Tk Window", string)); Tcl_SetErrorCode(interp, "TK", "EMBED", "HANDLE", NULL); return TCL_ERROR; } containerPtr = ckalloc(sizeof(Container)); containerPtr->parentPtr = NULL; containerPtr->embedded = (Window) macWin; containerPtr->embeddedPtr = macWin->winPtr; containerPtr->nextPtr = firstContainerPtr; firstContainerPtr = containerPtr; } else { /* * The window is embedded in another Tk window. */ macWin->xOff = parent->winPtr->privatePtr->xOff + parent->winPtr->changes.border_width + winPtr->changes.x; macWin->yOff = parent->winPtr->privatePtr->yOff + parent->winPtr->changes.border_width + winPtr->changes.y; /* * Finish filling up the container structure with the embedded * window's information. */ containerPtr->embedded = (Window) macWin; containerPtr->embeddedPtr = macWin->winPtr; /* * Create an event handler to clean up the Container structure when * tkwin is eventually deleted. */ Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbeddedEventProc, winPtr); } return TCL_OK; }
KeySym TkpGetKeySym( TkDisplay *dispPtr, /* Display in which to map keycode. */ XEvent *eventPtr) /* Description of X event. */ { KeySym sym; int index; TkKeyEvent* kePtr = (TkKeyEvent*) eventPtr; #ifdef TK_USE_INPUT_METHODS /* * If input methods are active, we may already have determined a keysym. * Return it. */ if (eventPtr->type == KeyPress && dispPtr && (dispPtr->flags & TK_DISPLAY_USE_IM)) { if (kePtr->charValuePtr == NULL) { Tcl_DString ds; TkWindow *winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, eventPtr->xany.window); Tcl_DStringInit(&ds); (void) TkpGetString(winPtr, eventPtr, &ds); Tcl_DStringFree(&ds); } if (kePtr->charValuePtr != NULL) { return kePtr->keysym; } } #endif /* * Refresh the mapping information if it's stale */ if (dispPtr->bindInfoStale) { TkpInitKeymapInfo(dispPtr); } /* * Figure out which of the four slots in the keymap vector to use for this * key. Refer to Xlib documentation for more info on how this computation * works. */ index = 0; if (eventPtr->xkey.state & dispPtr->modeModMask) { index = 2; } if ((eventPtr->xkey.state & ShiftMask) || ((dispPtr->lockUsage != LU_IGNORE) && (eventPtr->xkey.state & LockMask))) { index += 1; } sym = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, 0, index); /* * Special handling: if the key was shifted because of Lock, but lock is * only caps lock, not shift lock, and the shifted keysym isn't upper-case * alphabetic, then switch back to the unshifted keysym. */ if ((index & 1) && !(eventPtr->xkey.state & ShiftMask) && (dispPtr->lockUsage == LU_CAPS)) { if (!(((sym >= XK_A) && (sym <= XK_Z)) || ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) || ((sym >= XK_Ooblique) && (sym <= XK_Thorn)))) { index &= ~1; sym = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, 0, index); } } /* * Another bit of special handling: if this is a shifted key and there is * no keysym defined, then use the keysym for the unshifted key. */ if ((index & 1) && (sym == NoSymbol)) { sym = XkbKeycodeToKeysym(dispPtr->display, eventPtr->xkey.keycode, 0, index & ~1); } return sym; }