Usermode/AxWin4 - PushData implemented
authorJohn Hodge <[email protected]>
Sun, 8 Jun 2014 10:39:52 +0000 (18:39 +0800)
committerJohn Hodge <[email protected]>
Sun, 8 Jun 2014 10:39:52 +0000 (18:39 +0800)
Usermode/Applications/axwin4_src/Common/include/serialisation.hpp
Usermode/Applications/axwin4_src/Common/serialisation.cpp
Usermode/Applications/axwin4_src/Server/CRect.cpp
Usermode/Applications/axwin4_src/Server/CSurface.cpp
Usermode/Applications/axwin4_src/Server/include/CRect.hpp
Usermode/Applications/axwin4_src/Server/include/CSurface.hpp
Usermode/Applications/axwin4_src/Server/ipc.cpp
Usermode/Libraries/libaxwin4.so_src/window_drawing.cpp

index 7212018..c147809 100644 (file)
@@ -32,6 +32,7 @@ public:
        ::uint8_t       ReadU8();
        ::uint16_t      ReadU16();
        ::int16_t       ReadS16();
+       const ::std::vector<uint8_t>    ReadBuffer();
        const ::std::string     ReadString();
 private:
        void RangeCheck(const char *Method, size_t bytes) throw(::std::out_of_range);
index 7bb77bf..9f536b5 100644 (file)
@@ -49,6 +49,17 @@ bool CDeserialiser::IsConsumed() const
                return ~rv_u + 1;
 }
 
+const ::std::vector<uint8_t> CDeserialiser::ReadBuffer()
+{
+       RangeCheck("CDeserialiser::ReadBuffer(len)", 2);
+       size_t  size = ReadU16();
+       
+       ::std::vector<uint8_t> ret( size );
+       for( size_t i = 0; i < size; i ++ )
+               ret[i] = m_data[m_offset++];
+       return ret;
+}
+
 const ::std::string CDeserialiser::ReadString()
 {
        RangeCheck("CDeserialiser::ReadString(len)", 1);
index 34013b1..6f504d8 100644 (file)
@@ -26,6 +26,14 @@ void CRect::Move(int NewX, int NewY)
        m_y2 = m_y + m_h;
 }
 
