diff options
Diffstat (limited to 'unix/tkUnixSelect.c')
-rw-r--r-- | unix/tkUnixSelect.c | 85 |
1 files changed, 51 insertions, 34 deletions
diff --git a/unix/tkUnixSelect.c b/unix/tkUnixSelect.c index 1b27b70..2b79a70 100644 --- a/unix/tkUnixSelect.c +++ b/unix/tkUnixSelect.c @@ -4,12 +4,12 @@ * This file contains X specific routines for manipulating * selections. * - * Copyright (c) 1995 Sun Microsystems, Inc. + * Copyright (c) 1995-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. * - * RCS: @(#) $Id: tkUnixSelect.c,v 1.2 1998/09/14 18:23:57 stanton Exp $ + * RCS: @(#) $Id: tkUnixSelect.c,v 1.3 1999/04/16 01:51:47 stanton Exp $ */ #include "tkInt.h" @@ -57,9 +57,12 @@ typedef struct IncrInfo { * retrievals currently pending. */ } IncrInfo; -static IncrInfo *pendingIncrs = NULL; - /* List of all incr structures + +typedef struct ThreadSpecificData { + IncrInfo *pendingIncrs; /* List of all incr structures * currently active. */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; /* * Largest property that we'll accept when sending or receiving the @@ -98,7 +101,7 @@ static void SelTimeoutProc _ANSI_ARGS_((ClientData clientData)); * 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. + * then an error message is left in the interp's result. * * Side effects: * None. @@ -230,6 +233,8 @@ TkSelPropProc(eventPtr) int numItems; char *propPtr; Tk_ErrorHandler errorHandler; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * See if this event announces the deletion of a property being @@ -240,7 +245,7 @@ TkSelPropProc(eventPtr) if (eventPtr->xproperty.state != PropertyDelete) { return; } - for (incrPtr = pendingIncrs; incrPtr != NULL; + for (incrPtr = tsdPtr->pendingIncrs; incrPtr != NULL; incrPtr = incrPtr->nextPtr) { if (incrPtr->reqWindow != eventPtr->xproperty.window) { continue; @@ -269,12 +274,12 @@ TkSelPropProc(eventPtr) } else { TkSelInProgress ip; ip.selPtr = selPtr; - ip.nextPtr = pendingPtr; - pendingPtr = &ip; + ip.nextPtr = TkSelGetInProgress(); + TkSelSetInProgress(&ip); numItems = (*selPtr->proc)(selPtr->clientData, incrPtr->offsets[i], (char *) buffer, TK_SEL_BYTES_AT_ONCE); - pendingPtr = ip.nextPtr; + TkSelSetInProgress(ip.nextPtr); if (ip.selPtr == NULL) { /* * The selection handler deleted itself. @@ -422,9 +427,12 @@ TkSelEventProc(tkwin, eventPtr) if ((type == XA_STRING) || (type == dispPtr->textAtom) || (type == dispPtr->compoundTextAtom)) { if (format != 8) { - sprintf(retrPtr->interp->result, - "bad format for string selection: wanted \"8\", got \"%d\"", - format); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, + "bad format for string selection: wanted \"8\", got \"%d\"", + format); + Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE); retrPtr->result = TCL_ERROR; return; } @@ -456,9 +464,12 @@ TkSelEventProc(tkwin, eventPtr) char *string; if (format != 32) { - sprintf(retrPtr->interp->result, - "bad format for selection: wanted \"32\", got \"%d\"", - format); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, + "bad format for selection: wanted \"32\", got \"%d\"", + format); + Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE); retrPtr->result = TCL_ERROR; return; } @@ -580,6 +591,8 @@ ConvertSelection(winPtr, eventPtr) Tk_ErrorHandler errorHandler; TkSelectionInfo *infoPtr; TkSelInProgress ip; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); errorHandler = Tk_CreateErrorHandler(eventPtr->display, -1, -1,-1, (int (*)()) NULL, (ClientData) NULL); @@ -694,12 +707,12 @@ ConvertSelection(winPtr, eventPtr) } } else { ip.selPtr = selPtr; - ip.nextPtr = pendingPtr; - pendingPtr = &ip; + ip.nextPtr = TkSelGetInProgress(); + TkSelSetInProgress(&ip); type = selPtr->format; numItems = (*selPtr->proc)(selPtr->clientData, 0, (char *) buffer, TK_SEL_BYTES_AT_ONCE); - pendingPtr = ip.nextPtr; + TkSelSetInProgress(ip.nextPtr); if ((ip.selPtr == NULL) || (numItems < 0)) { incr.multAtoms[2*i + 1] = None; continue; @@ -761,8 +774,8 @@ ConvertSelection(winPtr, eventPtr) incr.idleTime = 0; incr.reqWindow = reply.requestor; incr.time = infoPtr->time; - incr.nextPtr = pendingIncrs; - pendingIncrs = &incr; + incr.nextPtr = tsdPtr->pendingIncrs; + tsdPtr->pendingIncrs = &incr; } if (multiple) { XChangeProperty(reply.display, reply.requestor, reply.property, @@ -798,10 +811,10 @@ ConvertSelection(winPtr, eventPtr) -1, -1,-1, (int (*)()) NULL, (ClientData) NULL); XSelectInput(reply.display, reply.requestor, 0L); Tk_DeleteErrorHandler(errorHandler); - if (pendingIncrs == &incr) { - pendingIncrs = incr.nextPtr; + if (tsdPtr->pendingIncrs == &incr) { + tsdPtr->pendingIncrs = incr.nextPtr; } else { - for (incrPtr2 = pendingIncrs; incrPtr2 != NULL; + for (incrPtr2 = tsdPtr->pendingIncrs; incrPtr2 != NULL; incrPtr2 = incrPtr2->nextPtr) { if (incrPtr2->nextPtr == &incr) { incrPtr2->nextPtr = incr.nextPtr; @@ -891,10 +904,12 @@ SelRcvIncrProc(clientData, eventPtr) || (type == retrPtr->winPtr->dispPtr->textAtom) || (type == retrPtr->winPtr->dispPtr->compoundTextAtom)) { if (format != 8) { - Tcl_SetResult(retrPtr->interp, (char *) NULL, TCL_STATIC); - sprintf(retrPtr->interp->result, - "bad format for string selection: wanted \"8\", got \"%d\"", - format); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, + "bad format for string selection: wanted \"8\", got \"%d\"", + format); + Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE); retrPtr->result = TCL_ERROR; goto done; } @@ -909,10 +924,12 @@ SelRcvIncrProc(clientData, eventPtr) char *string; if (format != 32) { - Tcl_SetResult(retrPtr->interp, (char *) NULL, TCL_STATIC); - sprintf(retrPtr->interp->result, - "bad format for selection: wanted \"32\", got \"%d\"", - format); + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, + "bad format for selection: wanted \"32\", got \"%d\"", + format); + Tcl_SetResult(retrPtr->interp, buf, TCL_VOLATILE); retrPtr->result = TCL_ERROR; goto done; } @@ -964,8 +981,8 @@ SelectionSize(selPtr) size = TK_SEL_BYTES_AT_ONCE; ip.selPtr = selPtr; - ip.nextPtr = pendingPtr; - pendingPtr = &ip; + ip.nextPtr = TkSelGetInProgress(); + TkSelSetInProgress(&ip); do { chunkSize = (*selPtr->proc)(selPtr->clientData, size, (char *) buffer, TK_SEL_BYTES_AT_ONCE); @@ -975,7 +992,7 @@ SelectionSize(selPtr) } size += chunkSize; } while (chunkSize == TK_SEL_BYTES_AT_ONCE); - pendingPtr = ip.nextPtr; + TkSelSetInProgress(ip.nextPtr); return size; } |