Usermode/AxWin4 - Screen dimensions acquisition, speedup, window render
authorJohn Hodge <[email protected]>
Sat, 21 Jun 2014 15:39:25 +0000 (23:39 +0800)
committerJohn Hodge <[email protected]>
Sat, 21 Jun 2014 15:39:25 +0000 (23:39 +0800)
31 files changed:
Usermode/Applications/axwin4_src/Common/include/serialisation.hpp
Usermode/Applications/axwin4_src/Common/serialisation.cpp
Usermode/Applications/axwin4_src/Server/CClient.cpp
Usermode/Applications/axwin4_src/Server/CIPCChannel_AcessIPCPipe.cpp
Usermode/Applications/axwin4_src/Server/CRect.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/CCompositor.hpp
Usermode/Applications/axwin4_src/Server/include/CIPCChannel_AcessIPCPipe.hpp
Usermode/Applications/axwin4_src/Server/include/CWindow.hpp
Usermode/Applications/axwin4_src/Server/ipc.cpp
Usermode/Applications/axwin4_src/Server/main.cpp
Usermode/Applications/axwin4_src/Server/video.cpp
Usermode/Applications/axwin4_src/UI/main.c
Usermode/Libraries/libaxwin4.so_src/include/common.hpp
Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h
Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/definitions.h [new file with mode: 0644]
Usermode/Libraries/libaxwin4.so_src/ipc.cpp
Usermode/Libraries/libaxwin4.so_src/ipc_acessipcpipe.cpp
Usermode/Libraries/libaxwin4.so_src/wm.cpp
Usermode/Libraries/libc++.so_src/Makefile
Usermode/Libraries/libc++.so_src/exceptions.cc
Usermode/Libraries/libc++.so_src/include_exp/_libcxx_helpers.h
Usermode/Libraries/libc++.so_src/include_exp/algorithm
Usermode/Libraries/libc++.so_src/include_exp/allocator
Usermode/Libraries/libc++.so_src/include_exp/list
Usermode/Libraries/libc++.so_src/include_exp/mutex [new file with mode: 0644]
Usermode/Libraries/libc++.so_src/include_exp/new
Usermode/Libraries/libc++.so_src/include_exp/vector
Usermode/Libraries/libc++.so_src/mutex.cc [new file with mode: 0644]

index c147809..5ccef67 100644 (file)
@@ -23,11 +23,16 @@ class CDeserialiseException:
 
 class CDeserialiser
 {
-       const size_t    m_length;
-       const uint8_t*  m_data;
+       ::std::vector<uint8_t>  m_vect;
        size_t  m_offset;
 public:
-       CDeserialiser(size_t Length, const uint8_t *Buffer);
+       CDeserialiser():
+               CDeserialiser(::std::vector<uint8_t>())
+       {}
+       CDeserialiser(const ::std::vector<uint8_t>& vect);
+       CDeserialiser(::std::vector<uint8_t>&& vect);
+       CDeserialiser(const CDeserialiser& x) { *this = x; };
+       CDeserialiser& operator=(const CDeserialiser& x);
        bool    IsConsumed() const;
        ::uint8_t       ReadU8();
        ::uint16_t      ReadU16();
index 9f536b5..f23d5cd 100644 (file)
 
 namespace AxWin {
 
-CDeserialiser::CDeserialiser(size_t Length, const uint8_t *Buffer):
-       m_length(Length),
-       m_data(Buffer),
+CDeserialiser::CDeserialiser(const ::std::vector<uint8_t>& vector):
+       m_vect(vector),
        m_offset(0)
 {
 }
+CDeserialiser::CDeserialiser(::std::vector<uint8_t>&& vector):
+       m_vect(vector),
+       m_offset(0)
+{
+}
+CDeserialiser& CDeserialiser::operator=(const CDeserialiser& x)
+{
+       m_vect = x.m_vect;
+       m_offset = x.m_offset;
+}
 
 bool CDeserialiser::IsConsumed() const
 {
-       return m_offset == m_length;
+       return m_offset == m_vect.size();
 }
 
 ::uint8_t CDeserialiser::ReadU8()
 {
        RangeCheck("CDeserialiser::ReadU8", 1);
-       uint8_t rv = m_data[m_offset];
+       uint8_t rv = m_vect[m_offset];
        m_offset ++;
        return rv;
 }
@@ -35,7 +44,7 @@ bool CDeserialiser::IsConsumed() const
 ::uint16_t CDeserialiser::ReadU16()
 {
        RangeCheck("CDeserialiser::ReadU16", 2);
-       uint16_t rv = m_data[m_offset] | ((uint16_t)m_data[m_offset+1] << 8);
+       uint16_t rv = m_vect[m_offset] | ((uint16_t)m_vect[m_offset+1] << 8);
        m_offset += 2;
        return rv;
 }
@@ -54,28 +63,27 @@ 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++];
+       auto range_start = m_vect.begin() + int(m_offset);
+       ::std::vector<uint8_t> ret( range_start, range_start + int(size) );
+       m_offset += size;
        return ret;
 }
 
 const ::std::string CDeserialiser::ReadString()
 {
        RangeCheck("CDeserialiser::ReadString(len)", 1);
-       uint8_t len = m_data[m_offset];
-       m_offset ++;
+       uint8_t len = ReadU8();
        
        RangeCheck("CDeserialiser::ReadString(data)", len);
-       ::std::string ret( reinterpret_cast<const char*>(m_data+m_offset), len );
+       ::std::string ret( reinterpret_cast<const char*>(m_vect.data()+m_offset), len );
        m_offset += len;
        return ret;
 }
 
 void CDeserialiser::RangeCheck(const char *Method, size_t bytes) throw(::std::out_of_range)
 {
-       if( m_offset + bytes > m_length ) {
-               ::_SysDebug("%s - out of range %i+%i >= %i", Method, m_offset, bytes, m_length);
+       if( m_offset + bytes > m_vect.size() ) {
+               ::_SysDebug("%s - out of range %i+%i >= %i", Method, m_offset, bytes, m_vect.size());
                throw ::std::out_of_range(Method);
        }
 }
index 92898b1..6c9fe68 100644 (file)
@@ -24,7 +24,6 @@ CClient::~CClient()
 
 CWindow* CClient::GetWindow(int ID)
 {
-       _SysDebug("GetWindow(ID=%i)", ID);
        try {
                return m_windows.at(ID);
        }
index a9818cd..df94958 100644 (file)
@@ -83,8 +83,7 @@ void CIPCChannel_AcessIPCPipe::HandleSelect(const fd_set& rfds)
 
 CClient_AcessIPCPipe::CClient_AcessIPCPipe(::AxWin::IIPCChannel& channel, int fd):
        CClient(channel),
-       m_fd(fd),
-       m_rxbuf(0x1000)
+       m_fd(fd)
 {
 }
 
@@ -99,17 +98,22 @@ void CClient_AcessIPCPipe::SendMessage(CSerialiser& message)
        const ::std::vector<uint8_t>&   data = message.Compact();
        
        _SysDebug("CClient_AcessIPCPipe::SendMessage - %i bytes to %i", data.size(), m_fd);
+       _SysDebugHex("CClient_AcessIPCPipe::SendMessage", data.data(), data.size());
        _SysWrite(m_fd, data.data(), data.size());
 }
 
 void CClient_AcessIPCPipe::HandleReceive()
 {
-       size_t len = _SysRead(m_fd, &m_rxbuf[0], m_rxbuf.capacity());
+       ::std::vector<uint8_t>  rxbuf(0x1000);
+       size_t len = _SysRead(m_fd, rxbuf.data(), rxbuf.capacity());
        if( len == (size_t)-1 )
                throw ::std::system_error(errno, ::std::system_category());
+       //_SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
+       //_SysDebugHex("CClient_AcessIPCPipe::HandleReceive", m_rxbuf.data(), len);
+       rxbuf.resize(len);
        
-       CDeserialiser   message(len, &m_rxbuf[0]);
-       CClient::HandleMessage(message);
+       CDeserialiser   msg( ::std::move(rxbuf) );
+       CClient::HandleMessage( msg );
 }
 
 };
index 6f504d8..acbcc27 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <CRect.hpp>
 #include <algorithm>
+#include <acess/sys.h>
 
 namespace AxWin {
 
@@ -57,10 +58,10 @@ CRect CRect::Intersection(const CRect& other) const
        int x2 = ::std::min(m_x2, other.m_x2);
        int y2 = ::std::min(m_y2, other.m_y2);
        
-       if( x1 <= x2 || y2 <= y1 )
+       if( x2 <= x1 || y2 <= y1 )
                return CRect();
        
-       return CRect(x1, y1, x2-x1, y2-y2);
+       return CRect(x1, y1, x2-x1, y2-y1);
 }
 
 CRect CRect::RelativeIntersection(const CRect& area)
index db43bac..f70db32 100644 (file)
@@ -41,7 +41,14 @@ void CWindow::Repaint(const CRect& rect)
 
 void CWindow::Show(bool bShow)
 {
-       assert(!"TODO: CWindow::Show");
+       if( m_is_shown == bShow )
+               return;
+       
+       if( bShow )
+               m_compositor.ShowWindow( this );
+       else
+               m_compositor.HideWindow( this );
+       m_is_shown = bShow;
 }
 
 void CWindow::Move(int X, int Y)
@@ -71,5 +78,13 @@ void CWindow::KeyEvent(::uint32_t Scancode, const ::std::string &Translated, boo
 {
 }
 
+
+void CWindow::DrawScanline(unsigned int row, unsigned int x, unsigned int w, const uint8_t *data)
+{
+       m_surface.DrawScanline(row, x, w, data);
+       CRect   damaged( m_surface.m_rect.m_x+x, m_surface.m_rect.m_y+row, w, 1 );
+       m_compositor.DamageArea(damaged);
+}
+
 };
 
index 18b7d37..0d78e9c 100644 (file)
@@ -13,6 +13,7 @@ OBJ += CRect.o CSurface.o
 BIN := AxWinServer
 
 LDFLAGS += -lc++
+CXXFLAGS += -O3
 
 include ../../Makefile.tpl
 
index 040852e..a5d1ff2 100644 (file)
@@ -22,6 +22,19 @@ 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);
+       // TODO: Append to separate sub-lists (or to separate lists all together)
+       //   if flags AXWIN4_WNDFLAG_KEEPBELOW or AXWIN4_WNDFLAG_KEEPABOVE are set
+       m_windows.push_back(window);
+}
+void CCompositor::HideWindow(CWindow* window)
+{
+       DamageArea(window->m_surface.m_rect);
+       m_windows.remove(window);
+}
+
 bool CCompositor::GetScreenDims(unsigned int ScreenID, unsigned int* W, unsigned int* H)
 {
        assert(W && H);
@@ -40,10 +53,11 @@ bool CCompositor::GetScreenDims(unsigned int ScreenID, unsigned int* W, unsigned
 
 void CCompositor::Redraw()
 {
-       _SysDebug("CCompositor::Redraw");
        // Redraw the screen and clear damage rects
-       if( m_damageRects.empty() )
+       if( m_damageRects.empty() ) {
+               _SysDebug("- No damaged regions");
                return ;
+       }
        
        // Build up foreground grid (Rects and windows)
        // - This should already be built (mutated on window move/resize/reorder)
@@ -51,14 +65,14 @@ void CCompositor::Redraw()
        // For all windows, check for intersection with damage rects
        for( auto rect : m_damageRects )
        {
-               _SysDebug("rect=(%i,%i) %ix%i", rect.m_x, rect.m_y, rect.m_w, rect.m_h);
                // window list should be sorted by draw order (lowest first)
                for( auto window : m_windows )
                {
-                       if( rect.HasIntersection( window->m_surface.m_rect ) )
+                       if( window->m_is_shown && rect.HasIntersection( window->m_surface.m_rect ) )
                        {
                                // TODO: just reblit
                                CRect   rel_rect = window->m_surface.m_rect.RelativeIntersection(rect);
+                               //_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 );
                        }
index 0b773ce..7c1272a 100644 (file)
@@ -41,13 +41,15 @@ class CCompositor
        ::std::list<CWindow*>   m_windows;
 
        ::std::vector<TWindowID>        m_windowIDBuffer;       // One 32-bit value per pixel
-       //::std::vector<CPixel>         m_frameBuffer;  // Local copy of the framebuffer (needed?)
        
 public:
        CCompositor(CVideo& video);
 
        CWindow* CreateWindow(CClient& client, const ::std::string& name);
 
+       void    ShowWindow(CWindow* window);
+       void    HideWindow(CWindow* window);
+
        bool    GetScreenDims(unsigned int ScrenID, unsigned int *Width, unsigned int *Height);
 
        void    Redraw();
index 4a717d4..c4ec004 100644 (file)
@@ -20,7 +20,6 @@ class CClient_AcessIPCPipe:
 {
        friend class CIPCChannel_AcessIPCPipe;
         int    m_fd;
-       ::std::vector<uint8_t>  m_rxbuf;
 public:
        CClient_AcessIPCPipe(IIPCChannel& channel, int fd);
        ~CClient_AcessIPCPipe();
index 2248853..704f0c1 100644 (file)
@@ -38,6 +38,9 @@ public:
        void MouseMove(int NewX, int NewY);
        void KeyEvent(::uint32_t Scancode, const ::std::string &Translated, bool Down);
 
+       void DrawScanline(unsigned int row, unsigned int x, unsigned int w, const uint8_t *data);
+       
+       bool    m_is_shown;
        CSurface        m_surface;
 private:
        CCompositor&    m_compositor;
index 70605fc..732ddfd 100644 (file)
@@ -41,7 +41,6 @@ int FillSelect(fd_set& rfds)
        int ret = 0;
        for( const auto channel : glChannels )
        {
-               _SysDebug("IPC::FillSelect - channel=%p", channel);
                assert(channel);
                ret = ::std::max(ret, channel->FillSelect(rfds));
        }
@@ -122,6 +121,9 @@ void HandleMessage_GetGlobalAttr(CClient& client, CDeserialiser& message)
                reply.WriteU16( (w <= UINT16_MAX ? w : UINT16_MAX) );
                reply.WriteU16( (h <= UINT16_MAX ? h : UINT16_MAX) );
                break; }
+       case IPC_GLOBATTR_MAXAREA:
+               assert(!"TODO: IPC_GLOBATTR_MAXAREA");
+               break;
        default:
                throw IPC::CClientFailure("Bad global attribute ID");
        }
@@ -195,6 +197,15 @@ void HandleMessage_SetWindowAttr(CClient& client, CDeserialiser& message)
                int16_t new_y = message.ReadS16();
                win->Move(new_x, new_y);
                break; }
+       case IPC_WINATTR_SHOW:
+               win->Show( message.ReadU8() != 0 );
+               break;
+       case IPC_WINATTR_FLAGS:
+               _SysDebug("TODO: IPC_WINATTR_FLAGS");
+               break;
+       case IPC_WINATTR_TITLE:
+               assert(!"TODO: IPC_WINATTR_TITLE");
+               break;
        default:
                _SysDebug("HandleMessage_SetWindowAttr - Bad attr %u", attr_id);
                throw IPC::CClientFailure("Bad window attr");
@@ -233,13 +244,12 @@ void HandleMessage_PushData(CClient& client, CDeserialiser& message)
        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());
+               win->DrawScanline(y+row, x, w, scanline_data.data());
        }
 }
 void HandleMessage_Blit(CClient& client, CDeserialiser& message)
@@ -284,9 +294,7 @@ void HandleMessage(CClient& client, CDeserialiser& message)
                return ;
        }
        
-       _SysDebug("IPC::HandleMessage - command=%i", command);
        (message_handlers[command])(client, message);
-       _SysDebug("IPC::HandleMessage - Completed");
 }
 
 CClientFailure::CClientFailure(std::string&& what):
index a15774e..1b64da4 100644 (file)
@@ -111,7 +111,7 @@ int main(int argc, char *argv[])
                        timeoutp = &timeout;
                }
                else {
-                       ::_SysDebug("Calling select with no timeout");
+                       //::_SysDebug("Calling select with no timeout");
                        timeoutp = 0;
                }
                int rv = ::_SysSelect(nfd, &rfds, NULL, NULL/*&efds*/, timeoutp, 0);
index 55e3acb..8d5f5dd 100644 (file)
@@ -60,7 +60,7 @@ void CVideo::BlitLine(const uint32_t* src, unsigned int dst_y, unsigned int dst_
        size_t  cmdlen = sizeof(struct ptycmd_senddata)/4 + width;
        //_SysDebug(" - Offset = %i, cmdlen = %i", (dst_y * m_width + dst_x) * 4, cmdlen);
        struct ptycmd_senddata  cmd = {
-               {PTY2D_CMD_SEND, cmdlen & 0xFF, cmdlen>>8},
+               {PTY2D_CMD_SEND, uint8_t(cmdlen & 0xFF), uint16_t(cmdlen>>8)},
                (dst_y * m_width + dst_x)
        };
        SetBufFormat(PTYBUFFMT_2DCMD);
index 3b94448..3baf027 100644 (file)
@@ -15,13 +15,20 @@ int main(int argc, const char *argv[])
        
        tAxWin4_Window  *bgwin = AxWin4_CreateWindow("background");
        
+       unsigned int w, h;
+       AxWin4_GetScreenDimensions(0, &w, &h);
+
        AxWin4_MoveWindow(bgwin, 0,0);
-       AxWin4_ResizeWindow(bgwin, 640,480);
-       //AxWin4_SetWindowFlags(bgwin, AXWIN4_WNDFLAG_NODECORATE|AXWIN4_WNDFLAG_KEEPBELOW);
+       AxWin4_ResizeWindow(bgwin, w,h);
+       AxWin4_SetWindowFlags(bgwin, AXWIN4_WNDFLAG_NODECORATE|AXWIN4_WNDFLAG_KEEPBELOW);
+       AxWin4_ShowWindow(bgwin, true);
        
        // Load image
-       //char *image = malloc(640*480*4);
-       //AxWin4_DrawBitmap(bgwin, 0, 0, 640, 480, image);
+       uint32_t *image = malloc(w*h*4);
+       for(size_t i = 0; i < w*h; i ++ )
+               image[i] = rand();
+       
+       AxWin4_DrawBitmap(bgwin, 0, 0, w, h, (void*)image);
 
        _SysDebug("Beginning queue");
        
index 431fce5..f0ec6d7 100644 (file)
@@ -13,6 +13,7 @@
 namespace AxWin {
 
 extern void    SendMessage(CSerialiser& message);
+extern void    RecvMessage(CDeserialiser& message);
 
 };
 
index 1bcf6f7..e531db0 100644 (file)
@@ -1,4 +1,9 @@
 /*
+ * Acess2 GUIv4 (AxWin4)
+ * - By John Hodge (thePowersGang)
+ *
+ * axwin4/axwin.h
+ * - Client library interface header
  */
 #ifndef _LIBAXWIN4_AXWIN4_AXWIN_H_
 #define _LIBAXWIN4_AXWIN4_AXWIN_H_
@@ -19,13 +24,20 @@ extern bool AxWin4_Connect(const char *URI);
 extern bool    AxWin4_WaitEventQueue(uint64_t Timeout);        
 extern bool    AxWin4_WaitEventQueueSelect(int nFDs, fd_set *rfds, fd_set *wfds, fd_set *efds, uint64_t Timeout);
 
+extern void    AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *Width, unsigned int *Height);
+
 extern tAxWin4_Window  *AxWin4_CreateWindow(const char *Name);
-extern void    AxWin4_ShowWindow(tAxWin4_Window *Window);
+extern void    AxWin4_DestroyWindow(tAxWin4_Window *Window);
+extern void    AxWin4_ShowWindow(tAxWin4_Window *Window, bool Shown);
+extern void    AxWin4_SetWindowFlags(tAxWin4_Window *Window, unsigned int NewFlags);
 extern void    AxWin4_SetTitle(tAxWin4_Window *Window, const char *Title);
 extern void    AxWin4_MoveWindow(tAxWin4_Window *Window, int X, int Y);
 extern void    AxWin4_ResizeWindow(tAxWin4_Window *Window, unsigned int W, unsigned int H);
+
 extern void    AxWin4_DrawBitmap(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, void *Data);
 
+#include "definitions.h"
+
 
 #ifdef __cplusplus
 }
diff --git a/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/definitions.h b/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/definitions.h
new file mode 100644 (file)
index 0000000..8e347cf
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 GUIv4 (AxWin4)
+ * - By John Hodge (thePowersGang)
+ *
+ * axwin4/definitions.h
+ * - Shared definitions (Client and server)
+ */
+#ifndef _LIBAXWIN4_AXWIN4_DEFINITIONS_H_
+#define _LIBAXWIN4_AXWIN4_DEFINITIONS_H_
+
+#define AXWIN4_WNDFLAG_NODECORATE      0x01
+#define AXWIN4_WNDFLAG_KEEPBELOW       0x02
+#define AXWIN4_WNDFLAG_KEEPABOVE       0x04
+
+#endif
+
index 10331fb..d6df7f8 100644 (file)
@@ -9,7 +9,10 @@
 #include "include/common.hpp"
 #include "include/IIPCChannel.hpp"
 #include "include/CIPCChannel_AcessIPCPipe.hpp"
+#include <ipc_proto.hpp>
 #include <algorithm>
+#include <mutex>
+#include <stdexcept>
 
 #include <cstring>
 #include <cstdio>
@@ -17,6 +20,9 @@
 namespace AxWin {
 
 IIPCChannel*   gIPCChannel;
+::std::mutex   glSyncReply;
+bool   gSyncReplyValid;
+CDeserialiser  gSyncReplyBuf;
 
 extern "C" bool AxWin4_Connect(const char *URI)
 {
@@ -50,7 +56,7 @@ extern "C" bool AxWin4_PeekEventQueue(void)
 
 extern "C" bool AxWin4_WaitEventQueue(uint64_t Timeout)
 {
-       AxWin4_WaitEventQueueSelect(0, NULL, NULL, NULL, Timeout);
+       return AxWin4_WaitEventQueueSelect(0, NULL, NULL, NULL, Timeout);
 }
 
 extern "C" bool AxWin4_WaitEventQueueSelect(int nFDs, fd_set *rfds, fd_set *wfds, fd_set *efds, uint64_t Timeout)
@@ -73,6 +79,70 @@ void SendMessage(CSerialiser& message)
 {
        gIPCChannel->Send(message);
 }
+void RecvMessage(CDeserialiser& message)
+{
+       uint8_t id = message.ReadU8();
+       switch(id)
+       {
+       case IPCMSG_REPLY:
+               // Flag reply and take a copy of this message
+               if( gSyncReplyValid )
+               {
+                       // Oh... that was unexpected
+                       _SysDebug("Unexpected second reply message %i", message.ReadU8());
+               }
+               else
+               {
+                       gSyncReplyValid = true;
+                       gSyncReplyBuf = message;
+               }
+               break;
+       default:
+               _SysDebug("TODO: RecvMessage(%i)", id);
+               break;
+       }
+}
+
+CDeserialiser GetSyncReply(CSerialiser& request, unsigned int Message)
+{
+       ::std::lock_guard<std::mutex>   lock(glSyncReply);
+       gSyncReplyValid = false;
+       // Send once lock is acquired
+       SendMessage(request);
+       
+       while( !gSyncReplyValid )
+       {
+               // Tick along
+               if( !AxWin4_WaitEventQueue(0) )
+                       throw ::std::runtime_error("Connection dropped while waiting for reply");
+       }
+       
+       uint8_t id = gSyncReplyBuf.ReadU8();
+       if( id != Message )
+       {
+               _SysDebug("Unexpected reply message '%i', message.ReadU8()");
+       }
+       
+       return gSyncReplyBuf;
+}
+
+extern "C" void AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *Width, unsigned int *Height)
+{
+       CSerialiser     req;
+       req.WriteU8(IPCMSG_GETGLOBAL);
+       req.WriteU16(IPC_GLOBATTR_SCREENDIMS);
+       req.WriteU8(ScreenIndex);
+       
+       CDeserialiser   response = GetSyncReply(req, IPCMSG_GETGLOBAL);
+       if( response.ReadU16() != IPC_GLOBATTR_SCREENDIMS ) {
+               
+       }
+       
+       *Width = response.ReadU16();
+       *Height = response.ReadU16();
+       
+       _SysDebug("AxWin4_GetScreenDimensions: %i = %ix%i", ScreenIndex, *Width, *Height);
+}
 
 IIPCChannel::~IIPCChannel()
 {
index 09cebca..4b4bc71 100644 (file)
@@ -5,6 +5,7 @@
  * ipc_acessipcpipe.c
  * - Acess2 /Devices/ipcpipe/ IPC Channel
  */
+#include "include/common.hpp"
 #include "include/CIPCChannel_AcessIPCPipe.hpp"
 #include <system_error>
 #include <cerrno>
@@ -33,6 +34,16 @@ bool CIPCChannel_AcessIPCPipe::HandleSelect(const fd_set& fds)
 {
        if( FD_ISSET(m_fd, &fds) )
        {
+               ::std::vector<uint8_t>  rxbuf(4096);
+               size_t len = _SysRead(m_fd, rxbuf.data(), rxbuf.capacity());
+               if( len == (size_t)-1 )
+                       throw ::std::system_error(errno, ::std::system_category());
+               rxbuf.resize(len);
+               _SysDebug("CClient_AcessIPCPipe::HandleReceive - Rx %i/%i bytes", len, rxbuf.capacity());
+               _SysDebugHex("CClient_AcessIPCPipe::HandleReceive", rxbuf.data(), len);
+               
+               CDeserialiser   msg(rxbuf);
+               ::AxWin::RecvMessage( msg );
        }
        return true;
 }
@@ -44,6 +55,8 @@ void CIPCChannel_AcessIPCPipe::Send(CSerialiser& message)
                throw ::std::length_error("CIPCChannel_AcessIPCPipe::Send");
        }
        _SysDebug("CIPCChannel_AcessIPCPipe::Send(%i bytes)", serialised.size());
+       //_SysDebugHex("CIPCChannel_AcessIPCPipe::Send",     serialised.data(), serialised.size());
+       
        size_t rv = _SysWrite(m_fd, serialised.data(), serialised.size());
        if( rv != serialised.size() ) {
                throw ::std::system_error(errno, ::std::system_category());
index 2144eb7..f023ea8 100644 (file)
@@ -8,16 +8,33 @@
 #include <axwin4/axwin.h>
 #include "include/common.hpp"
 #include <ipc_proto.hpp>
+#include <vector>
+#include <algorithm>
+#include <mutex>
 
 namespace AxWin {
 
+static const int       MAX_WINDOW_ID = 16;
+static ::std::mutex    glWindowList;
+static ::std::vector<tAxWin4_Window*>  gWindowList;
+
 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();
+       if( id >= MAX_WINDOW_ID ) {
+               throw ::std::runtime_error("AxWin4_CreateWindow - Out of IDs (TODO: Better exception)");
+       }
+       if( id == gWindowList.size() )
+       {
+               gWindowList.push_back(nullptr);
+       }
        
        // Create window structure locally
        tAxWin4_Window *ret = new tAxWin4_Window();
-       ret->m_id = 0;
+       gWindowList[id] = ret;
+       ret->m_id = id;
        // Request creation of window
        CSerialiser     message;
        message.WriteU8(IPCMSG_CREATEWIN);
@@ -27,13 +44,23 @@ extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name)
        return ret;
 }
 
-extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window)
+extern "C" void AxWin4_ShowWindow(tAxWin4_Window *Window, bool Show)
 {
        CSerialiser     message;
        message.WriteU8(IPCMSG_SETWINATTR);
        message.WriteU16(Window->m_id);
        message.WriteU16(IPC_WINATTR_SHOW);
-       message.WriteU8(1);
+       message.WriteU8( (Show ? 1 : 0) );
+       ::AxWin::SendMessage(message);
+}
+
+extern "C" void AxWin4_SetWindowFlags(tAxWin4_Window *Window, unsigned int Flags)
+{
+       CSerialiser     message;
+       message.WriteU8(IPCMSG_SETWINATTR);
+       message.WriteU16(Window->m_id);
+       message.WriteU16(IPC_WINATTR_FLAGS);
+       message.WriteU8( Flags );
        ::AxWin::SendMessage(message);
 }
 
