After a B_DIRECT_STOP notification, the app_server could trigger a

B_DIRECT_MODIFY with, for example, B_CLIPPING_MODIFIED. This was ignored,
though. Now we combine this notification with the next ones, so that
on B_DIRECT_START, the client is informed of all the things which have
changed. Chart was relying on receiving the B_CLIPPING_MODIFIED notification
to exclude some stars from being erased, in case the window went offscreen.
Anyway, the net result is that Chart doesn't crash now, and we follow
more closely the original BDirectWindow protocol. Fixed ticket #1939.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32392 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini 2009-08-14 20:38:35 +00:00
parent 4dc6088201
commit 2a2d0f1d10
2 changed files with 40 additions and 11 deletions

View File

@ -120,6 +120,24 @@ static profile sRedrawProcessingTime;
#endif
// TODO: Move to another file
struct BufferState {
BufferState(const direct_buffer_state &state)
: fState(state)
{
}
direct_buffer_state Action() const
{
return (direct_buffer_state)(fState & B_DIRECT_MODE_MASK);
}
direct_buffer_state Reason() const
{
return (direct_buffer_state)(fState & ~B_DIRECT_MODE_MASK);
}
direct_buffer_state fState;
};
class DirectWindowData {
public:
DirectWindowData();
@ -131,8 +149,8 @@ public:
status_t SyncronizeWithClient();
bool SetState(const direct_buffer_state &bufferState,
const direct_driver_state &driverState);
const direct_driver_state &driverState);
BRect old_window_frame;
direct_buffer_info *buffer_info;
@ -140,6 +158,7 @@ private:
sem_id fSem;
sem_id fAcknowledgeSem;
area_id fBufferArea;
direct_buffer_state fPreviousState;
};
@ -148,7 +167,8 @@ DirectWindowData::DirectWindowData()
buffer_info(NULL),
fSem(-1),
fAcknowledgeSem(-1),
fBufferArea(-1)
fBufferArea(-1),
fPreviousState(B_DIRECT_STOP)
{
fBufferArea = create_area("direct area", (void **)&buffer_info,
B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE);
@ -219,22 +239,31 @@ bool
DirectWindowData::SetState(const direct_buffer_state &bufferState,
const direct_driver_state &driverState)
{
BufferState inputState(bufferState);
BufferState currentState(buffer_info->buffer_state);
// Don't issue a DirectConnected() notification
// if the connection is stopped, and we are called
// with bufferState == B_DIRECT_MODIFY.
if ((buffer_info->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START)
// with bufferState == B_DIRECT_MODIFY, but save the reason
// and combine it for next time we are called with B_DIRECT_START
if (currentState.Action() == B_DIRECT_STOP
&& inputState.Action() != B_DIRECT_START) {
fPreviousState = (direct_buffer_state)(fPreviousState
| inputState.Reason());
return false;
if (bufferState != -1)
buffer_info->buffer_state = bufferState;
}
buffer_info->buffer_state = (direct_buffer_state)(bufferState
| BufferState(fPreviousState).Reason());
fPreviousState = B_DIRECT_STOP;
if (driverState != -1)
buffer_info->driver_state = driverState;
return true;
}
// #pragma mark -

View File

@ -90,7 +90,7 @@ public:
// related thread/team_id(s).
inline team_id ClientTeam() const { return fClientTeam; }
void HandleDirectConnection(int32 bufferState = -1,
void HandleDirectConnection(int32 bufferState,
int32 driverState = -1);
inline int32 ClientToken() const { return fClientToken; }