From 122905281dd29a0ee9ef35dd280a33aab21e6c3d Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Mon, 5 Nov 2012 11:24:07 +0100 Subject: [PATCH 01/21] Terminal: Make the cursor color configurable. Signed-off-by: Adrien Destugues - PulkoMandy --- src/apps/terminal/AppearPrefView.cpp | 2 ++ src/apps/terminal/PrefHandler.cpp | 2 ++ src/apps/terminal/TermConst.h | 2 ++ src/apps/terminal/TermView.cpp | 28 ++++++++++++---------------- src/apps/terminal/TermView.h | 3 +++ src/apps/terminal/TermWindow.cpp | 2 ++ 6 files changed, 23 insertions(+), 16 deletions(-) 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..5070021e87 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; @@ -1225,15 +1228,8 @@ TermView::_DrawCursor() } else { 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); - } + else + SetHighColor(fCursorBackColor); 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..f039c9549d 100644 --- a/src/apps/terminal/TermWindow.cpp +++ b/src/apps/terminal/TermWindow.cpp @@ -1018,6 +1018,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)); } From ab7a2ea818743b87f41e747871b11d58127ee23f Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 5 Nov 2012 17:53:14 +0100 Subject: [PATCH 02/21] Add support for creating derived types to DwarfType. --- src/apps/debugger/debug_info/DwarfTypes.cpp | 16 ++++++++++++++++ src/apps/debugger/debug_info/DwarfTypes.h | 5 +++++ src/apps/debugger/model/Type.cpp | 9 +++++++++ src/apps/debugger/model/Type.h | 7 +++++++ 4 files changed, 37 insertions(+) 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/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; From 9e7a46be2010116155a07fb4b5aa6b627eeb7be2 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 5 Nov 2012 17:53:41 +0100 Subject: [PATCH 03/21] Extend typecasting to support pointer/address types. We now parse the user's input to see if it should be a pointer/reference type and create a derived type accordingly. This allows casting to e.g. StyledEditApp*. --- .../gui/team_window/VariablesView.cpp | 104 ++++++++++++++++-- .../gui/team_window/VariablesView.h | 5 + 2 files changed, 99 insertions(+), 10 deletions(-) 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..e7bc845ece 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1645,19 +1645,20 @@ 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) - break; - - Type* type = NULL; - if (info->LookupTypeByName(message->FindString("text"), - TypeLookupConstraints(), type) != B_OK) { - // TODO: notify user + if (message->FindPointer("node", reinterpret_cast(&node)) + != B_OK) { break; } + Type* type = NULL; + BString typeName = message->FindString("text"); + if (typeName.Length() == 0) + break; + + + if (_ParseInputType(typeName, type) != B_OK) + break; + ValueNode* valueNode = NULL; if (TypeHandlerRoster::Default()->CreateValueNode( node->NodeChild(), type, valueNode) != B_OK) { @@ -2139,6 +2140,89 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState, } +status_t +VariablesView::_ParseInputType(const BString& typeName, + Type*& _resultType) const +{ + status_t result = B_OK; + Type* baseType = NULL; + + TeamDebugInfo* info = fThread->GetTeam()->DebugInfo(); + if (info == NULL) + return B_NO_MEMORY; + + BString parsedName = typeName; + BString baseTypeName; + parsedName.RemoveAll(" "); + + // TODO: this is fairly C/C++-specific and should probably be + // language-agnostic in the long run + 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; +} + + // #pragma mark - Listener 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..5c9467ed52 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; @@ -80,6 +82,9 @@ private: VariablesViewState* viewState, void* parent, TreeTablePath& path); + status_t _ParseInputType(const BString& typeName, + Type*& _outputType) const; + private: Thread* fThread; StackFrame* fStackFrame; From a0e690928b4f96178b9da9432656abdfc30e7e79 Mon Sep 17 00:00:00 2001 From: Jonathan Schleifer Date: Mon, 5 Nov 2012 18:05:18 +0100 Subject: [PATCH 04/21] Terminal: Fix cursor blinking. Signed-off-by: Adrien Destugues - PulkoMandy --- src/apps/terminal/TermView.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/apps/terminal/TermView.cpp b/src/apps/terminal/TermView.cpp index 5070021e87..7e7c089933 100644 --- a/src/apps/terminal/TermView.cpp +++ b/src/apps/terminal/TermView.cpp @@ -1228,8 +1228,12 @@ TermView::_DrawCursor() } else { if (selected) SetHighColor(fSelectBackColor); - else - SetHighColor(fCursorBackColor); + else { + if (cursorVisible) + SetHighColor(fCursorBackColor); + else + SetHighColor(kTermColorTable[IS_BACKCOLOR(attr)]); + } FillRect(rect); } From 82a674605b14403f45c28163480890ef16164476 Mon Sep 17 00:00:00 2001 From: Adrien Destugues - PulkoMandy Date: Mon, 5 Nov 2012 19:21:06 +0100 Subject: [PATCH 05/21] Use Web+ tabs close button Fixes #9566 --- src/servers/notification/AppGroupView.cpp | 45 ++++++++++++---- src/servers/notification/AppGroupView.h | 3 ++ src/servers/notification/NotificationView.cpp | 53 ++++++++++++++----- src/servers/notification/NotificationView.h | 4 +- .../notification/NotificationWindow.cpp | 2 +- 5 files changed, 81 insertions(+), 26 deletions(-) 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; From 8ef01bd74e313b9b1e9732a76f91c59deeca8a02 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Mon, 5 Nov 2012 19:52:35 +0100 Subject: [PATCH 06/21] Fix #8193 - wrong LC_* vars if there's no country code. --- src/bin/locale/locale.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) 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" : ""); } } From ca0d271159445d49707998406c66e97c9d9e61c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 5 Nov 2012 20:01:51 +0100 Subject: [PATCH 07/21] Terminal: Add a tooltip when in fullscreen mode * When in full screen mode, add a tooltip with the window title, and a keyboard shortcut hint so one knows how to get out of it. Should help with #7356 * 80 column cleanup --- src/apps/terminal/TermWindow.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/apps/terminal/TermWindow.cpp b/src/apps/terminal/TermWindow.cpp index f039c9549d..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); @@ -1648,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); } From 35cadd6f3cda83bfd58be558ce287157acc9174e Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 5 Nov 2012 19:15:46 +0100 Subject: [PATCH 08/21] Add watchpoint support in DebuggerInterface. --- .../debugger_interface/DebuggerInterface.cpp | 36 ++++++++++++++++++- .../debugger_interface/DebuggerInterface.h | 6 +++- 2 files changed, 40 insertions(+), 2 deletions(-) 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, From c2ee0abbc1fced075be4e5af2d343240d209f59f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 5 Nov 2012 20:47:39 +0100 Subject: [PATCH 09/21] m68k: Remove one thing done from the TODO list --- docs/develop/ports/m68k/TODO | 1 - 1 file changed, 1 deletion(-) 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? From a6e7fd728d04e5c10ef2e48e878fd0d2bf5936a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 5 Nov 2012 20:49:20 +0100 Subject: [PATCH 10/21] m68k: Add some references to the port docs --- docs/develop/ports/m68k/amiga/urls.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/develop/ports/m68k/amiga/urls.txt 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/ From 35ef01c5663c170ea9f5a9fcaaa1b6d6b9edb84d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 5 Nov 2012 20:58:04 +0100 Subject: [PATCH 11/21] m68k: Add some atari references to the port docs --- docs/develop/ports/m68k/atari/urls.txt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docs/develop/ports/m68k/atari/urls.txt 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 + From 24ad8261a9e60661a01331a1d350c47567c6f018 Mon Sep 17 00:00:00 2001 From: czeidler Date: Mon, 5 Nov 2012 22:24:42 +0100 Subject: [PATCH 12/21] Integrate patch from jessicah #8937. Thanks! - navigate in a single S&T group using (win + left and right arrows) - minor fixed to the patch - enable switching between S&T groups on the same desktop again (win + up and down arrows) Hope window key + arrow keys does not collide with to many apps? --- src/servers/app/stackandtile/StackAndTile.cpp | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) 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()); From 3704c0f8b1bad6ab6cbc6b21d2e33c8bb0dda38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 5 Nov 2012 23:13:56 +0100 Subject: [PATCH 13/21] Add a totally useless Shelf screensaver * Allows dropping replicants, and showing them later on when idle. * Needs some cleanup. --- src/add-ons/screen_savers/Jamfile | 1 + src/add-ons/screen_savers/shelf/Jamfile | 6 + src/add-ons/screen_savers/shelf/Shelf.cpp | 263 ++++++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 src/add-ons/screen_savers/shelf/Jamfile create mode 100644 src/add-ons/screen_savers/shelf/Shelf.cpp 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 +} + + From f5a14b17df1d1d13251f4d86a7ed024b516960ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 6 Nov 2012 00:29:57 +0100 Subject: [PATCH 14/21] vm_page_allocate_page_run: fix for aligned page allocations * don't enforce a zero boundary or a zero alignment * when going to the next range, takes alignment into account. It could previously just be enforced again through alignment and loop infinite. * it should help with some FreeBSD based drivers --- src/system/kernel/vm/vm_page.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) 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; } } From 662b04ff7d27ad3f07210efd527d9d99bda4b538 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 6 Nov 2012 01:03:49 +0100 Subject: [PATCH 15/21] listsem didn't actually support the -s option its help listed. Minor cleanups. --- src/bin/listsem.c | 73 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/src/bin/listsem.c b/src/bin/listsem.c index 6fdb102054..8440eb3249 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,12 +78,12 @@ 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")) { fprintf(stderr, "Usage: %s [-s semid] [teamid]\n", argv[0]); @@ -78,15 +93,31 @@ int main(int argc, char **argv) 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")) { + if (argc < i + 2) + printf("-s used without associated sem id\n"); + else { + sem_id sem = atoi(argv[i+1]); + + } + int semID = atoi(argv[i+1]); + sem_info info; + if (get_sem_info(semID, &info) == B_OK) { + print_header(NULL); + print_sem_info(&info); + } else + printf("semaphore %ld unknown\n\n", semID); + 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; } From 553b6b21235665b1e70bb744a5ad37c36d01569f Mon Sep 17 00:00:00 2001 From: John Scipione Date: Tue, 6 Nov 2012 00:45:53 -0500 Subject: [PATCH 16/21] Fix gcc2 build along with some (minor) style issues --- src/bin/listsem.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/bin/listsem.c b/src/bin/listsem.c index 8440eb3249..d066fcb824 100644 --- a/src/bin/listsem.c +++ b/src/bin/listsem.c @@ -85,29 +85,31 @@ int main(int argc, char **argv) } 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")) { + } else if (strcmp(argv[i], "-s") == 0) { if (argc < i + 2) printf("-s used without associated sem id\n"); else { - sem_id sem = atoi(argv[i+1]); + 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++; } - int semID = atoi(argv[i+1]); - sem_info info; - if (get_sem_info(semID, &info) == B_OK) { - print_header(NULL); - print_sem_info(&info); - } else - printf("semaphore %ld unknown\n\n", semID); - i++; } else { team_id team; team = atoi(argv[i]); From bc61f3813005e20229763f22663c0dd3f255bc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 10:32:32 +0100 Subject: [PATCH 17/21] Add some ARM references * Actually stuff about FDT for now, also useful for other arch like PPC. --- docs/develop/ports/arm/urls.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/develop/ports/arm/urls.txt diff --git a/docs/develop/ports/arm/urls.txt b/docs/develop/ports/arm/urls.txt new file mode 100644 index 0000000000..d48a92a3cc --- /dev/null +++ b/docs/develop/ports/arm/urls.txt @@ -0,0 +1,3 @@ +* FDT +http://elinux.org/images/4/4e/Glikely-powerpc-porting-guide.pdf +http://ols.fedoraproject.org/OLS/Reprints-2008/likely2-reprint.pdf From f8e10024ad2d1e8afce14f342d768d6bd6bf6af7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 10:39:23 +0100 Subject: [PATCH 18/21] Some more FDT references --- docs/develop/ports/arm/urls.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/develop/ports/arm/urls.txt b/docs/develop/ports/arm/urls.txt index d48a92a3cc..f4537b0937 100644 --- a/docs/develop/ports/arm/urls.txt +++ b/docs/develop/ports/arm/urls.txt @@ -1,3 +1,5 @@ * 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 From 6d8c8c0b32406d80b10feb39a215a7ca11126cc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 6 Nov 2012 10:59:58 +0100 Subject: [PATCH 19/21] Even more FDT references --- docs/develop/ports/arm/urls.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/develop/ports/arm/urls.txt b/docs/develop/ports/arm/urls.txt index f4537b0937..abaef44273 100644 --- a/docs/develop/ports/arm/urls.txt +++ b/docs/develop/ports/arm/urls.txt @@ -3,3 +3,6 @@ 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 From 4235cb3e331c05b73700905462dc7dfab02eda36 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 6 Nov 2012 11:45:26 +0100 Subject: [PATCH 20/21] Start adding the underlying infrastructure for watchpoint support. --- src/apps/debugger/Jamfile | 3 + src/apps/debugger/MessageCodes.h | 4 + src/apps/debugger/TeamDebugger.cpp | 170 ++++++++++++++++++ src/apps/debugger/TeamDebugger.h | 17 ++ src/apps/debugger/WatchpointManager.cpp | 95 ++++++++++ src/apps/debugger/WatchpointManager.h | 37 ++++ src/apps/debugger/model/Team.cpp | 145 ++++++++++++--- src/apps/debugger/model/Team.h | 54 +++++- src/apps/debugger/model/Watchpoint.cpp | 65 +++++++ src/apps/debugger/model/Watchpoint.h | 52 ++++++ src/apps/debugger/settings/TeamSettings.cpp | 32 ++++ src/apps/debugger/settings/TeamSettings.h | 6 + .../debugger/settings/WatchpointSetting.cpp | 100 +++++++++++ .../debugger/settings/WatchpointSetting.h | 46 +++++ .../debugger/user_interface/UserInterface.h | 12 ++ 15 files changed, 810 insertions(+), 28 deletions(-) create mode 100644 src/apps/debugger/WatchpointManager.cpp create mode 100644 src/apps/debugger/WatchpointManager.h create mode 100644 src/apps/debugger/model/Watchpoint.cpp create mode 100644 src/apps/debugger/model/Watchpoint.h create mode 100644 src/apps/debugger/settings/WatchpointSetting.cpp create mode 100644 src/apps/debugger/settings/WatchpointSetting.h 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/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/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/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; From 7b74c56650d6e8320b3b0de1fea0a13d0359a312 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 6 Nov 2012 12:22:06 +0100 Subject: [PATCH 21/21] Cleanup: move expression parsing for types to SourceLanguage. --- .../debugger/source_language/CppLanguage.cpp | 83 ++++++++++++++ .../debugger/source_language/CppLanguage.h | 4 + .../source_language/SourceLanguage.cpp | 8 ++ .../debugger/source_language/SourceLanguage.h | 7 ++ .../gui/team_window/VariablesView.cpp | 105 +++--------------- .../gui/team_window/VariablesView.h | 3 - 6 files changed, 120 insertions(+), 90 deletions(-) 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/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index e7bc845ece..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" @@ -1651,14 +1655,24 @@ VariablesView::MessageReceived(BMessage* message) } Type* type = NULL; - BString typeName = message->FindString("text"); - if (typeName.Length() == 0) + BString typeExpression = message->FindString("text"); + if (typeExpression.Length() == 0) break; - - if (_ParseInputType(typeName, type) != B_OK) + 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; + } + ValueNode* valueNode = NULL; if (TypeHandlerRoster::Default()->CreateValueNode( node->NodeChild(), type, valueNode) != B_OK) { @@ -2140,89 +2154,6 @@ VariablesView::_ApplyViewStateDescendentNodeInfos(VariablesViewState* viewState, } -status_t -VariablesView::_ParseInputType(const BString& typeName, - Type*& _resultType) const -{ - status_t result = B_OK; - Type* baseType = NULL; - - TeamDebugInfo* info = fThread->GetTeam()->DebugInfo(); - if (info == NULL) - return B_NO_MEMORY; - - BString parsedName = typeName; - BString baseTypeName; - parsedName.RemoveAll(" "); - - // TODO: this is fairly C/C++-specific and should probably be - // language-agnostic in the long run - 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; -} - - // #pragma mark - Listener 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 5c9467ed52..7c09b73f98 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -82,9 +82,6 @@ private: VariablesViewState* viewState, void* parent, TreeTablePath& path); - status_t _ParseInputType(const BString& typeName, - Type*& _outputType) const; - private: Thread* fThread; StackFrame* fStackFrame;