diff --git a/rainbow/Turtle/Ctrl.h b/rainbow/Turtle/Ctrl.h index 5af627870..39d412222 100644 --- a/rainbow/Turtle/Ctrl.h +++ b/rainbow/Turtle/Ctrl.h @@ -59,7 +59,7 @@ private: static void DoMouseFB(int event, Point p, int zdelta, CParser& cp); - static void Reply(); + static void Output(); friend struct PaintProxy__; friend class TopWindowFrame; @@ -71,7 +71,9 @@ private: static void Signal(int signal); static void Broadcast(int signal); - static void Put8(int x) { turtle_stream.Put(x); } + static TurtleStream turtle_stream; + static Stream& OutputStream() { turtle_stream.SetDataFlag(); return turtle_stream; } + static void Put8(int x) { turtle_stream.SetDataFlag(); turtle_stream.Put(x); } static void Put16(int x); static void Put32(int x); static void Put(Point p); @@ -79,6 +81,13 @@ private: static void Put(const Rect& r); static void Put(const String& s); + static void SyncClient(); + + friend void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, + int n, Color color, int type, int animation); + friend void DrawDragLine(SystemDraw& w, bool horz, int x, int y, int len, int n, int animation); + + public: static bool DoKeyFB(dword key, int cnt); @@ -89,6 +98,10 @@ public: static Time stat_started; static int64 stat_data_send; + static int stat_putrect; + static int stat_putimage; + static int stat_setimage; + static int64 stat_setimage_len; static bool StartSession(); static Callback WhenDisconnect; @@ -97,6 +110,7 @@ public: static void SetDesktop(Ctrl& q); static Ctrl *GetDesktop() { return desktop; } static void SetDesktopSize(Size sz); + static Size GetDesktopSize() { return DesktopSize; } void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation); diff --git a/rainbow/Turtle/Cursor.cpp b/rainbow/Turtle/Cursor.cpp deleted file mode 100644 index fe730190e..000000000 --- a/rainbow/Turtle/Cursor.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "Local.h" - -#ifdef GUI_TURTLE - -NAMESPACE_UPP - -#define LLOG(x) LOG(x) -#define LDUMP(x) //DDUMP(x) - -void Ctrl::SetMouseCursor(const Image& image) -{ - GuiLock __; - if(image.GetSerialId() != fbCursorImage.GetSerialId()) { - fbCursorImage = image; - fbCursorPos = Null; - _TODO_ - } -} - -END_UPP_NAMESPACE - -#endif \ No newline at end of file diff --git a/rainbow/Turtle/Draw.cpp b/rainbow/Turtle/Draw.cpp index 891252439..5405e0995 100644 --- a/rainbow/Turtle/Draw.cpp +++ b/rainbow/Turtle/Draw.cpp @@ -32,6 +32,8 @@ int SystemDraw::GetImageI(int from, Index& img_index, int maxcount, const Ctrl::Put8(s->b); Ctrl::Put8(s->a); } + Ctrl::stat_setimage++; + Ctrl::stat_setimage_len += img.GetLength() * sizeof(RGBA); } return q + from; } @@ -47,6 +49,7 @@ int SystemDraw::GetImageI(const Image& img) void SystemDraw::PutImage(Point p, const Image& img, const Rect& src) { LLOG("Ctrl::PutImage " << p << ", size: " << img.GetSize() << ", src: " << src << ", id: " << img.GetSerialId()); + Ctrl::stat_putimage++; int i = GetImageI(img); if(Rect(img.GetSize()) == src) { Point dp = p - pos; @@ -69,6 +72,7 @@ void SystemDraw::PutImage(Point p, const Image& img, const Rect& src) void SystemDraw::PutRect(const Rect& r, Color color) { LLOG("Ctrl::PutRect " << r << ", color " << color); + Ctrl::stat_putrect++; Point p = r.TopLeft(); if(color == InvertColor()) { Ctrl::Put8(INVERTRECT); diff --git a/rainbow/Turtle/DrawDragRect.cpp b/rainbow/Turtle/DrawDragRect.cpp index 5b94472f7..586328c1a 100644 --- a/rainbow/Turtle/DrawDragRect.cpp +++ b/rainbow/Turtle/DrawDragRect.cpp @@ -11,65 +11,48 @@ struct DrawDragRectInfo { int animation; }; -void DrawDragLine(SystemDraw& w, bool horz, int x, int y, int len, int n, const int *pattern, int animation) +void DrawDragLine(SystemDraw& w, bool horz, int x, int y, int len, int n, int anim) { if(len <= 0) return; - if(horz) - w.Clip(x, y, len, n); - else - w.Clip(x, y, n, len); - - (horz ? x : y) -= animation; - len += animation; - bool ch = false; - while(len > 0) { - int segment = pattern[ch]; - int d = segment + pattern[2]; - if(horz) { - w.DrawRect(x, y, segment, n, InvertColor()); - x += d; - } - else { - w.DrawRect(x, y, n, segment, InvertColor()); - y += d; - } - len -= d; - ch = !ch; + for(int i = 0; i < n; i++) { + Ctrl::Put8(horz ? SystemDraw::HORZDRAGLINE : SystemDraw::VERTDRAGLINE); + Ctrl::Put16(x + !horz * i); + Ctrl::Put16(y + horz * i); + Ctrl::Put16(len); + Ctrl::Put16(anim); } - w.End(); } -void DrawDragFrame(SystemDraw& w, const Rect& r, int n, const int *pattern, int animation) +void DrawDragFrame(SystemDraw& w, const Rect& r, int n, int animation) { - DrawDragLine(w, true, r.left, r.top, r.GetWidth(), n, pattern, animation); - DrawDragLine(w, false, r.left, r.top + n, r.GetHeight() - 2 * n, n, pattern, animation); - DrawDragLine(w, false, r.right - n, r.top + n, r.GetHeight() - 2 * n, n, pattern, animation); - DrawDragLine(w, true, r.left, r.bottom - n, r.GetWidth(), n, pattern, animation); + DrawDragLine(w, true, r.left, r.top, r.GetWidth(), n, animation); + DrawDragLine(w, false, r.left, r.top + n, r.GetHeight() - 2 * n, n, animation); + DrawDragLine(w, false, r.right - n, r.top + n, r.GetHeight() - 2 * n, n, animation); + DrawDragLine(w, true, r.left, r.bottom - n, r.GetWidth(), n, animation); } void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f) { - _TODO_ SystemDraw w; - Ctrl::PaintScene(w); + w.Init(Ctrl::GetDesktopSize()); w.Clip(f.clip); + /* TODO static int dashes[3][3] = { { 32, 32, 0 }, { 1, 1, 1 }, { 5, 1, 2 }, }; - const int *dash = dashes[minmax(f.type, 0, 2)]; - DrawDragFrame(w, f.rect1, f.n, dash, f.animation); - DrawDragFrame(w, f.rect2, f.n, dash, f.animation); -// w.End(); -// Ctrl::PaintCaretCursor(w); -// SDL_GL_SwapWindow(screen.win); + */ + DrawDragFrame(w, f.rect1, f.n, f.animation); + DrawDragFrame(w, f.rect2, f.n, f.animation); + w.End(); } void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation) { + DLOG("DrawDragRect"); Ctrl *top = q.GetTopCtrl(); if(top) { Point off = q.GetScreenView().TopLeft(); @@ -81,16 +64,13 @@ void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& cli f.type = type; f.animation = animation; DrawDragRect(*top, f); + Ctrl::Output(); + top->Sync(); } } void FinishDragRect(Ctrl& q) { - SystemDraw w; - Ctrl::PaintScene(w); -// Ctrl::PaintCaretCursor(w); - _TODO_ - //SDL_GL_SwapWindow(screen.win); } END_UPP_NAMESPACE diff --git a/rainbow/Turtle/Event.cpp b/rainbow/Turtle/Event.cpp index c7fae6a96..08f565416 100644 --- a/rainbow/Turtle/Event.cpp +++ b/rainbow/Turtle/Event.cpp @@ -10,6 +10,10 @@ NAMESPACE_UPP Time Ctrl::stat_started; int64 Ctrl::stat_data_send; +int Ctrl::stat_putrect; +int Ctrl::stat_putimage; +int Ctrl::stat_setimage; +int64 Ctrl::stat_setimage_len; static Point MousePos; @@ -274,7 +278,7 @@ void Ctrl::DoMouseButton(int event, CParser& p) bool Ctrl::ProcessEvent(const String& event) { - LLOG("Processing event " << event); + DLOG("Processing event " << event); CParser p(event); try { if(p.Id("I")) diff --git a/rainbow/Turtle/Output.cpp b/rainbow/Turtle/Output.cpp index 507aa3ea9..c6c19afca 100644 --- a/rainbow/Turtle/Output.cpp +++ b/rainbow/Turtle/Output.cpp @@ -8,6 +8,8 @@ NAMESPACE_UPP #define LDUMP(x) // RDUMP(x) #define LTIMING(x) +TurtleStream Ctrl::turtle_stream; + void Ctrl::Put16(int x) { Put8(LOBYTE(x)); @@ -40,9 +42,26 @@ void Ctrl::Put(const Rect& r) void Ctrl::Put(const String& s) { Put32(s.GetLength()); + turtle_stream.SetDataFlag(); turtle_stream.Put(s); } +void Ctrl::Output() +{ + socket.Timeout(20000); + if(turtle_stream.HasData()) { + websocket.SendBinary(ZCompress(String(SystemDraw::DISABLESENDING, 1))); // Do not send events until data transfered and processed + int64 x = ++update_serial; + Put8(SystemDraw::UPDATESERIAL); + Put32(LODWORD(x)); + Put32(HIDWORD(x)); + String s = turtle_stream.FlushStream(); + stat_data_send += s.GetCount(); + DLOG("Sending " << s.GetLength()); + websocket.SendBinary(s); + } +} + void Ctrl::TimerAndPaint() { LLOG("TimerAndPaint " << msecs()); @@ -52,18 +71,7 @@ void Ctrl::TimerAndPaint() SyncTopWindows(); SweepMkImageCache(); DoPaint(); - socket.Timeout(20000); - if(turtle_stream.HasData()) { - websocket.SendBinary(ZCompress(String(SystemDraw::DISABLESENDING, 1))); // Do not send events until data transfered and processed - int64 x = ++update_serial; - Put8(SystemDraw::UPDATESERIAL); - Put32(LODWORD(x)); - Put32(HIDWORD(x)); - String s = turtle_stream.FlushStream(); - stat_data_send += s.GetCount(); - LLOG("Sending " << s.GetLength()); - websocket.SendBinary(s); - } + Output(); } void Ctrl::SyncCaret() @@ -109,6 +117,23 @@ void Ctrl::PaintScene(SystemDraw& draw) // DDUMP(turtle_stream.FlushStream().GetCount()); abort(); } +void Ctrl::SetMouseCursor(const Image& image) +{ + GuiLock __; + if(image.GetSerialId() != fbCursorImage.GetSerialId()) { + fbCursorImage = image; + fbCursorPos = Null; + } +} + +void Ctrl::SyncClient() +{ + while(recieved_update_serial < update_serial) { + GuiSleep(10); + IsWaitingEvent(); + } +} + void Ctrl::DoPaint() { if(recieved_update_serial >= update_serial - 1) { // Prevent overloading of transfer diff --git a/rainbow/Turtle/Server.cpp b/rainbow/Turtle/Server.cpp index 75d69c957..22100ff2d 100644 --- a/rainbow/Turtle/Server.cpp +++ b/rainbow/Turtle/Server.cpp @@ -18,6 +18,7 @@ int Ctrl::main_pid; Vector Ctrl::pid; bool Ctrl::quit; + void Ctrl::Broadcast(int signal) { #ifdef PLATFORM_POSIX if(getpid() == main_pid) diff --git a/rainbow/Turtle/Stream.cpp b/rainbow/Turtle/Stream.cpp index 0963d1d4a..2802ac6a3 100644 --- a/rainbow/Turtle/Stream.cpp +++ b/rainbow/Turtle/Stream.cpp @@ -8,8 +8,6 @@ NAMESPACE_UPP #define LDUMP(x) // RDUMP(x) #define LTIMING(x) -TurtleStream turtle_stream; - void TurtleStream::Reset() { zlib.Clear(); @@ -20,7 +18,6 @@ void TurtleStream::Reset() void TurtleStream::Out(const void *data, dword size) { zlib.Put(data, (int)size); - hasdata = true; } String TurtleStream::FlushStream() diff --git a/rainbow/Turtle/Turtle.h b/rainbow/Turtle/Turtle.h index 802c95ffa..d8f7aded3 100644 --- a/rainbow/Turtle/Turtle.h +++ b/rainbow/Turtle/Turtle.h @@ -25,14 +25,13 @@ private: void Reset(); public: - String FlushStream(); + void SetDataFlag() { hasdata = true; } bool HasData() const { return hasdata; } + String FlushStream(); TurtleStream() { Reset(); } }; -extern TurtleStream turtle_stream; - class SystemDraw : public SDraw { public: virtual void PutImage(Point p, const Image& img, const Rect& src); @@ -61,6 +60,9 @@ public: RECTNN = 16, SETCARET = 17, + + HORZDRAGLINE = 18, + VERTDRAGLINE = 19, }; static Index img_index[3]; diff --git a/rainbow/Turtle/Turtle.html b/rainbow/Turtle/Turtle.html index 919360f09..87c33512a 100644 --- a/rainbow/Turtle/Turtle.html +++ b/rainbow/Turtle/Turtle.html @@ -103,6 +103,22 @@ function InvertRect(x, y, cx, cy) ctx.putImageData(imageData, x, y); } +function DrawDragLine(x, y, cx, cy, anim) +{ + if(cx <= 0 || cy <= 0) + return; + var imageData = ctx.getImageData(x, y, cx, cy); + var data = imageData.data; + for(var i = 0; i < data.length; i += 4) { + if(((i / 4 + anim) / 4) & 1) { + data[i] = 255 - data[i]; + data[i + 1] = 255 - data[i + 1]; + data[i + 2] = 255 - data[i + 2]; + } + } + ctx.putImageData(imageData, x, y); +} + function InvertCaret() { // Log("InvertCaret " + caretx + " " + carety + " " + caretcx + " " + caretcy); @@ -144,7 +160,7 @@ function HideCaret(x, y, cx, cy) return; if(Math.max(x, caretx) < Math.min(x + cx, caretx + caretcx) && Math.max(y, carety) < Math.min(y + cy, carety + caretcy)) { - Log("Hiding caret"); + // Log("Hiding caret"); InvertShownCaret(); caretHidden = true; } @@ -154,6 +170,8 @@ function ProcessDraw(s) { // console.clear(); +// Log("Painting started " + s.length); + // window.document.title = "Processing draw"; var p = new Object; @@ -317,11 +335,28 @@ function ProcessDraw(s) CaretTimer(); // Log("SET CARET " + caretx + " " + carety + " " + caretcx + " " + caretcy); } + else + if(Char(p, 18)) { // HORZDRAGLINE, + var x = Get16(p); + var y = Get16(p); + var l = Get16(p); + var anim = Get16(p); + DrawDragLine(x, y, l, 1, anim); + } + else + if(Char(p, 19)) { // VERTDRAGLINE, + var x = Get16(p); + var y = Get16(p); + var l = Get16(p); + var anim = Get16(p); + DrawDragLine(x, y, 1, l, anim); + } } InvertShownCaret(); // window.document.title = "OK"; if(SendingEnabled && event_queue.length) ScheduleSend(); +// Log("Painting finished"); } function SImage(p, sx, sy) @@ -458,9 +493,11 @@ function SendEvents() { if(SendingEnabled) { if(event_queue.length) { - Log(event_queue); + // Log(event_queue); ws.send(event_queue); } + else + ws.send("PING"); event_queue = ""; if(timerID != undefined) clearTimeout(timerID); diff --git a/rainbow/Turtle/Turtle.upp b/rainbow/Turtle/Turtle.upp index 807db5992..6553ceb2c 100644 --- a/rainbow/Turtle/Turtle.upp +++ b/rainbow/Turtle/Turtle.upp @@ -16,7 +16,6 @@ file DrawDragRect.cpp, Ctrl.cpp, Wnd.cpp, - Cursor.cpp, Stream.cpp, Server.cpp, Output.cpp, diff --git a/rainbow/Turtle/Wnd.cpp b/rainbow/Turtle/Wnd.cpp index 0dc89cad5..1c0832020 100644 --- a/rainbow/Turtle/Wnd.cpp +++ b/rainbow/Turtle/Wnd.cpp @@ -168,8 +168,8 @@ Rect Ctrl::GetClipBound(const Vector& inv, const Rect& r) void Ctrl::WndUpdate(const Rect& r) { GuiLock __; -// WndInvalidateRect(r); -// DoPaint(); // TODO + WndInvalidateRect(r); + WndUpdate(); } Rect Ctrl::GetWndScreenRect() const @@ -186,6 +186,9 @@ void Ctrl::WndShow(bool b) void Ctrl::WndUpdate() { GuiLock __; + SyncClient(); + DoPaint(); + Output(); } bool Ctrl::IsWndOpen() const { diff --git a/rainbow/WebWord/WebWord.cpp b/rainbow/WebWord/WebWord.cpp index 6c77a7346..7bdcaa01b 100644 --- a/rainbow/WebWord/WebWord.cpp +++ b/rainbow/WebWord/WebWord.cpp @@ -77,6 +77,9 @@ void UWord::ShowInfo() if(secs) s << ", average bandwidth " << FormatSize(Ctrl::stat_data_send / secs) << "/s"; s << ", actual bandwidth " << FormatSize(Ctrl::stat_data_send - sent_prev); + s << ", putimage " << Ctrl::stat_putimage; + s << ", putrect " << Ctrl::stat_putrect; + s << ", setimage " << Ctrl::stat_setimage << " len " << FormatSize(Ctrl::stat_setimage_len); sent_prev = Ctrl::stat_data_send; statusbar.Set(s); }