Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
}