📄 tkmacembed.c
字号:
* Results: * None. * * Side effects: * Depends on the event. For example, when ConfigureRequest events * occur, geometry information gets set for the container window. * *---------------------------------------------------------------------- */static voidContainerEventProc(clientData, eventPtr) ClientData clientData; /* Token for container window. */ XEvent *eventPtr; /* ResizeRequest event. */{ TkWindow *winPtr = (TkWindow *) clientData; Container *containerPtr; Tk_ErrorHandler errHandler; /* * Ignore any X protocol errors that happen in this procedure * (almost any operation could fail, for example, if the embedded * application has deleted its window). */ errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); /* * Find the Container structure associated with the parent window. */ for (containerPtr = firstContainerPtr; containerPtr->parent != eventPtr->xmaprequest.parent; containerPtr = containerPtr->nextPtr) { if (containerPtr == NULL) { panic("ContainerEventProc couldn't find Container record"); } } if (eventPtr->type == CreateNotify) { /* * A new child window has been created in the container. Record * its id in the Container structure (if more than one child is * created, just remember the last one and ignore the earlier * ones). */ containerPtr->embedded = eventPtr->xcreatewindow.window; } else if (eventPtr->type == ConfigureRequest) { if ((eventPtr->xconfigurerequest.x != 0) || (eventPtr->xconfigurerequest.y != 0)) { /* * The embedded application is trying to move itself, which * isn't legal. At this point, the window hasn't actually * moved, but we need to send it a ConfigureNotify event to * let it know that its request has been denied. If the * embedded application was also trying to resize itself, a * ConfigureNotify will be sent by the geometry management * code below, so we don't need to do anything. Otherwise, * generate a synthetic event. */ if ((eventPtr->xconfigurerequest.width == winPtr->changes.width) && (eventPtr->xconfigurerequest.height == winPtr->changes.height)) { EmbedSendConfigure(containerPtr); } } EmbedGeometryRequest(containerPtr, eventPtr->xconfigurerequest.width, eventPtr->xconfigurerequest.height); } else if (eventPtr->type == MapRequest) { /* * The embedded application's map request was ignored and simply * passed on to us, so we have to map the window for it to appear * on the screen. */ XMapWindow(eventPtr->xmaprequest.display, eventPtr->xmaprequest.window); } else if (eventPtr->type == DestroyNotify) { /* * The embedded application is gone. Destroy the container window. */ Tk_DestroyWindow((Tk_Window) winPtr); } Tk_DeleteErrorHandler(errHandler);}/* *---------------------------------------------------------------------- * * EmbedStructureProc -- * * This procedure is invoked by the Tk event dispatcher when * a container window owned by this application gets resized * (and also at several other times that we don't care about). * This procedure reflects the size change in the embedded * window that corresponds to the container. * * Results: * None. * * Side effects: * The embedded window gets resized to match the container. * *---------------------------------------------------------------------- */static voidEmbedStructureProc(clientData, eventPtr) ClientData clientData; /* Token for container window. */ XEvent *eventPtr; /* ResizeRequest event. */{ Container *containerPtr = (Container *) clientData; Tk_ErrorHandler errHandler; if (eventPtr->type == ConfigureNotify) { if (containerPtr->embedded != None) { /* * Ignore errors, since the embedded application could have * deleted its window. */ errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); Tk_MoveResizeWindow((Tk_Window) containerPtr->embeddedPtr, 0, 0, (unsigned int) Tk_Width( (Tk_Window) containerPtr->parentPtr), (unsigned int) Tk_Height( (Tk_Window) containerPtr->parentPtr)); Tk_DeleteErrorHandler(errHandler); } } else if (eventPtr->type == DestroyNotify) { EmbedWindowDeleted(containerPtr->parentPtr); }}/* *---------------------------------------------------------------------- * * EmbedActivateProc -- * * This procedure is invoked by the Tk event dispatcher when * Activate and Deactivate events occur for a container window owned * by this application. It is responsible for forwarding an activate * event down into the embedded toplevel. * * Results: * None. * * Side effects: * The X focus may change. * *---------------------------------------------------------------------- */static voidEmbedActivateProc(clientData, eventPtr) ClientData clientData; /* Token for container window. */ XEvent *eventPtr; /* ResizeRequest event. */{ Container *containerPtr = (Container *) clientData; if (containerPtr->embeddedPtr != NULL) { if (eventPtr->type == ActivateNotify) { TkGenerateActivateEvents(containerPtr->embeddedPtr,1); } else if (eventPtr->type == DeactivateNotify) { TkGenerateActivateEvents(containerPtr->embeddedPtr,0); } }}/* *---------------------------------------------------------------------- * * EmbedFocusProc -- * * This procedure is invoked by the Tk event dispatcher when * FocusIn and FocusOut events occur for a container window owned * by this application. It is responsible for moving the focus * back and forth between a container application and an embedded * application. * * Results: * None. * * Side effects: * The X focus may change. * *---------------------------------------------------------------------- */static voidEmbedFocusProc(clientData, eventPtr) ClientData clientData; /* Token for container window. */ XEvent *eventPtr; /* ResizeRequest event. */{ Container *containerPtr = (Container *) clientData; Display *display; XEvent event; if (containerPtr->embeddedPtr != NULL) { display = Tk_Display(containerPtr->parentPtr); event.xfocus.serial = LastKnownRequestProcessed(display); event.xfocus.send_event = false; event.xfocus.display = display; event.xfocus.mode = NotifyNormal; event.xfocus.window = containerPtr->embedded; if (eventPtr->type == FocusIn) { /* * The focus just arrived at the container. Change the X focus * to move it to the embedded application, if there is one. * Ignore X errors that occur during this operation (it's * possible that the new focus window isn't mapped). */ event.xfocus.detail = NotifyNonlinear; event.xfocus.type = FocusIn; } else if (eventPtr->type == FocusOut) { /* When the container gets a FocusOut event, it has to tell the embedded app * that it has lost the focus. */ event.xfocus.type = FocusOut; event.xfocus.detail = NotifyNonlinear; } Tk_QueueWindowEvent(&event, TCL_QUEUE_MARK); } }/* *---------------------------------------------------------------------- * * EmbedGeometryRequest -- * * This procedure is invoked when an embedded application requests * a particular size. It processes the request (which may or may * not actually honor the request) and reflects the results back * to the embedded application. * * NOTE: On the Mac, this is a stub, since we don't synthesize * ConfigureRequest events. * * Results: * None. * * Side effects: * If we deny the child's size change request, a Configure event * is synthesized to let the child know how big it ought to be. * Events get processed while we're waiting for the geometry * managers to do their thing. * *---------------------------------------------------------------------- */static voidEmbedGeometryRequest(containerPtr, width, height) Container *containerPtr; /* Information about the embedding. */ int width, height; /* Size that the child has requested. */{ TkWindow *winPtr = containerPtr->parentPtr; /* * Forward the requested size into our geometry management hierarchy * via the container window. We need to send a Configure event back * to the embedded application if we decide not to honor its * request; to make this happen, process all idle event handlers * synchronously here (so that the geometry managers have had a * chance to do whatever they want to do), and if the window's size * didn't change then generate a configure event. */ Tk_GeometryRequest((Tk_Window) winPtr, width, height); while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) { /* Empty loop body. */ } if ((winPtr->changes.width != width) || (winPtr->changes.height != height)) { EmbedSendConfigure(containerPtr); }}/* *---------------------------------------------------------------------- * * EmbedSendConfigure -- * * This is currently a stub. It is called to notify an * embedded application of its current size and location. This * procedure is called when the embedded application made a * geometry request that we did not grant, so that the embedded * application knows that its geometry didn't change after all. * It is a response to ConfigureRequest events, which we do not * currently synthesize on the Mac * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */static voidEmbedSendConfigure(containerPtr) Container *containerPtr; /* Information about the embedding. */{}/* *---------------------------------------------------------------------- * * EmbedWindowDeleted -- * * This procedure is invoked when a window involved in embedding * (as either the container or the embedded application) is * destroyed. It cleans up the Container structure for the window. * * Results: * None. * * Side effects: * A Container structure may be freed. * *---------------------------------------------------------------------- */static voidEmbedWindowDeleted(winPtr) TkWindow *winPtr; /* Tk's information about window that * was deleted. */{ Container *containerPtr, *prevPtr; /* * Find the Container structure for this window. Delete the * information about the embedded application and free the container's * record. */ prevPtr = NULL; containerPtr = firstContainerPtr; while (1) { if (containerPtr->embeddedPtr == winPtr) { /* * We also have to destroy our parent, to clean up the container. * Fabricate an event to do this. */ if (containerPtr->parentPtr != NULL && containerPtr->parentPtr->flags & TK_BOTH_HALVES) { XEvent event; event.xany.serial = Tk_Display(containerPtr->parentPtr)->request; event.xany.send_event = False; event.xany.display = Tk_Display(containerPtr->parentPtr); event.xany.type = DestroyNotify; event.xany.window = containerPtr->parent; event.xdestroywindow.event = containerPtr->parent; Tk_QueueWindowEvent(&event, TCL_QUEUE_HEAD); } containerPtr->embedded = None; containerPtr->embeddedPtr = NULL; break; } if (containerPtr->parentPtr == winPtr) { containerPtr->parentPtr = NULL; break; } prevPtr = containerPtr; containerPtr = containerPtr->nextPtr; } if ((containerPtr->embeddedPtr == NULL) && (containerPtr->parentPtr == NULL)) { if (prevPtr == NULL) { firstContainerPtr = containerPtr->nextPtr; } else { prevPtr->nextPtr = containerPtr->nextPtr; } ckfree((char *) containerPtr); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -