[haiku-commits] r37857 - haiku/trunk/src/servers/app

  • From: clemens.zeidler@xxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 3 Aug 2010 06:36:21 +0200 (CEST)

Author: czeidler
Date: 2010-08-03 06:36:21 +0200 (Tue, 03 Aug 2010)
New Revision: 37857
Changeset: http://dev.haiku-os.org/changeset/37857

Modified:
   haiku/trunk/src/servers/app/DecorManager.cpp
   haiku/trunk/src/servers/app/DecorManager.h
   haiku/trunk/src/servers/app/Desktop.cpp
   haiku/trunk/src/servers/app/Desktop.h
   haiku/trunk/src/servers/app/DesktopListener.cpp
   haiku/trunk/src/servers/app/DesktopListener.h
   haiku/trunk/src/servers/app/Window.cpp
   haiku/trunk/src/servers/app/Window.h
Log:
Introduce a new DecorAddOn class which provide the DecorManager with the needed 
Decorator, WindowBehaviour and DesktopListener.



Modified: haiku/trunk/src/servers/app/DecorManager.cpp
===================================================================
--- haiku/trunk/src/servers/app/DecorManager.cpp        2010-08-03 04:30:07 UTC 
(rev 37856)
+++ haiku/trunk/src/servers/app/DecorManager.cpp        2010-08-03 04:36:21 UTC 
(rev 37857)
@@ -21,87 +21,55 @@
 
 #include "AppServer.h"
 #include "DefaultDecorator.h"
+#include "DefaultWindowBehaviour.h"
 #include "Desktop.h"
 #include "DesktopSettings.h"
 #include "ServerConfig.h"
 #include "Window.h"
 
 typedef float get_version(void);
-typedef Decorator* create_decorator(DesktopSettings& desktopSettings, BRect 
rect,
-       window_look look, uint32 flags);
+typedef DecorAddOn* create_decor_addon(image_id id, const char* name);
 
 // Globals
 DecorManager gDecorManager;
 
 
-// This is a class used only by the DecorManager to track all the decorators 
in memory
-class DecorInfo {
-       public:
-                                                       DecorInfo(image_id id, 
const char* name,
-                                                               
create_decorator* allocator = NULL);
-                                                       ~DecorInfo();
+DecorAddOn::DecorAddOn(image_id id, const char* name)
+       :
+       fImageID(id),
+       fName(name)
+{
+}
 
-               status_t                        InitCheck() const;
 
-               image_id                        ID() const { return fID; }
-               const char*                     Name() const { return 
fName.String(); }
+DecorAddOn::~DecorAddOn()
+{
 
-               Decorator*                      Instantiate(Desktop* desktop, 
DrawingEngine* engine,
-                                                               BRect rect, 
const char* title,
-                                                               window_look 
look, uint32 flags);
-
-       private:
-               image_id                        fID;
-               BString                         fName;
-               create_decorator*       fAllocator;
-};
-
-
-DecorInfo::DecorInfo(image_id id, const char* name, create_decorator* 
allocator)
-       :
-       fID(id),
-       fName(name),
-       fAllocator(allocator)
-{
 }
 
 
-DecorInfo::~DecorInfo()
+status_t
+DecorAddOn::InitCheck() const
 {
-       // Do nothing. Normal programming practice would say that one should 
unload
-       // the object's associate image_id. However, there is some  funkiness 
with
-       // the R5 kernel in which addons aren't unloaded when unload_add_on() is
-       // called -- perhaps it's lazy unloading or something. In any event, it
-       // causes crashes which are *extremely* hard to track down to this.
-       
-       // Considering the usage of DecorInfo and DecorManager, we can live with
-       // this because the app_server will not the DecorManager is freed only
-       // when the app_server quits. It's not pretty, but it gets the job done.
+       return B_OK;
 }
 
 
-Decorator *
-DecorInfo::Instantiate(Desktop* desktop, DrawingEngine* engine, BRect rect,
-       const char *title, window_look look, uint32 flags)
+Decorator*
+DecorAddOn::AllocateDecorator(Desktop* desktop, DrawingEngine* engine,
+       BRect rect, const char* title, window_look look, uint32 flags)
 {
        if (!desktop->LockSingleWindow())
                return NULL;
 
        DesktopSettings settings(desktop);
-       Decorator *decorator;
-       
-       try {
-               if (fAllocator != NULL)
-                       decorator = fAllocator(settings, rect, look, flags);
-               else
-                       decorator = new DefaultDecorator(settings, rect, look, 
flags);
-       } catch (...) {
-               desktop->UnlockSingleWindow();
-               return NULL;
-       }
+       Decorator* decorator;
+       decorator = _AllocateDecorator(settings, rect, look, flags);
 
        desktop->UnlockSingleWindow();
 
+       if (!decorator)
+               return NULL;
        decorator->SetDrawingEngine(engine);
        decorator->SetTitle(title);
 
@@ -109,17 +77,38 @@
 }
 
 
+WindowBehaviour*
+DecorAddOn::AllocateWindowBehaviour(Window* window)
+{
+       return new (std::nothrow)DefaultWindowBehaviour(window);
+}
+
+
+const DesktopListenerList&
+DecorAddOn::GetDesktopListeners()
+{
+       return fDesktopListeners;
+}
+
+
+Decorator*
+DecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect,
+       window_look look, uint32 flags)
+{
+       return new (std::nothrow)DefaultDecorator(settings, rect, look, flags);
+}
+
+
 //     #pragma mark -
 
 
 DecorManager::DecorManager()
        :
-       fDecorList(0),
+       fDefaultDecorAddOn(-1, "Default"),
        fCurrentDecor(NULL)
 {
        // Start with the default decorator - index is always 0
-       DecorInfo *defaultDecor = new DecorInfo(-1, "Default", NULL);
-       fDecorList.AddItem(defaultDecor);
+       fDecorList.AddItem(&fDefaultDecorAddOn);
 
        // Add any on disk
        RescanDecorators();
@@ -127,7 +116,7 @@
        _LoadSettingsFromDisk();
 
        if (!fCurrentDecor)
-               fCurrentDecor = (DecorInfo*)fDecorList.ItemAt(0L);
+               fCurrentDecor = fDecorList.ItemAt(0L);
 }
 
 
@@ -170,18 +159,25 @@
                // to do so. If we *did* do anything with decorator versions, 
the 
                // assignment would go here.
 
-               create_decorator* createFunc;
+               create_decor_addon* createFunc;
 
                // Get the instantiation function
-               status_t status = get_image_symbol(image, 
"instantiate_decorator",
+               status_t status = get_image_symbol(image, 
"instantiate_decor_addon",
                                                                
B_SYMBOL_TYPE_TEXT, (void**)&createFunc);
                if (status != B_OK) {
                        unload_add_on(image);
                        continue;
                }
 
+               DecorAddOn* addon = createFunc(image, ref.name);
+
                // TODO: unload images until they are actually used!
-               fDecorList.AddItem(new DecorInfo(image, ref.name, createFunc));
+               if (!addon || addon->InitCheck() != B_OK
+                       || !fDecorList.AddItem(addon)) {
+                       unload_add_on(image);
+                       delete addon;
+                       continue;
+               }
        }
 }
 
@@ -199,11 +195,31 @@
                return NULL;
        }
 
-       return fCurrentDecor->Instantiate(desktop, engine, rect, title,
+       return fCurrentDecor->AllocateDecorator(desktop, engine, rect, title,
                look, flags);
 }
 
 
+WindowBehaviour*
+DecorManager::AllocateWindowBehaviour(Window* window)
+{
+       if (!fCurrentDecor) {
+               // We should *never* be here. If we do, it's a bug.
+               debugger("DecorManager::AllocateDecorator has a NULL 
decorator");
+               return NULL;
+       }
+
+       return fCurrentDecor->AllocateWindowBehaviour(window);
+}
+
+
+const DesktopListenerList&
+DecorManager::GetDesktopListeners()
+{
+       return fCurrentDecor->GetDesktopListeners();
+}
+
+
 int32
 DecorManager::CountDecorators() const
 {
@@ -221,11 +237,11 @@
 bool
 DecorManager::SetDecorator(int32 index, Desktop* desktop)
 {
-       DecorInfo* newDecInfo = (DecorInfo*)fDecorList.ItemAt(index);
+       DecorAddOn* newDecor = fDecorList.ItemAt(index);
 
-       if (newDecInfo) {
-               fCurrentDecor = newDecInfo;
-               desktop->ReloadAllDecorators();
+       if (newDecor) {
+               fCurrentDecor = newDecor;
+               desktop->ReloadDecor();
                _SaveSettingsToDisk();
                return true;
        }
@@ -248,9 +264,9 @@
                        return false;
        }
 
-       DecorInfo *newDecInfo = _FindDecor(string.String());
-       if (newDecInfo) {
-               fCurrentDecor = newDecInfo;
+       DecorAddOn *newDecor = _FindDecor(string);
+       if (newDecor) {
+               fCurrentDecor = newDecor;
                return true;
        }
 
@@ -258,40 +274,43 @@
 }
 
 
-const char *
+BString
 DecorManager::GetDecoratorName(int32 index)
 {
-       DecorInfo *info = fDecorList.ItemAt(index);
-       if (info)
-               return info->Name();
+       DecorAddOn *decor = fDecorList.ItemAt(index);
+       if (decor)
+               return decor->Name();
 
-       return NULL;
+       return BString("");
 }
 
 
 void
 DecorManager::_EmptyList()
 {
-       for (int32 i = 0; i < fDecorList.CountItems(); i++) {
-               delete fDecorList.ItemAt(i);;
+       for (int32 i = 1; i < fDecorList.CountItems(); i++) {
+               unload_add_on(fDecorList.ItemAt(i)->ImageID());
+               delete fDecorList.ItemAt(i);
        }
 
        fDecorList.MakeEmpty();
-       fCurrentDecor = NULL;
+       fDecorList.AddItem(&fDefaultDecorAddOn);
+
+       fCurrentDecor = &fDefaultDecorAddOn;
 }
 
 
-DecorInfo*
-DecorManager::_FindDecor(const char *name)
+DecorAddOn*
+DecorManager::_FindDecor(BString name)
 {
        if (!name)
                return NULL;
 
        for (int32 i = 0; i < fDecorList.CountItems(); i++) {
-               DecorInfo* info = fDecorList.ItemAt(i);
+               DecorAddOn* decor = fDecorList.ItemAt(i);
 
-               if (strcmp(name, info->Name()) == 0)
-                       return info;
+               if (decor->Name() == name)
+                       return decor;
        }
 
        return NULL;
@@ -321,7 +340,7 @@
        if (settings.Unflatten(&file) == B_OK) {
                BString itemtext;
                if (settings.FindString("decorator", &itemtext) == B_OK) {
-                       DecorInfo* decor = _FindDecor(itemtext.String());
+                       DecorAddOn* decor = _FindDecor(itemtext);
                        if (decor) {
                                fCurrentDecor = decor;
                                return true;

Modified: haiku/trunk/src/servers/app/DecorManager.h
===================================================================
--- haiku/trunk/src/servers/app/DecorManager.h  2010-08-03 04:30:07 UTC (rev 
37856)
+++ haiku/trunk/src/servers/app/DecorManager.h  2010-08-03 04:36:21 UTC (rev 
37857)
@@ -20,9 +20,48 @@
 
 class DecorInfo;
 class Desktop;
+class DesktopListener;
 class DrawingEngine;
+class Window;
+class WindowBehaviour;
 
 
+typedef BObjectList<DesktopListener> DesktopListenerList;
+
+
+class DecorAddOn
+{
+public:
+                                                               
DecorAddOn(image_id id, const char* name);
+       virtual                                         ~DecorAddOn();
+
+       virtual status_t                        InitCheck() const;
+
+               image_id                                ImageID() const { 
return fImageID; }
+               BString                                 Name() const { return 
fName; }
+
+               Decorator*                              
AllocateDecorator(Desktop* desktop,
+                                                                       
DrawingEngine* engine, BRect rect,
+                                                                       const 
char* title, window_look look,
+                                                                       uint32 
flags);
+
+       virtual float                           Version() { return 1.0; }
+       virtual WindowBehaviour*        AllocateWindowBehaviour(Window* window);
+
+       virtual const DesktopListenerList&      GetDesktopListeners();
+
+protected:
+       virtual Decorator*                      
_AllocateDecorator(DesktopSettings& settings,
+                                                                       BRect 
rect, window_look look, uint32 flags);
+
+               DesktopListenerList             fDesktopListeners;
+
+private:
+               image_id                                fImageID;
+               BString                                 fName;
+};
+
+
 class DecorManager
 {
 public:
@@ -36,13 +75,15 @@
                                                BRect rect,
                                                const char* title, window_look 
look,
                                                uint32 flags);
+               WindowBehaviour*                        
AllocateWindowBehaviour(Window* window);
+               const DesktopListenerList&      GetDesktopListeners();
 
                int32           CountDecorators() const;
 
                int32           GetDecorator() const;
                bool            SetDecorator(int32 index, Desktop* desktop);
                bool            SetR5Decorator(int32 value);
-               const char*     GetDecoratorName(int32 index);
+               BString         GetDecoratorName(int32 index);
 
                // TODO: Implement this method once the rest of the necessary 
infrastructure
                // is in place
@@ -50,13 +91,14 @@
 
 private:
                void            _EmptyList();
-               DecorInfo*      _FindDecor(const char *name);
+               DecorAddOn*     _FindDecor(BString name);
 
                bool            _LoadSettingsFromDisk();
                bool            _SaveSettingsToDisk();
 
-               BObjectList<DecorInfo> fDecorList;
-               DecorInfo*      fCurrentDecor;
+               BObjectList<DecorAddOn> fDecorList;
+               DecorAddOn      fDefaultDecorAddOn;
+               DecorAddOn*     fCurrentDecor;
 };
 
 extern DecorManager gDecorManager;

Modified: haiku/trunk/src/servers/app/Desktop.cpp
===================================================================
--- haiku/trunk/src/servers/app/Desktop.cpp     2010-08-03 04:30:07 UTC (rev 
37856)
+++ haiku/trunk/src/servers/app/Desktop.cpp     2010-08-03 04:36:21 UTC (rev 
37857)
@@ -36,6 +36,7 @@
 #include <WindowInfo.h>
 
 #include "AppServer.h"
+#include "DecorManager.h"
 #include "DesktopSettingsPrivate.h"
 #include "DrawingEngine.h"
 #include "HWInterface.h"
@@ -1901,17 +1902,29 @@
 
 
 void
-Desktop::ReloadAllDecorators()
+Desktop::ReloadDecor()
 {
        AutoWriteLocker _(fWindowLock);
 
+       // TODO it is assumed all listeners are registered by one decor
+       // unregister old listeners
+       const DesktopListenerDLList& currentListeners = 
GetDesktopListenerList();
+       for (DesktopListener* listener = currentListeners.First();
+               listener != NULL; listener = currentListeners.GetNext(listener))
+               UnregisterListener(listener);
+       // register new listeners
+       const DesktopListenerList& newListeners
+               = gDecorManager.GetDesktopListeners();
+       for (int i = 0; i < newListeners.CountItems(); i++)
+               RegisterListener(newListeners.ItemAt(i));
+
        for (int32 i = 0; i < kMaxWorkspaces; i++) {
                for (Window* window = _Windows(i).LastWindow(); window;
                                window = window->PreviousWindow(i)) {
                        BRegion oldBorder;
                        window->GetBorderRegion(&oldBorder);
 
-                       window->ReloadDecorator();
+                       window->ReloadDecor();
 
                        BRegion border;
                        window->GetBorderRegion(&border);

Modified: haiku/trunk/src/servers/app/Desktop.h
===================================================================
--- haiku/trunk/src/servers/app/Desktop.h       2010-08-03 04:30:07 UTC (rev 
37856)
+++ haiku/trunk/src/servers/app/Desktop.h       2010-08-03 04:36:21 UTC (rev 
37857)
@@ -14,6 +14,14 @@
 #define DESKTOP_H
 
 
+#include <Autolock.h>
+#include <InterfaceDefs.h>
+#include <List.h>
+#include <Menu.h>
+#include <ObjectList.h>
+#include <Region.h>
+#include <Window.h>
+
 #include "CursorManager.h"
 #include "DesktopListener.h"
 #include "DesktopSettings.h"
@@ -27,16 +35,7 @@
 #include "Workspace.h"
 #include "WorkspacePrivate.h"
 
-#include <ObjectList.h>
 
-#include <Autolock.h>
-#include <InterfaceDefs.h>
-#include <List.h>
-#include <Menu.h>
-#include <Region.h>
-#include <Window.h>
-
-
 #define USE_MULTI_LOCKER 1
 
 #if USE_MULTI_LOCKER
@@ -233,7 +232,7 @@
                        void                            Redraw();
                        void                            RedrawBackground();
 
-                       void                            ReloadAllDecorators();
+                       void                            ReloadDecor();
 
                        BRegion&                        BackgroundRegion()
                                                                        { 
return fBackgroundRegion; }

Modified: haiku/trunk/src/servers/app/DesktopListener.cpp
===================================================================
--- haiku/trunk/src/servers/app/DesktopListener.cpp     2010-08-03 04:30:07 UTC 
(rev 37856)
+++ haiku/trunk/src/servers/app/DesktopListener.cpp     2010-08-03 04:36:21 UTC 
(rev 37857)
@@ -37,6 +37,13 @@
 }
 
 
+const DesktopListenerDLList&
+DesktopObservable::GetDesktopListenerList()
+{
+       return fDesktopListenerList;
+}
+
+
 #define FOR_ALL_DESKTOP_LISTENER                                               
                                        \
        for (DesktopListener* listener = fDesktopListenerList.First();          
        \
                listener != NULL; listener = 
fDesktopListenerList.GetNext(listener))

Modified: haiku/trunk/src/servers/app/DesktopListener.h
===================================================================
--- haiku/trunk/src/servers/app/DesktopListener.h       2010-08-03 04:30:07 UTC 
(rev 37856)
+++ haiku/trunk/src/servers/app/DesktopListener.h       2010-08-03 04:36:21 UTC 
(rev 37857)
@@ -55,7 +55,7 @@
 };
 
 
-typedef DoublyLinkedList<DesktopListener> DesktopListenerList;
+typedef DoublyLinkedList<DesktopListener> DesktopListenerDLList;
 
 
 class DesktopObservable
@@ -65,6 +65,7 @@
 
                void                            
RegisterListener(DesktopListener* listener);
                void                            
UnregisterListener(DesktopListener* listener);
+       const DesktopListenerDLList&    GetDesktopListenerList();
 
                void                            InvokeAddWindow(Window* window);
                void                            InvokeRemoveWindow(Window* 
window);
@@ -104,10 +105,10 @@
                                bool&   fInvoking;
                };
 
-               DesktopListenerList     fDesktopListenerList;
+               DesktopListenerDLList   fDesktopListenerList;
                
                // prevent recursive invokes
-               bool                            fWeAreInvoking;
+               bool                                    fWeAreInvoking;
 };
 
 #endif

Modified: haiku/trunk/src/servers/app/Window.cpp
===================================================================
--- haiku/trunk/src/servers/app/Window.cpp      2010-08-03 04:30:07 UTC (rev 
37856)
+++ haiku/trunk/src/servers/app/Window.cpp      2010-08-03 04:36:21 UTC (rev 
37857)
@@ -10,20 +10,18 @@
  *             Brecht Machiels <brecht@xxxxxxxxxxx>
  *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
  */
-
-
 #include "Window.h"
 
 #include "Decorator.h"
 #include "DecorManager.h"
 #include "Desktop.h"
-#include "DefaultWindowBehaviour.h"
 #include "DrawingEngine.h"
 #include "HWInterface.h"
 #include "MessagePrivate.h"
 #include "PortLink.h"
 #include "ServerApp.h"
 #include "ServerWindow.h"
+#include "WindowBehaviour.h"
 #include "Workspace.h"
 #include "WorkspacesView.h"
 
@@ -135,7 +133,7 @@
                                &fMaxWidth, &fMaxHeight);
                }
        }
-       fWindowBehaviour = new (std::nothrow)DefaultWindowBehaviour(this);
+       fWindowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
 
        // do we need to change our size to let the decorator fit?
        // _ResizeBy() will adapt the frame for validity before resizing
@@ -542,17 +540,35 @@
 }
 
 
-void
-Window::ReloadDecorator()
+bool
+Window::ReloadDecor()
 {
+       ::Decorator* decorator = NULL;
+       WindowBehaviour* windowBehaviour = NULL;
+
        if (fLook != B_NO_BORDER_WINDOW_LOOK) {
-               delete fDecorator;
                // we need a new decorator
-               fDecorator = gDecorManager.AllocateDecorator(fDesktop, 
fDrawingEngine,
+               decorator = gDecorManager.AllocateDecorator(fDesktop, 
fDrawingEngine,
                        Frame(), Title(), fLook, fFlags);
+               if (!decorator)
+                       return false;
                if (IsFocus())
-                       fDecorator->SetFocus(true);
+                       decorator->SetFocus(true);
        }
+
+       windowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
+       if (!windowBehaviour) {
+               delete decorator;
+               return false;
+       }
+
+       delete fDecorator;
+       fDecorator = decorator;
+
+       delete fWindowBehaviour;
+       fWindowBehaviour = windowBehaviour;
+
+       return true;
 }
 
 

Modified: haiku/trunk/src/servers/app/Window.h
===================================================================
--- haiku/trunk/src/servers/app/Window.h        2010-08-03 04:30:07 UTC (rev 
37856)
+++ haiku/trunk/src/servers/app/Window.h        2010-08-03 04:36:21 UTC (rev 
37857)
@@ -10,12 +10,10 @@
  *             Brecht Machiels <brecht@xxxxxxxxxxx>
  *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
  */
-
 #ifndef WINDOW_H
 #define WINDOW_H
 
 
-#include "Decorator.h"
 #include "RegionPool.h"
 #include "ServerWindow.h"
 #include "View.h"
@@ -71,7 +69,7 @@
                        ::EventTarget&          EventTarget() const
                                                                        { 
return fWindow->EventTarget(); }
 
-                       void                            ReloadDecorator();
+                       bool                            ReloadDecor();
 
                        void                            SetScreen(const 
::Screen* screen);
                        const ::Screen*         Screen() const;


Other related posts:

  • » [haiku-commits] r37857 - haiku/trunk/src/servers/app - clemens . zeidler