From: John Hodge Date: Sat, 21 Jun 2014 15:39:25 +0000 (+0800) Subject: Usermode/AxWin4 - Screen dimensions acquisition, speedup, window render X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=145dd00e5c5a36f844be327e16a00b2983245423;p=tpg%2Facess2.git Usermode/AxWin4 - Screen dimensions acquisition, speedup, window render --- diff --git a/Usermode/Applications/axwin4_src/Common/include/serialisation.hpp b/Usermode/Applications/axwin4_src/Common/include/serialisation.hpp index c1478096..5ccef67e 100644 --- a/Usermode/Applications/axwin4_src/Common/include/serialisation.hpp +++ b/Usermode/Applications/axwin4_src/Common/include/serialisation.hpp @@ -23,11 +23,16 @@ class CDeserialiseException: class CDeserialiser { - const size_t m_length; - const uint8_t* m_data; + ::std::vector m_vect; size_t m_offset; public: - CDeserialiser(size_t Length, const uint8_t *Buffer); + CDeserialiser(): + CDeserialiser(::std::vector()) + {} + CDeserialiser(const ::std::vector& vect); + CDeserialiser(::std::vector&& vect); + CDeserialiser(const CDeserialiser& x) { *this = x; }; + CDeserialiser& operator=(const CDeserialiser& x); bool IsConsumed() const; ::uint8_t ReadU8(); ::uint16_t ReadU16(); diff --git a/Usermode/Applications/axwin4_src/Common/serialisation.cpp b/Usermode/Applications/axwin4_src/Common/serialisation.cpp index 9f536b5d..f23d5cd8 100644 --- a/Usermode/Applications/axwin4_src/Common/serialisation.cpp +++ b/Usermode/Applications/axwin4_src/Common/serialisation.cpp @@ -12,22 +12,31 @@ namespace AxWin { -CDeserialiser::CDeserialiser(size_t Length, const uint8_t *Buffer): - m_length(Length), - m_data(Buffer), +CDeserialiser::CDeserialiser(const ::std::vector& vector): + m_vect(vector), m_offset(0) { } +CDeserialiser::CDeserialiser(::std::vector&& 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 CDeserialiser::ReadBuffer() RangeCheck("CDeserialiser::ReadBuffer(len)", 2); size_t size = ReadU16(); - ::std::vector 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 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(m_data+m_offset), len ); + ::std::string ret( reinterpret_cast(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); } } diff --git a/Usermode/Applications/axwin4_src/Server/CClient.cpp b/Usermode/Applications/axwin4_src/Server/CClient.cpp index 92898b11..6c9fe685 100644 --- a/Usermode/Applications/axwin4_src/Server/CClient.cpp +++ b/Usermode/Applications/axwin4_src/Server/CClient.cpp @@ -24,7 +24,6 @@ CClient::~CClient() CWindow* CClient::GetWindow(int ID) { - _SysDebug("GetWindow(ID=%i)", ID); try { return m_windows.at(ID); } diff --git a/Usermode/Applications/axwin4_src/Server/CIPCChannel_AcessIPCPipe.cpp b/Usermode/Applications/axwin4_src/Server/CIPCChannel_AcessIPCPipe.cpp index a9818cdb..df94958c 100644 --- a/Usermode/Applications/axwin4_src/Server/CIPCChannel_AcessIPCPipe.cpp +++ b/Usermode/Applications/axwin4_src/Server/CIPCChannel_AcessIPCPipe.cpp @@ -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& 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 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 ); } }; diff --git a/Usermode/Applications/axwin4_src/Server/CRect.cpp b/Usermode/Applications/axwin4_src/Server/CRect.cpp index 6f504d85..acbcc27e 100644 --- a/Usermode/Applications/axwin4_src/Server/CRect.cpp +++ b/Usermode/Applications/axwin4_src/Server/CRect.cpp @@ -7,6 +7,7 @@ */ #include #include +#include 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) diff --git a/Usermode/Applications/axwin4_src/Server/CWindow.cpp b/Usermode/Applications/axwin4_src/Server/CWindow.cpp index db43bac8..f70db321 100644 --- a/Usermode/Applications/axwin4_src/Server/CWindow.cpp +++ b/Usermode/Applications/axwin4_src/Server/CWindow.cpp @@ -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); +} + }; diff --git a/Usermode/Applications/axwin4_src/Server/Makefile b/Usermode/Applications/axwin4_src/Server/Makefile index 18b7d370..0d78e9c6 100644 --- a/Usermode/Applications/axwin4_src/Server/Makefile +++ b/Usermode/Applications/axwin4_src/Server/Makefile @@ -13,6 +13,7 @@ OBJ += CRect.o CSurface.o BIN := AxWinServer LDFLAGS += -lc++ +CXXFLAGS += -O3 include ../../Makefile.tpl diff --git a/Usermode/Applications/axwin4_src/Server/compositor.cpp b/Usermode/Applications/axwin4_src/Server/compositor.cpp index 040852ef..a5d1ff2d 100644 --- a/Usermode/Applications/axwin4_src/Server/compositor.cpp +++ b/Usermode/Applications/axwin4_src/Server/compositor.cpp @@ -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 ); } diff --git a/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp b/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp index 0b773cef..7c1272a6 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp @@ -41,13 +41,15 @@ class CCompositor ::std::list m_windows; ::std::vector m_windowIDBuffer; // One 32-bit value per pixel - //::std::vector 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(); diff --git a/Usermode/Applications/axwin4_src/Server/include/CIPCChannel_AcessIPCPipe.hpp b/Usermode/Applications/axwin4_src/Server/include/CIPCChannel_AcessIPCPipe.hpp index 4a717d43..c4ec0042 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CIPCChannel_AcessIPCPipe.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CIPCChannel_AcessIPCPipe.hpp @@ -20,7 +20,6 @@ class CClient_AcessIPCPipe: { friend class CIPCChannel_AcessIPCPipe; int m_fd; - ::std::vector m_rxbuf; public: CClient_AcessIPCPipe(IIPCChannel& channel, int fd); ~CClient_AcessIPCPipe(); diff --git a/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp b/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp index 2248853b..704f0c16 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp @@ -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; diff --git a/Usermode/Applications/axwin4_src/Server/ipc.cpp b/Usermode/Applications/axwin4_src/Server/ipc.cpp index 70605fc0..732ddfd1 100644 --- a/Usermode/Applications/axwin4_src/Server/ipc.cpp +++ b/Usermode/Applications/axwin4_src/Server/ipc.cpp @@ -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 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): diff --git a/Usermode/Applications/axwin4_src/Server/main.cpp b/Usermode/Applications/axwin4_src/Server/main.cpp index a15774ec..1b64da4e 100644 --- a/Usermode/Applications/axwin4_src/Server/main.cpp +++ b/Usermode/Applications/axwin4_src/Server/main.cpp @@ -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); diff --git a/Usermode/Applications/axwin4_src/Server/video.cpp b/Usermode/Applications/axwin4_src/Server/video.cpp index 55e3acbc..8d5f5dd2 100644 --- a/Usermode/Applications/axwin4_src/Server/video.cpp +++ b/Usermode/Applications/axwin4_src/Server/video.cpp @@ -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); diff --git a/Usermode/Applications/axwin4_src/UI/main.c b/Usermode/Applications/axwin4_src/UI/main.c index 3b94448f..3baf0279 100644 --- a/Usermode/Applications/axwin4_src/UI/main.c +++ b/Usermode/Applications/axwin4_src/UI/main.c @@ -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"); diff --git a/Usermode/Libraries/libaxwin4.so_src/include/common.hpp b/Usermode/Libraries/libaxwin4.so_src/include/common.hpp index 431fce58..f0ec6d77 100644 --- a/Usermode/Libraries/libaxwin4.so_src/include/common.hpp +++ b/Usermode/Libraries/libaxwin4.so_src/include/common.hpp @@ -13,6 +13,7 @@ namespace AxWin { extern void SendMessage(CSerialiser& message); +extern void RecvMessage(CDeserialiser& message); }; diff --git a/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h b/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h index 1bcf6f73..e531db0e 100644 --- a/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h +++ b/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h @@ -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 index 00000000..8e347cf2 --- /dev/null +++ b/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/definitions.h @@ -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 + diff --git a/Usermode/Libraries/libaxwin4.so_src/ipc.cpp b/Usermode/Libraries/libaxwin4.so_src/ipc.cpp index 10331fb3..d6df7f86 100644 --- a/Usermode/Libraries/libaxwin4.so_src/ipc.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/ipc.cpp @@ -9,7 +9,10 @@ #include "include/common.hpp" #include "include/IIPCChannel.hpp" #include "include/CIPCChannel_AcessIPCPipe.hpp" +#include #include +#include +#include #include #include @@ -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 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() { diff --git a/Usermode/Libraries/libaxwin4.so_src/ipc_acessipcpipe.cpp b/Usermode/Libraries/libaxwin4.so_src/ipc_acessipcpipe.cpp index 09cebcae..4b4bc71a 100644 --- a/Usermode/Libraries/libaxwin4.so_src/ipc_acessipcpipe.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/ipc_acessipcpipe.cpp @@ -5,6 +5,7 @@ * ipc_acessipcpipe.c * - Acess2 /Devices/ipcpipe/ IPC Channel */ +#include "include/common.hpp" #include "include/CIPCChannel_AcessIPCPipe.hpp" #include #include @@ -33,6 +34,16 @@ bool CIPCChannel_AcessIPCPipe::HandleSelect(const fd_set& fds) { if( FD_ISSET(m_fd, &fds) ) { + ::std::vector 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()); diff --git a/Usermode/Libraries/libaxwin4.so_src/wm.cpp b/Usermode/Libraries/libaxwin4.so_src/wm.cpp index 2144eb74..f023ea81 100644 --- a/Usermode/Libraries/libaxwin4.so_src/wm.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/wm.cpp @@ -8,16 +8,33 @@ #include #include "include/common.hpp" #include +#include +#include +#include namespace AxWin { +static const int MAX_WINDOW_ID = 16; +static ::std::mutex glWindowList; +static ::std::vector gWindowList; + extern "C" tAxWin4_Window *AxWin4_CreateWindow(const char *Name) { // Allocate a window ID + ::std::lock_guard 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); } diff --git a/Usermode/Libraries/libc++.so_src/Makefile b/Usermode/Libraries/libc++.so_src/Makefile index e04b6700..6d070de1 100644 --- a/Usermode/Libraries/libc++.so_src/Makefile +++ b/Usermode/Libraries/libc++.so_src/Makefile @@ -13,7 +13,7 @@ LIBS += -lc $(LIBGCC_PATH) $(CRTEND) $(CRTN) USE_CXX_LINK := yes OBJ = misc.o new.o guard.o cxxabi.o typeinfo.o -OBJ += string.o +OBJ += string.o mutex.o OBJ += exceptions.o exception_handling.o system_error.o OBJ += gxx_personality.o DEPFILES := $(OBJ:%.o=%.d) diff --git a/Usermode/Libraries/libc++.so_src/exceptions.cc b/Usermode/Libraries/libc++.so_src/exceptions.cc index f570f341..117ceeb2 100644 --- a/Usermode/Libraries/libc++.so_src/exceptions.cc +++ b/Usermode/Libraries/libc++.so_src/exceptions.cc @@ -57,3 +57,9 @@ void ::std::terminate() logic_error(what_str) { } + +::std::runtime_error::runtime_error(const ::std::string& what_str): + exception(what_str) +{ +} + diff --git a/Usermode/Libraries/libc++.so_src/include_exp/_libcxx_helpers.h b/Usermode/Libraries/libc++.so_src/include_exp/_libcxx_helpers.h index d2f8b230..755337df 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/_libcxx_helpers.h +++ b/Usermode/Libraries/libc++.so_src/include_exp/_libcxx_helpers.h @@ -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 diff --git a/Usermode/Libraries/libc++.so_src/include_exp/algorithm b/Usermode/Libraries/libc++.so_src/include_exp/algorithm index b02f5b0d..c08e28f3 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/algorithm +++ b/Usermode/Libraries/libc++.so_src/include_exp/algorithm @@ -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 + +#include "_libcxx_helpers.h" + namespace std { +// --- Non-modifiying sequence operations --- +#if _CXX11_AVAIL +// TODO: all_of +// TODO: any_of +// TODO: none_of +#endif +template +Function for_each(InputIterator first, InputIterator last, Function fn) +{ + while( first != last ) + { + fn( *first ); + ++ first; + } + return _CXX11_MOVE(fn); +} + +template +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 const T& max(const T& a, const T& b) diff --git a/Usermode/Libraries/libc++.so_src/include_exp/allocator b/Usermode/Libraries/libc++.so_src/include_exp/allocator index 0ed1bcde..1608a3c7 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/allocator +++ b/Usermode/Libraries/libc++.so_src/include_exp/allocator @@ -85,59 +85,9 @@ class allocator_noconstruct: public ::std::_bits::allocator_real { 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 - struct rebind - { - typedef allocator other; - }; - - allocator_noconstruct() throw() { - } - allocator_noconstruct(const allocator_noconstruct& alloc __attribute__((unused))) throw() { - } - template - allocator_noconstruct(const allocator_noconstruct& 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( ::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::pointer p, typename allocator_real::const_reference val ) { *p = val; } - // C++11 - #if _CXX11_AVAIL - template - void construct( U* p, Args&&... args ) { - } - #endif void destroy(typename allocator_real::pointer p) { } }; @@ -150,6 +100,7 @@ class allocator: { }; +#if 1 template <> class allocator: public _bits::allocator_noconstruct @@ -160,6 +111,7 @@ class allocator: public _bits::allocator_noconstruct { }; +#endif }; diff --git a/Usermode/Libraries/libc++.so_src/include_exp/list b/Usermode/Libraries/libc++.so_src/include_exp/list index f63e31de..181f0e49 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/list +++ b/Usermode/Libraries/libc++.so_src/include_exp/list @@ -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 void remove_if(Predicate pred) { + for( iterator it = begin(); it != end(); ) + { + if( pred(*it) ) + it = erase(it); + else + ++ it; + } + } + + void unique(); + template void unique(BinaryPredicate binary_pred); + + void merge(list& x); + template void merge(list& x, Compare comp); + + void sort(); + template 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 index 00000000..d3d9ffd3 --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/include_exp/mutex @@ -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 " 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 + diff --git a/Usermode/Libraries/libc++.so_src/include_exp/new b/Usermode/Libraries/libc++.so_src/include_exp/new index d5a21db2..f1ed0abb 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/new +++ b/Usermode/Libraries/libc++.so_src/include_exp/new @@ -12,11 +12,15 @@ //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 diff --git a/Usermode/Libraries/libc++.so_src/include_exp/vector b/Usermode/Libraries/libc++.so_src/include_exp/vector index 426fd57b..c058d0cd 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/vector +++ b/Usermode/Libraries/libc++.so_src/include_exp/vector @@ -16,10 +16,15 @@ extern "C" void _SysDebug(const char *, ...); namespace std { namespace _bits { -template +template 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 +template +const vector_iterator operator+(const vector_iterator& it, typename VectorType::difference_type n) { + return vector_iterator(it) += n; +} +template +const vector_iterator operator+(typename VectorType::difference_type n, const vector_iterator& it) { + return vector_iterator(it) += n; +} +template +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 > @@ -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 iterator; - typedef ::std::_bits::vector_iterator const_iterator; + typedef ::std::_bits::vector_iterator iterator; + typedef ::std::_bits::vector_iterator const_iterator; private: allocator_type m_alloc; @@ -107,31 +164,54 @@ public: { resize(n, val); } + template + 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 + 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 index 00000000..5ff27dfa --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/mutex.cc @@ -0,0 +1,39 @@ +/* + * Acess2 C++ Library + * - By John Hodge (thePowersGang) + * + * mutex.cc + * - ::std::mutex and helpers + */ +#include +#include +#include + +// === 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; +} +