Usermode/AxWin4 - Fixing ID lookups of windows and clients
authorJohn Hodge (sonata) <[email protected]>
Fri, 7 Nov 2014 08:44:29 +0000 (16:44 +0800)
committerJohn Hodge (sonata) <[email protected]>
Fri, 7 Nov 2014 08:44:29 +0000 (16:44 +0800)
12 files changed:
Usermode/Applications/axwin4_src/Server/CClient.cpp
Usermode/Applications/axwin4_src/Server/CSurface.cpp
Usermode/Applications/axwin4_src/Server/CWindow.cpp
Usermode/Applications/axwin4_src/Server/Makefile
Usermode/Applications/axwin4_src/Server/compositor.cpp
Usermode/Applications/axwin4_src/Server/include/CClient.hpp
Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp
Usermode/Applications/axwin4_src/Server/include/CWindow.hpp
Usermode/Applications/axwin4_src/Server/include/ipc.hpp
Usermode/Applications/axwin4_src/Server/include/video.hpp
Usermode/Applications/axwin4_src/Server/ipc.cpp
Usermode/Libraries/libaxwin4.so_src/wm.cpp

index 6c9fe68..8640bf3 100644 (file)
@@ -12,7 +12,8 @@
 namespace AxWin {
 
 CClient::CClient(::AxWin::IIPCChannel& channel):
-       m_channel(channel)
+       m_channel(channel),
+       m_id(0)
 {
        
 }
@@ -35,10 +36,13 @@ CWindow* CClient::GetWindow(int ID)
 void CClient::SetWindow(int ID, CWindow* window)
 {
        _SysDebug("SetWindow(ID=%i,window=%p)", ID, window);
-       if( m_windows[ID] ) {
-               delete m_windows[ID];
+       auto it = m_windows.find(ID);
+       if( it != m_windows.end() ) {
+               _SysDebug("CLIENT BUG: Window ID %i is already used by %p", ID, it->second);
+       }
+       else {
+               m_windows[ID] = window;
        }
-       m_windows[ID] = window;
 }
 
 void CClient::HandleMessage(CDeserialiser& message)
index 27078d8..91bbb9a 100644 (file)
@@ -27,6 +27,13 @@ CSurface::CSurface(int x, int y, unsigned int w, unsigned int h):
 
 CSurface::~CSurface()
 {
+       if( m_fd == -1 ) {
+               delete[] m_data;
+       }
+       else {
+               size_t  size = m_rect.m_w*m_rect.m_h*4;
+               _SysMUnMap(m_data, size);
+       }
 }
 
 uint64_t CSurface::GetSHMHandle()
index 392fd47..55c2482 100644 (file)
 
 namespace AxWin {
 
-CWindow::CWindow(CCompositor& compositor, CClient& client, const ::std::string& name):
+CWindow::CWindow(CCompositor& compositor, CClient& client, const ::std::string& name, unsigned int id):
        m_surface(0,0,0,0),
        m_compositor(compositor),
        m_client(client),
+       m_id(id),
        m_name(name),
        m_is_shown(false)
 {
index c7d7983..87ed9af 100644 (file)
@@ -14,7 +14,7 @@ OBJ += draw_control.o
 BIN := AxWinServer
 
 LIBS += -lc++
-CXXFLAGS += -O3
+#CXXFLAGS += -O3
 USE_CXX_LINK = 1 
 
 include ../../Makefile.tpl
index 7a18747..42bb8b9 100644 (file)
@@ -7,21 +7,20 @@
  */
 #include <video.hpp>
 #include <CCompositor.hpp>
+#include <CClient.hpp>
+#include <ipc.hpp>
 #include <cassert>
 
 namespace AxWin {
 
 CCompositor::CCompositor(CVideo& video):
-       m_video(video)
+       // TODO: Support multiple screens
+       m_video(video),
+       m_windowIDBuffer(video.width(), video.height())
 {
        // 
 }
 
-CWindow* CCompositor::CreateWindow(CClient& client, const ::std::string& name)
-{
-       return new CWindow(*this, client, name);
-}
-
 void CCompositor::ShowWindow(CWindow* window)
 {
        DamageArea(window->m_surface.m_rect);
@@ -75,6 +74,7 @@ void CCompositor::Redraw()
                                _SysDebug("Reblit (%i,%i) %ix%i", rel_rect.m_x, rel_rect.m_y, rel_rect.m_w, rel_rect.m_h);
                                BlitFromSurface( window->m_surface, rel_rect );
                                //window->Repaint( rel_rect );
+                               m_windowIDBuffer.set(rel_rect.m_x, rel_rect.m_y, rel_rect.m_w, rel_rect.m_h, window);
                        }
                }
                
@@ -109,13 +109,23 @@ void CCompositor::MouseMove(unsigned int Cursor, unsigned int X, unsigned int Y,
 {
        _SysDebug("MouseButton(%i, %i,%i, %+i,%+i)", Cursor, X, Y, dX, dY);
        m_video.SetCursorPos(X+dX, Y+dY);
-       // TODO: Pass event on to window
+       CWindow *dstwin = getWindowForCoord(X, Y);
+       if( dstwin )
+       {
+               // TODO: Pass event on to window
+       }
 }
 
 void CCompositor::MouseButton(unsigned int Cursor, unsigned int X, unsigned int Y, eMouseButton Button, bool Press)
 {
        _SysDebug("MouseButton(%i, %i,%i, %i=%i)", Cursor, X, Y, Button, Press);
-       // TODO: Pass event on to window
+       CWindow *dstwin = getWindowForCoord(X, Y);
+       if( dstwin )
+       {
+               // 1. Give focus and bring to front
+               // 2. Send event
+               // TODO: Pass event on to window
+       }
 }
 
 void CCompositor::KeyState(unsigned int KeyboardID, uint32_t KeySym, bool Press, uint32_t Codepoint)
@@ -123,5 +133,38 @@ void CCompositor::KeyState(unsigned int KeyboardID, uint32_t KeySym, bool Press,
        _SysDebug("KeyState(%i, 0x%x, %b, 0x%x)", KeyboardID, KeySym, Press, Codepoint);
 }
 
+CWindow* CCompositor::getWindowForCoord(unsigned int X, unsigned int Y)
+{
+       return m_windowIDBuffer.get(X, Y);
+}
+
+// --------------------------------------------------------------------
+CWindowIDBuffer::CWindowIDBuffer(unsigned int W, unsigned int H):
+       m_w(W),
+       m_buf(W*H)
+{
+}
+void CWindowIDBuffer::set(unsigned int X, unsigned int Y, unsigned int W, unsigned int H, CWindow* win)
+{
+       TWindowID       ent = {
+               .Client = win->client().id(),
+               .Window = win->id(),
+               };
+       
+}
+CWindow* CWindowIDBuffer::get(unsigned int X, unsigned int Y)
+{
+       if( X >= m_w )
+               return nullptr;
+       unsigned int pos = Y*m_w + X;
+       if( pos >= m_buf.size() )
+               return nullptr;
+       auto id = m_buf[pos];
+       auto client = ::AxWin::IPC::GetClientByID(id.Client);
+       if( client == nullptr )
+               return nullptr;
+       return client->GetWindow(id.Window);
+}
+
 }      // namespace AxWin
 
index a42d9fa..24e7dab 100644 (file)
@@ -11,6 +11,7 @@
 #include "CWindow.hpp"
 #include "serialisation.hpp"
 #include <map>
+#include <cassert>
 
 namespace AxWin {
 
@@ -18,6 +19,7 @@ class IIPCChannel;
 
 class CClient
 {
+       unsigned int    m_id;
        IIPCChannel&    m_channel;
        
        ::std::map<unsigned int,CWindow*>       m_windows;
@@ -26,6 +28,9 @@ public:
        CClient(::AxWin::IIPCChannel& channel);
        virtual ~CClient();
        
+       void set_id(unsigned int id) { assert(m_id == 0); m_id = id; }
+       unsigned int id() const { return m_id; }
+       
        CWindow*        GetWindow(int ID);
        void    SetWindow(int ID, CWindow* window);
        
index 7c1272a..ec40d36 100644 (file)
@@ -19,11 +19,6 @@ namespace AxWin {
 class CClient;
 class CVideo;
 
-struct TWindowID
-{
-       uint16_t        Client;
-       uint16_t        Window;
-};
 
 enum eMouseButton
 {
@@ -34,13 +29,29 @@ enum eMouseButton
        MOUSEBTN_BTN5,
 };
 
+class CWindowIDBuffer
+{
+       struct TWindowID
+       {
+               uint16_t        Client;
+               uint16_t        Window;
+       };
+       unsigned int    m_w;
+       ::std::vector<TWindowID>        m_buf;
+public:
+       CWindowIDBuffer(unsigned int W, unsigned int H);
+       
+       void set(unsigned int X, unsigned int Y, unsigned int W, unsigned int H, CWindow* win);
+       CWindow* get(unsigned int X, unsigned int Y);
+};
+
 class CCompositor
 {
        CVideo& m_video;
        ::std::list<CRect>      m_damageRects;
        ::std::list<CWindow*>   m_windows;
 
-       ::std::vector<TWindowID>        m_windowIDBuffer;       // One 32-bit value per pixel
+       CWindowIDBuffer m_windowIDBuffer;       // One 32-bit value per pixel
        
 public:
        CCompositor(CVideo& video);
@@ -60,6 +71,8 @@ public:
        void    MouseButton(unsigned int Cursor, unsigned int X, unsigned int Y, eMouseButton Button, bool Press);
        
        void    KeyState(unsigned int KeyboardID, uint32_t KeySym, bool Press, uint32_t Codepoint);
+public:
+       CWindow*        getWindowForCoord(unsigned int X, unsigned int Y);
 };
 
 
index 3c763de..5161f03 100644 (file)
@@ -23,9 +23,12 @@ class CRegion;
 class CWindow
 {
 public:
-       CWindow(CCompositor& compositor, CClient& client, const ::std::string &name);
+       CWindow(CCompositor& compositor, CClient& client, const ::std::string &name, unsigned int id);
        ~CWindow();
        
+       const CClient& client() const { return m_client; }
+       const unsigned int id() const { return m_id; }
+       
        void Repaint(const CRect& rect);
 
        void Show(bool bShow);  
@@ -46,6 +49,7 @@ public:
 private:
        CCompositor&    m_compositor;
        CClient&        m_client;
+       unsigned int    m_id;
        const ::std::string     m_name;
        ::std::vector<CRegion*> m_regions;
 };
index 729f153..5706a85 100644 (file)
@@ -28,6 +28,7 @@ extern void   Initialise(const CConfigIPC& config, CCompositor& compositor);
 extern int     FillSelect(::fd_set& rfds);
 extern void    HandleSelect(const ::fd_set& rfds);
 extern void    RegisterClient(CClient& client);
+extern CClient*        GetClientByID(uint16_t id);
 extern void    DeregisterClient(CClient& client);
 
 extern void    SendMessage_NotifyDims(CClient& client, unsigned int NewW, unsigned int NewH);
index 9ca7b42..3738099 100644 (file)
@@ -23,6 +23,8 @@ public:
        CVideo(const CConfigVideo& config);
 
        void GetDims(unsigned int& w, unsigned int& h); 
+       unsigned int width()  const { return m_width;  }
+       unsigned int height() const { return m_height; }
 
        void BlitLine(const uint32_t* src, unsigned int dst_y, unsigned int dst_x, unsigned int width);
        void Flush();
index 58cda2b..c507285 100644 (file)
@@ -25,7 +25,8 @@ namespace IPC {
 
 CCompositor*   gpCompositor;
 ::std::list<IIPCChannel*>      glChannels;
-//::std::map<uint16_t,CClient*>        glClients;
+::std::map<uint16_t,CClient*>  glClients;
+uint16_t       giNextClient = 1;
 
 void Initialise(const CConfigIPC& config, CCompositor& compositor)
 {
@@ -65,13 +66,30 @@ void HandleSelect(const fd_set& rfds)
 void RegisterClient(CClient& client)
 {
        // allocate a client ID, and save
-       //client.m_id = 123;
-       //glClients[client.m_id] = &client;
+       for( int i = 0; i < 100; i ++ )
+       {
+               uint16_t id = giNextClient++;
+               if(giNextClient == 0)   giNextClient = 1;
+               auto r = glClients.insert( ::std::pair<uint16_t,CClient*>(id, &client) );
+               if( r.second == true )
+               {
+                       client.set_id(id);
+                       return;
+               }
+       }
+       // Wut? 100 attempts and fail!
+       assert(!"Todo - Better way of handling client ID reuse");
+}
+
+CClient* GetClientByID(uint16_t id)
+{
+       auto it = glClients.find(id);
+       return (it == glClients.end() ? nullptr : it->second);
 }
 
 void DeregisterClient(CClient& client)
 {
-       //glClients.erase( client.m_id );
+       glClients.erase( client.id() );
 }
 
 
@@ -163,7 +181,7 @@ void HandleMessage_CreateWindow(CClient& client, CDeserialiser& message)
        ::std::string   name = message.ReadString();
        
        ::_SysDebug("_CreateWindow: (%i, '%s')", new_id, name.c_str());
-       client.SetWindow( new_id, gpCompositor->CreateWindow(client, name) );
+       client.SetWindow( new_id, new CWindow(*gpCompositor, client, name, new_id) );
 }
 
 void HandleMessage_DestroyWindow(CClient& client, CDeserialiser& message)
index 3672078..cae79c7 100644 (file)
@@ -11,6 +11,7 @@
 #include <vector>
 #include <algorithm>
 #include <mutex>
+#include <cassert>
 
 namespace AxWin {
 
@@ -22,7 +23,7 @@ extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name)
 {
        // Allocate a window ID
        ::std::lock_guard<std::mutex>   lock(glWindowList);
-       int id = ::std::find(gWindowList.begin(), gWindowList.end(), nullptr) - gWindowList.end();
+       int id = ::std::find(gWindowList.begin(), gWindowList.end(), nullptr) - gWindowList.begin();
        if( id >= MAX_WINDOW_ID ) {
                throw ::std::runtime_error("AxWin4_CreateWindow - Out of IDs (TODO: Better exception)");
        }
@@ -30,6 +31,7 @@ extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name)
        {
                gWindowList.push_back(nullptr);
        }
+       assert(gWindowList[id] == nullptr);
        
        // Create window structure locally
        tAxWin4_Window *ret = new tAxWin4_Window();

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