summaryrefslogtreecommitdiff
path: root/Applications/SystemMonitor
diff options
context:
space:
mode:
Diffstat (limited to 'Applications/SystemMonitor')
-rw-r--r--Applications/SystemMonitor/CMakeLists.txt16
-rw-r--r--Applications/SystemMonitor/DevicesModel.cpp198
-rw-r--r--Applications/SystemMonitor/DevicesModel.h69
-rw-r--r--Applications/SystemMonitor/GraphWidget.cpp163
-rw-r--r--Applications/SystemMonitor/GraphWidget.h70
-rw-r--r--Applications/SystemMonitor/InterruptsWidget.cpp68
-rw-r--r--Applications/SystemMonitor/InterruptsWidget.h44
-rw-r--r--Applications/SystemMonitor/MemoryStatsWidget.cpp138
-rw-r--r--Applications/SystemMonitor/MemoryStatsWidget.h53
-rw-r--r--Applications/SystemMonitor/NetworkStatisticsWidget.cpp98
-rw-r--r--Applications/SystemMonitor/NetworkStatisticsWidget.h46
-rw-r--r--Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp74
-rw-r--r--Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h45
-rw-r--r--Applications/SystemMonitor/ProcessMemoryMapWidget.cpp141
-rw-r--r--Applications/SystemMonitor/ProcessMemoryMapWidget.h46
-rw-r--r--Applications/SystemMonitor/ProcessModel.cpp454
-rw-r--r--Applications/SystemMonitor/ProcessModel.h172
-rw-r--r--Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp57
-rw-r--r--Applications/SystemMonitor/ProcessUnveiledPathsWidget.h45
-rw-r--r--Applications/SystemMonitor/ThreadStackWidget.cpp68
-rw-r--r--Applications/SystemMonitor/ThreadStackWidget.h47
-rw-r--r--Applications/SystemMonitor/main.cpp670
22 files changed, 0 insertions, 2782 deletions
diff --git a/Applications/SystemMonitor/CMakeLists.txt b/Applications/SystemMonitor/CMakeLists.txt
deleted file mode 100644
index ee2e4d2323..0000000000
--- a/Applications/SystemMonitor/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-set(SOURCES
- DevicesModel.cpp
- GraphWidget.cpp
- InterruptsWidget.cpp
- main.cpp
- MemoryStatsWidget.cpp
- NetworkStatisticsWidget.cpp
- ProcessFileDescriptorMapWidget.cpp
- ProcessMemoryMapWidget.cpp
- ProcessModel.cpp
- ProcessUnveiledPathsWidget.cpp
- ThreadStackWidget.cpp
-)
-
-serenity_app(SystemMonitor ICON app-system-monitor)
-target_link_libraries(SystemMonitor LibGUI LibPCIDB)
diff --git a/Applications/SystemMonitor/DevicesModel.cpp b/Applications/SystemMonitor/DevicesModel.cpp
deleted file mode 100644
index f0692cdd24..0000000000
--- a/Applications/SystemMonitor/DevicesModel.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "DevicesModel.h"
-#include <AK/JsonArray.h>
-#include <AK/JsonObject.h>
-#include <AK/JsonValue.h>
-#include <LibCore/DirIterator.h>
-#include <LibCore/File.h>
-#include <sys/stat.h>
-
-NonnullRefPtr<DevicesModel> DevicesModel::create()
-{
- return adopt(*new DevicesModel);
-}
-
-DevicesModel::DevicesModel()
-{
-}
-
-DevicesModel::~DevicesModel()
-{
-}
-
-int DevicesModel::row_count(const GUI::ModelIndex&) const
-{
- return m_devices.size();
-}
-
-int DevicesModel::column_count(const GUI::ModelIndex&) const
-{
- return Column::__Count;
-}
-
-String DevicesModel::column_name(int column) const
-{
- switch (column) {
- case Column::Device:
- return "Device";
- case Column::Major:
- return "Major";
- case Column::Minor:
- return "Minor";
- case Column::ClassName:
- return "Class";
- case Column::Type:
- return "Type";
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-GUI::Variant DevicesModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
-{
- ASSERT(is_valid(index));
-
- if (role == GUI::ModelRole::TextAlignment) {
- switch (index.column()) {
- case Column::Device:
- return Gfx::TextAlignment::CenterLeft;
- case Column::Major:
- return Gfx::TextAlignment::CenterRight;
- case Column::Minor:
- return Gfx::TextAlignment::CenterRight;
- case Column::ClassName:
- return Gfx::TextAlignment::CenterLeft;
- case Column::Type:
- return Gfx::TextAlignment::CenterLeft;
- }
- return {};
- }
-
- if (role == GUI::ModelRole::Sort) {
- const DeviceInfo& device = m_devices[index.row()];
- switch (index.column()) {
- case Column::Device:
- return device.path;
- case Column::Major:
- return device.major;
- case Column::Minor:
- return device.minor;
- case Column::ClassName:
- return device.class_name;
- case Column::Type:
- return device.type;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- if (role == GUI::ModelRole::Display) {
- const DeviceInfo& device = m_devices[index.row()];
- switch (index.column()) {
- case Column::Device:
- return device.path;
- case Column::Major:
- return device.major;
- case Column::Minor:
- return device.minor;
- case Column::ClassName:
- return device.class_name;
- case Column::Type:
- switch (device.type) {
- case DeviceInfo::Type::Block:
- return "Block";
- case DeviceInfo::Type::Character:
- return "Character";
- default:
- ASSERT_NOT_REACHED();
- }
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- return {};
-}
-
-void DevicesModel::update()
-{
- auto proc_devices = Core::File::construct("/proc/devices");
- if (!proc_devices->open(Core::IODevice::OpenMode::ReadOnly))
- ASSERT_NOT_REACHED();
-
- auto json = JsonValue::from_string(proc_devices->read_all());
- ASSERT(json.has_value());
-
- m_devices.clear();
- json.value().as_array().for_each([this](auto& value) {
- JsonObject device = value.as_object();
- DeviceInfo device_info;
-
- device_info.major = device.get("major").to_uint();
- device_info.minor = device.get("minor").to_uint();
- device_info.class_name = device.get("class_name").to_string();
-
- String type_str = device.get("type").to_string();
- if (type_str == "block")
- device_info.type = DeviceInfo::Type::Block;
- else if (type_str == "character")
- device_info.type = DeviceInfo::Type::Character;
- else
- ASSERT_NOT_REACHED();
-
- m_devices.append(move(device_info));
- });
-
- auto fill_in_paths_from_dir = [this](const String& dir) {
- Core::DirIterator dir_iter { dir, Core::DirIterator::Flags::SkipDots };
- while (dir_iter.has_next()) {
- auto name = dir_iter.next_path();
- auto path = String::format("%s/%s", dir.characters(), name.characters());
- struct stat statbuf;
- if (lstat(path.characters(), &statbuf) != 0) {
- ASSERT_NOT_REACHED();
- }
- if (!S_ISBLK(statbuf.st_mode) && !S_ISCHR(statbuf.st_mode))
- continue;
- unsigned _major = major(statbuf.st_rdev);
- unsigned _minor = minor(statbuf.st_rdev);
-
- auto it = m_devices.find_if([_major, _minor](const auto& device_info) {
- return device_info.major == _major && device_info.minor == _minor;
- });
- if (it != m_devices.end()) {
- (*it).path = move(path);
- }
- }
- };
-
- fill_in_paths_from_dir("/dev");
- fill_in_paths_from_dir("/dev/pts");
-
- did_update();
-}
diff --git a/Applications/SystemMonitor/DevicesModel.h b/Applications/SystemMonitor/DevicesModel.h
deleted file mode 100644
index dd8cacc7e0..0000000000
--- a/Applications/SystemMonitor/DevicesModel.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/String.h>
-#include <AK/Vector.h>
-#include <LibGUI/Model.h>
-
-class DevicesModel final : public GUI::Model {
-public:
- enum Column {
- Device = 0,
- Major,
- Minor,
- ClassName,
- Type,
- __Count
- };
-
- virtual ~DevicesModel() override;
- static NonnullRefPtr<DevicesModel> create();
-
- virtual int row_count(const GUI::ModelIndex&) const override;
- virtual int column_count(const GUI::ModelIndex&) const override;
- virtual String column_name(int column) const override;
- virtual GUI::Variant data(const GUI::ModelIndex&, GUI::ModelRole) const override;
- virtual void update() override;
-
-private:
- DevicesModel();
-
- struct DeviceInfo {
- String path;
- unsigned major;
- unsigned minor;
- String class_name;
- enum Type {
- Block,
- Character
- };
- Type type;
- };
-
- Vector<DeviceInfo> m_devices;
-};
diff --git a/Applications/SystemMonitor/GraphWidget.cpp b/Applications/SystemMonitor/GraphWidget.cpp
deleted file mode 100644
index 5c1d9982d4..0000000000
--- a/Applications/SystemMonitor/GraphWidget.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "GraphWidget.h"
-#include <LibGUI/Painter.h>
-#include <LibGfx/Font.h>
-#include <LibGfx/Path.h>
-
-GraphWidget::GraphWidget()
-{
-}
-
-GraphWidget::~GraphWidget()
-{
-}
-
-void GraphWidget::add_value(Vector<int, 1>&& value)
-{
- m_values.enqueue(move(value));
- update();
-}
-
-void GraphWidget::paint_event(GUI::PaintEvent& event)
-{
- GUI::Frame::paint_event(event);
- GUI::Painter painter(*this);
- painter.add_clip_rect(event.rect());
- painter.add_clip_rect(frame_inner_rect());
- painter.fill_rect(event.rect(), m_background_color);
-
- auto inner_rect = frame_inner_rect();
- float scale = (float)inner_rect.height() / (float)m_max;
-
- if (!m_values.is_empty()) {
- // Draw one set of values at a time
- for (size_t k = 0; k < m_value_format.size(); k++) {
- const auto& format = m_value_format[k];
- if (format.line_color == Color::Transparent && format.background_color == Color::Transparent)
- continue;
- m_calculated_points.clear_with_capacity();
- for (size_t i = 0; i < m_values.size(); i++) {
- int x = inner_rect.right() - (i * 2) + 1;
- if (x < 0)
- break;
- const auto& current_values = m_values.at(m_values.size() - i - 1);
- if (current_values.size() <= k) {
- // Don't have a data point
- m_calculated_points.append({ -1, -1 });
- continue;
- }
- float value = current_values[k];
- if (m_stack_values) {
- for (size_t l = k + 1; l < current_values.size(); l++)
- value += current_values[l];
- }
- float scaled_value = value * scale;
- Gfx::IntPoint current_point { x, inner_rect.bottom() - (int)scaled_value };
- m_calculated_points.append(current_point);
- }
- ASSERT(m_calculated_points.size() <= m_values.size());
- if (format.background_color != Color::Transparent) {
- // Fill the background for the area we have values for
- Gfx::Path path;
- size_t points_in_path = 0;
- bool started_path = false;
- const Gfx::IntPoint* current_point = nullptr;
- const Gfx::IntPoint* first_point = nullptr;
- auto check_fill_area = [&]() {
- if (!started_path)
- return;
- if (points_in_path > 1) {
- ASSERT(current_point);
- ASSERT(first_point);
- path.line_to({ current_point->x() - 1, inner_rect.bottom() + 1 });
- path.line_to({ first_point->x() + 1, inner_rect.bottom() + 1 });
- path.close();
- painter.fill_path(path, format.background_color, Gfx::Painter::WindingRule::EvenOdd);
- } else if (points_in_path == 1 && current_point) {
- // Can't fill any area, we only have one data point.
- // Just draw a vertical line as a "fill"...
- painter.draw_line(*current_point, { current_point->x(), inner_rect.bottom() }, format.background_color);
- }
- path = {};
- points_in_path = 0;
- first_point = nullptr;
- started_path = false;
- };
- for (size_t i = 0; i < m_calculated_points.size(); i++) {
- current_point = &m_calculated_points[i];
- if (current_point->x() < 0) {
- check_fill_area();
- continue;
- }
- if (!started_path) {
- path.move_to({ current_point->x() + 1, current_point->y() });
- points_in_path = 1;
- first_point = current_point;
- started_path = true;
- } else {
- path.line_to({ current_point->x(), current_point->y() });
- points_in_path++;
- }
- }
- check_fill_area();
- }
- if (format.line_color != Color::Transparent) {
- // Draw the line for the data points we have
- const Gfx::IntPoint* previous_point = nullptr;
- for (size_t i = 0; i < m_calculated_points.size(); i++) {
- const auto& current_point = m_calculated_points[i];
- if (current_point.x() < 0) {
- previous_point = nullptr;
- continue;
- }
- if (previous_point)
- painter.draw_line(*previous_point, current_point, format.line_color);
- previous_point = &current_point;
- }
- }
- }
- }
-
- if (!m_values.is_empty() && !m_value_format.is_empty()) {
- const auto& current_values = m_values.last();
- int y = 0;
- for (size_t i = 0; i < min(m_value_format.size(), current_values.size()); i++) {
- const auto& format = m_value_format[i];
- if (!format.text_formatter)
- continue;
- auto constrain_rect = inner_rect.shrunken(8, 8);
- auto text_rect = constrain_rect.translated(0, y).intersected(constrain_rect);
- text_rect.set_height(font().glyph_height());
- auto text = format.text_formatter(current_values[i]);
- if (format.text_shadow_color != Color::Transparent)
- painter.draw_text(text_rect.translated(1, 1), text.characters(), Gfx::TextAlignment::CenterRight, format.text_shadow_color);
- painter.draw_text(text_rect, text.characters(), Gfx::TextAlignment::CenterRight, format.line_color);
- y += text_rect.height() + 4;
- }
- }
-}
diff --git a/Applications/SystemMonitor/GraphWidget.h b/Applications/SystemMonitor/GraphWidget.h
deleted file mode 100644
index fc40f59bbd..0000000000
--- a/Applications/SystemMonitor/GraphWidget.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/CircularQueue.h>
-#include <LibGUI/Frame.h>
-
-class GraphWidget final : public GUI::Frame {
- C_OBJECT(GraphWidget)
-public:
- virtual ~GraphWidget() override;
-
- void set_max(int max) { m_max = max; }
- int max() const { return m_max; }
-
- void add_value(Vector<int, 1>&&);
-
- void set_background_color(Color color) { m_background_color = color; }
-
- struct ValueFormat {
- Color line_color { Color::Transparent };
- Color background_color { Color::Transparent };
- Color text_shadow_color { Color::Transparent };
- Function<String(int)> text_formatter;
- };
- void set_value_format(size_t index, ValueFormat&& format)
- {
- if (m_value_format.size() <= index)
- m_value_format.resize(index + 1);
- m_value_format[index] = move(format);
- }
- void set_stack_values(bool stack_values) { m_stack_values = stack_values; }
-
-private:
- explicit GraphWidget();
-
- virtual void paint_event(GUI::PaintEvent&) override;
-
- int m_max { 100 };
- Vector<ValueFormat, 1> m_value_format;
- CircularQueue<Vector<int, 1>, 4000> m_values;
- Color m_background_color { Color::Black };
- bool m_stack_values { false };
-
- Vector<Gfx::IntPoint, 1> m_calculated_points;
-};
diff --git a/Applications/SystemMonitor/InterruptsWidget.cpp b/Applications/SystemMonitor/InterruptsWidget.cpp
deleted file mode 100644
index 3e56f29ec4..0000000000
--- a/Applications/SystemMonitor/InterruptsWidget.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2020, the SerenityOS developers.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "InterruptsWidget.h"
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/GroupBox.h>
-#include <LibGUI/JsonArrayModel.h>
-#include <LibGUI/SortingProxyModel.h>
-#include <LibGUI/TableView.h>
-
-InterruptsWidget::InterruptsWidget()
-{
- on_first_show = [this](auto&) {
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 4, 4, 4, 4 });
-
- Vector<GUI::JsonArrayModel::FieldSpec> interrupts_field;
- interrupts_field.empend("interrupt_line", "Line", Gfx::TextAlignment::CenterRight);
- interrupts_field.empend("purpose", "Purpose", Gfx::TextAlignment::CenterLeft);
- interrupts_field.empend("controller", "Controller", Gfx::TextAlignment::CenterLeft);
- interrupts_field.empend("cpu_handler", "CPU Handler", Gfx::TextAlignment::CenterRight);
- interrupts_field.empend("device_sharing", "# Devices Sharing", Gfx::TextAlignment::CenterRight);
- interrupts_field.empend("call_count", "Call Count", Gfx::TextAlignment::CenterRight);
-
- m_interrupt_table_view = add<GUI::TableView>();
- m_interrupt_model = GUI::JsonArrayModel::create("/proc/interrupts", move(interrupts_field));
- m_interrupt_table_view->set_model(GUI::SortingProxyModel::create(*m_interrupt_model));
-
- m_update_timer = add<Core::Timer>(
- 1000, [this] {
- update_model();
- });
-
- update_model();
- };
-}
-
-InterruptsWidget::~InterruptsWidget()
-{
-}
-
-void InterruptsWidget::update_model()
-{
- m_interrupt_table_view->model()->update();
-}
diff --git a/Applications/SystemMonitor/InterruptsWidget.h b/Applications/SystemMonitor/InterruptsWidget.h
deleted file mode 100644
index bc11215217..0000000000
--- a/Applications/SystemMonitor/InterruptsWidget.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020, the SerenityOS developers.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibCore/Timer.h>
-#include <LibGUI/LazyWidget.h>
-
-class InterruptsWidget final : public GUI::LazyWidget {
- C_OBJECT(InterruptsWidget)
-public:
- virtual ~InterruptsWidget() override;
-
-private:
- InterruptsWidget();
- void update_model();
-
- RefPtr<GUI::TableView> m_interrupt_table_view;
- RefPtr<GUI::JsonArrayModel> m_interrupt_model;
- RefPtr<Core::Timer> m_update_timer;
-};
diff --git a/Applications/SystemMonitor/MemoryStatsWidget.cpp b/Applications/SystemMonitor/MemoryStatsWidget.cpp
deleted file mode 100644
index 6675ea8c4a..0000000000
--- a/Applications/SystemMonitor/MemoryStatsWidget.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "MemoryStatsWidget.h"
-#include "GraphWidget.h"
-#include <AK/ByteBuffer.h>
-#include <AK/JsonObject.h>
-#include <LibCore/File.h>
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/Label.h>
-#include <LibGUI/Painter.h>
-#include <LibGfx/Font.h>
-#include <LibGfx/FontDatabase.h>
-#include <LibGfx/StylePainter.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-static MemoryStatsWidget* s_the;
-
-MemoryStatsWidget* MemoryStatsWidget::the()
-{
- return s_the;
-}
-
-MemoryStatsWidget::MemoryStatsWidget(GraphWidget& graph)
- : m_graph(graph)
-{
- ASSERT(!s_the);
- s_the = this;
-
- set_fixed_height(110);
-
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 0, 8, 0, 0 });
- layout()->set_spacing(3);
-
- auto build_widgets_for_label = [this](const String& description) -> RefPtr<GUI::Label> {
- auto& container = add<GUI::Widget>();
- container.set_layout<GUI::HorizontalBoxLayout>();
- container.set_fixed_size(275, 12);
- auto& description_label = container.add<GUI::Label>(description);
- description_label.set_font(Gfx::FontDatabase::default_bold_font());
- description_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
- auto& label = container.add<GUI::Label>();
- label.set_text_alignment(Gfx::TextAlignment::CenterRight);
- return label;
- };
-
- m_user_physical_pages_label = build_widgets_for_label("Physical memory:");
- m_user_physical_pages_committed_label = build_widgets_for_label("Committed memory:");
- m_supervisor_physical_pages_label = build_widgets_for_label("Supervisor physical:");
- m_kmalloc_space_label = build_widgets_for_label("Kernel heap:");
- m_kmalloc_count_label = build_widgets_for_label("Calls kmalloc:");
- m_kfree_count_label = build_widgets_for_label("Calls kfree:");
- m_kmalloc_difference_label = build_widgets_for_label("Difference:");
-
- refresh();
-}
-
-MemoryStatsWidget::~MemoryStatsWidget()
-{
-}
-
-static inline size_t page_count_to_kb(size_t kb)
-{
- return (kb * 4096) / 1024;
-}
-
-static inline size_t bytes_to_kb(size_t bytes)
-{
- return bytes / 1024;
-}
-
-void MemoryStatsWidget::refresh()
-{
- auto proc_memstat = Core::File::construct("/proc/memstat");
- if (!proc_memstat->open(Core::IODevice::OpenMode::ReadOnly))
- ASSERT_NOT_REACHED();
-
- auto file_contents = proc_memstat->read_all();
- auto json_result = JsonValue::from_string(file_contents);
- ASSERT(json_result.has_value());
- auto json = json_result.value().as_object();
-
- [[maybe_unused]] unsigned kmalloc_eternal_allocated = json.get("kmalloc_eternal_allocated").to_u32();
- unsigned kmalloc_allocated = json.get("kmalloc_allocated").to_u32();
- unsigned kmalloc_available = json.get("kmalloc_available").to_u32();
- unsigned user_physical_allocated = json.get("user_physical_allocated").to_u32();
- unsigned user_physical_available = json.get("user_physical_available").to_u32();
- unsigned user_physical_committed = json.get("user_physical_committed").to_u32();
- unsigned user_physical_uncommitted = json.get("user_physical_uncommitted").to_u32();
- unsigned super_physical_alloc = json.get("super_physical_allocated").to_u32();
- unsigned super_physical_free = json.get("super_physical_available").to_u32();
- unsigned kmalloc_call_count = json.get("kmalloc_call_count").to_u32();
- unsigned kfree_call_count = json.get("kfree_call_count").to_u32();
-
- size_t kmalloc_bytes_total = kmalloc_allocated + kmalloc_available;
- size_t user_physical_pages_total = user_physical_allocated + user_physical_available;
- size_t supervisor_pages_total = super_physical_alloc + super_physical_free;
-
- size_t physical_pages_total = user_physical_pages_total + supervisor_pages_total;
- size_t physical_pages_in_use = user_physical_allocated + super_physical_alloc;
- size_t total_userphysical_and_swappable_pages = user_physical_allocated + user_physical_committed + user_physical_uncommitted;
-
- m_kmalloc_space_label->set_text(String::formatted("{}K/{}K", bytes_to_kb(kmalloc_allocated), bytes_to_kb(kmalloc_bytes_total)));
- m_user_physical_pages_label->set_text(String::formatted("{}K/{}K", page_count_to_kb(physical_pages_in_use), page_count_to_kb(physical_pages_total)));
- m_user_physical_pages_committed_label->set_text(String::formatted("{}K", page_count_to_kb(user_physical_committed)));
- m_supervisor_physical_pages_label->set_text(String::formatted("{}K/{}K", page_count_to_kb(super_physical_alloc), page_count_to_kb(supervisor_pages_total)));
- m_kmalloc_count_label->set_text(String::formatted("{}", kmalloc_call_count));
- m_kfree_count_label->set_text(String::formatted("{}", kfree_call_count));
- m_kmalloc_difference_label->set_text(String::formatted("{:+}", kmalloc_call_count - kfree_call_count));
-
- m_graph.set_max(page_count_to_kb(total_userphysical_and_swappable_pages) + bytes_to_kb(kmalloc_bytes_total));
- m_graph.add_value({ (int)page_count_to_kb(user_physical_committed), (int)page_count_to_kb(user_physical_allocated), (int)bytes_to_kb(kmalloc_bytes_total) });
-}
diff --git a/Applications/SystemMonitor/MemoryStatsWidget.h b/Applications/SystemMonitor/MemoryStatsWidget.h
deleted file mode 100644
index e915730257..0000000000
--- a/Applications/SystemMonitor/MemoryStatsWidget.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibGUI/Widget.h>
-
-class GraphWidget;
-
-class MemoryStatsWidget final : public GUI::Widget {
- C_OBJECT(MemoryStatsWidget)
-public:
- static MemoryStatsWidget* the();
-
- virtual ~MemoryStatsWidget() override;
-
- void refresh();
-
-private:
- MemoryStatsWidget(GraphWidget& graph);
-
- GraphWidget& m_graph;
- RefPtr<GUI::Label> m_user_physical_pages_label;
- RefPtr<GUI::Label> m_user_physical_pages_committed_label;
- RefPtr<GUI::Label> m_supervisor_physical_pages_label;
- RefPtr<GUI::Label> m_kmalloc_space_label;
- RefPtr<GUI::Label> m_kmalloc_count_label;
- RefPtr<GUI::Label> m_kfree_count_label;
- RefPtr<GUI::Label> m_kmalloc_difference_label;
-};
diff --git a/Applications/SystemMonitor/NetworkStatisticsWidget.cpp b/Applications/SystemMonitor/NetworkStatisticsWidget.cpp
deleted file mode 100644
index 7ee2450ee1..0000000000
--- a/Applications/SystemMonitor/NetworkStatisticsWidget.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "NetworkStatisticsWidget.h"
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/GroupBox.h>
-#include <LibGUI/JsonArrayModel.h>
-#include <LibGUI/SortingProxyModel.h>
-#include <LibGUI/TableView.h>
-
-NetworkStatisticsWidget::NetworkStatisticsWidget()
-{
- on_first_show = [this](auto&) {
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 4, 4, 4, 4 });
- set_fill_with_background_color(true);
-
- auto& adapters_group_box = add<GUI::GroupBox>("Adapters");
- adapters_group_box.set_layout<GUI::VerticalBoxLayout>();
- adapters_group_box.layout()->set_margins({ 6, 16, 6, 6 });
- adapters_group_box.set_fixed_height(120);
-
- m_adapter_table_view = adapters_group_box.add<GUI::TableView>();
-
- Vector<GUI::JsonArrayModel::FieldSpec> net_adapters_fields;
- net_adapters_fields.empend("name", "Name", Gfx::TextAlignment::CenterLeft);
- net_adapters_fields.empend("class_name", "Class", Gfx::TextAlignment::CenterLeft);
- net_adapters_fields.empend("mac_address", "MAC", Gfx::TextAlignment::CenterLeft);
- net_adapters_fields.empend("ipv4_address", "IPv4", Gfx::TextAlignment::CenterLeft);
- net_adapters_fields.empend("packets_in", "Pkt In", Gfx::TextAlignment::CenterRight);
- net_adapters_fields.empend("packets_out", "Pkt Out", Gfx::TextAlignment::CenterRight);
- net_adapters_fields.empend("bytes_in", "Bytes In", Gfx::TextAlignment::CenterRight);
- net_adapters_fields.empend("bytes_out", "Bytes Out", Gfx::TextAlignment::CenterRight);
- m_adapter_model = GUI::JsonArrayModel::create("/proc/net/adapters", move(net_adapters_fields));
- m_adapter_table_view->set_model(GUI::SortingProxyModel::create(*m_adapter_model));
-
- auto& sockets_group_box = add<GUI::GroupBox>("Sockets");
- sockets_group_box.set_layout<GUI::VerticalBoxLayout>();
- sockets_group_box.layout()->set_margins({ 6, 16, 6, 6 });
-
- m_socket_table_view = sockets_group_box.add<GUI::TableView>();
-
- Vector<GUI::JsonArrayModel::FieldSpec> net_tcp_fields;
- net_tcp_fields.empend("peer_address", "Peer", Gfx::TextAlignment::CenterLeft);
- net_tcp_fields.empend("peer_port", "Port", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("local_address", "Local", Gfx::TextAlignment::CenterLeft);
- net_tcp_fields.empend("local_port", "Port", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("state", "State", Gfx::TextAlignment::CenterLeft);
- net_tcp_fields.empend("ack_number", "Ack#", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("sequence_number", "Seq#", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("packets_in", "Pkt In", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("packets_out", "Pkt Out", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("bytes_in", "Bytes In", Gfx::TextAlignment::CenterRight);
- net_tcp_fields.empend("bytes_out", "Bytes Out", Gfx::TextAlignment::CenterRight);
- m_socket_model = GUI::JsonArrayModel::create("/proc/net/tcp", move(net_tcp_fields));
- m_socket_table_view->set_model(GUI::SortingProxyModel::create(*m_socket_model));
-
- m_update_timer = add<Core::Timer>(
- 1000, [this] {
- update_models();
- });
-
- update_models();
- };
-}
-
-NetworkStatisticsWidget::~NetworkStatisticsWidget()
-{
-}
-
-void NetworkStatisticsWidget::update_models()
-{
- m_adapter_table_view->model()->update();
- m_socket_table_view->model()->update();
-}
diff --git a/Applications/SystemMonitor/NetworkStatisticsWidget.h b/Applications/SystemMonitor/NetworkStatisticsWidget.h
deleted file mode 100644
index d49a9641c8..0000000000
--- a/Applications/SystemMonitor/NetworkStatisticsWidget.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibCore/Timer.h>
-#include <LibGUI/LazyWidget.h>
-
-class NetworkStatisticsWidget final : public GUI::LazyWidget {
- C_OBJECT(NetworkStatisticsWidget)
-public:
- virtual ~NetworkStatisticsWidget() override;
-
-private:
- NetworkStatisticsWidget();
- void update_models();
-
- RefPtr<GUI::TableView> m_adapter_table_view;
- RefPtr<GUI::TableView> m_socket_table_view;
- RefPtr<GUI::JsonArrayModel> m_adapter_model;
- RefPtr<GUI::JsonArrayModel> m_socket_model;
- RefPtr<Core::Timer> m_update_timer;
-};
diff --git a/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp b/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp
deleted file mode 100644
index 48dfae098d..0000000000
--- a/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ProcessFileDescriptorMapWidget.h"
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/JsonArrayModel.h>
-#include <LibGUI/SortingProxyModel.h>
-#include <LibGUI/TableView.h>
-
-ProcessFileDescriptorMapWidget::ProcessFileDescriptorMapWidget()
-{
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 4, 4, 4, 4 });
- m_table_view = add<GUI::TableView>();
-
- Vector<GUI::JsonArrayModel::FieldSpec> pid_fds_fields;
- pid_fds_fields.empend("fd", "FD", Gfx::TextAlignment::CenterRight);
- pid_fds_fields.empend("class", "Class", Gfx::TextAlignment::CenterLeft);
- pid_fds_fields.empend("offset", "Offset", Gfx::TextAlignment::CenterRight);
- pid_fds_fields.empend("absolute_path", "Path", Gfx::TextAlignment::CenterLeft);
- pid_fds_fields.empend("Access", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- return object.get("seekable").to_bool() ? "Seekable" : "Sequential";
- });
- pid_fds_fields.empend("Blocking", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- return object.get("blocking").to_bool() ? "Blocking" : "Nonblocking";
- });
- pid_fds_fields.empend("On exec", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- return object.get("cloexec").to_bool() ? "Close" : "Keep";
- });
- pid_fds_fields.empend("Can read", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- return object.get("can_read").to_bool() ? "Yes" : "No";
- });
- pid_fds_fields.empend("Can write", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- return object.get("can_write").to_bool() ? "Yes" : "No";
- });
-
- m_model = GUI::JsonArrayModel::create({}, move(pid_fds_fields));
- m_table_view->set_model(GUI::SortingProxyModel::create(*m_model));
-}
-
-ProcessFileDescriptorMapWidget::~ProcessFileDescriptorMapWidget()
-{
-}
-
-void ProcessFileDescriptorMapWidget::set_pid(pid_t pid)
-{
- if (m_pid == pid)
- return;
- m_pid = pid;
- m_model->set_json_path(String::formatted("/proc/{}/fds", m_pid));
-}
diff --git a/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h b/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h
deleted file mode 100644
index 2c45577525..0000000000
--- a/Applications/SystemMonitor/ProcessFileDescriptorMapWidget.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibGUI/Widget.h>
-
-class ProcessFileDescriptorMapWidget final : public GUI::Widget {
- C_OBJECT(ProcessFileDescriptorMapWidget);
-
-public:
- virtual ~ProcessFileDescriptorMapWidget() override;
-
- void set_pid(pid_t);
-
-private:
- ProcessFileDescriptorMapWidget();
-
- RefPtr<GUI::TableView> m_table_view;
- RefPtr<GUI::JsonArrayModel> m_model;
- pid_t m_pid { -1 };
-};
diff --git a/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp b/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp
deleted file mode 100644
index d36a7f57ab..0000000000
--- a/Applications/SystemMonitor/ProcessMemoryMapWidget.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ProcessMemoryMapWidget.h"
-#include <LibCore/Timer.h>
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/JsonArrayModel.h>
-#include <LibGUI/Painter.h>
-#include <LibGUI/SortingProxyModel.h>
-#include <LibGUI/TableView.h>
-#include <LibGfx/Palette.h>
-
-class PagemapPaintingDelegate final : public GUI::TableCellPaintingDelegate {
-public:
- virtual ~PagemapPaintingDelegate() override { }
-
- virtual void paint(GUI::Painter& painter, const Gfx::IntRect& a_rect, const Gfx::Palette&, const GUI::ModelIndex& index) override
- {
- auto rect = a_rect.shrunken(2, 2);
- auto pagemap = index.data(GUI::ModelRole::Custom).to_string();
-
- float scale_factor = (float)pagemap.length() / (float)rect.width();
-
- for (int i = 0; i < rect.width(); ++i) {
- int x = rect.x() + i;
- char c = pagemap[(float)i * scale_factor];
- Color color;
- if (c == 'N') // Null (no page at all, typically an inode-backed page that hasn't been paged in.)
- color = Color::White;
- else if (c == 'Z') // Zero (globally shared zero page, typically an untouched anonymous page.)
- color = Color::from_rgb(0xc0c0ff);
- else if (c == 'P') // Physical (a resident page)
- color = Color::Black;
- else
- ASSERT_NOT_REACHED();
-
- painter.draw_line({ x, rect.top() }, { x, rect.bottom() }, color);
- }
-
- painter.draw_rect(rect, Color::Black);
- }
-};
-
-ProcessMemoryMapWidget::ProcessMemoryMapWidget()
-{
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 4, 4, 4, 4 });
- m_table_view = add<GUI::TableView>();
- Vector<GUI::JsonArrayModel::FieldSpec> pid_vm_fields;
- pid_vm_fields.empend(
- "Address", Gfx::TextAlignment::CenterLeft,
- [](auto& object) { return String::formatted("{:#x}", object.get("address").to_u32()); },
- [](auto& object) { return object.get("address").to_u32(); });
- pid_vm_fields.empend("size", "Size", Gfx::TextAlignment::CenterRight);
- pid_vm_fields.empend("amount_resident", "Resident", Gfx::TextAlignment::CenterRight);
- pid_vm_fields.empend("amount_dirty", "Dirty", Gfx::TextAlignment::CenterRight);
- pid_vm_fields.empend("Access", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- StringBuilder builder;
- if (!object.get("user_accessible").to_bool())
- builder.append('K');
- if (object.get("readable").to_bool())
- builder.append('R');
- if (object.get("writable").to_bool())
- builder.append('W');
- if (object.get("executable").to_bool())
- builder.append('X');
- if (object.get("shared").to_bool())
- builder.append('S');
- if (object.get("stack").to_bool())
- builder.append('T');
- return builder.to_string();
- });
- pid_vm_fields.empend("vmobject", "VMObject type", Gfx::TextAlignment::CenterLeft);
- pid_vm_fields.empend("Purgeable", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- if (object.get("volatile").to_bool())
- return "Volatile";
- return "Non-volatile";
- });
- pid_vm_fields.empend(
- "Page map", Gfx::TextAlignment::CenterLeft,
- [](auto&) {
- return GUI::Variant();
- },
- [](auto&) {
- return GUI::Variant(0);
- },
- [](const JsonObject& object) {
- auto pagemap = object.get("pagemap").as_string_or({});
- return pagemap;
- });
- pid_vm_fields.empend("cow_pages", "# CoW", Gfx::TextAlignment::CenterRight);
- pid_vm_fields.empend("name", "Name", Gfx::TextAlignment::CenterLeft);
- m_json_model = GUI::JsonArrayModel::create({}, move(pid_vm_fields));
- m_table_view->set_model(GUI::SortingProxyModel::create(*m_json_model));
-
- m_table_view->set_column_painting_delegate(7, make<PagemapPaintingDelegate>());
-
- m_table_view->set_key_column_and_sort_order(0, GUI::SortOrder::Ascending);
- m_timer = add<Core::Timer>(1000, [this] { refresh(); });
-}
-
-ProcessMemoryMapWidget::~ProcessMemoryMapWidget()
-{
-}
-
-void ProcessMemoryMapWidget::set_pid(pid_t pid)
-{
- if (m_pid == pid)
- return;
- m_pid = pid;
- m_json_model->set_json_path(String::formatted("/proc/{}/vm", pid));
-}
-
-void ProcessMemoryMapWidget::refresh()
-{
- if (m_pid != -1)
- m_json_model->update();
-}
diff --git a/Applications/SystemMonitor/ProcessMemoryMapWidget.h b/Applications/SystemMonitor/ProcessMemoryMapWidget.h
deleted file mode 100644
index 71a554fe51..0000000000
--- a/Applications/SystemMonitor/ProcessMemoryMapWidget.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibGUI/Widget.h>
-
-class ProcessMemoryMapWidget final : public GUI::Widget {
- C_OBJECT(ProcessMemoryMapWidget);
-
-public:
- virtual ~ProcessMemoryMapWidget() override;
-
- void set_pid(pid_t);
- void refresh();
-
-private:
- ProcessMemoryMapWidget();
- RefPtr<GUI::TableView> m_table_view;
- RefPtr<GUI::JsonArrayModel> m_json_model;
- pid_t m_pid { -1 };
- RefPtr<Core::Timer> m_timer;
-};
diff --git a/Applications/SystemMonitor/ProcessModel.cpp b/Applications/SystemMonitor/ProcessModel.cpp
deleted file mode 100644
index c12a5503ab..0000000000
--- a/Applications/SystemMonitor/ProcessModel.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ProcessModel.h"
-#include "GraphWidget.h"
-#include <AK/JsonArray.h>
-#include <AK/JsonObject.h>
-#include <AK/JsonValue.h>
-#include <AK/SharedBuffer.h>
-#include <LibCore/File.h>
-#include <LibCore/ProcessStatisticsReader.h>
-#include <LibGUI/FileIconProvider.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-static ProcessModel* s_the;
-
-ProcessModel& ProcessModel::the()
-{
- ASSERT(s_the);
- return *s_the;
-}
-
-ProcessModel::ProcessModel()
-{
- ASSERT(!s_the);
- s_the = this;
- m_generic_process_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/gear.png");
- m_high_priority_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/highpriority.png");
- m_low_priority_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/lowpriority.png");
- m_normal_priority_icon = Gfx::Bitmap::load_from_file("/res/icons/16x16/normalpriority.png");
-
- auto file = Core::File::construct("/proc/cpuinfo");
- if (file->open(Core::IODevice::ReadOnly)) {
- auto json = JsonValue::from_string({ file->read_all() });
- auto cpuinfo_array = json.value().as_array();
- cpuinfo_array.for_each([&](auto& value) {
- auto& cpu_object = value.as_object();
- auto cpu_id = cpu_object.get("processor").as_u32();
- m_cpus.append(make<CpuInfo>(cpu_id));
- });
- }
-
- if (m_cpus.is_empty())
- m_cpus.append(make<CpuInfo>(0));
-}
-
-ProcessModel::~ProcessModel()
-{
-}
-
-int ProcessModel::row_count(const GUI::ModelIndex&) const
-{
- return m_pids.size();
-}
-
-int ProcessModel::column_count(const GUI::ModelIndex&) const
-{
- return Column::__Count;
-}
-
-String ProcessModel::column_name(int column) const
-{
- switch (column) {
- case Column::Icon:
- return "";
- case Column::PID:
- return "PID";
- case Column::TID:
- return "TID";
- case Column::PPID:
- return "PPID";
- case Column::PGID:
- return "PGID";
- case Column::SID:
- return "SID";
- case Column::State:
- return "State";
- case Column::User:
- return "User";
- case Column::Priority:
- return "Pr";
- case Column::EffectivePriority:
- return "EPr";
- case Column::Virtual:
- return "Virtual";
- case Column::Physical:
- return "Physical";
- case Column::DirtyPrivate:
- return "DirtyP";
- case Column::CleanInode:
- return "CleanI";
- case Column::PurgeableVolatile:
- return "Purg:V";
- case Column::PurgeableNonvolatile:
- return "Purg:N";
- case Column::CPU:
- return "CPU";
- case Column::Processor:
- return "Processor";
- case Column::Name:
- return "Name";
- case Column::Syscalls:
- return "Syscalls";
- case Column::InodeFaults:
- return "F:Inode";
- case Column::ZeroFaults:
- return "F:Zero";
- case Column::CowFaults:
- return "F:CoW";
- case Column::IPv4SocketReadBytes:
- return "IPv4 In";
- case Column::IPv4SocketWriteBytes:
- return "IPv4 Out";
- case Column::UnixSocketReadBytes:
- return "Unix In";
- case Column::UnixSocketWriteBytes:
- return "Unix Out";
- case Column::FileReadBytes:
- return "File In";
- case Column::FileWriteBytes:
- return "File Out";
- case Column::Pledge:
- return "Pledge";
- case Column::Veil:
- return "Veil";
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-static String pretty_byte_size(size_t size)
-{
- return String::formatted("{}K", size / 1024);
-}
-
-GUI::Variant ProcessModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
-{
- ASSERT(is_valid(index));
-
- if (role == GUI::ModelRole::TextAlignment) {
- switch (index.column()) {
- case Column::Icon:
- case Column::Name:
- case Column::State:
- case Column::User:
- case Column::Pledge:
- case Column::Veil:
- return Gfx::TextAlignment::CenterLeft;
- case Column::PID:
- case Column::TID:
- case Column::PPID:
- case Column::PGID:
- case Column::SID:
- case Column::Priority:
- case Column::EffectivePriority:
- case Column::Virtual:
- case Column::Physical:
- case Column::DirtyPrivate:
- case Column::CleanInode:
- case Column::PurgeableVolatile:
- case Column::PurgeableNonvolatile:
- case Column::CPU:
- case Column::Processor:
- case Column::Syscalls:
- case Column::InodeFaults:
- case Column::ZeroFaults:
- case Column::CowFaults:
- case Column::FileReadBytes:
- case Column::FileWriteBytes:
- case Column::UnixSocketReadBytes:
- case Column::UnixSocketWriteBytes:
- case Column::IPv4SocketReadBytes:
- case Column::IPv4SocketWriteBytes:
- return Gfx::TextAlignment::CenterRight;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- auto it = m_threads.find(m_pids[index.row()]);
- auto& thread = *(*it).value;
-
- if (role == GUI::ModelRole::Sort) {
- switch (index.column()) {
- case Column::Icon:
- return 0;
- case Column::PID:
- return thread.current_state.pid;
- case Column::TID:
- return thread.current_state.tid;
- case Column::PPID:
- return thread.current_state.ppid;
- case Column::PGID:
- return thread.current_state.pgid;
- case Column::SID:
- return thread.current_state.sid;
- case Column::State:
- return thread.current_state.state;
- case Column::User:
- return thread.current_state.user;
- case Column::Priority:
- return thread.current_state.priority;
- case Column::EffectivePriority:
- return thread.current_state.effective_priority;
- case Column::Virtual:
- return (int)thread.current_state.amount_virtual;
- case Column::Physical:
- return (int)thread.current_state.amount_resident;
- case Column::DirtyPrivate:
- return (int)thread.current_state.amount_dirty_private;
- case Column::CleanInode:
- return (int)thread.current_state.amount_clean_inode;
- case Column::PurgeableVolatile:
- return (int)thread.current_state.amount_purgeable_volatile;
- case Column::PurgeableNonvolatile:
- return (int)thread.current_state.amount_purgeable_nonvolatile;
- case Column::CPU:
- return thread.current_state.cpu_percent;
- case Column::Processor:
- return thread.current_state.cpu;
- case Column::Name:
- return thread.current_state.name;
- case Column::Syscalls:
- return thread.current_state.syscall_count;
- case Column::InodeFaults:
- return thread.current_state.inode_faults;
- case Column::ZeroFaults:
- return thread.current_state.zero_faults;
- case Column::CowFaults:
- return thread.current_state.cow_faults;
- case Column::IPv4SocketReadBytes:
- return thread.current_state.ipv4_socket_read_bytes;
- case Column::IPv4SocketWriteBytes:
- return thread.current_state.ipv4_socket_write_bytes;
- case Column::UnixSocketReadBytes:
- return thread.current_state.unix_socket_read_bytes;
- case Column::UnixSocketWriteBytes:
- return thread.current_state.unix_socket_write_bytes;
- case Column::FileReadBytes:
- return thread.current_state.file_read_bytes;
- case Column::FileWriteBytes:
- return thread.current_state.file_write_bytes;
- case Column::Pledge:
- return thread.current_state.pledge;
- case Column::Veil:
- return thread.current_state.veil;
- }
- ASSERT_NOT_REACHED();
- return {};
- }
-
- if (role == GUI::ModelRole::Display) {
- switch (index.column()) {
- case Column::Icon: {
- auto icon = GUI::FileIconProvider::icon_for_executable(thread.current_state.executable);
- if (auto* bitmap = icon.bitmap_for_size(16))
- return *bitmap;
- return *m_generic_process_icon;
- }
- case Column::PID:
- return thread.current_state.pid;
- case Column::TID:
- return thread.current_state.tid;
- case Column::PPID:
- return thread.current_state.ppid;
- case Column::PGID:
- return thread.current_state.pgid;
- case Column::SID:
- return thread.current_state.sid;
- case Column::State:
- return thread.current_state.state;
- case Column::User:
- return thread.current_state.user;
- case Column::Priority:
- return thread.current_state.priority;
- case Column::EffectivePriority:
- return thread.current_state.effective_priority;
- case Column::Virtual:
- return pretty_byte_size(thread.current_state.amount_virtual);
- case Column::Physical:
- return pretty_byte_size(thread.current_state.amount_resident);
- case Column::DirtyPrivate:
- return pretty_byte_size(thread.current_state.amount_dirty_private);
- case Column::CleanInode:
- return pretty_byte_size(thread.current_state.amount_clean_inode);
- case Column::PurgeableVolatile:
- return pretty_byte_size(thread.current_state.amount_purgeable_volatile);
- case Column::PurgeableNonvolatile:
- return pretty_byte_size(thread.current_state.amount_purgeable_nonvolatile);
- case Column::CPU:
- return thread.current_state.cpu_percent;
- case Column::Processor:
- return thread.current_state.cpu;
- case Column::Name:
- return thread.current_state.name;
- case Column::Syscalls:
- return thread.current_state.syscall_count;
- case Column::InodeFaults:
- return thread.current_state.inode_faults;
- case Column::ZeroFaults:
- return thread.current_state.zero_faults;
- case Column::CowFaults:
- return thread.current_state.cow_faults;
- case Column::IPv4SocketReadBytes:
- return thread.current_state.ipv4_socket_read_bytes;
- case Column::IPv4SocketWriteBytes:
- return thread.current_state.ipv4_socket_write_bytes;
- case Column::UnixSocketReadBytes:
- return thread.current_state.unix_socket_read_bytes;
- case Column::UnixSocketWriteBytes:
- return thread.current_state.unix_socket_write_bytes;
- case Column::FileReadBytes:
- return thread.current_state.file_read_bytes;
- case Column::FileWriteBytes:
- return thread.current_state.file_write_bytes;
- case Column::Pledge:
- return thread.current_state.pledge;
- case Column::Veil:
- return thread.current_state.veil;
- }
- }
-
- return {};
-}
-
-void ProcessModel::update()
-{
- auto previous_pid_count = m_pids.size();
- auto all_processes = Core::ProcessStatisticsReader::get_all(m_proc_all);
-
- u64 last_sum_ticks_scheduled = 0, last_sum_ticks_scheduled_kernel = 0;
- for (auto& it : m_threads) {
- auto& current_state = it.value->current_state;
- last_sum_ticks_scheduled += current_state.ticks_user + current_state.ticks_kernel;
- last_sum_ticks_scheduled_kernel += current_state.ticks_kernel;
- }
-
- HashTable<PidAndTid> live_pids;
- u64 sum_ticks_scheduled = 0, sum_ticks_scheduled_kernel = 0;
- if (all_processes.has_value()) {
- for (auto& it : all_processes.value()) {
- for (auto& thread : it.value.threads) {
- ThreadState state;
- state.pid = it.value.pid;
- state.user = it.value.username;
- state.pledge = it.value.pledge;
- state.veil = it.value.veil;
- state.syscall_count = thread.syscall_count;
- state.inode_faults = thread.inode_faults;
- state.zero_faults = thread.zero_faults;
- state.cow_faults = thread.cow_faults;
- state.unix_socket_read_bytes = thread.unix_socket_read_bytes;
- state.unix_socket_write_bytes = thread.unix_socket_write_bytes;
- state.ipv4_socket_read_bytes = thread.ipv4_socket_read_bytes;
- state.ipv4_socket_write_bytes = thread.ipv4_socket_write_bytes;
- state.file_read_bytes = thread.file_read_bytes;
- state.file_write_bytes = thread.file_write_bytes;
- state.amount_virtual = it.value.amount_virtual;
- state.amount_resident = it.value.amount_resident;
- state.amount_dirty_private = it.value.amount_dirty_private;
- state.amount_clean_inode = it.value.amount_clean_inode;
- state.amount_purgeable_volatile = it.value.amount_purgeable_volatile;
- state.amount_purgeable_nonvolatile = it.value.amount_purgeable_nonvolatile;
-
- state.name = thread.name;
- state.executable = it.value.executable;
-
- state.ppid = it.value.ppid;
- state.tid = thread.tid;
- state.pgid = it.value.pgid;
- state.sid = it.value.sid;
- state.times_scheduled = thread.times_scheduled;
- state.ticks_user = thread.ticks_user;
- state.ticks_kernel = thread.ticks_kernel;
- state.cpu = thread.cpu;
- state.cpu_percent = 0;
- state.priority = thread.priority;
- state.effective_priority = thread.effective_priority;
- state.state = thread.state;
- sum_ticks_scheduled += thread.ticks_user + thread.ticks_kernel;
- sum_ticks_scheduled_kernel += thread.ticks_kernel;
- {
- auto pit = m_threads.find({ it.value.pid, thread.tid });
- if (pit == m_threads.end())
- m_threads.set({ it.value.pid, thread.tid }, make<Thread>());
- }
- auto pit = m_threads.find({ it.value.pid, thread.tid });
- ASSERT(pit != m_threads.end());
- (*pit).value->previous_state = (*pit).value->current_state;
- (*pit).value->current_state = state;
-
- live_pids.set({ it.value.pid, thread.tid });
- }
- }
- }
-
- m_pids.clear();
- for (auto& c : m_cpus) {
- c.total_cpu_percent = 0.0;
- c.total_cpu_percent_kernel = 0.0;
- }
- Vector<PidAndTid, 16> pids_to_remove;
- for (auto& it : m_threads) {
- if (!live_pids.contains(it.key)) {
- pids_to_remove.append(it.key);
- continue;
- }
- auto& process = *it.value;
- u32 ticks_scheduled_diff = (process.current_state.ticks_user + process.current_state.ticks_kernel)
- - (process.previous_state.ticks_user + process.previous_state.ticks_kernel);
- u32 ticks_scheduled_diff_kernel = process.current_state.ticks_kernel - process.previous_state.ticks_kernel;
- process.current_state.cpu_percent = ((float)ticks_scheduled_diff * 100) / (float)(sum_ticks_scheduled - last_sum_ticks_scheduled);
- process.current_state.cpu_percent_kernel = ((float)ticks_scheduled_diff_kernel * 100) / (float)(sum_ticks_scheduled - last_sum_ticks_scheduled);
- if (it.key.pid != 0) {
- auto& cpu_info = m_cpus[process.current_state.cpu];
- cpu_info.total_cpu_percent += process.current_state.cpu_percent;
- cpu_info.total_cpu_percent_kernel += process.current_state.cpu_percent_kernel;
- m_pids.append(it.key);
- }
- }
- for (auto pid : pids_to_remove)
- m_threads.remove(pid);
-
- if (on_cpu_info_change)
- on_cpu_info_change(m_cpus);
-
- // FIXME: This is a rather hackish way of invalidating indexes.
- // It would be good if GUI::Model had a way to orchestrate removal/insertion while preserving indexes.
- did_update(previous_pid_count == m_pids.size() ? GUI::Model::UpdateFlag::DontInvalidateIndexes : GUI::Model::UpdateFlag::InvalidateAllIndexes);
-}
diff --git a/Applications/SystemMonitor/ProcessModel.h b/Applications/SystemMonitor/ProcessModel.h
deleted file mode 100644
index 11f39cac76..0000000000
--- a/Applications/SystemMonitor/ProcessModel.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <AK/HashMap.h>
-#include <AK/NonnullOwnPtrVector.h>
-#include <AK/String.h>
-#include <AK/Vector.h>
-#include <LibGUI/Model.h>
-#include <unistd.h>
-
-class GraphWidget;
-
-struct PidAndTid {
- bool operator==(const PidAndTid& other) const
- {
- return pid == other.pid && tid == other.tid;
- }
- pid_t pid;
- int tid;
-};
-
-class ProcessModel final : public GUI::Model {
-public:
- enum Column {
- Icon = 0,
- Name,
- CPU,
- Processor,
- State,
- Priority,
- EffectivePriority,
- User,
- PID,
- TID,
- PPID,
- PGID,
- SID,
- Virtual,
- Physical,
- DirtyPrivate,
- CleanInode,
- PurgeableVolatile,
- PurgeableNonvolatile,
- Veil,
- Pledge,
- Syscalls,
- InodeFaults,
- ZeroFaults,
- CowFaults,
- FileReadBytes,
- FileWriteBytes,
- UnixSocketReadBytes,
- UnixSocketWriteBytes,
- IPv4SocketReadBytes,
- IPv4SocketWriteBytes,
- __Count
- };
-
- static ProcessModel& the();
-
- static NonnullRefPtr<ProcessModel> create() { return adopt(*new ProcessModel); }
- virtual ~ProcessModel() override;
-
- virtual int row_count(const GUI::ModelIndex&) const override;
- virtual int column_count(const GUI::ModelIndex&) const override;
- virtual String column_name(int column) const override;
- virtual GUI::Variant data(const GUI::ModelIndex&, GUI::ModelRole) const override;
- virtual void update() override;
-
- struct CpuInfo {
- u32 id;
- float total_cpu_percent { 0.0 };
- float total_cpu_percent_kernel { 0.0 };
-
- CpuInfo(u32 id)
- : id(id)
- {
- }
- };
-
- Function<void(const NonnullOwnPtrVector<CpuInfo>&)> on_cpu_info_change;
-
- const NonnullOwnPtrVector<CpuInfo>& cpus() const { return m_cpus; }
-
-private:
- ProcessModel();
-
- struct ThreadState {
- pid_t tid;
- pid_t pid;
- pid_t ppid;
- pid_t pgid;
- pid_t sid;
- unsigned times_scheduled;
- unsigned ticks_user;
- unsigned ticks_kernel;
- String executable;
- String name;
- String state;
- String user;
- String pledge;
- String veil;
- u32 cpu;
- u32 priority;
- u32 effective_priority;
- size_t amount_virtual;
- size_t amount_resident;
- size_t amount_dirty_private;
- size_t amount_clean_inode;
- size_t amount_purgeable_volatile;
- size_t amount_purgeable_nonvolatile;
- unsigned syscall_count;
- unsigned inode_faults;
- unsigned zero_faults;
- unsigned cow_faults;
- unsigned unix_socket_read_bytes;
- unsigned unix_socket_write_bytes;
- unsigned ipv4_socket_read_bytes;
- unsigned ipv4_socket_write_bytes;
- unsigned file_read_bytes;
- unsigned file_write_bytes;
- float cpu_percent;
- float cpu_percent_kernel;
- };
-
- struct Thread {
- ThreadState current_state;
- ThreadState previous_state;
- };
-
- HashMap<uid_t, String> m_usernames;
- HashMap<PidAndTid, NonnullOwnPtr<Thread>> m_threads;
- NonnullOwnPtrVector<CpuInfo> m_cpus;
- Vector<PidAndTid> m_pids;
- RefPtr<Gfx::Bitmap> m_generic_process_icon;
- RefPtr<Gfx::Bitmap> m_high_priority_icon;
- RefPtr<Gfx::Bitmap> m_low_priority_icon;
- RefPtr<Gfx::Bitmap> m_normal_priority_icon;
- RefPtr<Core::File> m_proc_all;
-};
-
-namespace AK {
-template<>
-struct Traits<PidAndTid> : public GenericTraits<PidAndTid> {
- static unsigned hash(const PidAndTid& value) { return pair_int_hash(value.pid, value.tid); }
-};
-}
diff --git a/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp b/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp
deleted file mode 100644
index 9e2d22443c..0000000000
--- a/Applications/SystemMonitor/ProcessUnveiledPathsWidget.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ProcessUnveiledPathsWidget.h"
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/JsonArrayModel.h>
-#include <LibGUI/SortingProxyModel.h>
-#include <LibGUI/TableView.h>
-
-ProcessUnveiledPathsWidget::ProcessUnveiledPathsWidget()
-{
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 4, 4, 4, 4 });
- m_table_view = add<GUI::TableView>();
-
- Vector<GUI::JsonArrayModel::FieldSpec> pid_unveil_fields;
- pid_unveil_fields.empend("path", "Path", Gfx::TextAlignment::CenterLeft);
- pid_unveil_fields.empend("permissions", "Permissions", Gfx::TextAlignment::CenterLeft);
-
- m_model = GUI::JsonArrayModel::create({}, move(pid_unveil_fields));
- m_table_view->set_model(GUI::SortingProxyModel::create(*m_model));
-}
-
-ProcessUnveiledPathsWidget::~ProcessUnveiledPathsWidget()
-{
-}
-
-void ProcessUnveiledPathsWidget::set_pid(pid_t pid)
-{
- if (m_pid == pid)
- return;
- m_pid = pid;
- m_model->set_json_path(String::formatted("/proc/{}/unveil", m_pid));
-}
diff --git a/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h b/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h
deleted file mode 100644
index d1eac898b2..0000000000
--- a/Applications/SystemMonitor/ProcessUnveiledPathsWidget.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibGUI/Widget.h>
-
-class ProcessUnveiledPathsWidget final : public GUI::Widget {
- C_OBJECT(ProcessUnveiledPathsWidget);
-
-public:
- virtual ~ProcessUnveiledPathsWidget() override;
-
- void set_pid(pid_t);
-
-private:
- ProcessUnveiledPathsWidget();
-
- RefPtr<GUI::TableView> m_table_view;
- RefPtr<GUI::JsonArrayModel> m_model;
- pid_t m_pid { -1 };
-};
diff --git a/Applications/SystemMonitor/ThreadStackWidget.cpp b/Applications/SystemMonitor/ThreadStackWidget.cpp
deleted file mode 100644
index 01e37791a0..0000000000
--- a/Applications/SystemMonitor/ThreadStackWidget.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ThreadStackWidget.h"
-#include <AK/ByteBuffer.h>
-#include <LibCore/File.h>
-#include <LibCore/Timer.h>
-#include <LibGUI/BoxLayout.h>
-
-ThreadStackWidget::ThreadStackWidget()
-{
- set_layout<GUI::VerticalBoxLayout>();
- layout()->set_margins({ 4, 4, 4, 4 });
- m_stack_editor = add<GUI::TextEditor>();
- m_stack_editor->set_mode(GUI::TextEditor::ReadOnly);
-
- m_timer = add<Core::Timer>(1000, [this] { refresh(); });
-}
-
-ThreadStackWidget::~ThreadStackWidget()
-{
-}
-
-void ThreadStackWidget::set_ids(pid_t pid, pid_t tid)
-{
- if (m_pid == pid && m_tid == tid)
- return;
- m_pid = pid;
- m_tid = tid;
- refresh();
-}
-
-void ThreadStackWidget::refresh()
-{
- auto file = Core::File::construct(String::formatted("/proc/{}/stacks/{}", m_pid, m_tid));
- if (!file->open(Core::IODevice::ReadOnly)) {
- m_stack_editor->set_text(String::formatted("Unable to open {}", file->filename()));
- return;
- }
-
- auto new_text = file->read_all();
- if (m_stack_editor->text() != new_text) {
- m_stack_editor->set_text(new_text);
- }
-}
diff --git a/Applications/SystemMonitor/ThreadStackWidget.h b/Applications/SystemMonitor/ThreadStackWidget.h
deleted file mode 100644
index 5a10e93b0a..0000000000
--- a/Applications/SystemMonitor/ThreadStackWidget.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <LibGUI/TextEditor.h>
-#include <LibGUI/Widget.h>
-
-class ThreadStackWidget final : public GUI::Widget {
- C_OBJECT(ThreadStackWidget)
-public:
- virtual ~ThreadStackWidget() override;
-
- void set_ids(pid_t pid, pid_t tid);
- void refresh();
-
-private:
- ThreadStackWidget();
-
- pid_t m_pid { -1 };
- pid_t m_tid { -1 };
- RefPtr<GUI::TextEditor> m_stack_editor;
- RefPtr<Core::Timer> m_timer;
-};
diff --git a/Applications/SystemMonitor/main.cpp b/Applications/SystemMonitor/main.cpp
deleted file mode 100644
index bdf88e44d1..0000000000
--- a/Applications/SystemMonitor/main.cpp
+++ /dev/null
@@ -1,670 +0,0 @@
-/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "DevicesModel.h"
-#include "GraphWidget.h"
-#include "InterruptsWidget.h"
-#include "MemoryStatsWidget.h"
-#include "NetworkStatisticsWidget.h"
-#include "ProcessFileDescriptorMapWidget.h"
-#include "ProcessMemoryMapWidget.h"
-#include "ProcessModel.h"
-#include "ProcessUnveiledPathsWidget.h"
-#include "ThreadStackWidget.h"
-#include <AK/NumberFormat.h>
-#include <LibCore/ArgsParser.h>
-#include <LibCore/Timer.h>
-#include <LibGUI/Action.h>
-#include <LibGUI/ActionGroup.h>
-#include <LibGUI/Application.h>
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/GroupBox.h>
-#include <LibGUI/Icon.h>
-#include <LibGUI/JsonArrayModel.h>
-#include <LibGUI/Label.h>
-#include <LibGUI/LazyWidget.h>
-#include <LibGUI/Menu.h>
-#include <LibGUI/MenuBar.h>
-#include <LibGUI/Painter.h>
-#include <LibGUI/SortingProxyModel.h>
-#include <LibGUI/Splitter.h>
-#include <LibGUI/TabWidget.h>
-#include <LibGUI/TableView.h>
-#include <LibGUI/ToolBar.h>
-#include <LibGUI/Widget.h>
-#include <LibGUI/Window.h>
-#include <LibGfx/Palette.h>
-#include <LibPCIDB/Database.h>
-#include <serenity.h>
-#include <signal.h>
-#include <spawn.h>
-#include <stdio.h>
-#include <unistd.h>
-
-static NonnullRefPtr<GUI::Widget> build_file_systems_tab();
-static NonnullRefPtr<GUI::Widget> build_pci_devices_tab();
-static NonnullRefPtr<GUI::Widget> build_devices_tab();
-static NonnullRefPtr<GUI::Widget> build_graphs_tab();
-static NonnullRefPtr<GUI::Widget> build_processors_tab();
-
-class UnavailableProcessWidget final : public GUI::Frame {
- C_OBJECT(UnavailableProcessWidget)
-public:
- virtual ~UnavailableProcessWidget() override { }
-
- const String& text() const { return m_text; }
- void set_text(String text) { m_text = move(text); }
-
-private:
- UnavailableProcessWidget(String text)
- : m_text(move(text))
- {
- }
-
- virtual void paint_event(GUI::PaintEvent& event) override
- {
- Frame::paint_event(event);
- if (text().is_empty())
- return;
- GUI::Painter painter(*this);
- painter.add_clip_rect(event.rect());
- painter.draw_text(frame_inner_rect(), text(), Gfx::TextAlignment::Center, palette().window_text(), Gfx::TextElision::Right);
- }
-
- String m_text;
-};
-
-static bool can_access_pid(pid_t pid)
-{
- auto path = String::formatted("/proc/{}", pid);
- return access(path.characters(), X_OK) == 0;
-}
-
-int main(int argc, char** argv)
-{
- if (pledge("stdio proc shared_buffer accept rpath exec unix cpath fattr", nullptr) < 0) {
- perror("pledge");
- return 1;
- }
-
- auto app = GUI::Application::construct(argc, argv);
-
- if (pledge("stdio proc shared_buffer accept rpath exec", nullptr) < 0) {
- perror("pledge");
- return 1;
- }
-
- if (unveil("/etc/passwd", "r") < 0) {
- perror("unveil");
- return 1;
- }
-
- if (unveil("/res", "r") < 0) {
- perror("unveil");
- return 1;
- }
-
- if (unveil("/proc", "r") < 0) {
- perror("unveil");
- return 1;
- }
-
- if (unveil("/dev", "r") < 0) {
- perror("unveil");
- return 1;
- }
-
- if (unveil("/bin", "r") < 0) {
- perror("unveil");
- return 1;
- }
-
- if (unveil("/bin/Profiler", "rx") < 0) {
- perror("unveil");
- return 1;
- }
-
- if (unveil("/bin/Inspector", "rx") < 0) {
- perror("unveil");
- return 1;
- }
-
- unveil(nullptr, nullptr);
-
- const char* args_tab = "processes";
- Core::ArgsParser parser;
- parser.add_option(args_tab, "Tab, one of 'processes', 'graphs', 'fs', 'pci', 'devices', 'network', 'processors' or 'interrupts'", "open-tab", 't', "tab");
- parser.parse(argc, argv);
- StringView args_tab_view = args_tab;
-
- auto app_icon = GUI::Icon::default_icon("app-system-monitor");
-
- auto window = GUI::Window::construct();
- window->set_title("System Monitor");
- window->resize(680, 400);
-
- auto& keeper = window->set_main_widget<GUI::Widget>();
- keeper.set_layout<GUI::VerticalBoxLayout>();
- keeper.set_fill_with_background_color(true);
- keeper.layout()->set_margins({ 2, 2, 2, 2 });
-
- auto& tabwidget = keeper.add<GUI::TabWidget>();
-
- auto process_container_splitter = GUI::VerticalSplitter::construct();
- tabwidget.add_widget("Processes", process_container_splitter);
- process_container_splitter->layout()->set_margins({ 4, 4, 4, 4 });
-
- auto& process_table_container = process_container_splitter->add<GUI::Widget>();
-
- auto graphs_widget = build_graphs_tab();
- tabwidget.add_widget("Graphs", graphs_widget);
-
- auto file_systems_widget = build_file_systems_tab();
- tabwidget.add_widget("File systems", file_systems_widget);
-
- auto pci_devices_widget = build_pci_devices_tab();
- tabwidget.add_widget("PCI devices", pci_devices_widget);
-
- auto devices_widget = build_devices_tab();
- tabwidget.add_widget("Devices", devices_widget);
-
- auto network_stats_widget = NetworkStatisticsWidget::construct();
- tabwidget.add_widget("Network", network_stats_widget);
-
- auto processors_widget = build_processors_tab();
- tabwidget.add_widget("Processors", processors_widget);
-
- auto interrupts_widget = InterruptsWidget::construct();
- tabwidget.add_widget("Interrupts", interrupts_widget);
-
- process_table_container.set_layout<GUI::VerticalBoxLayout>();
- process_table_container.layout()->set_spacing(0);
-
- auto& process_table_view = process_table_container.add<GUI::TableView>();
- process_table_view.set_column_headers_visible(true);
- process_table_view.set_model(GUI::SortingProxyModel::create(ProcessModel::create()));
- process_table_view.set_key_column_and_sort_order(ProcessModel::Column::CPU, GUI::SortOrder::Descending);
- process_table_view.model()->update();
-
- auto& refresh_timer = window->add<Core::Timer>(
- 3000, [&] {
- process_table_view.model()->update();
- if (auto* memory_stats_widget = MemoryStatsWidget::the())
- memory_stats_widget->refresh();
- });
-
- auto selected_id = [&](ProcessModel::Column column) -> pid_t {
- if (process_table_view.selection().is_empty())
- return -1;
- auto pid_index = process_table_view.model()->index(process_table_view.selection().first().row(), column);
- return pid_index.data().to_i32();
- };
-
- auto kill_action = GUI::Action::create("Kill process", { Mod_Ctrl, Key_K }, Gfx::Bitmap::load_from_file("/res/icons/16x16/kill.png"), [&](const GUI::Action&) {
- pid_t pid = selected_id(ProcessModel::Column::PID);
- if (pid != -1)
- kill(pid, SIGKILL);
- });
-
- auto stop_action = GUI::Action::create("Stop process", { Mod_Ctrl, Key_S }, Gfx::Bitmap::load_from_file("/res/icons/16x16/stop-hand.png"), [&](const GUI::Action&) {
- pid_t pid = selected_id(ProcessModel::Column::PID);
- if (pid != -1)
- kill(pid, SIGSTOP);
- });
-
- auto continue_action = GUI::Action::create("Continue process", { Mod_Ctrl, Key_C }, Gfx::Bitmap::load_from_file("/res/icons/16x16/continue.png"), [&](const GUI::Action&) {
- pid_t pid = selected_id(ProcessModel::Column::PID);
- if (pid != -1)
- kill(pid, SIGCONT);
- });
-
- auto profile_action = GUI::Action::create("Profile process", { Mod_Ctrl, Key_P },
- Gfx::Bitmap::load_from_file("/res/icons/16x16/app-profiler.png"), [&](auto&) {
- pid_t pid = selected_id(ProcessModel::Column::PID);
- if (pid != -1) {
- auto pid_string = String::format("%d", pid);
- pid_t child;
- const char* argv[] = { "/bin/Profiler", "--pid", pid_string.characters(), nullptr };
- if ((errno = posix_spawn(&child, "/bin/Profiler", nullptr, nullptr, const_cast<char**>(argv), environ))) {
- perror("posix_spawn");
- } else {
- if (disown(child) < 0)
- perror("disown");
- }
- }
- });
-
- auto inspect_action = GUI::Action::create("Inspect process", { Mod_Ctrl, Key_I },
- Gfx::Bitmap::load_from_file("/res/icons/16x16/app-inspector.png"), [&](auto&) {
- pid_t pid = selected_id(ProcessModel::Column::PID);
- if (pid != -1) {
- auto pid_string = String::format("%d", pid);
- pid_t child;
- const char* argv[] = { "/bin/Inspector", pid_string.characters(), nullptr };
- if ((errno = posix_spawn(&child, "/bin/Inspector", nullptr, nullptr, const_cast<char**>(argv), environ))) {
- perror("posix_spawn");
- } else {
- if (disown(child) < 0)
- perror("disown");
- }
- }
- });
-
- auto menubar = GUI::MenuBar::construct();
- auto& app_menu = menubar->add_menu("System Monitor");
- app_menu.add_action(GUI::CommonActions::make_quit_action([](auto&) {
- GUI::Application::the()->quit();
- return;
- }));
-
- auto& process_menu = menubar->add_menu("Process");
- process_menu.add_action(kill_action);
- process_menu.add_action(stop_action);
- process_menu.add_action(continue_action);
- process_menu.add_separator();
- process_menu.add_action(profile_action);
- process_menu.add_action(inspect_action);
-
- auto process_context_menu = GUI::Menu::construct();
- process_context_menu->add_action(kill_action);
- process_context_menu->add_action(stop_action);
- process_context_menu->add_action(continue_action);
- process_context_menu->add_separator();
- process_context_menu->add_action(profile_action);
- process_context_menu->add_action(inspect_action);
- process_table_view.on_context_menu_request = [&]([[maybe_unused]] const GUI::ModelIndex& index, const GUI::ContextMenuEvent& event) {
- process_context_menu->popup(event.screen_position());
- };
-
- auto& frequency_menu = menubar->add_menu("Frequency");
- GUI::ActionGroup frequency_action_group;
- frequency_action_group.set_exclusive(true);
-
- auto make_frequency_action = [&](auto& title, int interval, bool checked = false) {
- auto action = GUI::Action::create_checkable(title, [&refresh_timer, interval](auto&) {
- refresh_timer.restart(interval);
- });
- action->set_checked(checked);
- frequency_action_group.add_action(*action);
- frequency_menu.add_action(*action);
- };
-
- make_frequency_action("1 sec", 1000);
- make_frequency_action("3 sec", 3000, true);
- make_frequency_action("5 sec", 5000);
-
- auto& help_menu = menubar->add_menu("Help");
- help_menu.add_action(GUI::CommonActions::make_about_action("System Monitor", app_icon, window));
-
- app->set_menubar(move(menubar));
-
- auto& process_tab_unused_widget = process_container_splitter->add<UnavailableProcessWidget>("No process selected");
- process_tab_unused_widget.set_visible(true);
-
- auto& process_tab_widget = process_container_splitter->add<GUI::TabWidget>();
- process_tab_widget.set_tab_position(GUI::TabWidget::TabPosition::Bottom);
- process_tab_widget.set_visible(false);
-
- auto& memory_map_widget = process_tab_widget.add_tab<ProcessMemoryMapWidget>("Memory map");
- auto& open_files_widget = process_tab_widget.add_tab<ProcessFileDescriptorMapWidget>("Open files");
- auto& unveiled_paths_widget = process_tab_widget.add_tab<ProcessUnveiledPathsWidget>("Unveiled paths");
- auto& stack_widget = process_tab_widget.add_tab<ThreadStackWidget>("Stack");
-
- process_table_view.on_selection = [&](auto&) {
- auto pid = selected_id(ProcessModel::Column::PID);
- auto tid = selected_id(ProcessModel::Column::TID);
- if (!can_access_pid(pid)) {
- process_tab_widget.set_visible(false);
- process_tab_unused_widget.set_text("Process cannot be accessed");
- process_tab_unused_widget.set_visible(true);
- return;
- }
-
- process_tab_widget.set_visible(true);
- process_tab_unused_widget.set_visible(false);
- open_files_widget.set_pid(pid);
- stack_widget.set_ids(pid, tid);
- memory_map_widget.set_pid(pid);
- unveiled_paths_widget.set_pid(pid);
- };
-
- window->show();
-
- window->set_icon(app_icon.bitmap_for_size(16));
-
- if (args_tab_view == "processes")
- tabwidget.set_active_widget(process_container_splitter);
- else if (args_tab_view == "graphs")
- tabwidget.set_active_widget(graphs_widget);
- else if (args_tab_view == "fs")
- tabwidget.set_active_widget(file_systems_widget);
- else if (args_tab_view == "pci")
- tabwidget.set_active_widget(pci_devices_widget);
- else if (args_tab_view == "devices")
- tabwidget.set_active_widget(devices_widget);
- else if (args_tab_view == "network")
- tabwidget.set_active_widget(network_stats_widget);
- else if (args_tab_view == "processors")
- tabwidget.set_active_widget(processors_widget);
- else if (args_tab_view == "interrupts")
- tabwidget.set_active_widget(interrupts_widget);
-
- return app->exec();
-}
-
-class ProgressBarPaintingDelegate final : public GUI::TableCellPaintingDelegate {
-public:
- virtual ~ProgressBarPaintingDelegate() override { }
-
- virtual void paint(GUI::Painter& painter, const Gfx::IntRect& a_rect, const Palette& palette, const GUI::ModelIndex& index) override
- {
- auto rect = a_rect.shrunken(2, 2);
- auto percentage = index.data(GUI::ModelRole::Custom).to_i32();
-
- auto data = index.data();
- String text;
- if (data.is_string())
- text = data.as_string();
- Gfx::StylePainter::paint_progress_bar(painter, rect, palette, 0, 100, percentage, text);
- painter.draw_rect(rect, Color::Black);
- }
-};
-
-NonnullRefPtr<GUI::Widget> build_file_systems_tab()
-{
- auto fs_widget = GUI::LazyWidget::construct();
-
- fs_widget->on_first_show = [](GUI::LazyWidget& self) {
- self.set_layout<GUI::VerticalBoxLayout>();
- self.layout()->set_margins({ 4, 4, 4, 4 });
- auto& fs_table_view = self.add<GUI::TableView>();
-
- Vector<GUI::JsonArrayModel::FieldSpec> df_fields;
- df_fields.empend("mount_point", "Mount point", Gfx::TextAlignment::CenterLeft);
- df_fields.empend("class_name", "Class", Gfx::TextAlignment::CenterLeft);
- df_fields.empend("source", "Source", Gfx::TextAlignment::CenterLeft);
- df_fields.empend(
- "Size", Gfx::TextAlignment::CenterRight,
- [](const JsonObject& object) {
- StringBuilder size_builder;
- size_builder.append(" ");
- size_builder.append(human_readable_size(object.get("total_block_count").to_u32() * object.get("block_size").to_u32()));
- size_builder.append(" ");
- return size_builder.to_string();
- },
- [](const JsonObject& object) {
- return object.get("total_block_count").to_u32() * object.get("block_size").to_u32();
- },
- [](const JsonObject& object) {
- auto total_blocks = object.get("total_block_count").to_u32();
- if (total_blocks == 0)
- return 0;
- auto free_blocks = object.get("free_block_count").to_u32();
- auto used_blocks = total_blocks - free_blocks;
- int percentage = (int)((float)used_blocks / (float)total_blocks * 100.0f);
- return percentage;
- });
- df_fields.empend(
- "Used", Gfx::TextAlignment::CenterRight,
- [](const JsonObject& object) {
- auto total_blocks = object.get("total_block_count").to_u32();
- auto free_blocks = object.get("free_block_count").to_u32();
- auto used_blocks = total_blocks - free_blocks;
- return human_readable_size(used_blocks * object.get("block_size").to_u32()); },
- [](const JsonObject& object) {
- auto total_blocks = object.get("total_block_count").to_u32();
- auto free_blocks = object.get("free_block_count").to_u32();
- auto used_blocks = total_blocks - free_blocks;
- return used_blocks * object.get("block_size").to_u32();
- });
- df_fields.empend(
- "Available", Gfx::TextAlignment::CenterRight,
- [](const JsonObject& object) {
- return human_readable_size(object.get("free_block_count").to_u32() * object.get("block_size").to_u32());
- },
- [](const JsonObject& object) {
- return object.get("free_block_count").to_u32() * object.get("block_size").to_u32();
- });
- df_fields.empend("Access", Gfx::TextAlignment::CenterLeft, [](const JsonObject& object) {
- bool readonly = object.get("readonly").to_bool();
- int mount_flags = object.get("mount_flags").to_int();
- return readonly || (mount_flags & MS_RDONLY) ? "Read-only" : "Read/Write";
- });
- df_fields.empend("Mount flags", Gfx::TextAlignment::CenterLeft, [](const JsonObject& object) {
- int mount_flags = object.get("mount_flags").to_int();
- StringBuilder builder;
- bool first = true;
- auto check = [&](int flag, const char* name) {
- if (!(mount_flags & flag))
- return;
- if (!first)
- builder.append(',');
- builder.append(name);
- first = false;
- };
- check(MS_NODEV, "nodev");
- check(MS_NOEXEC, "noexec");
- check(MS_NOSUID, "nosuid");
- check(MS_BIND, "bind");
- check(MS_RDONLY, "ro");
- if (builder.string_view().is_empty())
- return String("defaults");
- return builder.to_string();
- });
- df_fields.empend("free_block_count", "Free blocks", Gfx::TextAlignment::CenterRight);
- df_fields.empend("total_block_count", "Total blocks", Gfx::TextAlignment::CenterRight);
- df_fields.empend("free_inode_count", "Free inodes", Gfx::TextAlignment::CenterRight);
- df_fields.empend("total_inode_count", "Total inodes", Gfx::TextAlignment::CenterRight);
- df_fields.empend("block_size", "Block size", Gfx::TextAlignment::CenterRight);
- fs_table_view.set_model(GUI::SortingProxyModel::create(GUI::JsonArrayModel::create("/proc/df", move(df_fields))));
-
- fs_table_view.set_column_painting_delegate(3, make<ProgressBarPaintingDelegate>());
-
- fs_table_view.model()->update();
- };
- return fs_widget;
-}
-
-NonnullRefPtr<GUI::Widget> build_pci_devices_tab()
-{
- auto pci_widget = GUI::LazyWidget::construct();
-
- pci_widget->on_first_show = [](GUI::LazyWidget& self) {
- self.set_layout<GUI::VerticalBoxLayout>();
- self.layout()->set_margins({ 4, 4, 4, 4 });
- auto& pci_table_view = self.add<GUI::TableView>();
-
- auto db = PCIDB::Database::open();
-
- Vector<GUI::JsonArrayModel::FieldSpec> pci_fields;
- pci_fields.empend(
- "Address", Gfx::TextAlignment::CenterLeft,
- [](const JsonObject& object) {
- auto seg = object.get("seg").to_u32();
- auto bus = object.get("bus").to_u32();
- auto slot = object.get("slot").to_u32();
- auto function = object.get("function").to_u32();
- return String::formatted("{:04x}:{:02x}:{:02x}.{}", seg, bus, slot, function);
- });
- pci_fields.empend(
- "Class", Gfx::TextAlignment::CenterLeft,
- [db](const JsonObject& object) {
- auto class_id = object.get("class").to_u32();
- String class_name = db->get_class(class_id);
- return class_name == "" ? String::formatted("{:04x}", class_id) : class_name;
- });
- pci_fields.empend(
- "Vendor", Gfx::TextAlignment::CenterLeft,
- [db](const JsonObject& object) {
- auto vendor_id = object.get("vendor_id").to_u32();
- String vendor_name = db->get_vendor(vendor_id);
- return vendor_name == "" ? String::formatted("{:02x}", vendor_id) : vendor_name;
- });
- pci_fields.empend(
- "Device", Gfx::TextAlignment::CenterLeft,
- [db](const JsonObject& object) {
- auto vendor_id = object.get("vendor_id").to_u32();
- auto device_id = object.get("device_id").to_u32();
- String device_name = db->get_device(vendor_id, device_id);
- return device_name == "" ? String::formatted("{:02x}", device_id) : device_name;
- });
- pci_fields.empend(
- "Revision", Gfx::TextAlignment::CenterRight,
- [](const JsonObject& object) {
- auto revision_id = object.get("revision_id").to_u32();
- return String::formatted("{:02x}", revision_id);
- });
-
- pci_table_view.set_model(GUI::SortingProxyModel::create(GUI::JsonArrayModel::create("/proc/pci", move(pci_fields))));
- pci_table_view.model()->update();
- };
-
- return pci_widget;
-}
-
-NonnullRefPtr<GUI::Widget> build_devices_tab()
-{
- auto devices_widget = GUI::LazyWidget::construct();
-
- devices_widget->on_first_show = [](GUI::LazyWidget& self) {
- self.set_layout<GUI::VerticalBoxLayout>();
- self.layout()->set_margins({ 4, 4, 4, 4 });
-
- auto& devices_table_view = self.add<GUI::TableView>();
- devices_table_view.set_model(GUI::SortingProxyModel::create(DevicesModel::create()));
- devices_table_view.model()->update();
- };
-
- return devices_widget;
-}
-
-NonnullRefPtr<GUI::Widget> build_graphs_tab()
-{
- auto graphs_container = GUI::LazyWidget::construct();
-
- graphs_container->on_first_show = [](GUI::LazyWidget& self) {
- self.set_fill_with_background_color(true);
- self.set_background_role(ColorRole::Button);
- self.set_layout<GUI::VerticalBoxLayout>();
- self.layout()->set_margins({ 4, 4, 4, 4 });
-
- auto& cpu_graph_group_box = self.add<GUI::GroupBox>("CPU usage");
- cpu_graph_group_box.set_layout<GUI::HorizontalBoxLayout>();
- cpu_graph_group_box.layout()->set_margins({ 6, 16, 6, 6 });
- cpu_graph_group_box.set_fixed_height(120);
- Vector<GraphWidget*> cpu_graphs;
- for (size_t i = 0; i < ProcessModel::the().cpus().size(); i++) {
- auto& cpu_graph = cpu_graph_group_box.add<GraphWidget>();
- cpu_graph.set_max(100);
- cpu_graph.set_background_color(Color::White);
- cpu_graph.set_value_format(0, {
- .line_color = Color::Blue,
- .background_color = Color::from_rgb(0xaaaaff),
- .text_formatter = [](int value) {
- return String::formatted("Total: {}%", value);
- },
- });
- cpu_graph.set_value_format(1, {
- .line_color = Color::Red,
- .background_color = Color::from_rgb(0xffaaaa),
- .text_formatter = [](int value) {
- return String::formatted("Kernel: {}%", value);
- },
- });
- cpu_graphs.append(&cpu_graph);
- }
- ProcessModel::the().on_cpu_info_change = [cpu_graphs](const NonnullOwnPtrVector<ProcessModel::CpuInfo>& cpus) {
- for (size_t i = 0; i < cpus.size(); i++)
- cpu_graphs[i]->add_value({ (int)cpus[i].total_cpu_percent, (int)cpus[i].total_cpu_percent_kernel });
- };
-
- auto& memory_graph_group_box = self.add<GUI::GroupBox>("Memory usage");
- memory_graph_group_box.set_layout<GUI::VerticalBoxLayout>();
- memory_graph_group_box.layout()->set_margins({ 6, 16, 6, 6 });
- memory_graph_group_box.set_fixed_height(120);
- auto& memory_graph = memory_graph_group_box.add<GraphWidget>();
- memory_graph.set_background_color(Color::White);
- memory_graph.set_stack_values(true);
- memory_graph.set_value_format(0, {
- .line_color = Color::from_rgb(0x619910),
- .background_color = Color::from_rgb(0xbbffbb),
- .text_formatter = [&memory_graph](int value) {
- return String::formatted("Committed: {} KiB", value);
- },
- });
- memory_graph.set_value_format(1, {
- .line_color = Color::Blue,
- .background_color = Color::from_rgb(0xaaaaff),
- .text_formatter = [&memory_graph](int value) {
- return String::formatted("Allocated: {} KiB", value);
- },
- });
- memory_graph.set_value_format(2, {
- .line_color = Color::Red,
- .background_color = Color::from_rgb(0xffaaaa),
- .text_formatter = [&memory_graph](int value) {
- return String::formatted("Kernel heap: {} KiB", value);
- },
- });
-
- self.add<MemoryStatsWidget>(memory_graph);
- };
- return graphs_container;
-}
-
-NonnullRefPtr<GUI::Widget> build_processors_tab()
-{
- auto processors_widget = GUI::LazyWidget::construct();
-
- processors_widget->on_first_show = [](GUI::LazyWidget& self) {
- self.set_layout<GUI::VerticalBoxLayout>();
- self.layout()->set_margins({ 4, 4, 4, 4 });
-
- Vector<GUI::JsonArrayModel::FieldSpec> processors_field;
- processors_field.empend("processor", "Processor", Gfx::TextAlignment::CenterRight);
- processors_field.empend("cpuid", "CPUID", Gfx::TextAlignment::CenterLeft);
- processors_field.empend("brandstr", "Brand", Gfx::TextAlignment::CenterLeft);
- processors_field.empend("Features", Gfx::TextAlignment::CenterLeft, [](auto& object) {
- StringBuilder builder;
- auto features = object.get("features").as_array();
- for (auto& feature : features.values()) {
- builder.append(feature.to_string());
- builder.append(' ');
- }
- return GUI::Variant(builder.to_string());
- });
- processors_field.empend("family", "Family", Gfx::TextAlignment::CenterRight);
- processors_field.empend("model", "Model", Gfx::TextAlignment::CenterRight);
- processors_field.empend("stepping", "Stepping", Gfx::TextAlignment::CenterRight);
- processors_field.empend("type", "Type", Gfx::TextAlignment::CenterRight);
-
- auto& processors_table_view = self.add<GUI::TableView>();
- processors_table_view.set_model(GUI::JsonArrayModel::create("/proc/cpuinfo", move(processors_field)));
- processors_table_view.model()->update();
- };
-
- return processors_widget;
-}