diff --git a/docs/develop/ports/arm/urls.txt b/docs/develop/ports/arm/urls.txt new file mode 100644 index 0000000000..abaef44273 --- /dev/null +++ b/docs/develop/ports/arm/urls.txt @@ -0,0 +1,8 @@ +* FDT +http://www.denx.de/wiki/U-Boot/UBootFdtInfo +http://wiki.freebsd.org/FlattenedDeviceTree#Supporting_library_.28libfdt.29 +http://elinux.org/images/4/4e/Glikely-powerpc-porting-guide.pdf +http://ols.fedoraproject.org/OLS/Reprints-2008/likely2-reprint.pdf +http://www.bsdcan.org/2010/schedule/events/171.en.html +http://www.devicetree.org/ (unofficial bindings) +http://elinux.org/Device_Trees diff --git a/docs/develop/ports/m68k/TODO b/docs/develop/ports/m68k/TODO index a75d4dadbe..e67f5557e4 100644 --- a/docs/develop/ports/m68k/TODO +++ b/docs/develop/ports/m68k/TODO @@ -1,4 +1,3 @@ -- fix the VM stuff that broke after the Great VM Overhaul(tm). - optimization: remove M68KPagingStructures[*]::UpdateAllPageDirs() and just allocate all the kernel page root entries at boot and be done with it. It's not very big anyway. - possibly other optimizations in the VM code due to not supporting SMP? diff --git a/docs/develop/ports/m68k/amiga/urls.txt b/docs/develop/ports/m68k/amiga/urls.txt new file mode 100644 index 0000000000..b11018a6b6 --- /dev/null +++ b/docs/develop/ports/m68k/amiga/urls.txt @@ -0,0 +1 @@ +http://wandel.ca/homepage/execdis/ diff --git a/docs/develop/ports/m68k/atari/urls.txt b/docs/develop/ports/m68k/atari/urls.txt new file mode 100644 index 0000000000..2874b4b90c --- /dev/null +++ b/docs/develop/ports/m68k/atari/urls.txt @@ -0,0 +1,19 @@ +http://toshyp.atari.org/en/index.html + +http://www.lysator.liu.se/~celeborn/sync/atari/misc.html +http://www.lysator.liu.se/~celeborn/sync/atari/ATARI/F30.ZIP +http://www.lysator.liu.se/~celeborn/sync/atari/ATARI/FALCLIB6.ZIP +http://www.lysator.liu.se/~celeborn/sync/atari/ATARI/FALCREGS.ZIP + + +http://fxr.watson.org/fxr/source/include/asm-m68k/atarihw.h?v=linux-2.4.22 +http://lxr.linux.no/linux+v2.6.27/arch/m68k/atari/config.c#L664 + +http://www.atari-forum.com/wiki/index.php/MFP_MK68901 + +http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/arch/atari/stand/xxboot/ahdi-xxboot/xxboot.ahdi.S +AHDI args +http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/arch/atari/stand/xxboot/wdboot/wdboot.S +http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/arch/atari/stand/xxboot/sdboot/sdboot.S +http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/arch/atari/stand/xxboot/fdboot/fdboot.S + diff --git a/src/add-ons/screen_savers/Jamfile b/src/add-ons/screen_savers/Jamfile index 8246ed0170..1116db75f6 100644 --- a/src/add-ons/screen_savers/Jamfile +++ b/src/add-ons/screen_savers/Jamfile @@ -9,6 +9,7 @@ SubInclude HAIKU_TOP src add-ons screen_savers icons ; SubInclude HAIKU_TOP src add-ons screen_savers ifs ; SubInclude HAIKU_TOP src add-ons screen_savers leaves ; SubInclude HAIKU_TOP src add-ons screen_savers message ; +SubInclude HAIKU_TOP src add-ons screen_savers shelf ; SubInclude HAIKU_TOP src add-ons screen_savers simpleclock ; SubInclude HAIKU_TOP src add-ons screen_savers slideshowsaver ; SubInclude HAIKU_TOP src add-ons screen_savers spider ; diff --git a/src/add-ons/screen_savers/shelf/Jamfile b/src/add-ons/screen_savers/shelf/Jamfile new file mode 100644 index 0000000000..09702e4466 --- /dev/null +++ b/src/add-ons/screen_savers/shelf/Jamfile @@ -0,0 +1,6 @@ +SubDir HAIKU_TOP src add-ons screen_savers shelf ; + +ScreenSaver Shelf : + Shelf.cpp : + be libscreensaver.so ; + diff --git a/src/add-ons/screen_savers/shelf/Shelf.cpp b/src/add-ons/screen_savers/shelf/Shelf.cpp new file mode 100644 index 0000000000..e304c515c7 --- /dev/null +++ b/src/add-ons/screen_savers/shelf/Shelf.cpp @@ -0,0 +1,263 @@ +/* + * Copyright 2007-2012, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ryan Leavengood + * François Revol + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const rgb_color kMediumBlue = {0, 0, 100}; +const rgb_color kWhite = {255, 255, 255}; + +const char *kInConfigName = "InConfig"; +const char *kShelfArchiveName = "Shelf"; + + +// Inspired by the classic BeOS screensaver, of course +class Shelf : public BScreenSaver +{ + public: + Shelf(BMessage *archive, image_id); + void Draw(BView *view, int32 frame); + void StartConfig(BView *view); + void StopConfig(); + status_t StartSaver(BView *view, bool preview); + void StopSaver(); + status_t SaveState(BMessage *state) const; + + private: + BShelf *fShelf; + BWindow *fConfigWindow; + bool fInConfig; + bool fInEdit; + BMallocIO fShelfData; +}; + + +BScreenSaver *instantiate_screen_saver(BMessage *msg, image_id image) +{ + PRINT(("%s()\n", __FUNCTION__)); + return new Shelf(msg, image); +} + + +Shelf::Shelf(BMessage *archive, image_id id) + : BScreenSaver(archive, id) + , fShelf(NULL) + , fConfigWindow(NULL) + , fInConfig(false) + , fInEdit(false) + , fShelfData() +{ + archive->PrintToStream(); + if (archive->FindBool(kInConfigName, &fInConfig) < B_OK) + fInConfig = false; + + status_t status; + const void *data; + ssize_t length; + + status = archive->FindData(kShelfArchiveName, 'shlf', &data, &length); + if (status == B_OK) { + fShelfData.WriteAt(0LL, data, length); + fShelfData.Seek(SEEK_SET, 0LL); + } + + +/* + if (fInConfig) { + fInEdit = true; + fInConfig = false; + } +*/} + + +void +Shelf::StartConfig(BView *view) +{ + PRINT(("%p:%s()\n", this, __FUNCTION__)); + fInConfig = true; + view->AddChild(new BStringView(BRect(20, 10, 200, 35), "", + "Shelf, by François Revol.")); + + BScreen screen; + fConfigWindow = new BWindow(screen.Frame(), "Shelf Config", + B_UNTYPED_WINDOW, B_NOT_MOVABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE + | B_NOT_MINIMIZABLE | B_NOT_RESIZABLE | B_AVOID_FRONT | B_AVOID_FOCUS); + + BView *shelfView = new BView(fConfigWindow->Bounds(), "ShelfView", + B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS); + shelfView->SetViewColor(216, 216, 216, 0); + + fConfigWindow->AddChild(shelfView); + + fShelfData.Seek(SEEK_SET, 0LL); + fShelf = new BShelf(&fShelfData, shelfView); + fShelf->SetDisplaysZombies(true); + fShelfData.Seek(SEEK_SET, 0LL); + + // start the Looper + fConfigWindow->Show(); + + fConfigWindow->Lock(); + fConfigWindow->SendBehind(view->Window()); + fConfigWindow->Unlock(); + + //"\nDrop replicants on me!" +} + + +void +Shelf::StopConfig() +{ + fInConfig = false; + PRINT(("%p:%s()\n", this, __FUNCTION__)); + fConfigWindow->Lock(); + fConfigWindow->Quit(); + fShelf = NULL; + + BScreenSaver::StopConfig(); +} + + +status_t +Shelf::StartSaver(BView *view, bool preview) +{ + PRINT(("%p:%s(, %d)\n", this, __FUNCTION__, preview)); + if (!preview) { + view->SetViewColor(216, 216, 216, 0); + fShelfData.Seek(SEEK_SET, 0LL); + fShelf = new BShelf(&fShelfData, view); + + } + BString s; + s << "preview: " << preview << " "; + s << "BView:Name: " << view->Name() << " "; + s << "BApp:Name: " << be_app->Name(); + + PRINT(("%p:%s:%s\n", this, __FUNCTION__, s.String())); + //BAlert *a = new BAlert("debug", s.String(), "Ok"); + //a->Go(); + return B_ERROR; +#if 0 + float width = view->Bounds().Width(); + float height = view->Bounds().Height(); + + BFont font; + view->GetFont(&font); + font.SetSize(height / 2.5); + view->SetFont(&font); + + BRect rect; + escapement_delta delta; + delta.nonspace = 0; + delta.space = 0; + // If anyone has suggestions for how to clean this up, speak up + font.GetBoundingBoxesForStrings(&fLine1, 1, B_SCREEN_METRIC, &delta, &rect); + float y = ((height - (rect.Height() * 2 + height / 10)) / 2) + rect.Height(); + fLine1Start.Set((width - rect.Width()) / 2, y); + font.GetBoundingBoxesForStrings(&fLine2, 1, B_SCREEN_METRIC, &delta, &rect); + fLine2Start.Set((width - rect.Width()) / 2, y + rect.Height() + height / 10); + +#endif + return B_OK; +} + + +void +Shelf::StopSaver() +{ + PRINT(("%p:%s()\n", this, __FUNCTION__)); + //if (fShelf) + //delete fShelf; + //fShelf = NULL; +} + + +status_t +Shelf::SaveState(BMessage *state) const +{ + status_t status; + + PRINT(("%p:%s()\n", this, __FUNCTION__)); + state->PrintToStream(); + + if (fInConfig) + state->AddBool(kInConfigName, fInConfig); + if (!fInConfig) + state->RemoveData(kInConfigName); + if (fInConfig && fShelf) { + status = state->AddBool("got it", true); + + fShelf->LockLooper(); + status = fShelf->Save(); + fShelf->UnlockLooper(); + if (status < B_OK) + return status; + status = state->AddData(kShelfArchiveName, 'shlf', fShelfData.Buffer(), + fShelfData.BufferLength()); + +// return B_OK; +//fShelfData.SetSize(0LL); +#if 0 + BMallocIO mio; + status = fShelf->SetSaveLocation(&mio); + if (status < B_OK) + return status; + status = fShelf->Save(); + fShelf->SetSaveLocation((BDataIO *)NULL); + if (status < B_OK) + return status; + status = state->AddData(kShelfArchiveName, 'shlf', mio.Buffer(), + mio.BufferLength()); +#endif + if (status < B_OK) + return status; + } + return B_OK; +} + + +void +Shelf::Draw(BView *view, int32 frame) +{ + PRINT(("%p:%s(, %d)\n", this, __FUNCTION__, frame)); + BScreenSaver::Draw(view, frame); +#if 0 + if (frame == 0) { + // fill with blue on first frame + view->SetLowColor(kMediumBlue); + view->FillRect(view->Bounds(), B_SOLID_LOW); + + // Set tick size to 500,000 microseconds = 0.5 second + SetTickSize(500000); + } else { + // Drawing the background color every other frame to make the text blink + if (frame % 2 == 1) + view->SetHighColor(kWhite); + else + view->SetHighColor(kMediumBlue); + + view->DrawString(fLine1, fLine1Start); + view->DrawString(fLine2, fLine2Start); + } +#endif +} + + diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index fca0a8318b..727155ef50 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -61,6 +61,7 @@ Application Debugger : TeamMemoryBlockManager.cpp TeamDebugger.cpp ThreadHandler.cpp + WatchpointManager.cpp Worker.cpp # arch @@ -140,6 +141,7 @@ Application Debugger : TypeComponentPath.cpp TypeLookupConstraints.cpp Variable.cpp + Watchpoint.cpp # settings BreakpointSetting.cpp @@ -148,6 +150,7 @@ Application Debugger : TeamSettings.cpp TeamUiSettings.cpp TeamUiSettingsFactory.cpp + WatchpointSetting.cpp # settings/generic Setting.cpp diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index 64af5be95f..75a2df88f3 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -16,6 +16,10 @@ enum { MSG_CLEAR_BREAKPOINT = 'cbrk', MSG_ENABLE_BREAKPOINT = 'ebrk', MSG_DISABLE_BREAKPOINT = 'dbrk', + MSG_SET_WATCHPOINT = 'swpt', + MSG_CLEAR_WATCHPOINT = 'cwpt', + MSG_ENABLE_WATCHPOINT = 'ewpt', + MSG_DISABLE_WATCHPOINT = 'dwpt', MSG_THREAD_STATE_CHANGED = 'tsch', MSG_THREAD_CPU_STATE_CHANGED = 'tcsc', diff --git a/src/apps/debugger/TeamDebugger.cpp b/src/apps/debugger/TeamDebugger.cpp index 58eb10d880..26378e1019 100644 --- a/src/apps/debugger/TeamDebugger.cpp +++ b/src/apps/debugger/TeamDebugger.cpp @@ -45,6 +45,8 @@ #include "ValueNode.h" #include "ValueNodeContainer.h" #include "Variable.h" +#include "WatchpointManager.h" +#include "WatchpointSetting.h" // #pragma mark - ImageHandler @@ -142,6 +144,7 @@ TeamDebugger::TeamDebugger(Listener* listener, UserInterface* userInterface, fFileManager(NULL), fWorker(NULL), fBreakpointManager(NULL), + fWatchpointManager(NULL), fMemoryBlockManager(NULL), fDebugEventListener(-1), fUserInterface(userInterface), @@ -199,6 +202,7 @@ TeamDebugger::~TeamDebugger() delete fImageHandlers; delete fBreakpointManager; + delete fWatchpointManager; delete fMemoryBlockManager; delete fWorker; delete fTeam; @@ -304,6 +308,16 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, bool stopInMain) if (error != B_OK) return error; + // create the watchpoint manager + fWatchpointManager = new(std::nothrow) WatchpointManager(fTeam, + fDebuggerInterface); + if (fWatchpointManager == NULL) + return B_NO_MEMORY; + + error = fWatchpointManager->Init(); + if (error != B_OK) + return error; + // create the memory block manager fMemoryBlockManager = new(std::nothrow) TeamMemoryBlockManager(); if (fMemoryBlockManager == NULL) @@ -465,6 +479,46 @@ TeamDebugger::MessageReceived(BMessage* message) break; } + case MSG_SET_WATCHPOINT: + case MSG_CLEAR_WATCHPOINT: + { + Watchpoint* watchpoint = NULL; + BReference watchpointReference; + uint64 address = 0; + uint32 type = 0; + int32 length = 0; + + if (message->FindPointer("watchpoint", (void**)&watchpoint) + == B_OK) { + watchpointReference.SetTo(watchpoint, true); + } else if (message->FindUInt64("address", &address) != B_OK) + break; + + if (message->what == MSG_SET_WATCHPOINT) { + if (watchpoint == NULL && (message->FindUInt32("type", &type) + != B_OK + || message->FindInt32("length", &length) != B_OK)) { + break; + } + + bool enabled; + if (message->FindBool("enabled", &enabled) != B_OK) + enabled = true; + + if (watchpoint != NULL) + _HandleSetWatchpoint(watchpoint, enabled); + else + _HandleSetWatchpoint(address, type, length, enabled); + } else { + if (watchpoint != NULL) + _HandleClearWatchpoint(watchpoint); + else + _HandleClearWatchpoint(address); + } + + break; + } + case MSG_INSPECT_ADDRESS: { TeamMemoryBlock::Listener* listener; @@ -696,6 +750,54 @@ TeamDebugger::ClearBreakpointRequested(UserBreakpoint* breakpoint) } +void +TeamDebugger::SetWatchpointRequested(target_addr_t address, uint32 type, + int32 length, bool enabled) +{ + BMessage message(MSG_SET_WATCHPOINT); + message.AddUInt64("address", (uint64)address); + message.AddUInt32("type", type); + message.AddInt32("length", length); + message.AddBool("enabled", enabled); + PostMessage(&message); +} + + +void +TeamDebugger::SetWatchpointEnabledRequested(Watchpoint* watchpoint, + bool enabled) +{ + BMessage message(MSG_SET_WATCHPOINT); + BReference watchpointReference(watchpoint); + if (message.AddPointer("watchpoint", watchpoint) == B_OK + && message.AddBool("enabled", enabled) == B_OK + && PostMessage(&message) == B_OK) { + watchpointReference.Detach(); + } +} + + +void +TeamDebugger::ClearWatchpointRequested(target_addr_t address) +{ + BMessage message(MSG_CLEAR_WATCHPOINT); + message.AddUInt64("address", (uint64)address); + PostMessage(&message); +} + + +void +TeamDebugger::ClearWatchpointRequested(Watchpoint* watchpoint) +{ + BMessage message(MSG_CLEAR_WATCHPOINT); + BReference watchpointReference(watchpoint); + if (message.AddPointer("watchpoint", watchpoint) == B_OK + && PostMessage(&message) == B_OK) { + watchpointReference.Detach(); + } +} + + void TeamDebugger::InspectRequested(target_addr_t address, TeamMemoryBlock::Listener *listener) @@ -1309,6 +1411,59 @@ TeamDebugger::_HandleClearUserBreakpoint(UserBreakpoint* breakpoint) } +void +TeamDebugger::_HandleSetWatchpoint(target_addr_t address, uint32 type, + int32 length, bool enabled) +{ + Watchpoint* watchpoint = new(std::nothrow) Watchpoint(address, type, + length); + + if (watchpoint == NULL) + return; + BReference watchpointRef(watchpoint, true); + + _HandleSetWatchpoint(watchpoint, enabled); +} + + +void +TeamDebugger::_HandleSetWatchpoint(Watchpoint* watchpoint, bool enabled) +{ + status_t error = fWatchpointManager->InstallWatchpoint(watchpoint, + enabled); + if (error != B_OK) { + _NotifyUser("Install Watchpoint", "Failed to install watchpoint: %s", + strerror(error)); + } +} + + +void +TeamDebugger::_HandleClearWatchpoint(target_addr_t address) +{ + TRACE_CONTROL("TeamDebugger::_HandleClearWatchpoint(%#" B_PRIx64 ")\n", + address); + + AutoLocker< ::Team> locker(fTeam); + + Watchpoint* watchpoint = fTeam->WatchpointAtAddress(address); + if (watchpoint == NULL) + return; + BReference watchpointReference(watchpoint); + + locker.Unlock(); + + _HandleClearWatchpoint(watchpoint); +} + + +void +TeamDebugger::_HandleClearWatchpoint(Watchpoint* watchpoint) +{ + fWatchpointManager->UninstallWatchpoint(watchpoint); +} + + void TeamDebugger::_HandleInspectAddress(target_addr_t address, TeamMemoryBlock::Listener* listener) @@ -1428,6 +1583,21 @@ TeamDebugger::_LoadSettings() breakpointSetting->IsEnabled()); } + // create the saved watchpoints; + for (int32 i = 0; const WatchpointSetting* watchpointSetting + = fTeamSettings.WatchpointAt(i); i++) { + Watchpoint* watchpoint = new(std::nothrow) Watchpoint( + watchpointSetting->Address(), watchpointSetting->Type(), + watchpointSetting->Length()); + if (watchpoint == NULL) + return; + BReference watchpointReference(watchpoint, true); + + // install it + fWatchpointManager->InstallWatchpoint(watchpoint, + watchpointSetting->IsEnabled()); + } + const TeamUiSettings* uiSettings = fTeamSettings.UiSettingFor( fUserInterface->ID()); if (uiSettings != NULL) diff --git a/src/apps/debugger/TeamDebugger.h b/src/apps/debugger/TeamDebugger.h index 189a448fc1..b66d5405d8 100644 --- a/src/apps/debugger/TeamDebugger.h +++ b/src/apps/debugger/TeamDebugger.h @@ -24,6 +24,7 @@ class FileManager; class SettingsManager; class TeamDebugInfo; class TeamMemoryBlockManager; +class WatchpointManager; class TeamDebugger : public BLooper, private UserInterfaceListener, @@ -67,6 +68,14 @@ private: virtual void ClearBreakpointRequested(target_addr_t address); virtual void ClearBreakpointRequested( UserBreakpoint* breakpoint); + virtual void SetWatchpointRequested(target_addr_t address, + uint32 type, int32 length, bool enabled); + virtual void SetWatchpointEnabledRequested( + Watchpoint *watchpoint, bool enabled); + virtual void ClearWatchpointRequested(target_addr_t address); + virtual void ClearWatchpointRequested( + Watchpoint* breakpoint); + virtual void InspectRequested(target_addr_t address, TeamMemoryBlock::Listener* listener); virtual bool UserInterfaceQuitRequested( @@ -123,6 +132,13 @@ private: void _HandleClearUserBreakpoint( UserBreakpoint* breakpoint); + void _HandleSetWatchpoint(target_addr_t address, + uint32 type, int32 length, bool enabled); + void _HandleSetWatchpoint( + Watchpoint* watchpoint, bool enabled); + void _HandleClearWatchpoint( target_addr_t address); + void _HandleClearWatchpoint(Watchpoint* watchpoint); + void _HandleInspectAddress( target_addr_t address, TeamMemoryBlock::Listener* listener); @@ -151,6 +167,7 @@ private: FileManager* fFileManager; Worker* fWorker; BreakpointManager* fBreakpointManager; + WatchpointManager* fWatchpointManager; TeamMemoryBlockManager* fMemoryBlockManager; thread_id fDebugEventListener; diff --git a/src/apps/debugger/WatchpointManager.cpp b/src/apps/debugger/WatchpointManager.cpp new file mode 100644 index 0000000000..e5854a06be --- /dev/null +++ b/src/apps/debugger/WatchpointManager.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + +#include "WatchpointManager.h" + +#include + +#include + +#include + +#include "DebuggerInterface.h" +#include "Team.h" +#include "Tracing.h" + + +WatchpointManager::WatchpointManager(Team* team, + DebuggerInterface* debuggerInterface) + : + fLock("watchpoint manager"), + fTeam(team), + fDebuggerInterface(debuggerInterface) +{ + fDebuggerInterface->AcquireReference(); +} + + +WatchpointManager::~WatchpointManager() +{ + fDebuggerInterface->ReleaseReference(); +} + + +status_t +WatchpointManager::Init() +{ + return fLock.InitCheck(); +} + + +status_t +WatchpointManager::InstallWatchpoint(Watchpoint* watchpoint, + bool enabled) +{ + status_t error = B_OK; + TRACE_CONTROL("WatchpointManager::InstallUserWatchpoint(%p, %d)\n", + userWatchpoint, enabled); + + AutoLocker installLocker(fLock); + AutoLocker teamLocker(fTeam); + + bool oldEnabled = watchpoint->IsEnabled(); + if (enabled == oldEnabled) { + TRACE_CONTROL(" watchpoint already valid and with same enabled " + "state\n"); + return B_OK; + } + + watchpoint->SetEnabled(enabled); + + if (watchpoint->ShouldBeInstalled()) { + error = fDebuggerInterface->InstallWatchpoint(watchpoint->Address(), + watchpoint->Type(), watchpoint->Length()); + + if (error == B_OK) + watchpoint->SetInstalled(true); + } else { + error = fDebuggerInterface->UninstallWatchpoint(watchpoint->Address()); + + if (error == B_OK) + watchpoint->SetInstalled(false); + } + + return error; +} + + +void +WatchpointManager::UninstallWatchpoint(Watchpoint* watchpoint) +{ + AutoLocker installLocker(fLock); + AutoLocker teamLocker(fTeam); + + if (!watchpoint->IsInstalled()) + return; + + status_t error = fDebuggerInterface->UninstallWatchpoint( + watchpoint->Address()); + + if (error == B_OK) + watchpoint->SetInstalled(false); +} \ No newline at end of file diff --git a/src/apps/debugger/WatchpointManager.h b/src/apps/debugger/WatchpointManager.h new file mode 100644 index 0000000000..c854a6e592 --- /dev/null +++ b/src/apps/debugger/WatchpointManager.h @@ -0,0 +1,37 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef WATCHPOINT_MANAGER_H +#define WATCHPOINT_MANAGER_H + +#include + +#include "Watchpoint.h" + + +class DebuggerInterface; +class Team; + + +class WatchpointManager { +public: + WatchpointManager(Team* team, + DebuggerInterface* debuggerInterface); + ~WatchpointManager(); + + status_t Init(); + + status_t InstallWatchpoint(Watchpoint* watchpoint, + bool enabled); + void UninstallWatchpoint(Watchpoint* watchpoint); + +private: + BLocker fLock; // used to synchronize un-/installing + Team* fTeam; + DebuggerInterface* fDebuggerInterface; +}; + + +#endif // WATCHPOINT_MANAGER_H diff --git a/src/apps/debugger/debug_info/DwarfTypes.cpp b/src/apps/debugger/debug_info/DwarfTypes.cpp index c1544960ce..608ec1dbcf 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.cpp +++ b/src/apps/debugger/debug_info/DwarfTypes.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copryight 2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -225,6 +226,21 @@ DwarfType::ByteSize() const } +status_t +DwarfType::CreateDerivedAddressType(address_type_kind addressType, + AddressType*& _resultType) +{ + DwarfAddressType* resultType = new(std::nothrow) + DwarfAddressType(fTypeContext, fName, NULL, addressType, this); + + if (resultType == NULL) + return B_NO_MEMORY; + + _resultType = resultType; + return B_OK; +} + + status_t DwarfType::ResolveObjectDataLocation(const ValueLocation& objectLocation, ValueLocation*& _location) diff --git a/src/apps/debugger/debug_info/DwarfTypes.h b/src/apps/debugger/debug_info/DwarfTypes.h index ef6c4d265e..976f4e1baa 100644 --- a/src/apps/debugger/debug_info/DwarfTypes.h +++ b/src/apps/debugger/debug_info/DwarfTypes.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copryight 2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_TYPES_H @@ -107,6 +108,10 @@ public: virtual const BString& Name() const; virtual target_size_t ByteSize() const; + virtual status_t CreateDerivedAddressType( + address_type_kind kind, + AddressType*& _resultType); + virtual status_t ResolveObjectDataLocation( const ValueLocation& objectLocation, ValueLocation*& _location); diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp index 25043899d7..8a47162d4b 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.cpp +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010, Rene Gollent, rene@gollent.com. + * Copyright 2010-2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -425,6 +425,40 @@ DebuggerInterface::UninstallBreakpoint(target_addr_t address) } +status_t +DebuggerInterface::InstallWatchpoint(target_addr_t address, uint32 type, + int32 length) +{ + DebugContextGetter contextGetter(fDebugContextPool); + + debug_nub_set_watchpoint message; + message.reply_port = contextGetter.Context()->reply_port; + message.address = (void*)(addr_t)address; + message.type = type; + message.length = length; + + debug_nub_set_watchpoint_reply reply; + + status_t error = send_debug_message(contextGetter.Context(), + B_DEBUG_MESSAGE_SET_WATCHPOINT, &message, sizeof(message), &reply, + sizeof(reply)); + return error == B_OK ? reply.error : error; +} + + +status_t +DebuggerInterface::UninstallWatchpoint(target_addr_t address) +{ + DebugContextGetter contextGetter(fDebugContextPool); + + debug_nub_clear_watchpoint message; + message.address = (void*)(addr_t)address; + + return write_port(fNubPort, B_DEBUG_MESSAGE_CLEAR_WATCHPOINT, + &message, sizeof(message)); +} + + status_t DebuggerInterface::GetThreadInfos(BObjectList& infos) { diff --git a/src/apps/debugger/debugger_interface/DebuggerInterface.h b/src/apps/debugger/debugger_interface/DebuggerInterface.h index c700034ce0..bdf9b2c9c9 100644 --- a/src/apps/debugger/debugger_interface/DebuggerInterface.h +++ b/src/apps/debugger/debugger_interface/DebuggerInterface.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010, Rene Gollent, rene@gollent.com. + * Copyright 2010-2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DEBUGGER_INTERFACE_H @@ -48,6 +48,10 @@ public: virtual status_t InstallBreakpoint(target_addr_t address); virtual status_t UninstallBreakpoint(target_addr_t address); + virtual status_t InstallWatchpoint(target_addr_t address, + uint32 type, int32 length); + virtual status_t UninstallWatchpoint(target_addr_t address); + virtual status_t GetThreadInfos(BObjectList& infos); virtual status_t GetImageInfos(BObjectList& infos); virtual status_t GetSymbolInfos(team_id team, image_id image, diff --git a/src/apps/debugger/model/Team.cpp b/src/apps/debugger/model/Team.cpp index d4868ee11f..3a379c20e1 100644 --- a/src/apps/debugger/model/Team.cpp +++ b/src/apps/debugger/model/Team.cpp @@ -22,6 +22,7 @@ #include "Statement.h" #include "TeamDebugInfo.h" #include "Tracing.h" +#include "Watchpoint.h" // #pragma mark - BreakpointByAddressPredicate @@ -45,6 +46,26 @@ private: }; +// #pragma mark - WatchpointByAddressPredicate + + +struct Team::WatchpointByAddressPredicate + : UnaryPredicate { + WatchpointByAddressPredicate(target_addr_t address) + : + fAddress(address) + { + } + + virtual int operator()(const Watchpoint* watchpoint) const + { + return -Watchpoint::CompareAddressWatchpoint(&fAddress, watchpoint); + } + +private: + target_addr_t fAddress; +}; + // #pragma mark - Team @@ -363,6 +384,67 @@ Team::RemoveUserBreakpoint(UserBreakpoint* userBreakpoint) } +bool +Team::AddWatchpoint(Watchpoint* watchpoint) +{ + if (fWatchpoints.BinaryInsert(watchpoint, &Watchpoint::CompareWatchpoints)) + return true; + + watchpoint->ReleaseReference(); + return false; +} + + +void +Team::RemoveWatchpoint(Watchpoint* watchpoint) +{ + int32 index = fWatchpoints.BinarySearchIndex(*watchpoint, + &Watchpoint::CompareWatchpoints); + if (index < 0) + return; + + fWatchpoints.RemoveItemAt(index); + watchpoint->ReleaseReference(); +} + + +int32 +Team::CountWatchpoints() const +{ + return fWatchpoints.CountItems(); +} + + +Watchpoint* +Team::WatchpointAt(int32 index) const +{ + return fWatchpoints.ItemAt(index); +} + + +Watchpoint* +Team::WatchpointAtAddress(target_addr_t address) const +{ + return fWatchpoints.BinarySearchByKey(address, + &Watchpoint::CompareAddressWatchpoint); +} + + +void +Team::GetWatchpointsInAddressRange(TargetAddressRange range, + BObjectList& watchpoints) const +{ + int32 index = fWatchpoints.FindBinaryInsertionIndex( + WatchpointByAddressPredicate(range.Start())); + for (; Watchpoint* watchpoint = fWatchpoints.ItemAt(index); index++) { + if (watchpoint->Address() > range.End()) + break; + + watchpoints.AddItem(watchpoint); + } +} + + status_t Team::GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function, Statement*& _statement) @@ -539,6 +621,17 @@ Team::NotifyUserBreakpointChanged(UserBreakpoint* breakpoint) } +void +Team::NotifyWatchpointChanged(Watchpoint* watchpoint) +{ + for (ListenerList::Iterator it = fListeners.GetIterator(); + Listener* listener = it.Next();) { + listener->WatchpointChanged(WatchpointEvent( + TEAM_EVENT_WATCHPOINT_CHANGED, this, watchpoint)); + } +} + + void Team::_NotifyThreadAdded(Thread* thread) { @@ -579,28 +672,6 @@ Team::_NotifyImageRemoved(Image* image) } -void -Team::_NotifyBreakpointAdded(Breakpoint* breakpoint) -{ - for (ListenerList::Iterator it = fListeners.GetIterator(); - Listener* listener = it.Next();) { - listener->BreakpointAdded(BreakpointEvent( - TEAM_EVENT_BREAKPOINT_ADDED, this, breakpoint)); - } -} - - -void -Team::_NotifyBreakpointRemoved(Breakpoint* breakpoint) -{ - for (ListenerList::Iterator it = fListeners.GetIterator(); - Listener* listener = it.Next();) { - listener->BreakpointRemoved(BreakpointEvent( - TEAM_EVENT_BREAKPOINT_REMOVED, this, breakpoint)); - } -} - - // #pragma mark - Event @@ -646,6 +717,18 @@ Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team, } +// #pragma mark - WatchpointEvent + + +Team::WatchpointEvent::WatchpointEvent(uint32 type, Team* team, + Watchpoint* watchpoint) + : + Event(type, team), + fWatchpoint(watchpoint) +{ +} + + // #pragma mark - UserBreakpointEvent @@ -730,3 +813,21 @@ void Team::Listener::UserBreakpointChanged(const Team::UserBreakpointEvent& event) { } + + +void +Team::Listener::WatchpointAdded(const Team::WatchpointEvent& event) +{ +} + + +void +Team::Listener::WatchpointRemoved(const Team::WatchpointEvent& event) +{ +} + + +void +Team::Listener::WatchpointChanged(const Team::WatchpointEvent& event) +{ +} diff --git a/src/apps/debugger/model/Team.h b/src/apps/debugger/model/Team.h index 8a2f26918a..03dd5f5038 100644 --- a/src/apps/debugger/model/Team.h +++ b/src/apps/debugger/model/Team.h @@ -16,6 +16,7 @@ #include "Thread.h" #include "ThreadInfo.h" #include "UserBreakpoint.h" +#include "Watchpoint.h" // team event types @@ -33,7 +34,11 @@ enum { TEAM_EVENT_BREAKPOINT_ADDED, TEAM_EVENT_BREAKPOINT_REMOVED, - TEAM_EVENT_USER_BREAKPOINT_CHANGED + TEAM_EVENT_USER_BREAKPOINT_CHANGED, + + TEAM_EVENT_WATCHPOINT_ADDED, + TEAM_EVENT_WATCHPOINT_REMOVED, + TEAM_EVENT_WATCHPOINT_CHANGED }; @@ -55,10 +60,11 @@ class UserBreakpoint; class Team { public: class Event; - class ThreadEvent; - class ImageEvent; class BreakpointEvent; + class ImageEvent; + class ThreadEvent; class UserBreakpointEvent; + class WatchpointEvent; class Listener; public: @@ -127,6 +133,19 @@ public: const UserBreakpointList& UserBreakpoints() const { return fUserBreakpoints; } + bool AddWatchpoint(Watchpoint* watchpoint); + // takes over reference (also on error) + void RemoveWatchpoint(Watchpoint* watchpoint); + // releases its own reference + int32 CountWatchpoints() const; + Watchpoint* WatchpointAt(int32 index) const; + Watchpoint* WatchpointAtAddress( + target_addr_t address) const; + void GetWatchpointsInAddressRange( + TargetAddressRange range, + BObjectList& watchpoints) + const; + status_t GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function, Statement*& _statement); @@ -158,20 +177,23 @@ public: void NotifyUserBreakpointChanged( UserBreakpoint* breakpoint); + // watchpoint related service methods + void NotifyWatchpointChanged( + Watchpoint* watchpoint); + private: struct BreakpointByAddressPredicate; + struct WatchpointByAddressPredicate; typedef BObjectList BreakpointList; typedef DoublyLinkedList ListenerList; + typedef BObjectList WatchpointList; private: void _NotifyThreadAdded(Thread* thread); void _NotifyThreadRemoved(Thread* thread); void _NotifyImageAdded(Image* image); void _NotifyImageRemoved(Image* image); - void _NotifyBreakpointAdded(Breakpoint* breakpoint); - void _NotifyBreakpointRemoved( - Breakpoint* breakpoint); private: BLocker fLock; @@ -185,6 +207,7 @@ private: ThreadList fThreads; ImageList fImages; BreakpointList fBreakpoints; + WatchpointList fWatchpoints; UserBreakpointList fUserBreakpoints; ListenerList fListeners; }; @@ -237,6 +260,18 @@ protected: }; +class Team::WatchpointEvent : public Event { +public: + WatchpointEvent(uint32 type, Team* team, + Watchpoint* watchpoint); + + Watchpoint* GetWatchpoint() const { return fWatchpoint; } + +protected: + Watchpoint* fWatchpoint; +}; + + class Team::UserBreakpointEvent : public Event { public: UserBreakpointEvent(uint32 type, Team* team, @@ -275,6 +310,13 @@ public: const Team::BreakpointEvent& event); virtual void UserBreakpointChanged( const Team::UserBreakpointEvent& event); + + virtual void WatchpointAdded( + const Team::WatchpointEvent& event); + virtual void WatchpointRemoved( + const Team::WatchpointEvent& event); + virtual void WatchpointChanged( + const Team::WatchpointEvent& event); }; diff --git a/src/apps/debugger/model/Type.cpp b/src/apps/debugger/model/Type.cpp index e898682525..83f098f1b0 100644 --- a/src/apps/debugger/model/Type.cpp +++ b/src/apps/debugger/model/Type.cpp @@ -87,6 +87,15 @@ Type::ResolveRawType(bool nextOneOnly) const } +status_t +Type::CreateDerivedAddressType(address_type_kind kind, + AddressType*& _resultType) +{ + _resultType = NULL; + return B_ERROR; +} + + // #pragma mark - PrimitiveType diff --git a/src/apps/debugger/model/Type.h b/src/apps/debugger/model/Type.h index 20ffdb901b..44b0b2a5c1 100644 --- a/src/apps/debugger/model/Type.h +++ b/src/apps/debugger/model/Type.h @@ -52,6 +52,7 @@ enum { }; +class AddressType; class ArrayIndexPath; class BString; class Type; @@ -117,6 +118,12 @@ public: // strips modifiers and typedefs (only one, // if requested) + + // TODO: also need the ability to derive array types + virtual status_t CreateDerivedAddressType( + address_type_kind kind, + AddressType*& _resultType); + virtual status_t ResolveObjectDataLocation( const ValueLocation& objectLocation, ValueLocation*& _location) = 0; diff --git a/src/apps/debugger/model/Watchpoint.cpp b/src/apps/debugger/model/Watchpoint.cpp new file mode 100644 index 0000000000..5c324d00c5 --- /dev/null +++ b/src/apps/debugger/model/Watchpoint.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + +#include "Watchpoint.h" + + +Watchpoint::Watchpoint(target_addr_t address, uint32 type, int32 length) + : + fAddress(address), + fType(type), + fLength(length), + fInstalled(false), + fEnabled(false) +{ +} + + +Watchpoint::~Watchpoint() +{ +} + + +void +Watchpoint::SetInstalled(bool installed) +{ + fInstalled = installed; +} + + +void +Watchpoint::SetEnabled(bool enabled) +{ + fEnabled = enabled; +} + + +bool +Watchpoint::Contains(target_addr_t address) const +{ + return address >= fAddress && address <= (fAddress + fLength); +} + + +int +Watchpoint::CompareWatchpoints(const Watchpoint* a, const Watchpoint* b) +{ + if (a->Address() < b->Address()) + return -1; + return a->Address() == b->Address() ? 0 : 1; +} + + +int +Watchpoint::CompareAddressWatchpoint(const target_addr_t* address, + const Watchpoint* watchpoint) +{ + if (*address < watchpoint->Address()) + return -1; + return *address == watchpoint->Address() ? 0 : 1; +} + + + diff --git a/src/apps/debugger/model/Watchpoint.h b/src/apps/debugger/model/Watchpoint.h new file mode 100644 index 0000000000..a9d591f829 --- /dev/null +++ b/src/apps/debugger/model/Watchpoint.h @@ -0,0 +1,52 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef WATCHPOINT_H +#define WATCHPOINT_H + + +#include + +#include "types/Types.h" + + +class Watchpoint : public BReferenceable { +public: + Watchpoint(target_addr_t address, uint32 type, + int32 length); + ~Watchpoint(); + + target_addr_t Address() const { return fAddress; } + uint32 Type() const { return fType; } + int32 Length() const { return fLength; } + + bool IsInstalled() const { return fInstalled; } + void SetInstalled(bool installed); + + bool IsEnabled() const { return fEnabled; } + void SetEnabled(bool enabled); + // WatchpointManager only + + bool ShouldBeInstalled() const + { return fEnabled && !fInstalled; } + + bool Contains(target_addr_t address) const; + + static int CompareWatchpoints(const Watchpoint* a, + const Watchpoint* b); + static int CompareAddressWatchpoint( + const target_addr_t* address, + const Watchpoint* watchpoint); + +private: + target_addr_t fAddress; + uint32 fType; + int32 fLength; + + bool fInstalled; + bool fEnabled; +}; + + +#endif // WATCHPOINT_H diff --git a/src/apps/debugger/settings/TeamSettings.cpp b/src/apps/debugger/settings/TeamSettings.cpp index 605202dcf8..fbed4c8f74 100644 --- a/src/apps/debugger/settings/TeamSettings.cpp +++ b/src/apps/debugger/settings/TeamSettings.cpp @@ -18,6 +18,7 @@ #include "TeamUiSettings.h" #include "TeamUiSettingsFactory.h" #include "UserBreakpoint.h" +#include "WatchpointSetting.h" TeamSettings::TeamSettings() @@ -70,6 +71,23 @@ TeamSettings::SetTo(Team* team) } } + // add watchpoints + for (int32 i = 0; Watchpoint* watchpoint = team->WatchpointAt(i); i++) { + WatchpointSetting* watchpointSetting + = new(std::nothrow) WatchpointSetting; + if (watchpointSetting == NULL) + return B_NO_MEMORY; + + status_t error = watchpointSetting->SetTo(*watchpoint, + watchpoint->IsEnabled()); + if (error == B_OK && !fWatchpoints.AddItem(watchpointSetting)) + error = B_NO_MEMORY; + if (error != B_OK) { + delete watchpointSetting; + return error; + } + } + return B_OK; } @@ -166,6 +184,20 @@ TeamSettings::BreakpointAt(int32 index) const } +int32 +TeamSettings::CountWatchpoints() const +{ + return fWatchpoints.CountItems(); +} + + +const WatchpointSetting* +TeamSettings::WatchpointAt(int32 index) const +{ + return fWatchpoints.ItemAt(index); +} + + int32 TeamSettings::CountUiSettings() const { diff --git a/src/apps/debugger/settings/TeamSettings.h b/src/apps/debugger/settings/TeamSettings.h index f41f2bf8bd..3bc74e3d87 100644 --- a/src/apps/debugger/settings/TeamSettings.h +++ b/src/apps/debugger/settings/TeamSettings.h @@ -15,6 +15,7 @@ class BMessage; class Team; class BreakpointSetting; class TeamUiSettings; +class WatchpointSetting; class TeamSettings { @@ -33,6 +34,9 @@ public: int32 CountBreakpoints() const; const BreakpointSetting* BreakpointAt(int32 index) const; + int32 CountWatchpoints() const; + const WatchpointSetting* WatchpointAt(int32 index) const; + int32 CountUiSettings() const; const TeamUiSettings* UiSettingAt(int32 index) const; const TeamUiSettings* UiSettingFor(const char* id) const; @@ -44,12 +48,14 @@ public: private: typedef BObjectList BreakpointList; typedef BObjectList UiSettingsList; + typedef BObjectList WatchpointList; private: void _Unset(); private: BreakpointList fBreakpoints; + WatchpointList fWatchpoints; UiSettingsList fUiSettings; BString fTeamName; }; diff --git a/src/apps/debugger/settings/WatchpointSetting.cpp b/src/apps/debugger/settings/WatchpointSetting.cpp new file mode 100644 index 0000000000..0872e148dd --- /dev/null +++ b/src/apps/debugger/settings/WatchpointSetting.cpp @@ -0,0 +1,100 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "WatchpointSetting.h" + +#include + +#include "Watchpoint.h" + + +WatchpointSetting::WatchpointSetting() + : + fAddress(0), + fType(0), + fLength(0), + fEnabled(false) +{ +} + + +WatchpointSetting::WatchpointSetting(const WatchpointSetting& other) + : + fAddress(other.fAddress), + fType(other.fType), + fLength(other.fLength), + fEnabled(other.fEnabled) +{ +} + + +WatchpointSetting::~WatchpointSetting() +{ +} + + +status_t +WatchpointSetting::SetTo(const Watchpoint& watchpoint, bool enabled) +{ + fAddress = watchpoint.Address(); + fType = watchpoint.Type(); + fLength = watchpoint.Length(); + fEnabled = enabled; + + return B_OK; +} + + +status_t +WatchpointSetting::SetTo(const BMessage& archive) +{ + if (archive.FindUInt64("address", &fAddress) != B_OK) + fAddress = 0; + + if (archive.FindUInt32("type", &fType) != B_OK) + fType = 0; + + if (archive.FindInt32("length", &fLength) != B_OK) + fLength = 0; + + if (archive.FindBool("enabled", &fEnabled) != B_OK) + fEnabled = false; + + return B_OK; +} + + +status_t +WatchpointSetting::WriteTo(BMessage& archive) const +{ + archive.MakeEmpty(); + + status_t error; + if ((error = archive.AddUInt64("address", fAddress)) != B_OK + || (error = archive.AddUInt32("type", fType)) != B_OK + || (error = archive.AddInt32("length", fLength)) != B_OK + || (error = archive.AddBool("enabled", fEnabled)) != B_OK) { + return error; + } + + return B_OK; +} + + +WatchpointSetting& +WatchpointSetting::operator=(const WatchpointSetting& other) +{ + if (this == &other) + return *this; + + fAddress = other.fAddress; + fType = other.fType; + fLength = other.fLength; + fEnabled = other.fEnabled; + + return *this; +} diff --git a/src/apps/debugger/settings/WatchpointSetting.h b/src/apps/debugger/settings/WatchpointSetting.h new file mode 100644 index 0000000000..14fd16ceb4 --- /dev/null +++ b/src/apps/debugger/settings/WatchpointSetting.h @@ -0,0 +1,46 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef WATCHPOINT_SETTING_H +#define WATCHPOINT_SETTING_H + + +#include + +#include "types/Types.h" + +class BMessage; +class Watchpoint; + + +class WatchpointSetting { +public: + WatchpointSetting(); + WatchpointSetting( + const WatchpointSetting& other); + ~WatchpointSetting(); + + status_t SetTo(const Watchpoint& watchpoint, + bool enabled); + status_t SetTo(const BMessage& archive); + status_t WriteTo(BMessage& archive) const; + + target_addr_t Address() const { return fAddress; } + uint32 Type() const { return fType; } + int32 Length() const { return fLength; } + + bool IsEnabled() const { return fEnabled; } + + WatchpointSetting& operator=(const WatchpointSetting& other); + +private: + target_addr_t fAddress; + uint32 fType; + int32 fLength; + bool fEnabled; +}; + + +#endif // BREAKPOINT_SETTING_H diff --git a/src/apps/debugger/source_language/CppLanguage.cpp b/src/apps/debugger/source_language/CppLanguage.cpp index 451a567e10..2aa19301de 100644 --- a/src/apps/debugger/source_language/CppLanguage.cpp +++ b/src/apps/debugger/source_language/CppLanguage.cpp @@ -1,11 +1,16 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "CppLanguage.h" +#include "TeamTypeInformation.h" +#include "Type.h" +#include "TypeLookupConstraints.h" + CppLanguage::CppLanguage() { @@ -22,3 +27,81 @@ CppLanguage::Name() const { return "C++"; } + + +status_t +CppLanguage::ParseTypeExpression(const BString &expression, + TeamTypeInformation* info, + Type*& _resultType) const +{ + status_t result = B_OK; + Type* baseType = NULL; + + BString parsedName = expression; + BString baseTypeName; + parsedName.RemoveAll(" "); + + int32 modifierIndex = -1; + for (int32 i = parsedName.Length() - 1; i >= 0; i--) { + if (parsedName[i] == '*' || parsedName[i] == '&') + modifierIndex = i; + } + + if (modifierIndex >= 0) { + parsedName.CopyInto(baseTypeName, 0, modifierIndex); + parsedName.Remove(0, modifierIndex); + } else + baseTypeName = parsedName; + + result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(), + baseType); + if (result != B_OK) + return result; + + BReference typeRef; + typeRef.SetTo(baseType, true); + + if (!parsedName.IsEmpty()) { + AddressType* derivedType = NULL; + // walk the list of modifiers trying to add each. + for (int32 i = 0; i < parsedName.Length(); i++) { + address_type_kind typeKind; + switch (parsedName[i]) { + case '*': + { + typeKind = DERIVED_TYPE_POINTER; + break; + } + case '&': + { + typeKind = DERIVED_TYPE_REFERENCE; + break; + } + default: + { + return B_BAD_VALUE; + } + + } + + if (derivedType == NULL) { + result = baseType->CreateDerivedAddressType(typeKind, + derivedType); + } else { + result = derivedType->CreateDerivedAddressType(typeKind, + derivedType); + } + + if (result != B_OK) + return result; + typeRef.SetTo(derivedType, true); + } + + _resultType = derivedType; + } else + _resultType = baseType; + + typeRef.Detach(); + + return result; +} diff --git a/src/apps/debugger/source_language/CppLanguage.h b/src/apps/debugger/source_language/CppLanguage.h index d163ed15d6..41211d9bbd 100644 --- a/src/apps/debugger/source_language/CppLanguage.h +++ b/src/apps/debugger/source_language/CppLanguage.h @@ -15,6 +15,10 @@ public: virtual ~CppLanguage(); virtual const char* Name() const; + + virtual status_t ParseTypeExpression(const BString &expression, + TeamTypeInformation* lookup, + Type*& _resultType) const; }; diff --git a/src/apps/debugger/source_language/SourceLanguage.cpp b/src/apps/debugger/source_language/SourceLanguage.cpp index b6c04b374b..6533f11b65 100644 --- a/src/apps/debugger/source_language/SourceLanguage.cpp +++ b/src/apps/debugger/source_language/SourceLanguage.cpp @@ -17,3 +17,11 @@ SourceLanguage::GetSyntaxHighlighter() const { return NULL; } + + +status_t +SourceLanguage::ParseTypeExpression(const BString &expression, + TeamTypeInformation* info, Type*& _resultType) const +{ + return B_NOT_SUPPORTED; +} diff --git a/src/apps/debugger/source_language/SourceLanguage.h b/src/apps/debugger/source_language/SourceLanguage.h index c06c295fd1..d33ed50bce 100644 --- a/src/apps/debugger/source_language/SourceLanguage.h +++ b/src/apps/debugger/source_language/SourceLanguage.h @@ -9,7 +9,10 @@ #include +class BString; class SyntaxHighlighter; +class TeamTypeInformation; +class Type; class SourceLanguage : public BReferenceable { @@ -21,6 +24,10 @@ public: virtual SyntaxHighlighter* GetSyntaxHighlighter() const; // returns a reference, // may return NULL, if not available + + virtual status_t ParseTypeExpression(const BString &expression, + TeamTypeInformation* info, + Type*& _resultType) const; }; diff --git a/src/apps/debugger/user_interface/UserInterface.h b/src/apps/debugger/user_interface/UserInterface.h index 60ae097d5a..a69303711d 100644 --- a/src/apps/debugger/user_interface/UserInterface.h +++ b/src/apps/debugger/user_interface/UserInterface.h @@ -27,6 +27,7 @@ class UserInterfaceListener; class ValueNode; class ValueNodeContainer; class Variable; +class Watchpoint; enum user_notification_type { @@ -100,6 +101,17 @@ public: UserBreakpoint* breakpoint) = 0; // TODO: Consolidate those! + virtual void SetWatchpointRequested(target_addr_t address, + uint32 type, int32 length, + bool enabled) = 0; + virtual void SetWatchpointEnabledRequested( + Watchpoint* watchpoint, + bool enabled) = 0; + virtual void ClearWatchpointRequested( + target_addr_t address) = 0; + virtual void ClearWatchpointRequested( + Watchpoint* watchpoint) = 0; + virtual void InspectRequested( target_addr_t address, TeamMemoryBlock::Listener* listener) = 0; diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 9cbbadcc42..87a34bef24 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -23,12 +23,16 @@ #include "ActionMenuItem.h" #include "Architecture.h" +#include "FileSourceCode.h" +#include "Function.h" #include "FunctionID.h" #include "FunctionInstance.h" #include "GuiSettingsUtils.h" #include "MessageCodes.h" #include "Register.h" #include "SettingsMenu.h" +#include "SourceLanguage.h" +#include "StackTrace.h" #include "StackFrame.h" #include "StackFrameValues.h" #include "TableCellValueRenderer.h" @@ -1645,16 +1649,27 @@ VariablesView::MessageReceived(BMessage* message) case MSG_TYPECAST_NODE: { ModelNode* node = NULL; - if (message->FindPointer("node", reinterpret_cast(&node)) != B_OK) - break; - TeamDebugInfo* info = fThread->GetTeam()->DebugInfo(); - if (info == NULL) + if (message->FindPointer("node", reinterpret_cast(&node)) + != B_OK) { break; + } Type* type = NULL; - if (info->LookupTypeByName(message->FindString("text"), - TypeLookupConstraints(), type) != B_OK) { - // TODO: notify user + BString typeExpression = message->FindString("text"); + if (typeExpression.Length() == 0) + break; + + FileSourceCode* code = fStackFrame->Function()->GetFunction() + ->GetSourceCode(); + if (code == NULL) + break; + + SourceLanguage* language = code->GetSourceLanguage(); + if (language == NULL) + break; + + if (language->ParseTypeExpression(typeExpression, + fThread->GetTeam()->DebugInfo(), type) != B_OK) { break; } diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h index 30f3149fa9..7c09b73f98 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2012, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef VARIABLES_VIEW_H @@ -16,6 +17,7 @@ class CpuState; class SettingsMenu; class StackFrame; class Thread; +class Type; class TypeComponentPath; class ValueNode; class ValueNodeContainer; diff --git a/src/apps/terminal/AppearPrefView.cpp b/src/apps/terminal/AppearPrefView.cpp index d0864e7c50..eea2156a5b 100644 --- a/src/apps/terminal/AppearPrefView.cpp +++ b/src/apps/terminal/AppearPrefView.cpp @@ -75,6 +75,8 @@ AppearancePrefView::AppearancePrefView(const char* name, const char* kColorTable[] = { B_TRANSLATE("Text"), B_TRANSLATE("Background"), + B_TRANSLATE("Cursor text"), + B_TRANSLATE("Cursor background"), B_TRANSLATE("Selected text"), B_TRANSLATE("Selected background"), NULL diff --git a/src/apps/terminal/PrefHandler.cpp b/src/apps/terminal/PrefHandler.cpp index c60d156ef5..030b62e1e7 100644 --- a/src/apps/terminal/PrefHandler.cpp +++ b/src/apps/terminal/PrefHandler.cpp @@ -44,6 +44,8 @@ static const pref_defaults kTermDefaults[] = { { PREF_TEXT_FORE_COLOR, " 0, 0, 0" }, { PREF_TEXT_BACK_COLOR, "255, 255, 255" }, + { PREF_CURSOR_FORE_COLOR, " 0, 0, 0" }, + { PREF_CURSOR_BACK_COLOR, "255, 200, 0" }, { PREF_SELECT_FORE_COLOR, "255, 255, 255" }, { PREF_SELECT_BACK_COLOR, " 0, 0, 0" }, diff --git a/src/apps/terminal/TermConst.h b/src/apps/terminal/TermConst.h index 4181a85739..cf0a31c2c6 100644 --- a/src/apps/terminal/TermConst.h +++ b/src/apps/terminal/TermConst.h @@ -103,6 +103,8 @@ static const char* const PREF_HALF_FONT_SIZE = "Half Font Size"; static const char* const PREF_TEXT_FORE_COLOR = "Text"; static const char* const PREF_TEXT_BACK_COLOR = "Background"; +static const char* const PREF_CURSOR_FORE_COLOR = "Cursor text"; +static const char* const PREF_CURSOR_BACK_COLOR = "Cursor background"; static const char* const PREF_SELECT_FORE_COLOR = "Selected text"; static const char* const PREF_SELECT_BACK_COLOR = "Selected background"; diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index cad69cc2b7..7e7c089933 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -886,6 +886,14 @@ TermView::SetTextColor(rgb_color fore, rgb_color back) } +void +TermView::SetCursorColor(rgb_color fore, rgb_color back) +{ + fCursorForeColor = fore; + fCursorBackColor = back; +} + + void TermView::SetSelectColor(rgb_color fore, rgb_color back) { @@ -1143,13 +1151,8 @@ TermView::_DrawLinePart(int32 x1, int32 y1, uint32 attr, char *buf, // Selection check. if (cursor) { - rgb_fore.red = 255 - rgb_fore.red; - rgb_fore.green = 255 - rgb_fore.green; - rgb_fore.blue = 255 - rgb_fore.blue; - - rgb_back.red = 255 - rgb_back.red; - rgb_back.green = 255 - rgb_back.green; - rgb_back.blue = 255 - rgb_back.blue; + rgb_fore = fCursorForeColor; + rgb_back = fCursorBackColor; } else if (mouse) { rgb_fore = fSelectForeColor; rgb_back = fSelectBackColor; @@ -1226,13 +1229,10 @@ TermView::_DrawCursor() if (selected) SetHighColor(fSelectBackColor); else { - rgb_color color = kTermColorTable[IS_BACKCOLOR(attr)]; - if (cursorVisible) { - color.red = 255 - color.red; - color.green = 255 - color.green; - color.blue = 255 - color.blue; - } - SetHighColor(color); + if (cursorVisible) + SetHighColor(fCursorBackColor); + else + SetHighColor(kTermColorTable[IS_BACKCOLOR(attr)]); } FillRect(rect); diff --git a/src/apps/terminal/TermView.h b/src/apps/terminal/TermView.h index 96e62f1abc..68272eeab7 100644 --- a/src/apps/terminal/TermView.h +++ b/src/apps/terminal/TermView.h @@ -77,6 +77,7 @@ public: int *rows, int *columns); void SetTextColor(rgb_color fore, rgb_color back); + void SetCursorColor(rgb_color fore, rgb_color back); void SetSelectColor(rgb_color fore, rgb_color back); int Encoding() const; @@ -255,6 +256,8 @@ private: InlineInput* fInline; // Color and Attribute. + rgb_color fCursorForeColor; + rgb_color fCursorBackColor; rgb_color fSelectForeColor; rgb_color fSelectBackColor; diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index 1fe2ccbee7..19cdf278d7 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -77,6 +77,9 @@ using namespace BPrivate ; // BCharacterSet stuff #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "Terminal TermWindow" +// actually an arrow +#define UTF8_ENTER "\xe2\x86\xb5" + // #pragma mark - TermViewContainerView @@ -795,14 +798,17 @@ TermWindow::MessageReceived(BMessage *message) float mbHeight = fMenuBar->Bounds().Height() + 1; fSavedFrame = Frame(); BScreen screen(this); - for (int32 i = fTabView->CountTabs() - 1; i >=0 ; i--) - _TermViewAt(i)->ScrollBar()->ResizeBy(0, (B_H_SCROLL_BAR_HEIGHT - 1)); + + for (int32 i = fTabView->CountTabs() - 1; i >= 0 ; i--) + _TermViewAt(i)->ScrollBar()->ResizeBy(0, + (B_H_SCROLL_BAR_HEIGHT - 1)); fMenuBar->Hide(); fTabView->ResizeBy(0, mbHeight); fTabView->MoveBy(0, -mbHeight); fSavedLook = Look(); - // done before ResizeTo to work around a Dano bug (not erasing the decor) + // done before ResizeTo to work around a Dano bug + // (not erasing the decor) SetLook(B_NO_BORDER_WINDOW_LOOK); ResizeTo(screen.Frame().Width()+1, screen.Frame().Height()+1); MoveTo(screen.Frame().left, screen.Frame().top); @@ -812,8 +818,11 @@ TermWindow::MessageReceived(BMessage *message) _ActiveTermView()->DisableResizeView(); float mbHeight = fMenuBar->Bounds().Height() + 1; fMenuBar->Show(); - for (int32 i = fTabView->CountTabs() - 1; i >=0 ; i--) - _TermViewAt(i)->ScrollBar()->ResizeBy(0, -(B_H_SCROLL_BAR_HEIGHT - 1)); + + for (int32 i = fTabView->CountTabs() - 1; i >= 0 ; i--) + _TermViewAt(i)->ScrollBar()->ResizeBy(0, + -(B_H_SCROLL_BAR_HEIGHT - 1)); + ResizeTo(fSavedFrame.Width(), fSavedFrame.Height()); MoveTo(fSavedFrame.left, fSavedFrame.top); fTabView->ResizeBy(0, -mbHeight); @@ -1018,6 +1027,8 @@ TermWindow::_SetTermColors(TermViewContainerView* containerView) TermView *termView = containerView->GetTermView(); termView->SetTextColor(handler->getRGB(PREF_TEXT_FORE_COLOR), background); + termView->SetCursorColor(handler->getRGB(PREF_CURSOR_FORE_COLOR), + handler->getRGB(PREF_CURSOR_BACK_COLOR)); termView->SetSelectColor(handler->getRGB(PREF_SELECT_FORE_COLOR), handler->getRGB(PREF_SELECT_BACK_COLOR)); } @@ -1646,6 +1657,16 @@ TermWindow::_UpdateSessionTitle(int32 index) fTitle.title = windowTitle; SetTitle(fTitle.title); } + + // If fullscreen, add a tooltip with the title and a keyboard shortcut hint + if (fFullScreen) { + BString toolTip(fTitle.title); + toolTip += "\n("; + toolTip += B_TRANSLATE("Full screen"); + toolTip += " (ALT " UTF8_ENTER "))"; + termView->SetToolTip(toolTip.String()); + } else + termView->SetToolTip((const char *)NULL); } diff --git a/src/bin/listsem.c b/src/bin/listsem.c index 6fdb102054..d066fcb824 100644 --- a/src/bin/listsem.c +++ b/src/bin/listsem.c @@ -1,14 +1,14 @@ /* * listsem.c * - * Lists all semaphores in all Teams. + * Lists all semaphores in all Teams. * by O.Siebenmarck. - * + * * 04-27-2002 - mmu_man * added command line args - * - * Legal stuff follows: - + * + * Legal stuff follows: + Copyright (c) 2002 Oliver Siebenmarck , OpenBeOS project Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -33,29 +33,44 @@ #include #include +#include #include + +static void print_sem_info(sem_info *info) +{ + printf("%7ld%31s%7ld\n", info->sem ,info->name , info->count); +} + + +static void print_header(team_info *tinfo) +{ + if (tinfo != NULL) + printf("TEAM %ld (%s):\n", tinfo->team, tinfo->args ); + + printf(" ID name count\n"); + printf("---------------------------------------------\n"); +} + + static void list_sems(team_info *tinfo) { sem_info info; int32 cookie = 0; - printf("TEAM %ld (%s):\n", tinfo->team, tinfo->args ); - printf(" ID name count\n"); - printf("---------------------------------------------\n"); - + print_header(tinfo); + while (get_next_sem_info(tinfo->team, &cookie, &info) == B_OK) - { - printf("%7ld%31s%7ld\n", info.sem ,info.name , info.count ); - } + print_sem_info(&info); + printf("\n"); } int main(int argc, char **argv) { team_info tinfo; - int32 cook = 0; - int i; + int32 cookie = 0; + int32 i; system_info sysinfo; // show up some stats first... @@ -63,30 +78,48 @@ int main(int argc, char **argv) printf("sem: total: %5li, used: %5li, left: %5li\n\n", sysinfo.max_sems, sysinfo.used_sems, sysinfo.max_sems - sysinfo.used_sems); if (argc == 1) { - while (get_next_team_info( &cook, &tinfo) == B_OK) - { + while (get_next_team_info( &cookie, &tinfo) == B_OK) list_sems(&tinfo); - } + return 0; } + for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) { + if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { fprintf(stderr, "Usage: %s [-s semid] [teamid]\n", argv[0]); - fputs(" List the semaphores allocated by the specified\n", stderr); - fputs(" team, or all teams if none is specified.\n", stderr); + fputs(" List the semaphores allocated by the specified\n", + stderr); + fputs(" team, or all teams if none is specified.\n", + stderr); fputs("\n", stderr); - fputs(" The -s option displays the sem_info data for a\n", stderr); + fputs(" The -s option displays the sem_info data for a\n", + stderr); fputs(" specified semaphore.\n", stderr); return 0; + } else if (strcmp(argv[i], "-s") == 0) { + if (argc < i + 2) + printf("-s used without associated sem id\n"); + else { + sem_id id = atoi(argv[i + 1]); + sem_info info; + if (get_sem_info(id, &info) == B_OK) { + print_header(NULL); + print_sem_info(&info); + } else + printf("semaphore %ld unknown\n\n", id); + + i++; + } } else { - int t; - t = atoi(argv[i]); - if (get_team_info(t, &tinfo) == B_OK) + team_id team; + team = atoi(argv[i]); + if (get_team_info(team, &tinfo) == B_OK) list_sems(&tinfo); else - printf("team %i unknown\n\n", t); + printf("team %ld unknown\n\n", team); } } + return 0; } diff --git a/src/bin/locale/locale.cpp b/src/bin/locale/locale.cpp index 53d787a7c4..2635fc945a 100644 --- a/src/bin/locale/locale.cpp +++ b/src/bin/locale/locale.cpp @@ -43,8 +43,12 @@ print_formatting_conventions() { BFormattingConventions conventions; BLocale::Default()->GetFormattingConventions(&conventions); - printf("%s_%s.UTF-8\n", conventions.LanguageCode(), - conventions.CountryCode()); + if (conventions.CountryCode() != NULL) { + printf("%s_%s.UTF-8\n", conventions.LanguageCode(), + conventions.CountryCode()); + } else { + printf("%s.UTF-8\n", conventions.LanguageCode()); + } } @@ -53,12 +57,15 @@ print_time_conventions() { BFormattingConventions conventions; BLocale::Default()->GetFormattingConventions(&conventions); - if (conventions.UseStringsFromPreferredLanguage()) { - printf("%s_%s.UTF-8@strings=messages\n", conventions.LanguageCode(), - conventions.CountryCode()); + if (conventions.CountryCode() != NULL) { + printf("%s_%s.UTF-8%s\n", conventions.LanguageCode(), + conventions.CountryCode(), + conventions.UseStringsFromPreferredLanguage() + ? "@strings=messages" : ""); } else { - printf("%s_%s.UTF-8\n", conventions.LanguageCode(), - conventions.CountryCode()); + printf("%s.UTF-8%s\n", conventions.LanguageCode(), + conventions.UseStringsFromPreferredLanguage() + ? "@strings=messages" : ""); } } diff --git a/src/servers/app/stackandtile/StackAndTile.cpp b/src/servers/app/stackandtile/StackAndTile.cpp index 2fb545478b..8568f71965 100644 --- a/src/servers/app/stackandtile/StackAndTile.cpp +++ b/src/servers/app/stackandtile/StackAndTile.cpp @@ -129,16 +129,42 @@ StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) if (!wasPressed && fSATKeyPressed) _StartSAT(); } -// switch off group navigation because it clashes with tracker... -return false; - if (!SATKeyPressed() || (modifiers & B_COMMAND_KEY) == 0 - || what != B_KEY_DOWN) + + if (!SATKeyPressed() || what != B_KEY_DOWN) return false; const int kArrowKeyUp = 87; const int kArrowKeyDown = 98; + const int kArrowKeyLeft = 97; + const int kArrowKeyRight = 99; switch (key) { + case kArrowKeyLeft: + case kArrowKeyRight: + { + SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); + SATGroup* currentGroup = NULL; + if (frontWindow) + currentGroup = frontWindow->GetGroup(); + int32 groupSize = currentGroup->CountItems(); + if (!currentGroup || groupSize <= 1) + return false; + + for (int32 i = 0; i < groupSize; i++) { + SATWindow* targetWindow = currentGroup->WindowAt(i); + if (targetWindow == frontWindow) { + if (key == kArrowKeyLeft && i > 0) { + targetWindow = currentGroup->WindowAt(i - 1); + } else if (key == kArrowKeyRight && i < groupSize - 1) { + targetWindow = currentGroup->WindowAt(i + 1); + } + _ActivateWindow(targetWindow); + return true; + } + } + break; + } + case kArrowKeyDown: { SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); diff --git a/src/servers/notification/AppGroupView.cpp b/src/servers/notification/AppGroupView.cpp index 9266c3aa4c..450476f80a 100644 --- a/src/servers/notification/AppGroupView.cpp +++ b/src/servers/notification/AppGroupView.cpp @@ -31,7 +31,8 @@ AppGroupView::AppGroupView(NotificationWindow* win, const char* label) BGroupView("appGroup", B_VERTICAL, 0), fLabel(label), fParent(win), - fCollapsed(false) + fCollapsed(false), + fCloseClicked(false) { SetFlags(Flags() | B_WILL_DRAW); @@ -78,14 +79,7 @@ AppGroupView::Draw(BRect updateRect) SetPenSize(kPenSize); // Draw the dismiss widget - BRect closeCross = fCloseRect; - closeCross.InsetBy(kSmallPadding, kSmallPadding); - rgb_color detailCol = ui_color(B_CONTROL_BORDER_COLOR); - detailCol = tint_color(detailCol, B_LIGHTEN_2_TINT); - - StrokeRoundRect(fCloseRect, kSmallPadding, kSmallPadding); - StrokeLine(closeCross.LeftTop(), closeCross.RightBottom()); - StrokeLine(closeCross.RightTop(), closeCross.LeftBottom()); + _DrawCloseButton(updateRect); // Draw the label SetHighColor(ui_color(B_PANEL_TEXT_COLOR)); @@ -100,6 +94,39 @@ AppGroupView::Draw(BRect updateRect) } +void +AppGroupView::_DrawCloseButton(const BRect& updateRect) +{ + PushState(); + BRect closeRect = Bounds(); + + closeRect.InsetBy(7, 7); + closeRect.left = closeRect.right - kCloseSize; + closeRect.bottom = closeRect.top + kCloseSize; + + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + float tint = B_DARKEN_2_TINT; + + if (fCloseClicked) { + BRect buttonRect(closeRect.InsetByCopy(-4, -4)); + be_control_look->DrawButtonFrame(this, buttonRect, updateRect, + base, base, + BControlLook::B_ACTIVATED | BControlLook::B_BLEND_FRAME); + be_control_look->DrawButtonBackground(this, buttonRect, updateRect, + base, BControlLook::B_ACTIVATED); + tint *= 1.2; + closeRect.OffsetBy(1, 1); + } + + base = tint_color(base, tint); + SetHighColor(base); + SetPenSize(2); + StrokeLine(closeRect.LeftTop(), closeRect.RightBottom()); + StrokeLine(closeRect.LeftBottom(), closeRect.RightTop()); + PopState(); +} + + void AppGroupView::MouseDown(BPoint point) { diff --git a/src/servers/notification/AppGroupView.h b/src/servers/notification/AppGroupView.h index 0c1406d56d..10f9e60cc2 100644 --- a/src/servers/notification/AppGroupView.h +++ b/src/servers/notification/AppGroupView.h @@ -35,12 +35,15 @@ public: const BString& Group() const; private: + void _DrawCloseButton(const BRect& updateRect); + BString fLabel; NotificationWindow* fParent; infoview_t fInfo; bool fCollapsed; BRect fCloseRect; BRect fCollapseRect; + bool fCloseClicked; }; #endif // _APP_GROUP_VIEW_H diff --git a/src/servers/notification/NotificationView.cpp b/src/servers/notification/NotificationView.cpp index 3bfff101bd..f5a2994fe2 100644 --- a/src/servers/notification/NotificationView.cpp +++ b/src/servers/notification/NotificationView.cpp @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -58,7 +59,8 @@ NotificationView::NotificationView(NotificationWindow* win, fNotification(notification), fTimeout(timeout), fRunner(NULL), - fBitmap(NULL) + fBitmap(NULL), + fCloseClicked(false) { if (fNotification->Icon() != NULL) fBitmap = new BBitmap(fNotification->Icon()); @@ -271,19 +273,7 @@ NotificationView::Draw(BRect updateRect) rgb_color detailCol = ui_color(B_CONTROL_BORDER_COLOR); detailCol = tint_color(detailCol, B_LIGHTEN_2_TINT); - // Draw the close widget - BRect closeRect = Bounds(); - closeRect.InsetBy(2 * kEdgePadding, 2 * kEdgePadding); - closeRect.left = closeRect.right - kCloseSize; - closeRect.bottom = closeRect.top + kCloseSize; - - PushState(); - SetHighColor(detailCol); - StrokeRoundRect(closeRect, kSmallPadding, kSmallPadding); - BRect closeCross = closeRect.InsetByCopy(kSmallPadding, kSmallPadding); - StrokeLine(closeCross.LeftTop(), closeCross.RightBottom()); - StrokeLine(closeCross.LeftBottom(), closeCross.RightTop()); - PopState(); + _DrawCloseButton(updateRect); SetHighColor(tint_color(ViewColor(), B_DARKEN_1_TINT)); BPoint left(Bounds().left, Bounds().top); @@ -294,6 +284,39 @@ NotificationView::Draw(BRect updateRect) } +void +NotificationView::_DrawCloseButton(const BRect& updateRect) +{ + PushState(); + BRect closeRect = Bounds(); + + closeRect.InsetBy(3 * kEdgePadding, 3 * kEdgePadding); + closeRect.left = closeRect.right - kCloseSize; + closeRect.bottom = closeRect.top + kCloseSize; + + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + float tint = B_DARKEN_2_TINT; + + if (fCloseClicked) { + BRect buttonRect(closeRect.InsetByCopy(-4, -4)); + be_control_look->DrawButtonFrame(this, buttonRect, updateRect, + base, base, + BControlLook::B_ACTIVATED | BControlLook::B_BLEND_FRAME); + be_control_look->DrawButtonBackground(this, buttonRect, updateRect, + base, BControlLook::B_ACTIVATED); + tint *= 1.2; + closeRect.OffsetBy(1, 1); + } + + base = tint_color(base, tint); + SetHighColor(base); + SetPenSize(2); + StrokeLine(closeRect.LeftTop(), closeRect.RightBottom()); + StrokeLine(closeRect.LeftBottom(), closeRect.RightTop()); + PopState(); +} + + void NotificationView::MouseDown(BPoint point) { @@ -355,6 +378,8 @@ NotificationView::MouseDown(BPoint point) be_roster->Launch(fNotification->OnClickApp(), &messages); else be_roster->Launch(fNotification->OnClickFile(), &messages); + } else { + fCloseClicked = true; } // Remove the info view after a click diff --git a/src/servers/notification/NotificationView.h b/src/servers/notification/NotificationView.h index 37ed61c7da..4653c66df9 100644 --- a/src/servers/notification/NotificationView.h +++ b/src/servers/notification/NotificationView.h @@ -52,6 +52,7 @@ public: private: void _CalculateSize(); + void _DrawCloseButton(const BRect& updateRect); struct LineInfo { BFont font; @@ -68,10 +69,9 @@ private: BMessageRunner* fRunner; BBitmap* fBitmap; - LineInfoList fLines; - float fHeight; + bool fCloseClicked; }; #endif // _NOTIFICATION_VIEW_H diff --git a/src/servers/notification/NotificationWindow.cpp b/src/servers/notification/NotificationWindow.cpp index 5a901469b8..be8e670c1d 100644 --- a/src/servers/notification/NotificationWindow.cpp +++ b/src/servers/notification/NotificationWindow.cpp @@ -48,7 +48,7 @@ property_info main_prop_list[] = { }; -const float kCloseSize = 8; +const float kCloseSize = 6; const float kExpandSize = 8; const float kPenSize = 1; const float kEdgePadding = 2; diff --git a/src/system/kernel/vm/vm_page.cpp b/src/system/kernel/vm/vm_page.cpp index 9e4c591779..29df4e1a92 100644 --- a/src/system/kernel/vm/vm_page.cpp +++ b/src/system/kernel/vm/vm_page.cpp @@ -3862,13 +3862,13 @@ vm_page_allocate_page_run(uint32 flags, page_num_t length, page_num_t offsetStart = start + sPhysicalPageOffset; // enforce alignment - if ((offsetStart & alignmentMask) != 0) { + if (alignmentMask != 0 && (offsetStart & alignmentMask) != 0) { offsetStart = ((offsetStart + alignmentMask) & ~alignmentMask) - sPhysicalPageOffset; } // enforce boundary - if (offsetStart << boundaryShift + if (boundaryShift != 0 && offsetStart << boundaryShift != (offsetStart + length - 1) << boundaryShift) { offsetStart = (offsetStart + length - 1) << boundaryShift >> boundaryShift; @@ -3887,7 +3887,10 @@ vm_page_allocate_page_run(uint32 flags, page_num_t length, } dprintf("vm_page_allocate_page_run(): Failed to allocate run of " - "length %" B_PRIuPHYSADDR " in second iteration!", length); + "length %" B_PRIuPHYSADDR " (%" B_PRIuPHYSADDR " %" + B_PRIuPHYSADDR ") in second iteration (align: %" B_PRIuPHYSADDR + " boundary: %" B_PRIuPHYSADDR ") !", length, requestedStart, + end, restrictions->alignment, restrictions->boundary); freeClearQueueLocker.Unlock(); vm_page_unreserve_pages(&reservation); @@ -3916,7 +3919,7 @@ vm_page_allocate_page_run(uint32 flags, page_num_t length, freeClearQueueLocker.Lock(); } - start += i + 1; + start += max_c(i, alignmentMask) + 1; } }