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

📄 tkselect.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  * tkSelect.c -- * *	This file manages the selection for the Tk toolkit, *	translating between the standard X ICCCM conventions *	and Tcl commands. * * Copyright (c) 1990-1993 The Regents of the University of California. * Copyright (c) 1994-1995 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: @(#) tkSelect.c 1.57 96/05/03 10:52:40 */#include "tkInt.h"#include "tkSelect.h"/* * When a selection handler is set up by invoking "selection handle", * one of the following data structures is set up to hold information * about the command to invoke and its interpreter. */typedef struct {    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */    int cmdLength;		/* # of non-NULL bytes in command. */    char command[4];		/* Command to invoke.  Actual space is				 * allocated as large as necessary.  This				 * must be the last entry in the structure. */} CommandInfo;/* * When selection ownership is claimed with the "selection own" Tcl command, * one of the following structures is created to record the Tcl command * to be executed when the selection is lost again. */typedef struct LostCommand {    Tcl_Interp *interp;		/* Interpreter in which to invoke command. */    char command[4];		/* Command to invoke.  Actual space is				 * allocated as large as necessary.  This				 * must be the last entry in the structure. */} LostCommand;/* * Shared variables: */TkSelInProgress *pendingPtr = NULL;				/* Topmost search in progress, or				 * NULL if none. *//* * Forward declarations for procedures defined in this file: */static int		HandleTclCommand _ANSI_ARGS_((ClientData clientData,			    int offset, char *buffer, int maxBytes));static void		LostSelection _ANSI_ARGS_((ClientData clientData));static int		SelGetProc _ANSI_ARGS_((ClientData clientData,			    Tcl_Interp *interp, char *portion));/* *-------------------------------------------------------------- * * Tk_CreateSelHandler -- * *	This procedure is called to register a procedure *	as the handler for selection requests of a particular *	target type on a particular window for a particular *	selection. * * Results: *	None. * * Side effects: *	In the future, whenever the selection is in tkwin's *	window and someone requests the selection in the *	form given by target, proc will be invoked to provide *	part or all of the selection in the given form.  If *	there was already a handler declared for the given *	window, target and selection type, then it is replaced. *	Proc should have the following form: * *	int *	proc(clientData, offset, buffer, maxBytes) *	    ClientData clientData; *	    int offset; *	    char *buffer; *	    int maxBytes; *	{ *	} * *	The clientData argument to proc will be the same as *	the clientData argument to this procedure.  The offset *	argument indicates which portion of the selection to *	return:  skip the first offset bytes.  Buffer is a *	pointer to an area in which to place the converted *	selection, and maxBytes gives the number of bytes *	available at buffer.  Proc should place the selection *	in buffer as a string, and return a count of the number *	of bytes of selection actually placed in buffer (not *	including the terminating NULL character).  If the *	return value equals maxBytes, this is a sign that there *	is probably still more selection information available. * *-------------------------------------------------------------- */voidTk_CreateSelHandler(tkwin, selection, target, proc, clientData, format)    Tk_Window tkwin;		/* Token for window. */    Atom selection;		/* Selection to be handled. */    Atom target;		/* The kind of selection conversions				 * that can be handled by proc,				 * e.g. TARGETS or STRING. */    Tk_SelectionProc *proc;	/* Procedure to invoke to convert				 * selection to type "target". */    ClientData clientData;	/* Value to pass to proc. */    Atom format;		/* Format in which the selection				 * information should be returned to				 * the requestor. XA_STRING is best by				 * far, but anything listed in the ICCCM				 * will be tolerated (blech). */{    register TkSelHandler *selPtr;    TkWindow *winPtr = (TkWindow *) tkwin;    if (winPtr->dispPtr->multipleAtom == None) {	TkSelInit(tkwin);    }    /*     * See if there's already a handler for this target and selection on     * this window.  If so, re-use it.  If not, create a new one.     */    for (selPtr = winPtr->selHandlerList; ; selPtr = selPtr->nextPtr) {	if (selPtr == NULL) {	    selPtr = (TkSelHandler *) ckalloc(sizeof(TkSelHandler));	    selPtr->nextPtr = winPtr->selHandlerList;	    winPtr->selHandlerList = selPtr;	    break;	}	if ((selPtr->selection == selection) && (selPtr->target == target)) {	    /*	     * Special case:  when replacing handler created by	     * "selection handle", free up memory.  Should there be a	     * callback to allow other clients to do this too?	     */	    if (selPtr->proc == HandleTclCommand) {		ckfree((char *) selPtr->clientData);	    }	    break;	}    }    selPtr->selection = selection;    selPtr->target = target;    selPtr->format = format;    selPtr->proc = proc;    selPtr->clientData = clientData;    if (format == XA_STRING) {	selPtr->size = 8;    } else {	selPtr->size = 32;    }}/* *---------------------------------------------------------------------- * * Tk_DeleteSelHandler -- * *	Remove the selection handler for a given window, target, and *	selection, if it exists. * * Results: *	None. * * Side effects: *	The selection handler for tkwin and target is removed.  If there *	is no such handler then nothing happens. * *---------------------------------------------------------------------- */voidTk_DeleteSelHandler(tkwin, selection, target)    Tk_Window tkwin;			/* Token for window. */    Atom selection;			/* The selection whose handler					 * is to be removed. */    Atom target;			/* The target whose selection					 * handler is to be removed. */{    TkWindow *winPtr = (TkWindow *) tkwin;    register TkSelHandler *selPtr, *prevPtr;    register TkSelInProgress *ipPtr;    /*     * Find the selection handler to be deleted, or return if it doesn't     * exist.     */     for (selPtr = winPtr->selHandlerList, prevPtr = NULL; ;	    prevPtr = selPtr, selPtr = selPtr->nextPtr) {	if (selPtr == NULL) {	    return;	}	if ((selPtr->selection == selection) && (selPtr->target == target)) {	    break;	}    }    /*     * If ConvertSelection is processing this handler, tell it that the     * handler is dead.     */    for (ipPtr = pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {	if (ipPtr->selPtr == selPtr) {	    ipPtr->selPtr = NULL;	}    }    /*     * Free resources associated with the handler.     */    if (prevPtr == NULL) {	winPtr->selHandlerList = selPtr->nextPtr;    } else {	prevPtr->nextPtr = selPtr->nextPtr;    }    if (selPtr->proc == HandleTclCommand) {	ckfree((char *) selPtr->clientData);    }    ckfree((char *) selPtr);}/* *-------------------------------------------------------------- * * Tk_OwnSelection -- * *	Arrange for tkwin to become the owner of a selection. * * Results: *	None. * * Side effects: *	From now on, requests for the selection will be directed *	to procedures associated with tkwin (they must have been *	declared with calls to Tk_CreateSelHandler).  When the *	selection is lost by this window, proc will be invoked *	(see the manual entry for details).  This procedure may *	invoke callbacks, including Tcl scripts, so any calling *	function should be reentrant at the point where *	Tk_OwnSelection is invoked. * *-------------------------------------------------------------- */voidTk_OwnSelection(tkwin, selection, proc, clientData)    Tk_Window tkwin;		/* Window to become new selection				 * owner. */    Atom selection;		/* Selection that window should own. */    Tk_LostSelProc *proc;	/* Procedure to call when selection				 * is taken away from tkwin. */    ClientData clientData;	/* Arbitrary one-word argument to				 * pass to proc. */{    register TkWindow *winPtr = (TkWindow *) tkwin;    TkDisplay *dispPtr = winPtr->dispPtr;    TkSelectionInfo *infoPtr;    Tk_LostSelProc *clearProc = NULL;    ClientData clearData = NULL;	/* Initialization needed only to					 * prevent compiler warning. */            if (dispPtr->multipleAtom == None) {	TkSelInit(tkwin);    }    Tk_MakeWindowExist(tkwin);    /*     * This code is somewhat tricky.  First, we find the specified selection     * on the selection list.  If the previous owner is in this process, and     * is a different window, then we need to invoke the clearProc.  However,     * it's dangerous to call the clearProc right now, because it could     * invoke a Tcl script that wrecks the current state (e.g. it could     * delete the window).  To be safe, defer the call until the end of the     * procedure when we no longer care about the state.     */    for (infoPtr = dispPtr->selectionInfoPtr; infoPtr != NULL;	    infoPtr = infoPtr->nextPtr) {	if (infoPtr->selection == selection) {	    break;	}    }    if (infoPtr == NULL) {	infoPtr = (TkSelectionInfo*) ckalloc(sizeof(TkSelectionInfo));	infoPtr->selection = selection;	infoPtr->nextPtr = dispPtr->selectionInfoPtr;	dispPtr->selectionInfoPtr = infoPtr;    } else if (infoPtr->clearProc != NULL) {	if (infoPtr->owner != tkwin) {	    clearProc = infoPtr->clearProc;	    clearData = infoPtr->clearData;	} else if (infoPtr->clearProc == LostSelection) {	    /*	     * If the selection handler is one created by "selection own",	     * be sure to free the record for it;  otherwise there will be	     * a memory leak.	     */	    ckfree((char *) infoPtr->clearData);	}    }    infoPtr->owner = tkwin;    infoPtr->serial = NextRequest(winPtr->display);    infoPtr->clearProc = proc;    infoPtr->clearData = clientData;    /*     * Note that we are using CurrentTime, even though ICCCM recommends against     * this practice (the problem is that we don't necessarily have a valid     * time to use).  We will not be able to retrieve a useful timestamp for     * the TIMESTAMP target later.     */    infoPtr->time = CurrentTime;    /*     * Note that we are not checking to see if the selection claim succeeded.     * If the ownership does not change, then the clearProc may never be     * invoked, and we will return incorrect information when queried for the     * current selection owner.     */    XSetSelectionOwner(winPtr->display, infoPtr->selection, winPtr->window,	    infoPtr->time);    /*     * Now that we are done, we can invoke clearProc without running into     * reentrancy problems.     */    if (clearProc != NULL) {	(*clearProc)(clearData);    }}/* *---------------------------------------------------------------------- * * Tk_ClearSelection -- * *	Eliminate the specified selection on tkwin's display, if there is one. * * Results: *	None. * * Side effects: *	The specified selection is cleared, so that future requests to retrieve *	it will fail until some application owns it again.  This procedure *	invokes callbacks, possibly including Tcl scripts, so any calling *	function should be reentrant at the point Tk_ClearSelection is invoked. * *---------------------------------------------------------------------- */voidTk_ClearSelection(tkwin, selection)    Tk_Window tkwin;		/* Window that selects a display. */    Atom selection;		/* Selection to be cancelled. */{    register TkWindow *winPtr = (TkWindow *) tkwin;    TkDisplay *dispPtr = winPtr->dispPtr;    TkSelectionInfo *infoPtr;    TkSelectionInfo *prevPtr;    TkSelectionInfo *nextPtr;    Tk_LostSelProc *clearProc = NULL;    ClientData clearData = NULL;	/* Initialization needed only to					 * prevent compiler warning. */    if (dispPtr->multipleAtom == None) {	TkSelInit(tkwin);    }    for (infoPtr = dispPtr->selectionInfoPtr, prevPtr = NULL;	     infoPtr != NULL; infoPtr = nextPtr) {	nextPtr = infoPtr->nextPtr;	if (infoPtr->selection == selection) {	    if (prevPtr == NULL) {		dispPtr->selectionInfoPtr = nextPtr;	    } else {		prevPtr->nextPtr = nextPtr;	    }	    break;	}	prevPtr = infoPtr;    }        if (infoPtr != NULL) {	clearProc = infoPtr->clearProc;	clearData = infoPtr->clearData;	ckfree((char *) infoPtr);    }    XSetSelectionOwner(winPtr->display, selection, None, CurrentTime);    if (clearProc != NULL) {	(*clearProc)(clearData);    }}/* *-------------------------------------------------------------- * * Tk_GetSelection -- * *	Retrieve the value of a selection and pass it off (in *	pieces, possibly) to a given procedure. * * Results: *	The return value is a standard Tcl return value. *	If an error occurs (such as no selection exists) *	then an error message is left in interp->result. * * Side effects: *	The standard X11 protocols are used to retrieve the *	selection.  When it arrives, it is passed to proc.  If *	the selection is very large, it will be passed to proc *	in several pieces.  Proc should have the following *	structure: * *	int *	proc(clientData, interp, portion) *	    ClientData clientData; *	    Tcl_Interp *interp; *	    char *portion; *	{

⌨️ 快捷键说明

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