index e04b670..6d070de 100644 (file)
@@ -13,7 +13,7 @@ LIBS     += -lc $(LIBGCC_PATH) $(CRTEND) $(CRTN)
 USE_CXX_LINK := yes\r
 \r
 OBJ  = misc.o new.o guard.o cxxabi.o typeinfo.o\r
-OBJ += string.o\r
+OBJ += string.o mutex.o\r
 OBJ += exceptions.o exception_handling.o system_error.o\r
 OBJ += gxx_personality.o\r
 DEPFILES := $(OBJ:%.o=%.d)\r
index f570f34..117ceeb 100644 (file)
@@ -57,3 +57,9 @@ void ::std::terminate()
        logic_error(what_str)
 {
 }
+
+::std::runtime_error::runtime_error(const ::std::string& what_str):
+       exception(what_str)
+{
+}
+
index d2f8b23..755337d 100644 (file)
@@ -20,5 +20,11 @@ extern void abort() __asm__ ("abort") __attribute__((noreturn));
 extern void debug(const char *, ...);
 };
 
+#if _CXX11_AVAIL
+#define _CXX11_MOVE(val)       ::std::move(val)
+#else
+#define _CXX11_MOVE(val)       val
+#endif
+
 #endif
 
index b02f5b0..c08e28f 100644 (file)
@@ -2,14 +2,51 @@
  * Acess2 C++ Library
  * - By John Hodge (thePowersGang)
  *
- * string (header)
- * - C++'s String type
+ * algorithm (header)
+ * - C++'s generic algorithms
  */
 #ifndef _LIBCXX_ALGORITHM_
 #define _LIBCXX_ALGORITHM_
 
+#include <utility>
+
+#include "_libcxx_helpers.h"
+
 namespace std {
 
+// --- Non-modifiying sequence operations ---
+#if _CXX11_AVAIL
+// TODO: all_of
+// TODO: any_of
+// TODO: none_of
+#endif
+template <class InputIterator, class Function>
+Function for_each(InputIterator first, InputIterator last, Function fn)
+{
+       while( first != last )
+       {
+               fn( *first );
+               ++ first;
+       }
+       return _CXX11_MOVE(fn);
+}
+
+template <class InputIterator, class T>
+InputIterator find(InputIterator first, InputIterator last, const T& val)
+{
+       while( first != last )
+       {
+               if( *first == val )
+                       return first;
+               ++ first;
+       }
+       return last;
+}
+// TODO: find_if
+// TODO: find_if_not (C++11)
+// TODO: find_end
+// TODO: find_first_of
+
 // Maximum
 template <class T>
 const T& max(const T& a, const T& b)
index 0ed1bcd..1608a3c 100644 (file)
@@ -85,59 +85,9 @@ class allocator_noconstruct:
        public ::std::_bits::allocator_real<T>
 {
 public:
-/*
-       typedef T       value_type;
-       typedef T*      pointer;
-       typedef T&      reference;
-       typedef const T* const_pointer;
-       typedef const T&        const_reference;
-       typedef size_t  size_type;
-       typedef ptrdiff_t       difference_type;
-
-       template <class Type>
-       struct rebind
-       {
-               typedef allocator<Type> other;
-       };
-       
-       allocator_noconstruct() throw() {
-       }
-       allocator_noconstruct(const allocator_noconstruct& alloc __attribute__((unused))) throw() {
-       }
-       template <class U>
-       allocator_noconstruct(const allocator_noconstruct<U>& alloc) throw() {
-       }
-       ~allocator_noconstruct() throw() {
-       }
-
-       pointer address(reference x) const {
-               return &x;
-       }
-       const_pointer address(const_reference x) const {
-               return &x;
-       }
-       pointer allocate(size_type n, const void* hint=0) {
-               hint = hint;
-               return static_cast<pointer>( ::operator new (n * sizeof(value_type)) );
-       }
-       void deallocate(pointer p, size_type n) {
-               n=n;
-               ::operator delete(p);
-       }
-       size_type max_size() {
-               return ((size_type)-1) / sizeof(value_type);
-       }
-*/
-
        void construct( typename allocator_real<T>::pointer p, typename allocator_real<T>::const_reference val ) {
                *p = val;
        }
-       // C++11
-       #if _CXX11_AVAIL
-       template<class U, class... Args>
-       void construct( U* p, Args&&... args ) {
-       }
-       #endif
        void destroy(typename allocator_real<T>::pointer p) {
        }
 };
@@ -150,6 +100,7 @@ class allocator:
 {
 };
 
+#if 1
 template <>
 class allocator<unsigned char>:
        public _bits::allocator_noconstruct<unsigned char>
@@ -160,6 +111,7 @@ class allocator<unsigned long>:
        public _bits::allocator_noconstruct<unsigned long>
 {
 };
+#endif
 
 };
 
index f63e31d..181f0e4 100644 (file)
@@ -173,6 +173,53 @@ public:
                }
                m_item_count = 0;
        }
+
+       void splice(iterator position, list& x) {
+               splice(position, x, x.begin(), x.end());
+       }
+       void splice(iterator position, list& x, iterator i) {
+               splice(position, x, i, x.end());
+       }
+       void splice(iterator position, list& x, iterator first, iterator last);
+
+private:
+       class _equal
+       {
+               const value_type&       m_val;
+       public:
+               _equal(const value_type& val):
+                       m_val(val)
+               {
+               };
+               bool operator() (const value_type& v1)
+               {
+                       return m_val == v1;
+               }
+       };
+public:
+       void remove(const value_type& val) {
+               remove_if(_equal(val));
+       }
+       template <class Predicate> void remove_if(Predicate pred) {
+               for( iterator it = begin(); it != end(); )
+               {
+                       if( pred(*it) )
+                               it = erase(it);
+                       else
+                               ++ it;
+               }
+       }
+       
+       void unique();
+       template <class BinaryPredicate> void unique(BinaryPredicate binary_pred);
+       
+       void merge(list& x);
+       template <class Compare> void merge(list& x, Compare comp);
+       
+       void sort();
+       template <class Compare> void sort(Compare comp);
+       
+       void reverse() throw();
 private:
        iterator insert_item(iterator position, item_type *newi) {
                m_item_count ++;
diff --git a/Usermode/Libraries/libc++.so_src/include_exp/mutex b/Usermode/Libraries/libc++.so_src/include_exp/mutex
new file mode 100644 (file)
index 0000000..d3d9ffd
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * mutex (header)
+ * - C++11's tutex handling
+ */
+#ifndef _LIBCXX_MUTEX_
+#define _LIBCXX_MUTEX_
+
+#include "_libcxx_helpers.h"
+
+#if !_CXX11_AVAIL
+# error        "<mutex> requires C++11 support"
+#endif
+
+namespace std {
+
+#if _CXX11_AVAIL
+
+class mutex
+{
+public:
+       constexpr mutex() noexcept:
+               m_flag(false)
+       {
+       }
+       mutex(const mutex&) = delete;
+       mutex& operator=(const mutex&) = delete;
+       ~mutex();
+       
+       void lock();
+       bool try_lock();
+       void unlock();
+
+       typedef void*   native_handle;
+private:
+       // TODO: Proper userland mutex support
+       bool    m_flag;
+};
+
+struct defer_lock_t {};
+struct try_to_lock_t {};
+struct adopt_lock_t {};
+
+template< class Mutex >
+class lock_guard
+{
+public:
+       typedef Mutex   mutex_type;
+private:
+       mutex_type&     m_lock;
+public:
+       lock_guard(mutex_type& m):
+               m_lock(m)
+       {
+               m_lock.lock();
+       }
+       lock_guard(mutex_type& m, std::adopt_lock_t t):
+               m_lock(m)
+       {
+               // Adopted
+       }
+       ~lock_guard() {
+               m_lock.unlock();
+       }
+};
+
+#endif
+
+};     // namespace std
+
+#endif
+
+// vim: ft=cpp
+
index d5a21db..f1ed0ab 100644 (file)
 
 //extern void* operator new(size_t size) throw (::std::bad_alloc);
 //extern void* operator new(size_t size, const std::nothrow_t& nothrow_value) throw();
-extern void* operator new(size_t size, void* ptr) throw();
+inline void* operator new(size_t /*size*/, void* ptr) throw() {
+       return ptr;
+}
 
 //extern void* operator new[](size_t size) throw (::std::bad_alloc);
 //extern void* operator new[](size_t size, const std::nothrow_t& nothrow_value) throw();
-extern void* operator new[](size_t size, void* ptr) throw();
+inline void* operator new[](size_t /*size*/, void* ptr) throw() {
+       return ptr;
+}
 
 #endif
 
index 426fd57..c058d0c 100644 (file)
@@ -16,10 +16,15 @@ extern "C" void _SysDebug(const char *, ...);
 namespace std {
 
 namespace _bits {
-template <class T, typename size_type>
+template <class VectorType, class T>
 class vector_iterator//:
        //public random_acess_iterator_tag
 {
+       friend VectorType;
+       
+       typedef typename VectorType::size_type  size_type;
+       typedef typename VectorType::difference_type    difference_type;
+       
        T*      m_array;
        size_type       m_pos;
        size_type       m_max;
@@ -58,19 +63,71 @@ public:
        T& operator->() const {
                return m_array[m_pos];
        }
+       T& operator[](difference_type n) {
+               return *(*this + n);
+       }
        vector_iterator& operator++() {
                if(m_pos < m_max) {
                        m_pos ++;
                }
                return *this;
        }
+       const vector_iterator operator++(int) {
+               vector_iterator ret(*this);
+               ++*this;
+               return ret;
+       }
        vector_iterator& operator--() {
                if(m_pos > 0) {
                        m_pos --;
                }
                return *this;
        }
+       const vector_iterator operator--(int) {
+               vector_iterator ret(*this);
+               --*this;
+               return ret;
+       }
+       vector_iterator& operator+=(difference_type n) {
+               if( n < 0 )
+                       return (*this -= -n);
+               if( n > 0 )
+                       m_pos = (m_pos + n < m_max ? m_pos + n : m_max); 
+               return *this;
+       }
+       vector_iterator& operator-=(difference_type n) {
+               if( n < 0 )
+                       return (*this += -n);
+               if( n > 0 )
+                       m_pos = (m_pos >= n ? m_pos - n : 0);
+               return *this;
+       }
+       const difference_type operator-(const vector_iterator& it2) const {
+               //_libcxx_assert(m_array == it2.m_array);
+               return m_pos - it2.m_pos;
+       }
+       bool operator<(const vector_iterator& o) const { return m_pos < o.m_pos; }
+       bool operator>(const vector_iterator& o) const { return m_pos > o.m_pos; }
+       bool operator<=(const vector_iterator& o) const { return m_pos <= o.m_pos; }
+       bool operator>=(const vector_iterator& o) const { return m_pos >= o.m_pos; }
 };
+#define vector_iterator_tpl class VectorType, class T
+#define vector_iterator        vector_iterator<VectorType, T>
+template <vector_iterator_tpl>
+const vector_iterator operator+(const vector_iterator& it, typename VectorType::difference_type n) {
+       return vector_iterator(it) += n;
+}
+template <vector_iterator_tpl>
+const vector_iterator operator+(typename VectorType::difference_type n, const vector_iterator& it) {
+       return vector_iterator(it) += n;
+}
+template <vector_iterator_tpl>
+const vector_iterator operator-(const vector_iterator& it, typename VectorType::difference_type n) {
+       return vector_iterator(it) -= n;
+}
+#undef vector_iterator_tpl
+#undef vector_iterator
+
 }
 
 template <class T, class Alloc = allocator<T> >
@@ -85,8 +142,8 @@ public:
        typedef typename allocator_type::const_pointer  const_pointer;
        typedef int     difference_type;
        typedef size_t  size_type;
-       typedef ::std::_bits::vector_iterator<T,size_type>      iterator;
-       typedef ::std::_bits::vector_iterator<const T,size_type>        const_iterator;
+       typedef ::std::_bits::vector_iterator<vector,T> iterator;
+       typedef ::std::_bits::vector_iterator<vector,const T>   const_iterator;
 
 private:
        allocator_type  m_alloc;
@@ -107,31 +164,54 @@ public:
        {
                resize(n, val);
        }
+       template <class InputIterator>
+       vector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()):
+               vector(alloc)
+       {
+               insert(begin(), first, last);
+       }
        vector(const vector& x):
                vector(x.m_alloc)
        {
                *this = x;
        }
+       #if _CXX11_AVAIL
+       vector(vector&& x):
+               m_alloc(x.m_alloc),
+               m_size(x.m_size),
+               m_capacity(x.m_capacity),
+               m_data(x.m_data)
+       {
+               x.m_data = nullptr;
+               x.m_capacity = 0;
+               x.m_size = 0;
+       }
+       #endif
+       vector& operator=(const vector& x)
+       {
+               clear();
+               m_alloc.deallocate(m_data, m_capacity);
+               m_capacity = 0;
+               
+               reserve(x.size());
+               for( size_type i = 0; i < x.size(); i ++ )
+                       push_back( x[i] );
+               
+               return *this;
+       }
        
        ~vector()
        {
                clear();
                m_alloc.deallocate(m_data, m_capacity);
+               m_capacity = 0;
        }
        
        // Iterators
-       iterator begin() {
-               return iterator(m_data, 0, m_size);
-       }
-       const_iterator begin() const {
-               return const_iterator(m_data, 0, m_size);
-       }
-       iterator end() {
-               return iterator(m_data, m_size, m_size);
-       }
-       const_iterator end() const {
-               return const_iterator(m_data, m_size, m_size);
-       }
+       iterator       begin()       { return iterator_to(0); }
+       const_iterator begin() const { return iterator_to(0); }
+       iterator       end()       { return iterator_to(m_size); }
+       const_iterator end() const { return iterator_to(m_size); }
        
        // Capacity
        size_type size() const {
@@ -229,10 +309,44 @@ public:
                }
        }
        iterator insert(iterator position, const value_type& val) {
-               inesert(position, 1, val);
-               return position;
+               insert(position, 1, val);
+               return iterator_to(position.m_pos);
+       }
+       void insert(iterator position, size_type n, const value_type& val) {
+               reserve(m_size + n);
+               if( position != end() ) {
+                       ::_sys::debug("TODO: vector::insert within vector (%i!=%i)",
+                               position-begin(), end()-begin());
+                       ::_sys::abort();
+               }
+               size_type       pos = m_size;
+               while( n -- )
+               {
+                       //::_sys::debug("vector::insert - %x at %i", val, pos);
+                       m_alloc.construct( &m_data[pos], val );
+                       pos ++;
+                       m_size ++;
+               }
+       }
+       template <class InputIterator>
+       void insert(iterator position, InputIterator first, InputIterator last) {
+               InputIterator   it = first;
+               size_type       len = 0;
+               while(it != last) {
+                       ++ it;
+                       len ++;
+               }
+               reserve(m_size + len);
+               
+               it = first;
+               while(it != last)
+               {
+                       //::_sys::debug("vector::insert - to %i, from %p:%i",
+                       //      position.m_pos, it.m_array, it.m_pos);
+                       position = insert(position, *it) + 1;
+                       ++it;
+               }
        }
