2 * Acess2 Window Manager v3
3 * - By John Hodge (thePowersGang)
6 * - Window manager core
9 #include <wm_renderer.h>
15 tWMRenderer *gpWM_Renderers;
16 tWindow *gpWM_RootWindow;
19 void WM_Initialise(void)
21 WM_CreateWindow(NULL, 0x0088FF, "Background");
22 gpWM_RootWindow->W = giScreenWidth;
23 gpWM_RootWindow->H = giScreenHeight;
24 gpWM_RootWindow->Flags = WINFLAG_SHOW;
27 void WM_RegisterRenderer(tWMRenderer *Renderer)
29 // TODO: Catch out duplicates
30 Renderer->Next = gpWM_Renderers;
31 gpWM_Renderers = Renderer;
35 tWindow *WM_CreateWindow(tWindow *Parent, int RendererArg, const char *RendererName)
37 tWMRenderer *renderer;
41 for( renderer = gpWM_Renderers; renderer; renderer = renderer->Next )
43 if(strcmp(RendererName, renderer->Name) == 0)
50 Parent = gpWM_RootWindow;
52 // - Call create window function
53 ret = renderer->CreateWindow(RendererArg);
55 ret->Renderer = renderer;
56 ret->Flags = WINFLAG_CLEAN; // Note, not acutally clean, but it makes invaidate work
62 Parent->LastChild->NextSibling = ret;
64 Parent->FirstChild = ret;
65 ret->PrevSibling = Parent->LastChild;
66 Parent->LastChild = ret;
70 gpWM_RootWindow = ret;
77 tWindow *WM_CreateWindowStruct(size_t ExtraSize)
81 ret = calloc( sizeof(tWindow) + ExtraSize, 1 );
82 ret->RendererInfo = ret + 1; // Get end of tWindow
87 void WM_ShowWindow(tWindow *Window, int bShow)
89 // TODO: Message window
91 Window->Flags |= WINFLAG_SHOW;
93 Window->Flags &= ~WINFLAG_SHOW;
94 WM_Invalidate(Window);
97 int WM_MoveWindow(tWindow *Window, int X, int Y)
100 if(X + Window->W < 0) X = -Window->W + 1;
101 if(Y + Window->H < 0) Y = -Window->H + 1;
102 if(X >= giScreenWidth) X = giScreenWidth - 1;
103 if(Y >= giScreenHeight) Y = giScreenHeight - 1;
105 Window->X = X; Window->Y = Y;
107 WM_Invalidate(Window);
112 int WM_ResizeWindow(tWindow *Window, int W, int H)
114 if(W <= 0 || H <= 0 ) return 1;
115 if(Window->X + W < 0) Window->X = -W + 1;
116 if(Window->Y + H < 0) Window->Y = -H + 1;
118 Window->W = W; Window->H = H;
120 WM_Invalidate(Window);
125 void WM_Invalidate(tWindow *Window)
127 // Don't invalidate twice (speedup)
128 if( !(Window->Flags & WINFLAG_CLEAN) ) return;
130 _SysDebug("Invalidating %p");
132 // Mark for re-render
133 Window->Flags &= ~WINFLAG_CLEAN;
135 // Mark up the tree that a child window has changed
136 while( (Window = Window->Parent) )
138 _SysDebug("Childclean removed from %p", Window);
139 Window->Flags &= ~WINFLAG_CHILDCLEAN;
143 // --- Rendering / Update
144 void WM_int_UpdateWindow(tWindow *Window)
148 // Ignore hidden windows
149 if( !(Window->Flags & WINFLAG_SHOW) )
153 if( !(Window->Flags & WINFLAG_CLEAN) )
155 Window->Renderer->Redraw(Window);
156 Window->Flags |= WINFLAG_CLEAN;
160 if( !(Window->Flags & WINFLAG_CHILDCLEAN) )
162 for( child = Window->FirstChild; child; child = child->NextSibling )
164 WM_int_UpdateWindow(child);
166 Window->Flags |= WINFLAG_CHILDCLEAN;
171 void WM_int_BlitWindow(tWindow *Window)
175 // Ignore hidden windows
176 if( !(Window->Flags & WINFLAG_SHOW) )
179 Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->W, Window->H);
181 for( child = Window->FirstChild; child; child = child->NextSibling )
183 WM_int_BlitWindow(child);
189 // Don't redraw if nothing has changed
190 if( (gpWM_RootWindow->Flags & WINFLAG_CHILDCLEAN) )
193 // - Iterate through visible windows, updating them as needed
194 WM_int_UpdateWindow(gpWM_RootWindow);
196 // - Draw windows from back to front to the render buffer
197 WM_int_BlitWindow(gpWM_RootWindow);
202 // --- WM Render Routines
203 // TODO: Move to another file?
204 void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H)
208 _SysDebug("WM_Render_FilledRect(%p, 0x%x...", Window, Colour);
209 _SysDebug(" (%i,%i), %ix%i)", X, Y, W, H);
210 // Clip to window dimensions
211 if(X < 0) { W += X; X = 0; }
212 if(Y < 0) { H += Y; Y = 0; }
213 if(X >= Window->W) return;
214 if(Y >= Window->H) return;
215 if(X + W > Window->W) W = Window->W - X;
216 if(Y + H > Window->H) H = Window->H - Y;
217 _SysDebug(" Clipped to (%i,%i), %ix%i", X, Y, W, H);
222 if(!Window->RenderBuffer) {
223 Window->RenderBuffer = malloc(Window->W*Window->H*4);
226 dest = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
231 dest += Window->W - W;