Work in progress towards cleaning up the directwindow server code:
Renamed direct_window_data to DirectWindowData and turned it into a class. Encapsulated some functionality inside the DirectWindowData class. No functional change (yet). More to come. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32374 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
* DarkWyrm <[email protected]>
|
* DarkWyrm <[email protected]>
|
||||||
* Adrian Oanca <[email protected]>
|
* Adrian Oanca <[email protected]>
|
||||||
* Stephan Aßmus <[email protected]>
|
* Stephan Aßmus <[email protected]>
|
||||||
* Stefano Ceccherini ([email protected])
|
* Stefano Ceccherini <[email protected]>
|
||||||
* Axel Dörfler, [email protected]
|
* Axel Dörfler, [email protected]
|
||||||
* Artur Wyszynski <[email protected]>
|
* Artur Wyszynski <[email protected]>
|
||||||
* Philippe Saint-Pierre, [email protected]
|
* Philippe Saint-Pierre, [email protected]
|
||||||
@@ -120,63 +120,125 @@ static profile sRedrawProcessingTime;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct direct_window_data {
|
class DirectWindowData {
|
||||||
direct_window_data();
|
public:
|
||||||
~direct_window_data();
|
DirectWindowData();
|
||||||
|
~DirectWindowData();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
sem_id sem;
|
status_t GetSyncData(direct_window_sync_data &data) const;
|
||||||
sem_id sem_ack;
|
status_t SyncronizeWithClient();
|
||||||
area_id area;
|
|
||||||
|
bool SetState(const direct_buffer_state &bufferState,
|
||||||
|
const direct_driver_state &driverState);
|
||||||
|
|
||||||
BRect old_window_frame;
|
BRect old_window_frame;
|
||||||
direct_buffer_info *buffer_info;
|
direct_buffer_info *buffer_info;
|
||||||
bool started;
|
bool started;
|
||||||
|
|
||||||
|
private:
|
||||||
|
sem_id fSem;
|
||||||
|
sem_id fAcknowledgeSem;
|
||||||
|
area_id fBufferArea;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
direct_window_data::direct_window_data()
|
DirectWindowData::DirectWindowData()
|
||||||
:
|
:
|
||||||
sem(-1),
|
|
||||||
sem_ack(-1),
|
|
||||||
area(-1),
|
|
||||||
buffer_info(NULL),
|
buffer_info(NULL),
|
||||||
started(false)
|
started(false),
|
||||||
|
fSem(-1),
|
||||||
|
fAcknowledgeSem(-1),
|
||||||
|
fBufferArea(-1)
|
||||||
{
|
{
|
||||||
area = create_area("direct area", (void **)&buffer_info,
|
fBufferArea = create_area("direct area", (void **)&buffer_info,
|
||||||
B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE);
|
B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE);
|
||||||
|
|
||||||
sem = create_sem(0, "direct sem");
|
buffer_info->buffer_state = B_DIRECT_STOP;
|
||||||
sem_ack = create_sem(0, "direct sem ack");
|
fSem = create_sem(0, "direct sem");
|
||||||
|
fAcknowledgeSem = create_sem(0, "direct sem ack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
direct_window_data::~direct_window_data()
|
DirectWindowData::~DirectWindowData()
|
||||||
{
|
{
|
||||||
// this should make the client die in case it's still running
|
// this should make the client die in case it's still running
|
||||||
buffer_info->bits = NULL;
|
buffer_info->bits = NULL;
|
||||||
buffer_info->bytes_per_row = 0;
|
buffer_info->bytes_per_row = 0;
|
||||||
|
|
||||||
delete_area(area);
|
delete_area(fBufferArea);
|
||||||
delete_sem(sem);
|
delete_sem(fSem);
|
||||||
delete_sem(sem_ack);
|
delete_sem(fAcknowledgeSem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
direct_window_data::InitCheck() const
|
DirectWindowData::InitCheck() const
|
||||||
{
|
{
|
||||||
if (area < B_OK)
|
if (fBufferArea < B_OK)
|
||||||
return area;
|
return fBufferArea;
|
||||||
if (sem < B_OK)
|
if (fSem < B_OK)
|
||||||
return sem;
|
return fSem;
|
||||||
if (sem_ack < B_OK)
|
if (fAcknowledgeSem < B_OK)
|
||||||
return sem_ack;
|
return fAcknowledgeSem;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DirectWindowData::GetSyncData(direct_window_sync_data &data) const
|
||||||
|
{
|
||||||
|
data.area = fBufferArea;
|
||||||
|
data.disable_sem = fSem;
|
||||||
|
data.disable_sem_ack = fAcknowledgeSem;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DirectWindowData::SyncronizeWithClient()
|
||||||
|
{
|
||||||
|
// Releasing this semaphore causes the client to call
|
||||||
|
// BDirectWindow::DirectConnected()
|
||||||
|
status_t status = release_sem(fSem);
|
||||||
|
if (status < B_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
// Wait with a timeout of half a second until the client exits
|
||||||
|
// from its DirectConnected() implementation
|
||||||
|
do {
|
||||||
|
status = acquire_sem_etc(fAcknowledgeSem, 1, B_TIMEOUT, 500000);
|
||||||
|
} while (status == B_INTERRUPTED);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DirectWindowData::SetState(const direct_buffer_state &bufferState,
|
||||||
|
const direct_driver_state &driverState)
|
||||||
|
{
|
||||||
|
// 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)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bufferState != -1)
|
||||||
|
buffer_info->buffer_state = bufferState;
|
||||||
|
if (driverState != -1)
|
||||||
|
buffer_info->driver_state = driverState;
|
||||||
|
|
||||||
|
started = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -1118,11 +1180,8 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
|||||||
|
|
||||||
fLink.StartMessage(status);
|
fLink.StartMessage(status);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
struct direct_window_sync_data syncData = {
|
struct direct_window_sync_data syncData;
|
||||||
fDirectWindowData->area,
|
fDirectWindowData->GetSyncData(syncData);
|
||||||
fDirectWindowData->sem,
|
|
||||||
fDirectWindowData->sem_ack
|
|
||||||
};
|
|
||||||
|
|
||||||
fLink.Attach(&syncData, sizeof(syncData));
|
fLink.Attach(&syncData, sizeof(syncData));
|
||||||
}
|
}
|
||||||
@@ -3483,7 +3542,7 @@ ServerWindow::_EnableDirectWindowMode()
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fDirectWindowData = new (nothrow) direct_window_data;
|
fDirectWindowData = new (nothrow) DirectWindowData;
|
||||||
if (fDirectWindowData == NULL)
|
if (fDirectWindowData == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -3510,26 +3569,9 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
|
|||||||
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START))
|
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't issue a DirectConnected() notification
|
if (!fDirectWindowData->SetState((direct_buffer_state)bufferState,
|
||||||
// if the connection is stopped, and we are called
|
(direct_driver_state)driverState))
|
||||||
// with bufferState == B_DIRECT_MODIFY.
|
|
||||||
if ((fDirectWindowData->buffer_info->buffer_state & B_DIRECT_MODE_MASK)
|
|
||||||
== B_DIRECT_STOP
|
|
||||||
&& (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
fDirectWindowData->started = true;
|
|
||||||
|
|
||||||
if (bufferState != -1) {
|
|
||||||
fDirectWindowData->buffer_info->buffer_state
|
|
||||||
= (direct_buffer_state)bufferState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (driverState != -1) {
|
|
||||||
fDirectWindowData->buffer_info->driver_state
|
|
||||||
= (direct_driver_state)driverState;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) {
|
if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) {
|
||||||
// TODO: Locking ?
|
// TODO: Locking ?
|
||||||
@@ -3591,20 +3633,7 @@ ServerWindow::HandleDirectConnection(int32 bufferState, int32 driverState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Releasing this semaphore causes the client to call
|
status_t status = fDirectWindowData->SyncronizeWithClient();
|
||||||
// BDirectWindow::DirectConnected()
|
|
||||||
release_sem(fDirectWindowData->sem);
|
|
||||||
|
|
||||||
// TODO: Waiting half a second in the ServerWindow thread is not a problem,
|
|
||||||
// but since we are called from the Desktop's thread too, very bad things
|
|
||||||
// could happen.
|
|
||||||
// Find some way to call this method only within ServerWindow's thread
|
|
||||||
// (messaging ?)
|
|
||||||
status_t status;
|
|
||||||
do {
|
|
||||||
status = acquire_sem_etc(fDirectWindowData->sem_ack, 1, B_TIMEOUT,
|
|
||||||
500000);
|
|
||||||
} while (status == B_INTERRUPTED);
|
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
// The client application didn't release the semaphore
|
// The client application didn't release the semaphore
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class Window;
|
|||||||
class Workspace;
|
class Workspace;
|
||||||
class View;
|
class View;
|
||||||
class ServerPicture;
|
class ServerPicture;
|
||||||
struct direct_window_data;
|
class DirectWindowData;
|
||||||
struct window_info;
|
struct window_info;
|
||||||
|
|
||||||
#define AS_UPDATE_DECORATOR 'asud'
|
#define AS_UPDATE_DECORATOR 'asud'
|
||||||
@@ -168,7 +168,7 @@ private:
|
|||||||
BRegion fCurrentDrawingRegion;
|
BRegion fCurrentDrawingRegion;
|
||||||
bool fCurrentDrawingRegionValid;
|
bool fCurrentDrawingRegionValid;
|
||||||
|
|
||||||
direct_window_data* fDirectWindowData;
|
DirectWindowData* fDirectWindowData;
|
||||||
window_feel fDirectWindowFeel;
|
window_feel fDirectWindowFeel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user