?? tkunixselect.c
字號:
} Tcl_DeleteTimerHandler(incr.timeout); errorHandler = Tk_CreateErrorHandler(winPtr->display, -1, -1,-1, (int (*)()) NULL, (ClientData) NULL); XSelectInput(reply.display, reply.requestor, 0L); Tk_DeleteErrorHandler(errorHandler); if (pendingIncrs == &incr) { pendingIncrs = incr.nextPtr; } else { for (incrPtr2 = pendingIncrs; incrPtr2 != NULL; incrPtr2 = incrPtr2->nextPtr) { if (incrPtr2->nextPtr == &incr) { incrPtr2->nextPtr = incr.nextPtr; break; } } } } /* * All done. Cleanup and return. */ ckfree((char *) incr.offsets); if (multiple) { XFree((char *) incr.multAtoms); } return; /* * An error occurred. Send back a refusal message. */ refuse: reply.property = None; XSendEvent(reply.display, reply.requestor, False, 0, (XEvent *) &reply); Tk_DeleteErrorHandler(errorHandler); return;}/* *---------------------------------------------------------------------- * * SelRcvIncrProc -- * * This procedure handles the INCR protocol on the receiving * side. It is invoked in response to property changes on * the requestor's window (which hopefully are because a new * chunk of the selection arrived). * * Results: * None. * * Side effects: * If a new piece of selection has arrived, a procedure is * invoked to deal with that piece. When the whole selection * is here, a flag is left for the higher-level procedure that * initiated the selection retrieval. * *---------------------------------------------------------------------- */static voidSelRcvIncrProc(clientData, eventPtr) ClientData clientData; /* Information about retrieval. */ register XEvent *eventPtr; /* X PropertyChange event. */{ register TkSelRetrievalInfo *retrPtr = (TkSelRetrievalInfo *) clientData; char *propInfo; Atom type; int format, result; unsigned long numItems, bytesAfter; Tcl_Interp *interp; if ((eventPtr->xproperty.atom != retrPtr->property) || (eventPtr->xproperty.state != PropertyNewValue) || (retrPtr->result != -1)) { return; } propInfo = NULL; result = XGetWindowProperty(eventPtr->xproperty.display, eventPtr->xproperty.window, retrPtr->property, 0, MAX_PROP_WORDS, True, (Atom) AnyPropertyType, &type, &format, &numItems, &bytesAfter, (unsigned char **) &propInfo); if ((result != Success) || (type == None)) { return; } if (bytesAfter != 0) { Tcl_SetResult(retrPtr->interp, "selection property too large", TCL_STATIC); retrPtr->result = TCL_ERROR; goto done; } if (numItems == 0) { retrPtr->result = TCL_OK; } else if ((type == XA_STRING) || (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); retrPtr->result = TCL_ERROR; goto done; } interp = retrPtr->interp; Tcl_Preserve((ClientData) interp); result = (*retrPtr->proc)(retrPtr->clientData, interp, propInfo); Tcl_Release((ClientData) interp); if (result != TCL_OK) { retrPtr->result = result; } } else { 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); retrPtr->result = TCL_ERROR; goto done; } string = SelCvtFromX((long *) propInfo, (int) numItems, type, (Tk_Window) retrPtr->winPtr); interp = retrPtr->interp; Tcl_Preserve((ClientData) interp); result = (*retrPtr->proc)(retrPtr->clientData, interp, string); Tcl_Release((ClientData) interp); if (result != TCL_OK) { retrPtr->result = result; } ckfree(string); } done: XFree(propInfo); retrPtr->idleTime = 0;}/* *---------------------------------------------------------------------- * * SelectionSize -- * * This procedure is called when the selection is too large to * send in a single buffer; it computes the total length of * the selection in bytes. * * Results: * The return value is the number of bytes in the selection * given by selPtr. * * Side effects: * The selection is retrieved from its current owner (this is * the only way to compute its size). * *---------------------------------------------------------------------- */static intSelectionSize(selPtr) TkSelHandler *selPtr; /* Information about how to retrieve * the selection whose size is wanted. */{ char buffer[TK_SEL_BYTES_AT_ONCE+1]; int size, chunkSize; TkSelInProgress ip; size = TK_SEL_BYTES_AT_ONCE; ip.selPtr = selPtr; ip.nextPtr = pendingPtr; pendingPtr = &ip; do { chunkSize = (*selPtr->proc)(selPtr->clientData, size, (char *) buffer, TK_SEL_BYTES_AT_ONCE); if (ip.selPtr == NULL) { size = 0; break; } size += chunkSize; } while (chunkSize == TK_SEL_BYTES_AT_ONCE); pendingPtr = ip.nextPtr; return size;}/* *---------------------------------------------------------------------- * * IncrTimeoutProc -- * * This procedure is invoked once a second while sending the * selection to a requestor in INCR mode. After a while it * gives up and aborts the selection operation. * * Results: * None. * * Side effects: * A new timeout gets registered so that this procedure gets * called again in another second, unless too many seconds * have elapsed, in which case incrPtr is marked as "all done". * *---------------------------------------------------------------------- */static voidIncrTimeoutProc(clientData) ClientData clientData; /* Information about INCR-mode * selection retrieval for which * we are selection owner. */{ register IncrInfo *incrPtr = (IncrInfo *) clientData; incrPtr->idleTime++; if (incrPtr->idleTime >= 5) { incrPtr->numIncrs = 0; } else { incrPtr->timeout = Tcl_CreateTimerHandler(1000, IncrTimeoutProc, (ClientData) incrPtr); }}/* *---------------------------------------------------------------------- * * SelCvtToX -- * * Given a selection represented as a string (the normal Tcl form), * convert it to the ICCCM-mandated format for X, depending on * the type argument. This procedure and SelCvtFromX are inverses. * * Results: * The return value is a malloc'ed buffer holding a value * equivalent to "string", but formatted as for "type". It is * the caller's responsibility to free the string when done with * it. The word at *numLongsPtr is filled in with the number of * 32-bit words returned in the result. * * Side effects: * None. * *---------------------------------------------------------------------- */static long *SelCvtToX(string, type, tkwin, numLongsPtr) char *string; /* String representation of selection. */ Atom type; /* Atom specifying the X format that is * desired for the selection. Should not * be XA_STRING (if so, don't bother calling * this procedure at all). */ Tk_Window tkwin; /* Window that governs atom conversion. */ int *numLongsPtr; /* Number of 32-bit words contained in the * result. */{ register char *p; char *field; int numFields; long *propPtr, *longPtr;#define MAX_ATOM_NAME_LENGTH 100 char atomName[MAX_ATOM_NAME_LENGTH+1]; /* * The string is assumed to consist of fields separated by spaces. * The property gets generated by converting each field to an * integer number, in one of two ways: * 1. If type is XA_ATOM, convert each field to its corresponding * atom. * 2. If type is anything else, convert each field from an ASCII number * to a 32-bit binary number. */ numFields = 1; for (p = string; *p != 0; p++) { if (isspace(UCHAR(*p))) { numFields++; } } propPtr = (long *) ckalloc((unsigned) numFields*sizeof(long)); /* * Convert the fields one-by-one. */ for (longPtr = propPtr, *numLongsPtr = 0, p = string; ; longPtr++, (*numLongsPtr)++) { while (isspace(UCHAR(*p))) { p++; } if (*p == 0) { break; } field = p; while ((*p != 0) && !isspace(UCHAR(*p))) { p++; } if (type == XA_ATOM) { int length; length = p - field; if (length > MAX_ATOM_NAME_LENGTH) { length = MAX_ATOM_NAME_LENGTH; } strncpy(atomName, field, (unsigned) length); atomName[length] = 0; *longPtr = (long) Tk_InternAtom(tkwin, atomName); } else { char *dummy; *longPtr = strtol(field, &dummy, 0); } } return propPtr;}/* *---------------------------------------------------------------------- * * SelCvtFromX -- * * Given an X property value, formatted as a collection of 32-bit * values according to "type" and the ICCCM conventions, convert * the value to a string suitable for manipulation by Tcl. This * procedure is the inverse of SelCvtToX. * * Results: * The return value is the string equivalent of "property". It is * malloc-ed and should be freed by the caller when no longer * needed. * * Side effects: * None. * *---------------------------------------------------------------------- */static char *SelCvtFromX(propPtr, numValues, type, tkwin) register long *propPtr; /* Property value from X. */ int numValues; /* Number of 32-bit values in property. */ Atom type; /* Type of property Should not be * XA_STRING (if so, don't bother calling * this procedure at all). */ Tk_Window tkwin; /* Window to use for atom conversion. */{ char *result; int resultSpace, curSize, fieldSize; char *atomName; /* * Convert each long in the property to a string value, which is * either the name of an atom (if type is XA_ATOM) or a hexadecimal * string. Make an initial guess about the size of the result, but * be prepared to enlarge the result if necessary. */ resultSpace = 12*numValues+1; curSize = 0; atomName = ""; /* Not needed, but eliminates compiler warning. */ result = (char *) ckalloc((unsigned) resultSpace); *result = '\0'; for ( ; numValues > 0; propPtr++, numValues--) { if (type == XA_ATOM) { atomName = Tk_GetAtomName(tkwin, (Atom) *propPtr); fieldSize = strlen(atomName) + 1; } else { fieldSize = 12; } if (curSize+fieldSize >= resultSpace) { char *newResult; resultSpace *= 2; if (curSize+fieldSize >= resultSpace) { resultSpace = curSize + fieldSize + 1; } newResult = (char *) ckalloc((unsigned) resultSpace); strncpy(newResult, result, (unsigned) curSize); ckfree(result); result = newResult; } if (curSize != 0) { result[curSize] = ' '; curSize++; } if (type == XA_ATOM) { strcpy(result+curSize, atomName); } else { sprintf(result+curSize, "0x%x", (unsigned int) *propPtr); } curSize += strlen(result+curSize); } return result;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -