From d593ad8f06534e5366cfbb22734d3c139f3c6e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Wed, 25 May 2005 23:59:23 +0000 Subject: [PATCH] added a little debugging facility for printing on-screen debugging info on Haiku. For those like me without serial debugging... also made RootLayer use the desktop background color. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12819 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/DebugInfoManager.cpp | 64 +++++++++++++++++++ src/servers/app/DebugInfoManager.h | 47 ++++++++++++++ src/servers/app/Jamfile | 1 + src/servers/app/Layer.cpp | 9 +-- src/servers/app/RootLayer.cpp | 91 ++++++++++++++++++++-------- src/servers/app/RootLayer.h | 11 +++- src/servers/app/ServerWindow.cpp | 5 +- 7 files changed, 195 insertions(+), 33 deletions(-) create mode 100644 src/servers/app/DebugInfoManager.cpp create mode 100644 src/servers/app/DebugInfoManager.h diff --git a/src/servers/app/DebugInfoManager.cpp b/src/servers/app/DebugInfoManager.cpp new file mode 100644 index 0000000000..6b59b64493 --- /dev/null +++ b/src/servers/app/DebugInfoManager.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2005, Stephan Aßmus . All rights reserved. + * Distributed under the terms of the MIT License. + * + * Class used to manage global access to on-screen debugging info + * in the RootLayer class. + * + */ + +#include "RootLayer.h" + +#include "DebugInfoManager.h" + +// init globals +DebugInfoManager* +DebugInfoManager::sDefaultInstance = NULL; + +#if ON_SCREEN_DEBUGGING_INFO +char* gDebugString = new char[2048]; +#endif + +// destructor +DebugInfoManager::~DebugInfoManager() +{ +} + +// Default +DebugInfoManager* +DebugInfoManager::Default() +{ + if (!sDefaultInstance) + sDefaultInstance = new DebugInfoManager(); + return sDefaultInstance; +} + +// AddInfo +void +DebugInfoManager::AddInfo(const char* string) +{ +#if ON_SCREEN_DEBUGGING_INFO + if (fRootLayer) { + fRootLayer->AddDebugInfo(string); + } +#endif // ON_SCREEN_DEBUGGING_INFO +} + +// constructor +DebugInfoManager::DebugInfoManager() +#if ON_SCREEN_DEBUGGING_INFO + : fRootLayer(NULL) +#endif // ON_SCREEN_DEBUGGING_INFO +{ + gDebugString[0] = 0; +} + +#if ON_SCREEN_DEBUGGING_INFO +// SetRootLayer +void +DebugInfoManager::SetRootLayer(RootLayer* layer) +{ + fRootLayer = layer; +} +#endif // ON_SCREEN_DEBUGGING_INFO + diff --git a/src/servers/app/DebugInfoManager.h b/src/servers/app/DebugInfoManager.h new file mode 100644 index 0000000000..1d17a781b7 --- /dev/null +++ b/src/servers/app/DebugInfoManager.h @@ -0,0 +1,47 @@ +/* + * Copyright 2005, Stephan Aßmus . All rights reserved. + * Distributed under the terms of the MIT License. + * + * Class used to manage global access to on-screen debugging info + * in the RootLayer class. + * + */ + +#ifndef DEBUG_INFO_MANAGER_H +#define DEBUG_INFO_MANAGER_H + +#include + +#if __HAIKU__ +# define ON_SCREEN_DEBUGGING_INFO 1 +#else +# define ON_SCREEN_DEBUGGING_INFO 1 +#endif + +#if ON_SCREEN_DEBUGGING_INFO + extern char* gDebugString; +# define CRITICAL(x) { sprintf(gDebugString, (x)); DebugInfoManager::Default()->AddInfo(gDebugString); } +#else +# define CRITICAL(x) debugger x +#endif // ON_SCREEN_DEBUGGING_INFO + +class DebugInfoManager { + public: + virtual ~DebugInfoManager(); + + static DebugInfoManager* Default(); + void AddInfo(const char* string); + + private: + DebugInfoManager(); + static DebugInfoManager* sDefaultInstance; + +#if ON_SCREEN_DEBUGGING_INFO + friend class RootLayer; + void SetRootLayer(RootLayer* layer); + + RootLayer* fRootLayer; +#endif // ON_SCREEN_DEBUGGING_INFO +}; + +#endif // DEBUG_INFO_H diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index cb81814bb2..d46818347a 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -70,6 +70,7 @@ SharedLibrary appserver : Server app_server : # Misc. Sources + DebugInfoManager.cpp FMWList.cpp PicturePlayer.cpp PNGDump.cpp diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 29a39ed92e..31dee32cc8 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -36,6 +36,7 @@ #include #include +#include "DebugInfoManager.h" #include "DisplayDriver.h" #include "LayerData.h" #include "PortLink.h" @@ -118,7 +119,7 @@ Layer::Layer(BRect frame, const char* name, int32 token, fFrame.Set(0, 0, 5, 5); if (!fDriver) - debugger("You MUST have a valid driver to init a Layer object\n"); + CRITICAL("You MUST have a valid driver to init a Layer object\n"); STRACE(("Layer(%s) successfuly created\n", GetName())); } @@ -965,7 +966,7 @@ Layer::MoveBy(float x, float y) { STRACE(("Layer(%s)::MoveBy() START\n", GetName())); if (!fParent) { - debugger("ERROR: in Layer::MoveBy()! - No parent!\n"); + CRITICAL("ERROR: in Layer::MoveBy()! - No parent!\n"); return; } @@ -1245,7 +1246,7 @@ Layer::UpdateStart() wb->fUpdateReg.MakeEmpty(); wb->cnt--; if (wb->cnt != 0) - debugger("Adi2: Not Allowed!"); + CRITICAL("Layer::UpdateStart(): wb->cnt != 0 -> Not Allowed!"); } } @@ -1404,7 +1405,7 @@ Layer::RequestDraw(const BRegion ®, Layer *startFrom) fOwner->fUpdateReg = fOwner->zUpdateReg; fOwner->cnt++; if (fOwner->cnt != 1) - debugger("Adi: Not Allowed!"); + CRITICAL("Layer::RequestDraw(): fOwner->cnt != 1 -> Not Allowed!"); fOwner->zUpdateReg.MakeEmpty(); SendUpdateMsg(fOwner->fUpdateReg); fOwner->fRequestSent = true; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index 8e7c00ffed..da5470f366 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2001-2003, Haiku, Inc. +// Copyright (c) 2001-2005, Haiku, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ // Author: Gabe Yoder // DarkWyrm // Adi Oanca +// Stephan Aßmus // Description: Class used for the top layer of each workspace's Layer tree // //------------------------------------------------------------------------------ @@ -59,6 +60,8 @@ #define STRACE(a) /* nothing */ #endif +static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152); + RootLayer::RootLayer(const char *name, int32 workspaceCount, Desktop *desktop, DisplayDriver *driver) : Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver) @@ -107,7 +110,10 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, // init the first, default workspace fActiveWksIndex = 0; - fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00, RGBColor()); + fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00, + kDefaultWorkspaceColor); + fLayerData->SetHighColor(RGBColor(255, 255, 255)); + fLayerData->SetLowColor(fWorkspace[fActiveWksIndex]->BGColor()); // Spawn our working thread // fThreadID = spawn_thread(WorkingThread, name, B_REAL_TIME_DISPLAY_PRIORITY, this); @@ -118,6 +124,9 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fListenPort = -1; return; } +#if ON_SCREEN_DEBUGGING_INFO + DebugInfoManager::Default()->SetRootLayer(this); +#endif } RootLayer::~RootLayer() @@ -131,17 +140,10 @@ RootLayer::~RootLayer() wait_for_thread(fThreadID, &exitValue); - if (fDragMessage) - delete fDragMessage; + delete fDragMessage; for (int32 i = 0; i < fWsCount; i++) - { - if (fWorkspace[i]) - { - delete fWorkspace[i]; - fWorkspace[i] = NULL; - } - } + delete fWorkspace[i]; // RootLayer object just uses Screen objects, it is not allowed to delete them. } @@ -152,7 +154,7 @@ void RootLayer::RunThread() if (fThreadID > 0) resume_thread(fThreadID); else - debugger("Can not create any more threads.\n"); + CRITICAL("Can not create any more threads.\n"); } /*! @@ -415,7 +417,7 @@ void RootLayer::AddWinBorder(WinBorder* winBorder) { if (!winBorder->IsHidden()) { - debugger("RootLayer::RemoveWinBorder - winBorder must be hidden\n"); + CRITICAL("RootLayer::RemoveWinBorder - winBorder must be hidden\n"); return; } @@ -453,7 +455,7 @@ void RootLayer::RemoveWinBorder(WinBorder* winBorder) if (!winBorder->IsHidden()) { - debugger("RootLayer::RemoveWinBorder - winBorder must be hidden\n"); + CRITICAL("RootLayer::RemoveWinBorder - winBorder must be hidden\n"); return; } @@ -476,7 +478,7 @@ void RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder) // SUBSET windows _must_ have their workspaceIndex set to 0x0 if (winBorder->Workspaces() != 0UL) { - debugger("SUBSET windows _must_ have their workspaceIndex set to 0x0\n"); + CRITICAL("SUBSET windows _must_ have their workspaceIndex set to 0x0\n"); return; } @@ -552,7 +554,7 @@ bool RootLayer::SetActiveWorkspace(int32 index) if (!fWorkspace[index]) { // TODO: we NEED datas from a file!!! - fWorkspace[index] = new Workspace(index, 0xFF00FF00, RGBColor()); + fWorkspace[index] = new Workspace(index, 0xFF00FF00, kDefaultWorkspaceColor); // we need to lock the window list here so no other window can be created desktop->Lock(); @@ -574,6 +576,12 @@ bool RootLayer::SetActiveWorkspace(int32 index) desktop->Unlock(); } + rgb_color bg = fWorkspace[index]->BGColor().GetColor32(); + if ((bg.red + bg.green + bg.blue) / 3 > 128) + fLayerData->SetHighColor(RGBColor(0, 0, 0)); + else + fLayerData->SetHighColor(RGBColor(255, 255, 255)); + fLayerData->SetLowColor(fWorkspace[index]->BGColor()); int32 exIndex = ActiveWorkspaceIndex(); @@ -975,15 +983,18 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) if (fLastMousePossition != evt.where) { // TODO: a B_MOUSE_MOVED message might have to be generated in order to // correctly trigger entered/exited view transits. -fprintf(stderr, "mouse position changed in B_MOUSE_DOWN (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!", - evt.where.x, evt.where.y, fLastMousePossition.x, fLastMousePossition.y); +// Commented for now, since it is not _that_ critical and happens frequently with the Haiku +// mouse driver (which is ok, but we need to catch it here). +// CRITICAL("mouse position changed in B_MOUSE_DOWN from last B_MOUSE_MOVED\n"); // update on screen mouse pos GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y); fLastMousePossition = evt.where; } - if (fLastMouseMoved == NULL) - debugger("RootLayer: fLastMouseMoved is null!\n"); + if (fLastMouseMoved == NULL) { + CRITICAL("RootLayer: fLastMouseMoved is null!\n"); + break; + } if (fLastMouseMoved == this) break; @@ -1159,7 +1170,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M // from within RootLayer's thread!!! Layer *target = LayerAt(evt.where); if (target == NULL) - debugger("RootLayer::MouseEventHandler: 'target' can't be null.\n"); + CRITICAL("RootLayer::MouseEventHandler: 'target' can't be null.\n"); WinBorder *winBorderUnder = NULL; // TODO: I think that windows created without the B_ASYNCHRONOUS_CONTROLS flag @@ -2047,16 +2058,44 @@ void RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive) // NOTE: the following 3 lines are here for safety reasons! fLastMouseMoved = LayerAt(fLastMousePossition); if (fLastMouseMoved == NULL) - debugger("RootLayer::KeyboardEventHandler: 'fLastMouseMoved' can't be null.\n"); + CRITICAL("RootLayer::KeyboardEventHandler: 'fLastMouseMoved' can't be null.\n"); } void RootLayer::Draw(const BRect &r) { - fDriver->FillRect(r, fLayerData->ViewColor()); + fDriver->FillRect(r, fWorkspace[fActiveWksIndex]->BGColor()); #ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER char string[30]; - sprintf(string, "Workspace %ld", fActiveWksIndex+1); - fDriver->DrawString(string, strlen(string), BPoint(5,15), + sprintf(string, "Workspace %ld", fActiveWksIndex + 1); + fDriver->DrawString(string, strlen(string), BPoint(5, 15), fLayerData); -#endif +#endif // APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER +#if ON_SCREEN_DEBUGGING_INFO + BPoint location(5, 40); + float textHeight = 15.0; // be lazy + const char* p = fDebugInfo.String(); + const char* start = p; + while (*p) { + p++; + if (*p == 0 || *p == '\n') { + fDriver->DrawString(start, p - start, location, + fLayerData); + // NOTE: Eventually, this will be below the screen! + location.y += textHeight; + start = p + 1; + } + } +#endif // ON_SCREEN_DEBUGGING_INFO } + +#if ON_SCREEN_DEBUGGING_INFO +void +RootLayer::AddDebugInfo(const char* string) +{ + if (Lock()) { + fDebugInfo << string; + GoRedraw(this, BRegion(fFrame)); + Unlock(); + } +} +#endif // ON_SCREEN_DEBUGGING_INFO diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index d10aa41c67..d37373756d 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright (c) 2001-2003, Haiku, Inc. +// Copyright (c) 2001-2005, Haiku, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,7 @@ // File Name: RootLayer.h // Author: Gabe Yoder // DarkWyrm +// Stephan Aßmus // Description: Class used for the top layer of each workspace's Layer tree // //------------------------------------------------------------------------------ @@ -31,6 +32,7 @@ #include #include +#include "DebugInfoManager.h" #include "Layer.h" #include "FMWList.h" #include "CursorManager.h" @@ -43,6 +45,7 @@ class Desktop; class DisplayDriver; class BPortLink; + /*! \class RootLayer RootLayer.h \brief Class used for the top layer of each workspace's Layer tree @@ -196,6 +199,12 @@ friend class Desktop; int32 fScreenShotIndex; bool fQuiting; + +#if ON_SCREEN_DEBUGGING_INFO + friend class DebugInfoManager; + void AddDebugInfo(const char* string); + BString fDebugInfo; +#endif }; #endif diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 068b5fe206..1eacff5bed 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -37,6 +37,7 @@ #include #include "AppServer.h" #include "BGet++.h" +#include "DebugInfoManager.h" #include "Desktop.h" #include "Layer.h" #include "RAMLinkMsgReader.h" @@ -496,7 +497,7 @@ void ServerWindow::DispatchMessage(int32 code, LinkMsgReader &link) if (current) cl=current; else // hope this NEVER happens! :-) - debugger("Server PANIC: window cannot find Layer with ID\n"); + CRITICAL("Server PANIC: window cannot find Layer with ID\n"); break; } @@ -2099,7 +2100,7 @@ int32 ServerWindow::MonitorWin(void *data) // } // ServerWindow's destructor takes care of pulling this object off the desktop. if (!win->fWinBorder->IsHidden()) - debugger("ServerWindow: a window must be hidden before it's deleted\n"); + CRITICAL("ServerWindow: a window must be hidden before it's deleted\n"); delete win; // myRootLayer->Unlock();