diff --git a/headers/os/interface/Region.h b/headers/os/interface/Region.h index b4d1fab129..5ca0616e1b 100644 --- a/headers/os/interface/Region.h +++ b/headers/os/interface/Region.h @@ -17,10 +17,10 @@ namespace BPrivate { class ServerLink; + class LinkReceiver; }; - -/* Integer rect used to define a cliping rectangle. All bounds are included */ +/* Integer rect used to define a clipping rectangle. All bounds are inclusive. */ /* Moved from DirectWindow.h */ typedef struct { int32 left; @@ -71,6 +71,7 @@ private: friend class BDirectWindow; friend class Support; friend class BPrivate::ServerLink; + friend class BPrivate::LinkReceiver; void _AddRect(clipping_rect r); void set_size(long new_size); diff --git a/headers/private/app/LinkReceiver.h b/headers/private/app/LinkReceiver.h index b2a804d205..748a52b4f7 100644 --- a/headers/private/app/LinkReceiver.h +++ b/headers/private/app/LinkReceiver.h @@ -14,6 +14,7 @@ #include class BString; +class BRegion; namespace BPrivate { @@ -26,15 +27,16 @@ class LinkReceiver { void SetPort(port_id port); port_id Port(void) { return fReceivePort; } - status_t GetNextMessage(int32 &code, bigtime_t timeout = B_INFINITE_TIMEOUT); + status_t GetNextMessage(int32& code, bigtime_t timeout = B_INFINITE_TIMEOUT); bool HasMessages() const; bool NeedsReply() const; int32 Code() const; - virtual status_t Read(void *data, ssize_t size); + virtual status_t Read(void* data, ssize_t size); status_t ReadString(char** _string, size_t* _length = NULL); status_t ReadString(BString& string, size_t* _length = NULL); - status_t ReadString(char *buffer, size_t bufferSize); + status_t ReadString(char* buffer, size_t bufferSize); + status_t ReadRegion(BRegion* region); template status_t Read(Type *data) { return Read(data, sizeof(Type)); } @@ -46,7 +48,7 @@ class LinkReceiver { port_id fReceivePort; - char *fRecvBuffer; + char* fRecvBuffer; int32 fRecvPosition; //current read position int32 fRecvStart; //start of current message int32 fRecvBufferSize; diff --git a/src/kits/app/LinkReceiver.cpp b/src/kits/app/LinkReceiver.cpp index 84e1d7e1dd..cf7472793d 100644 --- a/src/kits/app/LinkReceiver.cpp +++ b/src/kits/app/LinkReceiver.cpp @@ -5,17 +5,20 @@ * Authors: * Pahtz * Axel Dörfler + * Stephan Aßmus */ /** Class for low-overhead port-based messaging */ +#include + #include #include #include #include -#include #include +#include #include "link_message.h" @@ -396,4 +399,22 @@ err: return status; } +status_t +LinkReceiver::ReadRegion(BRegion* region) +{ + status_t status = Read(®ion->count, sizeof(int32)); + if (status >= B_OK) + status = Read(®ion->bound, sizeof(clipping_rect)); + if (status >= B_OK) { + region->set_size(region->count); + status = Read(region->data, region->count * sizeof(clipping_rect)); + if (status < B_OK) + region->MakeEmpty(); + } + return status; +} + + } // namespace BPrivate + + diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index be49b4df60..b9c4a20185 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -2714,19 +2714,12 @@ BView::FillRegion(BRegion *region, ::pattern pattern) _UpdatePattern(pattern); - int32 count = region->CountRects(); + fOwner->fLink->StartMessage(AS_FILL_REGION); + fOwner->fLink->AttachRegion(*region); + // TODO: make this automatically chose + // to send over area or handle failure here? - if (count * sizeof(BRect) < MAX_ATTACHMENT_SIZE) { - fOwner->fLink->StartMessage(AS_FILL_REGION); - fOwner->fLink->Attach(count); - - for (int32 i = 0; i < count; i++) - fOwner->fLink->Attach(region->RectAt(i)); - - _FlushIfNotInTransaction(); - } else { - // TODO: send via area - } + _FlushIfNotInTransaction(); } diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index d4db8125eb..c2ac4d213e 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -871,6 +871,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&token) != B_OK) break; + if (!fDesktop->GetCursorManager().Lock()) + break; + ServerCursor* oldCursor = fAppCursor; fAppCursor = fDesktop->GetCursorManager().FindCursor(token); if (fAppCursor != NULL) @@ -882,6 +885,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (oldCursor != NULL) oldCursor->Release(); + fDesktop->GetCursorManager().Unlock(); + if (sync) { // The application is expecting a reply fLink.StartMessage(B_OK); @@ -944,6 +949,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (link.Read(&pendingViewCursor) != B_OK) break; + if (!fDesktop->GetCursorManager().Lock()) + break; + ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); if (cursor) { if (pendingViewCursor) @@ -951,6 +959,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) cursor->Release(); } + fDesktop->GetCursorManager().Unlock(); + break; } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index f9b5064bef..b623621803 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1258,9 +1258,14 @@ ServerWindow::_DispatchViewMessage(int32 code, if (link.Read(&sync) != B_OK) break; + if (!fDesktop->GetCursorManager().Lock()) + break; + ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); fCurrentLayer->SetCursor(cursor); + fDesktop->GetCursorManager().Unlock(); + if (fWindowLayer->IsFocus()) { // The cursor might need to be updated now if (fDesktop->ViewUnderMouse(fWindowLayer) == fCurrentLayer->Token()) @@ -1603,6 +1608,7 @@ ServerWindow::_DispatchViewMessage(int32 code, status = link.Read(&r); if (status < B_OK) break; + // TODO: optimize (use AttachRegion()+ReadRegion()) region.Include(r); } } else @@ -2096,30 +2102,13 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, BPrivate::LinkReceiver &li { DTRACE(("ServerWindow %s: Message AS_FILL_REGION\n", Title())); - int32 count; - link.Read(&count); - - BRect* rects = new(nothrow) BRect[count]; - if (link.Read(rects, sizeof(BRect) * count) < B_OK) { - delete[] rects; - break; - } - - // Between the client-side conversion to BRects from clipping_rects to the overhead - // in repeatedly calling FillRect(), this is definitely in need of optimization. At - // least it works for now. :) BRegion region; - for (int32 i = 0; i < count; i++) { - region.Include(rects[i]); - } + if (link.ReadRegion(®ion) < B_OK) + break; fCurrentLayer->ConvertToScreenForDrawing(®ion); drawingEngine->FillRegion(region, fCurrentLayer->CurrentState()); - delete[] rects; - - // TODO: create support for clipping_rect usage for faster BRegion display. - // Tweaks to DrawingEngine are necessary along with conversion routines in ViewLayer break; } case AS_STROKE_LINEARRAY: