+void WM_DestroyWindow(tWindow *Window)
+{
+ // TODO: Lock window and flag as invalid
+
+ // - Remove from render tree
+ {
+ // TODO: Lock render tree?
+ tWindow *prev = Window->PrevSibling;
+ tWindow *next = Window->NextSibling;
+ if(prev)
+ prev->NextSibling = next;
+ else
+ Window->Parent->FirstChild = next;
+ if(next)
+ next->PrevSibling = prev;
+ else
+ Window->Parent->LastChild = prev;
+ }
+ // - Full invalidate
+ WM_Invalidate(Window, 0);
+ Window->Parent->Flags &= ~WINFLAG_CLEAN; // Mark parent as unclean, forcing redraw
+
+ // - Remove from inheritance tree?
+
+ // - Clean up render children
+ {
+ // Lock should not be needed
+ tWindow *win, *next;
+ for( win = Window->FirstChild; win; win = next )
+ {
+ next = win->NextSibling;
+ ASSERT(Window->FirstChild->Parent == Window);
+ WM_DestroyWindow(win);
+ }
+ }
+
+ // - Clean up inheriting children?
+
+ // - Tell renderer to clean up
+ if( Window->Renderer->DestroyWindow )
+ Window->Renderer->DestroyWindow(Window);
+ else
+ _SysDebug("WARN: Renderer '%s' does not have a destroy function", Window->Renderer->Name);
+
+ // - Tell client to clean up
+ WM_SendMessage(NULL, Window, WNDMSG_DESTROY, 0, NULL);
+
+ // - Clean up render cache and window structure
+ free(Window->Title);
+ free(Window->RenderBuffer);
+ free(Window);
+ IPC_int_SetWindow(Window->Client, Window->ID, NULL);
+}
+
+tWindow *WM_GetWindowByID(tWindow *Requester, uint32_t ID)
+{
+ return IPC_int_GetWindow(Requester->Client, ID);
+}
+