⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tkunixembed.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * tkUnixEmbed.c -- * *	This file contains platform-specific procedures for UNIX to provide *	basic operations needed for application embedding (where one *	application can use as its main window an internal window from *	some other application). * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tkUnixEmbed.c 1.22 97/08/13 11:15:51 */#include "tkInt.h"#include "tkUnixInt.h"/* * One of the following structures exists for each container in this * application.  It keeps track of the container window and its * associated embedded window. */typedef struct Container {    Window parent;			/* X's window id for the parent of					 * the pair (the container). */    Window parentRoot;			/* Id for the root window of parent's					 * screen. */    TkWindow *parentPtr;		/* Tk's information about the container,					 * or NULL if the container isn't					 * in this process. */    Window wrapper;			/* X's window id for the wrapper					 * window for the embedded window.					 * Starts off as None, but gets					 * filled in when the window is					 * eventually created. */    TkWindow *embeddedPtr;		/* Tk's information about the embedded					 * window, or NULL if the embedded					 * application isn't in this process.					 * Note that this is *not* the					 * same window as wrapper: wrapper is					 * the parent of embeddedPtr. */    struct Container *nextPtr;		/* Next in list of all containers in					 * this process. */} Container;static Container *firstContainerPtr = NULL;					/* First in list of all containers					 * managed by this process.  *//* * Prototypes for static procedures defined in this file: */static void		ContainerEventProc _ANSI_ARGS_((			    ClientData clientData, XEvent *eventPtr));static void		EmbeddedEventProc _ANSI_ARGS_((			    ClientData clientData, XEvent *eventPtr));static int		EmbedErrorProc _ANSI_ARGS_((ClientData clientData,			    XErrorEvent *errEventPtr));static void		EmbedFocusProc _ANSI_ARGS_((ClientData clientData,			    XEvent *eventPtr));static void		EmbedGeometryRequest _ANSI_ARGS_((			    Container * containerPtr, int width, int height));static void		EmbedSendConfigure _ANSI_ARGS_((			    Container *containerPtr));static void		EmbedStructureProc _ANSI_ARGS_((ClientData clientData,			    XEvent *eventPtr));static void		EmbedWindowDeleted _ANSI_ARGS_((TkWindow *winPtr));/* *---------------------------------------------------------------------- * * TkpUseWindow -- * *	This procedure causes a Tk window to use a given X window as *	its parent window, rather than the root window for the screen. *	It is invoked by an embedded application to specify the window *	in which it is embedded. * * Results: *	The return value is normally TCL_OK.  If an error occurs (such *	as string not being a valid window spec), then the return value *	is TCL_ERROR and an error message is left in interp->result if *	interp is non-NULL. * * Side effects: *	Changes the colormap and other visual information to match that *	of the parent window given by "string". * *---------------------------------------------------------------------- */intTkpUseWindow(interp, tkwin, string)    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. */    char *string;		/* String identifying an X window to use				 * for tkwin;  must be an integer value. */{    TkWindow *winPtr = (TkWindow *) tkwin;    int id, anyError;    Window parent;    Tk_ErrorHandler handler;    Container *containerPtr;    XWindowAttributes parentAtts;    if (winPtr->window != None) {	panic("TkUseWindow: X window already assigned");    }    if (Tcl_GetInt(interp, string, &id) != TCL_OK) {	return TCL_ERROR;    }    parent = (Window) id;    /*     * 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, (ClientData) &anyError);    if (!XGetWindowAttributes(winPtr->display, parent, &parentAtts)) {        anyError =  1;    }    XSync(winPtr->display, False);    Tk_DeleteErrorHandler(handler);    if (anyError) {	if (interp != NULL) {	    Tcl_AppendResult(interp, "couldn't create child of window \"",		    string, "\"", (char *) 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,	    (ClientData) 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 = 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 = (Container *) ckalloc(sizeof(Container));	containerPtr->parent = parent;	containerPtr->parentRoot = parentAtts.root;	containerPtr->parentPtr = NULL;	containerPtr->wrapper = None;	containerPtr->nextPtr = firstContainerPtr;	firstContainerPtr = containerPtr;    }    containerPtr->embeddedPtr = winPtr;    winPtr->flags |= TK_EMBEDDED;    return TCL_OK;}/* *---------------------------------------------------------------------- * * TkpMakeWindow -- * *	Create an actual window system window object based on the *	current attributes of the specified TkWindow. * * Results: *	Returns the handle to the new window, or None on failure. * * Side effects: *	Creates a new X window. * *---------------------------------------------------------------------- */WindowTkpMakeWindow(winPtr, parent)    TkWindow *winPtr;		/* Tk's information about the window that				 * is to be instantiated. */    Window parent;		/* Window system token for the parent in				 * which the window is to be created. */{    Container *containerPtr;    if (winPtr->flags & TK_EMBEDDED) {	/*	 * This window is embedded.  Don't create the new window in the	 * given parent; instead, create it as a child of the root window	 * of the container's screen.  The window will get reparented	 * into a wrapper window later.	 */	for (containerPtr = firstContainerPtr; ;		containerPtr = containerPtr->nextPtr) {	    if (containerPtr == NULL) {		panic("TkMakeWindow couldn't find container for window");	    }	    if (containerPtr->embeddedPtr == winPtr) {		break;	    }	}	parent = containerPtr->parentRoot;    }    return XCreateWindow(winPtr->display, parent, winPtr->changes.x,	    winPtr->changes.y, (unsigned) winPtr->changes.width,	    (unsigned) winPtr->changes.height,	    (unsigned) winPtr->changes.border_width, winPtr->depth,	    InputOutput, winPtr->visual, winPtr->dirtyAtts,	    &winPtr->atts);}/* *---------------------------------------------------------------------- * * 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(tkwin)    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     * find out later if the embedded app. is in the same process.     */    Tk_MakeWindowExist(tkwin);    containerPtr = (Container *) ckalloc(sizeof(Container));    containerPtr->parent = Tk_WindowId(tkwin);    containerPtr->parentRoot = RootWindowOfScreen(Tk_Screen(tkwin));    containerPtr->parentPtr = winPtr;    containerPtr->wrapper = 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.     */    winPtr->atts.event_mask |= SubstructureRedirectMask|SubstructureNotifyMask;    XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);    Tk_CreateEventHandler(tkwin,	    SubstructureNotifyMask|SubstructureRedirectMask,	    ContainerEventProc, (ClientData) winPtr);    Tk_CreateEventHandler(tkwin, StructureNotifyMask, EmbedStructureProc,	    (ClientData) containerPtr);    Tk_CreateEventHandler(tkwin, FocusChangeMask, EmbedFocusProc,	    (ClientData) containerPtr);}/* *---------------------------------------------------------------------- * * EmbedErrorProc -- * *	This procedure is invoked if an error occurs while creating *	an embedded window. * * Results: *	Always returns 0 to indicate that the error has been properly *	handled. * * Side effects: *	The integer pointed to by the clientData argument is set to 1. * *---------------------------------------------------------------------- */static intEmbedErrorProc(clientData, errEventPtr)    ClientData clientData;	/* Points to integer to set. */    XErrorEvent *errEventPtr;	/* Points to information about error				 * (not used). */{    int *iPtr = (int *) clientData;    *iPtr = 1;    return 0;}/* *---------------------------------------------------------------------- * * 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. * * 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).  Also set the child's size to match the container.	 */	containerPtr->wrapper = eventPtr->xcreatewindow.window;	XMoveResizeWindow(eventPtr->xcreatewindow.display,		containerPtr->wrapper, 0, 0,		(unsigned int) Tk_Width(			(Tk_Window) containerPtr->parentPtr),		(unsigned int) Tk_Height(			(Tk_Window) containerPtr->parentPtr));    } 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->wrapper != 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -