app_server: Implement screen changed hooks and notifications.

The ScreenOwner interface gets an additional ScreenChanged() hook. It
is implemented in the Desktop class to automatically set the preferred
screen mode on the changed screen.

The HWInterfaceListener, previously only used by the downstream
DrawingEngine, gets an additional ScreenChanged() hook as well to inform
an upstream client of a changed screen.

The ScreenManager ties these two mechanisms together.
This commit is contained in:
Michael Lotz 2017-11-21 20:59:27 +01:00
parent 5ed41cffff
commit f3e8ed4d48
6 changed files with 94 additions and 5 deletions

View File

@ -3493,6 +3493,19 @@ Desktop::_ResumeDirectFrameBufferAccess()
}
void
Desktop::ScreenChanged(Screen* screen)
{
AutoWriteLocker windowLocker(fWindowLock);
AutoWriteLocker screenLocker(fScreenLock);
screen->SetPreferredMode();
screenLocker.Unlock();
_ScreenChanged(screen);
}
void
Desktop::_ScreenChanged(Screen* screen)
{

View File

@ -145,6 +145,7 @@ public:
// ScreenOwner implementation
virtual void ScreenRemoved(Screen* screen) {}
virtual void ScreenAdded(Screen* screen) {}
virtual void ScreenChanged(Screen* screen);
virtual bool ReleaseScreen(Screen* screen) { return false; }
// Workspace methods

View File

@ -37,6 +37,35 @@ using std::nothrow;
ScreenManager* gScreenManager;
class ScreenChangeListener : public HWInterfaceListener {
public:
ScreenChangeListener(ScreenManager& manager,
Screen* screen);
private:
virtual void ScreenChanged(HWInterface* interface);
ScreenManager& fManager;
Screen* fScreen;
};
ScreenChangeListener::ScreenChangeListener(ScreenManager& manager,
Screen* screen)
:
fManager(manager),
fScreen(screen)
{
}
void
ScreenChangeListener::ScreenChanged(HWInterface* interface)
{
fManager.ScreenChanged(fScreen);
}
ScreenManager::ScreenManager()
:
BLooper("screen manager"),
@ -58,6 +87,7 @@ ScreenManager::~ScreenManager()
screen_item* item = fScreenList.ItemAt(i);
delete item->screen;
delete item->listener;
delete item;
}
}
@ -151,6 +181,19 @@ ScreenManager::ReleaseScreens(ScreenList& list)
}
void
ScreenManager::ScreenChanged(Screen* screen)
{
BAutolock locker(this);
for (int32 i = 0; i < fScreenList.CountItems(); i++) {
screen_item* item = fScreenList.ItemAt(i);
if (item->screen == screen)
item->owner->ScreenChanged(screen);
}
}
void
ScreenManager::_ScanDrivers()
{
@ -193,12 +236,20 @@ ScreenManager::_AddHWInterface(HWInterface* interface)
if (screen->Initialize() >= B_OK) {
screen_item* item = new(nothrow) screen_item;
if (item != NULL) {
item->screen = screen;
item->owner = NULL;
if (fScreenList.AddItem(item))
return item;
item->listener = new(nothrow) ScreenChangeListener(*this, screen);
if (item->listener != NULL
&& interface->AddListener(item->listener)) {
if (fScreenList.AddItem(item))
return item;
interface->RemoveListener(item->listener);
}
delete item->listener;
delete item;
}
}

View File

@ -12,10 +12,12 @@
#include <Looper.h>
#include <ObjectList.h>
class BMessage;
class DrawingEngine;
class HWInterface;
class HWInterfaceListener;
class Screen;
@ -27,6 +29,7 @@ class ScreenOwner {
virtual ~ScreenOwner() {};
virtual void ScreenRemoved(Screen* screen) = 0;
virtual void ScreenAdded(Screen* screen) = 0;
virtual void ScreenChanged(Screen* screen) = 0;
virtual bool ReleaseScreen(Screen* screen) = 0;
};
@ -45,12 +48,15 @@ class ScreenManager : public BLooper {
ScreenList& list);
void ReleaseScreens(ScreenList& list);
void ScreenChanged(Screen* screen);
virtual void MessageReceived(BMessage* message);
private:
struct screen_item {
Screen* screen;
ScreenOwner* owner;
Screen* screen;
ScreenOwner* owner;
HWInterfaceListener* listener;
};
void _ScanDrivers();

View File

@ -1096,6 +1096,19 @@ HWInterface::_NotifyFrameBufferChanged()
}
void
HWInterface::_NotifyScreenChanged()
{
BList listeners(fListeners);
int32 count = listeners.CountItems();
for (int32 i = 0; i < count; i++) {
HWInterfaceListener* listener
= (HWInterfaceListener*)listeners.ItemAtFast(i);
listener->ScreenChanged(this);
}
}
/*static*/ bool
HWInterface::_IsValidMode(const display_mode& mode)
{

View File

@ -44,7 +44,11 @@ public:
HWInterfaceListener();
virtual ~HWInterfaceListener();
virtual void FrameBufferChanged() = 0;
virtual void FrameBufferChanged() {};
// Informs a downstream DrawingEngine of a changed framebuffer.
virtual void ScreenChanged(HWInterface* interface) {};
// Informs an upstream client of a changed screen configuration.
};
@ -207,6 +211,7 @@ protected:
const BPoint& offset);
void _NotifyFrameBufferChanged();
void _NotifyScreenChanged();
static bool _IsValidMode(const display_mode& mode);