LRESULT TkWinEmbeddedEventProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int result = 1; Container *containerPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Find the Container structure associated with the parent window. */ for (containerPtr = tsdPtr->firstContainerPtr; containerPtr && containerPtr->parentHWnd != hwnd; containerPtr = containerPtr->nextPtr) { /* empty loop body */ } if (containerPtr) { TkWindow *topwinPtr = NULL; if(Tk_IsTopLevel(containerPtr->parentPtr)) { topwinPtr = containerPtr->parentPtr; } switch (message) { case TK_INFO: /* * An embedded window may send this message for container * verification and availability before attach. * * wParam - a sub message * * TK_CONTAINER_ISAVAILABLE - if the container is available * for use? * result = 1 for yes and 0 for no; * * TK_CONTAINER_VERIFY - request the container to verify its * identification * result = (long)hwnd if this window is a container * -(long)hwnd otherwise * * lParam - N/A */ switch(wParam) { case TK_CONTAINER_ISAVAILABLE: result = containerPtr->embeddedHWnd == NULL? 1:0; break; case TK_CONTAINER_VERIFY: result = (long)containerPtr->parentHWnd; break; default: result = 0; } break; case TK_ATTACHWINDOW: /* * An embedded window (either from this application or from * another application) is trying to attach to this container. We * attach it only if this container is not yet containing any * window. * * wParam - a handle of an embedded window * lParam - N/A * * An embedded window may send this message with a wParam of NULL * to test if a window is able to provide embedding service. The * container returns its window handle for accepting the * attachment and identifying itself or a zero for being already * in use. * * Return value: * 0 - the container is unable to be used. * hwnd - the container is ready to be used. */ if (containerPtr->embeddedHWnd == NULL) { if (wParam) { TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow((HWND) wParam); if (winPtr) { winPtr->flags |= TK_BOTH_HALVES; containerPtr->embeddedPtr = winPtr; containerPtr->parentPtr->flags |= TK_BOTH_HALVES; } containerPtr->embeddedHWnd = (HWND)wParam; } result = (long)containerPtr->parentHWnd; } else { result = 0; } break; case TK_DETACHWINDOW: /* * An embedded window notifies the container that it is detached. * The container should clearn the related variables and redraw * its window. * * wParam - N/A * lParam - N/A * * Return value: * 0 - the message is not processed. * others - the message is processed. */ containerPtr->embeddedMenuHWnd = NULL; containerPtr->embeddedHWnd = NULL; containerPtr->parentPtr->flags &= ~TK_BOTH_HALVES; if (topwinPtr) { TkWinSetMenu((Tk_Window) topwinPtr, 0); } InvalidateRect(hwnd, NULL, TRUE); break; case TK_GEOMETRYREQ: /* * An embedded window requests a window size change. * * wParam - window width * lParam - window height * * Return value: * 0 - the message is not processed. * others - the message is processed. */ EmbedGeometryRequest(containerPtr, (int)wParam, lParam); break; case TK_RAISEWINDOW: /* * An embedded window requests to change its Z-order. * * wParam - a window handle as a z-order stack reference * lParam - a flag of above-below: 0 - above; 1 or others: - below * * Return value: * 0 - the message is not processed. * others - the message is processed. */ TkWinSetWindowPos(GetParent(containerPtr->parentHWnd), (HWND)wParam, (int)lParam); break; case TK_GETFRAMEWID: /* * An embedded window requests to get the frame window's id. * * wParam - N/A * lParam - N/A * * Return vlaue: * * A handle of the frame window. If it is not availble, a zero is * returned. */ if (topwinPtr) { result = (long)GetParent(containerPtr->parentHWnd); } else { topwinPtr = containerPtr->parentPtr; while (!(topwinPtr->flags & TK_TOP_HIERARCHY)) { topwinPtr = topwinPtr->parentPtr; } if (topwinPtr && topwinPtr->window) { result = (long)GetParent(Tk_GetHWND(topwinPtr->window)); } else { result = 0; } } break; case TK_CLAIMFOCUS: /* * An embedded window requests a focus. * * wParam - a flag of forcing focus * lParam - N/A * * Return value: * 0 - the message is not processed * 1 - the message is processed */ if (!SetFocus(containerPtr->embeddedHWnd) && wParam) { /* * forcing focus TBD */ } break; case TK_WITHDRAW: /* * An embedded window requests withdraw. * * wParam - N/A * lParam - N/A * * Return value * 0 - the message is not processed * 1 - the message is processed */ if (topwinPtr) { TkpWinToplevelWithDraw(topwinPtr); } else { result = 0; } break; case TK_ICONIFY: /* * An embedded window requests iconification. * * wParam - N/A * lParam - N/A * * Return value * 0 - the message is not processed * 1 - the message is processed */ if (topwinPtr) { TkpWinToplevelIconify(topwinPtr); } else { result = 0; } break; case TK_DEICONIFY: /* * An embedded window requests deiconification. * * wParam - N/A * lParam - N/A * * Return value * 0 - the message is not processed * 1 - the message is processed */ if (topwinPtr) { TkpWinToplevelDeiconify(topwinPtr); } else { result = 0; } break; case TK_MOVEWINDOW: /* * An embedded window requests to move position if both wParam and * lParam are greater or equal to 0. * wParam - x value of the frame's upper left * lParam - y value of the frame's upper left * * Otherwise an embedded window requests the current position * * Return value: an encoded window position in a 32bit long, i.e, * ((x << 16) & 0xffff0000) | (y & 0xffff) * * Only a toplevel container may move the embedded. */ result = TkpWinToplevelMove(containerPtr->parentPtr, wParam, lParam); break; case TK_OVERRIDEREDIRECT: /* * An embedded window request overrideredirect. * * wParam * 0 - add a frame if there is no one * 1 - remove the frame if there is a one * < 0 - query the current overrideredirect value * * lParam - N/A * * Return value: * 1 + the current value of overrideredirect if the container is a * toplevel. Otherwise 0. */ if (topwinPtr) { result = 1 + TkpWinToplevelOverrideRedirect(topwinPtr, wParam); } else { result = 0; } break; case TK_SETMENU: /* * An embedded requests to set a menu. * * wParam - a menu handle * lParam - a menu window handle * * Return value: * 1 - the message is processed * 0 - the message is not processed */ if (topwinPtr) { containerPtr->embeddedMenuHWnd = (HWND)lParam; TkWinSetMenu((Tk_Window)topwinPtr, (HMENU)wParam); } else { result = 0; } break; case TK_STATE: /* * An embedded window request set/get state services. * * wParam - service directive * 0 - 3 for setting state * 0 - withdrawn state * 1 - normal state * 2 - zoom state * 3 - icon state * others for gettting state * * lParam - N/A * * Return value * 1 + the current state or 0 if the container is not a toplevel */ if (topwinPtr) { if (wParam >= 0 && wParam <= 3) { TkpWmSetState(topwinPtr, wParam); } result = 1+TkpWmGetState(topwinPtr); } else { result = 0; } break; /* * Return 0 since the current Tk container implementation is * unable to provide following services. */ default: result = 0; break; } } else { if ((message == TK_INFO) && (wParam == TK_CONTAINER_VERIFY)) { /* * Reply the message sender: this is not a Tk container */ return -(long)hwnd; } else { result = 0; } } return result; }
static void ContainerEventProc( ClientData clientData, /* Token for container window. */ XEvent *eventPtr) /* ResizeRequest event. */ { TkWindow *winPtr = 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, NULL, NULL); /* * Find the Container structure associated with the parent window. */ for (containerPtr = firstContainerPtr; containerPtr->parent != eventPtr->xmaprequest.parent; containerPtr = containerPtr->nextPtr) { if (containerPtr == NULL) { Tcl_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); }