📄 tkmacembed.c
字号:
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;}/* *---------------------------------------------------------------------- * * TkpMakeContainer -- * * This procedure is called to indicate that a particular window * will be a container for an embedded application. This changes * certain aspects of the window's behavior, such as whether it * will receive events anymore. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */voidTkpMakeContainer( Tk_Window tkwin) /* Token for a window that is about to * become a container. */{ TkWindow *winPtr = (TkWindow *) tkwin; Container *containerPtr; /* * Register the window as a container so that, for example, we can * make sure the argument to -use is valid. */ Tk_MakeWindowExist(tkwin); containerPtr = (Container *) ckalloc(sizeof(Container)); containerPtr->parent = Tk_WindowId(tkwin); containerPtr->parentPtr = winPtr; containerPtr->embedded = None; containerPtr->embeddedPtr = NULL; containerPtr->nextPtr = firstContainerPtr; firstContainerPtr = containerPtr; winPtr->flags |= TK_CONTAINER; /* * Request SubstructureNotify events so that we can find out when * the embedded application creates its window or attempts to * resize it. Also watch Configure events on the container so that * we can resize the child to match. Also, pass activate events from * the container down to the embedded toplevel. */ Tk_CreateEventHandler(tkwin, SubstructureNotifyMask|SubstructureRedirectMask, ContainerEventProc, (ClientData) winPtr); Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc, (ClientData) containerPtr); Tk_CreateEventHandler(tkwin, ActivateMask, EmbedActivateProc, (ClientData) containerPtr); Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc, (ClientData) containerPtr); }/* *---------------------------------------------------------------------- * * TkMacContainerId -- * * Given an embedded window, this procedure returns the MacDrawable * identifier for the associated container window. * * Results: * The return value is the MacDrawable for winPtr's * container window. * * Side effects: * None. * *---------------------------------------------------------------------- */MacDrawable *TkMacContainerId(winPtr) TkWindow *winPtr; /* Tk's structure for an embedded window. */{ Container *containerPtr; for (containerPtr = firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { if (containerPtr->embeddedPtr == winPtr) { return (MacDrawable *) containerPtr->parent; } } panic("TkMacContainerId couldn't find window"); return None;}/* *---------------------------------------------------------------------- * * TkMacGetHostToplevel -- * * Given the TkWindow, return the MacDrawable for the outermost * toplevel containing it. This will be a real Macintosh window. * * Results: * Returns a MacDrawable corresponding to a Macintosh Toplevel * * Side effects: * None. * *---------------------------------------------------------------------- */MacDrawable *TkMacGetHostToplevel( TkWindow *winPtr) /* Tk's structure for a window. */{ TkWindow *contWinPtr, *topWinPtr; topWinPtr = winPtr->privatePtr->toplevel->winPtr; if (!Tk_IsEmbedded(topWinPtr)) { return winPtr->privatePtr->toplevel; } else { contWinPtr = TkpGetOtherWindow(topWinPtr); /* * NOTE: Here we should handle out of process embedding. */ if (contWinPtr != NULL) { return TkMacGetHostToplevel(contWinPtr); } else { return None; } }}/* *---------------------------------------------------------------------- * * TkpClaimFocus -- * * This procedure is invoked when someone asks for the input focus * to be put on a window in an embedded application, but the * application doesn't currently have the focus. It requests the * input focus from the container application. * * Results: * None. * * Side effects: * The input focus may change. * *---------------------------------------------------------------------- */voidTkpClaimFocus( TkWindow *topLevelPtr, /* Top-level window containing desired * focus window; should be embedded. */ int force) /* One means that the container should * claim the focus if it doesn't * currently have it. */{ XEvent event; Container *containerPtr; if (!(topLevelPtr->flags & TK_EMBEDDED)) { return; } for (containerPtr = firstContainerPtr; containerPtr->embeddedPtr != topLevelPtr; containerPtr = containerPtr->nextPtr) { /* Empty loop body. */ } event.xfocus.type = FocusIn; event.xfocus.serial = LastKnownRequestProcessed(topLevelPtr->display); event.xfocus.send_event = 1; event.xfocus.display = topLevelPtr->display; event.xfocus.window = containerPtr->parent; event.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS; event.xfocus.detail = force; Tk_QueueWindowEvent(&event,TCL_QUEUE_TAIL);}/* *---------------------------------------------------------------------- * * TkpTestembedCmd -- * * This procedure implements the "testembed" command. It returns * some or all of the information in the list pointed to by * firstContainerPtr. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */intTkpTestembedCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ char **argv) /* Argument strings. */{ int all; Container *containerPtr; Tcl_DString dString; char buffer[50]; if ((argc > 1) && (strcmp(argv[1], "all") == 0)) { all = 1; } else { all = 0; } Tcl_DStringInit(&dString); for (containerPtr = firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { Tcl_DStringStartSublist(&dString); if (containerPtr->parent == None) { Tcl_DStringAppendElement(&dString, ""); } else { if (all) { sprintf(buffer, "0x%x", (int) containerPtr->parent); Tcl_DStringAppendElement(&dString, buffer); } else { Tcl_DStringAppendElement(&dString, "XXX"); } } if (containerPtr->parentPtr == NULL) { Tcl_DStringAppendElement(&dString, ""); } else { Tcl_DStringAppendElement(&dString, containerPtr->parentPtr->pathName); } if (containerPtr->embedded == None) { Tcl_DStringAppendElement(&dString, ""); } else { if (all) { sprintf(buffer, "0x%x", (int) containerPtr->embedded); Tcl_DStringAppendElement(&dString, buffer); } else { Tcl_DStringAppendElement(&dString, "XXX"); } } if (containerPtr->embeddedPtr == NULL) { Tcl_DStringAppendElement(&dString, ""); } else { Tcl_DStringAppendElement(&dString, containerPtr->embeddedPtr->pathName); } Tcl_DStringEndSublist(&dString); } Tcl_DStringResult(interp, &dString); return TCL_OK;}/* *---------------------------------------------------------------------- * * TkpRedirectKeyEvent -- * * This procedure is invoked when a key press or release event * arrives for an application that does not believe it owns the * input focus. This can happen because of embedding; for example, * X can send an event to an embedded application when the real * focus window is in the container application and is an ancestor * of the container. This procedure's job is to forward the event * back to the application where it really belongs. * * Results: * None. * * Side effects: * The event may get sent to a different application. * *---------------------------------------------------------------------- */voidTkpRedirectKeyEvent( TkWindow *winPtr, /* Window to which the event was originally * reported. */ XEvent *eventPtr) /* X event to redirect (should be KeyPress * or KeyRelease). */{}/* *---------------------------------------------------------------------- * * TkpGetOtherWindow -- * * If both the container and embedded window are in the same * process, this procedure will return either one, given the other. * * Results: * If winPtr is a container, the return value is the token for the * embedded window, and vice versa. If the "other" window isn't in * this process, NULL is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */TkWindow *TkpGetOtherWindow( TkWindow *winPtr) /* Tk's structure for a container or * embedded window. */{ Container *containerPtr; /* * TkpGetOtherWindow returns NULL if both windows are not * in the same process... */ if (!(winPtr->flags & TK_BOTH_HALVES)) { return NULL; } for (containerPtr = firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { if (containerPtr->embeddedPtr == winPtr) { return containerPtr->parentPtr; } else if (containerPtr->parentPtr == winPtr) { return containerPtr->embeddedPtr; } } return NULL;}/* *---------------------------------------------------------------------- * * EmbeddedEventProc -- * * This procedure is invoked by the Tk event dispatcher when various * useful events are received for a window that is embedded in * another application. * * Results: * None. * * Side effects: * Our internal state gets cleaned up when an embedded window is * destroyed. * *---------------------------------------------------------------------- */static voidEmbeddedEventProc(clientData, eventPtr) ClientData clientData; /* Token for container window. */ XEvent *eventPtr; /* ResizeRequest event. */{ TkWindow *winPtr = (TkWindow *) clientData; if (eventPtr->type == DestroyNotify) { EmbedWindowDeleted(winPtr); }}/* *---------------------------------------------------------------------- * * ContainerEventProc -- * * This procedure is invoked by the Tk event dispatcher when various * useful events are received for the children of a container * window. It forwards relevant information, such as geometry * requests, from the events into the container's application. * * NOTE: on the Mac, only the DestroyNotify branch is ever taken. * We don't synthesize the other events. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -