Usermode/AxWin4 - Fixing ID lookups of windows and clients
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Server / compositor.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang)
4  *
5  * compositor.cpp
6  * - Window compositor
7  */
8 #include <video.hpp>
9 #include <CCompositor.hpp>
10 #include <CClient.hpp>
11 #include <ipc.hpp>
12 #include <cassert>
13
14 namespace AxWin {
15
16 CCompositor::CCompositor(CVideo& video):
17         // TODO: Support multiple screens
18         m_video(video),
19         m_windowIDBuffer(video.width(), video.height())
20 {
21         // 
22 }
23
24 void CCompositor::ShowWindow(CWindow* window)
25 {
26         DamageArea(window->m_surface.m_rect);
27         // TODO: Append to separate sub-lists (or to separate lists all together)
28         //   if flags AXWIN4_WNDFLAG_KEEPBELOW or AXWIN4_WNDFLAG_KEEPABOVE are set
29         m_windows.push_back(window);
30 }
31 void CCompositor::HideWindow(CWindow* window)
32 {
33         DamageArea(window->m_surface.m_rect);
34         m_windows.remove(window);
35 }
36
37 bool CCompositor::GetScreenDims(unsigned int ScreenID, unsigned int* W, unsigned int* H)
38 {
39         assert(W && H);
40         if( ScreenID != 0 )
41         {
42                 *W = 0;
43                 *H = 0;
44                 return false;
45         }
46         else
47         {
48                 m_video.GetDims(*W, *H);
49                 return true;
50         }
51 }
52
53 void CCompositor::Redraw()
54 {
55         // Redraw the screen and clear damage rects
56         if( m_damageRects.empty() ) {
57                 _SysDebug("- No damaged regions");
58                 return ;
59         }
60         
61         // Build up foreground grid (Rects and windows)
62         // - This should already be built (mutated on window move/resize/reorder)
63         
64         // For all windows, check for intersection with damage rects
65         for( auto rect : m_damageRects )
66         {
67                 // window list should be sorted by draw order (lowest first)
68                 for( auto window : m_windows )
69                 {
70                         if( window->m_is_shown && rect.HasIntersection( window->m_surface.m_rect ) )
71                         {
72                                 // TODO: just reblit
73                                 CRect   rel_rect = window->m_surface.m_rect.RelativeIntersection(rect);
74                                 _SysDebug("Reblit (%i,%i) %ix%i", rel_rect.m_x, rel_rect.m_y, rel_rect.m_w, rel_rect.m_h);
75                                 BlitFromSurface( window->m_surface, rel_rect );
76                                 //window->Repaint( rel_rect );
77                                 m_windowIDBuffer.set(rel_rect.m_x, rel_rect.m_y, rel_rect.m_w, rel_rect.m_h, window);
78                         }
79                 }
80                 
81                 // TODO: Blit from windows to a local surface, then blit from there to screen here
82         }
83
84         m_damageRects.clear();
85         m_video.Flush();
86 }
87
88 void CCompositor::DamageArea(const CRect& area)
89 {
90         m_damageRects.push_back( area );
91         // 1. Locate intersection with any existing damaged areas
92         // 2. Append after removing intersections
93 }
94
95 void CCompositor::BlitFromSurface(const CSurface& dest, const CRect& src_rect)
96 {
97         for( unsigned int i = 0; i < src_rect.m_h; i ++ )
98         {
99                 m_video.BlitLine(
100                         dest.GetScanline(src_rect.m_y+i, src_rect.m_x),
101                         dest.m_rect.m_y + src_rect.m_y + i,
102                         dest.m_rect.m_x + src_rect.m_x,
103                         src_rect.m_w
104                         );
105         }
106 }
107
108 void CCompositor::MouseMove(unsigned int Cursor, unsigned int X, unsigned int Y, int dX, int dY)
109 {
110         _SysDebug("MouseButton(%i, %i,%i, %+i,%+i)", Cursor, X, Y, dX, dY);
111         m_video.SetCursorPos(X+dX, Y+dY);
112         CWindow *dstwin = getWindowForCoord(X, Y);
113         if( dstwin )
114         {
115                 // TODO: Pass event on to window
116         }
117 }
118
119 void CCompositor::MouseButton(unsigned int Cursor, unsigned int X, unsigned int Y, eMouseButton Button, bool Press)
120 {
121         _SysDebug("MouseButton(%i, %i,%i, %i=%i)", Cursor, X, Y, Button, Press);
122         CWindow *dstwin = getWindowForCoord(X, Y);
123         if( dstwin )
124         {
125                 // 1. Give focus and bring to front
126                 // 2. Send event
127                 // TODO: Pass event on to window
128         }
129 }
130
131 void CCompositor::KeyState(unsigned int KeyboardID, uint32_t KeySym, bool Press, uint32_t Codepoint)
132 {
133         _SysDebug("KeyState(%i, 0x%x, %b, 0x%x)", KeyboardID, KeySym, Press, Codepoint);
134 }
135
136 CWindow* CCompositor::getWindowForCoord(unsigned int X, unsigned int Y)
137 {
138         return m_windowIDBuffer.get(X, Y);
139 }
140
141 // --------------------------------------------------------------------
142 CWindowIDBuffer::CWindowIDBuffer(unsigned int W, unsigned int H):
143         m_w(W),
144         m_buf(W*H)
145 {
146 }
147 void CWindowIDBuffer::set(unsigned int X, unsigned int Y, unsigned int W, unsigned int H, CWindow* win)
148 {
149         TWindowID       ent = {
150                 .Client = win->client().id(),
151                 .Window = win->id(),
152                 };
153         
154 }
155 CWindow* CWindowIDBuffer::get(unsigned int X, unsigned int Y)
156 {
157         if( X >= m_w )
158                 return nullptr;
159         unsigned int pos = Y*m_w + X;
160         if( pos >= m_buf.size() )
161                 return nullptr;
162         auto id = m_buf[pos];
163         auto client = ::AxWin::IPC::GetClientByID(id.Client);
164         if( client == nullptr )
165                 return nullptr;
166         return client->GetWindow(id.Window);
167 }
168
169 }       // namespace AxWin
170

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