From 47b0fc0ee32c124700ce0b23c1711e6df50dff5a Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Sat, 5 Apr 2003 01:51:35 +0000 Subject: [PATCH] Lots of minor tweaks here and there Added debug code to a number of files Enabled ServerWindow and WinBorder mouse-handling code ScreenDriver is now double-buffered (exceedingly useful for testing) I'm trying to think, but nothing happens! :D git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3052 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/server/AppServer.cpp | 2 +- src/servers/app/server/CursorManager.cpp | 10 +- src/servers/app/server/DefaultDecorator.cpp | 6 +- src/servers/app/server/Desktop.cpp | 61 +- src/servers/app/server/Desktop.h | 8 +- src/servers/app/server/DesktopClasses.cpp | 56 + src/servers/app/server/Layer.cpp | 13 +- src/servers/app/server/Layer.h | 1 + src/servers/app/server/RGBColor.cpp | 2 +- src/servers/app/server/RGBColor.h | 2 +- src/servers/app/server/RootLayer.cpp | 2 + src/servers/app/server/ScreenDriver.cpp | 2373 +++++-------------- src/servers/app/server/ScreenDriver.h | 252 +- src/servers/app/server/ServerApp.cpp | 4 +- src/servers/app/server/ServerConfig.h | 2 +- src/servers/app/server/ServerWindow.cpp | 53 +- src/servers/app/server/WinBorder.cpp | 185 +- 17 files changed, 1065 insertions(+), 1967 deletions(-) diff --git a/src/servers/app/server/AppServer.cpp b/src/servers/app/server/AppServer.cpp index 6e2325dd68..ee4c20c0db 100644 --- a/src/servers/app/server/AppServer.cpp +++ b/src/servers/app/server/AppServer.cpp @@ -130,7 +130,7 @@ AppServer::AppServer(void) _decor_lock=create_sem(1,"app_server_decor_sem"); // Get the driver first - Poller thread utilizes the thing - _driver=GetGfxDriver(); + _driver=GetGfxDriver(ActiveScreen()); // Spawn our input-polling thread _poller_id=spawn_thread(PollerThread, "Poller", B_NORMAL_PRIORITY, this); diff --git a/src/servers/app/server/CursorManager.cpp b/src/servers/app/server/CursorManager.cpp index a8546f275c..9906ecf824 100644 --- a/src/servers/app/server/CursorManager.cpp +++ b/src/servers/app/server/CursorManager.cpp @@ -150,7 +150,7 @@ void CursorManager::ShowCursor(void) { acquire_sem(_lock); - DisplayDriver *driver=GetGfxDriver(); + DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->ShowCursor(); release_sem(_lock); } @@ -160,7 +160,7 @@ void CursorManager::HideCursor(void) { acquire_sem(_lock); - DisplayDriver *driver=GetGfxDriver(); + DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->HideCursor(); release_sem(_lock); } @@ -170,7 +170,7 @@ void CursorManager::ObscureCursor(void) { acquire_sem(_lock); - DisplayDriver *driver=GetGfxDriver(); + DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->ObscureCursor(); release_sem(_lock); } @@ -185,7 +185,7 @@ void CursorManager::SetCursor(int32 token) ServerCursor *c=_FindCursor(token); if(c) { - DisplayDriver *driver=GetGfxDriver(); + DisplayDriver *driver=GetGfxDriver(ActiveScreen()); driver->SetCursor(c); _current_which=B_CURSOR_OTHER; } @@ -196,7 +196,7 @@ void CursorManager::SetCursor(cursor_which which) { acquire_sem(_lock); - DisplayDriver *driver=GetGfxDriver(); + DisplayDriver *driver=GetGfxDriver(ActiveScreen()); switch(which) { case B_CURSOR_DEFAULT: diff --git a/src/servers/app/server/DefaultDecorator.cpp b/src/servers/app/server/DefaultDecorator.cpp index 6d89ea8df0..54fa440bd5 100644 --- a/src/servers/app/server/DefaultDecorator.cpp +++ b/src/servers/app/server/DefaultDecorator.cpp @@ -32,6 +32,8 @@ #include "RGBColor.h" //#define DEBUG_DECORATOR + + #define USE_VIEW_FILL_HACK #ifdef DEBUG_DECORATOR @@ -141,8 +143,8 @@ else if(_tabrect.Contains(pt)) { // Here's part of our window management stuff - if(buttons==B_PRIMARY_MOUSE_BUTTON && !GetFocus()) - return CLICK_MOVETOFRONT; +// if(buttons==B_PRIMARY_MOUSE_BUTTON && !GetFocus()) +// return CLICK_MOVETOFRONT; if(buttons==B_SECONDARY_MOUSE_BUTTON) return CLICK_MOVETOBACK; return CLICK_DRAG; diff --git a/src/servers/app/server/Desktop.cpp b/src/servers/app/server/Desktop.cpp index d3252829de..4aba8262e5 100644 --- a/src/servers/app/server/Desktop.cpp +++ b/src/servers/app/server/Desktop.cpp @@ -41,6 +41,12 @@ #include "ServerWindow.h" +//#define DEBUG_DESKTOP + +#ifdef DEBUG_DESKTOP +#include +#endif + //! This namespace encapsulates all globals specifically for the desktop namespace desktop_private { int8 *dragmessage=NULL; @@ -73,12 +79,14 @@ void unlock_workspaces(void) { desktop_private::workspacelock.Unlock(); } */ void InitDesktop(void) { +#ifdef DEBUG_DESKTOP +printf("Desktop: InitWorkspace\n"); +#endif desktop_private::screenlist=new BList(0); DisplayDriver *tdriver; Screen *s=NULL; #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. @@ -99,6 +107,9 @@ void InitDesktop(void) tdriver->Shutdown(); delete tdriver; tdriver=NULL; +#ifdef DEBUG_DESKTOP +printf("\t NULL display driver. OK. We crash now. :P\n"); +#endif } #else @@ -123,6 +134,9 @@ void InitDesktop(void) tdriver->Shutdown(); delete tdriver; tdriver=NULL; +#ifdef DEBUG_DESKTOP +printf("\t NULL display driver. OK. We crash now. :P\n"); +#endif } #endif @@ -133,11 +147,18 @@ void InitDesktop(void) desktop_private::activescreen=s; s->SetSpace(0,B_32_BIT_640x480,true); } +#ifdef DEBUG_DESKTOP +else +printf("ERROR: NULL display driver\n"); +#endif } //! Shuts down the graphics subsystem void ShutdownDesktop(void) { +#ifdef DEBUG_DESKTOP +printf("Desktop: ShutdownDesktop\n"); +#endif Screen *s; for(int32 i=0;iCountItems();i++) @@ -165,6 +186,9 @@ void ShutdownDesktop(void) */ void AddWorkspace(int32 index=-1) { +#ifdef DEBUG_DESKTOP +printf("Desktop: AddWorkspace(%ld)\n",index+1); +#endif lock_workspaces(); lock_layers(); @@ -192,6 +216,9 @@ void AddWorkspace(int32 index=-1) */ void DeleteWorkspace(int32 index) { +#ifdef DEBUG_DESKTOP +printf("Desktop: DeleteWorkspace(%ld)\n",index+1); +#endif lock_workspaces(); lock_layers(); @@ -214,7 +241,6 @@ void DeleteWorkspace(int32 index) */ int32 CountWorkspaces(void) { - lock_workspaces(); lock_layers(); @@ -238,6 +264,9 @@ int32 CountWorkspaces(void) */ void SetWorkspaceCount(int32 count) { +#ifdef DEBUG_DESKTOP +printf("Desktop: SetWorkspaceCount(%ld)\n",count); +#endif if(count<1 || count>32) return; lock_workspaces(); @@ -290,6 +319,9 @@ Workspace *WorkspaceAt(int32 index) */ void SetWorkspace(int32 workspace) { +#ifdef DEBUG_DESKTOP +printf("Desktop: SetWorkspace(%ld)\n",workspace+1); +#endif lock_workspaces(); if(workspace<0 || workspace>(CountWorkspaces()-1)) { @@ -314,6 +346,9 @@ void SetWorkspace(int32 workspace) */ void SetScreen(screen_id id) { +#ifdef DEBUG_DESKTOP +printf("Desktop: SetScreen(%ld)\n",id.id); +#endif Screen *scr; for(int32 i=0;iCountItems();i++) { @@ -355,7 +390,7 @@ screen_id ActiveScreen(void) 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=B_MAIN_SCREEN_ID) +DisplayDriver *GetGfxDriver(screen_id screen) { return (desktop_private::activescreen)?desktop_private::activescreen->GetGfxDriver():NULL; } @@ -370,8 +405,12 @@ DisplayDriver *GetGfxDriver(screen_id screen=B_MAIN_SCREEN_ID) Because of the lack of outside multimonitor support, the screen ID is ignored for now. */ -status_t SetSpace(int32 index, int32 res, bool stick=true, screen_id screen=B_MAIN_SCREEN_ID) +status_t SetSpace(int32 index, int32 res, screen_id screen, bool stick=true) { +#ifdef DEBUG_DESKTOP +printf("Desktop: SetSpace(%ld,%ld,%s,%ld)\n",index+1,res, + stick?"stick":"non-stick",screen.id); +#endif desktop_private::workspacelock.Lock(); status_t stat=desktop_private::activescreen->SetSpace(index,res,stick); desktop_private::workspacelock.Unlock(); @@ -384,8 +423,12 @@ status_t SetSpace(int32 index, int32 res, bool stick=true, screen_id screen=B_MA \param workspace index of the workspace to add the window to \param screen Optional screen specifier. Currently unused. */ -void AddWindowToDesktop(ServerWindow *win, int32 workspace=B_CURRENT_WORKSPACE, screen_id screen=B_MAIN_SCREEN_ID) +void AddWindowToDesktop(ServerWindow *win, int32 workspace, screen_id screen) { +#ifdef DEBUG_DESKTOP +printf("Desktop: AddWindowToDesktop(%s,%ld,%ld)\n",win?win->GetTitle():"NULL", + workspace+1,screen.id); +#endif // Workspace() will be non-NULL if it has already been added to the desktop if(!win || win->GetWorkspace()) return; @@ -407,6 +450,9 @@ void AddWindowToDesktop(ServerWindow *win, int32 workspace=B_CURRENT_WORKSPACE, */ void RemoveWindowFromDesktop(ServerWindow *win) { +#ifdef DEBUG_DESKTOP +printf("Desktop: RemoveWindowFromDesktop(%s)\n",win?win->GetTitle():"NULL"); +#endif lock_workspaces(); lock_layers(); @@ -438,6 +484,9 @@ ServerWindow *GetActiveWindow(void) */ void SetActiveWindow(ServerWindow *win) { +#ifdef DEBUG_DESKTOP +printf("Desktop: SetActiveWindow(%s)\n",win?win->GetTitle():"NULL"); +#endif lock_workspaces(); Workspace *w=desktop_private::activescreen->GetActiveWorkspace(); if(win->GetWorkspace()!=w) @@ -458,7 +507,7 @@ void SetActiveWindow(ServerWindow *win) \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=B_CURRENT_WORKSPACE, screen_id screen=B_MAIN_SCREEN_ID) +Layer *GetRootLayer(int32 workspace, screen_id screen) { lock_workspaces(); lock_layers(); diff --git a/src/servers/app/server/Desktop.h b/src/servers/app/server/Desktop.h index 66d8d7e16a..2a8c470996 100644 --- a/src/servers/app/server/Desktop.h +++ b/src/servers/app/server/Desktop.h @@ -47,14 +47,14 @@ void SetWorkspace(int32 workspace); void SetScreen(screen_id id); int32 CountScreens(void); screen_id ActiveScreen(void); -DisplayDriver *GetGfxDriver(screen_id screen=B_MAIN_SCREEN_ID); -status_t SetSpace(int32 index, int32 res, bool stick=true, screen_id screen=B_MAIN_SCREEN_ID); +DisplayDriver *GetGfxDriver(screen_id screen); +status_t SetSpace(int32 index, int32 res, screen_id screen, bool stick=true); -void AddWindowToDesktop(ServerWindow *win, int32 workspace=B_CURRENT_WORKSPACE, screen_id screen=B_MAIN_SCREEN_ID); +void AddWindowToDesktop(ServerWindow *win, int32 workspace, screen_id screen); void RemoveWindowFromDesktop(ServerWindow *win); ServerWindow *GetActiveWindow(void); void SetActiveWindow(ServerWindow *win); -Layer *GetRootLayer(int32 workspace=B_CURRENT_WORKSPACE, screen_id screen=B_MAIN_SCREEN_ID); +Layer *GetRootLayer(int32 workspace, screen_id screen); void set_drag_message(int32 size, int8 *flattened); int8* get_drag_message(int32 *size); diff --git a/src/servers/app/server/DesktopClasses.cpp b/src/servers/app/server/DesktopClasses.cpp index 6769fb3c4b..63609939e1 100644 --- a/src/servers/app/server/DesktopClasses.cpp +++ b/src/servers/app/server/DesktopClasses.cpp @@ -30,6 +30,16 @@ #include "ServerWindow.h" #include "WinBorder.h" +//#define DEBUG_WORKSPACE +//#define DEBUG_SCREEN + +#ifdef DEBUG_WORKSPACE +#include +#endif +#ifdef DEBUG_SCREEN +#include +#endif + // Defined and initialized in AppServer.cpp extern RGBColor workspace_default_color; TokenHandler screen_id_handler; @@ -49,6 +59,9 @@ Workspace::Workspace(const graphics_card_info &gcinfo, const frame_buffer_info & _rootlayer=new RootLayer(BRect(0,0,fbinfo.display_width-1,fbinfo.display_height-1), "Workspace Root",_screen->GetGfxDriver()); _rootlayer->SetColor(workspace_default_color); +#ifdef DEBUG_WORKSPACE +printf("Workspace::Workspace(%s)\n",_rootlayer->GetName()); +#endif } /*! @@ -56,6 +69,9 @@ Workspace::Workspace(const graphics_card_info &gcinfo, const frame_buffer_info & */ Workspace::~Workspace(void) { +#ifdef DEBUG_WORKSPACE +printf("Workspace::~Workspace(%s)\n",_rootlayer->GetName()); +#endif if(_rootlayer) { _rootlayer->PruneTree(); @@ -70,6 +86,9 @@ Workspace::~Workspace(void) */ void Workspace::SetBGColor(const RGBColor &c) { +#ifdef DEBUG_WORKSPACE +printf("Workspace::SetBGColor(): "); c.PrintToStream(); +#endif _rootlayer->SetColor(c); } @@ -98,6 +117,9 @@ RootLayer *Workspace::GetRoot(void) */ void Workspace::SetData(const graphics_card_info &gcinfo, const frame_buffer_info &fbinfo) { +#ifdef DEBUG_WORKSPACE +printf("Workspace::SetData(%s)\n",_rootlayer->GetName()); +#endif if(_fbinfo.display_width!=fbinfo.display_width || _fbinfo.display_height!=fbinfo.display_height) { @@ -128,6 +150,9 @@ void Workspace::GetData(graphics_card_info *gcinfo, frame_buffer_info *fbinfo) */ void Workspace::SetSpace(int32 res) { +#ifdef DEBUG_WORKSPACE +printf("Workspace::SetSpace(%ld) unimplemented\n",res); +#endif // TODO: Implement } @@ -138,6 +163,9 @@ void Workspace::SetSpace(int32 res) */ Screen::Screen(DisplayDriver *gfxmodule, uint8 workspaces) { +#ifdef DEBUG_SCREEN +printf("Screen::Screen(%s,%u)\n",gfxmodule?"driver":"NULL",workspaces); +#endif _workspacelist=NULL; _driver=gfxmodule; _resolution=0; @@ -189,6 +217,9 @@ Screen::Screen(DisplayDriver *gfxmodule, uint8 workspaces) */ Screen::~Screen(void) { +#ifdef DEBUG_SCREEN +printf("Screen::~Screen\n"); +#endif if ( _workspacelist ) { int i; @@ -206,6 +237,9 @@ Screen::~Screen(void) */ void Screen::AddWorkspace(int32 index) { +#ifdef DEBUG_SCREEN +printf("Screen::AddWorkspace(%ld)\n",index+1); +#endif Workspace *workspace = new Workspace(_gcinfo,_fbinfo,this); if ( (index == -1) || !_workspacelist->AddItem(workspace,index) ) _workspacelist->AddItem(workspace); @@ -217,6 +251,9 @@ void Screen::AddWorkspace(int32 index) */ void Screen::DeleteWorkspace(int32 index) { +#ifdef DEBUG_SCREEN +printf("Screen::DeleteWorkspace(%ld)\n",index+1); +#endif Workspace *workspace; workspace = (Workspace *)_workspacelist->RemoveItem(index); if ( workspace ) @@ -255,6 +292,10 @@ void Screen::SetWorkspaceCount(int32 count) _workspacecount = count; if ( _currentworkspace > count-1 ) SetWorkspace(count-1); + +#ifdef DEBUG_SCREEN +printf("Screen::SetWorkspaceCount(%ld)\n",count); +#endif } /*! @@ -272,6 +313,9 @@ int32 Screen::CurrentWorkspace(void) */ void Screen::SetWorkspace(int32 index) { +#ifdef DEBUG_SCREEN +printf("Screen::SetWorkspace(%ld)\n",index+1); +#endif if ( (index >= 0) && (index <= _workspacecount-1) ) { _currentworkspace = index; @@ -285,6 +329,9 @@ void Screen::SetWorkspace(int32 index) */ void Screen::Activate(bool active) { +#ifdef DEBUG_SCREEN +printf("Screen::Activate(%s)\n",active?"active":"inactive"); +#endif _active=active; } @@ -306,6 +353,9 @@ DisplayDriver *Screen::GetGfxDriver(void) */ status_t Screen::SetSpace(int32 index, int32 res,bool stick) { +#ifdef DEBUG_SCREEN +printf("Screen::SetSpace(%ld,%ld,%s)\n",index,res,stick?"stick":"non-stick"); +#endif // the specified workspace isn't active, so this should be easy... Workspace *wkspc=(Workspace*)_workspacelist->ItemAt(index); if(!wkspc) @@ -332,6 +382,9 @@ status_t Screen::SetSpace(int32 index, int32 res,bool stick) */ void Screen::AddWindow(ServerWindow *win, int32 workspace) { +#ifdef DEBUG_SCREEN +printf("Screen::AddWindow(%s,%ld)\n",win?win->GetTitle():"NULL", workspace+1); +#endif if(!win || !win->_winborder) return; @@ -349,6 +402,9 @@ void Screen::AddWindow(ServerWindow *win, int32 workspace) */ void Screen::RemoveWindow(ServerWindow *win) { +#ifdef DEBUG_SCREEN +printf("Screen::RemoveWindow(%s)\n",win?win->GetTitle():"NULL"); +#endif if(!win || !win->_winborder) return; diff --git a/src/servers/app/server/Layer.cpp b/src/servers/app/server/Layer.cpp index f05f891cdf..eca4123cab 100644 --- a/src/servers/app/server/Layer.cpp +++ b/src/servers/app/server/Layer.cpp @@ -35,7 +35,7 @@ #include "TokenHandler.h" #include "RectUtils.h" -#define DEBUG_LAYER +//#define DEBUG_LAYER //! TokenHandler object used to provide IDs for all Layers and, thus, BViews TokenHandler view_token_handler; @@ -970,3 +970,14 @@ BRect Layer::ConvertFromTop(BRect rect) else return(rect); } + +// TODO: Implement and document +void Layer::MakeTopChild(void) +{ +} + +// TODO: Implement and document +void Layer::MakeBottomChild(void) +{ +} + diff --git a/src/servers/app/server/Layer.h b/src/servers/app/server/Layer.h index 46e01174e4..696b64a2e1 100644 --- a/src/servers/app/server/Layer.h +++ b/src/servers/app/server/Layer.h @@ -65,6 +65,7 @@ public: Layer *FindLayer(int32 token); Layer *GetChildAt(BPoint pt, bool recursive=false); PortLink *GetLink(void); + const char *GetName(void) { return (_name)?_name->String():NULL; } void Invalidate(BRect rect); void Invalidate(BRegion region); diff --git a/src/servers/app/server/RGBColor.cpp b/src/servers/app/server/RGBColor.cpp index 7119e4f554..a9d69266dc 100644 --- a/src/servers/app/server/RGBColor.cpp +++ b/src/servers/app/server/RGBColor.cpp @@ -289,7 +289,7 @@ RGBColor RGBColor::MakeBlendColor(RGBColor color, float position) /*! \brief Prints the 32-bit values of the color to standard out */ -void RGBColor::PrintToStream(void) +void RGBColor::PrintToStream(void) const { printf("RGBColor (%u,%u,%u,%u)\n", color32.red,color32.green,color32.blue,color32.alpha); } diff --git a/src/servers/app/server/RGBColor.h b/src/servers/app/server/RGBColor.h index e6a2622370..0c50a2537f 100644 --- a/src/servers/app/server/RGBColor.h +++ b/src/servers/app/server/RGBColor.h @@ -49,7 +49,7 @@ public: RGBColor(const RGBColor &col); RGBColor(void); - void PrintToStream(void); + void PrintToStream(void) const; uint8 GetColor8(void); uint16 GetColor16(void); diff --git a/src/servers/app/server/RootLayer.cpp b/src/servers/app/server/RootLayer.cpp index 9dca0f184c..9f4a7b6a4a 100644 --- a/src/servers/app/server/RootLayer.cpp +++ b/src/servers/app/server/RootLayer.cpp @@ -44,11 +44,13 @@ RootLayer::RootLayer(BRect rect, const char *layername, DisplayDriver *gfxdriver _driver=gfxdriver; _invalid=new BRegion(Bounds()); _is_dirty=true; + _bgcolor=new RGBColor(); } //! Frees all allocated heap memory (which happens to be none) ;) RootLayer::~RootLayer() { + delete _bgcolor; } /*! diff --git a/src/servers/app/server/ScreenDriver.cpp b/src/servers/app/server/ScreenDriver.cpp index e6961f2382..38242b2cd8 100644 --- a/src/servers/app/server/ScreenDriver.cpp +++ b/src/servers/app/server/ScreenDriver.cpp @@ -21,80 +21,51 @@ // // File Name: ScreenDriver.cpp // Author: DarkWyrm -// Gabe Yoder -// Description: BWindowScreen graphics module +// Description: BView/BWindow combination graphics module // //------------------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "Angle.h" -#include "PatternHandler.h" -#include "ScreenDriver.h" +#include "PortLink.h" #include "ServerProtocol.h" #include "ServerBitmap.h" -#include "ServerCursor.h" +#include "ScreenDriver.h" #include "ServerConfig.h" -#include "SystemPalette.h" -#include "ColorUtils.h" -#include "PortLink.h" +#include "ServerCursor.h" +#include "ServerFont.h" #include "FontFamily.h" -#include "RGBColor.h" #include "LayerData.h" -#include -#include -#include -#include -#include #include "PNGDump.h" -#define CLIP_X(a) ( (a < 0) ? 0 : ((a > fbuffer->gcinfo.width-1) ? \ - fbuffer->gcinfo.width-1 : a) ) -#define CLIP_Y(a) ( (a < 0) ? 0 : ((a > fbuffer->gcinfo.height-1) ? \ - fbuffer->gcinfo.height-1 : a) ) -#define CHECK_X(a) ( (a >= 0) || (a <= fbuffer->gcinfo.width-1) ) -#define CHECK_Y(a) ( (a >= 0) || (a <= fbuffer->gcinfo.height-1) ) +enum +{ +SDWIN_CLEAR=100, -// TODO: add code to take advantage of HW acceleration - -extern RGBColor workspace_default_color; // defined in AppServer.cpp +SDWIN_SHOWCURSOR, +SDWIN_HIDECURSOR, +SDWIN_OBSCURECURSOR, +SDWIN_MOVECURSOR, +SDWIN_SETCURSOR, +}; //TODO: Remove the need for these int64 patsolidhigh64=0xFFFFFFFFLL; int8 *patsolidhigh=(int8*)patsolidhigh64; -void HLine_32Bit(graphics_card_info i, uint16 x, uint16 y, uint16 length, rgb_color col); -void HLine_16Bit(graphics_card_info i, uint16 x, uint16 y, uint16 length, uint16 col); -void HLine_16Bit(graphics_card_info i, uint16 x, uint16 y, uint16 length, uint8 col); - -class LineCalc -{ -public: - LineCalc(const BPoint &pta, const BPoint &ptb); - float GetX(float y); - float GetY(float x); - float Slope(void) { return slope; } - float Offset(void) { return offset; } -private: - float slope; - float offset; - BPoint start, end; -}; - -LineCalc::LineCalc(const BPoint &pta, const BPoint &ptb) -{ - start=pta; - end=ptb; - slope=(start.y-end.y)/(start.x-end.x); - offset=start.y-(slope * start.x); -} - -float LineCalc::GetX(float y) -{ - return ( (y-offset)/slope ); -} - -float LineCalc::GetY(float x) -{ - return ( (slope * x) + offset ); -} +extern RGBColor workspace_default_color; FrameBuffer::FrameBuffer(const char *title, uint32 space, status_t *st,bool debug) : BWindowScreen(title,space,st,debug) @@ -104,21 +75,32 @@ FrameBuffer::FrameBuffer(const char *title, uint32 space, status_t *st,bool debu serverlink=new PortLink(serverport); mousepos.Set(0,0); buttons=0; + viewbmp=new BBitmap(BRect(0,0,639,479),B_CMAP8,true); // View exists to poll for the mouse view=new BView(Bounds(),"view",0,0); AddChild(view); view->GetMouse(&mousepos,&buttons); + + invalid=new BRegion(Bounds()); + invalidflag=0; + #ifdef ENABLE_INPUT_SERVER_EMULATION monitor_thread=spawn_thread(MouseMonitor,"mousemonitor",B_NORMAL_PRIORITY,this); resume_thread(monitor_thread); #endif + + copy_thread=spawn_thread(CopyThread,"copymonitor",B_NORMAL_PRIORITY,this); + resume_thread(copy_thread); } FrameBuffer::~FrameBuffer(void) { - delete serverlink; + kill_thread(copy_thread); kill_thread(monitor_thread); + delete viewbmp; + delete invalid; + delete serverlink; } void FrameBuffer::ScreenConnected(bool connected) @@ -129,34 +111,6 @@ void FrameBuffer::ScreenConnected(bool connected) // Cache the state just in case graphics_card_info *info=CardInfo(); gcinfo=*info; - - // Add our spiffy HW acceleration support -// graphics_card_hook gchook; -/* _ae=(acquire_engine)CardHookAt(B_ACQUIRE_ENGINE); - _re=(release_engine)CardHookAt(B_RELEASE_ENGINE); - _s2sb=(screen_to_screen_blit)CardHookAt(B_SCREEN_TO_SCREEN_BLIT); - _fspan=(fill_span)CardHookAt(B_FILL_SPAN); - _ir=(invert_rectangle)CardHookAt(HWINVERT); - - printf("Hardware Acceleration capabilities:\n"); - if(_ae) - printf("Acquire Engine\n"); - if(_re) - printf("Release Engine\n"); - if(_s2sb) - printf("Screen-To-Screen Blit\n"); - if(_fspan) - printf("Fill Span\n"); - if(_ir) - printf("Invert Rectangle\n"); - - gchook=CardHookAt(HWLINE_32BIT); - if(gchook) - printf("32-big line\n"); - gchook=CardHookAt(HWBLIT); - if(gchook) - printf("Screen Blit\n"); -*/ } } @@ -219,6 +173,41 @@ bool FrameBuffer::QuitRequested(void) return true; } +int32 FrameBuffer::CopyThread(void *data) +{ + FrameBuffer *fb=(FrameBuffer*)data; + + while(1) + { + if(fb->IsConnected()) + { + if(fb->invalidflag) + { + fb->Lock(); + fb->viewbmp->Lock(); + + if(fb->invalid) + { + int8 *start_ptr; + clipping_rect r; + for(int32 i=0; iinvalid->CountRects(); i++) + { + // Copy from viewbmp to framebuffer + start_ptr=(int8*)fb->viewbmp->Bits(); + r=fb->invalid->RectAtInt(i); + memcpy(fb->gcinfo.frame_buffer,start_ptr,fb->viewbmp->BitsLength()); + } + } + + fb->viewbmp->Unlock(); + fb->Unlock(); + } + } + } + + return 0; +} + int32 FrameBuffer::MouseMonitor(void *data) { FrameBuffer *fb=(FrameBuffer*)data; @@ -303,1657 +292,615 @@ int32 FrameBuffer::MouseMonitor(void *data) delete link; } -/*! - \brief Sets up internal variables needed by all DisplayDriver subclasses - - Subclasses should follow DisplayDriver's lead and use this function mostly - for initializing data members. -*/ -ScreenDriver::ScreenDriver(void) : DisplayDriver() +void FrameBuffer::Invalidate(const BRect &r) +{ + if(invalid) + invalid->Include(r); + else + invalid=new BRegion(r); +} + +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- +//----------------------------------------------------------------------- + +ScreenDriver::ScreenDriver(void) { status_t st; - fbuffer=new FrameBuffer("OBAppServer",B_8_BIT_640x480,&st,true); - - cursor=NULL; - under_cursor=NULL; - cursorframe.Set(0,0,0,0); - _SetMode(B_8_BIT_640x480); + screenwin=new FrameBuffer("OBAppServer",B_8_BIT_640x480,&st,false); + + framebuffer=screenwin->viewbmp; + serverlink=screenwin->serverlink; + hide_cursor=0; _SetWidth(640); _SetHeight(480); _SetDepth(8); - _SetBytesPerRow(fbuffer->FrameBufferInfo()->bytes_per_row); + _SetMode(B_8_BIT_640x480); + _SetBytesPerRow(framebuffer->BytesPerRow()); } -/*! - \brief Deletes the locking semaphore - - Subclasses should use the destructor mostly for freeing allocated heap space. -*/ ScreenDriver::~ScreenDriver(void) { - if(cursor) - delete cursor; - if(under_cursor) - delete under_cursor; + if(is_initialized) + { + screenwin->Lock(); + screenwin->Quit(); + screenwin=NULL; + } } -/*! - \brief Initializes the driver object. - \return true if successful, false if not - - Initialize sets up the driver for display, including the initial clearing - of the screen. If things do not go as they should, false should be returned. -*/ bool ScreenDriver::Initialize(void) { - fbuffer->Show(); + _Lock(); + drawview=new BView(framebuffer->Bounds(),"drawview",B_FOLLOW_ALL, B_WILL_DRAW); + framebuffer->AddChild(drawview); - // wait 1 sec for the window to show... - snooze(500000); + hide_cursor=0; + obscure_cursor=false; - if(fbuffer->IsConnected()) - { - graphics_card_info *info=fbuffer->CardInfo(); - fbuffer->gcinfo=*info; - - // clear the frame buffer. Otherwise, we'll have garbage in it - LayerData d; - d.highcolor=workspace_default_color; - for(int32 i=0; iheight; i++) - { - Line(BPoint(0,i),BPoint(info->width-1,i),&d,patsolidhigh); -// HLine(0, info->width-1, i, workspace_default_color); - } - } - else - printf("Not connected in Initialize\n"); + is_initialized=true; - // we start out without a cursor shown because otherwise we get glitches in the - // upper left corner. init_desktop *always* sets a cursor, so this shouldn't be a problem + // We can afford to call the above functions without locking + // because the window is locked until Show() is first called + screenwin->Show(); + _Unlock(); return true; } -/*! - \brief Shuts down the driver's video subsystem - - Any work done by Initialize() should be undone here. Note that Shutdown() is - called even if Initialize() was unsuccessful. -*/ void ScreenDriver::Shutdown(void) -{ - fbuffer->Lock(); - fbuffer->Quit(); -} - -/*! - \brief Called for all BView::CopyBits calls - \param src Source rectangle. - \param dest Destination rectangle. - - Bounds checking must be done in this call. If the destination is not the same size - as the source, the source should be scaled to fit. -*/ -void ScreenDriver::CopyBits(BRect src, BRect dest) -{ -printf("ScreenDriver::CopyBits unimplemented\n"); -} - -/*! - \brief Called for all BView::DrawBitmap calls - \param bmp Bitmap to be drawn. It will always be non-NULL and valid. The color - space is not guaranteed to match. - \param src Source rectangle - \param dest Destination rectangle. Source will be scaled to fit if not the same size. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - - Bounds checking must be done in this call. -*/ -void ScreenDriver::DrawBitmap(ServerBitmap *bitmap, BRect source, BRect dest, LayerData *d) { _Lock(); - if(fbuffer->IsConnected()) - { - // Scale bitmap here if source!=dest - - switch(fbuffer->gcinfo.bits_per_pixel) - { - case 32: - case 24: - { - // TODO: Implement - printf("DrawBitmap: 32/24-bit unimplemented\n"); - break; - } - case 16: - case 15: - { - // TODO: Implement - printf("DrawBitmap: 16/15-bit unimplemented\n"); - break; - } - case 8: - { - // TODO: Implement - printf("DrawBitmap: 8-bit unimplemented\n"); - break; - } - default: - { - break; - } - } - } - + screenwin->Disconnect(); + is_initialized=false; _Unlock(); } -/*! - \brief Called for all BView::FillArc calls - \param r Rectangle enclosing the entire arc - \param angle Starting angle for the arc in degrees - \param span Span of the arc in degrees. Ending angle = angle+span. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the arc may end up - being clipped. -*/ -void ScreenDriver::FillArc(BRect r, float angle, float span, LayerData *d, int8 *pat) -{ -} - -/*! - \brief Called for all BView::FillBezier calls. - \param pts 4-element array of BPoints in the order of start, end, and then the two control - points. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call. -*/ -void ScreenDriver::FillBezier(BPoint *pts, LayerData *d, int8 *pat) -{ -} - -/*! - \brief Called for all BView::FillEllipse calls - \param r BRect enclosing the ellipse to be drawn. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the ellipse may end up - being clipped. -*/ -void ScreenDriver::FillEllipse(BRect r, LayerData *ldata, int8 *pat) -{ -// Ellipse code shamelessly stolen from the graphics library gd v2.0.1 and bolted on -// to support our API - long d, b_sq, b_sq_4, b_sq_6; - long a_sq, a_sq_4, a_sq_6; - int x, y, switchem; - long lsqrt (long); - int pix, half, pstart; - int32 thick = (int32)ldata->pensize; - - half = thick / 2; - int32 w=int32(r.Width()/2), - h=int32(r.Height()/2); - int32 cx=(int32)r.left+w; - int32 cy=(int32)r.top+h; - - d = 2 * (long) h *h + (long) w *w - 2 * (long) w *w * h; - b_sq = (long) h *h; - b_sq_4 = 4 * (long) h *h; - b_sq_6 = 6 * (long) h *h; - a_sq = (long) w *w; - a_sq_4 = 4 * (long) w *w; - a_sq_6 = 6 * (long) w *w; - - x = 0; - y = -h; -// switchem = a_sq / lsqrt (a_sq + b_sq); - switchem = a_sq / (int32)sqrt(a_sq + b_sq); - - while (x <= switchem) - { - pstart = y - half; - for (pix = pstart; pix < pstart + thick; pix++) - { - Line( BPoint(cx - x, cy + pix), BPoint(cx + x, cy + pix), ldata, patsolidhigh); - Line( BPoint(cx - x, cy - pix), BPoint(cx + x, cy - pix), ldata, patsolidhigh); - } - if (d < 0) - d += b_sq_4 * x++ + b_sq_6; - else - d += b_sq_4 * x++ + b_sq_6 + a_sq_4 * (++y); - } - - /* Middlesplat! - ** Go a little further if the thickness is not nominal... - */ - if (thick > 1) - { - int xp = x; - int yp = y; - int dp = d; - int thick2 = thick + 2; - int half2 = half + 1; - - while (xp <= switchem + half) - { - pstart = yp - half2; - for (pix = pstart; pix < pstart + thick2; pix++) - { - Line( BPoint(cx - xp, cy + pix), BPoint(cx + xp, cy + pix), ldata, patsolidhigh); - Line( BPoint(cx - xp, cy - pix), BPoint(cx + xp, cy - pix), ldata, patsolidhigh); - } - if (dp < 0) - dp += b_sq_4 * xp++ + b_sq_6; - else - dp += b_sq_4 * xp++ + b_sq_6 + a_sq_4 * (++yp); - } - } - - d += -2 * (long) b_sq + 2 * (long) a_sq - 2 * (long) b_sq *(x - 1) + 2 * (long) a_sq *(y - 1); - - while (y <= 0) - { - pstart = x - half; - for (pix = pstart; pix < pstart + thick; pix++) - { - Line( BPoint(cx - pix, cy + y), BPoint(cx + pix, cy + y), ldata, patsolidhigh); - Line( BPoint(cx - pix, cy - y), BPoint(cx + pix, cy - y), ldata, patsolidhigh); - } - - if (d < 0) - d += a_sq_4 * y++ + a_sq_6 + b_sq_4 * (++x); - else - d += a_sq_4 * y++ + a_sq_6; - } -} - -/*! - \brief Called for all BView::FillRect calls - \param r BRect to be filled. Guaranteed to be in the frame buffer's coordinate space - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - -*/ -void ScreenDriver::FillRect(BRect r, LayerData *d, int8 *pat) -{ - _Lock(); - if(fbuffer->IsConnected()) - { - // int32 width=rect.IntegerWidth(); - for(int32 i=(int32)r.top;i<=r.bottom;i++) - // HLine(fbuffer->gcinfo,(int32)rect.left,i,width,col); - Line(BPoint(r.left,i),BPoint(r.right,i),d,pat); - } - _Unlock(); -} - -/*! - \brief Called for all BView::FillRoundRect calls - \param r The rectangle itself - \param xrad X radius of the corner arcs - \param yrad Y radius of the corner arcs - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the roundrect may end - up being clipped. -*/ -void ScreenDriver::FillRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat) -{ - printf("ScreenDriver::FillRoundRect unimplemented\n"); - StrokeRoundRect(r,xrad,yrad,d,pat); -} - -/*! - \brief Called for all BView::FillTriangle calls - \param pts Array of 3 BPoints. Always non-NULL. - \param r BRect enclosing the triangle. While it will definitely enclose the triangle, - it may not be within the frame buffer's bounds. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the triangle may end - up being clipped. -*/ -void ScreenDriver::FillTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat) -{ - if(!pts || !d || !pat) - return; - - _Lock(); - if(fbuffer->IsConnected()) - { - BPoint first, second, third; - - // Sort points according to their y values - if(pts[0].y < pts[1].y) - { - first=pts[0]; - second=pts[1]; - } - else - { - first=pts[1]; - second=pts[0]; - } - - if(second.ygcinfo.bits_per_pixel) - { - case 32: - case 24: - SetThickPixel32(x,y,thick,col.GetColor32()); - break; - case 16: - case 15: - SetThickPixel16(x,y,thick,col.GetColor16()); - break; - case 8: - SetThickPixel8(x,y,thick,col.GetColor8()); - break; - default: - printf("Unknown pixel depth %d in SetThickPixel\n",fbuffer->gcinfo.bits_per_pixel); - break; - } -} - -void ScreenDriver::SetThickPixel32(int x, int y, int thick, rgb_color col) -{ - // Code courtesy of YNOP's SecondDriver - union - { - uint8 bytes[4]; - uint32 word; - }c1; - - c1.bytes[0]=col.blue; - c1.bytes[1]=col.green; - c1.bytes[2]=col.red; - c1.bytes[3]=col.alpha; - - /* - uint32 *bits=(uint32*)fbuffer->gcinfo.frame_buffer; - *(bits + x + (y*fbuffer->gcinfo.width))=c1.word; - */ - uint32 *bits=(uint32*)fbuffer->gcinfo.frame_buffer+(x-thick/2)+(y-thick/2)*fbuffer->gcinfo.width; - int i,j; - for (i=0; igcinfo.width; - } -} - -void ScreenDriver::SetThickPixel16(int x, int y, int thick, uint16 col) -{ -// TODO: Implement -printf("SetThickPixel16 unimplemented\n"); - -} - -void ScreenDriver::SetThickPixel8(int x, int y, int thick, uint8 col) -{ - // When the DisplayDriver API changes, we'll use the uint8 highcolor. Until then, - // we'll use *pattern - /* - uint8 *bits=(uint8*)fbuffer->gcinfo.frame_buffer; - *(bits + x + (y*fbuffer->gcinfo.bytes_per_row))=col; - */ - - uint8 *bits=(uint8*)fbuffer->gcinfo.frame_buffer+(x-thick/2)+(y-thick/2)*fbuffer->gcinfo.bytes_per_row; - int i,j; - for (i=0; igcinfo.bytes_per_row; - } -} - -void ScreenDriver::SetPixel(int x, int y, RGBColor col) -{ - switch(fbuffer->gcinfo.bits_per_pixel) - { - case 32: - case 24: - SetPixel32(x,y,col.GetColor32()); - break; - case 16: - case 15: - SetPixel16(x,y,col.GetColor16()); - break; - case 8: - SetPixel8(x,y,col.GetColor8()); - break; - default: - break; - } -} - -void ScreenDriver::SetPixel32(int x, int y, rgb_color col) -{ - // Code courtesy of YNOP's SecondDriver - union - { - uint8 bytes[4]; - uint32 word; - }c1; - - c1.bytes[0]=col.blue; - c1.bytes[1]=col.green; - c1.bytes[2]=col.red; - c1.bytes[3]=col.alpha; - - uint32 *bits=(uint32*)fbuffer->gcinfo.frame_buffer; - *(bits + x + (y*fbuffer->gcinfo.width))=c1.word; -} - -void ScreenDriver::SetPixel16(int x, int y, uint16 col) -{ -// TODO: Implement -printf("SetPixel16 unimplemented\n"); - -} - -void ScreenDriver::SetPixel8(int x, int y, uint8 col) -{ - // When the DisplayDriver API changes, we'll use the uint8 highcolor. Until then, - // we'll use *pattern - uint8 *bits=(uint8*)fbuffer->gcinfo.frame_buffer; - *(bits + x + (y*fbuffer->gcinfo.bytes_per_row))=col; - -} - -/*! - \brief Sets the screen mode to specified resolution and color depth. - \param mode constant as defined in GraphicsDefs.h - - Subclasses must include calls to _SetDepth, _SetHeight, _SetWidth, and _SetMode - to update the state variables kept internally by the DisplayDriver class. -*/ void ScreenDriver::SetMode(int32 space) { - _Lock(); - if(fbuffer->IsConnected()) + screenwin->Lock(); + int16 w=640,h=480; + color_space s=B_CMAP8; + + switch(space) { - fbuffer->SetSpace(space); + case B_32_BIT_800x600: + case B_16_BIT_800x600: + case B_8_BIT_800x600: + { + w=800; h=600; + break; + } + case B_32_BIT_1024x768: + case B_16_BIT_1024x768: + case B_8_BIT_1024x768: + { + w=1024; h=768; + break; + } + default: + break; + } + screenwin->ResizeTo(w-1,h-1); + + switch(space) + { + case B_32_BIT_640x480: + case B_32_BIT_800x600: + case B_32_BIT_1024x768: + s=B_RGBA32; + _SetDepth(32); + break; + case B_16_BIT_640x480: + case B_16_BIT_800x600: + case B_16_BIT_1024x768: + s=B_RGBA15; + _SetDepth(15); + break; + case B_8_BIT_640x480: + case B_8_BIT_800x600: + case B_8_BIT_1024x768: + s=B_CMAP8; + _SetDepth(8); + break; + default: + _SetDepth(8); + break; + } + + // Clear the invalid flag so that there is no danger of a crash + while(screenwin->invalidflag>0) + atomic_add(&screenwin->invalidflag,-1); - // We have changed the frame buffer info, so update the cached info - graphics_card_info *info=fbuffer->CardInfo(); - fbuffer->gcinfo=*info; - - // clear the frame buffer. Otherwise, we'll have garbage in it - LayerData d; - d.highcolor=workspace_default_color; - for(int32 i=0; iheight; i++) - { - Line(BPoint(0,i),BPoint(info->width-1,i),&d,patsolidhigh); -// HLine(0,info->width-1,i,workspace_default_color); - } - _SetMode(space); - frame_buffer_info fbi=*fbuffer->FrameBufferInfo(); - _SetBytesPerRow(fbi.bytes_per_row); - _SetWidth(fbi.display_width); - _SetHeight(fbi.display_height); - _SetDepth(fbi.bits_per_pixel); - } - _Unlock(); + delete framebuffer; + + // don't forget to update the internal vars! + _SetWidth(w); + _SetHeight(h); + _SetMode(space); + + screenwin->SetSpace((uint32)space); + + screenwin->viewbmp=new BBitmap(screenwin->Bounds(),s,true); + framebuffer=screenwin->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(); + + screenwin->Invalidate(framebuffer->Bounds()); + + _SetBytesPerRow(framebuffer->BytesPerRow()); + atomic_add(&screenwin->invalidflag,1); + screenwin->Unlock(); } - -/*! - \brief Called for all BView::StrokeArc calls - \param r Rectangle enclosing the entire arc - \param angle Starting angle for the arc in degrees - \param span Span of the arc in degrees. Ending angle = angle+span. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the arc may end up - being clipped. -*/ -void ScreenDriver::StrokeArc(BRect r, float angle, float span, LayerData *d, int8 *pat) +void ScreenDriver::CopyBits(BRect src, BRect dest) { -// TODO: Add pattern support - float xc = (r.left+r.right)/2; - float yc = (r.top+r.bottom)/2; - float rx = r.Width()/2; - float ry = r.Height()/2; - int Rx2 = ROUND(rx*rx); - int Ry2 = ROUND(ry*ry); - int twoRx2 = 2*Rx2; - int twoRy2 = 2*Ry2; - int p; - int x=0; - int y = (int)ry; - int px = 0; - int py = twoRx2 * y; - int startx, endx; - int startQuad, endQuad; - bool useQuad1, useQuad2, useQuad3, useQuad4; - bool shortspan = false; - int thick = (int)d->pensize; - - // Watch out for bozos giving us whacko spans - if ( (span >= 360) || (span <= -360) ) - { - StrokeEllipse(r,d,pat); - return; - } - - if ( span > 0 ) - { - startQuad = (int)(angle/90)%4+1; - endQuad = (int)((angle+span)/90)%4+1; - startx = ROUND(.5*r.Width()*fabs(cos(angle*M_PI/180))); - endx = ROUND(.5*r.Width()*fabs(cos((angle+span)*M_PI/180))); - } - else - { - endQuad = (int)(angle/90)%4+1; - startQuad = (int)((angle+span)/90)%4+1; - endx = ROUND(.5*r.Width()*fabs(cos(angle*M_PI/180))); - startx = ROUND(.5*r.Width()*fabs(cos((angle+span)*M_PI/180))); - } - - if ( startQuad != endQuad ) - { - useQuad1 = (endQuad > 1) && (startQuad > endQuad); - useQuad2 = ((startQuad == 1) && (endQuad > 2)) || ((startQuad > endQuad) && (endQuad > 2)); - useQuad3 = ((startQuad < 3) && (endQuad == 4)) || ((startQuad < 3) && (endQuad < startQuad)); - useQuad4 = (startQuad < 4) && (startQuad > endQuad); - } - else - { - if ( (span < 90) && (span > -90) ) - { - useQuad1 = false; - useQuad2 = false; - useQuad3 = false; - useQuad4 = false; - shortspan = true; - } - else - { - useQuad1 = (startQuad != 1); - useQuad2 = (startQuad != 2); - useQuad3 = (startQuad != 3); - useQuad4 = (startQuad != 4); - } - } - - if ( useQuad1 || - (!shortspan && (((startQuad == 1) && (x <= startx)) || ((endQuad == 1) && (x >= endx)))) || - (shortspan && (startQuad == 1) && (x <= startx) && (x >= endx)) ) - SetThickPixel(xc+x,yc-y,thick,d->highcolor); - if ( useQuad2 || - (!shortspan && (((startQuad == 2) && (x >= startx)) || ((endQuad == 2) && (x <= endx)))) || - (shortspan && (startQuad == 2) && (x >= startx) && (x <= endx)) ) - SetThickPixel(xc-x,yc-y,thick,d->highcolor); - if ( useQuad3 || - (!shortspan && (((startQuad == 3) && (x <= startx)) || ((endQuad == 3) && (x >= endx)))) || - (shortspan && (startQuad == 3) && (x <= startx) && (x >= endx)) ) - SetThickPixel(xc-x,yc+y,thick,d->highcolor); - if ( useQuad4 || - (!shortspan && (((startQuad == 4) && (x >= startx)) || ((endQuad == 4) && (x <= endx)))) || - (shortspan && (startQuad == 4) && (x >= startx) && (x <= endx)) ) - SetThickPixel(xc+x,yc+y,thick,d->highcolor); - - p = ROUND (Ry2 - (Rx2 * ry) + (.25 * Rx2)); - while (px < py) - { - x++; - px += twoRy2; - if ( p < 0 ) - p += Ry2 + px; - else - { - y--; - py -= twoRx2; - p += Ry2 + px - py; - } - - if ( useQuad1 || - (!shortspan && (((startQuad == 1) && (x <= startx)) || ((endQuad == 1) && (x >= endx)))) || - (shortspan && (startQuad == 1) && (x <= startx) && (x >= endx)) ) - SetThickPixel(xc+x,yc-y,thick,d->highcolor); - if ( useQuad2 || - (!shortspan && (((startQuad == 2) && (x >= startx)) || ((endQuad == 2) && (x <= endx)))) || - (shortspan && (startQuad == 2) && (x >= startx) && (x <= endx)) ) - SetThickPixel(xc-x,yc-y,thick,d->highcolor); - if ( useQuad3 || - (!shortspan && (((startQuad == 3) && (x <= startx)) || ((endQuad == 3) && (x >= endx)))) || - (shortspan && (startQuad == 3) && (x <= startx) && (x >= endx)) ) - SetThickPixel(xc-x,yc+y,thick,d->highcolor); - if ( useQuad4 || - (!shortspan && (((startQuad == 4) && (x >= startx)) || ((endQuad == 4) && (x <= endx)))) || - (shortspan && (startQuad == 4) && (x >= startx) && (x <= endx)) ) - SetThickPixel(xc+x,yc+y,thick,d->highcolor); - } - - p = ROUND(Ry2*(x+.5)*(x+.5) + Rx2*(y-1)*(y-1) - Rx2*Ry2); - while (y>0) - { - y--; - py -= twoRx2; - if (p>0) - p += Rx2 - py; - else - { - x++; - px += twoRy2; - p += Rx2 - py +px; - } - - if ( useQuad1 || - (!shortspan && (((startQuad == 1) && (x <= startx)) || ((endQuad == 1) && (x >= endx)))) || - (shortspan && (startQuad == 1) && (x <= startx) && (x >= endx)) ) - SetThickPixel(xc+x,yc-y,thick,d->highcolor); - if ( useQuad2 || - (!shortspan && (((startQuad == 2) && (x >= startx)) || ((endQuad == 2) && (x <= endx)))) || - (shortspan && (startQuad == 2) && (x >= startx) && (x <= endx)) ) - SetThickPixel(xc-x,yc-y,thick,d->highcolor); - if ( useQuad3 || - (!shortspan && (((startQuad == 3) && (x <= startx)) || ((endQuad == 3) && (x >= endx)))) || - (shortspan && (startQuad == 3) && (x <= startx) && (x >= endx)) ) - SetThickPixel(xc-x,yc+y,thick,d->highcolor); - if ( useQuad4 || - (!shortspan && (((startQuad == 4) && (x >= startx)) || ((endQuad == 4) && (x <= endx)))) || - (shortspan && (startQuad == 4) && (x >= startx) && (x <= endx)) ) - SetThickPixel(xc+x,yc+y,thick,d->highcolor); - } + screenwin->Lock(); + framebuffer->Lock(); + drawview->CopyBits(src,dest); + drawview->Sync(); + screenwin->view->Invalidate(src); + screenwin->view->Invalidate(dest); + framebuffer->Unlock(); + screenwin->Unlock(); } -/*! - \brief Called for all BView::StrokeBezier calls. - \param pts 4-element array of BPoints in the order of start, end, and then the two control - points. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call. -*/ -void ScreenDriver::StrokeBezier(BPoint *pts, LayerData *d, int8 *pat) +void ScreenDriver::DrawBitmap(ServerBitmap *bitmap, BRect src, BRect dest) { -// TODO: Add pattern support - double Ax, Bx, Cx, Dx; - double Ay, By, Cy, Dy; - int x, y; - int lastx=-1, lasty=-1; - double t; - double dt = .001; - double dt2, dt3; - double X, Y, dx, ddx, dddx, dy, ddy, dddy; - - Ax = -pts[0].x + 3*pts[1].x - 3*pts[2].x + pts[3].x; - Bx = 3*pts[0].x - 6*pts[1].x + 3*pts[2].x; - Cx = -3*pts[0].x + 3*pts[1].x; - Dx = pts[0].x; - - Ay = -pts[0].y + 3*pts[1].y - 3*pts[2].y + pts[3].y; - By = 3*pts[0].y - 6*pts[1].y + 3*pts[2].y; - Cy = -3*pts[0].y + 3*pts[1].y; - Dy = pts[0].y; - - dt2 = dt * dt; - dt3 = dt2 * dt; - X = Dx; - dx = Ax*dt3 + Bx*dt2 + Cx*dt; - ddx = 6*Ax*dt3 + 2*Bx*dt2; - dddx = 6*Ax*dt3; - Y = Dy; - dy = Ay*dt3 + By*dt2 + Cy*dt; - ddy = 6*Ay*dt3 + 2*By*dt2; - dddy = 6*Ay*dt3; - - lastx = -1; - lasty = -1; - - for (t=0; t<=1; t+=dt) - { - x = ROUND(X); - y = ROUND(Y); - if ( (x!=lastx) || (y!=lasty) ) - SetThickPixel(x,y,d->pensize,d->highcolor); - lastx = x; - lasty = y; - - X += dx; - dx += ddx; - ddx += dddx; - Y += dy; - dy += ddy; - ddy += dddy; - } +#ifdef DEBUG_DRIVER_MODULE +printf("ScreenDriver:: DrawBitmap unimplemented()\n"); +#endif } -/*! - \brief Called for all BView::StrokeEllipse calls - \param r BRect enclosing the ellipse to be drawn. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the ellipse may end up - being clipped. -*/ -void ScreenDriver::StrokeEllipse(BRect r, LayerData *ldata, int8 *pat) +void ScreenDriver::DrawChar(char c, BPoint pt, LayerData *d) { -// Ellipse code shamelessly stolen from the graphics library gd v2.0.1 and bolted on -// to support our API - long d, b_sq, b_sq_4, b_sq_6; - long a_sq, a_sq_4, a_sq_6; - int x, y, switchem; - long lsqrt (long); - int pix, half, pstart; - int32 thick = (int32)ldata->pensize; - - half = thick / 2; - int32 w=int32(r.Width()/2), - h=int32(r.Height()/2); - int32 cx=(int32)r.left+w; - int32 cy=(int32)r.top+h; - - d = 2 * (long) h *h + (long) w *w - 2 * (long) w *w * h; - b_sq = (long) h *h; - b_sq_4 = 4 * (long) h *h; - b_sq_6 = 6 * (long) h *h; - a_sq = (long) w *w; - a_sq_4 = 4 * (long) w *w; - a_sq_6 = 6 * (long) w *w; - - x = 0; - y = -h; -// switchem = a_sq / lsqrt (a_sq + b_sq); - switchem = a_sq / (int32)sqrt(a_sq + b_sq); - - while (x <= switchem) - { - pstart = y - half; - for (pix = pstart; pix < pstart + thick; pix++) - { - SetPixel(cx + x, cy + pix, ldata->highcolor); - SetPixel(cx - x, cy + pix, ldata->highcolor); - SetPixel(cx + x, cy - pix, ldata->highcolor); - SetPixel(cx - x, cy - pix, ldata->highcolor); - } - if (d < 0) - d += b_sq_4 * x++ + b_sq_6; - else - d += b_sq_4 * x++ + b_sq_6 + a_sq_4 * (++y); - } - - /* Middlesplat! - ** Go a little further if the thickness is not nominal... - */ - if (thick > 1) - { - int xp = x; - int yp = y; - int dp = d; - int thick2 = thick + 2; - int half2 = half + 1; - - while (xp <= switchem + half) - { - pstart = yp - half2; - for (pix = pstart; pix < pstart + thick2; pix++) - { - SetPixel(cx + xp, cy + pix, ldata->highcolor); - SetPixel(cx - xp, cy + pix, ldata->highcolor); - SetPixel(cx + xp, cy - pix, ldata->highcolor); - SetPixel(cx - xp, cy - pix, ldata->highcolor); - } - if (dp < 0) - dp += b_sq_4 * xp++ + b_sq_6; - else - dp += b_sq_4 * xp++ + b_sq_6 + a_sq_4 * (++yp); - } - } - - d += -2 * (long) b_sq + 2 * (long) a_sq - 2 * (long) b_sq *(x - 1) + 2 * (long) a_sq *(y - 1); - - while (y <= 0) - { - pstart = x - half; - for (pix = pstart; pix < pstart + thick; pix++) - { - SetPixel (cx + pix, cy + y, ldata->highcolor); - SetPixel (cx - pix, cy + y, ldata->highcolor); - SetPixel (cx + pix, cy - y, ldata->highcolor); - SetPixel (cx - pix, cy - y, ldata->highcolor); - } - - if (d < 0) - d += a_sq_4 * y++ + a_sq_6 + b_sq_4 * (++x); - else - d += a_sq_4 * y++ + a_sq_6; - } - + char str[2]; + str[0]=c; + str[1]='\0'; + DrawString(str, 1, pt, d); } - -/*! - \brief Draws a line. Really. - \param start Starting point - \param end Ending point - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - The endpoints themselves are guaranteed to be in bounds, but clipping for lines with - a thickness greater than 1 will need to be done. -*/ -void ScreenDriver::StrokeLine(BPoint start, BPoint end, LayerData *d, int8 *pat) +/* +void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *delta=NULL) { - _Lock(); - if(fbuffer->IsConnected()) - { - // Courtesy YNOP's SecondDriver with minor changes by DW - int oct=0; - int xoff=(int32)end.x; - int yoff=(int32)end.y; - int32 x2=(int32)start.x-xoff; - int32 y2=(int32)start.y-yoff; - int32 x1=0; - int32 y1=0; - if(y2<0){ y2=-y2; oct+=4; }//bit2=1 - if(x2<0){ x2=-x2; oct+=2;}//bit1=1 - if(x2highcolor);break; - case 1:SetPixel(( y)+xoff,( x)+yoff,d->highcolor);break; - case 3:SetPixel((-y)+xoff,( x)+yoff,d->highcolor);break; - case 2:SetPixel((-x)+xoff,( y)+yoff,d->highcolor);break; - case 6:SetPixel((-x)+xoff,(-y)+yoff,d->highcolor);break; - case 7:SetPixel((-y)+xoff,(-x)+yoff,d->highcolor);break; - case 5:SetPixel(( y)+xoff,(-x)+yoff,d->highcolor);break; - case 4:SetPixel(( x)+xoff,(-y)+yoff,d->highcolor);break; - } - x++; - sum-=Dy; - if(sum < 0) - { - y++; - sum += Dx; - } - } - } - _Unlock(); -} - -/*! - \brief Called for all BView::StrokePolygon calls - \param ptlist Array of BPoints defining the polygon. - \param numpts Number of points in the BPoint array. - \param rect Rectangle which contains the polygon - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - The points in the array are not guaranteed to be within the framebuffer's - coordinate range. -*/ -void ScreenDriver::StrokePolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat, bool is_closed=true) -{ - _Lock(); - if(fbuffer->IsConnected()) - { - for(int32 i=0; i<(numpts-1); i++) - Line(ptlist[i],ptlist[i+1],d,pat); - - if(is_closed) - Line(ptlist[numpts-1],ptlist[0],d,pat); - } - _Unlock(); -} - -/*! - \brief Called for all BView::StrokeRect calls - \param r BRect to be filled. Guaranteed to be in the frame buffer's coordinate space - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - -*/ -void ScreenDriver::StrokeRect(BRect r, LayerData *d, int8 *pat) -{ - _Lock(); - if(fbuffer->IsConnected()) - { - Line(r.LeftTop(),r.RightTop(),d,pat); - Line(r.RightTop(),r.RightBottom(),d,pat); - Line(r.RightBottom(),r.LeftBottom(),d,pat); - Line(r.LeftTop(),r.LeftBottom(),d,pat); - } - _Unlock(); -} - -/*! - \brief Called for all BView::StrokeRoundRect calls - \param r The rect itself - \param xrad X radius of the corner arcs - \param yrad Y radius of the corner arcs - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the roundrect may end - up being clipped. -*/ -void ScreenDriver::StrokeRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat) -{ - float hLeft, hRight; - float vTop, vBottom; - float bLeft, bRight, bTop, bBottom; - _Lock(); - PatternHandler pattern(pat); - pattern.SetColors(d->highcolor, d->lowcolor); - - hLeft = r.left + xrad; - hRight = r.right - xrad; - vTop = r.top + yrad; - vBottom = r.bottom - yrad; - bLeft = hLeft + xrad; - bRight = hRight -xrad; - bTop = vTop + yrad; - bBottom = vBottom - yrad; - StrokeArc(BRect(bRight, r.top, r.right, bTop), 0, 90, d, pat); - Line(BPoint(hLeft,r.top), BPoint(hRight, r.top), d, pat); - - StrokeArc(BRect(r.left,r.top,bLeft,bTop), 90, 90, d, pat); - Line(BPoint(r.left,vTop),BPoint(r.left,vBottom),d,pat); - - StrokeArc(BRect(r.left,bBottom,bLeft,r.bottom), 180, 90, d, pat); - Line(BPoint(hLeft,r.bottom), BPoint(hRight, r.bottom), d, pat); - - StrokeArc(BRect(bRight,bBottom,r.right,r.bottom), 270, 90, d, pat); - StrokeLine(BPoint(r.right,vBottom),BPoint(r.right,vTop),d,pat); - _Unlock(); -} - -/*! - \brief Called for all BView::StrokeTriangle calls - \param pts Array of 3 BPoints. Always non-NULL. - \param r BRect enclosing the triangle. While it will definitely enclose the triangle, - it may not be within the frame buffer's bounds. - \param d Data structure containing any other data necessary for the call. Always non-NULL. - \param pat 8-byte array containing the pattern to use. Always non-NULL. - - Bounds checking must be done in this call because only part of the triangle may end - up being clipped. -*/ -void ScreenDriver::StrokeTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat) -{ - _Lock(); - if(fbuffer->IsConnected()) - { - Line(pts[0],pts[1],d,pat); - Line(pts[1],pts[2],d,pat); - Line(pts[2],pts[0],d,pat); - } - _Unlock(); -} - -void ScreenDriver::SetPixelPattern(int x, int y, uint8 *pattern, uint8 patternindex) -{ - // This function is designed to add pattern support to this thing. Should be - // inlined later to add speed lost in the multiple function calls. - if(patternindex>32) +#ifdef DEBUG_DRIVER_MODULE +printf("ScreenDriver:: DrawString(\"%s\",%ld,BPoint(%f,%f))\n",string,length,pt.x,pt.y); +#endif + if(!d) return; + BRect r; + + screenwin->Lock(); + framebuffer->Lock(); + + SetLayerData(d,true); // set all layer data and additionally set the font-related data - if(fbuffer->IsConnected()) - { -// uint64 *p64=(uint64*)pattern; + drawview->DrawString(string,length,pt,delta); + drawview->Sync(); + + // calculate the invalid rectangle + font_height fh; + BFont font; + drawview->GetFont(&font); + drawview->GetFontHeight(&fh); + r.left=pt.x; + r.right=pt.x+font.StringWidth(string); + r.top=pt.y-fh.ascent; + r.bottom=pt.y+fh.descent; + screenwin->view->Invalidate(r); + + framebuffer->Unlock(); + screenwin->Unlock(); + +} +*/ - // check for transparency in mask. If transparent, we can quit here - -// bool transparent_bit= -// ( *p64 & ~((uint64)2 << (32-patternindex)))?true:false; +bool ScreenDriver::DumpToFile(const char *path) +{ + // Dump to PNG + _Lock(); + SaveToPNG(path,framebuffer->Bounds(),framebuffer->ColorSpace(), + framebuffer->Bits(),framebuffer->BitsLength(),framebuffer->BytesPerRow()); -// bool highcolor_bit= -// ( *p64 & ~((uint64)2 << (64-patternindex)))?true:false; - - switch(fbuffer->gcinfo.bits_per_pixel) - { - case 32: - case 24: - { - - break; - } - case 16: - case 15: - { - break; - } - case 8: - { - break; - } - default: - { - break; - } - } - } + _Unlock(); + return true; } -void ScreenDriver::Line(BPoint start, BPoint end, LayerData *d, int8 *pat) +void ScreenDriver::FillArc(BRect r, float angle, float span, LayerData *d, int8 *pat) { - // Internal function which is called from within other functions + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->FillArc(r,angle,span,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::FillBezier(BPoint *pts, LayerData *d, int8 *pat) +{ + if(!pat || !pts) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->FillBezier(pts,*((pattern*)pat)); + drawview->Sync(); - // Courtesy YNOP's SecondDriver with minor changes by DW - int oct=0; - int xoff=(int32)end.x; - int yoff=(int32)end.y; - int32 x2=(int32)start.x-xoff; - int32 y2=(int32)start.y-yoff; - int32 x1=0; - int32 y1=0; - if(y2<0){ y2=-y2; oct+=4; }//bit2=1 - if(x2<0){ x2=-x2; oct+=2;}//bit1=1 - if(x2highcolor);break; - case 1:SetPixel(( y)+xoff,( x)+yoff,d->highcolor);break; - case 3:SetPixel((-y)+xoff,( x)+yoff,d->highcolor);break; - case 2:SetPixel((-x)+xoff,( y)+yoff,d->highcolor);break; - case 6:SetPixel((-x)+xoff,(-y)+yoff,d->highcolor);break; - case 7:SetPixel((-y)+xoff,(-x)+yoff,d->highcolor);break; - case 5:SetPixel(( y)+xoff,(-x)+yoff,d->highcolor);break; - case 4:SetPixel(( x)+xoff,(-y)+yoff,d->highcolor);break; - } - x++; - sum-=Dy; - if(sum < 0) - { - y++; - sum += Dx; - } - } + // Invalidate the whole view until I get around to adding in the invalid rect calc code + screenwin->view->Invalidate(); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::FillEllipse(BRect r, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->FillEllipse(r,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::FillPolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->FillPolygon(ptlist,numpts,rect,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(rect); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::FillRect(BRect r, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->FillRect(r,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::FillRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->FillRoundRect(r,xrad,yrad,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::FillTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat) +{ + if(!pat || !pts) + return; + screenwin->Lock(); + framebuffer->Lock(); + BPoint first=pts[0],second=pts[1],third=pts[2]; + SetLayerData(d); + drawview->FillTriangle(first,second,third,r,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); + } void ScreenDriver::HideCursor(void) { - _Lock(); - if(fbuffer->IsConnected()) - { - if(!IsCursorHidden()) - BlitBitmap(under_cursor,under_cursor->Bounds(),cursorframe, B_OP_COPY); - DisplayDriver::HideCursor(); - - } - _Unlock(); -} - -/*! - \brief Moves the cursor to the given point. - - The coordinates passed to MoveCursorTo are guaranteed to be within the frame buffer's - range, but the cursor data itself will need to be clipped. A check to see if the - cursor is obscured should be made and if so, a call to _SetCursorObscured(false) - should be made the cursor in addition to displaying at the passed coordinates. -*/ -void ScreenDriver::MoveCursorTo(float x, float y) -{ - if(!under_cursor) - return; - _Lock(); - if(!IsCursorHidden()) - BlitBitmap(under_cursor,under_cursor->Bounds(),cursorframe, B_OP_COPY); - - cursorframe.OffsetTo(x,y); - ExtractToBitmap(under_cursor,under_cursor->Bounds(),cursorframe); - - if(!IsCursorHidden()) - BlitBitmap(cursor,cursor->Bounds(),cursorframe, B_OP_OVER); - - _Unlock(); -} - -/*! - \brief Shows the cursor. - - Show calls are not nestable, unlike that of the BApplication class. Subclasses should - call _SetCursorHidden(false) somewhere within this function to ensure that data is - maintained accurately. Subclasses must call DisplayDriver::ShowCursor at some point - to ensure proper state tracking. -*/ -void ScreenDriver::ShowCursor(void) -{ - _Lock(); - if(fbuffer->IsConnected()) - { - if(IsCursorHidden()) - BlitBitmap(cursor,cursor->Bounds(),cursorframe, B_OP_OVER); - DisplayDriver::ShowCursor(); - } - _Unlock(); -} - -/*! - \brief Obscures the cursor. - - Obscure calls are not nestable. Subclasses should call DisplayDriver::ObscureCursor - somewhere within this function to ensure that data is maintained accurately. A check - will be made by the system before the next MoveCursorTo call to show the cursor if - it is obscured. -*/ -void ScreenDriver::ObscureCursor(void) -{ - _Lock(); - if(!IsCursorHidden() && fbuffer->IsConnected()) - BlitBitmap(under_cursor,under_cursor->Bounds(),cursorframe, B_OP_COPY); - DisplayDriver::ObscureCursor(); - _Unlock(); -} - -/*! - \brief Changes the cursor. - \param cursor The new cursor. Guaranteed to be non-NULL. - - The driver does not take ownership of the given cursor. Subclasses should make - a copy of the cursor passed to it. The default version of this function hides the - cursory, replaces it, and shows the cursor if previously visible. -*/ -void ScreenDriver::SetCursor(ServerCursor *csr) -{ - if(!csr) - return; - + screenwin->Lock(); _Lock(); - // erase old if visible - if(!IsCursorHidden() && under_cursor) - BlitBitmap(under_cursor,under_cursor->Bounds(),cursorframe, B_OP_COPY); + hide_cursor++; + screenwin->PostMessage(SDWIN_HIDECURSOR); - if(cursor) - delete cursor; - if(under_cursor) - delete under_cursor; - - cursor=new ServerCursor(csr); - under_cursor=new ServerCursor(csr); - - cursorframe.right=cursorframe.left+csr->Bounds().Width(); - cursorframe.bottom=cursorframe.top+csr->Bounds().Height(); - - ExtractToBitmap(under_cursor,under_cursor->Bounds(),cursorframe); - - if(!IsCursorHidden()) - BlitBitmap(cursor,cursor->Bounds(),cursorframe, B_OP_OVER); - _Unlock(); -} - - -/*! - \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 - \return False if unimplemented or unsuccessful. True if otherwise. - - Subclasses should add an extension based on what kind of file is saved -*/ -bool ScreenDriver::DumpToFile(const char *path) -{ - // TODO: implement calling SaveToPNG - return false; -} - -void ScreenDriver::HLine(int32 x1, int32 x2, int32 y, RGBColor color) -{ -// TODO: make this work with HW Acceleration, if possible -#ifndef DISABLE_HARDWARE_ACCELERATION - // Internal function called from others in the driver - if(fbuffer->_fspan) - { - uint16 ptarray[3]; - ptarray[0]=(uint16)x1; - ptarray[1]=(uint16)x2; - ptarray[2]=(uint16)y; - rgb_color col=color.GetColor32(); - fbuffer->_ae(B_2D_ACCELERATION,100000,&fbuffer->_stoken,&fbuffer->_et); - fbuffer->_fspan(fbuffer->_et,*((uint32*)&col),ptarray,1); - fbuffer->_re(fbuffer->_et,&fbuffer->_stoken); - return; - } -#endif - // TODO: Implement and substitute Line() calls with HLine calls as appropriate - // elsewhere in the driver - - switch(fbuffer->gcinfo.bits_per_pixel) - { - case 32: - case 24: - break; - case 16: - case 15: - break; - default: - break; - } -} - -void HLine_32Bit(graphics_card_info i, uint16 x, uint16 y, uint16 length, rgb_color col) -{ -// TODO: Finish -printf("HLine32() Unfinished\n"); - uint32 c=0,*pcolor,bytes; - - // apparently width=bytes per row - uint32 bpr=i.width; - - // ARGB order - c|=col.alpha * 0x01000000; - c|=col.red * 0x010000; - c|=col.green * 0x0100; - c|=col.blue; - - bytes=(uint32(x+length)>bpr)?length-((x+length)-bpr):length; - - pcolor=(uint32*)i.frame_buffer; - pcolor+=(y*bpr)+(x*4); - for(int32 i=0;ibpr)?length-((x+length)-bpr):length; - - memset(pcolor,col,bytes); -} - -// This function is intended to eventually take care of most of the heavy lifting for -// DrawBitmap in 32-bit mode, with others coming later. Right now, it is *just* used for -// the -void ScreenDriver::BlitBitmap(ServerBitmap *sourcebmp,BRect sourcerect, BRect destrect, drawing_mode mode=B_OP_COPY) -{ - // Another internal function called from other functions. - - if(!sourcebmp) - return; - - if(sourcebmp->BitsPerPixel() != fbuffer->gcinfo.bits_per_pixel) - return; - - uint8 colorspace_size=sourcebmp->BitsPerPixel()/8; - // First, clip source rect to destination - if(sourcerect.Width() > destrect.Width()) - sourcerect.right=sourcerect.left+destrect.Width(); - - - if(sourcerect.Height() > destrect.Height()) - sourcerect.bottom=sourcerect.top+destrect.Height(); - - - // Second, check rectangle bounds against their own bitmaps - BRect work_rect; - - work_rect=sourcebmp->Bounds(); - - if( !(work_rect.Contains(sourcerect)) ) - { // something in selection must be clipped - if(sourcerect.left < 0) - sourcerect.left = 0; - if(sourcerect.right > work_rect.right) - sourcerect.right = work_rect.right; - if(sourcerect.top < 0) - sourcerect.top = 0; - if(sourcerect.bottom > work_rect.bottom) - sourcerect.bottom = work_rect.bottom; - } - - work_rect.Set(0,0,fbuffer->gcinfo.width-1,fbuffer->gcinfo.height-1); - - // Check to see if we actually need to copy anything - if( (destrect.rightwork_rect.right) || - (destrect.bottomwork_rect.bottom) ) - return; - - // something in selection must be clipped - if(destrect.left < 0) - destrect.left = 0; - if(destrect.right > work_rect.right) - destrect.right = work_rect.right; - if(destrect.top < 0) - destrect.top = 0; - if(destrect.bottom > work_rect.bottom) - destrect.bottom = work_rect.bottom; - - // Set pointers to the actual data - uint8 *src_bits = (uint8*) sourcebmp->Bits(); - uint8 *dest_bits = (uint8*) fbuffer->gcinfo.frame_buffer; - - // Get row widths for offset looping - uint32 src_width = uint32 (sourcebmp->BytesPerRow()); - uint32 dest_width = uint32 (fbuffer->gcinfo.bytes_per_row); - - // Offset bitmap pointers to proper spot in each bitmap - src_bits += uint32 ( (sourcerect.top * src_width) + (sourcerect.left * colorspace_size) ); - dest_bits += uint32 ( (destrect.top * dest_width) + (destrect.left * colorspace_size) ); - - uint32 line_length = uint32 ((destrect.right - destrect.left+1)*colorspace_size); - uint32 lines = uint32 (destrect.bottom-destrect.top+1); - - switch(mode) - { - case B_OP_OVER: - { -// uint32 srow_pixels=src_width>>2; - uint32 srow_pixels=((destrect.IntegerWidth()>=sourcerect.IntegerWidth())?src_width:destrect.IntegerWidth()+1)>>2; - uint8 *srow_index, *drow_index; - - - // This could later be optimized to use uint32's for faster copying - for (uint32 pos_y=0; pos_y!=lines; pos_y++) - { - - srow_index=src_bits; - drow_index=dest_bits; - - for(uint32 pos_x=0; pos_x!=srow_pixels;pos_x++) - { - // 32-bit RGBA32 mode byte order is BGRA - if(srow_index[3]>127) - { - *drow_index=*srow_index; drow_index++; srow_index++; - *drow_index=*srow_index; drow_index++; srow_index++; - *drow_index=*srow_index; drow_index++; srow_index++; - // we don't copy the alpha channel - drow_index++; srow_index++; - } - else - { - srow_index+=4; - drow_index+=4; - } - } - - // Increment offsets - src_bits += src_width; - dest_bits += dest_width; - } - break; - } - default: // B_OP_COPY - { - for (uint32 pos_y = 0; pos_y != lines; pos_y++) - { - memcpy(dest_bits,src_bits,line_length); - - // Increment offsets - src_bits += src_width; - dest_bits += dest_width; - } - break; - } - } -} - -void ScreenDriver::ExtractToBitmap(ServerBitmap *destbmp,BRect destrect, BRect sourcerect) -{ - // Another internal function called from other functions. Extracts data from - // the framebuffer to a target ServerBitmap - - if(!destbmp) - return; - - if(destbmp->BitsPerPixel() != fbuffer->gcinfo.bits_per_pixel) - return; - - uint8 colorspace_size=destbmp->BitsPerPixel()/8; - // First, clip source rect to destination - if(sourcerect.Width() > destrect.Width()) - sourcerect.right=sourcerect.left+destrect.Width(); - - - if(sourcerect.Height() > destrect.Height()) - sourcerect.bottom=sourcerect.top+destrect.Height(); - - - // Second, check rectangle bounds against their own bitmaps - BRect work_rect; - - work_rect.Set( destbmp->Bounds().left, - destbmp->Bounds().top, - destbmp->Bounds().right, - destbmp->Bounds().bottom ); - if( !(work_rect.Contains(destrect)) ) - { // something in selection must be clipped - if(destrect.left < 0) - destrect.left = 0; - if(destrect.right > work_rect.right) - destrect.right = work_rect.right; - if(destrect.top < 0) - destrect.top = 0; - if(destrect.bottom > work_rect.bottom) - destrect.bottom = work_rect.bottom; - } - - work_rect.Set( 0,0,fbuffer->gcinfo.width-1,fbuffer->gcinfo.height-1); - - if( !(work_rect.Contains(sourcerect)) ) - { // something in selection must be clipped - if(sourcerect.left < 0) - sourcerect.left = 0; - if(sourcerect.right > work_rect.right) - sourcerect.right = work_rect.right; - if(sourcerect.top < 0) - sourcerect.top = 0; - if(sourcerect.bottom > work_rect.bottom) - sourcerect.bottom = work_rect.bottom; - } - - // Set pointers to the actual data - uint8 *dest_bits = (uint8*) destbmp->Bits(); - uint8 *src_bits = (uint8*) fbuffer->gcinfo.frame_buffer; - - // Get row widths for offset looping - uint32 dest_width = uint32 (destbmp->BytesPerRow()); - uint32 src_width = uint32 (fbuffer->gcinfo.bytes_per_row); - - // Offset bitmap pointers to proper spot in each bitmap - src_bits += uint32 ( (sourcerect.top * src_width) + (sourcerect.left * colorspace_size) ); - dest_bits += uint32 ( (destrect.top * dest_width) + (destrect.left * colorspace_size) ); - - uint32 line_length = uint32 ((destrect.right - destrect.left+1)*colorspace_size); - uint32 lines = uint32 (destrect.bottom-destrect.top+1); - - for (uint32 pos_y = 0; pos_y != lines; pos_y++) - { - memcpy(dest_bits,src_bits,line_length); - - // Increment offsets - src_bits += src_width; - dest_bits += dest_width; - } + screenwin->Unlock(); } void ScreenDriver::InvertRect(BRect r) { - _Lock(); - if(fbuffer->IsConnected()) - { - if(r.top<0 || r.left<0 || - r.right>fbuffer->gcinfo.width-1 || r.bottom>fbuffer->gcinfo.height-1) - { - _Unlock(); - return; - } - - switch(fbuffer->gcinfo.bits_per_pixel) - { - case 32: - case 24: - { - uint16 width=r.IntegerWidth(), height=r.IntegerHeight(); - uint32 *start=(uint32*)fbuffer->gcinfo.frame_buffer, *index; - start+=int32(r.top)*fbuffer->gcinfo.width; - start+=int32(r.left); - - for(int32 i=0;igcinfo.width); - for(int32 j=0; jLock(); + framebuffer->Lock(); + drawview->InvertRect(r); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); } +bool ScreenDriver::IsCursorHidden(void) +{ + screenwin->Lock(); + bool value=(hide_cursor>0)?true:false; + screenwin->Unlock(); + return value; +} + +void ScreenDriver::ObscureCursor(void) +{ + screenwin->Lock(); + screenwin->PostMessage(SDWIN_OBSCURECURSOR); + screenwin->Unlock(); +} + +void ScreenDriver::MoveCursorTo(float x, float y) +{ + screenwin->Lock(); + BMessage *msg=new BMessage(SDWIN_MOVECURSOR); + msg->AddFloat("x",x); + msg->AddFloat("y",y); + screenwin->PostMessage(msg); + screenwin->Unlock(); +} + +void ScreenDriver::SetCursor(ServerCursor *cursor) +{ +printf("SetCursor unimplemented\n"); +/* + if(cursor!=NULL) + { + screenwin->Lock(); + BBitmap *bmp=new BBitmap(cursor->Bounds(),B_RGBA32); + + // Copy the server bitmap in the cursor to a BBitmap + uint8 *sbmppos=(uint8*)cursor->Bits(), + *bbmppos=(uint8*)bmp->Bits(); + + int32 bytes=cursor->BytesPerRow(), + bbytes=bmp->BytesPerRow(); + + for(int i=0;i<=cursor->Bounds().IntegerHeight();i++) + memcpy(bbmppos+(i*bbytes), sbmppos+(i*bytes), bytes); + + // Replace the bitmap + delete screenwin->cursor; + screenwin->cursor=bmp; + screenwin->Invalidate(screenwin->view->cursorframe); + screenwin->Unlock(); + } +*/ +} + +void ScreenDriver::ShowCursor(void) +{ + screenwin->Lock(); + if(hide_cursor>0) + { + hide_cursor--; + screenwin->PostMessage(SDWIN_SHOWCURSOR); + } + screenwin->Unlock(); + +} + +void ScreenDriver::StrokeArc(BRect r, float angle, float span, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->StrokeArc(r,angle,span,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::StrokeBezier(BPoint *pts, LayerData *d, int8 *pat) +{ + if(!pat || !pts) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->StrokeBezier(pts,*((pattern*)pat)); + drawview->Sync(); + + // Invalidate the whole view until I get around to adding in the invalid rect calc code + screenwin->view->Invalidate(); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::StrokeEllipse(BRect r, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->StrokeEllipse(r,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::StrokeLine(BPoint start, BPoint end, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->StrokeLine(start,end,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(BRect(start,end)); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::StrokeLineArray(BPoint *pts, int32 numlines, RGBColor *colors, LayerData *d) +{ +#ifdef DEBUG_DRIVER_MODULE +printf("ScreenDriver:: StrokeLineArray unimplemented\n"); +#endif +} + +void ScreenDriver::StrokePolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat, bool is_closed=true) +{ + if(!pat || !ptlist) + return; + screenwin->Lock(); + framebuffer->Lock(); + + BRegion invalid; + + SetLayerData(d); + drawview->BeginLineArray(numpts+2); + for(int i=1;iAddLine(ptlist[i-1],ptlist[i],d->highcolor.GetColor32()); + invalid.Include(BRect(ptlist[i-1],ptlist[i])); + } + + if(is_closed) + { + drawview->AddLine(ptlist[numpts-1],ptlist[0],d->highcolor.GetColor32()); + invalid.Include(BRect(ptlist[numpts-1],ptlist[0])); + } + drawview->EndLineArray(); + + drawview->Sync(); + screenwin->view->Invalidate(invalid.Frame()); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::StrokeRect(BRect r, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->StrokeRect(r,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); +} + +void ScreenDriver::StrokeRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat) +{ + if(!pat || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + SetLayerData(d); + drawview->StrokeRoundRect(r,xrad,yrad,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::StrokeTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat) +{ + if(!pat || !pts || !d) + return; + screenwin->Lock(); + framebuffer->Lock(); + BPoint first=pts[0],second=pts[1],third=pts[2]; + SetLayerData(d); + drawview->StrokeTriangle(first,second,third,r,*((pattern*)pat)); + drawview->Sync(); + screenwin->view->Invalidate(r); + framebuffer->Unlock(); + screenwin->Unlock(); + +} + +void ScreenDriver::SetLayerData(LayerData *d, bool set_font_data=false) +{ + if(!d) + return; + + drawview->SetPenSize(d->pensize); + drawview->SetDrawingMode(d->draw_mode); + drawview->SetHighColor(d->highcolor.GetColor32()); + drawview->SetLowColor(d->lowcolor.GetColor32()); + drawview->SetScale(d->scale); + drawview->MovePenTo(d->penlocation); + if(set_font_data) + { + BFont font; + ServerFont *sf=d->font; + + if(!sf) + return; + + FontStyle *style=d->font->Style(); + + if(!style) + return; + + FontFamily *family=(FontFamily *)style->Family(); + if(!family) + return; + + font.SetFamilyAndStyle((font_family)family->Name(),style->Name()); + font.SetFlags(sf->Flags()); + font.SetEncoding(sf->Encoding()); + font.SetSize(sf->Size()); + font.SetRotation(sf->Rotation()); + font.SetShear(sf->Shear()); + font.SetSpacing(sf->Spacing()); + drawview->SetFont(&font); + } +} float ScreenDriver::StringWidth(const char *string, int32 length, LayerData *d) { if(!string || !d || !d->font) return 0.0; - _Lock(); + screenwin->Lock(); ServerFont *font=d->font; FontStyle *style=font->Style(); if(!style) - { - _Unlock(); return 0.0; - } FT_Face face; FT_GlyphSlot slot; @@ -1965,10 +912,7 @@ float ScreenDriver::StringWidth(const char *string, int32 length, LayerData *d) error=FT_New_Face(ftlib, style->GetPath(), 0, &face); if(error) - { - _Unlock(); return 0.0; - } slot=face->glyph; @@ -1976,10 +920,7 @@ float ScreenDriver::StringWidth(const char *string, int32 length, LayerData *d) error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72); if(error) - { - _Unlock(); return 0.0; - } // set the pen position in 26.6 cartesian space coordinates pen.x=0; @@ -2005,11 +946,11 @@ float ScreenDriver::StringWidth(const char *string, int32 length, LayerData *d) pen.x+=slot->advance.x; previous=glyph_index; } + screenwin->Unlock(); FT_Done_Face(face); returnval=pen.x>>6; - _Unlock(); return returnval; } @@ -2017,16 +958,13 @@ float ScreenDriver::StringHeight(const char *string, int32 length, LayerData *d) { if(!string || !d || !d->font) return 0.0; - _Lock(); + screenwin->Lock(); ServerFont *font=d->font; FontStyle *style=font->Style(); if(!style) - { - _Unlock(); return 0.0; - } FT_Face face; FT_GlyphSlot slot; @@ -2036,19 +974,13 @@ float ScreenDriver::StringHeight(const char *string, int32 length, LayerData *d) error=FT_New_Face(ftlib, style->GetPath(), 0, &face); if(error) - { - _Unlock(); return 0.0; - } slot=face->glyph; error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72); if(error) - { - _Unlock(); return 0.0; - } slot=face->glyph; @@ -2064,32 +996,19 @@ float ScreenDriver::StringHeight(const char *string, int32 length, LayerData *d) else ascent=MAX(slot->bitmap.rows,ascent); } - _Unlock(); + screenwin->Unlock(); FT_Done_Face(face); returnval=ascent+descent; - _Unlock(); return returnval; } -/*! - \brief Utilizes the font engine to draw a string to the frame buffer - \param string String to be drawn. Always non-NULL. - \param length Number of characters in the string to draw. Always greater than 0. If greater - than the number of characters in the string, draw the entire string. - \param pt Point at which the baseline starts. Characters are to be drawn 1 pixel above - this for backwards compatibility. While the point itself is guaranteed to be inside - the frame buffers coordinate range, the clipping of each individual glyph must be - performed by the driver itself. - \param d Data structure containing any other data necessary for the call. Always non-NULL. -*/ void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *edelta=NULL) { if(!string || !d || !d->font) return; - - _Lock(); + screenwin->Lock(); pt.y--; // because of Be's backward compatibility hack @@ -2097,10 +1016,7 @@ void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, Layer FontStyle *style=font->Style(); if(!style) - { - _Unlock(); return; - } FT_Face face; FT_GlyphSlot slot; @@ -2129,11 +1045,7 @@ void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, Layer error=FT_New_Face(ftlib, style->GetPath(), 0, &face); if(error) - { - printf("Couldn't create face object\n"); - _Unlock(); return; - } slot=face->glyph; @@ -2141,17 +1053,14 @@ void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, Layer error=FT_Set_Char_Size(face, 0,int32(font->Size())*64,72,72); if(error) - { - _Unlock(); return; - } // if we do any transformation, we do a call to FT_Set_Transform() here // First, rotate rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000); - rmatrix.xy = (FT_Fixed)( rotation.Sine()*0x10000); - rmatrix.yx = (FT_Fixed)(-rotation.Sine()*0x10000); + rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000); + rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000); rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000); // Next, shear @@ -2160,8 +1069,7 @@ void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, Layer smatrix.yx = (FT_Fixed)(0); smatrix.yy = (FT_Fixed)(0x10000); - //FT_Matrix_Multiply(&rmatrix,&smatrix); - FT_Matrix_Multiply(&smatrix,&rmatrix); + FT_Matrix_Multiply(&rmatrix,&smatrix); // Set up the increment value for escapement padding space.x=int32(d->edelta.space * rotation.Cosine()*64); @@ -2182,8 +1090,7 @@ void ScreenDriver::DrawString(const char *string, int32 length, BPoint pt, Layer for(i=0;ibitmap, BPoint(slot->bitmap_left,pt.y-(slot->bitmap_top-pt.y)), d); } - else - printf("Couldn't load character %c\n", string[i]); // increment pen position pen.x+=slot->advance.x; pen.y+=slot->advance.y; previous=glyph_index; } + + // TODO: implement properly + // calculate the invalid rectangle + BRect r; + r.left=MIN(pt.x,pen.x>>6); + r.right=MAX(pt.x,pen.x>>6); + r.top=pt.y-face->height; + r.bottom=pt.y+face->height; + + screenwin->view->Invalidate(r); + screenwin->Unlock(); + FT_Done_Face(face); - _Unlock(); } void ScreenDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) @@ -2241,7 +1157,7 @@ void ScreenDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) uint8 *srcindex, *destindex, *rowptr, value; // increment values for the index pointers - int32 srcinc=src->pitch, destinc=fbuffer->gcinfo.bytes_per_row; + int32 srcinc=src->pitch, destinc=framebuffer->BytesPerRow(); int16 i,j,k, srcwidth=src->pitch, srcheight=src->rows; int32 x=(int32)pt.x,y=(int32)pt.y; @@ -2258,18 +1174,18 @@ void ScreenDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) destbuffer+=destinc * (0-y); } - if(y+srcheight>fbuffer->gcinfo.height) + if(y+srcheight>framebuffer->Bounds().IntegerHeight()) { if(y>pt.y) y--; - srcheight-=(y+srcheight-1)-fbuffer->gcinfo.height; + srcheight-=(y+srcheight-1)-framebuffer->Bounds().IntegerHeight(); } - if(x+srcwidth>fbuffer->gcinfo.width) + if(x+srcwidth>framebuffer->Bounds().IntegerWidth()) { if(x>pt.x) x--; - srcwidth-=(x+srcwidth-1)-fbuffer->gcinfo.width; + srcwidth-=(x+srcwidth-1)-framebuffer->Bounds().IntegerWidth(); } if(x<0) @@ -2282,7 +1198,7 @@ void ScreenDriver::BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) } // starting point in destination bitmap - destbuffer=(uint8*)fbuffer->gcinfo.frame_buffer+int32( (pt.y*fbuffer->gcinfo.bytes_per_row)+(pt.x*4) ); + destbuffer=(uint8*)framebuffer->Bits()+int32( (pt.y*framebuffer->BytesPerRow())+(pt.x*4) ); srcindex=srcbuffer; destindex=destbuffer; @@ -2335,7 +1251,7 @@ void ScreenDriver::BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) y=(int32)pt.y, srcinc=src->pitch, // destinc=dest->BytesPerRow(), - destinc=fbuffer->gcinfo.bytes_per_row, + destinc=framebuffer->BytesPerRow(), srcwidth=src->width, srcheight=src->rows, incval=0; @@ -2347,7 +1263,7 @@ void ScreenDriver::BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) // starting point in destination bitmap // destbuffer=(uint8*)dest->Bits()+(y*dest->BytesPerRow()+(x*4)); - destbuffer=(uint8*)fbuffer->gcinfo.frame_buffer+(y*fbuffer->gcinfo.bytes_per_row+(x*4)); + destbuffer=(uint8*)framebuffer->Bits()+(y*framebuffer->BytesPerRow()+(x*4)); if(y<0) @@ -2362,18 +1278,18 @@ void ScreenDriver::BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d) destbuffer+=incval * destinc; } - if(y+srcheight>fbuffer->gcinfo.height) + if(y+srcheight>framebuffer->Bounds().IntegerHeight()) { if(y>pt.y) y--; - srcheight-=(y+srcheight-1)-fbuffer->gcinfo.height; + srcheight-=(y+srcheight-1)-framebuffer->Bounds().IntegerHeight(); } - if(x+srcwidth>fbuffer->gcinfo.width) + if(x+srcwidth>framebuffer->Bounds().IntegerWidth()) { if(x>pt.x) x--; - srcwidth-=(x+srcwidth-1)-fbuffer->gcinfo.width; + srcwidth-=(x+srcwidth-1)-framebuffer->Bounds().IntegerWidth(); } if(x<0) @@ -2528,6 +1444,5 @@ rgb_color ScreenDriver::GetBlitColor(rgb_color src, rgb_color dest, LayerData *d break; } } - _Unlock(); return returncolor; } diff --git a/src/servers/app/server/ScreenDriver.h b/src/servers/app/server/ScreenDriver.h index 3a33fed503..a9493194ad 100644 --- a/src/servers/app/server/ScreenDriver.h +++ b/src/servers/app/server/ScreenDriver.h @@ -29,58 +29,24 @@ #define _SCREENDRIVER_H_ #include -#include +#include #include #include -#include +#include // for pattern struct +#include #include -#include -#include -#include // for clipping_rect definition -#include -#include +#include +#include #include "DisplayDriver.h" #include +#include #include FT_FREETYPE_H -#include FT_GLYPH_H -class VDWindow; -class ServerCursor; -class ServerBitmap; -class RGBColor; +class BBitmap; class PortLink; +class SDWindow; +class LayerData; class ScreenDriver; -class PatternHandler; - -// defines to translate acceleration function indices to something I can remember -#define HWLINE_8BIT 3 -#define HWLINE_32BIT 4 -#define HWRECT_8BIT 5 -#define HWRECT_32BIT 6 -#define HWBLIT 7 -#define HWLINEARRAY_8BIT 8 -#define HWLINEARRAY_32BIT 9 -#define HWSYNC 10 -#define HWINVERT 11 -#define HWLINE_16BIT 12 -#define HWRECT_16BIT 13 - -// function pointer typedefs for accelerated 2d functions - from Be Advanced Topics. -typedef int32 hwline8bit(int32 sx,int32 dx, int32 sy, int32 dy, uint8 color, - bool cliptorect,int16 clipleft, int16 cliptop, int16 clipright, int16 clipbottom); -typedef int32 hwline32bit(int32 sx,int32 dx, int32 sy, int32 dy, uint32 color, - bool cliptorect,int16 clipleft, int16 cliptop, int16 clipright, int16 clipbottom); -typedef int32 hwrect8bit(int32 left, int32 top, int32 right, int32 bottom, uint8 color); -typedef int32 hwrect32bit(int32 left, int32 top, int32 right, int32 bottom, uint32 color); -typedef int32 hwblit(int32 sx, int32 sy, int32 dx, int32 dy, int32 width, int32 height); -typedef int32 hwlinearray8bit(indexed_color_line *array, int32 linecount, - bool cliptorect,int16 clipleft, int16 cliptop, int16 clipright, int16 clipbottom); -typedef int32 hwlinearray32bit(rgb_color_line *array, int32 linecount, - bool cliptorect,int16 clipleft, int16 cliptop, int16 clipright, int16 clipbottom); -typedef int32 hwsync(void); -typedef int32 hwline16bit(int32 sx,int32 dx, int32 sy, int32 dy, uint16 color, - bool cliptorect,int16 clipleft, int16 cliptop, int16 clipright, int16 clipbottom); -typedef int32 hwrect16bit(int32 left, int32 top, int32 right, int32 bottom, uint16 color); class FrameBuffer : public BWindowScreen { @@ -92,9 +58,9 @@ public: bool IsConnected(void) const { return is_connected; } bool QuitRequested(void); static int32 MouseMonitor(void *data); - + static int32 CopyThread(void *data); + void Invalidate(const BRect &r); graphics_card_info gcinfo; - protected: friend ScreenDriver; @@ -102,56 +68,65 @@ protected: PortLink *serverlink; BPoint mousepos; uint32 buttons; - thread_id monitor_thread; + thread_id monitor_thread,copy_thread; BView *view; - - // HW Acceleration stuff - display_mode _dm; + BBitmap *viewbmp; + ServerBitmap *cursor; + BRegion *invalid; + int32 invalidflag; +}; +/* +class SDView : public BView +{ +public: + SDView(BRect bounds); + ~SDView(void); + void AttachedToWindow(void); + void Draw(BRect rect); + void MouseDown(BPoint pt); + void MouseMoved(BPoint pt, uint32 transit, const BMessage *msg); + void MouseUp(BPoint pt); + void MessageReceived(BMessage *msg); + + BBitmap *viewbmp; + PortLink *serverlink; - frame_buffer_config _fbc; + int hide_cursor; + BBitmap *cursor; - set_cursor_shape _scs; - move_cursor _mc; - show_cursor _sc; - sync_token _st; - engine_token *_et; - acquire_engine _ae; - release_engine _re; - fill_rectangle _frect; - fill_span _fspan; + BRect cursorframe, oldcursorframe; + bool obscure_cursor; +}; +*/ +class SDWindow : public BWindowScreen +{ +public: + SDWindow(void); + ~SDWindow(void); + void MessageReceived(BMessage *msg); + bool QuitRequested(void); + void WindowActivated(bool active); - screen_to_screen_blit _s2sb; - fill_rectangle _fr; - invert_rectangle _ir; - screen_to_screen_transparent_blit _s2stb; - fill_span _fs; - - hwline32bit _hwline32; - hwrect32bit _hwrect32; - - sync_token _stoken; +// SDView *view; }; -/* - ScreenDriver.cpp - Replacement class for the ViewDriver which utilizes a BWindowScreen for ease - of testing without requiring a second video card for SecondDriver and also - without the limitations (mostly speed) of ViewDriver. - - This module also emulates the input server via the keyboard. - Cursor keys move the mouse and the left modifier keys Option and Ctrl, which - operate the first and second mouse buttons, respectively. - The right window key on American keymaps doesn't map to anything, so it is - not used. Consequently, when a right modifier key is pressed, it works normally. - - The concept is pretty close to the retooled ViewDriver, where each module - call locks a couple BLockers and draws to the buffer. - - Components: - ScreenDriver: actual driver module - FrameBuffer: BWindowScreen derivative which provides the module access - to the video card - Internal functions for doing graphics on the buffer +/*! + \brief BView/BWindow combination graphics module + + First, slowest, and easiest driver class in the app_server which is designed + to utilize the BeOS graphics functions to cut out a lot of junk in getting the + drawing infrastructure in this server. + + The concept is to have SDView::Draw() draw a bitmap, which is a "frame buffer" + of sorts, utilize a second view to write to it. This cuts out + the most problems with having a crapload of code to get just right without + having to write a bunch of unit tests + + Components: 3 classes, SDView, SDWindow, and ScreenDriver + + ScreenDriver - a wrapper class which mostly posts messages to the SDWindow + SDWindow - does most of the work. + SDView - doesn't do all that much except display the rendered bitmap */ class ScreenDriver : public DisplayDriver { @@ -159,66 +134,67 @@ public: ScreenDriver(void); ~ScreenDriver(void); - bool Initialize(void); - void Shutdown(void); + bool Initialize(void); // Sets the driver + void Shutdown(void); // You never know when you'll need this - // Settings functions - virtual void CopyBits(BRect src, BRect dest); - virtual void DrawBitmap(ServerBitmap *bmp, BRect src, BRect dest, LayerData *d); + // Drawing functions + void CopyBits(BRect src, BRect dest); + void DrawBitmap(ServerBitmap *bmp, BRect src, BRect dest); + void DrawChar(char c, BPoint pt, LayerData *d); // virtual void DrawPicture(SPicture *pic, BPoint pt); - virtual void DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *delta=NULL); + void DrawString(const char *string, int32 length, BPoint pt, LayerData *d, escapement_delta *delta=NULL); - virtual void FillArc(BRect r, float angle, float span, LayerData *d, int8 *pat); - virtual void FillBezier(BPoint *pts, LayerData *d, int8 *pat); - virtual void FillEllipse(BRect r, LayerData *d, int8 *pat); -// virtual void FillPolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat); - virtual void FillRect(BRect r, LayerData *d, int8 *pat); - virtual void FillRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat); -// virtual void FillShape(SShape *sh, LayerData *d, int8 *pat); - virtual void FillTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat); + void FillArc(BRect r, float angle, float span, LayerData *d, int8 *pat); + void FillBezier(BPoint *pts, LayerData *d, int8 *pat); + void FillEllipse(BRect r, LayerData *d, int8 *pat); + void FillPolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat); + void FillRect(BRect r, LayerData *d, int8 *pat); + void FillRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat); +// void FillShape(SShape *sh, LayerData *d, int8 *pat); + void FillTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat); - virtual void HideCursor(void); - virtual void MoveCursorTo(float x, float y); - virtual void InvertRect(BRect r); - virtual void ShowCursor(void); - virtual void ObscureCursor(void); - virtual void SetCursor(ServerCursor *cursor); + void HideCursor(void); + void InvertRect(BRect r); + bool IsCursorHidden(void); + void MoveCursorTo(float x, float y); +// void MovePenTo(BPoint pt); + void ObscureCursor(void); +// BPoint PenPosition(void); +// float PenSize(void); + void SetCursor(ServerCursor *cursor); +// drawing_mode GetDrawingMode(void); +// void SetDrawingMode(drawing_mode mode); + void ShowCursor(void); - virtual void StrokeArc(BRect r, float angle, float span, LayerData *d, int8 *pat); - virtual void StrokeBezier(BPoint *pts, LayerData *d, int8 *pat); - virtual void StrokeEllipse(BRect r, LayerData *d, int8 *pat); - virtual void StrokeLine(BPoint start, BPoint end, LayerData *d, int8 *pat); - virtual void StrokePolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat, bool is_closed=true); - virtual void StrokeRect(BRect r, LayerData *d, int8 *pat); - virtual void StrokeRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat); -// virtual void StrokeShape(SShape *sh, LayerData *d, int8 *pat); - virtual void StrokeTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat); -// virtual void StrokeLineArray(BPoint *pts, int32 numlines, RGBColor *colors, LayerData *d); - virtual void SetMode(int32 mode); + void StrokeArc(BRect r, float angle, float span, LayerData *d, int8 *pat); + void StrokeBezier(BPoint *pts, LayerData *d, int8 *pat); + void StrokeEllipse(BRect r, LayerData *d, int8 *pat); + void StrokeLine(BPoint start, BPoint end, LayerData *d, int8 *pat); + void StrokeLineArray(BPoint *pts, int32 numlines, RGBColor *colors, LayerData *d); + void StrokePolygon(BPoint *ptlist, int32 numpts, BRect rect, LayerData *d, int8 *pat, bool is_closed=true); + void StrokeRect(BRect r, LayerData *d, int8 *pat); + void StrokeRoundRect(BRect r, float xrad, float yrad, LayerData *d, int8 *pat); +// void StrokeShape(SShape *sh, LayerData *d, int8 *pat); + void StrokeTriangle(BPoint *pts, BRect r, LayerData *d, int8 *pat); + void SetMode(int32 mode); float StringWidth(const char *string, int32 length, LayerData *d); float StringHeight(const char *string, int32 length, LayerData *d); - virtual bool DumpToFile(const char *path); + bool DumpToFile(const char *path); + FrameBuffer *screenwin; protected: + void SetLayerData(LayerData *d, bool set_font_data=false); void BlitMono2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); void BlitGray2RGB32(FT_Bitmap *src, BPoint pt, LayerData *d); - void BlitBitmap(ServerBitmap *sourcebmp, BRect sourcerect, BRect destrect, drawing_mode mode=B_OP_COPY); - void ExtractToBitmap(ServerBitmap *destbmp, BRect destrect, BRect sourcerect); - void SetPixelPattern(int x, int y, uint8 *pattern, uint8 patternindex); - void Line(BPoint start, BPoint end, LayerData *d, int8 *pat); - void HLine(int32 x1, int32 x2, int32 y, RGBColor color); - void HLineThick(int32 x1, int32 x2, int32 y, int32 thick, PatternHandler *pat); rgb_color GetBlitColor(rgb_color src, rgb_color dest, LayerData *d, bool use_high=true); - void SetPixel(int x, int y, RGBColor col); - void SetPixel32(int x, int y, rgb_color col); - void SetPixel16(int x, int y, uint16 col); - void SetPixel8(int x, int y, uint8 col); - void SetThickPixel(int x, int y, int thick, RGBColor col); - void SetThickPixel32(int x, int y, int thick, rgb_color col); - void SetThickPixel16(int x, int y, int thick, uint16 col); - void SetThickPixel8(int x, int y, int thick, uint8 col); - FrameBuffer *fbuffer; - ServerCursor *cursor, *under_cursor; - BRect cursorframe; + int hide_cursor; + bool obscure_cursor; + BBitmap *framebuffer; + BView *drawview; + BRegion laregion; + PortLink *serverlink; + + rgb_color highcolor,lowcolor; + bool is_initialized; }; #endif diff --git a/src/servers/app/server/ServerApp.cpp b/src/servers/app/server/ServerApp.cpp index d491b8e1e2..fa14148a1e 100644 --- a/src/servers/app/server/ServerApp.cpp +++ b/src/servers/app/server/ServerApp.cpp @@ -89,7 +89,7 @@ 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(); + _driver=GetGfxDriver(ActiveScreen()); _cursorhidden=false; #ifdef DEBUG_SERVERAPP @@ -534,7 +534,7 @@ printf("ServerApp %s: Download Picture unimplemented\n",_signature.String()); #ifdef DEBUG_SERVERAPP printf("ServerApp %s: SetScreenMode: workspace %ld, mode %lu\n",_signature.String(), workspace, mode); #endif - SetSpace(workspace,mode,*((bool*)index)); + SetSpace(workspace,mode,ActiveScreen(),*((bool*)index)); break; } diff --git a/src/servers/app/server/ServerConfig.h b/src/servers/app/server/ServerConfig.h index bee6dfe948..672634c95e 100644 --- a/src/servers/app/server/ServerConfig.h +++ b/src/servers/app/server/ServerConfig.h @@ -26,7 +26,7 @@ #define HWDRIVER 3 // Display driver to be used by the server. -#define DISPLAYDRIVER VIEWDRIVER +#define DISPLAYDRIVER SCREENDRIVER // Uncomment this if the DisplayDriver should only rely on drawing functions implemented // in software even though hardware-accelerated functions are available diff --git a/src/servers/app/server/ServerWindow.cpp b/src/servers/app/server/ServerWindow.cpp index 0be0f54513..97c887306e 100644 --- a/src/servers/app/server/ServerWindow.cpp +++ b/src/servers/app/server/ServerWindow.cpp @@ -92,7 +92,7 @@ ServerWindow::ServerWindow(BRect rect, const char *string, uint32 wlook, _token=win_token_handler.GetToken(); - AddWindowToDesktop(this,index); + AddWindowToDesktop(this,index,ActiveScreen()); #ifdef DEBUG_SERVERWINDOW printf("ServerWindow %s:\n",_title->String()); printf("\tFrame (%.1f,%.1f,%.1f,%.1f)\n",rect.left,rect.top,rect.right,rect.bottom); @@ -658,16 +658,20 @@ void ServerWindow::HandleMouseEvent(int32 code, int8 *buffer) #ifdef DEBUG_SERVERWINDOW_MOUSE printf("ServerWindow::HandleMouseEvent unimplemented\n"); #endif -/* ServerWindow *mousewin=NULL; + ServerWindow *mousewin=NULL; int8 *index=buffer; // Find the window which will receive our mouse event. - Layer *root=GetRootLayer(); + Layer *root=GetRootLayer(CurrentWorkspace(),ActiveScreen()); WinBorder *_winborder; // activeborder is used to remember windows when resizing/moving windows // or sliding a tab - ASSERT(root!=NULL); + if(!root) + { + printf("ERROR: HandleMouseEvent has NULL root layer!!!\n"); + return; + } // Dispatch the mouse event to the proper window switch(code) @@ -684,14 +688,10 @@ printf("ServerWindow::HandleMouseEvent unimplemented\n"); // int64 time=*((int64*)index); index+=sizeof(int64); - float x=*((float*)index); - index+=sizeof(float); - float y=*((float*)index); - index+=sizeof(float); - int32 modifiers=*((int32*)index); - index+=sizeof(uint32); - uint32 buttons=*((uint32*)index); - index+=sizeof(uint32); + float x=*((float*)index); index+=sizeof(float); + float y=*((float*)index); index+=sizeof(float); +// int32 modifiers=*((int32*)index); index+=sizeof(uint32); +// uint32 buttons=*((uint32*)index); index+=sizeof(uint32); // int32 clicks=*((int32*)index); BPoint pt(x,y); @@ -700,7 +700,7 @@ printf("ServerWindow::HandleMouseEvent unimplemented\n"); if(_winborder) { mousewin=_winborder->Window(); - _winborder->MouseDown(pt,buttons,modifiers); + _winborder->MouseDown(buffer); } break; } @@ -714,10 +714,8 @@ printf("ServerWindow::HandleMouseEvent unimplemented\n"); // int64 time=*((int64*)index); index+=sizeof(int64); - float x=*((float*)index); - index+=sizeof(float); - float y=*((float*)index); - index+=sizeof(float); + float x=*((float*)index); index+=sizeof(float); + float y=*((float*)index); index+=sizeof(float); // int32 modifiers=*((int32*)index); BPoint pt(x,y); @@ -729,8 +727,7 @@ printf("ServerWindow::HandleMouseEvent unimplemented\n"); // Eventually, we will build in MouseUp messages with buttons specified // For now, we just "assume" no mouse specification with a 0. -// _winborder->MouseUp(pt,0,0); - + _winborder->MouseUp(buffer); } break; } @@ -743,26 +740,25 @@ printf("ServerWindow::HandleMouseEvent unimplemented\n"); // 4) int32 - buttons down // int64 time=*((int64*)index); index+=sizeof(int64); - float x=*((float*)index); - index+=sizeof(float); - float y=*((float*)index); - index+=sizeof(float); - uint32 buttons=*((uint32*)index); + float x=*((float*)index); index+=sizeof(float); + float y=*((float*)index); index+=sizeof(float); +// uint32 buttons=*((uint32*)index); BPoint pt(x,y); - if(is_moving_window() || is_resizing_window() || is_sliding_tab()) + // TODO: Fix +/* if(is_moving_window() || is_resizing_window() || is_sliding_tab()) { mousewin=active_serverwindow; mousewin->_winborder->MouseMoved(pt,buttons,0); } else { - _winborder=(WinBorder*)root->GetChildAt(pt); +*/ _winborder=(WinBorder*)root->GetChildAt(pt); if(_winborder) { mousewin=_winborder->Window(); - _winborder->MouseMoved(pt,buttons,0); - } + _winborder->MouseMoved(buffer); +// } } break; } @@ -771,7 +767,6 @@ printf("ServerWindow::HandleMouseEvent unimplemented\n"); break; } } -*/ } /*! diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index f51bae2b2f..004dc17a57 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -37,8 +37,9 @@ #include "WinBorder.h" #include "AppServer.h" // for new_decorator() -#define DEBUG_WINBORDER +//#define DEBUG_WINBORDER //#define DEBUG_WINBORDER_MOUSE +//#define DEBUG_WINBORDER_CLICK #ifdef DEBUG_WINBORDER #include @@ -48,6 +49,10 @@ #include #endif +#ifdef DEBUG_WINBORDER_CLICK +#include +#endif + namespace winborder_private { bool is_moving_window=false; @@ -62,6 +67,8 @@ bool is_moving_window(void) { return winborder_private::is_moving_window; } void set_is_moving_window(bool state) { winborder_private::is_moving_window=state; } bool is_resizing_window(void) { return winborder_private::is_resizing_window; } void set_is_resizing_window(bool state) { winborder_private::is_resizing_window=state; } +bool is_sliding_tab(void) { return winborder_private::is_sliding_tab; } +void set_is_sliding_tab(bool state) { winborder_private::is_sliding_tab=state; } WinBorder * get_active_winborder(void) { return winborder_private::active_winborder; } void set_active_winborder(WinBorder *win) { winborder_private::active_winborder=win; } @@ -80,8 +87,8 @@ WinBorder::WinBorder(BRect r, const char *name, int32 look, int32 feel, int32 fl _hresizewin=false; _vresizewin=false; - _decorator=new_decorator(r,name,look,feel,flags,GetGfxDriver()); - _decorator->SetDriver(GetGfxDriver()); + _decorator=new_decorator(r,name,look,feel,flags,GetGfxDriver(ActiveScreen())); + _decorator->SetDriver(GetGfxDriver(ActiveScreen())); #ifdef DEBUG_WINBORDER printf("WinBorder %s:\n",_title->String()); @@ -103,37 +110,67 @@ void WinBorder::MouseDown(int8 *buffer) #ifdef DEBUG_WINBORDER_MOUSE printf("WinBorder %s: MouseDown unimplemented\n",_title->String()); #endif -/* _mbuttons=buttons; - kmodifiers=modifiers; - click_type click=_decorator->Clicked(pt, _mbuttons, kmodifiers); + // Buffer data: + // 1) int64 - time of mouse click + // 2) float - x coordinate of mouse click + // 3) float - y coordinate of mouse click + // 4) int32 - modifier keys down + // 5) int32 - buttons down + // 6) int32 - clicks + int8 *index=buffer; index+=sizeof(int64); + float x=*((float*)index); index+=sizeof(float); + float y=*((float*)index); index+=sizeof(float); + int32 modifiers=*((int32*)index); index+=sizeof(int32); + int32 buttons=*((int32*)index); + + BPoint pt(x,y); + + _mbuttons=buttons; + _kmodifiers=modifiers; + click_type click=_decorator->Clicked(pt, _mbuttons, _kmodifiers); _mousepos=pt; switch(click) { case CLICK_MOVETOBACK: { - MoveToBack(); +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: MoveToBack\n"); +#endif + MakeTopChild(); break; } case CLICK_MOVETOFRONT: { - MoveToFront(); +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: MoveToFront\n"); +#endif + MakeBottomChild(); break; } case CLICK_CLOSE: { +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: Close\n"); +#endif _decorator->SetClose(true); _decorator->Draw(); break; } case CLICK_ZOOM: { +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: Zoom\n"); +#endif _decorator->SetZoom(true); _decorator->Draw(); break; } case CLICK_MINIMIZE: { +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: Minimize\n"); +#endif _decorator->SetMinimize(true); _decorator->Draw(); break; @@ -141,21 +178,40 @@ printf("WinBorder %s: MouseDown unimplemented\n",_title->String()); case CLICK_DRAG: { if(buttons==B_PRIMARY_MOUSE_BUTTON) - is_moving_window=true; + { +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: Drag\n"); +#endif + MakeBottomChild(); + set_is_moving_window(true); + } if(buttons==B_SECONDARY_MOUSE_BUTTON) - MoveToBack(); + { +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: MoveToBack\n"); +#endif + MakeTopChild(); + } break; } case CLICK_SLIDETAB: { - is_sliding_tab=true; +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: Slide Tab\n"); +#endif + set_is_sliding_tab(true); break; } case CLICK_RESIZE: { if(buttons==B_PRIMARY_MOUSE_BUTTON) - is_resizing_window=true; + { +#ifdef DEBUG_WINBORDER_CLICK +printf("Click: Resize\n"); +#endif + set_is_resizing_window(true); + } break; } case CLICK_NONE: @@ -167,19 +223,30 @@ printf("WinBorder %s: MouseDown unimplemented\n",_title->String()); break; } } - if(click!=CLICK_NONE) - ActivateWindow(_win); -*/ + // TODO: fix this +// if(click!=CLICK_NONE) +// ActivateWindow(_win); } void WinBorder::MouseMoved(int8 *buffer) { + // Buffer data: + // 1) int64 - time of mouse click + // 2) float - x coordinate of mouse click + // 3) float - y coordinate of mouse click + // 4) int32 - buttons down + int8 *index=buffer; index+=sizeof(int64); + float x=*((float*)index); index+=sizeof(float); + float y=*((float*)index); index+=sizeof(float); + int32 buttons=*((int32*)index); + + BPoint pt(x,y); + click_type click=_decorator->Clicked(pt, _mbuttons, _kmodifiers); + #ifdef DEBUG_WINBORDER_MOUSE printf("WinBorder %s: MouseMoved unimplemented\n",_title->String()); #endif -/* _mbuttons=buttons; - kmodifiers=modifiers; - click_type click=_decorator->Clicked(pt, _mbuttons, kmodifiers); + if(click!=CLICK_CLOSE && _decorator->GetClose()) { _decorator->SetClose(false); @@ -198,8 +265,11 @@ printf("WinBorder %s: MouseMoved unimplemented\n",_title->String()); _decorator->Draw(); } - if(is_sliding_tab) + if(is_sliding_tab()) { +#ifdef DEBUG_WINBORDER_CLICK +printf("ClickMove: Slide Tab\n"); +#endif float dx=pt.x-_mousepos.x; if(dx!=0) @@ -207,75 +277,97 @@ printf("WinBorder %s: MouseMoved unimplemented\n",_title->String()); // SlideTab returns how much things were moved, and currently // supports just the x direction, so get the value so // we can invalidate the proper area. - layerlock->Lock(); - parent->Invalidate(_decorator->SlideTab(dx,0)); - parent->RequestDraw(); + lock_layers(); + _parent->Invalidate(_decorator->SlideTab(dx,0)); + _parent->RequestDraw(); _decorator->DrawTab(); - layerlock->Unlock(); + unlock_layers(); } } - if(is_moving_window) + + + if(is_moving_window()) { +#ifdef DEBUG_WINBORDER_CLICK +printf("ClickMove: Drag\n"); +#endif float dx=pt.x-_mousepos.x, dy=pt.y-_mousepos.y; - if(dx!=0 || dy!=0) + if(buttons!=0 && (dx!=0 || dy!=0)) { BRect oldmoveframe=_win->_frame; - clientframe.OffsetBy(pt); + _clientframe.OffsetBy(pt); _win->Lock(); _win->_frame.OffsetBy(dx,dy); _win->Unlock(); - layerlock->Lock(); -// InvalidateLowerSiblings(oldmoveframe); - parent->Invalidate(oldmoveframe); + lock_layers(); + _parent->Invalidate(oldmoveframe); MoveBy(dx,dy); - parent->RequestDraw(); + _parent->RequestDraw(); _decorator->MoveBy(BPoint(dx, dy)); _decorator->Draw(); - layerlock->Unlock(); + unlock_layers(); } } - if(is_resizing_window) + + + if(is_resizing_window()) { +#ifdef DEBUG_WINBORDER_CLICK +printf("ClickMove: Resize\n"); +#endif float dx=pt.x-_mousepos.x, dy=pt.y-_mousepos.y; - if(dx!=0 || dy!=0) + if(buttons!=0 && (dx!=0 || dy!=0)) { - clientframe.right+=dx; - clientframe.bottom+=dy; + _clientframe.right+=dx; + _clientframe.bottom+=dy; _win->Lock(); _win->_frame.right+=dx; _win->_frame.bottom+=dy; _win->Unlock(); - layerlock->Lock(); + lock_layers(); ResizeBy(dx,dy); - parent->RequestDraw(); - layerlock->Unlock(); + _parent->RequestDraw(); + unlock_layers(); _decorator->ResizeBy(dx,dy); _decorator->Draw(); } } + _mousepos=pt; -*/ + } void WinBorder::MouseUp(int8 *buffer) { + // buffer data: + // 1) int64 - time of mouse click + // 2) float - x coordinate of mouse click + // 3) float - y coordinate of mouse click + // 4) int32 - modifier keys down + int8 *index=buffer; index+=sizeof(int64); + float x=*((float*)index); index+=sizeof(float); + float y=*((float*)index); index+=sizeof(float); + int32 modifiers=*((int32*)index); + BPoint pt(x,y); + #ifdef DEBUG_WINBORDER_MOUSE printf("WinBorder %s: MouseUp unimplmented\n",_title->String()); #endif -/* - _mbuttons=buttons; - kmodifiers=modifiers; - is_moving_window=false; - is_resizing_window=false; - is_sliding_tab=false; - click_type click=_decorator->Clicked(pt, _mbuttons, kmodifiers); + _mbuttons=0; + _kmodifiers=modifiers; + + set_is_moving_window(false); + set_is_resizing_window(false); + set_is_sliding_tab(false); + + click_type click=_decorator->Clicked(pt, _mbuttons, _kmodifiers); switch(click) { @@ -310,7 +402,6 @@ printf("WinBorder %s: MouseUp unimplmented\n",_title->String()); break; } } -*/ } void WinBorder::RequestDraw(const BRect &r)