From: John Hodge Date: Mon, 12 Jan 2015 11:24:19 +0000 (+0800) Subject: Merge branch 'master' of git://github.com/thepowersgang/acess2 X-Git-Url: https://git.ucc.asn.au/?p=tpg%2Facess2.git;a=commitdiff_plain;h=ba78deafcc3016555469ed263d7a0370fa99db4b;hp=7d1c355c2843a140d5c474567c690402793aaa36 Merge branch 'master' of git://github.com/thepowersgang/acess2 --- diff --git a/AcessNative/RunNative b/AcessNative/RunNative index f22ed7fe..03ec6b00 100755 --- a/AcessNative/RunNative +++ b/AcessNative/RunNative @@ -25,5 +25,6 @@ echo Kernel is $KERNEL_PID sleep 1 LD_LIBRARY_PATH=${DIR}:${DISTROOT}Libs AN_PREOPEN=$VTERM:$VTERM:$VTERM ${DBG} ${DISTROOT}Apps/AxWin/4.0/AxWinServer +trap '' SIGINT cleanup diff --git a/AcessNative/acesskernel_src/server.c b/AcessNative/acesskernel_src/server.c index 8de8ad3a..4dd964ca 100644 --- a/AcessNative/acesskernel_src/server.c +++ b/AcessNative/acesskernel_src/server.c @@ -228,6 +228,13 @@ int SyscallServer(void) server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = htonl(INADDR_ANY); + #if USE_TCP + { + int val = 1; + setsockopt(gSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val); + } + #endif + // Bind if( bind(gSocket, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) == -1 ) { diff --git a/Externals/libspiderscript/source b/Externals/libspiderscript/source index a5d190a8..9f2d7faf 160000 --- a/Externals/libspiderscript/source +++ b/Externals/libspiderscript/source @@ -1 +1 @@ -Subproject commit a5d190a89ca3f3a78c8b44a855b044ff4e713bb3 +Subproject commit 9f2d7faf34c16ceaee2f1bffe3d5558c41382523 diff --git a/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h b/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h index 2564716e..9c87bde1 100644 --- a/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h +++ b/Usermode/Applications/axwin3_src/WM/renderers/widget/common.h @@ -49,7 +49,7 @@ extern void Widget_Fire(tElement *Element); #define DEFWIDGETTYPE(_type, _name, _flags, _attribs...) \ tWidgetDef _widget_typedef_##_type = {.Name=_name,.Flags=(_flags),_attribs};\ void _widget_set_##_type(void) __attribute__((constructor));\ -void _widget_set_##_type(void) { _SysDebug("hai!\n"); Widget_int_SetTypeDef(_type, &_widget_typedef_##_type);} +void _widget_set_##_type(void) { Widget_int_SetTypeDef(_type, &_widget_typedef_##_type); } #endif diff --git a/Usermode/Applications/axwin4_src/Common/include/ipc_proto.hpp b/Usermode/Applications/axwin4_src/Common/include/ipc_proto.hpp index e47ed14d..a2e1bc97 100644 --- a/Usermode/Applications/axwin4_src/Common/include/ipc_proto.hpp +++ b/Usermode/Applications/axwin4_src/Common/include/ipc_proto.hpp @@ -33,6 +33,11 @@ enum IPCMSG_BLIT, // (win, sx, sy, dx, dy, w, h) - Blit locally IPCMSG_DRAWCTL, // (win, x, y, w, h, ctlid) - Draw IPCMSG_DRAWTEXT, // (win, x, y, fontid, text) - Draw text using an internal font + IPCMSG_FILLRECT, // (win, x, y, w, h, colour) + IPCMSG_DRAWRECT, // (win, x, y, w, h, colour) + + // - Client-bound commands + IPCMSG_INPUTEVENT, // (u8 event, u16 win, ...) }; enum eIPC_GlobalAttrs @@ -50,6 +55,13 @@ enum eIPC_WinAttrs IPC_WINATTR_TITLE, // string }; +enum eIPC_InputEvents +{ + IPC_INEV_KEYBOARD, // (u16 keysym, u8 keydown, string text) + IPC_INEV_MOUSEBTN, // (u16 x, u16 y) + IPC_INEV_MOUSEMOVE, // (u16 x, u16 y, u8 btn, u8 btndown) +}; + }; #endif diff --git a/Usermode/Applications/axwin4_src/Server/CClient.cpp b/Usermode/Applications/axwin4_src/Server/CClient.cpp index 70c4cf86..2abcb9b5 100644 --- a/Usermode/Applications/axwin4_src/Server/CClient.cpp +++ b/Usermode/Applications/axwin4_src/Server/CClient.cpp @@ -8,6 +8,7 @@ #include #include #include +#include // for the fonts namespace AxWin { @@ -45,6 +46,16 @@ void CClient::SetWindow(int ID, CWindow* window) } } +IFontFace& CClient::GetFont(unsigned int id) +{ + static CFontFallback fallback_font; + if( id == 0 ) { + _SysDebug("GetFont: %i = %p", id, &fallback_font); + return fallback_font; + } + assert(!"TODO: CClient::GetFont id != 0"); +} + void CClient::HandleMessage(CDeserialiser& message) { try { diff --git a/Usermode/Applications/axwin4_src/Server/CSurface.cpp b/Usermode/Applications/axwin4_src/Server/CSurface.cpp index 91bbb9ae..d0eddc42 100644 --- a/Usermode/Applications/axwin4_src/Server/CSurface.cpp +++ b/Usermode/Applications/axwin4_src/Server/CSurface.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace AxWin { @@ -92,6 +93,40 @@ void CSurface::DrawScanline(unsigned int row, unsigned int x_ofs, unsigned int w ::memcpy( &m_data[ofs], data, w*4 ); } +void CSurface::BlendScanline(unsigned int row, unsigned int x_ofs, unsigned int w, const void* 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"); + + const uint32_t* in_data = (const uint32_t*)data; + size_t ofs = row*m_rect.m_w + x_ofs; + for( unsigned int x = 0; x < w; x ++ ) + { + CColour out = CColour::from_argb(m_data[ofs+x]).blend( CColour::from_argb(in_data[x]) ); + m_data[ofs+x] = out.to_argb(); + } +} + +void CSurface::FillScanline(unsigned int row, unsigned int x_ofs, unsigned int w, uint32_t colour) +{ + if( row >= m_rect.m_h ) + throw ::std::out_of_range("CSurface::FillScanline row"); + if( x_ofs >= m_rect.m_w ) + throw ::std::out_of_range("CSurface::FillScanline x_ofs"); + + if( w > m_rect.m_w ) + throw ::std::out_of_range("CSurface::FillScanline width"); + + size_t ofs = row*m_rect.m_w + x_ofs; + while( w -- ) + m_data[ofs++] = colour; +} + const uint32_t* CSurface::GetScanline(unsigned int row, unsigned int x_ofs) const { if( row >= m_rect.m_h ) diff --git a/Usermode/Applications/axwin4_src/Server/CWindow.cpp b/Usermode/Applications/axwin4_src/Server/CWindow.cpp index 55c24823..022d6b49 100644 --- a/Usermode/Applications/axwin4_src/Server/CWindow.cpp +++ b/Usermode/Applications/axwin4_src/Server/CWindow.cpp @@ -59,7 +59,7 @@ void CWindow::Move(int X, int Y) void CWindow::Resize(unsigned int W, unsigned int H) { m_surface.Resize(W, H); - IPC::SendMessage_NotifyDims(m_client, W, H); + IPC::SendMessage_NotifyDims(m_client, m_id, W, H); } void CWindow::SetFlags(uint32_t Flags) { @@ -74,14 +74,18 @@ uint64_t CWindow::ShareSurface() void CWindow::MouseButton(int ButtonID, int X, int Y, bool Down) { + IPC::SendMessage_MouseButton(m_client, m_id, X, Y, ButtonID, Down); } void CWindow::MouseMove(int NewX, int NewY) { + // TODO: Only enable move events if client requests them + //IPC::SendMessage_MouseMove(m_client, m_id, NewX, NewY); } void CWindow::KeyEvent(::uint32_t Scancode, const ::std::string &Translated, bool Down) { + IPC::SendMessage_KeyEvent(m_client, m_id, Scancode, Down, Translated.c_str()); } @@ -92,5 +96,12 @@ void CWindow::DrawScanline(unsigned int row, unsigned int x, unsigned int w, con m_compositor.DamageArea(damaged); } +void CWindow::FillScanline(unsigned int row, unsigned int x, unsigned int w, const uint32_t colour) +{ + m_surface.FillScanline(row, x, w, colour); + 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 87ed9afe..b85fc088 100644 --- a/Usermode/Applications/axwin4_src/Server/Makefile +++ b/Usermode/Applications/axwin4_src/Server/Makefile @@ -10,10 +10,10 @@ OBJ += Common__serialisation.o OBJ += CClient.o OBJ += CIPCChannel_AcessIPCPipe.o OBJ += CRect.o CSurface.o -OBJ += draw_control.o +OBJ += draw_control.o draw_text.o BIN := AxWinServer -LIBS += -lc++ +LIBS += -lc++ -lunicode #CXXFLAGS += -O3 USE_CXX_LINK = 1 diff --git a/Usermode/Applications/axwin4_src/Server/compositor.cpp b/Usermode/Applications/axwin4_src/Server/compositor.cpp index da924e8d..e488380f 100644 --- a/Usermode/Applications/axwin4_src/Server/compositor.cpp +++ b/Usermode/Applications/axwin4_src/Server/compositor.cpp @@ -16,6 +16,7 @@ namespace AxWin { CCompositor::CCompositor(CVideo& video): // TODO: Support multiple screens m_video(video), + m_focussed_window(nullptr), m_windowIDBuffer(video.width(), video.height()) { // @@ -54,7 +55,7 @@ void CCompositor::Redraw() { // Redraw the screen and clear damage rects if( m_damageRects.empty() ) { - _SysDebug("- No damaged regions"); + //_SysDebug("- No damaged regions"); return ; } @@ -112,7 +113,8 @@ void CCompositor::MouseMove(unsigned int Cursor, unsigned int X, unsigned int Y, CWindow *dstwin = getWindowForCoord(X, Y); if( dstwin ) { - // TODO: Pass event on to window + // Pass event on to window + dstwin->MouseMove(X, Y); } } @@ -125,13 +127,18 @@ void CCompositor::MouseButton(unsigned int Cursor, unsigned int X, unsigned int { // 1. Give focus and bring to front // 2. Send event - // TODO: Pass event on to window + dstwin->MouseButton(Button, X, Y, Press); } } void CCompositor::KeyState(unsigned int KeyboardID, uint32_t KeySym, bool Press, uint32_t Codepoint) { _SysDebug("KeyState(%i, 0x%x, %b, 0x%x)", KeyboardID, KeySym, Press, Codepoint); + // TODO: Global hotkeys + if( m_focussed_window ) + { + m_focussed_window->KeyEvent(KeySym, "", Press); + } } CWindow* CCompositor::getWindowForCoord(unsigned int X, unsigned int Y) diff --git a/Usermode/Applications/axwin4_src/Server/draw_text.cpp b/Usermode/Applications/axwin4_src/Server/draw_text.cpp index f20f213f..7e9e7b8e 100644 --- a/Usermode/Applications/axwin4_src/Server/draw_text.cpp +++ b/Usermode/Applications/axwin4_src/Server/draw_text.cpp @@ -9,26 +9,158 @@ */ #include #include +#include // libunicode (acess) +extern "C" { +#include // assert... and _SysDebug +}; +#include "resources/font_8x16.h" // === CODE === namespace AxWin { -CFont::CFont(): - +// -- Primitive fallback font +CFontFallback::CFontFallback() { } -CFont::CFont(const char *Path): - +CRect CFontFallback::Size(const ::std::string& text, unsigned int Size) const { + return CRect(0,0, text.size() * Size * FONT_WIDTH / FONT_HEIGHT, Size); } /** * \param Text height in pixels (not in points) */ -void CFont::Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size) const +void CFontFallback::Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size) { + unsigned int font_step = Size * FONT_WIDTH / FONT_HEIGHT; + CRect pos = rect; + for( auto codepoint : ::libunicode::utf8string(text) ) + { + renderAtRes(dest, pos, codepoint, Size, 0x000000); + pos.Translate(font_step, 0); + } +} +void CFontFallback::renderAtRes(CSurface& dest, const CRect& rect, uint32_t cp, unsigned int Size, uint32_t FGC) +{ + unsigned int char_idx = unicodeToCharmap(cp); + assert(char_idx < 256); + const uint8_t* char_ptr = &VTermFont[char_idx * FONT_HEIGHT]; + unsigned int out_h = Size; + unsigned int out_w = (Size * FONT_WIDTH / FONT_HEIGHT); + uint32_t char_data[out_w]; + if( Size == FONT_HEIGHT ) { + // Standard blit + for( unsigned int row = 0; row < out_h; row ++ ) + { + for( unsigned int col = 0; col < out_w; col ++ ) + { + uint8_t alpha = getValueAtRaw(char_ptr, col, row); + char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF); + } + dest.BlendScanline(rect.m_y + row, rect.m_x, FONT_WIDTH, char_data); + } + } + else if( Size < FONT_HEIGHT ) { + // Down-scaled blit + // NOTE: uses the same code as the upscale blit (probably not correct, need to replace) + for( unsigned int row = 0; row < out_h; row ++ ) + { + unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h; + for( unsigned int col = 0; col < out_w; col ++ ) + { + unsigned int xf16 = col * FONT_WIDTH * 0x10000 / out_w; + uint8_t alpha = getValueAtPt(char_ptr, xf16, yf16); + //_SysDebug("row %i (%05x), col %i (%05x): alpha = %02x", row, yf16, col, xf16, alpha); + char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF); + } + dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data); + } + } + else { + // up-scaled blit + for( unsigned int row = 0; row < out_h; row ++ ) + { + unsigned int yf16 = row * FONT_HEIGHT * 0x10000 / out_h; + for( unsigned int col = 0; col < out_w; col ++ ) + { + unsigned int xf16 = col * FONT_WIDTH * 0x10000 / out_w; + uint8_t alpha = getValueAtPt(char_ptr, xf16, yf16); + //_SysDebug("row %i (%05x), col %i (%05x): alpha = %02x", row, yf16, col, xf16, alpha); + char_data[col] = ((uint32_t)alpha << 24) | (FGC & 0xFFFFFF); + } + dest.BlendScanline(rect.m_y + row, rect.m_x, out_w, char_data); + } + } +} +// X and Y are fixed-point 16.16 values +uint8_t CFontFallback::getValueAtPt(const uint8_t* char_ptr, unsigned int xf16, unsigned int yf16) +{ + unsigned int ix = xf16 >> 16; + unsigned int iy = yf16 >> 16; + unsigned int fx = xf16 & 0xFFFF; + unsigned int fy = yf16 & 0xFFFF; + + if( fx == 0 && fy == 0 ) { + return getValueAtRaw(char_ptr, ix, iy); + } + else if( fx == 0 ) { + float y = (float)fy / 0x10000; + uint8_t v0 = getValueAtRaw(char_ptr, ix, iy ); + uint8_t v1 = getValueAtRaw(char_ptr, ix, iy+1); + return v0 * (1 - y) + v1 * y; + } + else if( fy == 0 ) { + float x = (float)fx / 0x10000; + uint8_t v0 = getValueAtRaw(char_ptr, ix , iy); + uint8_t v1 = getValueAtRaw(char_ptr, ix+1, iy); + return v0 * (1 - x) + v1 * x; + } + else { + float x = (float)fx / 0x10000; + float y = (float)fx / 0x10000; + // [0,0](1 - x)(1 - y) + [1,0]x(1-y) + [0,1](1-x)y + [1,1]xy + uint8_t v00 = getValueAtRaw(char_ptr, ix, iy); + uint8_t v01 = getValueAtRaw(char_ptr, ix, iy+1); + uint8_t v10 = getValueAtRaw(char_ptr, ix+1, iy); + uint8_t v11 = getValueAtRaw(char_ptr, ix+1, iy+1); + //_SysDebug("x,y = %04x %04x", (unsigned)(x * 0x10000), (unsigned)(y * 0x10000)); + //_SysDebug("v = %02x %02x %02x %02x", v00, v01, v10, v11); + float val1 = v00 * (1 - x) * (1 - y); + float val2 = v10 * x * (1 - y); + float val3 = v01 * (1 - x) * y; + float val4 = v11 * x * y; + //_SysDebug("vals = %04x %04x %04x %04x", + // (unsigned)(val1 * 0x10000), + // (unsigned)(val2 * 0x10000), + // (unsigned)(val3 * 0x10000), + // (unsigned)(val4 * 0x10000) + // ); + + return (uint8_t)(val1 + val2 + val3 + val4); + } +} + +uint8_t CFontFallback::getValueAtRaw(const uint8_t* char_ptr, unsigned int x, unsigned int y) +{ + //if( x == 0 || y == 0 ) + // return 0; + //x --; y --; + if(x >= FONT_WIDTH || y >= FONT_HEIGHT) + return 0; + return (char_ptr[y] & (1 << (7-x))) ? 255 : 0; +} + +unsigned int CFontFallback::unicodeToCharmap(uint32_t cp) const +{ + if(cp >= ' ' && cp < 0x7F) + return cp; + switch(cp) + { + default: + return 0; + } } }; // namespace AxWin diff --git a/Usermode/Applications/axwin4_src/Server/include/CClient.hpp b/Usermode/Applications/axwin4_src/Server/include/CClient.hpp index 24e7daba..2a23f155 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CClient.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CClient.hpp @@ -12,6 +12,7 @@ #include "serialisation.hpp" #include #include +#include "IFontFace.hpp" namespace AxWin { @@ -34,6 +35,8 @@ public: CWindow* GetWindow(int ID); void SetWindow(int ID, CWindow* window); + IFontFace& GetFont(unsigned int id); + virtual void SendMessage(CSerialiser& reply) = 0; void HandleMessage(CDeserialiser& message); }; diff --git a/Usermode/Applications/axwin4_src/Server/include/CColour.hpp b/Usermode/Applications/axwin4_src/Server/include/CColour.hpp new file mode 100644 index 00000000..d47d7e04 --- /dev/null +++ b/Usermode/Applications/axwin4_src/Server/include/CColour.hpp @@ -0,0 +1,93 @@ +/* + * Acess2 GUI v4 + * - By John Hodge (thePowersGang) + * + * CColour.hpp + * - Generic colour handling and blending + */ +#ifndef _CCOLOUR_HPP_ +#define _CCOLOUR_HPP_ + +namespace AxWin { + +class CColour +{ + static const uint8_t uint8_max = 0xFF; + static const unsigned int comp_max = 0x7FFF; + + unsigned int m_alpha; + unsigned int m_red; + unsigned int m_green; + unsigned int m_blue; + +private: + static unsigned int u8_to_ui(uint8_t u8v) { + return (unsigned int)u8v * comp_max / uint8_max; + } + static uint8_t ui_to_u8(unsigned int uiv) { + return uiv * uint8_max / comp_max; + } + // Perform an alpha-based blend on two components + static unsigned int alpha_blend(unsigned int alpha_comp, unsigned int left, unsigned int right) { + return (left * (comp_max - alpha_comp) + right * alpha_comp) / comp_max; + } + // Float values: + // - infinity == saturation, 1 == nothing + // fv = MAX / (MAX - uiv) + static float ui_to_float(unsigned int uiv) { + return (float)comp_max / (comp_max - uiv); + } + // uiv = MAX - MAX / fv + static unsigned int float_to_ui(float fv) { + return comp_max - comp_max / fv; + } + // perform a non-oversaturating blend of two colours (using an inverse relationship) + static unsigned int add_blend(unsigned int a, unsigned int b) { + return float_to_ui( ui_to_float(a) + ui_to_float(b) ); + } + + CColour(unsigned int r, unsigned int g, unsigned int b, unsigned int a): + m_alpha(a), m_red(r), m_green(g), m_blue(b) + { + } +public: + + static CColour from_argb(uint32_t val) { + return CColour( + u8_to_ui((val>>16) & 0xFF), + u8_to_ui((val>> 8) & 0xFF), + u8_to_ui((val>> 0) & 0xFF), + u8_to_ui((val>>24) & 0xFF) + ); + } + + uint32_t to_argb() const { + uint32_t rv = 0; + rv |= (uint32_t)ui_to_u8(m_red) << 16; + rv |= (uint32_t)ui_to_u8(m_green) << 8; + rv |= (uint32_t)ui_to_u8(m_blue) << 0; + rv |= (uint32_t)ui_to_u8(m_alpha) << 24; + return rv; + } + + // performs a blend of the two colours, maintaining the target alpha, using the source alpha as the blend control + CColour& blend(const CColour& other) { + m_red = alpha_blend(other.m_alpha, m_red , other.m_red ); + m_green = alpha_blend(other.m_alpha, m_green, other.m_green); + m_blue = alpha_blend(other.m_alpha, m_blue , other.m_blue ); + return *this; + } + // Add all components + CColour& operator+(const CColour& other) { + m_alpha = add_blend(m_alpha, other.m_alpha); + m_red = add_blend(m_red , other.m_red ); + m_green = add_blend(m_green, other.m_green); + m_blue = add_blend(m_blue , other.m_blue ); + return *this; + } +}; + +} // namespace AxWin + +#endif + diff --git a/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp b/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp index ec40d369..fe243039 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CCompositor.hpp @@ -50,6 +50,7 @@ class CCompositor CVideo& m_video; ::std::list m_damageRects; ::std::list m_windows; + CWindow* m_focussed_window; CWindowIDBuffer m_windowIDBuffer; // One 32-bit value per pixel diff --git a/Usermode/Applications/axwin4_src/Server/include/CRect.hpp b/Usermode/Applications/axwin4_src/Server/include/CRect.hpp index 708186ac..3c344b25 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CRect.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CRect.hpp @@ -14,6 +14,10 @@ public: }; CRect(int X, int Y, unsigned int W, unsigned int H); + void Translate(int DX, int DY) { + m_x += DX; m_x2 += DX; + m_y += DY; m_y2 += DY; + } void Move(int NewX, int NewY); void Resize(int NewW, int NewH); diff --git a/Usermode/Applications/axwin4_src/Server/include/CSurface.hpp b/Usermode/Applications/axwin4_src/Server/include/CSurface.hpp index 6de73055..ac20d0f5 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CSurface.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CSurface.hpp @@ -19,6 +19,8 @@ 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); + void BlendScanline(unsigned int row, unsigned int x_ofs, unsigned int w, const void* data); + void FillScanline(unsigned int row, unsigned int x, unsigned int w, uint32_t colour); const uint32_t* GetScanline(unsigned int row, unsigned int x_ofs) const; CRect m_rect; diff --git a/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp b/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp index 5161f035..e9026593 100644 --- a/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/CWindow.hpp @@ -43,6 +43,7 @@ public: 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); + void FillScanline(unsigned int row, unsigned int x, unsigned int w, const uint32_t colour); bool m_is_shown; CSurface m_surface; diff --git a/Usermode/Applications/axwin4_src/Server/include/IFontFace.hpp b/Usermode/Applications/axwin4_src/Server/include/IFontFace.hpp new file mode 100644 index 00000000..76ba0422 --- /dev/null +++ b/Usermode/Applications/axwin4_src/Server/include/IFontFace.hpp @@ -0,0 +1,27 @@ +/* + * Acess2 GUI v4 + * - By John Hodge (thePowersGang) + * + * IFont.hpp + * - Text drawing (font rendering) primitive + */ +#ifndef _IFONT_HPP_ +#define _IFONT_HPP_ + +#include +#include "CRect.hpp" +#include "CSurface.hpp" + +namespace AxWin { + +class IFontFace +{ +public: + virtual CRect Size(const ::std::string& text, unsigned int Size) const = 0; + virtual void Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size) = 0; +}; + +}; + +#endif + diff --git a/Usermode/Applications/axwin4_src/Server/include/draw_text.hpp b/Usermode/Applications/axwin4_src/Server/include/draw_text.hpp new file mode 100644 index 00000000..4bf28a61 --- /dev/null +++ b/Usermode/Applications/axwin4_src/Server/include/draw_text.hpp @@ -0,0 +1,47 @@ +/* + * Acess2 GUI v4 + * - By John Hodge (thePowersGang) + * + * draw_text.hpp + * - Text drawing classes + */ +#ifndef _DRAW_TEXT_HPP_ +#define _DRAW_TEXT_HPP_ + +#include "IFontFace.hpp" + +namespace AxWin { + +class CFontFallback: + public IFontFace +{ +public: + CFontFallback(); + + CRect Size(const ::std::string& text, unsigned int Size) const override; + void Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size) override; +private: + void renderAtRes(CSurface& dest, const CRect& rect, uint32_t cp, unsigned int Size, uint32_t FGC); + static uint8_t getValueAtPt(const uint8_t* char_ptr, unsigned int xf16, unsigned int yf16); + static uint8_t getValueAtRaw(const uint8_t* char_ptr, unsigned int x, unsigned int y); + unsigned int unicodeToCharmap(uint32_t cp) const; +}; + +#if FREETYPE_ENABLED +class CFontFT: + public IFontFace +{ + FT_Face m_face; +public: + CFontFT(const char *Filename); + ~CFontFT(); + + CRect Size(const ::std::string& text, unsigned int Size) const override; + void Render(CSurface& dest, const CRect& rect, const ::std::string& text, unsigned int Size) override; +}; +#endif // FREETYPE_ENABLED + +} + +#endif + diff --git a/Usermode/Applications/axwin4_src/Server/include/ipc.hpp b/Usermode/Applications/axwin4_src/Server/include/ipc.hpp index 5706a85b..50b0dbe2 100644 --- a/Usermode/Applications/axwin4_src/Server/include/ipc.hpp +++ b/Usermode/Applications/axwin4_src/Server/include/ipc.hpp @@ -31,7 +31,10 @@ 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); +extern void SendMessage_NotifyDims(CClient& client, unsigned int WinID, unsigned int NewW, unsigned int NewH); +extern void SendMessage_MouseButton(CClient& client, unsigned int WinID, unsigned int X, unsigned int Y, uint8_t Button, bool Pressed); +extern void SendMessage_MouseMove(CClient& client, unsigned int WinID, unsigned int X, unsigned int Y); +extern void SendMessage_KeyEvent(CClient& client, unsigned int WinID, uint32_t KeySym, bool Pressed, const char *Translated); extern void HandleMessage(CClient& client, CDeserialiser& message); diff --git a/Usermode/Applications/axwin4_src/Server/ipc.cpp b/Usermode/Applications/axwin4_src/Server/ipc.cpp index 1c5ba994..f522ac22 100644 --- a/Usermode/Applications/axwin4_src/Server/ipc.cpp +++ b/Usermode/Applications/axwin4_src/Server/ipc.cpp @@ -19,6 +19,7 @@ extern "C" { }; #include #include +#include namespace AxWin { namespace IPC { @@ -101,9 +102,36 @@ void DeregisterClient(CClient& client) } -void SendMessage_NotifyDims(CClient& client, unsigned int NewW, unsigned int NewH) +void SendMessage_NotifyDims(CClient& client, unsigned int WinID, unsigned int NewW, unsigned int NewH) { - _SysDebug("TODO: CClient::SendNotify_Dims"); + _SysDebug("TODO: IPC::SendMessage_NotifyDims"); +} +void SendMessage_MouseButton(CClient& client, unsigned int WinID, unsigned int X, unsigned int Y, uint8_t Button, bool Pressed) +{ + CSerialiser msg; + msg.WriteU8(IPCMSG_INPUTEVENT); + msg.WriteU8(IPC_INEV_MOUSEBTN); + msg.WriteU16(WinID); + msg.WriteU16(X); + msg.WriteU16(Y); + msg.WriteU8(Button); + msg.WriteU8(Pressed ? 0 : 1); + client.SendMessage(msg); +} +void SendMessage_MouseMove(CClient& client, unsigned int WinID, unsigned int X, unsigned int Y) +{ + _SysDebug("TODO: IPC::SendMessage_MouseMove"); +} +void SendMessage_KeyEvent(CClient& client, unsigned int WinID, uint32_t KeySym, bool Pressed, const char *Translated) +{ + CSerialiser msg; + msg.WriteU8(IPCMSG_INPUTEVENT); + msg.WriteU8(IPC_INEV_KEYBOARD); + msg.WriteU16(WinID); + msg.WriteU16(KeySym); + msg.WriteU8(Pressed ? 0 : 1); + msg.WriteString(Translated); + client.SendMessage(msg); } @@ -355,9 +383,9 @@ void HandleMessage_DrawText(CClient& client, CDeserialiser& message) uint16_t y = message.ReadU16(); uint16_t w = message.ReadU16(); uint16_t h = message.ReadU16(); - uint16_t font = message.ReadU16(); + uint16_t font_id = message.ReadU16(); ::std::string str = message.ReadString(); - _SysDebug("_DrawText: (%i (%i,%i) %ix%i Font%i \"%s\")", win_id, x, y, w, h, font, str.c_str()); + _SysDebug("_DrawText: (%i (%i,%i) %ix%i Font%i \"%s\")", win_id, x, y, w, h, font_id, str.c_str()); CWindow* win = client.GetWindow(win_id); if(!win) { @@ -365,13 +393,66 @@ void HandleMessage_DrawText(CClient& client, CDeserialiser& message) } // 1. Get font from client structure - //CFont& font = client.GetFont(font_id); + IFontFace& fontface = client.GetFont(font_id); // 2. Render - //CRect area(x, y, w, h); - //font->Render(win->m_surface, area, str, h); + CRect area(x, y, w, h); + fontface.Render(win->m_surface, area, str, h); +} + +void HandleMessage_FillRect(CClient& client, CDeserialiser& message) +{ + 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(); + uint32_t colour = message.ReadU32(); + _SysDebug("_FillRect: (%i (%i,%i) %ix%i %06x)", win_id, x, y, w, h, colour); + + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_FillRect: Bad window"); + } + + while(h -- ) { + win->FillScanline(y++, x, w, colour); + } +} + +void HandleMessage_DrawRect(CClient& client, CDeserialiser& message) +{ + 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(); + uint32_t colour = message.ReadU32(); + _SysDebug("_DrawRect: (%i (%i,%i) %ix%i %06x)", win_id, x, y, w, h, colour); - _SysDebug("TODO: HandleMessage_DrawText"); + CWindow* win = client.GetWindow(win_id); + if(!win) { + throw IPC::CClientFailure("_DrawRect: Bad window"); + } + + if(h == 0) { + } + else if(h == 1) { + win->FillScanline(y, x, w, colour); + } + else if(h == 2) { + win->FillScanline(y++, x, w, colour); + win->FillScanline(y++, x, w, colour); + } + else { + win->FillScanline(y++, x, w, colour); + while( h -- > 2 ) { + win->FillScanline(y, x, 1, colour); + win->FillScanline(y, x+w-1, 1, colour); + y ++; + } + win->FillScanline(y++, x, w, colour); + } } typedef void MessageHandler_op_t(CClient& client, CDeserialiser& message); @@ -394,13 +475,17 @@ MessageHandler_op_t *message_handlers[] = { [IPCMSG_BLIT] = &HandleMessage_Blit, // Copy data from one part of the window to another [IPCMSG_DRAWCTL] = &HandleMessage_DrawCtl, // Draw a control [IPCMSG_DRAWTEXT] = &HandleMessage_DrawText, // Draw text + [IPCMSG_FILLRECT] = &HandleMessage_FillRect, // Fill a rectangle + [IPCMSG_DRAWRECT] = &HandleMessage_DrawRect, // Draw (outline) a rectangle }; void HandleMessage(CClient& client, CDeserialiser& message) { + const unsigned int num_commands = sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*); unsigned int command = message.ReadU8(); - if( command >= sizeof(message_handlers)/sizeof(IPC::MessageHandler_op_t*) ) { + if( command >= num_commands ) { // Drop, invalid command + _SysDebug("HandleMessage: Command %u is invalid (out of range for %u)", command, num_commands); return ; } diff --git a/Usermode/Applications/axwin4_src/Server/resources/font_8x16.h b/Usermode/Applications/axwin4_src/Server/resources/font_8x16.h new file mode 100644 index 00000000..b9bad5db --- /dev/null +++ b/Usermode/Applications/axwin4_src/Server/resources/font_8x16.h @@ -0,0 +1,265 @@ +/* + * Taken from http://cvs.savannah.gnu.org/viewvc/vgabios/vgafonts.h?root=vgabios&view=markup + * Altered for Acess2 + */ +#define FONT_WIDTH 8 +#define FONT_HEIGHT 16 +static uint8_t VTermFont[256*16]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; diff --git a/Usermode/Applications/axwin4_src/UI/main.c b/Usermode/Applications/axwin4_src/UI/main.c index c831558d..624e381a 100644 --- a/Usermode/Applications/axwin4_src/UI/main.c +++ b/Usermode/Applications/axwin4_src/UI/main.c @@ -59,7 +59,7 @@ tAxWin4_Window *CreateBGWin(int w, int h) } else { - //AxWin4_FillRect(bgwin, 0, 0, w, h, 0x0000CC); + AxWin4_FillRect(bgwin, 0, 0, w, h, 0x8888CC); } //AxWin4_DamageRect(bgwin, 0, 0, w, h); AxWin4_ShowWindow(bgwin, true); diff --git a/Usermode/Applications/axwin4_src/UI/taskbar.c b/Usermode/Applications/axwin4_src/UI/taskbar.c index 650e8e65..b62a0420 100644 --- a/Usermode/Applications/axwin4_src/UI/taskbar.c +++ b/Usermode/Applications/axwin4_src/UI/taskbar.c @@ -83,6 +83,7 @@ void Taskbar_Redraw(void) time(&rawtime); strftime(timestr, 5, "%H%M", localtime(&rawtime)); //AxWin4_DrawControl(gpTaskbar_Window, clock_start_x, TASKBAR_BORDER, TASKBAR_CLOCKSIZE, active_height, AXWIN4_CTL_BOX); + AxWin4_DrawText(gpTaskbar_Window, clock_start_x, TASKBAR_BORDER, TASKBAR_CLOCKSIZE, active_height, 0, timestr); } 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 0a23ad76..255b0e1d 100644 --- a/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h +++ b/Usermode/Libraries/libaxwin4.so_src/include_exp/axwin4/axwin.h @@ -28,6 +28,14 @@ extern void AxWin4_GetScreenDimensions(unsigned int ScreenIndex, unsigned int *W extern tAxWin4_Window *AxWin4_CreateWindow(const char *Name); extern void AxWin4_DestroyWindow(tAxWin4_Window *Window); + +// Callbacks +typedef int tAxWin4_KeyCallback(tAxWin4_Window* Winow, unsigned int Key, const char *Translated); +extern void AxWin4_SetCallback_Key(tAxWin4_Window* Window, tAxWin4_KeyCallback* cb); +typedef int tAxWin4_MouseBtnCallback(tAxWin4_Window* Winow, unsigned int Mouse, unsigned int X, unsigned int Y, unsigned int Button, bool IsPress); +extern void AxWin4_SetCallback_MouseBtn(tAxWin4_Window* Window, tAxWin4_MouseBtnCallback* cb); +typedef int tAxWin4_MouseMoveCallback(tAxWin4_Window* Winow, unsigned int Mouse, unsigned int X, unsigned int Y); + 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); @@ -66,6 +74,8 @@ extern void AxWin4_DrawBitmap(tAxWin4_Window *Window, int X, int Y, unsigned int */ extern void AxWin4_DrawControl(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, uint16_t ControlID, unsigned int Frame); +extern void AxWin4_FillRect(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, uint32_t Colour); + extern void AxWin4_DrawText(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, uint16_t FontID, const char *String); #include "definitions.h" diff --git a/Usermode/Libraries/libaxwin4.so_src/ipc.cpp b/Usermode/Libraries/libaxwin4.so_src/ipc.cpp index a262a9ee..d0455f53 100644 --- a/Usermode/Libraries/libaxwin4.so_src/ipc.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/ipc.cpp @@ -86,6 +86,15 @@ void RecvMessage(CDeserialiser& message) _SysDebug("RecvMessage: id=%i", id); switch(id) { + case IPCMSG_PING: + // If we hear ping, we must pong + { + CSerialiser pong; + pong.WriteU8(IPCMSG_REPLY); + pong.WriteU8(IPCMSG_PING); + SendMessage(pong); + } + break; case IPCMSG_REPLY: // Flag reply and take a copy of this message if( !gSyncReplyActive ) @@ -103,6 +112,12 @@ void RecvMessage(CDeserialiser& message) gSyncReplyBuf = message; } break; + // TODO: Handle messages from server (input events, IPC) + // TODO: If an event is currently being processed, save the message in a queue to be handled when processing is complete + // - This will prevent deep recursion (and make server errors aparent) + case IPCMSG_INPUTEVENT: + _SysDebug("TODO: Input events"); + break; default: _SysDebug("TODO: RecvMessage(%i)", id); break; diff --git a/Usermode/Libraries/libaxwin4.so_src/window_drawing.cpp b/Usermode/Libraries/libaxwin4.so_src/window_drawing.cpp index 8f355a6e..e6a4448c 100644 --- a/Usermode/Libraries/libaxwin4.so_src/window_drawing.cpp +++ b/Usermode/Libraries/libaxwin4.so_src/window_drawing.cpp @@ -60,6 +60,19 @@ extern "C" void AxWin4_DrawControl(tAxWin4_Window *Window, int X, int Y, unsigne ::AxWin::SendMessage(message); } +extern "C" void AxWin4_FillRect(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, uint32_t Colour) +{ + CSerialiser message; + message.WriteU8(IPCMSG_FILLRECT); + message.WriteU16(Window->m_id); + message.WriteU16(X); + message.WriteU16(Y); + message.WriteU16(W); + message.WriteU16(H); + message.WriteU32(Colour); + ::AxWin::SendMessage(message); +} + extern "C" void AxWin4_DrawText(tAxWin4_Window *Window, int X, int Y, unsigned int W, unsigned int H, uint16_t FontID, const char *String) { CSerialiser message; diff --git a/Usermode/Libraries/libc++.so_src/guard.cc b/Usermode/Libraries/libc++.so_src/guard.cc index a075a7b6..6468a676 100644 --- a/Usermode/Libraries/libc++.so_src/guard.cc +++ b/Usermode/Libraries/libc++.so_src/guard.cc @@ -6,24 +6,33 @@ * - One-time construction API */ #include +#include +#include + +#define FLAG_INIT_COMPLETE (1<<0) +#define FLAG_INIT_LOCKED (1<<1) extern "C" int __cxa_guard_acquire ( int64_t *guard_object ) { // TODO: Mutex! - if( *guard_object ) - return 1; - *guard_object = 1; - return 0; + if( *guard_object == FLAG_INIT_COMPLETE ) + return 0; + if( *guard_object == FLAG_INIT_LOCKED ) { + _SysDebug("ERROR: __cxa_guard_acquire - nested"); + } + *guard_object = FLAG_INIT_LOCKED; + return 1; } extern "C" void __cxa_guard_release ( int64_t *guard_object ) { - *guard_object = 0; + *guard_object = FLAG_INIT_COMPLETE; } extern "C" void __cxa_guard_abort ( int64_t *guard_object ) { - *guard_object = 0; - // TODO: abort + *guard_object = FLAG_INIT_COMPLETE; + _SysDebug("__cxa_guard_abort"); + abort(); } diff --git a/Usermode/Libraries/libc.so_src/timeconv.c b/Usermode/Libraries/libc.so_src/timeconv.c index 6fed585a..00eb13f3 100644 --- a/Usermode/Libraries/libc.so_src/timeconv.c +++ b/Usermode/Libraries/libc.so_src/timeconv.c @@ -114,7 +114,7 @@ int64_t get_days_since_y2k(int64_t ts, int *h, int *m, int *s) ts -= n_leap; #endif - int64_t days = ts / 24*60*60; + int64_t days = ts / (24*60*60); int64_t seconds = ts % (24*60*60); *s = (is_ls ? 60 : seconds % 60); *m = (seconds/60 % 24); diff --git a/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h b/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h index ef0eb56e..6c7e3e4a 100644 --- a/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h +++ b/Usermode/Libraries/libunicode.so_src/include_exp/unicode.h @@ -10,6 +10,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * \breif Read a single codepoint from a UTF-8 stream * \return Number of bytes read @@ -27,5 +31,102 @@ extern int WriteUTF8(char *buf, uint32_t Val); static inline int Unicode_IsPrinting(uint32_t Codepoint) { return 1; } +#ifdef __cplusplus +} // extern "C" +#endif + +#ifdef __cplusplus +#include + +namespace libunicode { + +class utf8iterator: + public ::std::iterator< ::std::forward_iterator_tag, uint32_t > +{ + const char* m_curpos; + uint32_t m_curval; +public: + utf8iterator(): + m_curpos(0) + { + } + utf8iterator(const char *pos): + m_curpos(pos) + { + (*this)++; + } + utf8iterator(const utf8iterator& other) { + m_curpos = other.m_curpos; + m_curval = other.m_curval; + } + utf8iterator& operator=(const utf8iterator& other) { + m_curpos = other.m_curpos; + m_curval = other.m_curval; + return *this; + } + + bool operator== (const utf8iterator& other) { + return other.m_curpos == m_curpos; + } + bool operator!= (const utf8iterator& other) { + return other.m_curpos != m_curpos; + } + utf8iterator& operator++() { + m_curpos += ::ReadUTF8(m_curpos, &m_curval); + return *this; + } + utf8iterator operator++(int) { + utf8iterator rv(*this); + m_curpos += ::ReadUTF8(m_curpos, &m_curval); + return rv; + } + uint32_t operator*() const { + return m_curval; + } + uint32_t operator->() const { + return m_curval; + } +}; + +class utf8string +{ + const char* m_data; + size_t m_len; + + size_t _strlen(const char*s) { + size_t l = 0; + while(*s) l ++; + return l; + } +public: + utf8string(const char* c_str): + m_data(c_str), + m_len(_strlen(c_str)) + { + } + utf8string(const char* c_str, size_t len): + m_data(c_str), + m_len(len) + { + } + utf8string(const ::std::string& str): + m_data(str.c_str()), + m_len(str.size()) + { + } + + utf8iterator begin() const { + return utf8iterator(m_data); + } + utf8iterator end() const { + return utf8iterator(m_data + m_len); + } +}; + + +}; + +#endif + #endif