various changes to handling custom cursors:
* all cursors owned by a team are visually different, or (iaw) an already existing cursor is reused when it is set by the client again * changed various occurances of cursor data from "int8*" to "uint8*" * ServerCursors also remember the R5 data from which they were created * the reference counting and destruction of ServerCursors changed: The cursor knows it is attached to a CursorManager and one can simply use ServerCursor::Acquire() and Release() and the reference counting and everything is being taken care of * destroying a ViewLayer will now correctly release a set ServerCursor * fixed a race condition when setting a cursor through BView::SetViewCursor(): If the client code looks like this: BCursor cursor(cursorData); someView->SetViewCursor(&cursor, false); there is a relatively high chance the BCursor destructor told the ServerApp thread to destroy the cursor before the ServerWindow thread got to "acquire" the cursor for use by the view layer. The very same problem is likely the reason that SetViewCursor works to unreliably on R5, even when the "sync" flag is set to "true" (although it should theoretically work in that case). all these fixes make WonderBrush work fine again with the new support of custom cursors.... coded by axeld and myself (the joys of pair programming :-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16521 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -33,6 +33,7 @@ class BCursor : BArchivable {
|
|||||||
|
|
||||||
int32 fServerToken;
|
int32 fServerToken;
|
||||||
bool fNeedToFree;
|
bool fNeedToFree;
|
||||||
|
mutable bool fPendingViewCursor;
|
||||||
|
|
||||||
uint32 _reserved[6];
|
uint32 _reserved[6];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class CursorSet : public BMessage {
|
|||||||
status_t Save(const char *path,int32 saveflags=0);
|
status_t Save(const char *path,int32 saveflags=0);
|
||||||
status_t Load(const char *path);
|
status_t Load(const char *path);
|
||||||
status_t AddCursor(cursor_which which,const BBitmap *cursor, const BPoint &hotspot);
|
status_t AddCursor(cursor_which which,const BBitmap *cursor, const BPoint &hotspot);
|
||||||
status_t AddCursor(cursor_which which, int8 *data);
|
status_t AddCursor(cursor_which which, uint8 *data);
|
||||||
void RemoveCursor(cursor_which which);
|
void RemoveCursor(cursor_which which);
|
||||||
status_t FindCursor(cursor_which which, BBitmap **cursor, BPoint *hotspot);
|
status_t FindCursor(cursor_which which, BBitmap **cursor, BPoint *hotspot);
|
||||||
status_t FindCursor(cursor_which which, ServerCursor **cursor);
|
status_t FindCursor(cursor_which which, ServerCursor **cursor);
|
||||||
@@ -51,7 +51,7 @@ class CursorSet : public BMessage {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const char *_CursorWhichToString(cursor_which which);
|
const char *_CursorWhichToString(cursor_which which);
|
||||||
BBitmap *_CursorDataToBitmap(int8 *data);
|
BBitmap *_CursorDataToBitmap(uint8 *data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CURSOR_SET_H
|
#endif // CURSOR_SET_H
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class ServerCursor : public ServerBitmap {
|
|||||||
int32 flags, BPoint hotspot,
|
int32 flags, BPoint hotspot,
|
||||||
int32 bytesperrow = -1,
|
int32 bytesperrow = -1,
|
||||||
screen_id screen = B_MAIN_SCREEN_ID);
|
screen_id screen = B_MAIN_SCREEN_ID);
|
||||||
ServerCursor(const int8* cursorDataFromR5);
|
ServerCursor(const uint8* cursorDataFromR5);
|
||||||
ServerCursor(const uint8* alreadyPaddedData,
|
ServerCursor(const uint8* alreadyPaddedData,
|
||||||
uint32 width, uint32 height,
|
uint32 width, uint32 height,
|
||||||
color_space format);
|
color_space format);
|
||||||
@@ -47,8 +47,16 @@ class ServerCursor : public ServerBitmap {
|
|||||||
int32 Token() const
|
int32 Token() const
|
||||||
{ return fToken; }
|
{ return fToken; }
|
||||||
|
|
||||||
void Acquire() { atomic_add(&fReferenceCount, 1); }
|
void Acquire()
|
||||||
bool Release() { return atomic_add(&fReferenceCount, -1) == 1; }
|
{ atomic_add(&fReferenceCount, 1); }
|
||||||
|
bool Release();
|
||||||
|
|
||||||
|
void SetPendingViewCursor(bool pending);
|
||||||
|
|
||||||
|
void AttachedToManager(CursorManager* manager);
|
||||||
|
|
||||||
|
const uint8* CursorData() const
|
||||||
|
{ return fCursorData; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CursorManager;
|
friend class CursorManager;
|
||||||
@@ -56,6 +64,9 @@ class ServerCursor : public ServerBitmap {
|
|||||||
BPoint fHotSpot;
|
BPoint fHotSpot;
|
||||||
team_id fOwningTeam;
|
team_id fOwningTeam;
|
||||||
int32 fReferenceCount;
|
int32 fReferenceCount;
|
||||||
|
uint8* fCursorData;
|
||||||
|
CursorManager* fManager;
|
||||||
|
vint32 fPendingViewCursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SERVER_CURSOR_H
|
#endif // SERVER_CURSOR_H
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ const BCursor *B_CURSOR_I_BEAM;
|
|||||||
BCursor::BCursor(const void *cursorData)
|
BCursor::BCursor(const void *cursorData)
|
||||||
:
|
:
|
||||||
fServerToken(-1),
|
fServerToken(-1),
|
||||||
fNeedToFree(false)
|
fNeedToFree(false),
|
||||||
|
fPendingViewCursor(false)
|
||||||
{
|
{
|
||||||
const uint8 *data = (const uint8 *)cursorData;
|
const uint8 *data = (const uint8 *)cursorData;
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ BCursor::BCursor(BMessage *data)
|
|||||||
// undefined on BeOS
|
// undefined on BeOS
|
||||||
fServerToken = -1;
|
fServerToken = -1;
|
||||||
fNeedToFree = false;
|
fNeedToFree = false;
|
||||||
|
fPendingViewCursor = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -78,6 +80,7 @@ BCursor::~BCursor()
|
|||||||
BPrivate::AppServerLink link;
|
BPrivate::AppServerLink link;
|
||||||
link.StartMessage(AS_DELETE_CURSOR);
|
link.StartMessage(AS_DELETE_CURSOR);
|
||||||
link.Attach<int32>(fServerToken);
|
link.Attach<int32>(fServerToken);
|
||||||
|
link.Attach<bool>(fPendingViewCursor);
|
||||||
link.Flush();
|
link.Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -980,18 +980,20 @@ BView::ResizingMode() const
|
|||||||
void
|
void
|
||||||
BView::SetViewCursor(const BCursor *cursor, bool sync)
|
BView::SetViewCursor(const BCursor *cursor, bool sync)
|
||||||
{
|
{
|
||||||
if (!cursor)
|
if (cursor == NULL || fOwner == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!fOwner)
|
|
||||||
debugger("View method requires owner and doesn't have one");
|
|
||||||
|
|
||||||
check_lock();
|
check_lock();
|
||||||
|
|
||||||
fOwner->fLink->StartMessage(AS_LAYER_SET_CURSOR);
|
fOwner->fLink->StartMessage(AS_LAYER_SET_CURSOR);
|
||||||
fOwner->fLink->Attach<int32>(cursor->fServerToken);
|
fOwner->fLink->Attach<int32>(cursor->fServerToken);
|
||||||
|
|
||||||
if (sync)
|
if (!sync) {
|
||||||
|
cursor->fPendingViewCursor = true;
|
||||||
|
// this avoids a race condition in case the cursor is
|
||||||
|
// immediately deleted after this call, as the deletion
|
||||||
|
// is handled by the application, not the window
|
||||||
|
} else
|
||||||
fOwner->fLink->Flush();
|
fOwner->fLink->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ transparent. Transparency only applies to white pixels—black pixels are always
|
|||||||
|
|
||||||
// Impressive ASCII art, eh?
|
// Impressive ASCII art, eh?
|
||||||
|
|
||||||
int8 default_cursor_data[] = {
|
uint8 default_cursor_data[] = {
|
||||||
16,1,0,0,
|
16,1,0,0,
|
||||||
255,224, // ***********-----
|
255,224, // ***********-----
|
||||||
128,16, // *----------*----
|
128,16, // *----------*----
|
||||||
@@ -91,56 +91,56 @@ int8 default_cursor_data[] = {
|
|||||||
0,0
|
0,0
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_text_data[] = {
|
uint8 default_text_data[] = {
|
||||||
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x06, 0xC0, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x06, 0xC0, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||||
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xC0, 0x0F, 0xE0, 0x07, 0xC0, 0x03, 0x80,
|
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x06, 0xC0, 0x0F, 0xE0, 0x07, 0xC0, 0x03, 0x80,
|
||||||
0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x07, 0xC0, 0x0F, 0xE0,
|
0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x07, 0xC0, 0x0F, 0xE0,
|
||||||
0x06, 0xC0
|
0x06, 0xC0
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_move_data[] = {
|
uint8 default_move_data[] = {
|
||||||
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x07, 0xC0, 0x00, 0x00, 0x10, 0x10, 0x30, 0x18, 0x71, 0x1C, 0x30, 0x18,
|
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x07, 0xC0, 0x00, 0x00, 0x10, 0x10, 0x30, 0x18, 0x71, 0x1C, 0x30, 0x18,
|
||||||
0x10, 0x10, 0x00, 0x00, 0x07, 0xC0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x07, 0xC0, 0x0F, 0xE0,
|
0x10, 0x10, 0x00, 0x00, 0x07, 0xC0, 0x03, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x07, 0xC0, 0x0F, 0xE0,
|
||||||
0x1F, 0xF0, 0x38, 0x38, 0x7B, 0xBC, 0xFB, 0xBE, 0x7B, 0xBC, 0x38, 0x38, 0x1F, 0xF0, 0x0F, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x01, 0x00,
|
0x1F, 0xF0, 0x38, 0x38, 0x7B, 0xBC, 0xFB, 0xBE, 0x7B, 0xBC, 0x38, 0x38, 0x1F, 0xF0, 0x0F, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x01, 0x00,
|
||||||
0x00, 0x00
|
0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_drag_data[] = {
|
uint8 default_drag_data[] = {
|
||||||
0x10, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x81, 0x00, 0x82, 0x00, 0x82, 0x00, 0x81, 0xFF, 0x80, 0x81, 0xB0, 0x41, 0xC8, 0x41, 0x04, 0x81,
|
0x10, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x81, 0x00, 0x82, 0x00, 0x82, 0x00, 0x81, 0xFF, 0x80, 0x81, 0xB0, 0x41, 0xC8, 0x41, 0x04, 0x81,
|
||||||
0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFE, 0x00, 0xFE, 0x00,
|
0x03, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFE, 0x00, 0xFE, 0x00,
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x07, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF,
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x07, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0xFF,
|
||||||
0x03, 0xFF
|
0x03, 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_resize_data[] = {
|
uint8 default_resize_data[] = {
|
||||||
0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x3E, 0x78, 0x1E, 0x70, 0x0E, 0x68, 0x16, 0x44, 0x22, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80,
|
0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x3E, 0x78, 0x1E, 0x70, 0x0E, 0x68, 0x16, 0x44, 0x22, 0x02, 0x40, 0x01, 0x80, 0x01, 0x80,
|
||||||
0x02, 0x40, 0x44, 0x22, 0x68, 0x16, 0x70, 0x0E, 0x78, 0x1E, 0x7C, 0x3E, 0x00, 0x00, 0xFE, 0x7F, 0xFE, 0x7F, 0xFC, 0x3F, 0xF8, 0x1F,
|
0x02, 0x40, 0x44, 0x22, 0x68, 0x16, 0x70, 0x0E, 0x78, 0x1E, 0x7C, 0x3E, 0x00, 0x00, 0xFE, 0x7F, 0xFE, 0x7F, 0xFC, 0x3F, 0xF8, 0x1F,
|
||||||
0xFC, 0x3F, 0xEE, 0x77, 0xC7, 0xE3, 0x03, 0xC0, 0x03, 0xC0, 0xC7, 0xE3, 0xEE, 0x77, 0xFC, 0x3F, 0xF8, 0x1F, 0xFC, 0x3F, 0xFE, 0x7F,
|
0xFC, 0x3F, 0xEE, 0x77, 0xC7, 0xE3, 0x03, 0xC0, 0x03, 0xC0, 0xC7, 0xE3, 0xEE, 0x77, 0xFC, 0x3F, 0xF8, 0x1F, 0xFC, 0x3F, 0xFE, 0x7F,
|
||||||
0xFE, 0x7F
|
0xFE, 0x7F
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_resize_ew_data[] = {
|
uint8 default_resize_ew_data[] = {
|
||||||
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x10, 0x31, 0x18, 0x71, 0x1C, 0x71, 0x1C,
|
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x10, 0x31, 0x18, 0x71, 0x1C, 0x71, 0x1C,
|
||||||
0x31, 0x18, 0x11, 0x10, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x03, 0x80, 0x0B, 0xA0,
|
0x31, 0x18, 0x11, 0x10, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x03, 0x80, 0x0B, 0xA0,
|
||||||
0x1B, 0xB0, 0x3B, 0xB8, 0x7B, 0xBC, 0xFB, 0xBE, 0xFB, 0xBE, 0x7B, 0xBC, 0x3B, 0xB8, 0x1B, 0xB0, 0x0B, 0xA0, 0x03, 0x80, 0x03, 0x80,
|
0x1B, 0xB0, 0x3B, 0xB8, 0x7B, 0xBC, 0xFB, 0xBE, 0xFB, 0xBE, 0x7B, 0xBC, 0x3B, 0xB8, 0x1B, 0xB0, 0x0B, 0xA0, 0x03, 0x80, 0x03, 0x80,
|
||||||
0x01, 0x00
|
0x01, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_resize_ns_data[] = {
|
uint8 default_resize_ns_data[] = {
|
||||||
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
|
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x0F, 0xF0,
|
0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0xC0, 0x07, 0xE0, 0x0F, 0xF0,
|
||||||
0x1F, 0xF8, 0x00, 0x00, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0x00, 0x00, 0x1F, 0xF8, 0x0F, 0xF0, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80,
|
0x1F, 0xF8, 0x00, 0x00, 0x7F, 0xFE, 0xFF, 0xFF, 0x7F, 0xFE, 0x00, 0x00, 0x1F, 0xF8, 0x0F, 0xF0, 0x07, 0xE0, 0x03, 0xC0, 0x01, 0x80,
|
||||||
0x00, 0x00
|
0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_resize_nwse_data[] = {
|
uint8 default_resize_nwse_data[] = {
|
||||||
0x10, 0x01, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x08, 0x1E, 0x10, 0x1C, 0x20, 0x18, 0x40, 0x10, 0x80, 0x01, 0x08,
|
0x10, 0x01, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x08, 0x1E, 0x10, 0x1C, 0x20, 0x18, 0x40, 0x10, 0x80, 0x01, 0x08,
|
||||||
0x02, 0x18, 0x04, 0x38, 0x08, 0x78, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xCC, 0x3F, 0x9C,
|
0x02, 0x18, 0x04, 0x38, 0x08, 0x78, 0x10, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xCC, 0x3F, 0x9C,
|
||||||
0x3F, 0x38, 0x3E, 0x70, 0x3C, 0xE4, 0x39, 0xCC, 0x33, 0x9C, 0x27, 0x3C, 0x0E, 0x7C, 0x1C, 0xFC, 0x39, 0xFC, 0x33, 0xFC, 0x00, 0x00,
|
0x3F, 0x38, 0x3E, 0x70, 0x3C, 0xE4, 0x39, 0xCC, 0x33, 0x9C, 0x27, 0x3C, 0x0E, 0x7C, 0x1C, 0xFC, 0x39, 0xFC, 0x33, 0xFC, 0x00, 0x00,
|
||||||
0x00, 0x00
|
0x00, 0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
int8 default_resize_nesw_data[] = {
|
uint8 default_resize_nesw_data[] = {
|
||||||
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xF8, 0x08, 0x78, 0x04, 0x38, 0x02, 0x18, 0x01, 0x08, 0x10, 0x80,
|
0x10, 0x01, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xF8, 0x08, 0x78, 0x04, 0x38, 0x02, 0x18, 0x01, 0x08, 0x10, 0x80,
|
||||||
0x18, 0x40, 0x1C, 0x20, 0x1E, 0x10, 0x1F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xFC, 0x39, 0xFC,
|
0x18, 0x40, 0x1C, 0x20, 0x1E, 0x10, 0x1F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xFC, 0x39, 0xFC,
|
||||||
0x1C, 0xFC, 0x0E, 0x7C, 0x27, 0x3C, 0x33, 0x9C, 0x39, 0xCC, 0x3C, 0xE4, 0x3E, 0x70, 0x3F, 0x38, 0x3F, 0x9C, 0x3F, 0xCC, 0x00, 0x00,
|
0x1C, 0xFC, 0x0E, 0x7C, 0x27, 0x3C, 0x33, 0x9C, 0x39, 0xCC, 0x3C, 0xE4, 0x3E, 0x70, 0x3F, 0x38, 0x3F, 0x9C, 0x3F, 0xCC, 0x00, 0x00,
|
||||||
@@ -149,7 +149,7 @@ int8 default_resize_nesw_data[] = {
|
|||||||
|
|
||||||
|
|
||||||
// known good cursor data for testing rest of system
|
// known good cursor data for testing rest of system
|
||||||
int8 cross_cursor[] = {16,1,5,5,
|
uint8 cross_cursor[] = {16,1,5,5,
|
||||||
14,0,4,0,4,0,4,0,128,32,241,224,128,32,4,0,
|
14,0,4,0,4,0,4,0,128,32,241,224,128,32,4,0,
|
||||||
4,0,4,0,14,0,0,0,0,0,0,0,0,0,0,0,
|
4,0,4,0,14,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
14,0,4,0,4,0,4,0,128,32,245,224,128,32,4,0,
|
14,0,4,0,4,0,4,0,128,32,245,224,128,32,4,0,
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
extern int8 default_cursor_data[];
|
extern uint8 default_cursor_data[];
|
||||||
extern int8 default_text_data[];
|
extern uint8 default_text_data[];
|
||||||
extern int8 default_move_data[];
|
extern uint8 default_move_data[];
|
||||||
extern int8 default_drag_data[];
|
extern uint8 default_drag_data[];
|
||||||
extern int8 default_resize_data[];
|
extern uint8 default_resize_data[];
|
||||||
extern int8 default_resize_ew_data[];
|
extern uint8 default_resize_ew_data[];
|
||||||
extern int8 default_resize_ns_data[];
|
extern uint8 default_resize_ns_data[];
|
||||||
extern int8 default_resize_nwse_data[];
|
extern uint8 default_resize_nwse_data[];
|
||||||
extern int8 default_resize_nesw_data[];
|
extern uint8 default_resize_nesw_data[];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,9 +8,11 @@
|
|||||||
|
|
||||||
/** Handles the system's cursor infrastructure */
|
/** Handles the system's cursor infrastructure */
|
||||||
|
|
||||||
|
#include "CursorManager.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "CursorData.h"
|
#include "CursorData.h"
|
||||||
#include "CursorManager.h"
|
|
||||||
#include "HaikuSystemCursor.h"
|
#include "HaikuSystemCursor.h"
|
||||||
#include "ServerCursor.h"
|
#include "ServerCursor.h"
|
||||||
#include "ServerConfig.h"
|
#include "ServerConfig.h"
|
||||||
@@ -67,72 +69,80 @@ CursorManager::CursorManager()
|
|||||||
CursorManager::~CursorManager()
|
CursorManager::~CursorManager()
|
||||||
{
|
{
|
||||||
for (int32 i = 0; i < fCursorList.CountItems(); i++) {
|
for (int32 i = 0; i < fCursorList.CountItems(); i++) {
|
||||||
delete (ServerCursor *)fCursorList.ItemAt(i);
|
delete (ServerCursor*)fCursorList.ItemAtFast(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerCursor*
|
||||||
|
CursorManager::CreateCursor(team_id clientTeam, const uint8* cursorData)
|
||||||
|
{
|
||||||
|
if (!Lock())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ServerCursor* cursor = _FindCursor(clientTeam, cursorData);
|
||||||
|
|
||||||
|
if (!cursor) {
|
||||||
|
cursor = new (nothrow) ServerCursor(cursorData);
|
||||||
|
if (cursor) {
|
||||||
|
cursor->SetOwningTeam(clientTeam);
|
||||||
|
if (AddCursor(cursor) < B_OK) {
|
||||||
|
delete cursor;
|
||||||
|
cursor = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cursor->Acquire();
|
||||||
|
}
|
||||||
|
|
||||||
|
Unlock();
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Registers a cursor with the manager.
|
\brief Registers a cursor with the manager.
|
||||||
\param sc ServerCursor object to register
|
\param cursor ServerCursor object to register
|
||||||
\return The token assigned to the cursor or B_ERROR if sc is NULL
|
\return The token assigned to the cursor or B_ERROR if cursor is NULL
|
||||||
*/
|
*/
|
||||||
int32
|
int32
|
||||||
CursorManager::AddCursor(ServerCursor* cursor, int32 token)
|
CursorManager::AddCursor(ServerCursor* cursor, int32 token)
|
||||||
{
|
{
|
||||||
if (!cursor)
|
if (!cursor || !Lock())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
Lock();
|
if (!fCursorList.AddItem(cursor)) {
|
||||||
|
Unlock();
|
||||||
fCursorList.AddItem(cursor);
|
return B_ERROR;
|
||||||
if (token == -1)
|
|
||||||
cursor->fToken = fTokenSpace.NewToken(kCursorToken, cursor);
|
|
||||||
else {
|
|
||||||
fTokenSpace.SetToken(token, kCursorToken, cursor);
|
|
||||||
cursor->fToken = token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token == -1) {
|
||||||
|
token = fTokenSpace.NewToken(kCursorToken, cursor);
|
||||||
|
} else {
|
||||||
|
fTokenSpace.SetToken(token, kCursorToken, cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor->fToken = token;
|
||||||
|
cursor->AttachedToManager(this);
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
CursorManager::_RemoveCursor(ServerCursor* cursor)
|
|
||||||
{
|
|
||||||
fCursorList.RemoveItem(cursor);
|
|
||||||
fTokenSpace.RemoveToken(cursor->fToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ServerCursor*
|
|
||||||
CursorManager::_RemoveCursor(int32 index)
|
|
||||||
{
|
|
||||||
ServerCursor* cursor = (ServerCursor *)fCursorList.RemoveItem(index);
|
|
||||||
if (cursor != NULL)
|
|
||||||
fTokenSpace.RemoveToken(cursor->fToken);
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Releases a reference to a cursor
|
\brief Releases a reference to a cursor
|
||||||
|
|
||||||
If this was the last reference to this cursor, it will be deleted.
|
If this was the last reference to this cursor, it will be deleted.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
CursorManager::ReleaseCursor(ServerCursor* cursor)
|
CursorManager::RemoveCursor(ServerCursor* cursor)
|
||||||
{
|
{
|
||||||
Lock();
|
if (!Lock())
|
||||||
|
return;
|
||||||
|
|
||||||
if (cursor->Release()) {
|
_RemoveCursor(cursor);
|
||||||
// this was the last reference, remove the cursor
|
|
||||||
|
|
||||||
_RemoveCursor(cursor);
|
|
||||||
delete cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
@@ -145,15 +155,13 @@ CursorManager::ReleaseCursor(ServerCursor* cursor)
|
|||||||
void
|
void
|
||||||
CursorManager::DeleteCursors(team_id team)
|
CursorManager::DeleteCursors(team_id team)
|
||||||
{
|
{
|
||||||
Lock();
|
if (!Lock())
|
||||||
|
return;
|
||||||
|
|
||||||
for (int32 index = fCursorList.CountItems(); index-- > 0;) {
|
for (int32 index = fCursorList.CountItems(); index-- > 0;) {
|
||||||
ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index);
|
ServerCursor *cursor = (ServerCursor*)fCursorList.ItemAtFast(index);
|
||||||
if (cursor->OwningTeam() != team)
|
if (cursor->OwningTeam() == team)
|
||||||
continue;
|
cursor->Release();
|
||||||
|
|
||||||
_RemoveCursor(index);
|
|
||||||
delete cursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Unlock();
|
Unlock();
|
||||||
@@ -372,22 +380,6 @@ CursorManager::ChangeCursor(cursor_which which, int32 token)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Internal function which finds the cursor with a particular ID
|
|
||||||
\param token ID of the cursor to find
|
|
||||||
\return The cursor or NULL if not found
|
|
||||||
*/
|
|
||||||
ServerCursor *
|
|
||||||
CursorManager::FindCursor(int32 token)
|
|
||||||
{
|
|
||||||
ServerCursor* cursor;
|
|
||||||
if (fTokenSpace.GetToken(token, kCursorToken, (void**)&cursor) == B_OK)
|
|
||||||
return cursor;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Sets the cursors to the defaults and saves them to CURSOR_SETTINGS_DIR/"d
|
//! Sets the cursors to the defaults and saves them to CURSOR_SETTINGS_DIR/"d
|
||||||
void
|
void
|
||||||
CursorManager::SetDefaults()
|
CursorManager::SetDefaults()
|
||||||
@@ -415,3 +407,56 @@ CursorManager::SetDefaults()
|
|||||||
SetCursorSet(string.String());
|
SetCursorSet(string.String());
|
||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Internal function which finds the cursor with a particular ID
|
||||||
|
\param token ID of the cursor to find
|
||||||
|
\return The cursor or NULL if not found
|
||||||
|
*/
|
||||||
|
ServerCursor *
|
||||||
|
CursorManager::FindCursor(int32 token)
|
||||||
|
{
|
||||||
|
ServerCursor* cursor;
|
||||||
|
if (fTokenSpace.GetToken(token, kCursorToken, (void**)&cursor) == B_OK)
|
||||||
|
return cursor;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ServerCursor *
|
||||||
|
CursorManager::_FindCursor(team_id clientTeam, const uint8* cursorData)
|
||||||
|
{
|
||||||
|
int32 count = fCursorList.CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
ServerCursor* cursor = (ServerCursor*)fCursorList.ItemAtFast(i);
|
||||||
|
if (cursor->OwningTeam() == clientTeam
|
||||||
|
&& cursor->CursorData()
|
||||||
|
&& memcmp(cursor->CursorData(), cursorData, 68) == 0) {
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CursorManager::_RemoveCursor(ServerCursor* cursor)
|
||||||
|
{
|
||||||
|
fCursorList.RemoveItem(cursor);
|
||||||
|
fTokenSpace.RemoveToken(cursor->fToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ServerCursor*
|
||||||
|
//CursorManager::_RemoveCursor(int32 index)
|
||||||
|
//{
|
||||||
|
// ServerCursor* cursor = (ServerCursor*)fCursorList.RemoveItem(index);
|
||||||
|
// if (cursor != NULL)
|
||||||
|
// fTokenSpace.RemoveToken(cursor->fToken);
|
||||||
|
//
|
||||||
|
// return cursor;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,21 +33,27 @@ class CursorManager : public BLocker {
|
|||||||
CursorManager();
|
CursorManager();
|
||||||
virtual ~CursorManager();
|
virtual ~CursorManager();
|
||||||
|
|
||||||
|
ServerCursor* CreateCursor(team_id clientTeam,
|
||||||
|
const uint8* cursorData);
|
||||||
|
|
||||||
int32 AddCursor(ServerCursor* cursor, int32 token = -1);
|
int32 AddCursor(ServerCursor* cursor, int32 token = -1);
|
||||||
void DeleteCursors(team_id team);
|
void DeleteCursors(team_id team);
|
||||||
|
|
||||||
void ReleaseCursor(ServerCursor* cursor);
|
void RemoveCursor(ServerCursor* cursor);
|
||||||
|
|
||||||
void SetCursorSet(const char* path);
|
void SetCursorSet(const char* path);
|
||||||
ServerCursor* GetCursor(cursor_which which);
|
ServerCursor* GetCursor(cursor_which which);
|
||||||
cursor_which GetCursorWhich();
|
cursor_which GetCursorWhich();
|
||||||
void ChangeCursor(cursor_which which, int32 token);
|
void ChangeCursor(cursor_which which, int32 token);
|
||||||
void SetDefaults();
|
void SetDefaults();
|
||||||
|
|
||||||
ServerCursor* FindCursor(int32 token);
|
ServerCursor* FindCursor(int32 token);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ServerCursor* _FindCursor(team_id cientTeam,
|
||||||
|
const uint8* cursorData);
|
||||||
void _RemoveCursor(ServerCursor* cursor);
|
void _RemoveCursor(ServerCursor* cursor);
|
||||||
ServerCursor* _RemoveCursor(int32 index);
|
// ServerCursor* _RemoveCursor(int32 index);
|
||||||
|
|
||||||
BList fCursorList;
|
BList fCursorList;
|
||||||
BTokenSpace fTokenSpace;
|
BTokenSpace fTokenSpace;
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ CursorSet::AddCursor(cursor_which which, const BBitmap *cursor, const BPoint &ho
|
|||||||
function must convert the R5 cursor data into a BBitmap
|
function must convert the R5 cursor data into a BBitmap
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
CursorSet::AddCursor(cursor_which which, int8 *data)
|
CursorSet::AddCursor(cursor_which which, uint8 *data)
|
||||||
{
|
{
|
||||||
// Convert cursor data to a bitmap because all cursors are internally stored
|
// Convert cursor data to a bitmap because all cursors are internally stored
|
||||||
// as bitmaps
|
// as bitmaps
|
||||||
@@ -316,7 +316,7 @@ CursorSet::_CursorWhichToString(cursor_which which)
|
|||||||
BBitmaps returned by this function are always in the RGBA32 color space
|
BBitmaps returned by this function are always in the RGBA32 color space
|
||||||
*/
|
*/
|
||||||
BBitmap *
|
BBitmap *
|
||||||
CursorSet::_CursorDataToBitmap(int8 *data)
|
CursorSet::_CursorDataToBitmap(uint8 *data)
|
||||||
{
|
{
|
||||||
// 68-byte array used in R5 for holding cursors.
|
// 68-byte array used in R5 for holding cursors.
|
||||||
// This API has serious problems and should be deprecated(but supported) in R2
|
// This API has serious problems and should be deprecated(but supported) in R2
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ Desktop::SetCursor(ServerCursor* newCursor)
|
|||||||
HWInterface()->SetCursor(newCursor);
|
HWInterface()->SetCursor(newCursor);
|
||||||
|
|
||||||
if (oldCursor != NULL)
|
if (oldCursor != NULL)
|
||||||
fCursorManager.ReleaseCursor(oldCursor);
|
oldCursor->Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -925,19 +925,33 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// 2) port_id reply port
|
// 2) port_id reply port
|
||||||
|
|
||||||
status_t status = B_ERROR;
|
status_t status = B_ERROR;
|
||||||
int8 cursorData[68];
|
uint8 cursorData[68];
|
||||||
ServerCursor* cursor = NULL;
|
ServerCursor* cursor = NULL;
|
||||||
|
|
||||||
|
// if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) {
|
||||||
|
// cursor = new (nothrow) ServerCursor(cursorData);
|
||||||
|
// if (cursor == NULL)
|
||||||
|
// status = B_NO_MEMORY;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (cursor != NULL) {
|
||||||
|
// cursor->SetOwningTeam(fClientTeam);
|
||||||
|
// fDesktop->GetCursorManager().AddCursor(cursor);
|
||||||
|
//
|
||||||
|
// // Synchronous message - BApplication is waiting on the cursor's ID
|
||||||
|
// fLink.StartMessage(B_OK);
|
||||||
|
// fLink.Attach<int32>(cursor->Token());
|
||||||
|
// } else
|
||||||
|
// fLink.StartMessage(status);
|
||||||
|
|
||||||
if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) {
|
if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) {
|
||||||
cursor = new (nothrow) ServerCursor(cursorData);
|
cursor = fDesktop->GetCursorManager().CreateCursor(fClientTeam,
|
||||||
|
cursorData);
|
||||||
if (cursor == NULL)
|
if (cursor == NULL)
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor != NULL) {
|
if (cursor != NULL) {
|
||||||
cursor->SetOwningTeam(fClientTeam);
|
|
||||||
fDesktop->GetCursorManager().AddCursor(cursor);
|
|
||||||
|
|
||||||
// Synchronous message - BApplication is waiting on the cursor's ID
|
// Synchronous message - BApplication is waiting on the cursor's ID
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach<int32>(cursor->Token());
|
fLink.Attach<int32>(cursor->Token());
|
||||||
@@ -952,14 +966,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
|
STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
|
||||||
// Attached data:
|
// Attached data:
|
||||||
// 1) int32 token ID of the cursor to delete
|
// 1) int32 token ID of the cursor to delete
|
||||||
int32 token = B_NULL_TOKEN;
|
int32 token;
|
||||||
|
bool pendingViewCursor;
|
||||||
link.Read<int32>(&token);
|
link.Read<int32>(&token);
|
||||||
|
if (link.Read<bool>(&pendingViewCursor) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
if (fAppCursor && fAppCursor->Token() == token)
|
if (fAppCursor && fAppCursor->Token() == token)
|
||||||
fAppCursor = NULL;
|
fAppCursor = NULL;
|
||||||
|
|
||||||
if (ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token))
|
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||||
fDesktop->GetCursorManager().ReleaseCursor(cursor);
|
if (cursor) {
|
||||||
|
if (pendingViewCursor)
|
||||||
|
cursor->SetPendingViewCursor(true);
|
||||||
|
|
||||||
|
cursor->Release();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,12 @@
|
|||||||
|
|
||||||
#include "ServerCursor.h"
|
#include "ServerCursor.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "CursorManager.h"
|
||||||
|
|
||||||
|
using std::nothrow;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Constructor
|
\brief Constructor
|
||||||
@@ -36,7 +40,10 @@ ServerCursor::ServerCursor(BRect r, color_space format,
|
|||||||
: ServerBitmap(r, format, flags, bytesPerRow, screen),
|
: ServerBitmap(r, format, flags, bytesPerRow, screen),
|
||||||
fHotSpot(hotspot),
|
fHotSpot(hotspot),
|
||||||
fOwningTeam(-1),
|
fOwningTeam(-1),
|
||||||
fReferenceCount(1)
|
fReferenceCount(1),
|
||||||
|
fCursorData(NULL),
|
||||||
|
fManager(NULL),
|
||||||
|
fPendingViewCursor(0)
|
||||||
{
|
{
|
||||||
fHotSpot.ConstrainTo(Bounds());
|
fHotSpot.ConstrainTo(Bounds());
|
||||||
_AllocateBuffer();
|
_AllocateBuffer();
|
||||||
@@ -47,11 +54,14 @@ ServerCursor::ServerCursor(BRect r, color_space format,
|
|||||||
\brief Constructor
|
\brief Constructor
|
||||||
\param data Pointer to 68-byte cursor data array. See BeBook entry for BCursor for details
|
\param data Pointer to 68-byte cursor data array. See BeBook entry for BCursor for details
|
||||||
*/
|
*/
|
||||||
ServerCursor::ServerCursor(const int8* data)
|
ServerCursor::ServerCursor(const uint8* data)
|
||||||
: ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0),
|
: ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0),
|
||||||
fHotSpot(0, 0),
|
fHotSpot(0, 0),
|
||||||
fOwningTeam(-1),
|
fOwningTeam(-1),
|
||||||
fReferenceCount(1)
|
fReferenceCount(1),
|
||||||
|
fCursorData(NULL),
|
||||||
|
fManager(NULL),
|
||||||
|
fPendingViewCursor(0)
|
||||||
{
|
{
|
||||||
// 68-byte array used in R5 for holding cursors.
|
// 68-byte array used in R5 for holding cursors.
|
||||||
// This API has serious problems and should be deprecated(but supported) in R2
|
// This API has serious problems and should be deprecated(but supported) in R2
|
||||||
@@ -99,6 +109,10 @@ ServerCursor::ServerCursor(const int8* data)
|
|||||||
bmppos[i] = ((cursorval != 0) ? black : white) &
|
bmppos[i] = ((cursorval != 0) ? black : white) &
|
||||||
((maskval > 0) ? 0xFFFFFFFF : 0x00FFFFFF);
|
((maskval > 0) ? 0xFFFFFFFF : 0x00FFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fCursorData = new (nothrow) uint8[68];
|
||||||
|
if (fCursorData)
|
||||||
|
memcpy(fCursorData, data, 68);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fWidth = 0;
|
fWidth = 0;
|
||||||
@@ -119,7 +133,10 @@ ServerCursor::ServerCursor(const uint8* alreadyPaddedData,
|
|||||||
: ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0),
|
: ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0),
|
||||||
fHotSpot(0, 0),
|
fHotSpot(0, 0),
|
||||||
fOwningTeam(-1),
|
fOwningTeam(-1),
|
||||||
fReferenceCount(1)
|
fReferenceCount(1),
|
||||||
|
fCursorData(NULL),
|
||||||
|
fManager(NULL),
|
||||||
|
fPendingViewCursor(0)
|
||||||
{
|
{
|
||||||
_AllocateBuffer();
|
_AllocateBuffer();
|
||||||
if (Bits())
|
if (Bits())
|
||||||
@@ -135,7 +152,10 @@ ServerCursor::ServerCursor(const ServerCursor* cursor)
|
|||||||
: ServerBitmap(cursor),
|
: ServerBitmap(cursor),
|
||||||
fHotSpot(0, 0),
|
fHotSpot(0, 0),
|
||||||
fOwningTeam(-1),
|
fOwningTeam(-1),
|
||||||
fReferenceCount(1)
|
fReferenceCount(1),
|
||||||
|
fCursorData(NULL),
|
||||||
|
fManager(NULL),
|
||||||
|
fPendingViewCursor(0)
|
||||||
{
|
{
|
||||||
// TODO: Hm. I don't move this into the if clause,
|
// TODO: Hm. I don't move this into the if clause,
|
||||||
// because it might break code elsewhere.
|
// because it might break code elsewhere.
|
||||||
@@ -146,6 +166,11 @@ ServerCursor::ServerCursor(const ServerCursor* cursor)
|
|||||||
if (Bits() && cursor->Bits())
|
if (Bits() && cursor->Bits())
|
||||||
memcpy(Bits(), cursor->Bits(), BitsLength());
|
memcpy(Bits(), cursor->Bits(), BitsLength());
|
||||||
fHotSpot = cursor->fHotSpot;
|
fHotSpot = cursor->fHotSpot;
|
||||||
|
if (cursor->fCursorData) {
|
||||||
|
fCursorData = new (nothrow) uint8[68];
|
||||||
|
if (fCursorData)
|
||||||
|
memcpy(fCursorData, cursor->fCursorData, 68);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,3 +193,37 @@ ServerCursor::SetHotSpot(BPoint hotSpot)
|
|||||||
fHotSpot.ConstrainTo(Bounds());
|
fHotSpot.ConstrainTo(Bounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
ServerCursor::Release()
|
||||||
|
{
|
||||||
|
if (atomic_add(&fReferenceCount, -1) == 1) {
|
||||||
|
if (fPendingViewCursor > 0) {
|
||||||
|
// There is a SetViewCursor() waiting to be carried out
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fManager) {
|
||||||
|
fManager->RemoveCursor(this);
|
||||||
|
}
|
||||||
|
delete this;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerCursor::SetPendingViewCursor(bool pending)
|
||||||
|
{
|
||||||
|
atomic_add(&fPendingViewCursor, pending ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerCursor::AttachedToManager(CursorManager* manager)
|
||||||
|
{
|
||||||
|
fManager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -162,8 +162,6 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
|||||||
fClientReplyPort(clientPort),
|
fClientReplyPort(clientPort),
|
||||||
fClientLooperPort(looperPort),
|
fClientLooperPort(looperPort),
|
||||||
|
|
||||||
fClientViewsWithInvalidCoords(B_VIEW_RESIZED),
|
|
||||||
|
|
||||||
fClientToken(clientToken),
|
fClientToken(clientToken),
|
||||||
|
|
||||||
fCurrentLayer(NULL),
|
fCurrentLayer(NULL),
|
||||||
@@ -1242,13 +1240,21 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
|||||||
{
|
{
|
||||||
DTRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: ViewLayer: %s - NOT IMPLEMENTED\n", Title(), fCurrentLayer->Name()));
|
DTRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: ViewLayer: %s - NOT IMPLEMENTED\n", Title(), fCurrentLayer->Name()));
|
||||||
int32 token;
|
int32 token;
|
||||||
if (link.Read<int32>(&token) == B_OK) {
|
if (link.Read<int32>(&token) != B_OK)
|
||||||
// TODO: this badly needs reference counting
|
break;
|
||||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
|
||||||
fCurrentLayer->SetCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: if fCurrentLayer is the view under the cursor, the appearance should change immediately!
|
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||||
|
fCurrentLayer->SetCursor(cursor);
|
||||||
|
|
||||||
|
if (fWindowLayer->IsFocus()) {
|
||||||
|
// The cursor might need to be updated now
|
||||||
|
fDesktop->UnlockSingleWindow();
|
||||||
|
|
||||||
|
if (fDesktop->EventDispatcher().ViewUnderMouse(fEventTarget) == fCurrentLayer->Token())
|
||||||
|
fDesktop->SetCursor(cursor);
|
||||||
|
|
||||||
|
fDesktop->LockSingleWindow();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_LAYER_SET_FLAGS:
|
case AS_LAYER_SET_FLAGS:
|
||||||
@@ -1263,14 +1269,12 @@ ServerWindow::_DispatchViewMessage(int32 code,
|
|||||||
case AS_LAYER_HIDE:
|
case AS_LAYER_HIDE:
|
||||||
{
|
{
|
||||||
STRACE(("ServerWindow %s: Message AS_LAYER_HIDE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
STRACE(("ServerWindow %s: Message AS_LAYER_HIDE: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||||
// TODO: test
|
|
||||||
fCurrentLayer->SetHidden(true);
|
fCurrentLayer->SetHidden(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_LAYER_SHOW:
|
case AS_LAYER_SHOW:
|
||||||
{
|
{
|
||||||
STRACE(("ServerWindow %s: Message AS_LAYER_SHOW: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
STRACE(("ServerWindow %s: Message AS_LAYER_SHOW: ViewLayer: %s\n", Title(), fCurrentLayer->Name()));
|
||||||
// TODO: test
|
|
||||||
fCurrentLayer->SetHidden(false);
|
fCurrentLayer->SetHidden(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include "DrawingEngine.h"
|
#include "DrawingEngine.h"
|
||||||
#include "ServerApp.h"
|
#include "ServerApp.h"
|
||||||
#include "ServerBitmap.h"
|
#include "ServerBitmap.h"
|
||||||
|
#include "ServerCursor.h"
|
||||||
#include "ServerPicture.h"
|
#include "ServerPicture.h"
|
||||||
#include "ServerWindow.h"
|
#include "ServerWindow.h"
|
||||||
#include "WindowLayer.h"
|
#include "WindowLayer.h"
|
||||||
@@ -95,6 +96,9 @@ ViewLayer::~ViewLayer()
|
|||||||
//
|
//
|
||||||
// TODO: Don't know yet if we should also delete fPicture
|
// TODO: Don't know yet if we should also delete fPicture
|
||||||
|
|
||||||
|
if (fCursor)
|
||||||
|
fCursor->Release();
|
||||||
|
|
||||||
// iterate over children and delete each one
|
// iterate over children and delete each one
|
||||||
ViewLayer* layer = fFirstChild;
|
ViewLayer* layer = fFirstChild;
|
||||||
while (layer) {
|
while (layer) {
|
||||||
@@ -890,7 +894,17 @@ ViewLayer::SetEventMask(uint32 eventMask, uint32 options)
|
|||||||
void
|
void
|
||||||
ViewLayer::SetCursor(ServerCursor *cursor)
|
ViewLayer::SetCursor(ServerCursor *cursor)
|
||||||
{
|
{
|
||||||
fCursor = cursor;
|
if (cursor != fCursor) {
|
||||||
|
if (fCursor)
|
||||||
|
fCursor->Release();
|
||||||
|
|
||||||
|
fCursor = cursor;
|
||||||
|
|
||||||
|
if (fCursor) {
|
||||||
|
fCursor->Acquire();
|
||||||
|
fCursor->SetPendingViewCursor(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user