diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index d2fdc8bf8e..e17c544d91 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -597,11 +597,7 @@ Desktop::SetCursor(ServerCursor* newCursor) if (newCursor == oldCursor) return; - newCursor->Acquire(); HWInterface()->SetCursor(newCursor); - - if (oldCursor != NULL) - oldCursor->Release(); } diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 5087504046..e3192e52b3 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -8,9 +8,12 @@ #include "EventDispatcher.h" + +#include "BitmapManager.h" #include "EventStream.h" #include "HWInterface.h" #include "InputManager.h" +#include "ServerBitmap.h" #include @@ -517,9 +520,23 @@ EventDispatcher::ViewUnderMouse(EventTarget& target) void -EventDispatcher::SetDragMessage(BMessage& message) +EventDispatcher::SetDragMessage(BMessage& message, + ServerBitmap* bitmap, + const BPoint& offsetFromCursor) { - printf("EventDispatcher::SetDragMessage()\n"); +// printf("EventDispatcher::SetDragMessage()\n"); + + if (fDragBitmap != bitmap) { + if (fDragBitmap) + gBitmapManager->DeleteBitmap(fDragBitmap); + + fDragBitmap = bitmap; + + if (fDragBitmap) + fDragBitmap->Acquire(); + } + + fHWInterface->SetDragBitmap(bitmap, offsetFromCursor); BAutolock _(this); @@ -624,7 +641,7 @@ EventDispatcher::_UnsetFeedFocus(BMessage* message) void EventDispatcher::_DeliverDragMessage() { - printf("EventDispatcher::_DeliverDragMessage()\n"); +// printf("EventDispatcher::_DeliverDragMessage()\n"); if (fDraggingMessage && fPreviousMouseTarget) { fDragMessage.RemoveName("_original_what"); @@ -632,7 +649,7 @@ EventDispatcher::_DeliverDragMessage() fDragMessage.what = _MESSAGE_DROPPED_; // fDragMessage.AddBool("dropped", true); -printf(" sending message to previous mouse target\n"); +//printf(" sending message to previous mouse target\n"); _SendMessage(fPreviousMouseTarget->Messenger(), &fDragMessage, 100.0); } @@ -642,6 +659,9 @@ printf(" sending message to previous mouse target\n"); fDraggingMessage = false; fHWInterface->SetDragBitmap(NULL, B_ORIGIN); + if (fDragBitmap) + gBitmapManager->DeleteBitmap(fDragBitmap); + fDragBitmap = NULL; } diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index fe1d17866d..cc7616d773 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -18,6 +18,7 @@ class EventStream; class HWInterface; +class ServerBitmap; struct event_listener; @@ -86,7 +87,8 @@ class EventDispatcher : public BLocker { int32 ViewUnderMouse(EventTarget& target); - void SetDragMessage(BMessage& message); + void SetDragMessage(BMessage& message, ServerBitmap* bitmap, + const BPoint& offsetFromCursor); // the message should be delivered on the next // "mouse up". // if the mouse is not pressed, it should @@ -140,6 +142,13 @@ class EventDispatcher : public BLocker { BMessage fDragMessage; bool fDraggingMessage; + ServerBitmap* fDragBitmap; + // NOTE: unfortunately, the EventDispatcher + // has to know what a ServerBitmap is... + // otherwise, linking the libs in the + // testenvironment is problematic, because + // the alternative is that HWInterface knows + // about BitmapManager BLocker fCursorLock; HWInterface* fHWInterface; diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index d05c17a0c3..6264d5a271 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -75,20 +75,18 @@ void HWInterface::SetCursor(ServerCursor* cursor) { if (WriteLock()) { - if (fDragBitmap) { - // if a bitmap is being dragged, - // we don't currently allow changing - // the cursor, part of the reason being - // that the original drag bitmap is not - // around anymore... but it could be - // considered iritating to the user to - // change cursor shapes while something - // is dragged anyways. - // TODO: like a "+" or "-" sign when dragging some files to indicate - // the current drag mode? - WriteUnlock(); - return; - } + // TODO: if a bitmap is being dragged, it could + // be considered iritating to the user to change + // cursor shapes while something is dragged. + // The disabled code below would do this (except + // for the minor annoyance that the cursor is not + // updated when the drag is over) +// if (fDragBitmap) { +// // TODO: like a "+" or "-" sign when dragging some files to indicate +// // the current drag mode? +// WriteUnlock(); +// return; +// } if (fCursor != cursor) { BRect oldFrame = _CursorFrame(); @@ -97,7 +95,14 @@ HWInterface::SetCursor(ServerCursor* cursor) fCursorAndDragBitmap = NULL; } + if (fCursor) + fCursor->Release(); + fCursor = cursor; + + if (fCursor) + fCursor->Acquire(); + Invalidate(oldFrame); _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset); @@ -625,7 +630,8 @@ void HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) { // TODO: support other colorspaces/convert bitmap - if (bitmap && !(bitmap->ColorSpace() == B_RGB32 || bitmap->ColorSpace() == B_RGBA32)) { + if (bitmap && !(bitmap->ColorSpace() == B_RGB32 + || bitmap->ColorSpace() == B_RGBA32)) { fprintf(stderr, "HWInterface::_AdoptDragBitmap() - bitmap has yet unsupported colorspace\n"); return; } @@ -633,7 +639,7 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) _RestoreCursorArea(); Invalidate(_CursorFrame()); - if (fCursorAndDragBitmap != fCursor) { + if (fCursorAndDragBitmap && fCursorAndDragBitmap != fCursor) { delete fCursorAndDragBitmap; fCursorAndDragBitmap = NULL; } @@ -701,7 +707,7 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) for (uint32 x = 0; x < width; x++) { // takes two semi-transparent pixels // with unassociated alpha (not pre-multiplied) - // and produces a premultiplied + // and stays within non-premultiplied color space if (s[3] > 0) { if (s[3] == 255) { d[0] = s[0]; @@ -758,13 +764,16 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) fCursorAndDragBitmap = fCursor; } -// TODO: handle reference counting stuff +// NOTE: the EventDispatcher does the reference counting stuff for us +// TODO: You can not simply call Release() on a ServerBitmap like you +// can for a ServerCursor... it could be changed, but there are linking +// troubles with the test environment that need to be solved than. // if (fDragBitmap) // fDragBitmap->Release(); fDragBitmap = bitmap; fDragBitmapOffset = offset; // if (fDragBitmap) -// fDragBitmap->Aquire(); +// fDragBitmap->Acquire(); delete fCursorAreaBackup; fCursorAreaBackup = NULL;