+void CRect::Resize(int NewW, int NewH)
+{
+       m_w = NewW;
+       m_h = NewH;
+       m_x2 = m_x + m_w;
+       m_y2 = m_y + m_h;
+}
+
 bool CRect::HasIntersection(const CRect& other) const
 {
        // If other's origin is past our far corner
index d52298c..429657a 100644 (file)
@@ -7,12 +7,18 @@
  */
 #include <CSurface.hpp>
 #include <cassert>
+#include <stdexcept>
+#include <cstring>
 
 namespace AxWin {
 
 CSurface::CSurface(int x, int y, unsigned int w, unsigned int h):
        m_rect(x,y, w,h)
 {
+       if( w > 0 && h > 0 )
+       {
+               m_data = new uint32_t[w * h];
+       }
 }
 
 CSurface::~CSurface()
@@ -21,12 +27,36 @@ CSurface::~CSurface()
 
 void CSurface::Resize(unsigned int W, unsigned int H)
 {
-       assert(!"TODO: CSurface::Resize");
+       // Easy realloc
+       // TODO: Should I maintain window contents sanely? NOPE!
+       delete m_data;
+       m_data = new uint32_t[W * H];
+       m_rect.Resize(W, H);
+}
+
+void CSurface::DrawScanline(unsigned int row, unsigned int x_ofs, unsigned int w, const void* data)
+{
+       _SysDebug("DrawScanline(%i,%i,%i,%p)", row, x_ofs, w, data);
+       if( row >= m_rect.m_h )
+               throw ::std::out_of_range("CSurface::DrawScanline row");
+       if( x_ofs >= m_rect.m_w )
+               throw ::std::out_of_range("CSurface::DrawScanline x_ofs");
+
+       if( w > m_rect.m_w )
+               throw ::std::out_of_range("CSurface::DrawScanline width");
+       
+       _SysDebug(" memcpy(%p, %p, %i)", &m_data[row*m_rect.m_w + x_ofs], data, w*4 );
+       ::memcpy( &m_data[row*m_rect.m_w + x_ofs], data, w*4 );
 }
 
 const uint32_t* CSurface::GetScanline(unsigned int row, unsigned int x_ofs) const
 {
-       return 0;
+       if( row >= m_rect.m_h )
+               throw ::std::out_of_range("CSurface::GetScanline row");
+       if( x_ofs >= m_rect.m_w )
+               throw ::std::out_of_range("CSurface::GetScanline x_ofs");
+
+       return &m_data[row * m_rect.m_w + x_ofs];
 }
 
 
index e8f9dc8..708186a 100644 (file)
@@ -15,6 +15,7 @@ public:
        CRect(int X, int Y, unsigned int W, unsigned int H);
        
        void Move(int NewX, int NewY);
+       void Resize(int NewW, int NewH);
        
        bool HasIntersection(const CRect& other) const;
        CRect Intersection(const CRect& other) const;
index c0c6c8b..488d4d6 100644 (file)
@@ -16,6 +16,7 @@ public:
        
        void Resize(unsigned int new_w, unsigned int new_h);
        
+       void DrawScanline(unsigned int row, unsigned int x_ofs, unsigned int w, const void* data);
        const uint32_t* GetScanline(unsigned int row, unsigned int x_ofs) const;
        
        CRect   m_rect;
index 4e5ba76..70605fc 100644 (file)
@@ -39,9 +39,10 @@ void Initialise(const CConfigIPC& config, CCompositor& compositor)
 int FillSelect(fd_set& rfds)
 {
        int ret = 0;
-       for( auto channel : glChannels )
+       for( const auto channel : glChannels )
        {
                _SysDebug("IPC::FillSelect - channel=%p", channel);
+               assert(channel);
                ret = ::std::max(ret, channel->FillSelect(rfds));
        }
        return ret;
@@ -49,8 +50,9 @@ int FillSelect(fd_set& rfds)
 
 void HandleSelect(const fd_set& rfds)
 {
-       for( auto channel : glChannels )
+       for( const auto channel : glChannels )
        {
+               assert(channel);
                channel->HandleSelect(rfds);
        }
 }
@@ -70,7 +72,7 @@ void DeregisterClient(CClient& client)
 
 void SendNotify_Dims(CClient& client, unsigned int NewW, unsigned int NewH)
 {
-       assert(!"TODO: CClient::SendNotify_Dims");
+       _SysDebug("TODO: CClient::SendNotify_Dims");
 }
 
 
@@ -216,7 +218,29 @@ void HandleMessage_GetWindowBuffer(CClient& client, CDeserialiser& message)
 
 void HandleMessage_PushData(CClient& client, CDeserialiser& message)
 {
-       assert(!"TODO HandleMessage_PushData");
+       uint16_t        win_id = message.ReadU16();
+       uint16_t        x = message.ReadU16();
+       uint16_t        y = message.ReadU16();
+       uint16_t        w = message.ReadU16();
+       uint16_t        h = message.ReadU16();
+       _SysDebug("_PushData: (%i, (%i,%i) %ix%i)", win_id, x, y, w, h);
+       
+       CWindow*        win = client.GetWindow(win_id);
+       if(!win) {
+               throw IPC::CClientFailure("_PushData: Bad window");
+       }
+       
+       for( unsigned int row = 0; row < h; row ++ )
+       {
+               const ::std::vector<uint8_t> scanline_data = message.ReadBuffer();
+               _SysDebug("_PushData: Scanline %i: %i bytes", row, scanline_data.size());
+               if( scanline_data.size() != w * 4 ) {
+                       _SysDebug("ERROR _PushData: Scanline buffer size mismatch (%i,%i)",
+                               scanline_data.size(), w*4);
+                       continue ;
+               }
+               win->m_surface.DrawScanline(y+row, x, w, scanline_data.data());
+       }
 }
 void HandleMessage_Blit(CClient& client, CDeserialiser& message)
 {
index 6f2f898..e074ee4 100644 (file)
 
 namespace AxWin {
 
+void _push_data(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, const void *Data)
+{
+       CSerialiser     message;
+       message.WriteU8(IPCMSG_PUSHDATA);
+       message.WriteU16(Window->m_id);
+       message.WriteU16(X);
+       message.WriteU16(Y);
+       message.WriteU16(W);
+       message.WriteU16(H);
+       message.WriteBuffer(H*W*4, Data);
+       ::AxWin::SendMessage(message);
+}
+
 extern "C" void AxWin4_DrawBitmap(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, void *Data)
 {
        // TODO: Split message up into blocks such that it can be dispatched
        if( W > 128 )
        {
                const uint32_t* data32 = static_cast<uint32_t*>(Data);
-               const unsigned int rows_per_message = 2048 / W;
+               const unsigned int rows_per_message = 1;        // 2048 / W;
                for( unsigned int row = 0; row < H; row += rows_per_message )
                {
-                       CSerialiser     message;
-                       message.WriteU8(IPCMSG_PUSHDATA);
-                       message.WriteU16(Window->m_id);
-                       message.WriteU16(X);
-                       message.WriteU16(Y+row);
-                       message.WriteU16(W);
-                       message.WriteU16( ::std::min(rows_per_message,H-row) );
-                       message.WriteBuffer(W*4, data32);
-                       ::AxWin::SendMessage(message);
+                       _push_data(Window, X, Y+row, W, ::std::min(rows_per_message,H-row), data32);
                        data32 += W*rows_per_message;
                }
        }
        else
        {
-               CSerialiser     message;
-               message.WriteU8(IPCMSG_PUSHDATA);
-               message.WriteU16(Window->m_id);
-               message.WriteU16(X);
-               message.WriteU16(Y);
-               message.WriteU16(W);
-               message.WriteU16(H);
-               message.WriteBuffer(W*H*4, Data);
-               ::AxWin::SendMessage(message);
+               _push_data(Window, X, Y, W, H, Data);
        }
 }
 

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