void TkpClaimFocus( TkWindow *topLevelPtr, /* Top-level window containing desired focus * window; should be embedded. */ int force) /* One means that the container should claim * the focus if it doesn't currently have * it. */ { XEvent event; Container *containerPtr; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!(topLevelPtr->flags & TK_EMBEDDED)) { return; } for (containerPtr = tsdPtr->firstContainerPtr; containerPtr->embeddedPtr != topLevelPtr; containerPtr = containerPtr->nextPtr) { /* Empty loop body. */ } event.xfocus.type = FocusIn; event.xfocus.serial = LastKnownRequestProcessed(topLevelPtr->display); event.xfocus.send_event = 1; event.xfocus.display = topLevelPtr->display; event.xfocus.window = containerPtr->parent; event.xfocus.mode = EMBEDDED_APP_WANTS_FOCUS; event.xfocus.detail = force; XSendEvent(event.xfocus.display, event.xfocus.window, False, 0, &event); }
Tk_Style Tk_GetStyle( Tcl_Interp *interp, /* Interp for error return. */ const char *name) /* Name of the style to retrieve. NULL or empty * means the default system style. */ { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; Style *stylePtr; /* * Search for a corresponding entry in the style table. */ entryPtr = Tcl_FindHashEntry(&tsdPtr->styleTable, (name!=NULL?name:"")); if (entryPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "style \"%s\" doesn't exist", name)); Tcl_SetErrorCode(interp, "TK", "LOOKUP", "STYLE", name, NULL); } return (Tk_Style) NULL; } stylePtr = Tcl_GetHashValue(entryPtr); return (Tk_Style) stylePtr; }
static void UpdateCursor( TkWindow *winPtr) { Cursor cursor = None; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * A window inherits its cursor from its parent if it doesn't have one of * its own. Top level windows inherit the default cursor. */ tsdPtr->cursorWinPtr = winPtr; while (winPtr != NULL) { if (winPtr->atts.cursor != None) { cursor = winPtr->atts.cursor; break; } else if (winPtr->flags & TK_TOP_HIERARCHY) { break; } winPtr = winPtr->parentPtr; } TkpSetCursor((TkpCursor) cursor); }
void Tcl_SetStartupScript( Tcl_Obj *path, /* Filesystem path of startup script file */ const char *encoding) /* Encoding of the data in that file */ { StartupScript *scriptPtr = Tcl_GetThreadData(&startupScriptKey, (int) sizeof(StartupScript)); Tcl_Obj *newEncoding = NULL; if (encoding != NULL) { newEncoding = Tcl_NewStringObj(encoding, -1); } if (scriptPtr->path != NULL) { Tcl_DecrRefCount(scriptPtr->path); } scriptPtr->path = path; if (scriptPtr->path != NULL) { Tcl_IncrRefCount(scriptPtr->path); } if (scriptPtr->encoding != NULL) { Tcl_DecrRefCount(scriptPtr->encoding); } scriptPtr->encoding = newEncoding; if (scriptPtr->encoding != NULL) { Tcl_IncrRefCount(scriptPtr->encoding); } }
void Tk_MacOSXSetupTkNotifier() { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { /* HACK ALERT: There is a bug in Jaguar where when it goes to make * the event queue for the Main Event Loop, it stores the Current * event loop rather than the Main Event Loop in the Queue structure. * So we have to make sure that the Main Event Queue gets set up on * the main thread. Calling GetMainEventQueue will force this to * happen. */ GetMainEventQueue(); tsdPtr->initialized = 1; /* Install Carbon events event source in main event loop thread. */ if (GetCurrentEventLoop() == GetMainEventLoop()) { if (!pthread_main_np()) { /* * Panic if the Carbon main event loop thread (i.e. the * thread where HIToolbox was first loaded) is not the * main application thread, as Carbon does not support * this properly. */ Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s", "first [load] of TkAqua has to occur in the main thread!"); } Tcl_CreateEventSource(CarbonEventsSetupProc, CarbonEventsCheckProc, GetMainEventQueue()); TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); } } }
void TkOptionDeadWindow( register TkWindow *winPtr) /* Window to be cleaned up. */ { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * If this window is in the option stacks, then clear the stacks. * * XXX: OptionThreadExitProc will be invoked before DeleteWindowsExitProc * XXX: if it is thread-specific (which it should be), invalidating the * XXX: tsd. Tk shutdown needs to be verified to handle this correctly. */ if (tsdPtr->initialized && (winPtr->optionLevel != -1)) { int i; for (i = 1; i <= tsdPtr->curLevel; i++) { tsdPtr->levels[i].winPtr->optionLevel = -1; } tsdPtr->curLevel = -1; tsdPtr->cachedWindow = NULL; } /* * If this window was a main window, then delete its option database. */ if ((winPtr->mainPtr != NULL) && (winPtr->mainPtr->winPtr == winPtr) && (winPtr->mainPtr->optionRootPtr != NULL)) { ClearOptionTree(winPtr->mainPtr->optionRootPtr); winPtr->mainPtr->optionRootPtr = NULL; } }
int XGrabPointer( Display *display, Window grab_window, Bool owner_events, unsigned int event_mask, int pointer_mode, int keyboard_mode, Window confine_to, Cursor cursor, Time time) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); display->request++; tsdPtr->grabWinPtr = (TkWindow *) Tk_IdToWindow(display, grab_window); tsdPtr->restrictWinPtr = NULL; TkpSetCapture(tsdPtr->grabWinPtr); if (TkPositionInTree(tsdPtr->lastWinPtr, tsdPtr->grabWinPtr) != TK_GRAB_IN_TREE) { UpdateCursor(tsdPtr->grabWinPtr); } return GrabSuccess; }
TkSelInProgress * TkSelGetInProgress(void) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return tsdPtr->pendingPtr; }
Tcl_HashTable * TkGetBitmapPredefTable(void) { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); return &tsdPtr->predefBitmapTable; }
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; } }
void TkUnixSetXftClipRegion( TkRegion clipRegion) /* The clipping region to install. */ { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->clipRegion = (Region) clipRegion; }
/* *---------------------------------------------------------------------- * * TkSelSetInProgress -- * * This function is used to set the thread-local list of pending * searches. It is required because the pending list is kept in thread * local storage. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TkSelSetInProgress( TkSelInProgress *pendingPtr) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->pendingPtr = pendingPtr; }
static int PreprocessMenu( TkMenu *menuPtr) { int index, result, finished; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_Preserve((ClientData) menuPtr); /* * First, let's process the post command on ourselves. If this command * destroys this menu, or if there was an error, we are done. */ result = TkPostCommand(menuPtr); if ((result != TCL_OK) || (menuPtr->tkwin == NULL)) { goto done; } /* * Now, we go through structure and process all of the commands. Since the * structure is changing, we stop after we do one command, and start over. * When we get through without doing any, we are done. */ do { finished = 1; for (index = 0; index < menuPtr->numEntries; index++) { register TkMenuEntry *entryPtr = menuPtr->entries[index]; if ((entryPtr->type == CASCADE_ENTRY) && (entryPtr->namePtr != NULL) && (entryPtr->childMenuRefPtr != NULL) && (entryPtr->childMenuRefPtr->menuPtr != NULL)) { TkMenu *cascadeMenuPtr = entryPtr->childMenuRefPtr->menuPtr; if (cascadeMenuPtr->postCommandGeneration != tsdPtr->postCommandGeneration) { cascadeMenuPtr->postCommandGeneration = tsdPtr->postCommandGeneration; result = PreprocessMenu(cascadeMenuPtr); if (result != TCL_OK) { goto done; } finished = 0; break; } } } } while (!finished); done: Tcl_Release((ClientData) menuPtr); return result; }
int TkpTestembedCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { int all; Container *containerPtr; Tcl_DString dString; char buffer[50]; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if ((argc > 1) && (strcmp(argv[1], "all") == 0)) { all = 1; } else { all = 0; } Tcl_DStringInit(&dString); for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { Tcl_DStringStartSublist(&dString); if (containerPtr->parent == None) { Tcl_DStringAppendElement(&dString, ""); } else if (all) { sprintf(buffer, "0x%x", (int) containerPtr->parent); Tcl_DStringAppendElement(&dString, buffer); } else { Tcl_DStringAppendElement(&dString, "XXX"); } if (containerPtr->parentPtr == NULL) { Tcl_DStringAppendElement(&dString, ""); } else { Tcl_DStringAppendElement(&dString, containerPtr->parentPtr->pathName); } if (containerPtr->wrapper == None) { Tcl_DStringAppendElement(&dString, ""); } else if (all) { sprintf(buffer, "0x%x", (int) containerPtr->wrapper); Tcl_DStringAppendElement(&dString, buffer); } else { Tcl_DStringAppendElement(&dString, "XXX"); } if (containerPtr->embeddedPtr == NULL) { Tcl_DStringAppendElement(&dString, ""); } else { Tcl_DStringAppendElement(&dString, containerPtr->embeddedPtr->pathName); } Tcl_DStringEndSublist(&dString); } Tcl_DStringResult(interp, &dString); return TCL_OK; }
static void DisplayExitHandler( ClientData clientData) /* Not used. */ { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL); tsdPtr->initialized = 0; }
static void FreeUidThreadExitProc( ClientData clientData) /* Not used. */ { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_DeleteHashTable(&tsdPtr->uidTable); tsdPtr->initialized = 0; }
int TkPreprocessMenu( TkMenu *menuPtr) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->postCommandGeneration++; menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration; return PreprocessMenu(menuPtr); }
static POINT * ConvertPoints( XPoint *points, int npoints, int mode, /* CoordModeOrigin or CoordModePrevious. */ RECT *bbox) /* Bounding box of points. */ { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); int i; /* * To avoid paying the cost of a malloc on every drawing routine, we reuse * the last array if it is large enough. */ if (npoints > tsdPtr->nWinPoints) { if (tsdPtr->winPoints != NULL) { ckfree((char *) tsdPtr->winPoints); } tsdPtr->winPoints = (POINT *) ckalloc(sizeof(POINT) * npoints); if (tsdPtr->winPoints == NULL) { tsdPtr->nWinPoints = -1; return NULL; } tsdPtr->nWinPoints = npoints; } bbox->left = bbox->right = points[0].x; bbox->top = bbox->bottom = points[0].y; if (mode == CoordModeOrigin) { for (i = 0; i < npoints; i++) { tsdPtr->winPoints[i].x = points[i].x; tsdPtr->winPoints[i].y = points[i].y; bbox->left = MIN(bbox->left, tsdPtr->winPoints[i].x); bbox->right = MAX(bbox->right, tsdPtr->winPoints[i].x); bbox->top = MIN(bbox->top, tsdPtr->winPoints[i].y); bbox->bottom = MAX(bbox->bottom, tsdPtr->winPoints[i].y); } } else { tsdPtr->winPoints[0].x = points[0].x; tsdPtr->winPoints[0].y = points[0].y; for (i = 1; i < npoints; i++) { tsdPtr->winPoints[i].x = tsdPtr->winPoints[i-1].x + points[i].x; tsdPtr->winPoints[i].y = tsdPtr->winPoints[i-1].y + points[i].y; bbox->left = MIN(bbox->left, tsdPtr->winPoints[i].x); bbox->right = MAX(bbox->right, tsdPtr->winPoints[i].x); bbox->top = MIN(bbox->top, tsdPtr->winPoints[i].y); bbox->bottom = MAX(bbox->bottom, tsdPtr->winPoints[i].y); } } return tsdPtr->winPoints; }
static ThreadSpecificData * GetTypeCache() { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->doubleTypePtr == NULL) { tsdPtr->doubleTypePtr = Tcl_GetObjType("double"); tsdPtr->intTypePtr = Tcl_GetObjType("int"); } return tsdPtr; }
void TkCreateXEventSource(void) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { tsdPtr->initialized = 1; Tcl_CreateEventSource(DisplaySetupProc, DisplayCheckProc, NULL); TkCreateExitHandler(DisplayExitHandler, NULL); } }
void TkpRedirectKeyEvent( TkWindow *winPtr, /* Window to which the event was originally * reported. */ XEvent *eventPtr) /* X event to redirect (should be KeyPress or * KeyRelease). */ { Container *containerPtr; Window saved; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * First, find the top-level window corresponding to winPtr. */ while (1) { if (winPtr == NULL) { /* * This window is being deleted. This is too confusing a case to * handle so discard the event. */ return; } if (winPtr->flags & TK_TOP_HIERARCHY) { break; } winPtr = winPtr->parentPtr; } if (winPtr->flags & TK_EMBEDDED) { /* * This application is embedded. If we got a key event without * officially having the focus, it means that the focus is really in * the container, but the mouse was over the embedded application. * Send the event back to the container. */ for (containerPtr = tsdPtr->firstContainerPtr; containerPtr->embeddedPtr != winPtr; containerPtr = containerPtr->nextPtr) { /* Empty loop body. */ } saved = eventPtr->xkey.window; eventPtr->xkey.window = containerPtr->parent; XSendEvent(eventPtr->xkey.display, eventPtr->xkey.window, False, KeyPressMask|KeyReleaseMask, eventPtr); eventPtr->xkey.window = saved; } }
void XUngrabPointer( Display *display, Time time) { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); display->request++; tsdPtr->grabWinPtr = NULL; tsdPtr->restrictWinPtr = NULL; TkpSetCapture(NULL); UpdateCursor(tsdPtr->lastWinPtr); }
void TkStylePkgFree( TkMainInfo *mainPtr) /* The application being deleted. */ { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashSearch search; Tcl_HashEntry *entryPtr; StyleEngine *enginePtr; int i; tsdPtr->nbInit--; if (tsdPtr->nbInit != 0) { return; } /* * Free styles. */ entryPtr = Tcl_FirstHashEntry(&tsdPtr->styleTable, &search); while (entryPtr != NULL) { ckfree(Tcl_GetHashValue(entryPtr)); entryPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&tsdPtr->styleTable); /* * Free engines. */ entryPtr = Tcl_FirstHashEntry(&tsdPtr->engineTable, &search); while (entryPtr != NULL) { enginePtr = Tcl_GetHashValue(entryPtr); FreeStyleEngine(enginePtr); ckfree(enginePtr); entryPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&tsdPtr->engineTable); /* * Free elements. */ for (i = 0; i < tsdPtr->nbElements; i++) { FreeElement(tsdPtr->elements+i); } Tcl_DeleteHashTable(&tsdPtr->elementTable); ckfree(tsdPtr->elements); }
void TkWinCleanupContainerList(void) { Container *nextPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (; tsdPtr->firstContainerPtr != (Container *) NULL; tsdPtr->firstContainerPtr = nextPtr) { nextPtr = tsdPtr->firstContainerPtr->nextPtr; ckfree((char *) tsdPtr->firstContainerPtr); } tsdPtr->firstContainerPtr = (Container *) NULL; }
void XDefineCursor( Display *display, Window w, Cursor cursor) { TkWindow *winPtr = (TkWindow *)Tk_IdToWindow(display, w); ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->cursorWinPtr == winPtr) { UpdateCursor(winPtr); } display->request++; }
int Tk_GetElementId( const char *name) /* Name of the element. */ { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr; int genericId = -1; char *dot; /* * Find the element Id. */ entryPtr = Tcl_FindHashEntry(&tsdPtr->elementTable, name); if (entryPtr) { return PTR2INT(Tcl_GetHashValue(entryPtr)); } /* * Element not found. If the given name was derived, then first search for * the generic element. If found, create the new derived element. */ dot = strchr(name, '.'); if (!dot) { return -1; } genericId = Tk_GetElementId(dot+1); if (genericId == -1) { return -1; } if (!tsdPtr->elements[genericId].created) { /* * The generic element was created implicitly and thus has no real * existence. */ return -1; } else { /* * The generic element was created explicitly. Create the derived * element. */ return CreateElement(name, 1); } }
HWND Tk_GetEmbeddedHWnd( TkWindow *winPtr) { Container *containerPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (containerPtr = tsdPtr->firstContainerPtr; containerPtr != NULL; containerPtr = containerPtr->nextPtr) { if (containerPtr->parentPtr == winPtr) { return containerPtr->embeddedHWnd; } } return NULL; }
static void OptionInit( register TkMainInfo *mainPtr) /* Top-level information about window that * isn't initialized yet. */ { int i; Tcl_Interp *interp; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Element *defaultMatchPtr = &tsdPtr->defaultMatch; /* * First, once-only initialization. */ if (tsdPtr->initialized == 0) { tsdPtr->initialized = 1; tsdPtr->cachedWindow = NULL; tsdPtr->numLevels = 5; tsdPtr->curLevel = -1; tsdPtr->serial = 0; tsdPtr->levels = (StackLevel *) ckalloc((unsigned) (5*sizeof(StackLevel))); for (i = 0; i < NUM_STACKS; i++) { tsdPtr->stacks[i] = NewArray(10); tsdPtr->levels[0].bases[i] = 0; } defaultMatchPtr->nameUid = NULL; defaultMatchPtr->child.valueUid = NULL; defaultMatchPtr->priority = -1; defaultMatchPtr->flags = 0; Tcl_CreateThreadExitHandler(OptionThreadExitProc, NULL); } /* * Then, per-main-window initialization. Create and delete dummy * interpreter for message logging. */ mainPtr->optionRootPtr = NewArray(20); interp = Tcl_CreateInterp(); GetDefaultOptions(interp, mainPtr->winPtr); Tcl_DeleteInterp(interp); }
CONST char * Tk_NameOfColor( XColor *colorPtr) /* Color whose name is desired. */ { register TkColor *tkColPtr = (TkColor *) colorPtr; if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) { return tkColPtr->hashPtr->key.string; } else { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red, colorPtr->green, colorPtr->blue); return tsdPtr->rgbString; } }
static void EmbedWindowDeleted( TkWindow *winPtr) /* Tk's information about window that was * deleted. */ { Container *containerPtr, *prevPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * Find the Container structure for this window work. Delete the * information about the embedded application and free the container's * record. The main container may be null. [Bug #476176] */ prevPtr = NULL; containerPtr = tsdPtr->firstContainerPtr; if (containerPtr == NULL) return; while (1) { if (containerPtr->embeddedPtr == winPtr) { containerPtr->embeddedHWnd = NULL; containerPtr->embeddedPtr = NULL; break; } if (containerPtr->parentPtr == winPtr) { SendMessage(containerPtr->embeddedHWnd, WM_CLOSE, 0, 0); containerPtr->parentPtr = NULL; containerPtr->embeddedPtr = NULL; break; } prevPtr = containerPtr; containerPtr = containerPtr->nextPtr; if (containerPtr == NULL) { return; } } if ((containerPtr->embeddedPtr == NULL) && (containerPtr->parentPtr == NULL)) { if (prevPtr == NULL) { tsdPtr->firstContainerPtr = containerPtr->nextPtr; } else { prevPtr->nextPtr = containerPtr->nextPtr; } ckfree((char *) containerPtr); } }