diff --git a/src/servers/app/server/AppServer.cpp b/src/servers/app/server/AppServer.cpp index 5f4b717933..a3287fa663 100644 --- a/src/servers/app/server/AppServer.cpp +++ b/src/servers/app/server/AppServer.cpp @@ -123,7 +123,7 @@ AppServer::AppServer(void) InitDecorators(); // Set up the Desktop - InitDesktop(); + desktop=new Desktop(); // Create the cursor manager. Object declared in CursorManager.cpp cursormanager=new CursorManager(); @@ -142,7 +142,7 @@ AppServer::AppServer(void) _decor_lock=create_sem(1,"app_server_decor_sem"); // Get the driver first - Poller thread utilizes the thing - _driver=GetGfxDriver(ActiveScreen()); + _driver=desktop->GetGfxDriver(); // Spawn our input-polling thread _poller_id=spawn_thread(PollerThread, "Poller", B_NORMAL_PRIORITY, this); @@ -183,8 +183,6 @@ AppServer::~AppServer(void) delete bitmapmanager; delete cursormanager; - ShutdownDesktop(); - // If these threads are still running, kill them - after this, if exit_poller // is deleted, who knows what will happen... These things will just return an // error and fail if the threads have already exited. @@ -194,6 +192,8 @@ AppServer::~AppServer(void) delete fontserver; make_decorator=NULL; + delete desktop; + desktop=NULL; } /*! @@ -824,7 +824,7 @@ void AppServer::HandleKeyMessage(int32 code, int8 *buffer) if(modifiers & B_CONTROL_KEY) { STRACE(("Set Workspace %ld\n",scancode-1)); - SetWorkspace(scancode-2); + desktop->SetWorkspace(scancode-2); break; } @@ -878,7 +878,7 @@ void AppServer::HandleKeyMessage(int32 code, int8 *buffer) if(modifiers & (B_LEFT_SHIFT_KEY | B_LEFT_CONTROL_KEY)) { STRACE(("Set Workspace %ld\n",scancode-1)); - SetWorkspace(scancode-2); + desktop->SetWorkspace(scancode-2); break; } } @@ -1101,6 +1101,7 @@ Decorator *new_decorator(BRect rect, const char *title, int32 wlook, int32 wfeel \param argv String array of the command-line arguments \return -1 if the app_server is already running, 0 if everything's OK. */ + int main( int argc, char** argv ) { // There can be only one.... diff --git a/src/servers/app/server/CursorManager.cpp b/src/servers/app/server/CursorManager.cpp index 0215dbb387..0b5eafc735 100644 --- a/src/servers/app/server/CursorManager.cpp +++ b/src/servers/app/server/CursorManager.cpp @@ -177,31 +177,37 @@ void CursorManager::RemoveAppCursors(const char *signature) //! Wrapper around the DisplayDriver ShowCursor call void CursorManager::ShowCursor(void) { - Lock(); + // TODO: Fix +/* Lock(); DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->ShowCursor(); Unlock(); +*/ } //! Wrapper around the DisplayDriver HideCursor call void CursorManager::HideCursor(void) { - Lock(); + // TODO: Fix +/* Lock(); DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->HideCursor(); Unlock(); +*/ } //! Wrapper around the DisplayDriver ObscureCursor call void CursorManager::ObscureCursor(void) { - Lock(); + // TODO: Fix +/* Lock(); DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->ObscureCursor(); Unlock(); +*/ } /*! @@ -210,7 +216,8 @@ void CursorManager::ObscureCursor(void) */ void CursorManager::SetCursor(int32 token) { - Lock(); + // TODO: Fix +/* Lock(); ServerCursor *c=_FindCursor(token); if(c) { @@ -219,11 +226,13 @@ void CursorManager::SetCursor(int32 token) _current_which=B_CURSOR_OTHER; } Unlock(); +*/ } void CursorManager::SetCursor(cursor_which which) { - Lock(); + // TODO: Fix +/* Lock(); DisplayDriver *driver=GetGfxDriver(ActiveScreen()); switch(which) @@ -287,6 +296,7 @@ void CursorManager::SetCursor(cursor_which which) } Unlock(); +*/ } /*! diff --git a/src/servers/app/server/Desktop.cpp b/src/servers/app/server/Desktop.cpp index b11d4d3512..ae0689b79d 100644 --- a/src/servers/app/server/Desktop.cpp +++ b/src/servers/app/server/Desktop.cpp @@ -1,819 +1,404 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Desktop.cpp -// Author: DarkWyrm -// Description: Functions used to work with workspaces and general desktop stuff -// -//------------------------------------------------------------------------------ -#include "DisplayDriver.h" #include "Desktop.h" -#include "DesktopClasses.h" + +#include +#include "RootLayer.h" +#include "ServerScreen.h" +#include "Layer.h" +#include "PortMessage.h" +#include "DisplayDriver.h" +#include "AccelerantDriver.h" +#include "ViewDriver.h" +#include "WinBorder.h" +#include "Workspace.h" +#include "Globals.h" +#include "ServerWindow.h" #include "ServerConfig.h" -#include "ViewDriver.h" -#include "ServerWindow.h" +#include +#include -#if DISPLAYDRIVER == SCREENDRIVER -#include "ScreenDriver.h" -#endif +Desktop *desktop=NULL; -#if DISPLAYDRIVER == HWDRIVER -#include "AccelerantDriver.h" -#endif - -//#define DEBUG_DESKTOP -#ifdef DEBUG_DESKTOP -# include -# define STRACE(x) printf x -#else -# define STRACE(x) ; -#endif - -bool ReadOBOSWorkspaceData(void); -bool ReadR5WorkspaceData(void); -void SaveWorkspaceData(void); - -//! This namespace encapsulates all globals specifically for the desktop -namespace desktop_private { - int8 *dragmessage=NULL; - int32 dragmessagesize=0; - BLocker draglock, - layerlock, - workspacelock, - optlock; - BList *screenlist=NULL; - Screen *activescreen=NULL; - scroll_bar_info scrollbarinfo; - menu_info menuinfo; - mode_mouse ffm_mode; - bool ffm; +Desktop::Desktop(void) +{ + fDragMessage = NULL; + fActiveRootLayer = NULL; + fFrontWinBorder = NULL; + fFocusWinBorder = NULL; + fActiveScreen = NULL; + Init(); } -//! locks layer access -void lock_layers(void) { desktop_private::layerlock.Lock(); } -//! unlocks layer access -void unlock_layers(void) { desktop_private::layerlock.Unlock(); } -//! locks access to drag and drop data -void lock_dragdata(void) { desktop_private::draglock.Lock(); } -//! unlocks access to drag and drop data -void unlock_dragdata(void) { desktop_private::draglock.Unlock(); } -//! locks access to the workspace list -void lock_workspaces(void) { desktop_private::workspacelock.Lock(); } -//! unlocks access to the workspace list -void unlock_workspaces(void) { desktop_private::workspacelock.Unlock(); } - -/*! - \brief Initializes the desktop for use. - - InitDesktop creates all workspaces, starts up the appropriate DisplayDriver, and - generally gets everything ready for the server to use. -*/ -void InitDesktop(void) +Desktop::~Desktop(void) { -STRACE(("Desktop: InitWorkspace\n")); - desktop_private::screenlist=new BList(0); - DisplayDriver *tdriver; - Screen *s=NULL; + if (fDragMessage) + delete fDragMessage; -#ifndef TEST_MODE - // If we're using the AccelerantDriver for rendering, eventually we will loop through - // drivers until one can't initialize in order to support multiple monitors. For now, - // we'll just load one and be done with it. - tdriver=new AccelerantDriver; + void *ptr; + for(int32 i=0; (ptr=fRootLayerList.ItemAt(i)); i++) + delete (RootLayer*)ptr; - if(tdriver->Initialize()) - { - s=new Screen(tdriver); - desktop_private::screenlist->AddItem(s); - } - else - { - // Uh-oh. We don't have a video card. This would be a *bad* thing. Seeing how - // we can't see anything, we can't do anything, either. It's time to crash now. ;) - tdriver->Shutdown(); - delete tdriver; - tdriver=NULL; -STRACE(("\t NULL display driver. OK. We crash now. :P\n")); - } -#else // end if not TEST_MODE + for(int32 i=0; (ptr=fScreenList.ItemAt(i)); i++) + delete (Screen*)ptr; -#if DISPLAYDRIVER == SCREENDRIVER - tdriver=new ScreenDriver; -#else - tdriver=new ViewDriver; -#endif - - if(tdriver->Initialize()) - { - s=new Screen(tdriver); - desktop_private::screenlist->AddItem(s); - } - else - { - // Uh-oh. We don't have a video card. This would be a *bad* thing. Seeing how - // we can't see anything, we can't do anything, either. It's time to crash now. ;) - tdriver->Shutdown(); - delete tdriver; - tdriver=NULL; -STRACE(("\t NULL display driver. OK. We crash now. :P\n")); - } -#endif - - // Once we utilize multiple monitors, we'll make Screen 0 the active one. - if(tdriver) - { - s->Activate(); - desktop_private::activescreen=s; - - // TODO: figure out how to load the workspace data and do it here. - // For now, we'll just use 3 workspaces. - // Initializing the workspaces has been seperated from the constructor - // since currently RootLayer can only be constructed when there is an - // active screen. - s->SetWorkspaceCount(3); -#ifdef TEST_MODE - s->SetSpace(0,B_32_BIT_640x480,true); -#endif - } + for(int32 i=0; (ptr=fWinBorderList.ItemAt(i)); i++) + delete (WinBorder*)ptr; } -//! Shuts down the graphics subsystem -void ShutdownDesktop(void) +void Desktop::Init(void) { -STRACE(("Desktop: ShutdownDesktop\n")); - Screen *s; - - for(int32 i=0;iCountItems();i++) + DisplayDriver *driver = NULL; + int32 driverCount = 0; + bool initDrivers = true; + + while(initDrivers) { - s=(Screen*)desktop_private::screenlist->ItemAt(i); - if(s) - delete s; - } - if(!desktop_private::dragmessage) - { - delete desktop_private::dragmessage; - desktop_private::dragmessage=NULL; - desktop_private::dragmessagesize=0; - } -} - -/*! - \brief Add a workspace to the desktop - \param index Place in the workspace list to add the new one. - - The default location to add a workspace is at the end of the list. If index - is less than 0 or greater than the current workspace count, AddWorkspace will place - the workspace at the list's end. Note that it is possible to insert a workspace - in the list simply by specifying an index. -*/ -void AddWorkspace(int32 index) -{ -STRACE(("Desktop: AddWorkspace(%ld)\n",index+1)); - lock_workspaces(); - lock_layers(); - - Screen *s; - - for(int32 i=0;iCountItems();i++) - { - s=(Screen*)desktop_private::screenlist->ItemAt(i); - if(s) - s->AddWorkspace(index); - } - - unlock_layers(); - unlock_workspaces(); -} - -/*! - \brief Deletes a workspace - \param index The index to delete - - If the workspace specified by index does not refer to a valid workspace, this function - will fail. Should the workspace to be deleted be the active one, the previous - workspace in the list will be chosen or workspace 0 if workspace 0 is being deleted. - This function will fail if there is only 1 workspace used. -*/ -void DeleteWorkspace(int32 index) -{ -STRACE(("Desktop: DeleteWorkspace(%ld)\n",index+1)); - lock_workspaces(); - lock_layers(); - - Screen *s; - - for(int32 i=0;iCountItems();i++) - { - s=(Screen*)desktop_private::screenlist->ItemAt(i); - if(s) - s->DeleteWorkspace(index); - } - - unlock_layers(); - unlock_workspaces(); -} - -/*! - \brief Returns the number of workspaces available - \return the number of workspaces available -*/ -int32 CountWorkspaces(void) -{ - lock_workspaces(); - lock_layers(); - - int32 count=desktop_private::activescreen->CountWorkspaces(); - - unlock_layers(); - unlock_workspaces(); - - return count; -} - -/*! - \brief Sets the number of workspaces available - \param count The new number of available workspaces - - This function will fail if count is less than 1 or greater than 32. The limit of 32 was - set by BeOS. Making the limit higher will cause unreachable workspaces because of the - API interface used to access them. Were this to change, the only limiting factor for - workspace count would be the hardware itself. - -*/ -void SetWorkspaceCount(int32 count) -{ -STRACE(("Desktop: SetWorkspaceCount(%ld)\n",count)); - if(count<1 || count>32) - return; - lock_workspaces(); - Screen *scr; - for(int32 i=0;iCountItems();i++) - { - scr=(Screen*)desktop_private::screenlist->ItemAt(i); - if(!scr) - continue; - scr->SetWorkspaceCount(count); - } - unlock_workspaces(); -} - -/*! - \brief Returns the index of the active workspace - \return the index of the active workspace or -1 if an internal error occurred. -*/ -int32 CurrentWorkspace(void) -{ - lock_workspaces(); - int32 id=-1; - - if(desktop_private::activescreen) - id=desktop_private::activescreen->CurrentWorkspace(); - unlock_workspaces(); - - return id; -} - -/*! - \brief Returns the workspace object for the active screen at the given index -*/ -Workspace *WorkspaceAt(int32 index) -{ - lock_workspaces(); - Workspace *w=NULL; - if(desktop_private::activescreen) - w=desktop_private::activescreen->GetWorkspace(index); - unlock_workspaces(); - return w; -} - -/*! - \brief Sets the active workspace - \param workspace Index of the workspace to activate - - This function will do nothing if passed an index which does not refer to a valid - workspace. -*/ -void SetWorkspace(int32 workspace) -{ -STRACE(("Desktop: SetWorkspace(%ld)\n",workspace+1)); - lock_workspaces(); - if(workspace<0 || workspace>(CountWorkspaces()-1)) - { - unlock_workspaces(); - return; - } - - Screen *scr; - for(int32 i=0;iCountItems();i++) - { - scr=(Screen*)desktop_private::screenlist->ItemAt(i); - if(!scr) - continue; - scr->SetWorkspace(workspace); - } - unlock_workspaces(); -} - -/*! - \brief Sets the active screen. Currently unused. - \param id ID of the screen to activate. -*/ -void SetScreen(screen_id id) -{ -STRACE(("Desktop: SetScreen(%ld)\n",id.id)); - Screen *scr; - for(int32 i=0;iCountItems();i++) - { - scr=(Screen*)desktop_private::screenlist->ItemAt(i); - if(!scr) - continue; - if(scr->GetID().id==id.id) + #ifdef TEST_MODE + driver = new ViewDriver(); + #else + + // If we're using the AccelerantDriver for rendering, eventually we will loop through + // drivers until one can't initialize in order to support multiple monitors. For now, + // we'll just load one and be done with it. + driver = new AccelerantDriver(); + #endif + + if(driver->Initialize()) { - desktop_private::activescreen->Activate(false); - desktop_private::activescreen=scr; - desktop_private::activescreen->Activate(true); + driverCount++; + + Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB32, driverCount); + + // TODO: be careful, it may fail to initialize! - Monitor may not support 640x480 + fScreenList.AddItem(sc); + + // TODO: remove this when you have a real Driver. + if (driverCount == 2) + initDrivers = false; + } + else + { + driver->Shutdown(); + delete driver; + driver = NULL; + initDrivers = false; } } -} -/*! - \brief Returns the number of screens available. Currently unused. - \return the number of screens available. -*/ -int32 CountScreens(void) -{ - return desktop_private::screenlist->CountItems();; -} + if (driverCount < 1) + delete this; -/*! - \brief Returns the index of the active screen. Currently unused. - \return the index of the active screen -*/ -screen_id ActiveScreen(void) -{ - return desktop_private::activescreen->GetID(); -} - -/*! - \brief Returns the active screen. - \return The currently active screen -*/ -Screen *GetActiveScreen(void) -{ - return desktop_private::activescreen; -} - -/*! - \brief Obtains the DisplayDriver object used for the specified screen. - \param screen ID of the screen to get the DisplayDriver for. - \return The DisplayDriver or NULL if not available for that screen ID + InitMode(); - Like the other multiscreen functions, this is unused. Because multiple screens are - not utilized, specifying an ID other than B_MAIN_SCREEN_ID will return NULL -*/ -DisplayDriver *GetGfxDriver(screen_id screen) -{ - return (desktop_private::activescreen)?desktop_private::activescreen->GetGfxDriver():NULL; + SetActiveRootLayerByIndex(0); } -/*! - \brief Sets the video parameters of the specified workspace - \param index The workspace to change - \param res Resolution constant from GraphicsDefs.h - \param stick If false, resolution will revert to its old value on next boot - \param screen ID of the screen to change. Currently unused. - \return B_OK if successful, B_ERROR if not. - - Because of the lack of outside multimonitor support, the screen ID is ignored for now. -*/ -status_t SetSpace(int32 index, int32 res, screen_id screen, bool stick) +void Desktop::InitMode(void) { - -STRACE(("Desktop: SetSpace(%ld,%ld,%s,%ld)\n",index+1,res, - stick?"stick":"non-stick",screen.id)); - - desktop_private::workspacelock.Lock(); - status_t stat=desktop_private::activescreen->SetSpace(index,res,stick); - desktop_private::workspacelock.Unlock(); - return stat; + // this is init mode for n-SS. + for (int32 i=0; iSetScreens(screens, 1, 1); + + fRootLayerList.AddItem(rl); + } } -/*! - \brief Adds a window to the desktop so that it will be displayed - \param win Window to add - \param workspace index of the workspace to add the window to - \param screen Optional screen specifier. Currently unused. -*/ -void AddWindowToDesktop(ServerWindow *win, int32 workspace, screen_id screen) +// Methods for multiple monitors. +Screen* Desktop::ScreenAt(int32 index) const { + Screen *sc; + sc = static_cast(fScreenList.ItemAt(index)); -STRACE(("Desktop: AddWindowToDesktop(%s,%ld,%ld)\n",win?win->GetTitle():"NULL", - workspace+1,screen.id)); + return sc; +} - // Workspace() will be non-NULL if it has already been added to the desktop - if(!win || win->GetWorkspace()) +int32 Desktop::ScreenCount(void) const +{ + return fScreenList.CountItems(); +} + +void Desktop::SetActiveScreen(int32 index) +{ + if(index<0 || index>fScreenList.CountItems()-1) return; - desktop_private::workspacelock.Lock(); - desktop_private::layerlock.Lock(); - - Workspace *w=desktop_private::activescreen->GetActiveWorkspace(); - win->SetWorkspace(w); - desktop_private::activescreen->AddWindow(win,workspace); + // TODO: Once we get multiple monitor support going officially, we'll likely + // need to do something with the cursor here. - desktop_private::layerlock.Unlock(); - desktop_private::workspacelock.Unlock(); + fActiveScreen=(Screen*)fScreenList.ItemAt(index); } -WinBorder* WindowContainsPoint( BPoint pt ){ - -STRACE(("Desktop: WindowContainsPoint(%s,%f,%f)\n",win?win->GetTitle():"NULL", - pt.x, pt.y)); - - WinBorder *wb; - - desktop_private::workspacelock.Lock(); - desktop_private::layerlock.Lock(); - - wb = desktop_private::activescreen->GetWindowAt( pt ); - - desktop_private::layerlock.Unlock(); - desktop_private::workspacelock.Unlock(); - - return wb; -} -/*! - \brief Removes a window from the desktop - \param win Window to remove -*/ -void RemoveWindowFromDesktop(ServerWindow *win) +void Desktop::SetActiveRootLayerByIndex(int32 listIndex) { -STRACE(("Desktop: RemoveWindowFromDesktop(%s)\n",win?win->GetTitle():"NULL")); - lock_workspaces(); - lock_layers(); - - win->SetWorkspace(NULL); - desktop_private::activescreen->RemoveWindow(win); - - unlock_layers(); - unlock_workspaces(); + RootLayer *rl; + rl = RootLayerAt(listIndex); + if (rl) + SetActiveRootLayer(rl); } -/*! - \brief Returns the active window in the current workspace of the active screen - \return The active window in the current workspace of the active screen -*/ -ServerWindow *GetActiveWindow(void) +void Desktop::SetActiveRootLayer(RootLayer* rl) { - lock_workspaces(); - ServerWindow *w=desktop_private::activescreen->ActiveWindow(); - unlock_workspaces(); - - return w; -} - -/*! - \brief Sets the active window in the current workspace of the active screen - \param win The window to activate - - If the window is not in the current workspace of the active screen, this call fails -*/ -void SetActiveWindow(ServerWindow *win) -{ -STRACE(("Desktop: SetActiveWindow(%s)\n",win?win->GetTitle():"NULL")); - lock_workspaces(); - Workspace *w=desktop_private::activescreen->GetActiveWorkspace(); - if(win && win->GetWorkspace()!=w) - { - desktop_private::workspacelock.Unlock(); + if (fActiveRootLayer == rl) return; + + fActiveRootLayer = rl; + + // also set he new front and focus + SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); + SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); + + // TODO: other tasks required when this happens. I don't know them now. + // Rebuild & Invalidate + // hide the mouse in the old ActiveRootLayer + // show the mouse in new ActiveRootLayer +} + +RootLayer* Desktop::ActiveRootLayer(void) const +{ + return fActiveRootLayer; +} + +int32 Desktop::ActiveRootLayerIndex(void) const +{ + int32 rootLayerCount = CountRootLayers(); + for(int32 i=0; iActiveWindow(); - ActivateWindow(oldwin,win); - - unlock_workspaces(); + return -1; } -/*! - \brief Returns the root layer for the specified workspace - \param workspace Index of the workspace to use - \param screen Index of the screen to use. Currently ignored. - \return The root layer or NULL if there was an invalid parameter. -*/ -Layer *GetRootLayer(int32 workspace, screen_id screen) +RootLayer* Desktop::RootLayerAt(int32 index) { - lock_workspaces(); - lock_layers(); - Layer *r=desktop_private::activescreen->GetRootLayer(); - unlock_layers(); - unlock_workspaces(); + RootLayer *rl; + rl = static_cast(fRootLayerList.ItemAt(index)); - return r; + return rl; } -/*! - \brief Assigns a flattened BMessage to the global drag data. - \param size Size of the data buffer - \param flattened Flattened BMessage data buffer - - This assigns a BMessage in its flattened state to the internal storage. Only - one message can be stored at a time. Once an assignment is made, another cannot - be made until the current one is emptied. If additional calls are made while - there is a drag message assigned, the function will fail and the new assignment - will not be made. Note that this merely passes a pointer around. No copies are - made and the caller is responsible for freeing any allocated objects from the heap. -*/ -void set_drag_message(int32 size, int8 *flattened) -{ - lock_dragdata(); +int32 Desktop::CountRootLayers(void) const{ + return fRootLayerList.CountItems(); +} - if(desktop_private::dragmessage) - { - desktop_private::draglock.Unlock(); +// Methods for layer(WinBorder) manipulation. + +void Desktop::AddWinBorder(WinBorder* winBorder) +{ + if(fWinBorderList.HasItem(winBorder)) return; - } - desktop_private::dragmessage=flattened; - desktop_private::dragmessagesize=size; - unlock_dragdata(); -} - -/*! - \brief Gets the current drag data - \param size Receives the size of the drag data buffer - \return the drag data buffer or NULL if size is NULL - - Retrieve the current drag message in use. This function will fail if a NULL pointer - is passed to it. Note that this does not free the current drag message from use. - The size of the flattened message is stored in the size parameter. Also, note that if - there is no message in use, it will return NULL and set size to 0. -*/ -int8 *get_drag_message(int32 *size) -{ - int8 *ptr=NULL; - - lock_dragdata(); - - if(desktop_private::dragmessage) + // special case for Tracker background window. + if (winBorder->GetServerFeel() == B_SYSTEM_LAST) { - ptr=desktop_private::dragmessage; - *size=desktop_private::dragmessagesize; + // it's added in all RottLayers + for(int32 i=0; iAddWinBorder(winBorder); + } } - unlock_dragdata(); - return ptr; -} - -//! Empties current drag data and allows for new data to be assigned -void empty_drag_message(void) -{ - lock_dragdata(); - - if(desktop_private::dragmessage) - delete desktop_private::dragmessage; - desktop_private::dragmessage=NULL; - desktop_private::dragmessagesize=0; - - unlock_dragdata(); -} - - -/*! - \brief Thread-safe way of obtaining the current scrollbar behavior info - \return Current scroll behavior data -*/ -scroll_bar_info GetScrollBarInfo(void) -{ - scroll_bar_info sbi; - desktop_private::optlock.Lock(); - sbi=desktop_private::scrollbarinfo; - desktop_private::optlock.Unlock(); - return sbi; -} - -/*! - \brief Thread-safe way of setting the current scrollbar behavior info - \param info Behavior data structure -*/ -void SetScrollBarInfo(const scroll_bar_info &info) -{ - desktop_private::optlock.Lock(); - desktop_private::scrollbarinfo=info; - desktop_private::optlock.Unlock(); -} - -/*! - \brief Thread-safe way of obtaining the current menu behavior info - \return Current menu behavior data -*/ -menu_info GetMenuInfo(void) -{ - menu_info mi; - desktop_private::optlock.Lock(); - mi=desktop_private::menuinfo; - desktop_private::optlock.Unlock(); - return mi; -} - -/*! - \brief Thread-safe way of setting the current menu behavior info - \param info Behavior data structure -*/ -void SetMenuInfo(const menu_info &info) -{ - desktop_private::optlock.Lock(); - desktop_private::menuinfo=info; - desktop_private::optlock.Unlock(); -} - -/*! - \brief See if the the system is in focus-follows-mouse mode - \return True if enabled, false if disabled -*/ -bool GetFFMouse(void) -{ - bool value; - desktop_private::optlock.Lock(); - value=desktop_private::ffm; - desktop_private::optlock.Unlock(); - return value; -} - -/*! - \brief Enable or disable focus-follows-mouse for system - \param info Enable/Disable flag -*/ -void SetFFMouse(const bool &value) -{ - desktop_private::optlock.Lock(); - desktop_private::ffm=value; - desktop_private::optlock.Unlock(); -} - -/*! - \brief Obtain the current focus-follows-mouse behavior - \return Current menu behavior data -*/ -mode_mouse GetFFMouseMode(void) -{ - mode_mouse value; - desktop_private::optlock.Lock(); - value=desktop_private::ffm_mode; - desktop_private::optlock.Unlock(); - return value; -} - -/*! - \brief Set the focus-follows-mouse behavior - \param info Behavior data structure -*/ -void SetFFMouseMode(const mode_mouse &value) -{ - desktop_private::optlock.Lock(); - desktop_private::ffm_mode=value; - desktop_private::optlock.Unlock(); -} - -/*! - \brief Read in settings from R5's workspace settings file in ~/config/settings - \return True if successful, false unable to read and parse file. -*/ -bool ReadR5WorkspaceData(void) -{ - //TODO: Add read checks for fscsnf calls - - // Should there be multiple graphics devices, I assume that we'd probably need to loop through - // each device and read the workspace data for each. For now, we just assume that there is - // just one. - - FILE *file=fopen("/boot/home/config/settings/app_server_settings",B_READ_ONLY); - if(!file) - return false; - - char devicepath[B_PATH_NAME_LENGTH]; - as_workspace_data wdata; - int workspace_count=3; - - Screen *active=GetActiveScreen(); - - // read in device - // Device - fscanf(file,"Device %s",devicepath); - - // read workspace count - // Workspaces # { - fscanf(file,"Workspaces %d {",&workspace_count); - - // read workspace config for all 32 (0-31) - - for(int i=0; i<32;i++) + else { - // Workspace # { - fscanf(file,"Workspace %d {",&wdata.index); - - // timing: display_timing struct in Accelerant.h - fscanf(file,"timing %lu %u %u %u %u %u %u %u %u %lu",&wdata.timing.pixel_clock, - (unsigned int*)&(wdata.timing.h_display),(unsigned int*)&(wdata.timing.h_sync_start), - (unsigned int*)&(wdata.timing.h_sync_end),(unsigned int*)&(wdata.timing.h_total), - (unsigned int*)&(wdata.timing.v_display),(unsigned int*)&(wdata.timing.v_sync_start), - (unsigned int*)&(wdata.timing.v_sync_end),(unsigned int*)&(wdata.timing.v_total), - &wdata.timing.flags); - - // colorspace: member of color_space struct, like RGB15, RGB32, etc. - fscanf(file,"colorspace %lx",(long*)&wdata.space); - - // virtual width height - fscanf(file,"virtual %d %d",&wdata.res_w, &wdata.res_h); - - // flags: - fscanf(file,"flags %lx",&wdata.flags); - - // color: RGB hexcode - fscanf(file,"color %lx",&wdata.bgcolor); - // } - - // Create a workspace and add it to the active screen. - Workspace *w=new Workspace(&wdata,active); - active->AddWorkspace(w); + // other windows are added to the current RootLayer only. + ActiveRootLayer()->AddWinBorder(winBorder); } - scroll_bar_info sbi; - - // read interface block - // Interface { - // read scrollbars block - // Scrollbars { - int bflag; - - // get the four scrollbar values - // proportional 1 - fscanf(file,"proportional %d",&bflag); - sbi.proportional=(bflag==1)?true:false; + // add that pointer to user winboder list so that we can keep track of them. + fWinBorderList.AddItem(winBorder); - // arrows 2 - fscanf(file,"arrows %d",&bflag); - sbi.double_arrows=(bflag==2)?true:false; - - // knobtype 0 - fscanf(file,"knobtype %ld",&sbi.knob); + SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); + SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); +} - // knobsize 15 - fscanf(file,"knobsize %ld",&sbi.min_knob_size); - // } - - // read options block - // Options { - - // get focus-follows-mouse block - // ffm # - // FFM values: - // 0: Disabled - // 1: Enabled - // 2: Warping - // 3: Instant Warping - int ffm; - fscanf(file,"ffm %d",&ffm); - SetFFMouse(ffm); - - // skip decor listing - fclose(file); - +void Desktop::RemoveWinBorder(WinBorder* winBorder) +{ + if(winBorder->GetServerFeel() == B_SYSTEM_LAST) + for(int32 i=0; iRemoveWinBorder(winBorder); + else + winBorder->GetRootLayer()->RemoveWinBorder(winBorder); + + if (winBorder == fFrontWinBorder) + SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); + + if (winBorder == fFocusWinBorder) + SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); + + fWinBorderList.RemoveItem(winBorder); +} + +bool Desktop::HasWinBorder(WinBorder* winBorder) +{ + return fWinBorderList.HasItem(winBorder); +} + +void Desktop::SetFrontWinBorder(WinBorder* winBorder) +{ + // TODO: implement + fFrontWinBorder = winBorder; +} + +void Desktop::SetFocusWinBorder(WinBorder* winBorder) +{ + // TODO: implement + fFocusWinBorder = winBorder; +} + +WinBorder* Desktop::FrontWinBorder(void) const +{ + return fActiveRootLayer->ActiveWorkspace()->FrontLayer(); +} + +WinBorder* Desktop::FocusWinBorder(void) const +{ + return fActiveRootLayer->ActiveWorkspace()->FocusLayer(); +} + +// Input related methods + +void Desktop::MouseEventHandler(PortMessage *msg) +{ +} + +void Desktop::KeyboardEventHandler(PortMessage *msg) +{ +} + +void Desktop::SetDragMessage(BMessage* msg) +{ + if (fDragMessage) + { + delete fDragMessage; + fDragMessage = NULL; + } + + if (msg) + fDragMessage = new BMessage(*msg); +} + +BMessage* Desktop::DragMessage(void) const +{ + return fDragMessage; +} + + // Methods for various desktop stuff handled by the server +void Desktop::SetScrollBarInfo(const scroll_bar_info &info) +{ + fScrollBarInfo = info; +} + +scroll_bar_info Desktop::ScrollBarInfo(void) const +{ + return fScrollBarInfo; +} + +void Desktop::SetMenuInfo(const menu_info &info) +{ + fMenuInfo = info; +} + +menu_info Desktop::MenuInfo(void) const +{ + return fMenuInfo; +} + +void Desktop::UseFFMouse(const bool &useffm) +{ + fFFMouseMode = useffm; +} + +bool Desktop::FFMouseInUse(void) const +{ + return fFFMouseMode; +} + +void Desktop::SetFFMouseMode(const mode_mouse &value) +{ + fMouseMode = value; +} + +mode_mouse Desktop::FFMouseMode(void) const +{ + return fMouseMode; +} + +bool Desktop::ReadWorkspaceData(void) +{ + // TODO: implement return true; } -/*! - \brief Reads in workspace config data using the regular system file - \return True if settings were successfully loaded. False if not - - The file's location is defined in ServerConfig.h - SERVER_SETTINGS_DIR/WORKSPACE_SETTINGS_NAME. -*/ -bool ReadOBOSWorkspaceData(void) +void Desktop::SaveWorkspaceData(void) { - //TODO: Implement - return false; + // TODO: implement } -//! Saves workspace config to SERVER_SETTINGS_DIR/WORKSPACE_SETTINGS_NAME as defined in ServerConfig.h -void SaveWorkspaceData(void) +void Desktop::RemoveSubsetWindow(WinBorder* wb) { - //TODO: Implement + WinBorder *winBorder = NULL; + int32 count = fWinBorderList.CountItems(); + + for(int32 i=0; i < count; i++) + { + winBorder = static_cast(fWinBorderList.ItemAt(i)); + if (winBorder->GetServerFeel() == B_NORMAL_FEEL) + winBorder->Window()->GetFMWList()->RemoveItem(wb); + } + + RootLayer *rl = winBorder->GetRootLayer(); + int32 countWKs = rl->WorkspaceCount(); + for (int32 i=0; i < countWKs; i++) + { + rl->WorkspaceAt(i+1)->RemoveLayerPtr(wb); + } +} + +void Desktop::PrintToStream(void) +{ + printf("RootLayer List:\n=======\n"); + for(int32 i=0; iGetName()); + ((RootLayer*)fRootLayerList.ItemAt(i))->PrintToStream(); + printf("-------\n"); + } + printf("=======\nActive RootLayer: %s\n", fActiveRootLayer? fActiveRootLayer->GetName(): "NULL"); +// printf("Active WinBorder: %s\n", fActiveWinBorder? fActiveWinBorder->Name(void): "NULL"); + + printf("Screen List:\n"); + for(int32 i=0; iScreenNumber()); + } + +} + +void Desktop::PrintVisibleInRootLayerNo(int32 no) +{ + if (no<0 || no>=fRootLayerList.CountItems()) + return; + + printf("Visible windows in RootLayer %ld, Workspace %ld\n", + ActiveRootLayerIndex(), ActiveRootLayer()->ActiveWorkspaceIndex()); + WinBorder *wb = NULL; + Workspace *ws = ActiveRootLayer()->ActiveWorkspace(); + for(wb = (WinBorder*)ws->GoToTopItem(); wb != NULL; wb = (WinBorder*)ws->GoToLowerItem()){ + if (!wb->IsHidden()) + wb->PrintToStream(); + } +} + +DisplayDriver *Desktop::GetGfxDriver(void) +{ + return fActiveScreen->GetDriver(); +} + +void Desktop::SetWorkspace(int32 index) +{ + fActiveRootLayer->SetActiveWorkspaceByIndex(index); } diff --git a/src/servers/app/server/Desktop.h b/src/servers/app/server/Desktop.h index ff988f0cd0..78ce9e93f2 100644 --- a/src/servers/app/server/Desktop.h +++ b/src/servers/app/server/Desktop.h @@ -1,89 +1,106 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Desktop.h -// Author: DarkWyrm -// Description: Functions used to work with workspaces and general desktop stuff -// -//------------------------------------------------------------------------------ -#ifndef DESKTOP_H_ -#define DESKTOP_H_ +#ifndef _DESKTOP_H_ +#define _DESKTOP_H_ -#include -#include +#include +#include #include -#include #include -//#include "WinBorder.h" -class ServerWindow; -class Screen; class DisplayDriver; +class RootLayer; +class Screen; class Layer; +class BMessage; +class PortMessage; class WinBorder; -void InitDesktop(void); -void ShutdownDesktop(void); +class Desktop +{ +public: + // startup methods + Desktop(void); + ~Desktop(void); + void Init(void); -void AddWorkspace(int32 index=-1); -void DeleteWorkspace(int32 index); -int32 CountWorkspaces(void); -void SetWorkspaceCount(int32 count); -int32 CurrentWorkspace(void); -void SetWorkspace(int32 workspace); + // 1-BigScreen or n-SmallScreens + void InitMode(void); + + // Methods for multiple monitors. + Screen *ScreenAt(int32 index) const; + int32 ScreenCount(void) const; + Screen *ActiveScreen(void) const { return fActiveScreen; } + void SetActiveScreen(int32 index); + + void SetActiveRootLayerByIndex(int32 listIndex); + void SetActiveRootLayer(RootLayer* rl); + RootLayer* RootLayerAt(int32 index); + RootLayer* ActiveRootLayer(void) const; + int32 ActiveRootLayerIndex(void) const; + int32 CountRootLayers(void) const; -void SetScreen(screen_id id); -int32 CountScreens(void); -screen_id ActiveScreen(void); -Screen *GetActiveScreen(void); -DisplayDriver *GetGfxDriver(screen_id screen); -status_t SetSpace(int32 index, int32 res, screen_id screen, bool stick=true); + // Stuff for easy access + DisplayDriver *GetGfxDriver(void); + void SetWorkspace(int32 index); + + // Methods for layer(WinBorder) manipulation. + void AddWinBorder(WinBorder* winBorder); + void RemoveWinBorder(WinBorder* winBorder); + bool HasWinBorder(WinBorder* winBorder); + void SetFrontWinBorder(WinBorder* winBorder); + void SetFocusWinBorder(WinBorder* winBorder); + WinBorder* FrontWinBorder(void) const; + WinBorder* FocusWinBorder(void) const; + + // Input related methods + void MouseEventHandler(PortMessage *msg); + void KeyboardEventHandler(PortMessage *msg); + + void SetDragMessage(BMessage* msg); + BMessage* DragMessage(void) const; + + // Methods for various desktop stuff handled by the server + void SetScrollBarInfo(const scroll_bar_info &info); + scroll_bar_info ScrollBarInfo(void) const; + + void SetMenuInfo(const menu_info &info); + menu_info MenuInfo(void) const; + + + void UseFFMouse(const bool &useffm); + bool FFMouseInUse(void) const; + void SetFFMouseMode(const mode_mouse &value); + mode_mouse FFMouseMode(void) const; + + bool ReadWorkspaceData(void); + void SaveWorkspaceData(void); + + // Debugging methods + void PrintToStream(void); + void PrintVisibleInRootLayerNo(int32 no); + + // "Private" to app_server :-) - means they should not be used very much + void RemoveSubsetWindow(WinBorder* wb); -void AddWindowToDesktop(ServerWindow *win, int32 workspace, screen_id screen); -void RemoveWindowFromDesktop(ServerWindow *win); -WinBorder* WindowContainsPoint( BPoint pt ); -ServerWindow *GetActiveWindow(void); -void SetActiveWindow(ServerWindow *win); -Layer *GetRootLayer(int32 workspace, screen_id screen); +private: + BLocker fLayerLock; + BList fWinBorderList; + + BMessage *fDragMessage; + + BList fRootLayerList; + RootLayer* fActiveRootLayer; + WinBorder* fFrontWinBorder; + WinBorder* fFocusWinBorder; + + BList fScreenList; + + scroll_bar_info fScrollBarInfo; + menu_info fMenuInfo; + mode_mouse fMouseMode; + bool fFFMouseMode; + Screen *fActiveScreen; +}; -void set_drag_message(int32 size, int8 *flattened); -int8* get_drag_message(int32 *size); -void empty_drag_message(void); +extern Desktop* desktop; -scroll_bar_info GetScrollBarInfo(void); -void SetScrollBarInfo(const scroll_bar_info &info); - -menu_info GetMenuInfo(void); -void SetMenuInfo(const menu_info &info); - -bool GetFFMouse(void); -void SetFFMouse(const bool &value); -mode_mouse GetFFMouseMode(void); -void SetFFMouseMode(const mode_mouse &value); - -void lock_layers(void); -void unlock_layers(void); -void lock_dragdata(void); -void unlock_dragdata(void); -void lock_workspaces(void); -void unlock_workspaces(void); - -#endif +#endif // _DESKTOP_H_ diff --git a/src/servers/app/server/DisplayDriver.cpp b/src/servers/app/server/DisplayDriver.cpp index 0abc5e16b8..af47ebfcd3 100644 --- a/src/servers/app/server/DisplayDriver.cpp +++ b/src/servers/app/server/DisplayDriver.cpp @@ -27,6 +27,7 @@ // //------------------------------------------------------------------------------ #include +#include #include "DisplayDriver.h" #include "LayerData.h" #include "ServerCursor.h" @@ -332,11 +333,11 @@ void DisplayDriver::DrawString(const char *string, int32 length, BPoint pt, Laye { } -void DisplayDriver::FillArc(const BRect r, float angle, float span, const RGBColor& color) +void DisplayDriver::FillArc(const BRect r, float angle, float span, RGBColor &color) { } -void DisplayDriver::FillArc(const BRect r, float angle, float span, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillArc(const BRect r, float angle, float span, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -715,11 +716,11 @@ void DisplayDriver::FillArc(const BRect r, float angle, float span, DisplayDrive Unlock(); } -void DisplayDriver::FillBezier(BPoint *pts, const RGBColor& color) +void DisplayDriver::FillBezier(BPoint *pts, RGBColor &color) { } -void DisplayDriver::FillBezier(BPoint *pts, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillBezier(BPoint *pts, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -803,11 +804,11 @@ void DisplayDriver::FillBezier(BPoint *pts, DisplayDriver* driver, SetHorizontal */ } -void DisplayDriver::FillEllipse(BRect r, const RGBColor& color) +void DisplayDriver::FillEllipse(BRect r, RGBColor &color) { } -void DisplayDriver::FillEllipse(BRect r, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillEllipse(BRect r, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -877,11 +878,11 @@ void DisplayDriver::FillEllipse(BRect r, DisplayDriver* driver, SetHorizontalLin Unlock(); } -void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, const RGBColor& color) +void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, RGBColor &color) { } -void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1018,7 +1019,7 @@ void DisplayDriver::FillPolygon(BPoint *ptlist, int32 numpts, DisplayDriver* dri \param r BRect to be filled. Guaranteed to be in the frame buffer's coordinate space \param color The color used to fill the rectangle */ -void DisplayDriver::FillRect(const BRect r, const RGBColor& color) +void DisplayDriver::FillRect(const BRect r, RGBColor &color) { } @@ -1029,7 +1030,7 @@ void DisplayDriver::FillRect(const BRect r, const RGBColor& color) \param high_color The high color of the pattern \param low_color The low color of the pattern */ -void DisplayDriver::FillRect(const BRect r, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillRect(const BRect r, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1038,7 +1039,7 @@ void DisplayDriver::FillRect(const BRect r, const Pattern& pattern, const RGBCol \param r BRegion to be filled \param color The color used to fill the region */ -void DisplayDriver::FillRegion(BRegion& r, const RGBColor& color) +void DisplayDriver::FillRegion(BRegion& r, RGBColor &color) { Lock(); @@ -1055,7 +1056,7 @@ void DisplayDriver::FillRegion(BRegion& r, const RGBColor& color) \param high_color The high color of the pattern \param low_color The low color of the pattern */ -void DisplayDriver::FillRegion(BRegion& r, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillRegion(BRegion& r, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { Lock(); @@ -1065,11 +1066,11 @@ void DisplayDriver::FillRegion(BRegion& r, const Pattern& pattern, const RGBColo Unlock(); } -void DisplayDriver::FillRoundRect(BRect r, float xrad, float yrad, const RGBColor& color) +void DisplayDriver::FillRoundRect(BRect r, float xrad, float yrad, RGBColor &color) { } -void DisplayDriver::FillRoundRect(BRect r, float xrad, float yrad, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillRoundRect(BRect r, float xrad, float yrad, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1102,11 +1103,11 @@ void DisplayDriver::FillRoundRect(BRect r, float xrad, float yrad, DisplayDriver //{ //} -void DisplayDriver::FillTriangle(BPoint *pts, const RGBColor& color) +void DisplayDriver::FillTriangle(BPoint *pts, RGBColor &color) { } -void DisplayDriver::FillTriangle(BPoint *pts, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::FillTriangle(BPoint *pts, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1306,11 +1307,11 @@ void DisplayDriver::SetCursor(ServerCursor *cursor) Unlock(); } -void DisplayDriver::StrokeArc(BRect r, float angle, float span, float pensize, const RGBColor& color) +void DisplayDriver::StrokeArc(BRect r, float angle, float span, float pensize, RGBColor &color) { } -void DisplayDriver::StrokeArc(BRect r, float angle, float span, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeArc(BRect r, float angle, float span, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1472,11 +1473,11 @@ void DisplayDriver::StrokeArc(BRect r, float angle, float span, DisplayDriver* d } -void DisplayDriver::StrokeBezier(BPoint *pts, float pensize, const RGBColor& color) +void DisplayDriver::StrokeBezier(BPoint *pts, float pensize, RGBColor &color) { } -void DisplayDriver::StrokeBezier(BPoint *pts, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeBezier(BPoint *pts, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1539,11 +1540,11 @@ void DisplayDriver::StrokeBezier(BPoint *pts, DisplayDriver* driver, SetPixelFun } } -void DisplayDriver::StrokeEllipse(BRect r, float pensize, const RGBColor& color) +void DisplayDriver::StrokeEllipse(BRect r, float pensize, RGBColor &color) { } -void DisplayDriver::StrokeEllipse(BRect r, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeEllipse(BRect r, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1614,11 +1615,11 @@ void DisplayDriver::StrokeEllipse(BRect r, DisplayDriver* driver, SetPixelFuncTy } } -void DisplayDriver::StrokeLine(BPoint start, BPoint end, float pensize, const RGBColor& color) +void DisplayDriver::StrokeLine(BPoint start, BPoint end, float pensize, RGBColor &color) { } -void DisplayDriver::StrokeLine(BPoint start, BPoint end, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeLine(BPoint start, BPoint end, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1657,15 +1658,15 @@ void DisplayDriver::StrokeLine(BPoint start, BPoint end, DisplayDriver* driver, } } -void DisplayDriver::StrokePoint(BPoint& pt, const RGBColor& color) +void DisplayDriver::StrokePoint(BPoint& pt, RGBColor &color) { } -void DisplayDriver::StrokePolygon(BPoint *ptlist, int32 numpts, float pensize, const RGBColor& color, bool is_closed) +void DisplayDriver::StrokePolygon(BPoint *ptlist, int32 numpts, float pensize, RGBColor &color, bool is_closed) { } -void DisplayDriver::StrokePolygon(BPoint *ptlist, int32 numpts, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color, bool is_closed) +void DisplayDriver::StrokePolygon(BPoint *ptlist, int32 numpts, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color, bool is_closed) { } @@ -1689,11 +1690,11 @@ void DisplayDriver::StrokePolygon(BPoint *ptlist, int32 numpts, DisplayDriver* d \param pensize Thickness of the lines \param color The color of the rectangle */ -void DisplayDriver::StrokeRect(BRect r, float pensize, const RGBColor& color) +void DisplayDriver::StrokeRect(BRect r, float pensize, RGBColor &color) { } -void DisplayDriver::StrokeRect(BRect r, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeRect(BRect r, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1712,7 +1713,7 @@ void DisplayDriver::StrokeRect(BRect r, DisplayDriver* driver, SetHorizontalLine \param pat 8-byte array containing the const Pattern &to use. Always non-NULL. */ -void DisplayDriver::StrokeRegion(BRegion& r, float pensize, const RGBColor& color) +void DisplayDriver::StrokeRegion(BRegion& r, float pensize, RGBColor &color) { Lock(); @@ -1722,7 +1723,7 @@ void DisplayDriver::StrokeRegion(BRegion& r, float pensize, const RGBColor& colo Unlock(); } -void DisplayDriver::StrokeRegion(BRegion& r, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeRegion(BRegion& r, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { Lock(); @@ -1732,11 +1733,11 @@ void DisplayDriver::StrokeRegion(BRegion& r, float pensize, const Pattern& patte Unlock(); } -void DisplayDriver::StrokeRoundRect(BRect r, float xrad, float yrad, float pensize, const RGBColor& color) +void DisplayDriver::StrokeRoundRect(BRect r, float xrad, float yrad, float pensize, RGBColor &color) { } -void DisplayDriver::StrokeRoundRect(BRect r, float xrad, float yrad, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeRoundRect(BRect r, float xrad, float yrad, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { } @@ -1786,7 +1787,7 @@ void DisplayDriver::StrokeRoundRect(BRect r, float xrad, float yrad, DisplayDriv \param pensize The line thickness \param color The color of the lines */ -void DisplayDriver::StrokeTriangle(BPoint *pts, float pensize, const RGBColor& color) +void DisplayDriver::StrokeTriangle(BPoint *pts, float pensize, RGBColor &color) { Lock(); StrokeLine(pts[0],pts[1],pensize,color); @@ -1795,7 +1796,7 @@ void DisplayDriver::StrokeTriangle(BPoint *pts, float pensize, const RGBColor& c Unlock(); } -void DisplayDriver::StrokeTriangle(BPoint *pts, float pensize, const Pattern& pattern, const RGBColor& high_color, const RGBColor& low_color) +void DisplayDriver::StrokeTriangle(BPoint *pts, float pensize, const Pattern& pattern, RGBColor &high_color, RGBColor &low_color) { Lock(); StrokeLine(pts[0],pts[1],pensize,pattern,high_color,low_color); @@ -1826,6 +1827,25 @@ void DisplayDriver::SetMode(int32 mode) { } +/* + \brief Sets the screen mode to specified resolution and color depth. + \param mode Data structure as defined in Screen.h + + Subclasses must include calls to _SetDepth, _SetHeight, _SetWidth, and _SetMode + to update the state variables kept internally by the DisplayDriver class. +*/ +void DisplayDriver::SetMode(const display_mode &mode) +{ +} + +/*! + \brief Sets the attributes in mode to reflect the current display mode + \param mode Structure to receive the current display mode's status +*/ +void DisplayDriver::GetMode(display_mode *mode) +{ +} + /*! \brief Dumps the contents of the frame buffer to a file. \param path Path and leaf of the file to be created without an extension diff --git a/src/servers/app/server/FMWList.cpp b/src/servers/app/server/FMWList.cpp new file mode 100644 index 0000000000..1ffdef483f --- /dev/null +++ b/src/servers/app/server/FMWList.cpp @@ -0,0 +1,141 @@ + +#include + +#include "FMWList.h" +#include "WinBorder.h" +#include "ServerWindow.h" + +FMWList::FMWList() +{ +} + +FMWList::~FMWList() +{ +//printf("~FMWList()\n"); +// if (fList.CountItems() > 0) +// printf("SERVER: WARNING: FMWList NOT empty in destructor!\n"); +} + +void FMWList::AddItem(void* item) +{ + int32 feelItem = ((WinBorder*)item)->Window()->GetFeel(); + int32 feelTemp = 0; + int32 location = 0; + + for(int32 i=0; iWindow()->GetFeel(); + + // in short: if 'item' is a floating window and 'temp' is a modal one, then + // we have found the place for our window('wb') + if( (feelItem == B_FLOATING_SUBSET_WINDOW_FEEL || + feelItem == B_FLOATING_APP_WINDOW_FEEL || + feelItem == B_FLOATING_ALL_WINDOW_FEEL) + && + (feelTemp == B_MODAL_SUBSET_WINDOW_FEEL || + feelTemp == B_MODAL_APP_WINDOW_FEEL || + feelTemp == B_MODAL_ALL_WINDOW_FEEL) + ) + { + location--; + break; + } + } + fList.AddItem(item, location); +} + +bool FMWList::HasItem(void* item) const +{ + return fList.HasItem(item); +} + +bool FMWList::RemoveItem(void* item) +{ + return fList.RemoveItem(item); +} + +void* FMWList::ItemAt(int32 i) const +{ + return fList.ItemAt(i); +} + +int32 FMWList::CountItems() const +{ + return fList.CountItems(); +} + +void* FMWList::LastItem() const +{ + return fList.LastItem(); +} + +void* FMWList::FirstItem() const +{ + return fList.FirstItem(); +} + +int32 FMWList::IndexOf(void *item) +{ + return fList.IndexOf(item); +} + +void FMWList::AddFMWList(FMWList *list) +{ + int32 i = 0; + for(i=0; iWindow()->GetFeel(); + if(feel == B_MODAL_SUBSET_WINDOW_FEEL || + feel == B_MODAL_APP_WINDOW_FEEL || + feel == B_MODAL_ALL_WINDOW_FEEL) + { + break; + } + } + + int32 j = 0; + for(j=0; jCountItems(); j++) + { + void *item = list->ItemAt(j); + int32 feel = ((WinBorder*)item)->Window()->GetFeel(); + if(feel == B_MODAL_SUBSET_WINDOW_FEEL || + feel == B_MODAL_APP_WINDOW_FEEL || + feel == B_MODAL_ALL_WINDOW_FEEL) + { + fList.AddItem(item, fList.CountItems()); + } + else + { + fList.AddItem(item, i); + i++; + } + } +} + +void FMWList::PrintToStream() const +{ + printf("Floating and modal windows list:\n"); + WinBorder *wb = NULL; + for (int32 i=0; iGetName()); + if (wb->Window()->GetFeel() == B_FLOATING_SUBSET_WINDOW_FEEL) + printf("\t%s\n", "B_FLOATING_SUBSET_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_FLOATING_APP_WINDOW_FEEL) + printf("\t%s\n", "B_FLOATING_APP_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_FLOATING_ALL_WINDOW_FEEL) + printf("\t%s\n", "B_FLOATING_ALL_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_MODAL_SUBSET_WINDOW_FEEL) + printf("\t%s\n", "B_MODAL_SUBSET_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_MODAL_APP_WINDOW_FEEL) + printf("\t%s\n", "B_MODAL_APP_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_MODAL_ALL_WINDOW_FEEL) + printf("\t%s\n", "B_MODAL_ALL_WINDOW_FEEL"); + + // this should NOT happen + if (wb->Window()->GetFeel() == B_NORMAL_WINDOW_FEEL) + printf("\t%s\n", "B_NORMAL_WINDOW_FEEL"); + } +} diff --git a/src/servers/app/server/FMWList.h b/src/servers/app/server/FMWList.h new file mode 100644 index 0000000000..f054e302de --- /dev/null +++ b/src/servers/app/server/FMWList.h @@ -0,0 +1,29 @@ +#ifndef _FMWLIST_H_ +#define _FMWLIST_H_ + +#include +#include + +class FMWList{ +public: + FMWList(); + virtual ~FMWList(); + void AddItem(void* item); + bool HasItem(void* item) const; + bool RemoveItem(void* item); + void* ItemAt(int32 i) const; + int32 CountItems() const; + void* LastItem() const; + void* FirstItem() const; + int32 IndexOf(void *item); + // special + void AddFMWList(FMWList *list); + // debugging methods + void PrintToStream() const; + +private: + + BList fList; +}; + +#endif diff --git a/src/servers/app/server/Globals.h b/src/servers/app/server/Globals.h new file mode 100644 index 0000000000..4bc1dde699 --- /dev/null +++ b/src/servers/app/server/Globals.h @@ -0,0 +1,14 @@ +#ifndef _GLOBALS_H_ +#define _GLOBALS_H_ + +#define B_SYSTEM_LAST 10 +#define B_NORMAL_FEEL 11 +#define B_FLOATING_SUBSET_FEEL 12 +#define B_FLOATING_APP_FEEL 13 +#define B_MODAL_SUBSET_FEEL 14 +#define B_MODAL_APP_FEEL 15 +#define B_FLOATING_ALL_FEEL 16 +#define B_MODAL_ALL_FEEL 17 +#define B_SYSTEM_FIRST 18 + +#endif diff --git a/src/servers/app/server/Jamfile b/src/servers/app/server/Jamfile index 684f1e40b2..d43f9a6654 100644 --- a/src/servers/app/server/Jamfile +++ b/src/servers/app/server/Jamfile @@ -36,6 +36,7 @@ Server app_server : # Misc. Sources Angle.cpp CursorData.cpp + FMWList.cpp PicturePlayer.cpp PNGDump.cpp SessionStreamReader.cpp @@ -55,11 +56,13 @@ Server app_server : ScreenDriver.cpp ViewDriver.cpp DefaultDecorator.cpp - DesktopClasses.cpp Layer.cpp RootLayer.cpp - WinBorder.cpp ServerPicture.cpp + ServerScreen.cpp + WinBorder.cpp + Workspace.cpp + ; LINKFLAGS on app_server ?= $(LINKFLAGS) ; diff --git a/src/servers/app/server/Layer.cpp b/src/servers/app/server/Layer.cpp index 39400e6415..b6c0c425a8 100644 --- a/src/servers/app/server/Layer.cpp +++ b/src/servers/app/server/Layer.cpp @@ -39,6 +39,7 @@ #include "ServerCursor.h" #include "CursorManager.h" #include "TokenHandler.h" +#include "RectUtils.h" #include "RootLayer.h" #include "DisplayDriver.h" #include "Desktop.h" @@ -93,8 +94,10 @@ Layer::Layer(BRect frame, const char *name, int32 token, uint32 resize, _serverwin = win; _cursor = NULL; + clipToPicture = NULL; - fDriver = GetGfxDriver(ActiveScreen()); + //TODO: Fix +// fDriver = GetGfxDriver(ActiveScreen()); } //! Destructor frees all allocated heap space @@ -161,6 +164,24 @@ void Layer::AddChild(Layer *layer, Layer *before) } } +/*! + \brief Used in the new Desktop Management code +*/ +void Layer::AddChild(Layer *layer, RootLayer *rootLayer) +{ + // TODO: Document + + if (layer->GetRootLayer()) + { + printf("Error: Layer already belongs to a RootLayer!\n"); + return; + } + + layer->fRootLayer = rootLayer; + + fLayerList.AddItem(layer); +} + /*! \brief Removes a layer from the child stack \param layer The layer to remove @@ -172,8 +193,10 @@ void Layer::RemoveChild(Layer *layer) printf("ERROR: RemoveChild(): Layer doesn't have a _parent\n"); return; } - if( layer->_parent != this ){ - printf("ERROR: RemoveChild(): Layer is not a child of this layer\n"); + + if (!(fLayerList.HasItem(layer))) + { + printf("Error: Layer is not a child of this RootLayer!\n"); return; } @@ -213,6 +236,9 @@ void Layer::RemoveChild(Layer *layer) DoInvalidate( BRegion(invalidRect), cachedUpperSibling ); } } + + fRootLayer = NULL; + fLayerList.RemoveItem(layer); } /*! @@ -229,13 +255,33 @@ void Layer::RemoveSelf() _parent->RemoveChild(this); } +/*! + \brief Used in the new Desktop Management code +*/ +bool Layer::HasChild(Layer* layer) const +{ + return fLayerList.HasItem(layer); +} + +/*! + \brief Used in the new Desktop Management code +*/ +void Layer::SetRootLayer(RootLayer* rl) +{ + fRootLayer = rl; +} + /*! \brief Finds the first child at a given point. \param pt Point to look for a child + \param recursive Flag to look for the bottom-most child \return non-NULL if found, NULL if not Find out which child gets hit if we click at a certain spot. Returns NULL if there are no _visible children or if the click does not hit a child layer + If recursive==true, then it will continue to call until it reaches a layer + which has no children, i.e. a layer that is at the top of its 'branch' in + the layer tree */ Layer* Layer::GetLayerAt(const BPoint &pt) { @@ -1265,9 +1311,3 @@ void Layer::MakeBottomChild(void) _parent->_bottomchild=this; } - -/* - @log - * added 2 new methods - DoMoveTo and DoResizeTo. They move/resize the frame rectangle of Layer class. - In DoResizeTo() I added some code for autoresizing(based on BView's resizeMask parameter) of children. Still, the effective code for resizing need to be written. :-) I could do that, but other things have greater priority. :-) -*/ diff --git a/src/servers/app/server/Layer.h b/src/servers/app/server/Layer.h index 8087ea135b..23e86f0aa5 100644 --- a/src/servers/app/server/Layer.h +++ b/src/servers/app/server/Layer.h @@ -35,7 +35,6 @@ #include #include #include "LayerData.h" -#include "DesktopClasses.h" #include "TokenHandler.h" class ServerWindow; @@ -57,66 +56,69 @@ class DisplayDriver; class Layer { public: - Layer(BRect frame, const char *name, int32 token, uint32 resize, - uint32 flags, ServerWindow *win); - virtual ~Layer(void); - - void AddChild(Layer *child, Layer *before=NULL); - void RemoveChild(Layer *child); - void RemoveSelf(); - uint32 CountChildren(void) const; - void MakeTopChild(void); - void MakeBottomChild(void); - Layer* FindLayer(const int32 token); - Layer* GetLayerAt(const BPoint &pt); - Layer* GetUpperSibling() const { return _uppersibling; } - Layer* GetLowerSibling() const { return _lowersibling; } - - const char* GetName(void) const { return (_name)?_name->String():NULL; } - LayerData* GetLayerData(void) const { return _layerdata; } + Layer(BRect frame, const char *name, int32 token, uint32 resize, uint32 flags, ServerWindow *win); + virtual ~Layer(void); - void SetLayerCursor(ServerCursor *csr); - ServerCursor* GetLayerCursor(void) const; - virtual void MouseTransit(uint32 transit); - - void Invalidate(const BRect &rect); - void Invalidate(const BRegion ®ion); - void DoInvalidate(const BRegion ®, Layer *start); - - virtual void RebuildRegions( const BRect& r ); - void RebuildChildRegions( const BRect &r, Layer* startFrom ); - void RebuildFullRegion(void); - void MoveRegionsBy(float x, float y); - void ResizeRegionsBy(float x, float y); + void AddChild(Layer *child, Layer *before=NULL); + void AddChild(Layer *layer, RootLayer *rootLayer); + void RemoveChild(Layer *child); + void RemoveSelf(); + bool HasChild(Layer* layer) const; + uint32 CountChildren(void) const; + void MakeTopChild(void); + void MakeBottomChild(void); + Layer* FindLayer(const int32 token); + Layer* GetLayerAt(const BPoint &pt); + Layer* GetUpperSibling() const { return _uppersibling; } + Layer* GetLowerSibling() const { return _lowersibling; } + RootLayer *GetRootLayer() const { return fRootLayer; } + void SetRootLayer(RootLayer* rl); - void RequestClientUpdate(const BRect &rect); - void RequestDraw(const BRect &r); - virtual void Draw(const BRect &r); + const char* GetName(void) const { return (_name)?_name->String():NULL; } + LayerData* GetLayerData(void) const { return _layerdata; } - void Show(void); - void Hide(void); - bool IsHidden(void) const; - - BRect Bounds(void) const; - BRect Frame(void) const; - - virtual void MoveBy(float x, float y); - virtual void ResizeBy(float x, float y); - - BRect ConvertToParent(BRect rect); - BRegion ConvertToParent(BRegion *reg); - BRect ConvertFromParent(BRect rect); - BRegion ConvertFromParent(BRegion *reg); - BRegion ConvertToTop(BRegion *reg); - BRect ConvertToTop(BRect rect); - BRegion ConvertFromTop(BRegion *reg); - BRect ConvertFromTop(BRect rect); - - void PruneTree(void); - - void PrintToStream(void); - void PrintNode(void); - void PrintTree(); + void SetLayerCursor(ServerCursor *csr); + ServerCursor *GetLayerCursor(void) const; + virtual void MouseTransit(uint32 transit); + + void Invalidate(const BRect &rect); + void Invalidate(const BRegion ®ion); + void DoInvalidate(const BRegion ®, Layer *start); + + virtual void RebuildRegions( const BRect& r ); + void RebuildChildRegions( const BRect &r, Layer* startFrom ); + void RebuildFullRegion(void); + void MoveRegionsBy(float x, float y); + void ResizeRegionsBy(float x, float y); + + void RequestClientUpdate(const BRect &rect); + void RequestDraw(const BRect &r); + virtual void Draw(const BRect &r); + + void Show(void); + void Hide(void); + bool IsHidden(void) const; + + BRect Bounds(void) const; + BRect Frame(void) const; + + virtual void MoveBy(float x, float y); + virtual void ResizeBy(float x, float y); + + BRect ConvertToParent(BRect rect); + BRegion ConvertToParent(BRegion *reg); + BRect ConvertFromParent(BRect rect); + BRegion ConvertFromParent(BRegion *reg); + BRegion ConvertToTop(BRegion *reg); + BRect ConvertToTop(BRect rect); + BRegion ConvertFromTop(BRegion *reg); + BRect ConvertFromTop(BRect rect); + + void PruneTree(void); + + void PrintToStream(void); + void PrintNode(void); + void PrintTree(); protected: friend class RootLayer; @@ -124,37 +126,35 @@ protected: friend class Screen; friend class ServerWindow; - BRect _frame; - BPoint _boundsLeftTop; - Layer *_parent, - *_uppersibling, - *_lowersibling, - *_topchild, - *_bottomchild; + BRect _frame; + BPoint _boundsLeftTop; + Layer *_parent, + *_uppersibling, + *_lowersibling, + *_topchild, + *_bottomchild; + + BRegion _visible, + _fullVisible, + _full; - BRegion _visible, - _fullVisible, - _full; + BRegion *clipToPicture; + bool clipToPictureInverse; - BRegion *clipToPicture; - bool clipToPictureInverse; + ServerWindow *_serverwin; + BString *_name; + int32 _view_token; + int32 _level; + uint32 _flags; + uint32 _resize_mode; + bool _hidden; + bool _is_updating; + LayerData *_layerdata; + ServerCursor *_cursor; + DisplayDriver *fDriver; - ServerWindow *_serverwin; - BString *_name; - int32 _view_token; - int32 _level; - uint32 _flags; - uint32 _resize_mode; - bool _hidden; - bool _is_updating; - LayerData *_layerdata; - ServerCursor *_cursor; - DisplayDriver* fDriver; + RootLayer* fRootLayer; + BList fLayerList; }; #endif -/* - @log - * added a new member, BPoint _boundsLeftTop. Beside other uses, (DW don't forget!)it will be needed in redraw code. - * _flags is now declared as uint32 -*/ diff --git a/src/servers/app/server/RGBColor.cpp b/src/servers/app/server/RGBColor.cpp index 1c3fff033c..0878a2e6d2 100644 --- a/src/servers/app/server/RGBColor.cpp +++ b/src/servers/app/server/RGBColor.cpp @@ -247,7 +247,7 @@ void RGBColor::SetColor(const RGBColor &col) \brief Set the object to specified color \param col color to copy */ -RGBColor & RGBColor::operator=(const RGBColor &col) +const RGBColor & RGBColor::operator=(const RGBColor &col) { color32=col.color32; color16=col.color16; @@ -261,7 +261,7 @@ RGBColor & RGBColor::operator=(const RGBColor &col) \brief Set the object to specified color \param col color to copy */ -RGBColor & RGBColor::operator=(const rgb_color &col) +const RGBColor & RGBColor::operator=(const rgb_color &col) { color32=col; update8=update16=true; diff --git a/src/servers/app/server/RootLayer.cpp b/src/servers/app/server/RootLayer.cpp index 3f5fa2a6e0..285c9ff4d2 100644 --- a/src/servers/app/server/RootLayer.cpp +++ b/src/servers/app/server/RootLayer.cpp @@ -1,112 +1,480 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2003, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: RootLayer.cpp -// Author: Gabe Yoder -// DarkWyrm -// Description: Class used for the top layer of each workspace's Layer tree -// -//------------------------------------------------------------------------------ -#include -#include "DisplayDriver.h" -#include "Layer.h" -#include "RootLayer.h" -#include "Desktop.h" -#include "PatternHandler.h" // for pattern_union -#include "ServerConfig.h" -#include "TokenHandler.h" -#include + #include +#include +#include -//! TokenHandler object used to provide IDs for RootLayers(WorkSpaces) -TokenHandler rlayer_token_handler; +#include "ServerApp.h" +#include "Globals.h" +#include "RootLayer.h" +#include "Layer.h" +#include "Workspace.h" +#include "ServerScreen.h" +#include "WinBorder.h" +#include "ServerWindow.h" +#include "Desktop.h" +#include "FMWList.h" -//#define DEBUG_ROOTLAYER - -/*! - \brief Sets up internal variables needed by the RootLayer - \param rect Frame of the root layer - \param layername Name of the root layer. Not really used. - \param gfxdriver Pointer to the related graphics driver -*/ -RootLayer::RootLayer(BRect rect, const char *layername, DisplayDriver *gfxdriver) - : Layer(rect, layername, B_NULL_TOKEN, B_FOLLOW_NONE, 0, NULL) +//--------------------------------------------------------------------------- +RootLayer::RootLayer(const char *layername, int32 workspaceCount, Desktop *desktop) + : Layer(BRect(0,0,0,0), layername, 0, B_NORMAL_WINDOW_FEEL, 0, NULL) { - _view_token = rlayer_token_handler.GetToken(); + fDesktop = desktop; + fActiveWorkspace = NULL; + fRows = 0; + fColumns = 0; +// TODO: read these 3 from a configuration file. + fScreenXResolution = 0; + fScreenYResolution = 0; + fColorSpace = B_RGB32; - fDriver = gfxdriver; - - _hidden = false; + _view_token = 0; // is this used for WinBorders? + _hidden = false; + + SetWorkspaceCount(workspaceCount); } - -//! Frees all allocated heap memory (which happens to be none) ;) -RootLayer::~RootLayer() -{ +//--------------------------------------------------------------------------- +RootLayer::~RootLayer(){ +//printf("~RootLayer( %s )\n", Name()); + // RootLayer object just uses Screen objects, it is not allowed to delete them. } +//--------------------------------------------------------------------------- +void RootLayer::Draw(const BRect &r){ +/* THIS method is here because of DisplayDriver testing! + * It SHOULD BE REMOVED as soon as testing is done!!!! + */ +/* +#ifdef DISPLAYDRIVER_TEST_HACK + int8 pattern[8]; + int8 pattern2[8]; + memset(pattern,255,8); + memset(pattern2,128+64+32+16,8); + BRect r1(100,100,1500,1100); + BPoint pts[4]; + pts[0].x = 200; + pts[0].y = 200; + pts[1].x = 400; + pts[1].y = 1000; + pts[2].x = 600; + pts[2].y = 400; + pts[3].x = 1200; + pts[3].y = 800; + BPoint triangle[3]; + BRect triangleRect(100,100,400,300); + triangle[0].x = 100; + triangle[0].y = 100; + triangle[1].x = 100; + triangle[1].y = 300; + triangle[2].x = 400; + triangle[2].y = 300; + BPoint polygon[6]; + BRect polygonRect(100,100,300,400); + polygon[0].x = 100; + polygon[0].y = 100; + polygon[1].x = 100; + polygon[1].y = 400; + polygon[2].x = 200; + polygon[2].y = 300; + polygon[3].x = 300; + polygon[3].y = 400; + polygon[4].x = 300; + polygon[4].y = 100; + polygon[5].x = 200; + polygon[5].y = 200; -/*! - \brief Sets the background color of the Screen - \param col The new background color + _layerdata->highcolor.SetColor(255,0,0,255); + _layerdata->lowcolor.SetColor(255,255,255,255); + _driver->FillRect(r1,_layerdata,pattern); + + _layerdata->highcolor.SetColor(255,255,0,255); + _driver->StrokeLine(BPoint(100,100),BPoint(1500,1100),_layerdata,pattern); + + _layerdata->highcolor.SetColor(0,0,255,255); + _driver->StrokeBezier(pts,_layerdata,pattern); + _driver->StrokeArc(BRect(200,300,400,600),30,270,_layerdata,pattern); + _driver->StrokeEllipse(BRect(200,700,400,900),_layerdata,pattern); + _driver->StrokeRect(BRect(650,1000,750,1090),_layerdata,pattern); + _driver->StrokeRoundRect(BRect(200,1000,600,1090),30,40,_layerdata,pattern); +// _driver->StrokePolygon(polygon,6,polygonRect,_layerdata,pattern); +// _driver->StrokeTriangle(triangle,triangleRect,_layerdata,pattern); + _layerdata->highcolor.SetColor(255,0,255,255); + _driver->FillArc(BRect(1250,300,1450,600),30,270,_layerdata,pattern); +// _driver->FillBezier(pts,_layerdata,pattern); + _driver->FillEllipse(BRect(800,300,1200,600),_layerdata,pattern); + _driver->FillRoundRect(BRect(800,1000,1200,1090),30,40,_layerdata,pattern2); + _driver->FillPolygon(polygon,6,polygonRect,_layerdata,pattern); +// _driver->FillTriangle(triangle,triangleRect,_layerdata,pattern); +#endif */ -void RootLayer::SetColor(const RGBColor &col) -{ +} +//--------------------------------------------------------------------------- +void RootLayer::MoveBy(float x, float y){ +} +//--------------------------------------------------------------------------- +void RootLayer::ResizeBy(float x, float y){ +} +//--------------------------------------------------------------------------- +Layer* RootLayer::VirtualTopChild() const{ + return fActiveWorkspace->GoToTopItem(); +} +//--------------------------------------------------------------------------- +Layer* RootLayer::VirtualLowerSibling() const{ + return fActiveWorkspace->GoToLowerItem(); +} +//--------------------------------------------------------------------------- +Layer* RootLayer::VirtualUpperSibling() const{ + return fActiveWorkspace->GoToUpperItem(); +} +//--------------------------------------------------------------------------- +Layer* RootLayer::VirtualBottomChild() const{ + return fActiveWorkspace->GoToBottomItem(); +} +//--------------------------------------------------------------------------- +void RootLayer::AddWinBorderToWorkspaces(WinBorder* winBorder, uint32 wks){ + if (wks == B_CURRENT_WORKSPACE){ + ActiveWorkspace()->AddLayerPtr(winBorder); + return; + } + + for( int32 i=0; i < 32; i++){ + if( wks & (0x00000001 << i) && i < WorkspaceCount()){ + WorkspaceAt(i+1)->AddLayerPtr(winBorder); + } + } +} +/* The main job, beside adding winBorder as a child, is to determine + * in witch workspaces to add this window. + */ +//--------------------------------------------------------------------------- +void RootLayer::AddWinBorder(WinBorder* winBorder){ + // add winBorder to the known list of WinBorders so we can keep track of it. + AddChild(winBorder, this); + + // add winBorder to the desired workspaces + switch(winBorder->Window()->GetFeel()){ + case B_MODAL_SUBSET_WINDOW_FEEL:{ + /* this kind of window isn't added anywhere. It *will* be added + to main window's subset when winBorder::AddToSubsetOf(main) + will be called.*/ + break; + } + + case B_MODAL_APP_WINDOW_FEEL:{ + // add to ***app's*** list of Floating/Modal Windows. + winBorder->Window()->GetApp()->GetFMWList()->AddItem(winBorder); + + // determine in witch workspaces to add this winBorder. + uint32 wks = 0; +// TODO: change later when you put this code into the server + for (int32 i=0; iGoToBottomItem(); wb!=NULL; wb = ws->GoToUpperItem()){ + if ( !(wb->IsHidden()) && + winBorder->Window()->GetClientTeamID() == wb->Window()->GetClientTeamID()) + { + wks = wks | winBorder->Window()->GetWorkspaces(); + break; + } + } + } +// by using _bottomchild and _uppersibling. + + AddWinBorderToWorkspaces(winBorder, wks); + break; + } + + case B_MODAL_ALL_WINDOW_FEEL:{ + // add to ***system's*** list of Floating/Modal Windows. + fMainFMWList.AddItem(winBorder); + // add this winBorder to all workspaces + AddWinBorderToWorkspaces(winBorder, 0xffffffffUL); + break; + } + + case B_FLOATING_SUBSET_WINDOW_FEEL:{ + /* this kind of window isn't added anywhere. It *will* be added to WS's list + when its main window will become the front one. + Also, it will be added to MainWinBorder's list when + winBorder::AddToSubset(main) is called.*/ + break; + } + + case B_FLOATING_APP_WINDOW_FEEL:{ + // add to ***app's*** list of Floating/Modal Windows. + winBorder->Window()->GetApp()->GetFMWList()->AddItem(winBorder); + + for (int32 i=0; iFrontLayer(); + if(wb && wb->Window()->GetClientTeamID() == winBorder->Window()->GetClientTeamID() + && wb->Window()->GetFeel() == B_NORMAL_WINDOW_FEEL) + { + ws->AddLayerPtr(winBorder); + } + } + + break; + } + + case B_FLOATING_ALL_WINDOW_FEEL:{ + // add to ***system's*** list of Floating/Modal Windows. + fMainFMWList.AddItem(winBorder); + // add this winBorder to all workspaces + AddWinBorderToWorkspaces(winBorder, 0xffffffffUL); + break; + } + + case B_NORMAL_WINDOW_FEEL:{ + // add this winBorder to the specified workspaces + AddWinBorderToWorkspaces(winBorder, winBorder->Window()->GetWorkspaces()); + break; + } + + case B_SYSTEM_LAST: + case B_SYSTEM_FIRST:{ + // add this winBorder to all workspaces + AddWinBorderToWorkspaces(winBorder, 0xffffffffUL); + break; + } + default: + break; + } +} +/* This method does 3 things: + * 1) Removes MODAL/SUBSET windows from system/app/window subset list. + * 2) Removes this window from any workspace it appears in. + * 3) Removes this window from RootLayer's list of chilren. + */ +//--------------------------------------------------------------------------- +void RootLayer::RemoveWinBorder(WinBorder* winBorder){ + + int32 feel = winBorder->Window()->GetFeel(); + if(feel == B_MODAL_SUBSET_WINDOW_FEEL || feel == B_FLOATING_SUBSET_WINDOW_FEEL){ + desktop->RemoveSubsetWindow(winBorder); + } + else if (feel == B_MODAL_APP_WINDOW_FEEL || feel == B_FLOATING_APP_WINDOW_FEEL){ + RemoveAppWindow(winBorder); + } + else if(feel == B_MODAL_ALL_WINDOW_FEEL || feel == B_FLOATING_ALL_WINDOW_FEEL + || feel == B_SYSTEM_FIRST || feel == B_SYSTEM_LAST) + { + if(feel == B_MODAL_ALL_WINDOW_FEEL || feel == B_FLOATING_ALL_WINDOW_FEEL) + fMainFMWList.RemoveItem(winBorder); + + int32 count = WorkspaceCount(); + for(int32 i=0; i < count; i++) + WorkspaceAt(i+1)->RemoveLayerPtr(winBorder); + } + else{ // for B_NORMAL_WINDOW_FEEL + uint32 workspaces = winBorder->Window()->GetWorkspaces(); + int32 count = WorkspaceCount(); + for( int32 i=0; i < 32 && i < count; i++) + if( workspaces & (0x00000001 << i)) + WorkspaceAt(i+1)->RemoveLayerPtr(winBorder); + } + + RemoveChild(winBorder); +} +//--------------------------------------------------------------------------- +void RootLayer::ChangeWorkspacesFor(WinBorder* winBorder, uint32 newWorkspaces){ + // only NORMAL windows are affected by this change + if(!winBorder->_level != B_NORMAL_FEEL) + return; + + uint32 oldWorkspaces = winBorder->Window()->GetWorkspaces(); + for(int32 i=0; i < WorkspaceCount(); i++){ + if ((oldWorkspaces & (0x00000001 << i)) && (newWorkspaces & (0x00000001 << i))){ + // do nothing. + } + else if(oldWorkspaces & (0x00000001 << i)){ + WorkspaceAt(i+1)->RemoveLayerPtr(winBorder); + } + else if (newWorkspaces & (0x00000001 << i)){ + WorkspaceAt(i+1)->AddLayerPtr(winBorder); + } + } +} +//--------------------------------------------------------------------------- +void RootLayer::SetScreens(Screen *screen[], int32 rows, int32 columns){ +// NOTE: *All* Screens *MUST* have the same resolution. + fScreenPtrList.MakeEmpty(); + BRect newFrame(0, 0, 0, 0); + for (int32 i=0; i < rows; i++){ + if (i==0) + for(int32 j=0; j < columns; j++){ + fScreenPtrList.AddItem(screen[i*rows + j]); + + newFrame.right += screen[i*rows + j]->Resolution().x; + } + newFrame.bottom += screen[i*rows]->Resolution().y; + } + + newFrame.right -= 1; + newFrame.bottom -= 1; + + _frame = newFrame; + fRows = rows; + fColumns = columns; + fScreenXResolution = (int32)(screen[0]->Resolution().x); + fScreenYResolution = (int32)(screen[0]->Resolution().y); + +// RebuildRegions(Frame()); +// Invalidate(Frame()); +} +//--------------------------------------------------------------------------- +Screen** RootLayer::Screens(){ + return (Screen**)fScreenPtrList.Items(); +} +//--------------------------------------------------------------------------- +bool RootLayer::SetScreenResolution(int32 width, int32 height, uint32 colorspace){ + // if there is no need to change resolution... exit + if (fScreenXResolution == width && fScreenYResolution == height && + fColorSpace == colorspace) + return false; + + bool accepted = true; + + for (int i=0; i < fScreenPtrList.CountItems(); i++){ + Screen *screen; + screen = static_cast(fScreenPtrList.ItemAt(i)); + + if ( !(screen->SupportsResolution(BPoint(width, height), colorspace)) ) + accepted = false; + } + + if (accepted){ + for (int i=0; i < fScreenPtrList.CountItems(); i++){ + Screen *screen; + screen = static_cast(fScreenPtrList.ItemAt(i)); + + screen->SetResolution(BPoint(width, height), colorspace); + } + + Screen **screens = (Screen**)fScreenPtrList.Items(); + SetScreens(screens, fRows, fColumns); + + return true; + } + + return false; +} +//--------------------------------------------------------------------------- +void RootLayer::SetWorkspaceCount(const int32 count){ + if ((count < 1 && count > 32) || count == WorkspaceCount()) + return; + + int32 exActiveWorkspaceIndex = ActiveWorkspaceIndex(); + + BList newWSPtrList; + void *workspacePtr; + + for(int i=0; i < count; i++){ + workspacePtr = fWSPtrList.ItemAt(i); + if (workspacePtr){ + newWSPtrList.AddItem(workspacePtr); + } + else{ + Workspace *ws; + ws = new Workspace(fColorSpace, i+1, BGColor()); + newWSPtrList.AddItem(ws); + } + } + + // delete other Workspace objects if WS count is smaller than current one. + for (int j=count; j < fWSPtrList.CountItems(); j++){ + Workspace *ws = NULL; + ws = static_cast(fWSPtrList.ItemAt(j)); + if (ws){ + delete ws; + } + else{ + printf("\nSERVER: PANIC: in RootLayer::SetWorkspaceCount()\n\n"); + return; + } + } + + fWSPtrList = newWSPtrList; + if (exActiveWorkspaceIndex > count) + SetActiveWorkspaceByIndex(count); + + // if true, this is the first time this method is called. + if (exActiveWorkspaceIndex == -1) + SetActiveWorkspaceByIndex(1); +} +//--------------------------------------------------------------------------- +int32 RootLayer::WorkspaceCount() const{ + return fWSPtrList.CountItems(); +} +//--------------------------------------------------------------------------- +Workspace* RootLayer::WorkspaceAt(const int32 index) const{ + Workspace *ws = NULL; + ws = static_cast(fWSPtrList.ItemAt(index-1)); + + return ws; +} +//--------------------------------------------------------------------------- +void RootLayer::SetActiveWorkspaceByIndex(const int32 index){ + Workspace *ws = NULL; + ws = static_cast(fWSPtrList.ItemAt(index-1)); + if (ws) + SetActiveWorkspace(ws); +} +//--------------------------------------------------------------------------- +void RootLayer::SetActiveWorkspace(Workspace *ws){ + if (fActiveWorkspace == ws || !ws) + return; + + fActiveWorkspace = ws; + +// RebuildRegions(Frame()); +// Invalidate(Frame()); +} +//--------------------------------------------------------------------------- +int32 RootLayer::ActiveWorkspaceIndex() const{ + if (fActiveWorkspace) + return fActiveWorkspace->ID(); + else + return -1; +} +//--------------------------------------------------------------------------- +Workspace* RootLayer::ActiveWorkspace() const{ + return fActiveWorkspace; +} +//--------------------------------------------------------------------------- +void RootLayer::SetBGColor(const RGBColor &col){ + ActiveWorkspace()->SetBGColor(col); + _layerdata->viewcolor = col; -} -/*! - \brief Returns the background color of the Screen - \return The background color -*/ -RGBColor RootLayer::GetColor(void) const -{ +// Invalidate(Frame()); +} +//--------------------------------------------------------------------------- +RGBColor RootLayer::BGColor(void) const{ return _layerdata->viewcolor; } +//--------------------------------------------------------------------------- +void RootLayer::RemoveAppWindow(WinBorder *wb){ + wb->Window()->GetApp()->GetFMWList()->RemoveItem(wb); -//! Empty function to disable moving the RootLayer -void RootLayer::MoveBy(float x, float y) -{ + int32 count = WorkspaceCount(); + for(int32 i=0; i < count; i++){ + WorkspaceAt(i+1)->RemoveLayerPtr(wb); + } } +//--------------------------------------------------------------------------- +void RootLayer::PrintToStream(){ + printf("\nRootLayer '%s' internals:\n", GetName()); + printf("Screen list:\n"); + for(int32 i=0; iScreenNumber()); + } + printf("Screen rows: %ld\nScreen columns: %ld\n", fRows, fColumns); + printf("Resolution for all Screens: %ldx%ldx%ld\n", fScreenXResolution, fScreenYResolution, fColorSpace); + printf("Workspace list:\n"); + for(int32 i=0; iID()); + ((Workspace*)fWSPtrList.ItemAt(i))->PrintToStream(); + printf("~~~~~~~~\n"); + } + printf("Active Workspace: %ld\n", fActiveWorkspace? fActiveWorkspace->ID(): -1); -//! Reimplemented for RootLayer special case -void RootLayer::ResizeBy(float x, float y) -{ - _frame.right += x; - _frame.bottom += y; - - _full.Set( _frame ); // NO ConvertTopTop !!! - - // We need to rebuild ALL regions because the screen is black now, - // and ALL views/Layers need redrawing. - RebuildRegions( _frame ); - - // Invalidate the hole screen, because we've changed resolution - // and the screen is black. - Invalidate( _frame ); -} - -/*! - \brief Assigns a particular display driver to the RootLayer - \param d The new display driver (ignored if NULL) -*/ -void RootLayer::SetDriver(DisplayDriver *driver) -{ - fDriver = driver; } diff --git a/src/servers/app/server/RootLayer.h b/src/servers/app/server/RootLayer.h index f209d81f60..7beca9285b 100644 --- a/src/servers/app/server/RootLayer.h +++ b/src/servers/app/server/RootLayer.h @@ -28,9 +28,16 @@ #ifndef _ROOTLAYER_H_ #define _ROOTLAYER_H_ -class DisplayDriver; +#include + +#include "Layer.h" +#include "FMWList.h" + class RGBColor; -//class Layer; +class Workspace; +class Screen; +class WinBorder; +class Desktop; /*! \class RootLayer RootLayer.h @@ -43,19 +50,60 @@ class RGBColor; class RootLayer : public Layer { public: - RootLayer(BRect rect, const char *layername, - DisplayDriver *gfxdriver); - virtual ~RootLayer(); + RootLayer(const char *layername, int32 workspaceCount, Desktop *desktop); + virtual ~RootLayer(); + + virtual void Draw(const BRect &r); + virtual void MoveBy(float x, float y); + virtual void ResizeBy(float x, float y); - virtual void MoveBy(float x, float y); - virtual void ResizeBy(float x, float y); + virtual Layer* VirtualTopChild() const; // + virtual Layer* VirtualLowerSibling() const; // ... for the active workspace + virtual Layer* VirtualUpperSibling() const; // + virtual Layer* VirtualBottomChild() const; // + + void AddWinBorder(WinBorder* winBorder); + void RemoveWinBorder(WinBorder* winBorder); + void ChangeWorkspacesFor(WinBorder* winBorder, uint32 newWorkspaces); + + void SetScreens(Screen *screen[], int32 rows, int32 columns); + Screen** Screens(); + bool SetScreenResolution(int32 width, int32 height, uint32 colorspace); + int32 ScreenRows() const { return fRows; } + int32 ScreenColumns() const { return fColumns; } + + void SetWorkspaceCount(const int32 count); + int32 WorkspaceCount(void) const; + Workspace* WorkspaceAt(const int32 index) const; + void SetActiveWorkspaceByIndex(const int32 index); + void SetActiveWorkspace(Workspace *ws); + int32 ActiveWorkspaceIndex(void) const; + Workspace* ActiveWorkspace(void) const; + + void SetBGColor(const RGBColor &col); + RGBColor BGColor(void) const; + + void AddWinBorderToWorkspaces(WinBorder* winBorder, uint32 wks); - void SetDriver(DisplayDriver *driver); - - void SetColor(const RGBColor &col); - RGBColor GetColor(void) const; + // ------- debugging methods ------- + void PrintToStream(); + + // "Private" to app_server :-) - they should not be used + void RemoveAppWindow(WinBorder *wb); + + FMWList fMainFMWList; private: - + Desktop *fDesktop; + + BList fScreenPtrList; + int32 fRows; + int32 fColumns; + int32 fScreenXResolution; + int32 fScreenYResolution; + uint32 fColorSpace; + + BList fWSPtrList; + Workspace *fActiveWorkspace; }; #endif diff --git a/src/servers/app/server/ServerApp.cpp b/src/servers/app/server/ServerApp.cpp index 440f0ea146..022c1c62e6 100644 --- a/src/servers/app/server/ServerApp.cpp +++ b/src/servers/app/server/ServerApp.cpp @@ -102,7 +102,9 @@ ServerApp::ServerApp(port_id sendport, port_id rcvport, int32 handlerID, char *s _appcursor=(defaultc)?new ServerCursor(defaultc):NULL; _lock=create_sem(1,"ServerApp sem"); - _driver=GetGfxDriver(ActiveScreen()); + // TODO: Fix +// _driver=GetGfxDriver(ActiveScreen()); + _cursorhidden=false; STRACE(("ServerApp %s:\n",_signature.String())); @@ -351,7 +353,9 @@ void ServerApp::_DispatchMessage(PortMessage *msg) } case AS_UPDATE_COLORS: { - ServerWindow *win; + // TODO: move message def to ServerProtocol.h to allow for + // complete build compatibility under R5 +/* ServerWindow *win; BMessage msg(_COLORS_UPDATED); for(int32 i=0; i<_winlist->CountItems(); i++) @@ -362,11 +366,14 @@ void ServerApp::_DispatchMessage(PortMessage *msg) win->SendMessageToClient(&msg); win->Unlock(); } - break; +*/ break; + } case AS_UPDATE_FONTS: { - ServerWindow *win; + // TODO: move message def to ServerProtocol.h to allow for + // complete build compatibility under R5 +/* ServerWindow *win; BMessage msg(_FONTS_UPDATED); for(int32 i=0; i<_winlist->CountItems(); i++) @@ -377,11 +384,13 @@ void ServerApp::_DispatchMessage(PortMessage *msg) win->SendMessageToClient(&msg); win->Unlock(); } - break; +*/ break; } case AS_UPDATE_DECORATOR: { - ServerWindow *win; + // TODO: move message def to ServerProtocol.h to allow for + // complete build compatibility under R5 +/* ServerWindow *win; for(int32 i=0; i<_winlist->CountItems(); i++) { @@ -390,7 +399,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg) win->_winborder->UpdateDecorator(); win->Unlock(); } - break; +*/ break; } case AS_CREATE_WINDOW: { @@ -592,8 +601,9 @@ void ServerApp::_DispatchMessage(PortMessage *msg) msg->Read(&workspace); msg->Read(&mode); msg->Read(&stick); - - SetSpace(workspace,mode,ActiveScreen(),stick); + + // TODO: Fix +// SetSpace(workspace,mode,ActiveScreen(),stick); break; } @@ -605,7 +615,9 @@ void ServerApp::_DispatchMessage(PortMessage *msg) // Error-checking is done in ActivateWorkspace, so this is a safe call int32 workspace; msg->Read(&workspace); - SetWorkspace(workspace); + + // TODO: Fix +// SetWorkspace(workspace); break; } @@ -723,7 +735,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg) { // Attached data: // 1) port_id reply port - synchronous message - scroll_bar_info sbi=GetScrollBarInfo(); + scroll_bar_info sbi=desktop->ScrollBarInfo(); port_id replyport; msg->Read(&replyport); @@ -739,7 +751,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg) // 1) scroll_bar_info scroll bar info structure scroll_bar_info sbi; msg->Read(&sbi); - SetScrollBarInfo(sbi); + desktop->SetScrollBarInfo(sbi); break; } case AS_FOCUS_FOLLOWS_MOUSE: @@ -751,7 +763,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg) msg->Read(&replyport); PortLink link(replyport); - link.Attach(GetFFMouse()); + link.Attach(desktop->FFMouseInUse()); link.Flush(); break; } @@ -761,7 +773,7 @@ void ServerApp::_DispatchMessage(PortMessage *msg) // 1) scroll_bar_info scroll bar info structure scroll_bar_info sbi; msg->Read(&sbi); - SetScrollBarInfo(sbi); + desktop->SetScrollBarInfo(sbi); break; } case AS_SET_MOUSE_MODE: @@ -770,14 +782,14 @@ void ServerApp::_DispatchMessage(PortMessage *msg) // 1) enum mode_mouse FFM mouse mode mode_mouse mmode; msg->Read(&mmode); - SetFFMouseMode(mmode); + desktop->SetFFMouseMode(mmode); break; } case AS_GET_MOUSE_MODE: { // Attached data: // 1) port_id reply port - synchronous message - mode_mouse mmode=GetFFMouseMode(); + mode_mouse mmode=desktop->FFMouseMode(); port_id replyport; msg->Read(&replyport); diff --git a/src/servers/app/server/ServerApp.h b/src/servers/app/server/ServerApp.h index d06bbc6e12..c094a6553b 100644 --- a/src/servers/app/server/ServerApp.h +++ b/src/servers/app/server/ServerApp.h @@ -29,6 +29,8 @@ #include #include +#include +#include "FMWList.h" class AppServer; class BMessage; @@ -38,6 +40,22 @@ class BList; class DisplayDriver; class ServerCursor; + +/* +class ServerApp{ +public: + ServerApp(team_id clientTeamID){ + fClientTeamID = clientTeamID; + } + virtual ~ServerApp(){ } + team_id ClientTeamID(){ return fClientTeamID; } + + FMWList fAppFMWList; +private: + team_id fClientTeamID; +}; +*/ + /*! \class ServerApp ServerApp.h \brief Counterpart to BApplication within the app_server @@ -66,6 +84,8 @@ public: void PostMessage(int32 code, size_t size=0, int8 *buffer=NULL); void SetAppCursor(void); + FMWList *GetFMWList(void) { return &fAppFMWList; } + protected: friend class AppServer; friend class ServerWindow; @@ -84,6 +104,7 @@ protected: bool _cursorhidden; bool _isactive; int32 _handlertoken; + FMWList fAppFMWList; }; #endif diff --git a/src/servers/app/server/ServerScreen.cpp b/src/servers/app/server/ServerScreen.cpp new file mode 100644 index 0000000000..a9460b6ec3 --- /dev/null +++ b/src/servers/app/server/ServerScreen.cpp @@ -0,0 +1,72 @@ + +#include +#include +#include +#include + +#include "ServerScreen.h" +#include "DisplayDriver.h" + +Screen::Screen(DisplayDriver *dDriver, BPoint res, uint32 colorspace, + const int32 &ID) +{ + fID = ID; + fDriver = dDriver; + SetResolution(res, colorspace); +} + +Screen::Screen(void) +{ +} + +Screen::~Screen(void){ +//printf("~Screen( %ld )\n", fID); +} + +bool Screen::SupportsResolution(const BPoint &res, const uint32 &colorspace) +{ + display_mode *dm=NULL; + uint32 count; + + fDriver->GetModeList(&dm, &count); + + for (uint32 i=0; i < count; i++) + { + if (dm[i].virtual_width == (uint16)res.x && + dm[i].virtual_height == (uint16)res.y && + dm[i].space == colorspace) + return true; + } + + delete dm; + return false; +} + +bool Screen::SetResolution(const BPoint &res, const uint32 &colorspace) +{ + if (!SupportsResolution(res, colorspace)) + return false; + + display_mode mode; + + mode.virtual_width = (uint16)res.x; + mode.virtual_height = (uint16)res.y; + mode.space = colorspace; + + fDriver->SetMode(mode); + + return true; +} + +BPoint Screen::Resolution() const{ + display_mode mode; + + fDriver->GetMode(&mode); + + return BPoint(mode.virtual_width, mode.virtual_height); +} + +int32 Screen::ScreenNumber(void) const{ + return fID; +} + diff --git a/src/servers/app/server/ServerScreen.h b/src/servers/app/server/ServerScreen.h new file mode 100644 index 0000000000..49724d0a21 --- /dev/null +++ b/src/servers/app/server/ServerScreen.h @@ -0,0 +1,30 @@ +#ifndef _SERVERSCREEN_H_ +#define _SERVERSCREEN_H_ + +#include +#include "DisplayDriver.h" + +class Screen{ +public: + Screen(DisplayDriver *dDriver, BPoint res, uint32 colorspace, const int32 &ID); + Screen(void); + ~Screen(void); + + void SetID(int32 ID){ fID = ID; } + + // TODO: get/set prototype methods for graphic card features + bool SupportsResolution(const BPoint &res, const uint32 &colorspace); + bool SetResolution(const BPoint &res, const uint32 &colorspace); + BPoint Resolution() const; + + int32 ScreenNumber(void) const; + DisplayDriver* GetDriver(void) const { return fDriver; } + +private: + + // TODO: add members in which we should store data. + int32 fID; + DisplayDriver *fDriver; +}; + +#endif diff --git a/src/servers/app/server/ServerWindow.cpp b/src/servers/app/server/ServerWindow.cpp index 610aadffcc..8488b90f44 100644 --- a/src/servers/app/server/ServerWindow.cpp +++ b/src/servers/app/server/ServerWindow.cpp @@ -41,7 +41,7 @@ #include "ServerProtocol.h" #include "WinBorder.h" #include "Desktop.h" -#include "DesktopClasses.h" +#include "Workspace.h" #include "TokenHandler.h" #include "Utils.h" #include "DisplayDriver.h" @@ -131,7 +131,7 @@ ServerWindow::ServerWindow(BRect rect, const char *string, uint32 wlook, _feel = wfeel; _handlertoken = handlerID; winLooperPort = looperPort; - _workspace_index= index; + _workspaces = index; _workspace = NULL; _token = win_token_handler.GetToken(); @@ -177,7 +177,7 @@ ServerWindow::ServerWindow(BRect rect, const char *string, uint32 wlook, top_layer= new Layer(vFrame, vName, vToken, vResizeMode, vFlags, this); delete vName; - cl = top_layer; + currentlayer = top_layer; // Create a WindoBorder object for our ServerWindow. @@ -191,7 +191,7 @@ ServerWindow::ServerWindow(BRect rect, const char *string, uint32 wlook, // Add window to desktop structure. - AddWindowToDesktop(this,index,ActiveScreen()); + desktop->AddWinBorder(_winborder); STRACE(("ServerWindow %s:\n",_title->String())); STRACE(("\tFrame (%.1f,%.1f,%.1f,%.1f)\n",rect.left,rect.top,rect.right,rect.bottom)); @@ -203,7 +203,8 @@ ServerWindow::ServerWindow(BRect rect, const char *string, uint32 wlook, ServerWindow::~ServerWindow(void) { STRACE(("ServerWindow %s:~ServerWindow()\n",_title->String())); - RemoveWindowFromDesktop(this); + desktop->RemoveWinBorder(_winborder); + if(_applink) { delete _applink; @@ -212,7 +213,7 @@ STRACE(("ServerWindow %s:~ServerWindow()\n",_title->String())); delete _winlink; delete _winborder; - cl = NULL; + currentlayer = NULL; if (top_layer) delete top_layer; } @@ -340,6 +341,30 @@ void ServerWindow::Zoom(){ // TODO: implement; } +void ServerWindow::SetLook(int32 look) +{ + // TODO: Finish + _look=look; +} + +void ServerWindow::SetFeel(int32 feel) +{ + // TODO: Finish + _feel=feel; +} + +void ServerWindow::SetFlags(int32 flags) +{ + // TODO: Finish + _flags=flags; +} + +void ServerWindow::SetWorkspaces(int32 workspaces) +{ + // TODO: Finish + _workspaces=workspaces; +} + /*! \brief Handles focus and redrawing when changing focus states @@ -490,11 +515,11 @@ void ServerWindow::DispatchMessage(PortMessage msg) Layer *current = FindLayer(top_layer, token); if (current) - cl = current; + currentlayer = current; else // hope this NEVER happens! :-) debugger("Server PANIC: window cannot find Layer with ID\n"); - STRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: Layer name: %s\n", _title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_SET_CURRENT_LAYER: Layer name: %s\n", _title->String(), currentlayer->_name->String())); break; } case AS_LAYER_CREATE: @@ -507,7 +532,7 @@ TODO: Figure out what Adi did here and convert to PortMessages // the area in which the new layer resides assuming that it is // visible. STRACE(("ServerWindow %s: AS_LAYER_CREATE...\n", _title->String())); - Layer *oldCL = cl; + Layer *oldCL = currentlayer; int32 token; BRect frame; @@ -532,7 +557,7 @@ TODO: Figure out what Adi did here and convert to PortMessages newLayer->_hidden = hidden; // we set Layer's attributes (BView's state) - cl = newLayer; + currentlayer = newLayer; int32 msgCode; msg.Read(&msgCode); // this is AS_LAYER_SET_FONT_STATE @@ -550,9 +575,9 @@ TODO: Figure out what Adi did here and convert to PortMessages DispatchMessage(msgCode); } - cl = oldCL; + currentlayer = oldCL; - STRACE(("DONE: ServerWindow %s: Message AS_CREATE_LAYER: Parent: %s, Child: %s\n", _title->String(), cl->_name->String(), name)); + STRACE(("DONE: ServerWindow %s: Message AS_CREATE_LAYER: Parent: %s, Child: %s\n", _title->String(), currentlayer->_name->String(), name)); */ break; } @@ -564,20 +589,20 @@ TODO: Figure out what Adi did here and convert to PortMessages // area assuming that the view was visible when removed STRACE(("SW %s: AS_LAYER_DELETE(self)...\n", _title->String())); Layer *parent; - parent = cl->_parent; + parent = currentlayer->_parent; // here we remove current layer from list. - cl->RemoveSelf(); + currentlayer->RemoveSelf(); // TODO: invalidate the region occupied by this view. // Should be done in Layer::RemoveChild() though! - cl->PruneTree(); + currentlayer->PruneTree(); parent->PrintTree(); - STRACE(("DONE: ServerWindow %s: Message AS_DELETE_LAYER: Parent: %s Layer: %s\n", _title->String(), parent->_name->String(), cl->_name->String())); + STRACE(("DONE: ServerWindow %s: Message AS_DELETE_LAYER: Parent: %s Layer: %s\n", _title->String(), parent->_name->String(), currentlayer->_name->String())); - delete cl; + delete currentlayer; - cl = parent; + currentlayer = parent; break; } case AS_LAYER_SET_STATE: @@ -588,53 +613,53 @@ TODO: Figure out what Adi did here and convert to PortMessages pattern patt; int32 clippRegRects; - msg.Read(&(cl->_layerdata->penlocation)); - msg.Read(&(cl->_layerdata->pensize)); + msg.Read(&(currentlayer->_layerdata->penlocation)); + msg.Read(&(currentlayer->_layerdata->pensize)); msg.Read(&highColor); msg.Read(&lowColor); msg.Read(&viewColor); msg.Read(&patt); - msg.Read((int8*)&(cl->_layerdata->draw_mode)); - msg.Read(&(cl->_layerdata->coordOrigin)); - msg.Read((int8*)&(cl->_layerdata->lineJoin)); - msg.Read((int8*)&(cl->_layerdata->lineCap)); - msg.Read(&(cl->_layerdata->miterLimit)); - msg.Read((int8*)&(cl->_layerdata->alphaSrcMode)); - msg.Read((int8*)&(cl->_layerdata->alphaFncMode)); - msg.Read(&(cl->_layerdata->scale)); - msg.Read(&(cl->_layerdata->fontAliasing)); + msg.Read((int8*)&(currentlayer->_layerdata->draw_mode)); + msg.Read(&(currentlayer->_layerdata->coordOrigin)); + msg.Read((int8*)&(currentlayer->_layerdata->lineJoin)); + msg.Read((int8*)&(currentlayer->_layerdata->lineCap)); + msg.Read(&(currentlayer->_layerdata->miterLimit)); + msg.Read((int8*)&(currentlayer->_layerdata->alphaSrcMode)); + msg.Read((int8*)&(currentlayer->_layerdata->alphaFncMode)); + msg.Read(&(currentlayer->_layerdata->scale)); + msg.Read(&(currentlayer->_layerdata->fontAliasing)); msg.Read(&clippRegRects); - cl->_layerdata->patt.Set(*((uint64*)&patt)); - cl->_layerdata->highcolor.SetColor(highColor); - cl->_layerdata->lowcolor.SetColor(lowColor); - cl->_layerdata->viewcolor.SetColor(viewColor); + currentlayer->_layerdata->patt.Set(*((uint64*)&patt)); + currentlayer->_layerdata->highcolor.SetColor(highColor); + currentlayer->_layerdata->lowcolor.SetColor(lowColor); + currentlayer->_layerdata->viewcolor.SetColor(viewColor); if(clippRegRects != 0){ - if(cl->_layerdata->clippReg == NULL) - cl->_layerdata->clippReg = new BRegion(); + if(currentlayer->_layerdata->clippReg == NULL) + currentlayer->_layerdata->clippReg = new BRegion(); else - cl->_layerdata->clippReg->MakeEmpty(); + currentlayer->_layerdata->clippReg->MakeEmpty(); BRect rect; for(int32 i = 0; i < clippRegRects; i++){ msg.Read(&rect); - cl->_layerdata->clippReg->Include(rect); + currentlayer->_layerdata->clippReg->Include(rect); } - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); } else{ - if (cl->_layerdata->clippReg){ - delete cl->_layerdata->clippReg; - cl->_layerdata->clippReg = NULL; + if (currentlayer->_layerdata->clippReg){ + delete currentlayer->_layerdata->clippReg; + currentlayer->_layerdata->clippReg = NULL; - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); } } - STRACE(("ServerWindow %s: Message AS_LAYER_SET_STATE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_STATE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_FONT_STATE: @@ -648,52 +673,52 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read((int32*)&fontID); // TODO: implement later. Currently there is no SetFamAndStyle(uint32) // in ServerFont class. DW, could you add one? - //cl->_layerdata->font-> + //currentlayer->_layerdata->font-> } if (mask & B_FONT_SIZE){ float size; msg.Read(&size); - cl->_layerdata->font.SetSize(size); + currentlayer->_layerdata->font.SetSize(size); } if (mask & B_FONT_SHEAR){ float shear; msg.Read(&shear); - cl->_layerdata->font.SetShear(shear); + currentlayer->_layerdata->font.SetShear(shear); } if (mask & B_FONT_ROTATION){ float rotation; msg.Read(&rotation); - cl->_layerdata->font.SetRotation(rotation); + currentlayer->_layerdata->font.SetRotation(rotation); } if (mask & B_FONT_SPACING){ uint8 spacing; msg.Read(&spacing); // uint8 - cl->_layerdata->font.SetSpacing(spacing); + currentlayer->_layerdata->font.SetSpacing(spacing); } if (mask & B_FONT_ENCODING){ uint8 encoding; msg.Read((int8*)&encoding); // uint8 - cl->_layerdata->font.SetEncoding(encoding); + currentlayer->_layerdata->font.SetEncoding(encoding); } if (mask & B_FONT_FACE){ uint16 face; msg.Read(&face); // uint16 - cl->_layerdata->font.SetFace(face); + currentlayer->_layerdata->font.SetFace(face); } if (mask & B_FONT_FLAGS){ uint32 flags; msg.Read(&flags); // uint32 - cl->_layerdata->font.SetFlags(flags); + currentlayer->_layerdata->font.SetFlags(flags); } - STRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_FONT_STATE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_STATE: @@ -703,7 +728,7 @@ TODO: Figure out what Adi did here and convert to PortMessages rgb_color hc, lc, vc; // high, low and view colors uint64 patt; // current pattern as a uint64 - ld = cl->_layerdata; // now we write fewer characters. :-) + ld = currentlayer->_layerdata; // now we write fewer characters. :-) hc = ld->highcolor.GetColor32(); lc = ld->lowcolor.GetColor32(); vc = ld->viewcolor.GetColor32(); @@ -746,12 +771,12 @@ TODO: Figure out what Adi did here and convert to PortMessages _winlink->Attach(ld->clippReg->RectAt(i)); } - _winlink->Attach(cl->_frame.left); - _winlink->Attach(cl->_frame.top); - _winlink->Attach(cl->_frame.OffsetToCopy(cl->_boundsLeftTop)); + _winlink->Attach(currentlayer->_frame.left); + _winlink->Attach(currentlayer->_frame.top); + _winlink->Attach(currentlayer->_frame.OffsetToCopy(currentlayer->_boundsLeftTop)); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_STATE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_STATE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_MOVETO: @@ -761,9 +786,9 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&x); msg.Read(&y); - cl->MoveBy(x, y); + currentlayer->MoveBy(x, y); - STRACE(("ServerWindow %s: Message AS_LAYER_MOVETO: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_MOVETO: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_RESIZETO: @@ -775,19 +800,19 @@ TODO: Figure out what Adi did here and convert to PortMessages /* TODO: check for minimum alowed. WinBorder should provide such * a method, based on its decorator. */ - cl->ResizeBy(newWidth, newHeight); + currentlayer->ResizeBy(newWidth, newHeight); - STRACE(("ServerWindow %s: Message AS_LAYER_RESIZETO: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_RESIZETO: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_COORD: { - _winlink->Attach(cl->_frame.left); - _winlink->Attach(cl->_frame.top); - _winlink->Attach(cl->_frame.OffsetToCopy(cl->_boundsLeftTop)); + _winlink->Attach(currentlayer->_frame.left); + _winlink->Attach(currentlayer->_frame.top); + _winlink->Attach(currentlayer->_frame.OffsetToCopy(currentlayer->_boundsLeftTop)); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_COORD: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_COORD: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_ORIGIN: @@ -797,24 +822,24 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&x); msg.Read(&y); - cl->_layerdata->coordOrigin.Set(x, y); + currentlayer->_layerdata->coordOrigin.Set(x, y); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_ORIGIN: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_ORIGIN: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_ORIGIN: { - _winlink->Attach(cl->_layerdata->coordOrigin); + _winlink->Attach(currentlayer->_layerdata->coordOrigin); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_ORIGIN: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_ORIGIN: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_RESIZE_MODE: { - msg.Read(&(cl->_resize_mode)); + msg.Read(&(currentlayer->_resize_mode)); - STRACE(("ServerWindow %s: Message AS_LAYER_RESIZE_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_RESIZE_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_CURSOR: @@ -825,28 +850,28 @@ TODO: Figure out what Adi did here and convert to PortMessages cursormanager->SetCursor(token); - STRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_FLAGS: { - msg.Read(&(cl->_flags)); + msg.Read(&(currentlayer->_flags)); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_FLAGS: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_HIDE: { - cl->Hide(); + currentlayer->Hide(); - STRACE(("ServerWindow %s: Message AS_LAYER_HIDE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_HIDE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SHOW: { - cl->Show(); + currentlayer->Show(); - STRACE(("ServerWindow %s: Message AS_LAYER_SHOW: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SHOW: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_LINE_MODE: @@ -859,61 +884,61 @@ TODO: Figure out what Adi did here and convert to PortMessages */ msg.Read(&lineCap); msg.Read(&lineJoin); - msg.Read(&(cl->_layerdata->miterLimit)); + msg.Read(&(currentlayer->_layerdata->miterLimit)); - cl->_layerdata->lineCap = (cap_mode)lineCap; - cl->_layerdata->lineJoin = (join_mode)lineJoin; + currentlayer->_layerdata->lineCap = (cap_mode)lineCap; + currentlayer->_layerdata->lineJoin = (join_mode)lineJoin; - STRACE(("ServerWindow %s: Message AS_LAYER_SET_LINE_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_LINE_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_LINE_MODE: { - _winlink->Attach((int8)(cl->_layerdata->lineCap)); - _winlink->Attach((int8)(cl->_layerdata->lineJoin)); - _winlink->Attach(cl->_layerdata->miterLimit); + _winlink->Attach((int8)(currentlayer->_layerdata->lineCap)); + _winlink->Attach((int8)(currentlayer->_layerdata->lineJoin)); + _winlink->Attach(currentlayer->_layerdata->miterLimit); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_LINE_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_LINE_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_PUSH_STATE: { LayerData *ld = new LayerData(); - ld->prevState = cl->_layerdata; - cl->_layerdata = ld; + ld->prevState = currentlayer->_layerdata; + currentlayer->_layerdata = ld; - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); - STRACE(("ServerWindow %s: Message AS_LAYER_PUSH_STATE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_PUSH_STATE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_POP_STATE: { - if (!(cl->_layerdata->prevState)) { - STRACE(("WARNING: SW(%s): User called BView(%s)::PopState(), but there is NO state on stack!\n", _title->String(), cl->_name->String())); + if (!(currentlayer->_layerdata->prevState)) { + STRACE(("WARNING: SW(%s): User called BView(%s)::PopState(), but there is NO state on stack!\n", _title->String(), currentlayer->_name->String())); break; } - LayerData *ld = cl->_layerdata; - cl->_layerdata = cl->_layerdata->prevState; + LayerData *ld = currentlayer->_layerdata; + currentlayer->_layerdata = currentlayer->_layerdata->prevState; delete ld; - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); - STRACE(("ServerWindow %s: Message AS_LAYER_POP_STATE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_POP_STATE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_SCALE: { - msg.Read(&(cl->_layerdata->scale)); + msg.Read(&(currentlayer->_layerdata->scale)); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_SCALE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_SCALE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_SCALE: { - LayerData *ld = cl->_layerdata; + LayerData *ld = currentlayer->_layerdata; float scale = ld->scale; while((ld = ld->prevState)) @@ -922,7 +947,7 @@ TODO: Figure out what Adi did here and convert to PortMessages _winlink->Attach(scale); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_SCALE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_SCALE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_PEN_LOC: @@ -932,32 +957,32 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&x); msg.Read(&y); - cl->_layerdata->penlocation.Set(x, y); + currentlayer->_layerdata->penlocation.Set(x, y); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_LOC: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_LOC: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_PEN_LOC: { - _winlink->Attach(cl->_layerdata->penlocation); + _winlink->Attach(currentlayer->_layerdata->penlocation); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_LOC: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_LOC: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_PEN_SIZE: { - msg.Read(&(cl->_layerdata->pensize)); + msg.Read(&(currentlayer->_layerdata->pensize)); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_SIZE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_PEN_SIZE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_PEN_SIZE: { - _winlink->Attach(cl->_layerdata->pensize); + _winlink->Attach(currentlayer->_layerdata->pensize); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_SIZE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_PEN_SIZE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_HIGH_COLOR: @@ -966,9 +991,9 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&c); - cl->_layerdata->highcolor.SetColor(c); + currentlayer->_layerdata->highcolor.SetColor(c); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_HIGH_COLOR: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_HIGH_COLOR: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_LOW_COLOR: @@ -977,9 +1002,9 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&c); - cl->_layerdata->lowcolor.SetColor(c); + currentlayer->_layerdata->lowcolor.SetColor(c); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_LOW_COLOR: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_LOW_COLOR: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_VIEW_COLOR: @@ -988,25 +1013,25 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&c); - cl->_layerdata->viewcolor.SetColor(c); + currentlayer->_layerdata->viewcolor.SetColor(c); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_VIEW_COLOR: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_VIEW_COLOR: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_COLORS: { rgb_color highColor, lowColor, viewColor; - highColor = cl->_layerdata->highcolor.GetColor32(); - lowColor = cl->_layerdata->lowcolor.GetColor32(); - viewColor = cl->_layerdata->viewcolor.GetColor32(); + highColor = currentlayer->_layerdata->highcolor.GetColor32(); + lowColor = currentlayer->_layerdata->lowcolor.GetColor32(); + viewColor = currentlayer->_layerdata->viewcolor.GetColor32(); _winlink->Attach(highColor); _winlink->Attach(lowColor); _winlink->Attach(viewColor); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_COLORS: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_COLORS: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_BLEND_MODE: @@ -1016,19 +1041,19 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&srcAlpha); msg.Read(&alphaFunc); - cl->_layerdata->alphaSrcMode = (source_alpha)srcAlpha; - cl->_layerdata->alphaFncMode = (alpha_function)alphaFunc; + currentlayer->_layerdata->alphaSrcMode = (source_alpha)srcAlpha; + currentlayer->_layerdata->alphaFncMode = (alpha_function)alphaFunc; - STRACE(("ServerWindow %s: Message AS_LAYER_SET_BLEND_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_BLEND_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_BLEND_MODE: { - _winlink->Attach((int8)(cl->_layerdata->alphaSrcMode)); - _winlink->Attach((int8)(cl->_layerdata->alphaFncMode)); + _winlink->Attach((int8)(currentlayer->_layerdata->alphaSrcMode)); + _winlink->Attach((int8)(currentlayer->_layerdata->alphaFncMode)); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_BLEND_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_BLEND_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_DRAW_MODE: @@ -1037,24 +1062,24 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&drawingMode); - cl->_layerdata->draw_mode = (drawing_mode)drawingMode; + currentlayer->_layerdata->draw_mode = (drawing_mode)drawingMode; - STRACE(("ServerWindow %s: Message AS_LAYER_SET_DRAW_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_DRAW_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_DRAW_MODE: { - _winlink->Attach((int8)(cl->_layerdata->draw_mode)); + _winlink->Attach((int8)(currentlayer->_layerdata->draw_mode)); _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_DRAW_MODE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_DRAW_MODE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_PRINT_ALIASING: { - msg.Read(&(cl->_layerdata->fontAliasing)); + msg.Read(&(currentlayer->_layerdata->fontAliasing)); - STRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_PRINT_ALIASING: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_CLIP_TO_PICTURE: @@ -1072,8 +1097,8 @@ TODO: Figure out what Adi did here and convert to PortMessages // if we had a picture to clip to, include the FULL visible region(if any) in the area to be redrawn // in other words: invalidate what ever is visible for this layer and his children. - if (cl->clipToPicture && cl->_fullVisible.CountRects() > 0){ - reg.Include(&cl->_fullVisible); + if (currentlayer->clipToPicture && currentlayer->_fullVisible.CountRects() > 0){ + reg.Include(¤tlayer->_fullVisible); redraw = true; } @@ -1081,12 +1106,12 @@ TODO: Figure out what Adi did here and convert to PortMessages ServerPicture *sp = NULL; int32 i = 0; for(;;){ - sp = static_cast(cl->_serverwin->_app->_piclist->ItemAt(i++)); + sp = static_cast(currentlayer->_serverwin->_app->_piclist->ItemAt(i++)); if (!sp) break; if(sp->GetToken() == pictureToken){ -// cl->clipToPicture = sp; +// currentlayer->clipToPicture = sp; // TODO: increase that picture's reference count.(~ allocate a picture) break; } @@ -1095,34 +1120,34 @@ TODO: Figure out what Adi did here and convert to PortMessages i = 0; // we have a new picture to clip to, so rebuild our full region - if(cl->clipToPicture) { + if(currentlayer->clipToPicture) { - cl->clipToPictureInverse = false; + currentlayer->clipToPictureInverse = false; - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); } // we need to rebuild the visible region, we may have a valid one. - if (cl->_parent && !(cl->_hidden)){ - cl->_parent->RebuildChildRegions(cl->_full.Frame(), cl); + if (currentlayer->_parent && !(currentlayer->_hidden)){ + currentlayer->_parent->RebuildChildRegions(currentlayer->_full.Frame(), currentlayer); } else{ // will this happen? Maybe... - cl->RebuildRegions(cl->_full.Frame()); + currentlayer->RebuildRegions(currentlayer->_full.Frame()); } // include our full visible region in the region to be redrawn - if (!(cl->_hidden) && (cl->_fullVisible.CountRects() > 0)){ - reg.Include(&(cl->_fullVisible)); + if (!(currentlayer->_hidden) && (currentlayer->_fullVisible.CountRects() > 0)){ + reg.Include(&(currentlayer->_fullVisible)); redraw = true; } // redraw if: we had OR if we NOW have a picture to clip to. if (redraw){ - cl->Invalidate(reg); + currentlayer->Invalidate(reg); } - STRACE(("ServerWindow %s: Message AS_LAYER_CLIP_TO_PICTURE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_CLIP_TO_PICTURE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_CLIP_TO_INVERSE_PICTURE: @@ -1138,12 +1163,12 @@ TODO: Figure out what Adi did here and convert to PortMessages int32 i = 0; for(;;){ - sp = static_cast(cl->_serverwin->_app->_piclist->ItemAt(i++)); + sp = static_cast(currentlayer->_serverwin->_app->_piclist->ItemAt(i++)); if (!sp) break; if(sp->GetToken() == pictureToken){ -// cl->clipToPicture = sp; +// currentlayer->clipToPicture = sp; // TODO: increase that picture's reference count.(~ allocate a picture) break; } @@ -1152,16 +1177,16 @@ TODO: Figure out what Adi did here and convert to PortMessages i = 0; // if a picture has been found... - if(cl->clipToPicture) { + if(currentlayer->clipToPicture) { - cl->clipToPictureInverse = true; + currentlayer->clipToPictureInverse = true; - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); - cl->RequestDraw(cl->clipToPicture->Frame()); + currentlayer->RequestDraw(currentlayer->clipToPicture->Frame()); } - STRACE(("ServerWindow %s: Message AS_LAYER_CLIP_TO_INVERSE_PICTURE: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_CLIP_TO_INVERSE_PICTURE: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_GET_CLIP_REGION: @@ -1171,8 +1196,8 @@ TODO: Figure out what Adi did here and convert to PortMessages LayerData *ld; int32 noOfRects; - ld = cl->_layerdata; - reg = cl->ConvertFromParent(&(cl->_visible)); + ld = currentlayer->_layerdata; + reg = currentlayer->ConvertFromParent(&(currentlayer->_visible)); if(ld->clippReg) reg.IntersectWith(ld->clippReg); @@ -1190,7 +1215,7 @@ TODO: Figure out what Adi did here and convert to PortMessages _winlink->Flush(); - STRACE(("ServerWindow %s: Message AS_LAYER_GET_CLIP_REGION: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_GET_CLIP_REGION: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_SET_CLIP_REGION: @@ -1199,23 +1224,23 @@ TODO: Figure out what Adi did here and convert to PortMessages int32 noOfRects; BRect r; - if(cl->_layerdata->clippReg) - cl->_layerdata->clippReg->MakeEmpty(); + if(currentlayer->_layerdata->clippReg) + currentlayer->_layerdata->clippReg->MakeEmpty(); else - cl->_layerdata->clippReg = new BRegion(); + currentlayer->_layerdata->clippReg = new BRegion(); msg.Read(&noOfRects); for(int i = 0; i < noOfRects; i++){ msg.Read(&r); - cl->_layerdata->clippReg->Include(r); + currentlayer->_layerdata->clippReg->Include(r); } - cl->RebuildFullRegion(); + currentlayer->RebuildFullRegion(); - cl->RequestDraw(cl->clipToPicture->Frame()); + currentlayer->RequestDraw(currentlayer->clipToPicture->Frame()); - STRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_CLIP_REGION: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } @@ -1226,11 +1251,11 @@ TODO: Figure out what Adi did here and convert to PortMessages msg.Read(&invalRect); - cl->Invalidate(invalRect); + currentlayer->Invalidate(invalRect); - cl->RequestDraw(invalRect); + currentlayer->RequestDraw(invalRect); - STRACE(("ServerWindow %s: Message AS_LAYER_INVAL_RECT: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_INVAL_RECT: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } case AS_LAYER_INVAL_REGION: @@ -1247,11 +1272,11 @@ TODO: Figure out what Adi did here and convert to PortMessages invalReg.Include(rect); } - cl->Invalidate(invalReg); + currentlayer->Invalidate(invalReg); - cl->RequestDraw(invalReg.Frame()); + currentlayer->RequestDraw(invalReg.Frame()); - STRACE(("ServerWindow %s: Message AS_LAYER_INVAL_RECT: Layer: %s\n",_title->String(), cl->_name->String())); + STRACE(("ServerWindow %s: Message AS_LAYER_INVAL_RECT: Layer: %s\n",_title->String(), currentlayer->_name->String())); break; } @@ -1448,7 +1473,7 @@ void ServerWindow::DispatchGraphicsMessage(int32 msgsize, int8 *msgbuffer) { code = read_from_buffer(&msgbuffer); view_token = read_from_buffer(&msgbuffer); - layer = _workspace->GetRoot()->FindLayer(view_token); + layer = desktop->ActiveRootLayer()->FindLayer(view_token); if (layer) { layerdata = layer->GetLayerData(); @@ -2002,7 +2027,7 @@ int32 ServerWindow::MonitorWin(void *data) //void ServerWindow::HandleMouseEvent(int32 code, int8 *buffer) void ServerWindow::HandleMouseEvent(PortMessage *msg) { - ServerWindow *mousewin=NULL; +/* ServerWindow *mousewin=NULL; // int8 *index=buffer; // Find the window which will receive our mouse event. @@ -2072,10 +2097,10 @@ void ServerWindow::HandleMouseEvent(PortMessage *msg) msg->Read(&y); BPoint pt(x,y); -/* set_is_sliding_tab(false); - set_is_moving_window(false); - set_is_resizing_window(false); -*/ _winborder = WindowContainsPoint(pt); +// set_is_sliding_tab(false); +// set_is_moving_window(false); +// set_is_resizing_window(false); + _winborder = WindowContainsPoint(pt); active_winborder=NULL; if(_winborder) { @@ -2104,28 +2129,29 @@ void ServerWindow::HandleMouseEvent(PortMessage *msg) msg->Read(&dummy); msg->Read(&x); msg->Read(&y); -/* BPoint pt(x,y); - - if(is_moving_window() || is_resizing_window() || is_sliding_tab()) - { - active_winborder->MouseMoved((int8*)msg->Buffer()); - } - else - { - _winborder = WindowContainsPoint(pt); - if(_winborder) - { - mousewin=_winborder->Window(); - _winborder->MouseMoved((int8*)msg->Buffer()); - } - } -*/ break; +// BPoint pt(x,y); +// +// if(is_moving_window() || is_resizing_window() || is_sliding_tab()) +// { +// active_winborder->MouseMoved((int8*)msg->Buffer()); +// } +// else +// { +// _winborder = WindowContainsPoint(pt); +// if(_winborder) +// { +// mousewin=_winborder->Window(); +// _winborder->MouseMoved((int8*)msg->Buffer()); +// } +// } + break; } default: { break; } } +*/ } /*! @@ -2155,13 +2181,18 @@ STRACE_KEY(("ServerWindow::HandleKeyEvent unimplemented\n")); If the window belongs to all workspaces, it returns the current workspace */ +/* Workspace *ServerWindow::GetWorkspace(void) { if(_workspace_index==B_ALL_WORKSPACES) + { return _workspace->GetScreen()->GetActiveWorkspace(); + + } return _workspace; } +*/ /*! \brief Assign the window to a particular workspace object diff --git a/src/servers/app/server/ServerWindow.h b/src/servers/app/server/ServerWindow.h index 0d92938163..079fcfd051 100644 --- a/src/servers/app/server/ServerWindow.h +++ b/src/servers/app/server/ServerWindow.h @@ -35,6 +35,7 @@ #include #include #include +#include "FMWList.h" class BString; class BMessenger; @@ -64,55 +65,68 @@ class Layer; class ServerWindow { public: - ServerWindow(BRect rect, const char *string, - uint32 wlook, uint32 wfeel, uint32 wflags, - ServerApp *winapp, port_id winport, - port_id looperPort, port_id replyport, uint32 index, - int32 handlerID); - ~ServerWindow(void); + ServerWindow(BRect rect, const char *string, uint32 wlook, uint32 wfeel, + uint32 wflags, ServerApp *winapp, port_id winport, + port_id looperPort, port_id replyport, uint32 index,int32 handlerID); + ~ServerWindow(void); - void ReplaceDecorator(void); - void Quit(void); - const char* GetTitle(void); - ServerApp* GetApp(void); - void Show(void); - void Hide(void); - bool IsHidden(void); - void Minimize(bool status); - void Zoom(void); - void SetFocus(bool value); - bool HasFocus(void); - void RequestDraw(BRect rect); - void RequestDraw(void); - - void WorkspaceActivated(int32 workspace, bool active); - void WorkspacesChanged(int32 oldone,int32 newone); - void WindowActivated(bool active); - void ScreenModeChanged(const BRect frame, const color_space cspace); - - void SetFrame(const BRect &rect); - BRect Frame(void); - - status_t Lock(void); - void Unlock(void); - bool IsLocked(void); - - void DispatchMessage(PortMessage msg); - void DispatchGraphicsMessage(int32 msgsize, int8 *msgbuffer); - static int32 MonitorWin(void *data); - static void HandleMouseEvent(PortMessage *msg); - static void HandleKeyEvent(int32 code, int8 *buffer); - - //! Returns the index of the workspaces to which it belongs - int32 GetWorkspaceIndex(void) { return _workspace_index; } - Workspace* GetWorkspace(void); - void SetWorkspace(Workspace *wkspc); + void ReplaceDecorator(void); + void Quit(void); - //! Returns the window's title - const char* Title(void) { return _title->String(); } + const char *GetTitle(void); + ServerApp *GetApp(void); + int32 GetLook(void) const { return _look; } + int32 GetFeel(void) const { return _feel; } + int32 GetFlags(void) const { return _flags; } + int32 GetHandlerID(void) const { return _handlertoken; } + //! Returns the index of the workspaces to which it belongs + uint32 GetWorkspaces(void) const { return _workspaces; } - Layer* FindLayer(const Layer* start, int32 token) const; - void SendMessageToClient( const BMessage* msg ) const; + team_id GetClientTeamID(void) const { return fClientTeamID; } + FMWList *GetFMWList(void) { return &fWinFMWList; } + + void SetLook(int32 look); + void SetFeel(int32 feel); + void SetFlags(int32 flags); + void SetWorkspaces(int32 workspaces); + + void Show(void); + void Hide(void); + bool IsHidden(void); + void Minimize(bool status); + void Zoom(void); + void SetFocus(bool value); + bool HasFocus(void); + void RequestDraw(BRect rect); + void RequestDraw(void); + + void WorkspaceActivated(int32 workspace, bool active); + void WorkspacesChanged(int32 oldone,int32 newone); + void WindowActivated(bool active); + void ScreenModeChanged(const BRect frame, const color_space cspace); + + void SetFrame(const BRect &rect); + BRect Frame(void); + + status_t Lock(void); + void Unlock(void); + bool IsLocked(void); + + void DispatchMessage(PortMessage msg); + void DispatchGraphicsMessage(int32 msgsize, int8 *msgbuffer); + + static int32 MonitorWin(void *data); + static void HandleMouseEvent(PortMessage *msg); + static void HandleKeyEvent(int32 code, int8 *buffer); + +// Workspace* GetWorkspace(void); + void SetWorkspace(Workspace *wkspc); + + //! Returns the window's title + const char *Title(void) { return _title->String(); } + + Layer* FindLayer(const Layer* start, int32 token) const; + void SendMessageToClient( const BMessage* msg ) const; protected: friend class ServerApp; @@ -120,39 +134,38 @@ protected: friend class Screen; friend class Layer; - BString *_title; - int32 _look, - _feel, - _flags; - uint32 _workspace_index; - Workspace *_workspace; - bool _active; + BString *_title; + int32 _look, + _feel, + _flags; + uint32 _workspaces; + Workspace *_workspace; + bool _active; - ServerApp *_app; - WinBorder *_winborder; + ServerApp *_app; + WinBorder *_winborder; - thread_id _monitorthread; - port_id _receiver; // Messages from window - port_id _sender; // Messages to window - PortLink *_winlink, - *_applink; - BLocker _locker; - BRect _frame; - uint32 _token; - int32 _handlertoken; + thread_id _monitorthread; + + port_id _receiver; // Messages from window + port_id _sender; // Messages to window + + PortLink *_winlink, + *_applink; + BLocker _locker; + BRect _frame; + uint32 _token; + int32 _handlertoken; - port_id winLooperPort; - Layer *top_layer; - Layer *cl; // short for currentLayer. We'll use it a lot, that's why it's short :-) + port_id winLooperPort; + Layer *top_layer; + Layer *currentlayer; + FMWList fWinFMWList; + team_id fClientTeamID; }; void ActivateWindow(ServerWindow *oldwin,ServerWindow *newwin); #endif -/* - @log - * added Layer as a friend. - * added a new member: port_id winLooperPort; We'll use it to send flattened BMessages(like _UPDATE_ / B_VIEW_RESIZED(MOVED)) to our BWindow counterpart. - * SendMessageToClient( BMessage ) sends that message BWindow's looper port. -*/ + diff --git a/src/servers/app/server/ViewDriver.cpp b/src/servers/app/server/ViewDriver.cpp index 9a21fdbbe0..00bb927144 100644 --- a/src/servers/app/server/ViewDriver.cpp +++ b/src/servers/app/server/ViewDriver.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "Angle.h" @@ -572,6 +573,45 @@ void ViewDriver::Shutdown(void) Unlock(); } +void ViewDriver::SetMode(const display_mode &mode) +{ + screenwin->Lock(); + + BBitmap *tempbmp=new BBitmap(BRect(0,0,mode.virtual_width-1,mode.virtual_height-1), + (color_space)mode.space,true); + + if(!tempbmp) + return; + + if(!tempbmp->IsValid()) + { + delete tempbmp; + return; + } + + delete framebuffer; + + // don't forget to update the internal vars! + _SetWidth(mode.virtual_width); + _SetHeight(mode.virtual_height); + _SetMode(mode.space); + + screenwin->view->viewbmp=tempbmp; + framebuffer=screenwin->view->viewbmp; + drawview=new BView(framebuffer->Bounds(),"drawview",B_FOLLOW_ALL, B_WILL_DRAW); + framebuffer->AddChild(drawview); + + framebuffer->Lock(); + drawview->SetHighColor(workspace_default_color.GetColor32()); + drawview->FillRect(drawview->Bounds()); + drawview->Sync(); + framebuffer->Unlock(); + + _SetBytesPerRow(framebuffer->BytesPerRow()); + screenwin->view->Invalidate(); + screenwin->Unlock(); +} + void ViewDriver::SetMode(int32 space) { screenwin->Lock(); @@ -2062,3 +2102,134 @@ rgb_color ViewDriver::GetBlitColor(rgb_color src, rgb_color dest, LayerData *d, } return returncolor; } + +status_t ViewDriver::SetDPMSMode(const uint32 &state) +{ + // TODO: Implement software DPMS + return B_ERROR; +} + +uint32 ViewDriver::DPMSMode(void) const +{ + // TODO: Implement software DPMS + return B_DPMS_ON; +} + +uint32 ViewDriver::DPMSCapabilities(void) const +{ + // TODO: Implement software DPMS + return B_DPMS_ON; +} + +status_t ViewDriver::GetDeviceInfo(accelerant_device_info *info) +{ + if(!info) + return B_ERROR; + + // We really don't have to provide anything here because this is strictly + // a software-only driver, but we'll have some fun, anyway. + + info->version=100; + sprintf(info->name,"OpenBeOS ViewDriver"); + sprintf(info->chipset,"OpenBeOS Chipset"); + sprintf(info->serial_no,"3.14159265358979323846"); + info->memory=134217728; // 128 MB, not that we really have that much. :) + info->dac_speed=0xFFFFFFFF; // *heh* + + return B_OK; +} + +status_t ViewDriver::GetModeList(display_mode **modes, uint32 *count) +{ + if(!count) + return B_ERROR; + + screenwin->Lock(); + + // TODO: Figure out good timing values to be returned in each of the modes + // supported. + + *modes=new display_mode[13]; + *count=13; + + modes[0]->virtual_width=640; + modes[0]->virtual_width=480; + modes[0]->space=B_CMAP8; + modes[1]->virtual_width=640; + modes[1]->virtual_width=480; + modes[1]->space=B_RGB16; + modes[2]->virtual_width=640; + modes[2]->virtual_width=480; + modes[2]->space=B_RGB32; + modes[3]->virtual_width=640; + modes[3]->virtual_width=480; + modes[3]->space=B_RGBA32; + + modes[4]->virtual_width=800; + modes[4]->virtual_width=600; + modes[4]->space=B_CMAP8; + modes[5]->virtual_width=800; + modes[5]->virtual_width=600; + modes[5]->space=B_RGB16; + modes[6]->virtual_width=800; + modes[6]->virtual_width=600; + modes[6]->space=B_RGB32; + + modes[7]->virtual_width=1024; + modes[7]->virtual_width=768; + modes[7]->space=B_CMAP8;; + modes[8]->virtual_width=1024; + modes[8]->virtual_width=768; + modes[8]->space=B_RGB16; + modes[9]->virtual_width=1024; + modes[9]->virtual_width=768; + modes[9]->space=B_RGB32; + + modes[10]->virtual_width=1152; + modes[10]->virtual_width=864; + modes[10]->space=B_CMAP8; + modes[11]->virtual_width=1152; + modes[11]->virtual_width=864; + modes[11]->space=B_RGB16; + modes[12]->virtual_width=1152; + modes[12]->virtual_width=864; + modes[12]->space=B_RGB32; + + for(int32 i=0; i<13; i++) + { + modes[i]->h_display_start=0; + modes[i]->v_display_start=0; + modes[i]->flags=B_PARALLEL_ACCESS; + } + screenwin->Unlock(); + + return B_OK; +} + +status_t ViewDriver::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) +{ + return B_ERROR; +} + +status_t ViewDriver::GetTimingConstraints(display_timing_constraints *dtc) +{ + return B_ERROR; +} + +status_t ViewDriver::ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high) +{ + // TODO: Unhack + + // We should be able to get away with this because we're not dealing with any + // specific hardware. This is a Good Thing(TM) because we can support any hardware + // we wish within reasbonable expectaions and programmer laziness. :P + return B_OK; +} + +status_t ViewDriver::WaitForRetrace(bigtime_t timeout=B_INFINITE_TIMEOUT) +{ + // Locking shouldn't be necessary here - R5 should handle this for us. :) + BScreen screen; + return screen.WaitForRetrace(timeout); +} + diff --git a/src/servers/app/server/ViewDriver.h b/src/servers/app/server/ViewDriver.h index fe737c4cfa..6d45ae7399 100644 --- a/src/servers/app/server/ViewDriver.h +++ b/src/servers/app/server/ViewDriver.h @@ -126,7 +126,7 @@ public: // void SetDrawingMode(drawing_mode mode); void ShowCursor(void); -virtual void FillArc(const BRect r, float angle, float span, RGBColor& color); + virtual void FillArc(const BRect r, float angle, float span, RGBColor& color); virtual void FillArc(const BRect r, float angle, float span, const Pattern& pattern, RGBColor& high_color, RGBColor& low_color); virtual void FillBezier(BPoint *pts, RGBColor& color); virtual void FillBezier(BPoint *pts, const Pattern& pattern, RGBColor& high_color, RGBColor& low_color); @@ -162,10 +162,23 @@ virtual void FillArc(const BRect r, float angle, float span, RGBColor& color); virtual void StrokeLineArray(BPoint *pts, int32 numlines, float pensize, RGBColor *colors); void SetMode(int32 mode); + void SetMode(const display_mode &mode); + float StringWidth(const char *string, int32 length, LayerData *d); float StringHeight(const char *string, int32 length, LayerData *d); bool DumpToFile(const char *path); VDWindow *screenwin; + + virtual status_t SetDPMSMode(const uint32 &state); + virtual uint32 DPMSMode(void) const; + virtual uint32 DPMSCapabilities(void) const; + virtual status_t GetDeviceInfo(accelerant_device_info *info); + virtual status_t GetModeList(display_mode **mode_list, uint32 *count); + virtual status_t GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high); + virtual status_t GetTimingConstraints(display_timing_constraints *dtc); + virtual status_t ProposeMode(display_mode *candidate, const display_mode *low, const display_mode *high); + virtual status_t WaitForRetrace(bigtime_t timeout=B_INFINITE_TIMEOUT); + protected: void SetLayerData(LayerData *d, bool set_font_data=false); void BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index e6c20bead7..b258cf3904 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -27,8 +27,10 @@ #include #include #include +#include #include #include +#include "Globals.h" #include "View.h" // for mouse button defines #include "ServerWindow.h" #include "Decorator.h" @@ -322,9 +324,48 @@ void WinBorder::SetFocus(const bool &active) _decorator->SetFocus(active); } +void WinBorder::SetServerFeel(int32 feel) +{ + switch(_win->GetFeel()) + { + case B_NORMAL_WINDOW_FEEL: + _serverfeel = B_NORMAL_FEEL; + break; + case B_FLOATING_SUBSET_WINDOW_FEEL: + _serverfeel = B_FLOATING_SUBSET_FEEL; + break; + case B_FLOATING_APP_WINDOW_FEEL: + _serverfeel = B_FLOATING_APP_FEEL; + break; + case B_FLOATING_ALL_WINDOW_FEEL: + _serverfeel = B_FLOATING_ALL_FEEL; + break; + case B_MODAL_SUBSET_WINDOW_FEEL: + _serverfeel = B_MODAL_SUBSET_FEEL; + break; + case B_MODAL_APP_WINDOW_FEEL: + _serverfeel = B_MODAL_APP_FEEL; + break; + case B_MODAL_ALL_WINDOW_FEEL: + _serverfeel = B_MODAL_ALL_FEEL; + break; + case B_SYSTEM_LAST: + case B_SYSTEM_FIRST: +// if(_win->ServerTeamID() != _win->ClientTeamID()) +// _win->QuietlySetFeel(B_NORMAL_WINDOW_FEEL); +// else +// _serverfeel = _win->GetFeel(); + break; + default: + _win->SetFeel(B_NORMAL_WINDOW_FEEL); + _serverfeel = B_NORMAL_FEEL; + break; + } +} + void WinBorder::RebuildRegions( const BRect& r ){ /* WinBorder is a little bit special. It doesn't have a visible region - in which to do its drawings. Instead the whole visible region is split + in witch to do its drawings. Instead the hole visible region is split between decorator and top_layer. */ diff --git a/src/servers/app/server/WinBorder.h b/src/servers/app/server/WinBorder.h index 59101d3e86..a35d1f0d9e 100644 --- a/src/servers/app/server/WinBorder.h +++ b/src/servers/app/server/WinBorder.h @@ -38,64 +38,74 @@ class DisplayDriver; class WinBorder : public Layer { public: - WinBorder(const BRect &r, const char *name, const int32 look, - const int32 feel, const int32 flags, ServerWindow *win); - virtual ~WinBorder(void); - - virtual void RebuildRegions( const BRect& r ); - virtual void Draw(const BRect &r); - - virtual void MoveBy(float x, float y); - virtual void ResizeBy(float x, float y); + WinBorder(const BRect &r, const char *name, const int32 look, + const int32 feel, const int32 flags, ServerWindow *win); + virtual ~WinBorder(void); - void MoveToBack(); - void MoveToFront(); - - void MouseDown(int8 *buffer); - void MouseMoved(int8 *buffer); - void MouseUp(int8 *buffer); - - void UpdateColors(void); - void UpdateDecorator(void); - void UpdateFont(void); - void UpdateScreen(void); - - void SetFocus(const bool &active); - ServerWindow* Window(void) const { return _win; } - Decorator* GetDecorator(void) const { return _decorator; } + virtual void RebuildRegions( const BRect& r ); + virtual void Draw(const BRect &r); + + virtual void MoveBy(float x, float y); + virtual void ResizeBy(float x, float y); + + void SetServerFeel(int32 feel); + int32 GetServerFeel(void) const { return _serverfeel; } + + void MoveToBack(); + void MoveToFront(); + + void MouseDown(int8 *buffer); + void MouseMoved(int8 *buffer); + void MouseUp(int8 *buffer); + + void UpdateColors(void); + void UpdateDecorator(void); + void UpdateFont(void); + void UpdateScreen(void); + + void SetFocus(const bool &active); + ServerWindow* Window(void) const { return _win; } + Decorator* GetDecorator(void) const { return _decorator; } + + WinBorder *MainWinBorder(void) const { return fMainWinBorder; } + // Server "private" :-) - should not be used + void SetMainWinBorder(WinBorder *newMain) { fMainWinBorder=newMain; } + protected: - ServerWindow *_win; - //BString *_title; - Decorator *_decorator; - int32 _flags; - BRect _clientframe; - int32 _mbuttons, - _kmodifiers; - BPoint fLastMousePosition; - bool _update; - bool _hresizewin,_vresizewin; - - BRegion *fDecFull, - *fDecFullVisible, - *fDecVisible; - -/* bool fIsMoving; - bool fIsResizing; - bool fIsClosing; - bool fIsMinimizing; - bool fIsZooming + ServerWindow *_win; + Decorator *_decorator; + int32 _flags; + BRect _clientframe; + int32 _mbuttons, + _kmodifiers; + int32 _serverfeel; + BPoint fLastMousePosition; + bool _update; + bool _hresizewin,_vresizewin; + WinBorder *fMainWinBorder; + + BRegion *fDecFull, + *fDecFullVisible, + *fDecVisible; + + //BString *_title; +/* bool fIsMoving; + bool fIsResizing; + bool fIsClosing; + bool fIsMinimizing; + bool fIsZooming */ }; -bool is_moving_window(void); -void set_is_moving_window(bool state); -bool is_resizing_window(void); -void set_is_resizing_window(bool state); -void set_active_winborder(WinBorder *win); -WinBorder* get_active_winborder(void); -void set_is_resizing_window(bool state); -void set_is_sliding_tab(bool state); -bool is_sliding_tab(void); +bool is_moving_window(void); +void set_is_moving_window(bool state); +bool is_resizing_window(void); +void set_is_resizing_window(bool state); +void set_active_winborder(WinBorder *win); +WinBorder *get_active_winborder(void); +void set_is_resizing_window(bool state); +void set_is_sliding_tab(bool state); +bool is_sliding_tab(void); #endif diff --git a/src/servers/app/server/Workspace.cpp b/src/servers/app/server/Workspace.cpp new file mode 100644 index 0000000000..a230896e69 --- /dev/null +++ b/src/servers/app/server/Workspace.cpp @@ -0,0 +1,1016 @@ +#include +#include + +#include "ServerApp.h" +#include "Workspace.h" +#include "Layer.h" +#include "WinBorder.h" +#include "ServerWindow.h" +#include "RGBColor.h" +#include "Globals.h" +#include "FMWList.h" +#include "RootLayer.h" +#include "Desktop.h" + +//#define DEBUG_WORKSPACE + +#ifdef DEBUG_WORKSPACE +# include +# define STRACE(x) printf x +#else +# define STRACE(x) ; +#endif + +#ifdef DEBUG_WORKSPACE +# include +# define STRACESTREAM() PrintToStream() +#else +# define STRACESTREAM() ; +#endif + + +Workspace::Workspace(const uint32 colorspace, int32 ID, const RGBColor& BGColor){ + fID = ID; + fSpace = colorspace; + fBGColor = BGColor; + + fBottomItem = NULL; + fTopItem = NULL; + fCurrentItem= NULL; + fFocusItem = NULL; + fFrontItem = NULL; +} +//--------------------------------------------------------------------------- +Workspace::~Workspace(){ +//printf("~Workspace( %ld )\n", fID); + ListData *toast; + while(fBottomItem){ + toast = fBottomItem; + fBottomItem = fBottomItem->upperItem; + + delete toast; + } + fBottomItem = NULL; + fTopItem = NULL; + fCurrentItem = NULL; + fFocusItem = NULL; + fFrontItem = NULL; +} +//--------------------------------------------------------------------------- +/* Adds layer ptr to workspace's list of WinBorders. After the item is added + * a *smart* search is performed to set the new front WinBorder. Of course, + * the first candidate is 'layer', but if it is hidden or it has the + * B_AVOID_FRONT flag, surely it won't get that status. + * This method also calls SearchAndSerNewFocus witch searches for a WinBorder, + * to give focus to, having as preferred 'layer'. + * Remember, some windows having B_AVOID_FOCUS can't have the focus state. + */ +bool Workspace::AddLayerPtr(WinBorder* layer){ + // allocate a new item + ListData *item; + item = new ListData; + + item->layerPtr = layer; + item->upperItem = NULL; + item->lowerItem = NULL; + + // insert 'item' at the end. It doesn't matter where we add it, + // it will be placed correctly by SearchAndSetNewFront(item->layerPtr); + InsertItem(item, NULL); +STRACE(("\n*AddLayerPtr(%s) -", layer->GetName())); + // do a *smart* search and set the new 'front' + SearchAndSetNewFront(layer); + // do a *smart* search and set the new 'focus' + SearchAndSetNewFocus(layer); + +STRACESTREAM(); + return true; +} +/* Removes a WinBorder from workspace's list. It DOES NOT delete it! + * If this window was the front/focus one it calls SearchAndSetNew(Front/Focus) + * to give the respective state to the window below her. + */ +//--------------------------------------------------------------------------- +bool Workspace::RemoveLayerPtr(WinBorder* layer){ + if (!layer) + return false; +STRACE(("\n#RemoveLayerPtr(%s)\n", layer->GetName())); + + // search to see if this workspace has WinBorder's pointer in its list + ListData *item = NULL; + if ((item = HasItem(layer))){ + ListData *nextItem = NULL; + bool wasFront, wasFocus; + + // prepare to set new front/focus if this layer was front/focus + nextItem = item->upperItem; + wasFront = fFrontItem->layerPtr == layer; + wasFocus = fFrontItem->layerPtr == layer; + + // remove any floating window our window may have + ListData *listItem = item->lowerItem; + while(listItem && (listItem->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL)) + { // *carefully* remove the item from the list + ListData *itemX = listItem; + listItem = listItem->lowerItem; + RemoveItem(itemX); + } + + // remove from workspace's list + RemoveItem(item); + + // reset some internal variables + layer->SetMainWinBorder(NULL); + // its RootLayer is set to NULL by Layer::RemoveChild(layer); +STRACESTREAM(); + + if (wasFront) + SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL); + + if (wasFocus) + SearchAndSetNewFocus(nextItem? nextItem->layerPtr: NULL); + + // delete item struct, we no longer need that + delete item; + return true; + } + else + return false; +} +//--------------------------------------------------------------------------- +bool Workspace::SetFocusLayer(WinBorder* layer){ + SearchAndSetNewFocus(layer); + return true; +} +//--------------------------------------------------------------------------- +WinBorder* Workspace::FocusLayer() const{ + return fFocusItem ? fFocusItem->layerPtr : NULL; +} +//--------------------------------------------------------------------------- +bool Workspace::SetFrontLayer(WinBorder* layer){ +STRACE(("\n@SetFrontLayer( %s )\n", layer? layer->GetName(): "NULL")); + SearchAndSetNewFront(layer); +STRACESTREAM(); + return true; +} +//--------------------------------------------------------------------------- +WinBorder* Workspace::FrontLayer() const{ + return fFrontItem? fFrontItem->layerPtr: NULL; +} +//--------------------------------------------------------------------------- +WinBorder* Workspace::GoToBottomItem(){ + fCurrentItem = fBottomItem; + return fCurrentItem ? fCurrentItem->layerPtr : NULL; +} +//--------------------------------------------------------------------------- +WinBorder* Workspace::GoToUpperItem(){ + if (fCurrentItem){ + fCurrentItem = fCurrentItem->upperItem; + return fCurrentItem ? fCurrentItem->layerPtr : NULL; + } + else + return NULL; +} +//--------------------------------------------------------------------------- +WinBorder* Workspace::GoToTopItem(){ + fCurrentItem = fTopItem; + return fCurrentItem ? fCurrentItem->layerPtr : NULL; +} +//--------------------------------------------------------------------------- +WinBorder* Workspace::GoToLowerItem(){ + if (fCurrentItem){ + fCurrentItem = fCurrentItem->lowerItem; + return fCurrentItem ? fCurrentItem->layerPtr : NULL; + } + else + return NULL; +} +//--------------------------------------------------------------------------- +bool Workspace::GoToItem(WinBorder* layer){ + if (!layer) + return false; + + if (fCurrentItem && fCurrentItem->layerPtr == layer){ + return true; + } + + for( ListData *item = fBottomItem; item != NULL; item = item->upperItem){ + if (item->layerPtr == layer){ + fCurrentItem = item; + return true; + } + } + return false; +} +//--------------------------------------------------------------------------- +void Workspace::InsertItem(ListData* item, ListData* before){ + // insert before one other item; + if (before){ + if (before->upperItem) + before->upperItem->lowerItem = item; + item->upperItem = before->upperItem; + before->upperItem = item; + item->lowerItem = before; + + // if we're inserting at top of the stack, change it accordingly. + if(fTopItem == before) + fTopItem = item; + } + // insert item at bottom. + else{ + item->upperItem = fBottomItem; + if (fBottomItem) + fBottomItem->lowerItem = item; + + fBottomItem = item; + + if (!fTopItem) + fTopItem = item; + } +} +//--------------------------------------------------------------------------- +void Workspace::RemoveItem(ListData* item){ + if (!item) + return; + + if (fBottomItem == item){ + fBottomItem = item->upperItem; + } + else{ + item->lowerItem->upperItem = item->upperItem; + } + if (fTopItem == item){ + fTopItem = item->lowerItem; + } + else{ + item->upperItem->lowerItem = item->lowerItem; + } + + // set all these to NULL to avoid confusion later. + + item->upperItem = NULL; + item->lowerItem = NULL; + + if (fFocusItem == item) + fFocusItem = NULL; + if (fFrontItem == item) + fFrontItem = NULL; + if (fCurrentItem == item) + fCurrentItem = NULL; +} +//--------------------------------------------------------------------------- +ListData* Workspace::HasItem(ListData* item){ + for (ListData *itemX = fBottomItem; itemX != NULL; itemX = itemX->upperItem){ + if (item == itemX){ + return itemX; + } + } + return NULL; +} +//--------------------------------------------------------------------------- +ListData* Workspace::HasItem(WinBorder* layer){ + for (ListData *item = fBottomItem; item != NULL; item = item->upperItem){ + if (item->layerPtr == layer){ + return item; + } + } + return NULL; +} +/* This, also is a "smart" method. Firstly this funtionality was in + * SearchAndSetNewFront, but I've split it for reasons of clarity. Anyway, + * what is to be noticed is that those 2 methods work hand-in-hand. + * What FindPlace() litelaly does, is *place* the 'pref' item into its + * >right< place! If 'pref->layerPtr'(the WinBorder in ListData structure) + * does not meet some conditions a search for another, valid, WinBorder is + * being made. + * + * NOTE: Do NOT be confussed! This method places the preferred window *ONLY*! + * Other windows that need to be placed before it, *WILL* be placed by almost + * all code found in SearchAndSetNewFront + */ +//--------------------------------------------------------------------------- +ListData* Workspace::FindPlace(ListData* pref){ + // if we received a NULL value, we stil have to give 'front' state to some window... + if (!pref) + pref = fBottomItem; + + ListData *item = NULL; + + // search a window that is not hidden and does *not* have B_AVOID_FRONT flag. + item = pref; + while(pref && item->lowerItem != pref){ + if ( !(item->layerPtr->Window()->GetFlags() & B_AVOID_FRONT) && !(item->layerPtr->IsHidden()) ) + break; + + if (item == fTopItem) + item = fBottomItem; + else + item = item->upperItem; + } + // if true, it means we have windows with B_AVOID_FRONT flag *only*, so pick one. + if (pref && item->lowerItem == pref){ + for (item = fBottomItem; item; item = item->upperItem){ + if ( !(item->layerPtr->IsHidden()) ) + break; + } + } + + // if the search took place or not... + pref = item; + + // we have exhausted all possibilities to make pref a vaid pointer... so... exit now. + if (!pref) + return NULL; + + // temporally remove 'pref' to reinsert it later in the *right* place + RemoveItem(pref); + + // we start searching its place + ListData *cursor = fBottomItem; + int32 feel = pref->layerPtr->Window()->GetFeel(); + + switch(feel){ + case B_NORMAL_WINDOW_FEEL:{ + while(cursor && cursor->layerPtr->GetServerFeel() > B_MODAL_APP_FEEL){ + cursor = cursor->upperItem; + } + InsertItem(pref, cursor? cursor->lowerItem: NULL); + break; + } + + case B_SYSTEM_LAST:{ + while(cursor && cursor->layerPtr->GetServerFeel() > pref->layerPtr->GetServerFeel()){ + cursor = cursor->upperItem; + } + InsertItem(pref, cursor? cursor->lowerItem: fTopItem); + break; + } + + case B_SYSTEM_FIRST: + case B_FLOATING_ALL_WINDOW_FEEL: + case B_MODAL_ALL_WINDOW_FEEL: + case B_MODAL_APP_WINDOW_FEEL:{ + while(cursor && cursor->layerPtr->GetServerFeel() > pref->layerPtr->GetServerFeel()){ + cursor = cursor->upperItem; + } + InsertItem(pref, cursor? cursor->lowerItem: NULL); + break; + } + + // place in front of: its main window, other subset windows and in front + // of other application's floating windows. + // NOTE that this happens only if its main window is the front most one. + case B_FLOATING_SUBSET_WINDOW_FEEL:{ + for(cursor = fBottomItem; cursor; cursor = cursor->upperItem){ + if (cursor->layerPtr->GetServerFeel() <= pref->layerPtr->GetServerFeel() + && (cursor->layerPtr == pref->layerPtr->MainWinBorder() + || cursor->layerPtr->MainWinBorder() == pref->layerPtr->MainWinBorder()) + ) + { break; } + else if(pref->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + && cursor->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL) + { break; } + } + if (cursor) + InsertItem(pref, cursor? cursor->lowerItem: NULL); + break; + } + + // place this SUBSET_MODAL behind APP_MODAL ones if they belong + // to the same application OR, in front of all MODAL/NORMAL if + // it belongs to another application + case B_MODAL_SUBSET_WINDOW_FEEL:{ + for(cursor = fBottomItem; cursor; cursor = cursor->upperItem){ + if (cursor->layerPtr->GetServerFeel() <= pref->layerPtr->GetServerFeel()) + break; + else if(pref->layerPtr->GetServerFeel() == B_MODAL_SUBSET_FEEL + && cursor->layerPtr->GetServerFeel() == B_MODAL_APP_FEEL + && pref->layerPtr->Window()->GetClientTeamID() + != cursor->layerPtr->Window()->GetClientTeamID()) + break; + } + if (cursor) + InsertItem(pref, cursor? cursor->lowerItem: NULL); + break; + } + + // place in front of: its main window, other floating windows + // NOTE that this happens only if its main window is the front most one. + case B_FLOATING_APP_WINDOW_FEEL:{ + for(cursor = fBottomItem; cursor; cursor = cursor->upperItem){ + if (cursor->layerPtr->GetServerFeel() <= pref->layerPtr->GetServerFeel() + && pref->layerPtr->Window()->GetClientTeamID() == + cursor->layerPtr->Window()->GetClientTeamID()) + { break; } + } + + if (cursor) + InsertItem(pref, cursor? cursor->lowerItem: NULL); + break; + } + } + + return pref; +} +/* This method is the key to correct window arangement!!! + * With the help of FindPlace it correctly aranges windows. FindPlace, only + * inserted the window in the correct place, this method also brings all + * other windows that are supposed to be in front of her - I'm talking here + * about floating and modal windows. + * It also clerverly selects the new FINAL front window. + */ +//--------------------------------------------------------------------------- +void Workspace::SearchAndSetNewFront(WinBorder* preferred){ + // the new front must not be the same as the previous one. + if (fFrontItem && fFrontItem->layerPtr == preferred) + return; + + // properly place this 'preferred' WinBorder. + ListData *lastInserted; + lastInserted = FindPlace(HasItem(preferred)); + preferred = lastInserted? lastInserted->layerPtr: NULL; + + // if the new front layer is the same... there is no point continuing + if(fFrontItem == lastInserted) + return; + + if (lastInserted && !(lastInserted->layerPtr->IsHidden())){ + int32 prefFeel = preferred->Window()->GetFeel(); + + if (prefFeel == B_NORMAL_WINDOW_FEEL){ +STRACE((" NORMAL Window '%s' -", preferred->GetName())); + if (fFrontItem){ + // if they are in the same team... + if (preferred->Window()->GetClientTeamID() == fFrontItem->layerPtr->Window()->GetClientTeamID()){ +STRACE((" SAME TeamID\n")); + // collect subset windows that are common to application's windows... + // NOTE: A subset window *can* be added to more than just one window. + FMWList commonFMW; + FMWList appFMW; + FMWList finalFMWList; + int32 count, i; + // collect floating and modal windows spread across the workspace only if + // they are in our window's subset + // * also remove them, for repositioning, later. + ListData *listItem = fTopItem; + while(listItem){ + int32 feel = listItem->layerPtr->Window()->GetFeel(); + if (feel == B_FLOATING_SUBSET_WINDOW_FEEL || feel == B_MODAL_SUBSET_WINDOW_FEEL){ + if(preferred->Window()->GetFMWList()->HasItem(listItem->layerPtr)){ + commonFMW.AddItem(listItem->layerPtr); + // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + // also remove floating windows. Those, SURELY belong to + // 'fFrontItem' - this being the *old* front window. + else if (feel == B_FLOATING_SUBSET_WINDOW_FEEL){ + // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + else + listItem = listItem->lowerItem; + } + // ALSO collect application's floating and modal windows, + // for reinsertion, later. + else if (feel == B_FLOATING_APP_WINDOW_FEEL || feel == B_MODAL_APP_WINDOW_FEEL){ + if(listItem->layerPtr->Window()->GetClientTeamID() == + preferred->Window()->GetClientTeamID()) + { + appFMW.AddItem(listItem->layerPtr); + // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + } + else + listItem = listItem->lowerItem; + } + // put in the final list, items that are not found in the common list + count = preferred->Window()->GetFMWList()->CountItems(); + for (i=0; iWindow()->GetFMWList()->ItemAt(i); + if (commonFMW.HasItem(item)){ } + else + finalFMWList.AddItem(item); + } + // colapse the 2 lists + finalFMWList.AddFMWList(&commonFMW); + finalFMWList.AddFMWList(&appFMW); + + // insert windows found in 'finalFMWList' in Workspace's list. + // IF *one* modal is found, do not add floating ones! + + // see if the last WinBorder in the list is a modal window. + // OR if the last one in Workspace's list is a modal window... + WinBorder *wb = (WinBorder*)finalFMWList.LastItem(); + bool lastIsModal = false; + if ( (wb && + (wb->Window()->GetFeel() == B_MODAL_SUBSET_WINDOW_FEEL + || wb->Window()->GetFeel() == B_MODAL_APP_WINDOW_FEEL)) + || (fBottomItem && + (fBottomItem->layerPtr->Window()->GetFeel() == B_MODAL_ALL_WINDOW_FEEL + || fBottomItem->layerPtr->Window()->GetFeel() == B_SYSTEM_FIRST)) + ) + { lastIsModal = true; } + + // this variable will help us in deciding the new front WinBorder. + WinBorder *finalPreferred = preferred; + // now insert items found in finalFMWList into Workspace + count = finalFMWList.CountItems(); + for(i=0; iWindow()->GetFeel() == B_FLOATING_SUBSET_WINDOW_FEEL + || wb->Window()->GetFeel() == B_FLOATING_APP_WINDOW_FEEL) + { + // set its new MainWinBorder + if(wb->Window()->GetFeel() == B_FLOATING_SUBSET_WINDOW_FEEL) + wb->SetMainWinBorder(preferred); + // don't add if the last WinBorder is a modal one. + if (lastIsModal) + continue; + } + else{ + if(wb->Window()->GetFeel() == B_MODAL_SUBSET_WINDOW_FEEL) + wb->SetMainWinBorder(preferred); + // if this modal window is not hidden, give it the front status. + if (!(wb->IsHidden())) + finalPreferred = wb; + } + + // insert item just after the last inserted one. + ListData *newItem = new ListData(); + newItem->layerPtr = wb; + newItem->lowerItem = lastInserted->lowerItem; + newItem->upperItem = lastInserted; + if (lastInserted->lowerItem) + lastInserted->lowerItem->upperItem = newItem; + lastInserted->lowerItem = newItem; + + if(lastInserted == fBottomItem) + fBottomItem = newItem; + + lastInserted = newItem; + } + preferred = finalPreferred; + } + else{ +STRACE((" DIFERRENT TeamID\n")); + // remove front window's floating(_SUBSET_/_APP_) windows, if any. + ListData *listItem = fFrontItem->lowerItem; + while(listItem && (listItem->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL)) + { // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + // now, jump to et1: to make a 'clean' selecting of + // windows to be inserted + fFrontItem = NULL; + goto et1; + } // else - if diferrent ClientTeamID()s. + } // if (fFrontItem) && NORMAL_WINDOW + else{ +STRACE((" NO previous FRONT Item\n")); + et1: + FMWList finalFMWList; + int32 count, i; + ListData *listItem = fTopItem; + // remove window's subset and application's *modal* windows spread + // across Workspace's list, to be insert later, in the corect order. + while(listItem){ + int32 feel = listItem->layerPtr->Window()->GetFeel(); + if ((feel == B_MODAL_SUBSET_WINDOW_FEEL + && preferred->Window()->GetFMWList()->HasItem(listItem->layerPtr)) + || (feel == B_MODAL_APP_WINDOW_FEEL + && preferred->Window()->GetClientTeamID() == + listItem->layerPtr->Window()->GetClientTeamID() + )) + { + // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + else + listItem = listItem->lowerItem; + } + + // add to the final list window's subset windows. (..._SUBSET_...) + finalFMWList.AddFMWList( preferred->Window()->GetFMWList() ); + // also add application's ones. (..._APP_...) + finalFMWList.AddFMWList(preferred->Window()->GetApp()->GetFMWList()); + + // insert windows found in 'finalFMWList' in Workspace's list. + // IF *one* modal is found, do not add floating ones! + + // see if the last WinBorder in the list is a modal window. + WinBorder *wb = (WinBorder*)finalFMWList.LastItem(); + bool lastIsModal = false; + if ( (wb && + (wb->Window()->GetFeel() == B_MODAL_SUBSET_WINDOW_FEEL + || wb->Window()->GetFeel() == B_MODAL_APP_WINDOW_FEEL)) + || (fBottomItem && + (fBottomItem->layerPtr->Window()->GetFeel() == B_MODAL_ALL_WINDOW_FEEL + || fBottomItem->layerPtr->Window()->GetFeel() == B_SYSTEM_FIRST)) + ) + { lastIsModal = true; } + + // this variable will help us in deciding the new front WinBorder. + WinBorder *finalPreferred = preferred; + // now insert items found in finalFMWList into Workspace + count = finalFMWList.CountItems(); + for(i=0; iWindow()->GetFeel() == B_FLOATING_SUBSET_WINDOW_FEEL + || wb->Window()->GetFeel() == B_FLOATING_APP_WINDOW_FEEL) + { + // set its new MainWinBorder + if(wb->Window()->GetFeel() == B_FLOATING_SUBSET_WINDOW_FEEL) + wb->SetMainWinBorder(preferred); + // don't add if the last WinBorder is a modal one. + if (lastIsModal) + continue; + } + else{ + if(wb->Window()->GetFeel() == B_MODAL_SUBSET_WINDOW_FEEL) + wb->SetMainWinBorder(preferred); + // if this modal window is not hidden, give it the front status. + if (!(wb->IsHidden())) + finalPreferred = wb; + } + // insert item just after the last inserted one. + ListData *newItem = new ListData(); + newItem->layerPtr = wb; + newItem->lowerItem = lastInserted->lowerItem; + newItem->upperItem = lastInserted; + if (lastInserted->lowerItem) + lastInserted->lowerItem->upperItem = newItem; + lastInserted->lowerItem = newItem; + + if(lastInserted == fBottomItem) + fBottomItem = newItem; + + lastInserted = newItem; + } + preferred = finalPreferred; + } // else - if(fFrontItem); + } // END: if _NORMAL_ window. + else if( prefFeel == B_FLOATING_SUBSET_WINDOW_FEEL + || prefFeel == B_FLOATING_APP_WINDOW_FEEL + || prefFeel == B_FLOATING_ALL_WINDOW_FEEL) + { +STRACE((" FLOATING Window '%s'\n", preferred->GetName())); + // Do nothing! FindPlace() was called and it has corectly placed our window + // We don't have to do noting here. + } + else if( prefFeel == B_MODAL_SUBSET_WINDOW_FEEL + || prefFeel == B_MODAL_APP_WINDOW_FEEL) + { +STRACE((" MODAL_APP/SUBSET Window '%s'\n", preferred->GetName())); + FMWList finalMWList; + int32 count, i; + int32 prefIndex; + + if (fFrontItem && fFrontItem->layerPtr->GetServerFeel() == B_NORMAL_FEEL) + { + // remove front window's floating(_SUBSET_/_APP_) windows, if any. + ListData *listItem = fFrontItem->lowerItem; + while(listItem && (listItem->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL)) + { // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + } + + // If this is a MODAL_SUBSET window, search it's place in its MainWinBorder + // window subset, and then take all modals after it; then continue talking + // modal windoes *only*, from application's set. + // If it is a MODAL_APP only search an take windows in/from application's set + if (prefFeel == B_MODAL_SUBSET_WINDOW_FEEL){ + prefIndex = preferred->MainWinBorder()->Window()->GetFMWList()->IndexOf(preferred); + count = preferred->MainWinBorder()->Window()->GetFMWList()->CountItems(); + if (prefIndex >= 0){ + WinBorder *wb = NULL; + // add modal windows from its main window subset - windows that are + // positioned after 'preferred'. + FMWList *listPtr = preferred->MainWinBorder()->Window()->GetFMWList(); + for(i = prefIndex+1; i < count; i++){ + // they *all* are modal windows. + wb = (WinBorder*)listPtr->ItemAt(i); + wb->SetMainWinBorder(preferred); + finalMWList.AddItem(wb); + // remove those windows(if in there), for correct re-insertion later. + ListData *ld = NULL; + if((ld = HasItem(wb))) + RemoveItem(ld); + } + // add modal windows that are found in application's subset + count = preferred->Window()->GetApp()->GetFMWList()->CountItems(); + listPtr = preferred->Window()->GetApp()->GetFMWList(); + for(i = 0; i < count; i++){ + wb = (WinBorder*)listPtr->ItemAt(i); + if (wb->Window()->GetFeel() == B_MODAL_APP_WINDOW_FEEL){ + finalMWList.AddItem(wb); + // remove those windows(if in there), for correct re-insertion later. + ListData *ld = NULL; + if((ld = HasItem(wb))) + RemoveItem(ld); + } + } + } + } + else if(prefFeel == B_MODAL_APP_WINDOW_FEEL){ + prefIndex = preferred->Window()->GetApp()->GetFMWList()->IndexOf(preferred); + count = preferred->Window()->GetApp()->GetFMWList()->CountItems(); + if (prefIndex >= 0){ + WinBorder *wb = NULL; + // add modal windows from application's subset - windows that are + // positioned after 'preferred'. + FMWList *listPtr = preferred->Window()->GetApp()->GetFMWList(); + for(i = prefIndex+1; i < count; i++){ + wb = (WinBorder*)listPtr->ItemAt(i); + // they *all* are modal windows. + finalMWList.AddItem(wb); + // remove those windows(if in there), for correct re-insertion later. + ListData *ld = NULL; + if((ld = HasItem(wb))) + RemoveItem(ld); + } + } + } + + // insert windows found in 'finalMWList' in Workspace's list, after "preferred" + count = finalMWList.CountItems(); + // this varable will help us designate the future front. + WinBorder *finalPreferred = preferred; + for(i=0; iIsHidden())) + finalPreferred = wb; + + // insert item just after the last inserted one. + ListData *newItem = new ListData(); + newItem->layerPtr = wb; + newItem->lowerItem = lastInserted->lowerItem; + newItem->upperItem = lastInserted; + if (lastInserted->lowerItem) + lastInserted->lowerItem->upperItem = newItem; + lastInserted->lowerItem = newItem; + + if(lastInserted == fBottomItem){ + fBottomItem = newItem; + } + + lastInserted = newItem; + } + preferred = finalPreferred; + } + else if(prefFeel == B_MODAL_ALL_WINDOW_FEEL + || prefFeel == B_SYSTEM_FIRST) + { +STRACE((" MODAL ALL/SYSTEM FIRST Window '%s'\n", preferred->GetName())); + // remove all application's floating windows. + if (fFrontItem && fFrontItem->layerPtr->GetServerFeel() == B_NORMAL_FEEL) + { + ListData *listItem = fFrontItem->lowerItem; + while(listItem && + (listItem->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL)) + { + // *carefully* remove the item from the list + ListData *item = listItem; + listItem = listItem->lowerItem; + RemoveItem(item); + } + } + } + else if(prefFeel == B_SYSTEM_LAST){ + ; // Do Nothing. + } + else{ + // We ***should NOT*** reach this point! + printf("SERVER: PANIC: \"%s\": What kind of window is this???\n", preferred->GetName()); + } + } + + if(preferred){ + int32 feel = fBottomItem->layerPtr->Window()->GetFeel(); + + // if preferred is one of these *don't* give front state to it! + if(preferred->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || preferred->GetServerFeel() == B_FLOATING_APP_FEEL + || preferred->GetServerFeel() == B_FLOATING_ALL_FEEL) + { } + // if the last in workspace's list is one of these, GIVE focus to it! + else if(feel == B_SYSTEM_FIRST || feel == B_MODAL_ALL_WINDOW_FEEL){ + fFrontItem = fBottomItem; + } + // the SYSTEM_LAST will get the front status, only if it's the only + // WinBorder in this workspace. + else if (preferred->GetServerFeel() == B_SYSTEM_LAST){ + if(fBottomItem->layerPtr == preferred) + fFrontItem = HasItem(preferred); + } + // this is in case of MODAL[APP/SUBSET] and NORMAL windows + else{ + fFrontItem = HasItem(preferred); + } + } + else{ fFrontItem = NULL; } +} +/* This method performs a simple opperation. It searched the new focus window + * by walking from front to back, cheking for some things, until all variables + * correspond. + */ +//--------------------------------------------------------------------------- +void Workspace::SearchAndSetNewFocus(WinBorder* preferred){ + return; + ListData *item = NULL; + for(item = fBottomItem; item != NULL; item = item->upperItem){ + // if this WinBorder doesn't want to have focus... get to the next one + if (item->layerPtr->Window()->GetFlags() & B_AVOID_FOCUS) + continue; + // this means there is no modal window before our preferred one. + if (item->layerPtr == preferred) + break; + // we now chose a modal window to give focus to + if (item->layerPtr->GetServerFeel() == B_SYSTEM_FIRST + || item->layerPtr->GetServerFeel() == B_MODAL_ALL_FEEL + || item->layerPtr->GetServerFeel() == B_MODAL_APP_FEEL + || item->layerPtr->GetServerFeel() == B_MODAL_SUBSET_FEEL) + { + break; + } + } + + if (item != fFocusItem){ + // TODO: item->ColorTabInGrey & send message to client + // TODO: item->ColorTabInYellow & send message to client + // TODO: Rebuild & Redraw. + fFocusItem = item; + } +} +/* The method moves a window to the back of its subset. + */ +//--------------------------------------------------------------------------- +void Workspace::MoveToBack(WinBorder* newLast){ +STRACE(("\n!MoveToBack(%s) -", newLast? newLast->GetName(): "NULL")); + // does the list have this element? + ListData *item = HasItem(newLast); + if(item){ + ListData *listItem = NULL; + + switch(item->layerPtr->GetServerFeel()){ + case B_FLOATING_ALL_FEEL:{ +STRACE((" B_FLOATING_ALL_FEEL window\n")); + // search the place where we should insert it later + listItem = item->upperItem; + while(listItem && (listItem->layerPtr->GetServerFeel() == item->layerPtr->GetServerFeel())) + listItem = listItem->upperItem; + + break; + } + + // those 2 flags form a 'virtual' set, so even if FLOATING_APP + // has a greater priority than FLOATING_SUBSET, it is still moved + // behind FLOATING_SUBSET. + case B_FLOATING_SUBSET_FEEL: + case B_FLOATING_APP_FEEL:{ +STRACE((" B_FLOATING_SUBSET_FEEL/B_FLOATING_APP_FEEL window\n")); + // search the place where we should insert it later + listItem = item->upperItem; + while(listItem && + (listItem->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL)) + listItem = listItem->upperItem; + + break; + } + + // the same like with floating window. Those 2 and NORMAL form a'virtual' set. + case B_MODAL_SUBSET_FEEL: + case B_MODAL_APP_FEEL:{ +STRACE((" B_MODAL_SUBSET_FEEL/B_MODAL_APP_FEEL window\n")); + // search the place where we should insert it later + listItem = item->upperItem; + while(listItem && + (listItem->layerPtr->GetServerFeel() == B_MODAL_SUBSET_FEEL + || listItem->layerPtr->GetServerFeel() == B_MODAL_APP_FEEL + || listItem->layerPtr->GetServerFeel() == B_NORMAL_FEEL)) + listItem = listItem->upperItem; + + break; + } + + // here is the simplest, we use the priority levels. + case B_NORMAL_FEEL:{ +STRACE((" B_NORMAL_FEEL window\n")); + listItem = item->upperItem; + while(listItem && (listItem->layerPtr->GetServerFeel() >= item->layerPtr->GetServerFeel())){ + listItem = listItem->upperItem; + } + + break; + } + } + + if ((listItem && item->lowerItem == listItem->lowerItem) + || (listItem == NULL && item == fTopItem)) + { + // do nothing! The window will be in the same position it is now. + } + else{ + // if it's a normal window, first remove any floating windows, + // it or its application has + if(newLast->GetServerFeel() == B_NORMAL_FEEL && fFrontItem->layerPtr == newLast){ + ListData *iter = item->lowerItem; + while(iter && + (iter->layerPtr->GetServerFeel() == B_FLOATING_SUBSET_FEEL + || iter->layerPtr->GetServerFeel() == B_FLOATING_APP_FEEL)) + { + // *carefully* remove the item from the list + ListData *itemX = iter; + iter = iter->lowerItem; + RemoveItem(itemX); + } + + } + + WinBorder *nextPreferred = item->upperItem? item->upperItem->layerPtr: NULL; + bool wasFront = fFrontItem->layerPtr == newLast; + bool wasFocus = fFocusItem->layerPtr == newLast; + // remove item + RemoveItem(item); + // insert in the new, right' position. + InsertItem(item, listItem? listItem->lowerItem: fTopItem); + + if (wasFront) + SearchAndSetNewFront(nextPreferred); + if (wasFocus) + SearchAndSetNewFocus(nextPreferred); + } +STRACESTREAM(); + } + else + STRACE((" this operation was not needed\n")); +} +//--------------------------------------------------------------------------- +void Workspace::SetLocalSpace(const uint32 colorspace){ + fSpace = colorspace; +} +//--------------------------------------------------------------------------- +uint32 Workspace::LocalSpace() const{ + return fSpace; +} +//--------------------------------------------------------------------------- +void Workspace::SetBGColor(const RGBColor &c){ + fBGColor = c; +} +//--------------------------------------------------------------------------- +RGBColor Workspace::BGColor(void) const{ + return fBGColor; +} +//--------------------------------------------------------------------------- +// Debug methods!!! +//--------------------------------------------------------------------------- +void Workspace::PrintToStream() const{ + printf("Workspace %ld hierarchy shown from back to front:\n", fID); + for (ListData *item = fTopItem; item != NULL; item = item->lowerItem){ + WinBorder *wb = (WinBorder*)item->layerPtr; + printf("\tName: %s\t%s", wb->GetName(), wb->IsHidden()?"Hidden\t": "NOT Hidden"); + if (wb->Window()->GetFeel() == B_FLOATING_SUBSET_WINDOW_FEEL) + printf("\t%s\n", "B_FLOATING_SUBSET_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_FLOATING_APP_WINDOW_FEEL) + printf("\t%s\n", "B_FLOATING_APP_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_FLOATING_ALL_WINDOW_FEEL) + printf("\t%s\n", "B_FLOATING_ALL_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_MODAL_SUBSET_WINDOW_FEEL) + printf("\t%s\n", "B_MODAL_SUBSET_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_MODAL_APP_WINDOW_FEEL) + printf("\t%s\n", "B_MODAL_APP_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_MODAL_ALL_WINDOW_FEEL) + printf("\t%s\n", "B_MODAL_ALL_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_NORMAL_WINDOW_FEEL) + printf("\t%s\n", "B_NORMAL_WINDOW_FEEL"); + if (wb->Window()->GetFeel() == B_SYSTEM_LAST) + printf("\t%s\n", "B_SYSTEM_LAST"); + if (wb->Window()->GetFeel() == B_SYSTEM_FIRST) + printf("\t%s\n", "B_SYSTEM_FIRST"); + } + printf("Focus Layer:\t%s\n", fFocusItem? fFocusItem->layerPtr->GetName(): "NULL"); + printf("Front Layer:\t%s\n", fFrontItem? fFrontItem->layerPtr->GetName(): "NULL"); +// printf("Current Layer:\t%s\n", fCurrentItem? fCurrentItem->layerPtr->GetName(): "NULL"); +// printf("Top Layer:\t%s\n", fTopItem? fTopItem->layerPtr->GetName(): "NULL"); +// printf("Bottom Layer:\t%s\n", fBottomItem? fBottomItem->layerPtr->GetName(): "NULL"); +} diff --git a/src/servers/app/server/Workspace.h b/src/servers/app/server/Workspace.h new file mode 100644 index 0000000000..69b7653f41 --- /dev/null +++ b/src/servers/app/server/Workspace.h @@ -0,0 +1,76 @@ +#ifndef _WORKSPACE_H_ +#define _WORKSPACE_H_ + +#include + +#include "RGBColor.h" + +class WinBorder; +class RBGColor; + +struct ListData{ + WinBorder *layerPtr; + ListData *upperItem; + ListData *lowerItem; +}; + +class Workspace +{ +public: + Workspace(const uint32 colorspace, + int32 ID, + const RGBColor& BGColor); + ~Workspace(); + + bool AddLayerPtr(WinBorder* layer); + bool RemoveLayerPtr(WinBorder* layer); + bool SetFocusLayer(WinBorder* layer); + WinBorder* FocusLayer() const; + bool SetFrontLayer(WinBorder* layer); + WinBorder* FrontLayer() const; + + void MoveToBack(WinBorder* newLast); + + WinBorder* GoToBottomItem(); // the one that's visible. + WinBorder* GoToUpperItem(); + WinBorder* GoToTopItem(); + WinBorder* GoToLowerItem(); + bool GoToItem(WinBorder* layer); + + void SetLocalSpace(const uint32 colorspace); + uint32 LocalSpace() const; + + void SetBGColor(const RGBColor &c); + RGBColor BGColor(void) const; + + int32 ID() const { return fID; } + +// void SetFlags(const uint32 flags); +// uint32 Flags(void) const; + // debug methods + void PrintToStream() const; + +private: + + void InsertItem(ListData* item, ListData* before); + void RemoveItem(ListData* item); + ListData* HasItem(ListData* item); + ListData* HasItem(WinBorder* layer); + + ListData* FindPlace(ListData* pref); + void SearchAndSetNewFront(WinBorder* preferred); + void SearchAndSetNewFocus(WinBorder* preferred); + + int32 fID; + uint32 fSpace; +// uint32 fFlags; + RGBColor fBGColor; + + ListData *fBottomItem, // first visible onscreen + *fTopItem, // the last visible(or covered by other Layers) + *fCurrentItem, // pointer to the currect element in the list + *fFocusItem, // the focus WinBorder - for keyboard events + *fFrontItem; // the one the mouse can bring in front as possible(in its set) +}; + +#endif