From 907e89c6e83770685f47219bb625d411602c4694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 8 Mar 2006 19:02:20 +0000 Subject: [PATCH] * The EventDispatcher takes care of reference counting the ServerBitmap used for the drag bitmap, see NOTEs on why that is... * moved reference counting of the ServerCursor from Desktop into HWInterface where it is actually used * I hope to have fixed the problems with _DrawCursor when dragging something. At least the reference counting of the ServerCursor was for real, since the HWInterface rejected changes to the cursor while something was dragged, which caused the old cursor to be Released() and deleted each time the mouse moved... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16657 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Desktop.cpp | 4 --- src/servers/app/EventDispatcher.cpp | 28 ++++++++++++--- src/servers/app/EventDispatcher.h | 11 +++++- src/servers/app/drawing/HWInterface.cpp | 47 +++++++++++++++---------- 4 files changed, 62 insertions(+), 28 deletions(-) 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;