* 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
This commit is contained in:
Stephan Aßmus 2006-03-08 19:02:20 +00:00
parent 8e89843efc
commit 907e89c6e8
4 changed files with 62 additions and 28 deletions

View File

@ -597,11 +597,7 @@ Desktop::SetCursor(ServerCursor* newCursor)
if (newCursor == oldCursor)
return;
newCursor->Acquire();
HWInterface()->SetCursor(newCursor);
if (oldCursor != NULL)
oldCursor->Release();
}

View File

@ -8,9 +8,12 @@
#include "EventDispatcher.h"
#include "BitmapManager.h"
#include "EventStream.h"
#include "HWInterface.h"
#include "InputManager.h"
#include "ServerBitmap.h"
#include <TokenSpace.h>
@ -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;
}

View File

@ -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;

View File

@ -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;