7a7a8d8e781861f8d84b65f4072a39f75a632911
[tpg/acess2.git] / Usermode / Applications / axwin3_src / WM / wm.c
1 /*
2  * Acess2 Window Manager v3
3  * - By John Hodge (thePowersGang)
4  *
5  * wm.c
6  * - Window manager core
7  */
8 #include <common.h>
9 #include <wm_renderer.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <video.h>
13
14 // === GLOBALS ===
15 tWMRenderer     *gpWM_Renderers;
16 tWindow *gpWM_RootWindow;
17
18 // === CODE ===
19 void WM_Initialise(void)
20 {
21         WM_CreateWindow(NULL, 0x0088FF, "Background");
22         gpWM_RootWindow->W = giScreenWidth;
23         gpWM_RootWindow->H = giScreenHeight;
24         gpWM_RootWindow->Flags = WINFLAG_SHOW;
25 }
26
27 void WM_RegisterRenderer(tWMRenderer *Renderer)
28 {
29         // TODO: Catch out duplicates
30         Renderer->Next = gpWM_Renderers;
31         gpWM_Renderers = Renderer;
32 }
33
34 tWindow *WM_CreateWindow(tWindow *Parent, int RendererArg, const char *RendererName)
35 {
36         tWMRenderer     *renderer;
37         tWindow *ret;
38         
39         // - Get Renderer
40         for( renderer = gpWM_Renderers; renderer; renderer = renderer->Next )
41         {
42                 if(strcmp(RendererName, renderer->Name) == 0)
43                         break;
44         }
45         if(renderer == NULL)
46                 return NULL;
47
48         // - Call create window function
49         ret = renderer->CreateWindow(RendererArg);
50         ret->Parent = Parent;
51         ret->Renderer = renderer;
52
53         if(!Parent)
54                 Parent = gpWM_RootWindow;
55
56         // Append to parent
57         if(Parent)
58         {
59                 if(Parent->LastChild)
60                         Parent->LastChild->NextSibling = ret;
61                 else
62                         Parent->FirstChild = ret;
63                 ret->PrevSibling = Parent->LastChild;
64                 Parent->LastChild = ret;
65         }
66         else
67         {
68                 gpWM_RootWindow = ret;
69         }
70
71         // - Return!
72         return ret;
73 }
74
75 tWindow *WM_CreateWindowStruct(size_t ExtraSize)
76 {
77         tWindow *ret;
78         
79         ret = calloc( sizeof(tWindow) + ExtraSize, 1 );
80         ret->RendererInfo = ret + 1;    // Get end of tWindow
81         
82         return ret;
83 }
84
85 void WM_int_UpdateWindow(tWindow *Window)
86 {
87         tWindow *child;
88
89         // Ignore hidden windows
90         if( !(Window->Flags & WINFLAG_SHOW) )
91                 return ;
92         // Ignore unchanged windows
93         if( Window->Flags & WINFLAG_CLEAN )
94                 return;
95
96         // Render
97         Window->Renderer->Redraw(Window);
98         
99         // Process children
100         for( child = Window->FirstChild; child; child = child->NextSibling )
101         {
102                 WM_int_UpdateWindow(child);
103         }
104         
105         Window->Flags |= WINFLAG_CLEAN;
106 }
107
108 void WM_int_BlitWindow(tWindow *Window)
109 {
110         tWindow *child;
111
112         // Ignore hidden windows
113         if( !(Window->Flags & WINFLAG_SHOW) )
114                 return ;
115         
116         Video_Blit(Window->RenderBuffer, Window->X, Window->Y, Window->W, Window->H);
117         
118         for( child = Window->FirstChild; child; child = child->NextSibling )
119         {
120                 WM_int_BlitWindow(child);
121         }
122 }
123
124 void WM_Update(void)
125 {
126         // Don't redraw if nothing has changed
127         if( gpWM_RootWindow->Flags & WINFLAG_CLEAN )
128                 return ;        
129
130         // - Iterate through visible windows, updating them as needed
131         WM_int_UpdateWindow(gpWM_RootWindow);
132         
133         // - Draw windows from back to front to the render buffer
134         WM_int_BlitWindow(gpWM_RootWindow);
135
136         Video_Update();
137 }
138
139 // --- WM Render Routines
140 // TODO: Move to another file?
141 void WM_Render_FilledRect(tWindow *Window, tColour Colour, int X, int Y, int W, int H)
142 {
143         uint32_t        *dest;
144          int    i;
145         _SysDebug("WM_Render_FilledRect(%p, 0x%x...", Window, Colour);
146         _SysDebug(" (%i,%i), %ix%i)", X, Y, W, H);
147         // Clip to window dimensions
148         if(X < 0) { W += X; X = 0; }
149         if(Y < 0) { H += Y; Y = 0; }
150         if(X >= Window->W)      return;
151         if(Y >= Window->H)      return;
152         if(X + W > Window->W)   W = Window->W - X;
153         if(Y + H > Window->H)   H = Window->H - Y;
154         _SysDebug(" Clipped to (%i,%i), %ix%i", X, Y, W, H);
155
156         // Render to buffer
157         // Create if needed?
158
159         if(!Window->RenderBuffer) {
160                 Window->RenderBuffer = malloc(Window->W*Window->H*4);
161         }
162
163         dest = (uint32_t*)Window->RenderBuffer + Y*Window->W + X;
164         while( H -- )
165         {
166                 for( i = W; i --; )
167                         *dest++ = Colour;
168                 dest += Window->W - W;
169         }
170 }
171

UCC git Repository :: git.ucc.asn.au