static void imfsample_event_proc(ClientData cldata, XEvent *eventPtr) { Imfsample *imfsample = (Imfsample *) cldata; if (eventPtr->type == Expose) { if (!imfsample->update_pending) { Tcl_DoWhenIdle(imfsample_display, cldata); imfsample->update_pending = 1; } } else if (eventPtr->type == ConfigureNotify) { if (!imfsample->update_pending) { Tcl_DoWhenIdle(imfsample_display, cldata); imfsample->update_pending = 1; } } else if (eventPtr->type == DestroyNotify) { if (imfsample->tkwin != NULL) { imfsample->tkwin = NULL; Tcl_DeleteCommand(imfsample->interp, Tcl_GetCommandName(imfsample->interp, imfsample->widgetCmd)); } if (imfsample->update_pending) { Tcl_CancelIdleCall(imfsample_display, cldata); } Tcl_EventuallyFree(cldata, imfsample_destroy); } }
void TkSelDeadWindow( register TkWindow *winPtr) /* Window that's being deleted. */ { register TkSelHandler *selPtr; register TkSelInProgress *ipPtr; TkSelectionInfo *infoPtr, *prevPtr, *nextPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * While deleting all the handlers, be careful to check whether * ConvertSelection or TkSelPropProc are about to process one of the * deleted handlers. */ while (winPtr->selHandlerList != NULL) { selPtr = winPtr->selHandlerList; winPtr->selHandlerList = selPtr->nextPtr; for (ipPtr = tsdPtr->pendingPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) { if (ipPtr->selPtr == selPtr) { ipPtr->selPtr = NULL; } } if (selPtr->proc == HandleTclCommand) { /* * Mark the CommandInfo as deleted and free it when we can. */ ((CommandInfo *) selPtr->clientData)->interp = NULL; Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC); } ckfree((char *) selPtr); } /* * Remove selections owned by window being deleted. */ for (infoPtr = winPtr->dispPtr->selectionInfoPtr, prevPtr = NULL; infoPtr != NULL; infoPtr = nextPtr) { nextPtr = infoPtr->nextPtr; if (infoPtr->owner == (Tk_Window) winPtr) { if (infoPtr->clearProc == LostSelection) { ckfree((char *) infoPtr->clearData); } ckfree((char *) infoPtr); infoPtr = prevPtr; if (prevPtr == NULL) { winPtr->dispPtr->selectionInfoPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } } prevPtr = infoPtr; } }
static void BusyEventProc( ClientData clientData, /* Busy window record */ XEvent *eventPtr) /* Event which triggered call to routine */ { Busy *busyPtr = clientData; if (eventPtr->type == DestroyNotify) { busyPtr->tkBusy = NULL; Tcl_EventuallyFree(busyPtr, DestroyBusy); } }
/* ARGSUSED */ static void BusyCustodyProc( ClientData clientData, /* Information about the busy window. */ Tk_Window tkwin) /* Not used. */ { Busy *busyPtr = clientData; Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc, busyPtr); TkpHideBusyWindow(busyPtr); busyPtr->tkBusy = NULL; Tcl_EventuallyFree(busyPtr, DestroyBusy); }
static void EventuallyDeleteImage( ImageMaster *masterPtr, /* Pointer to main data structure for image. */ int forgetImageHashNow) /* Flag to say whether the hash table is about * to vanish. */ { if (forgetImageHashNow) { masterPtr->hPtr = NULL; } if (!masterPtr->deleted) { masterPtr->deleted = 1; Tcl_EventuallyFree(masterPtr, (Tcl_FreeProc *) DeleteImage); } }
void TnmSnmpDeleteSession(TnmSnmp *session) { TnmSnmpRequest **rPtrPtr; if (! session) return; rPtrPtr = &queueHead; while (*rPtrPtr) { if ((*rPtrPtr)->session == session) { TnmSnmpRequest *request = *rPtrPtr; *rPtrPtr = (*rPtrPtr)->nextPtr; if (request->timer) { Tcl_DeleteTimerHandler(request->timer); } Tcl_EventuallyFree((ClientData) request, RequestDestroyProc); } else { rPtrPtr = &(*rPtrPtr)->nextPtr; } } Tcl_EventuallyFree((ClientData) session, SessionDestroyProc); }
static void TcpServerCloseProc( ClientData callbackData) /* The data passed in the call to * Tcl_CreateCloseHandler. */ { AcceptCallback *acceptCallbackPtr = (AcceptCallback *) callbackData; /* The actual data. */ if (acceptCallbackPtr->interp != NULL) { UnregisterTcpServerInterpCleanupProc(acceptCallbackPtr->interp, acceptCallbackPtr); } Tcl_EventuallyFree(acceptCallbackPtr->script, TCL_DYNAMIC); ckfree((char *) acceptCallbackPtr); }
static void DestroyMenuButton( char *memPtr) /* Info about button widget. */ { register TkMenuButton *mbPtr = (TkMenuButton *) memPtr; TkpDestroyMenuButton(mbPtr); if (mbPtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(TkpDisplayMenuButton, mbPtr); } /* * Free up all the stuff that requires special handling, then let * Tk_FreeOptions handle all the standard option-related stuff. */ Tcl_DeleteCommandFromToken(mbPtr->interp, mbPtr->widgetCmd); if (mbPtr->textVarName != NULL) { Tcl_UntraceVar(mbPtr->interp, mbPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuButtonTextVarProc, mbPtr); } if (mbPtr->image != NULL) { Tk_FreeImage(mbPtr->image); } if (mbPtr->normalTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->normalTextGC); } if (mbPtr->activeTextGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->activeTextGC); } if (mbPtr->disabledGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->disabledGC); } if (mbPtr->stippleGC != None) { Tk_FreeGC(mbPtr->display, mbPtr->stippleGC); } if (mbPtr->gray != None) { Tk_FreeBitmap(mbPtr->display, mbPtr->gray); } if (mbPtr->textLayout != NULL) { Tk_FreeTextLayout(mbPtr->textLayout); } Tk_FreeConfigOptions((char *) mbPtr, mbPtr->optionTable, mbPtr->tkwin); mbPtr->tkwin = NULL; Tcl_EventuallyFree(mbPtr, TCL_DYNAMIC); }
/* *------------------------------------------------------------------- * * TlsCloseProc -- * * This procedure is invoked by the generic IO level to perform * channel-type-specific cleanup when a SSL socket based channel * is closed. * * Note: we leave the underlying socket alone, is this right? * * Results: * 0 if successful, the value of Tcl_GetErrno() if failed. * * Side effects: * Closes the socket of the channel. * *------------------------------------------------------------------- */ static int TlsCloseProc(ClientData instanceData, /* The socket to close. */ Tcl_Interp *interp) /* For error reporting - unused. */ { State *statePtr = (State *) instanceData; dprintf(stderr,"\nTlsCloseProc(0x%x)", (unsigned int) statePtr); if (channelTypeVersion == TLS_CHANNEL_VERSION_1) { /* * Remove event handler to underlying channel, this could * be because we are closing for real, or being "unstacked". */ Tcl_DeleteChannelHandler(Tls_GetParent(statePtr), TlsChannelHandler, (ClientData) statePtr); } Tls_Clean(statePtr); Tcl_EventuallyFree((ClientData)statePtr, Tls_Free); return TCL_OK; }
void TkpDestroyScale( TkScale *scalePtr) { Tcl_EventuallyFree(scalePtr, TCL_DYNAMIC); }
static void MasterStructureProc( ClientData clientData, /* Pointer to Master structure for window * referred to by eventPtr. */ XEvent *eventPtr) /* Describes what just happened. */ { register Master *masterPtr = clientData; register Slave *slavePtr, *nextPtr; TkDisplay *dispPtr = ((TkWindow *) masterPtr->tkwin)->dispPtr; switch (eventPtr->type) { case ConfigureNotify: if ((masterPtr->slavePtr != NULL) && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, masterPtr); } return; case DestroyNotify: for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { slavePtr->masterPtr = NULL; nextPtr = slavePtr->nextPtr; slavePtr->nextPtr = NULL; } Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable, (char *) masterPtr->tkwin)); if (masterPtr->flags & PARENT_RECONFIG_PENDING) { Tcl_CancelIdleCall(RecomputePlacement, masterPtr); } masterPtr->tkwin = NULL; if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } Tcl_EventuallyFree(masterPtr, TCL_DYNAMIC); return; case MapNotify: /* * When a master gets mapped, must redo the geometry computation so * that all of its slaves get remapped. */ if ((masterPtr->slavePtr != NULL) && !(masterPtr->flags & PARENT_RECONFIG_PENDING)) { masterPtr->flags |= PARENT_RECONFIG_PENDING; Tcl_DoWhenIdle(RecomputePlacement, masterPtr); } return; case UnmapNotify: /* * Unmap all of the slaves when the master gets unmapped, so that they * don't keep redisplaying themselves. */ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; slavePtr = slavePtr->nextPtr) { Tk_UnmapWindow(slavePtr->tkwin); } return; } }
void Tk_DeleteSelHandler( 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; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * 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 = tsdPtr->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 ((target == XA_STRING) && (winPtr->dispPtr->utf8Atom != (Atom) NULL)) { /* * If the user asked for a STRING handler and we understand * UTF8_STRING, we may have implicitly created a UTF8_STRING handler * for them. Look for it and delete it as necessary. */ TkSelHandler *utf8selPtr; target = winPtr->dispPtr->utf8Atom; for (utf8selPtr = winPtr->selHandlerList; utf8selPtr != NULL; utf8selPtr = utf8selPtr->nextPtr) { if ((utf8selPtr->selection == selection) && (utf8selPtr->target == target)) { break; } } if (utf8selPtr != NULL) { if ((utf8selPtr->format == target) && (utf8selPtr->proc == selPtr->proc) && (utf8selPtr->size == selPtr->size)) { /* * This recursive call is OK, because we've changed the value * of 'target'. */ Tk_DeleteSelHandler(tkwin, selection, target); } } } if (selPtr->proc == HandleTclCommand) { /* * Mark the CommandInfo as deleted and free it if we can. */ ((CommandInfo*)selPtr->clientData)->interp = NULL; Tcl_EventuallyFree(selPtr->clientData, TCL_DYNAMIC); } ckfree((char *) selPtr); }
int Tk_BusyObjCmd( ClientData clientData, /* Main window associated with interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window tkwin = clientData; Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable; Busy *busyPtr; Tcl_Obj *objPtr; int index, result = TCL_OK; static const char *const optionStrings[] = { "cget", "configure", "current", "forget", "hold", "status", NULL }; enum options { BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD, BUSY_STATUS }; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "options ?arg arg ...?"); return TCL_ERROR; } /* * [tk busy <window>] command shortcut. */ if (Tcl_GetString(objv[1])[0] == '.') { if (objc%2 == 1) { Tcl_WrongNumArgs(interp, 1, objv, "window ?option value ...?"); return TCL_ERROR; } return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2); } if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { case BUSY_CGET: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "window option"); return TCL_ERROR; } busyPtr = GetBusy(interp, busyTablePtr, objv[2]); if (busyPtr == NULL) { return TCL_ERROR; } Tcl_Preserve(busyPtr); objPtr = Tk_GetOptionValue(interp, (char *) busyPtr, busyPtr->optionTable, objv[3], busyPtr->tkBusy); if (objPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, objPtr); } Tcl_Release(busyPtr); return result; case BUSY_CONFIGURE: if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "window ?option? ?value ...?"); return TCL_ERROR; } busyPtr = GetBusy(interp, busyTablePtr, objv[2]); if (busyPtr == NULL) { return TCL_ERROR; } Tcl_Preserve(busyPtr); if (objc <= 4) { objPtr = Tk_GetOptionInfo(interp, (char *) busyPtr, busyPtr->optionTable, (objc == 4) ? objv[3] : NULL, busyPtr->tkBusy); if (objPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, objPtr); } } else { result = ConfigureBusy(interp, busyPtr, objc-3, objv+3); } Tcl_Release(busyPtr); return result; case BUSY_CURRENT: { Tcl_HashEntry *hPtr; Tcl_HashSearch cursor; const char *pattern = (objc == 3 ? Tcl_GetString(objv[2]) : NULL); objPtr = Tcl_NewObj(); for (hPtr = Tcl_FirstHashEntry(busyTablePtr, &cursor); hPtr != NULL; hPtr = Tcl_NextHashEntry(&cursor)) { busyPtr = Tcl_GetHashValue(hPtr); if (pattern == NULL || Tcl_StringMatch(Tk_PathName(busyPtr->tkRef), pattern)) { Tcl_ListObjAppendElement(interp, objPtr, TkNewWindowObj(busyPtr->tkRef)); } } Tcl_SetObjResult(interp, objPtr); return TCL_OK; } case BUSY_FORGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); return TCL_ERROR; } busyPtr = GetBusy(interp, busyTablePtr, objv[2]); if (busyPtr == NULL) { return TCL_ERROR; } TkpHideBusyWindow(busyPtr); Tcl_EventuallyFree(busyPtr, DestroyBusy); return TCL_OK; case BUSY_HOLD: if (objc < 3 || objc%2 != 1) { Tcl_WrongNumArgs(interp, 2, objv, "window ?option value ...?"); return TCL_ERROR; } return HoldBusy(busyTablePtr, interp, objv[2], objc-3, objv+3); case BUSY_STATUS: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "window"); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewBooleanObj( GetBusy(interp, busyTablePtr, objv[2]) != NULL)); return TCL_OK; } Tcl_Panic("unhandled option: %d", index); return TCL_ERROR; /* Unreachable */ }
static void RefWinEventProc( ClientData clientData, /* Busy window record */ register XEvent *eventPtr) /* Event which triggered call to routine */ { register Busy *busyPtr = clientData; switch (eventPtr->type) { case ReparentNotify: case DestroyNotify: /* * Arrange for the busy structure to be removed at a proper time. */ Tcl_EventuallyFree(busyPtr, DestroyBusy); break; case ConfigureNotify: if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) || (busyPtr->height != Tk_Height(busyPtr->tkRef)) || (busyPtr->x != Tk_X(busyPtr->tkRef)) || (busyPtr->y != Tk_Y(busyPtr->tkRef))) { int x, y; busyPtr->width = Tk_Width(busyPtr->tkRef); busyPtr->height = Tk_Height(busyPtr->tkRef); busyPtr->x = Tk_X(busyPtr->tkRef); busyPtr->y = Tk_Y(busyPtr->tkRef); x = y = 0; if (busyPtr->tkParent != busyPtr->tkRef) { Tk_Window tkwin; for (tkwin = busyPtr->tkRef; (tkwin != NULL) && (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) { if (tkwin == busyPtr->tkParent) { break; } x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; } } if (busyPtr->tkBusy != NULL) { Tk_MoveResizeWindow(busyPtr->tkBusy, x, y, busyPtr->width, busyPtr->height); TkpShowBusyWindow(busyPtr); } } break; case MapNotify: if (busyPtr->tkParent != busyPtr->tkRef) { TkpShowBusyWindow(busyPtr); } break; case UnmapNotify: if (busyPtr->tkParent != busyPtr->tkRef) { TkpHideBusyWindow(busyPtr); } break; } }
void TnmSnmpDeleteRequest(TnmSnmpRequest *request) { TnmSnmpRequest *rPtr, **rPtrPtr; TnmSnmp *session; /* * Check whether the request still exists. It may have been * removed because the session for this request has been * destroyed during callback processing. */ for (rPtr = queueHead; rPtr; rPtr = rPtr->nextPtr) { if (rPtr == request) break; } if (! rPtr) return; /* * Check whether the session is still in the session list. * We sometimes get called when the session has already been * destroyed as a side effect of evaluating callbacks. */ for (session = tnmSnmpList; session; session = session->nextPtr) { if (session == request->session) break; } if (session) { if (request->sends) { session->active--; } else { session->waiting--; } } /* * Remove the request from the list of outstanding requests. * and free the resources allocated for this request. */ rPtrPtr = &queueHead; while (*rPtrPtr && *rPtrPtr != request) { rPtrPtr = &(*rPtrPtr)->nextPtr; } if (*rPtrPtr) { *rPtrPtr = request->nextPtr; if (request->timer) { Tcl_DeleteTimerHandler(request->timer); request->timer = NULL; } Tcl_EventuallyFree((ClientData) request, RequestDestroyProc); } /* * Update the request queue. This will activate async requests * that have been queued because of the window size. */ if (session) { TnmSnmpQueueRequest(session, NULL); } }
/* * Remove a connection Id from the hash table and * close all portals the user forgot. */ int PgDelConnectionId(DRIVER_DEL_PROTO) { Tcl_HashEntry *entry; Tcl_HashSearch hsearch; Pg_ConnectionId *connid; Pg_TclNotifies *notifies; int i; connid = (Pg_ConnectionId *) cData; for (i = 0; i < connid->res_max; i++) { if (connid->results[i]) PQclear(connid->results[i]); } ckfree((void *) connid->results); /* Release associated notify info */ while ((notifies = connid->notify_list) != NULL) { connid->notify_list = notifies->next; for (entry = Tcl_FirstHashEntry(¬ifies->notify_hash, &hsearch); entry != NULL; entry = Tcl_NextHashEntry(&hsearch)) ckfree((char *) Tcl_GetHashValue(entry)); Tcl_DeleteHashTable(¬ifies->notify_hash); if (notifies->conn_loss_cmd) ckfree((void *) notifies->conn_loss_cmd); if (notifies->interp) Tcl_DontCallWhenDeleted(notifies->interp, PgNotifyInterpDelete, (ClientData) notifies); ckfree((void *) notifies); } /* * Turn off the Tcl event source for this connection, and delete any * pending notify and connection-loss events. */ PgStopNotifyEventSource(connid, true); /* Close the libpq connection too */ PQfinish(connid->conn); connid->conn = NULL; /* * Kill the notifier channel, too. We must not do this until after * we've closed the libpq connection, because Tcl will try to close * the socket itself! * * XXX Unfortunately, while this works fine if we are closing due to * explicit pg_disconnect, all Tcl versions through 8.4.1 dump core if * we try to do it during interpreter shutdown. Not clear why. For * now, we kill the channel during pg_disconnect, but during interp * shutdown we just accept leakage of the (fairly small) amount of * memory taken for the channel state representation. (Note we are not * leaking a socket, since libpq closed that already.) We tell the * difference between pg_disconnect and interpreter shutdown by * testing for interp != NULL, which is an undocumented but apparently * safe way to tell. */ #if TCL_MAJOR_VERSION >= 8 if (connid->notifier_channel != NULL && interp != NULL) Tcl_UnregisterChannel(NULL, connid->notifier_channel); #endif /* * We must use Tcl_EventuallyFree because we don't want the connid * struct to vanish instantly if Pg_Notify_EventProc is active for it. * (Otherwise, closing the connection from inside a pg_listen callback * could lead to coredump.) Pg_Notify_EventProc can detect that the * connection has been deleted from under it by checking connid->conn. */ Tcl_EventuallyFree((ClientData) connid, TCL_DYNAMIC); return 0; }