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:
parent
4dc6088201
commit
2a2d0f1d10
@ -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 -
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user