-       void insert(iterator position, size_type n, const value_type& val);
        iterator erase(iterator position);
        iterator erase(iterator first, iterator last);
        //void swap(vector& x) {
@@ -246,6 +360,15 @@ public:
                }
                m_size = 0;
        }
+private:
+       iterator iterator_to(size_type index) {
+               _libcxx_assert(index <= m_size);
+               return iterator(m_data, index, m_size);
+       }
+       const_iterator iterator_to(size_type index) const {
+               _libcxx_assert(index <= m_size);
+               return const_iterator(m_data, index, m_size);
+       }
 };
 
 };     // namespace std
diff --git a/Usermode/Libraries/libc++.so_src/mutex.cc b/Usermode/Libraries/libc++.so_src/mutex.cc
new file mode 100644 (file)
index 0000000..5ff27df
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * mutex.cc
+ * - ::std::mutex and helpers
+ */
+#include <mutex>
+#include <system_error>
+#include <cerrno>
+
+// === CODE ===
+::std::mutex::~mutex()
+{
+       
+}
+
+void ::std::mutex::lock()
+{
+       if( m_flag )
+       {
+               _sys::debug("TODO: userland mutexes");
+               throw ::std::system_error(ENOTIMPL, ::std::system_category());
+       }
+       m_flag = true;
+}
+
+bool ::std::mutex::try_lock()
+{
+       bool rv = m_flag;
+       m_flag = true;
+       return !rv;
+}
+
+void ::std::mutex::unlock()
+{
+       m_flag = false;
+}
+

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