summaryrefslogtreecommitdiffstats
path: root/MainPanel.c
diff options
context:
space:
mode:
Diffstat (limited to 'MainPanel.c')
-rw-r--r--MainPanel.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/MainPanel.c b/MainPanel.c
new file mode 100644
index 0000000..8349023
--- /dev/null
+++ b/MainPanel.c
@@ -0,0 +1,247 @@
+/*
+htop - ColumnsPanel.c
+(C) 2004-2015 Hisham H. Muhammad
+(C) 2020 Red Hat, Inc. All Rights Reserved.
+Released under the GNU GPLv2+, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include "config.h" // IWYU pragma: keep
+
+#include "MainPanel.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include "CRT.h"
+#include "FunctionBar.h"
+#include "Machine.h"
+#include "Platform.h"
+#include "ProvideCurses.h"
+#include "Row.h"
+#include "RowField.h"
+#include "Settings.h"
+#include "Table.h"
+#include "XUtils.h"
+
+
+static const char* const MainFunctions[] = {"Help ", "Setup ", "Search", "Filter", "Tree ", "SortBy", "Nice -", "Nice +", "Kill ", "Quit ", NULL};
+static const char* const MainFunctions_ro[] = {"Help ", "Setup ", "Search", "Filter", "Tree ", "SortBy", " ", " ", " ", "Quit ", NULL};
+
+void MainPanel_updateLabels(MainPanel* this, bool list, bool filter) {
+ FunctionBar* bar = MainPanel_getFunctionBar(this);
+ FunctionBar_setLabel(bar, KEY_F(5), list ? "List " : "Tree ");
+ FunctionBar_setLabel(bar, KEY_F(4), filter ? "FILTER" : "Filter");
+}
+
+static void MainPanel_idSearch(MainPanel* this, int ch) {
+ Panel* super = (Panel*) this;
+ pid_t id = ch - 48 + this->idSearch;
+ for (int i = 0; i < Panel_size(super); i++) {
+ const Row* row = (const Row*) Panel_get(super, i);
+ if (row && row->id == id) {
+ Panel_setSelected(super, i);
+ break;
+ }
+ }
+ this->idSearch = id * 10;
+ if (this->idSearch > 10000000) {
+ this->idSearch = 0;
+ }
+}
+
+static const char* MainPanel_getValue(Panel* this, int i) {
+ Row* row = (Row*) Panel_get(this, i);
+ return Row_sortKeyString(row);
+}
+
+static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
+ MainPanel* this = (MainPanel*) super;
+ Machine* host = this->state->host;
+ Htop_Reaction reaction = HTOP_OK;
+ HandlerResult result = IGNORED;
+
+ /* Let supervising ScreenManager handle resize */
+ if (ch == KEY_RESIZE)
+ return IGNORED;
+
+ /* reset on every normal key */
+ bool needReset = ch != ERR;
+ #ifdef HAVE_GETMOUSE
+ /* except mouse events while mouse support is disabled */
+ if (!(ch != KEY_MOUSE || host->settings->enableMouse))
+ needReset = false;
+ #endif
+ if (needReset)
+ this->state->hideSelection = false;
+
+ Settings* settings = host->settings;
+ ScreenSettings* ss = settings->ss;
+
+ if (EVENT_IS_HEADER_CLICK(ch)) {
+ int x = EVENT_HEADER_CLICK_GET_X(ch);
+ int hx = super->scrollH + x + 1;
+ RowField field = RowField_keyAt(settings, hx);
+ if (ss->treeView && ss->treeViewAlwaysByPID) {
+ ss->treeView = false;
+ ss->direction = 1;
+ reaction |= Action_setSortKey(settings, field);
+ } else if (field == ScreenSettings_getActiveSortKey(ss)) {
+ ScreenSettings_invertSortOrder(ss);
+ } else {
+ reaction |= Action_setSortKey(settings, field);
+ }
+ reaction |= HTOP_RECALCULATE | HTOP_REDRAW_BAR | HTOP_SAVE_SETTINGS;
+ result = HANDLED;
+ } else if (EVENT_IS_SCREEN_TAB_CLICK(ch)) {
+ int x = EVENT_SCREEN_TAB_GET_X(ch);
+ reaction |= Action_setScreenTab(this->state, x);
+ result = HANDLED;
+ } else if (ch != ERR && this->inc->active) {
+ bool filterChanged = IncSet_handleKey(this->inc, ch, super, MainPanel_getValue, NULL);
+ if (filterChanged) {
+ host->activeTable->incFilter = IncSet_filter(this->inc);
+ reaction = HTOP_REFRESH | HTOP_REDRAW_BAR;
+ }
+ if (this->inc->found) {
+ reaction |= Action_follow(this->state);
+ reaction |= HTOP_KEEP_FOLLOWING;
+ }
+ result = HANDLED;
+ } else if (ch == 27) {
+ this->state->hideSelection = true;
+ return HANDLED;
+ } else if (ch != ERR && ch > 0 && ch < KEY_MAX && this->keys[ch]) {
+ reaction |= (this->keys[ch])(this->state);
+ result = HANDLED;
+ } else if (0 < ch && ch < 255 && isdigit((unsigned char)ch)) {
+ MainPanel_idSearch(this, ch);
+ } else {
+ if (ch != ERR) {
+ this->idSearch = 0;
+ } else {
+ reaction |= HTOP_KEEP_FOLLOWING;
+ }
+ }
+
+ if ((reaction & HTOP_REDRAW_BAR) == HTOP_REDRAW_BAR) {
+ MainPanel_updateLabels(this, settings->ss->treeView, host->activeTable->incFilter);
+ }
+ if ((reaction & HTOP_RESIZE) == HTOP_RESIZE) {
+ result |= RESIZE;
+ }
+ if ((reaction & HTOP_UPDATE_PANELHDR) == HTOP_UPDATE_PANELHDR) {
+ result |= REDRAW;
+ }
+ if ((reaction & HTOP_REFRESH) == HTOP_REFRESH) {
+ result |= REFRESH;
+ }
+ if ((reaction & HTOP_RECALCULATE) == HTOP_RECALCULATE) {
+ result |= RESCAN;
+ }
+ if ((reaction & HTOP_SAVE_SETTINGS) == HTOP_SAVE_SETTINGS) {
+ host->settings->changed = true;
+ }
+ if ((reaction & HTOP_QUIT) == HTOP_QUIT) {
+ return BREAK_LOOP;
+ }
+ if ((reaction & HTOP_KEEP_FOLLOWING) != HTOP_KEEP_FOLLOWING) {
+ host->activeTable->following = -1;
+ Panel_setSelectionColor(super, PANEL_SELECTION_FOCUS);
+ }
+ return result;
+}
+
+int MainPanel_selectedRow(MainPanel* this) {
+ const Row* row = (const Row*) Panel_getSelected((Panel*)this);
+ return row ? row->id : -1;
+}
+
+bool MainPanel_foreachRow(MainPanel* this, MainPanel_foreachRowFn fn, Arg arg, bool* wasAnyTagged) {
+ Panel* super = (Panel*) this;
+ bool ok = true;
+ bool anyTagged = false;
+ for (int i = 0; i < Panel_size(super); i++) {
+ Row* row = (Row*) Panel_get(super, i);
+ if (row->tag) {
+ ok &= fn(row, arg);
+ anyTagged = true;
+ }
+ }
+ if (!anyTagged) {
+ Row* row = (Row*) Panel_getSelected(super);
+ if (row) {
+ ok &= fn(row, arg);
+ }
+ }
+
+ if (wasAnyTagged)
+ *wasAnyTagged = anyTagged;
+
+ return ok;
+}
+
+static void MainPanel_drawFunctionBar(Panel* super, bool hideFunctionBar) {
+ MainPanel* this = (MainPanel*) super;
+
+ // Do not hide active search and filter bar.
+ if (hideFunctionBar && !this->inc->active)
+ return;
+
+ IncSet_drawBar(this->inc, CRT_colors[FUNCTION_BAR]);
+ if (this->state->pauseUpdate) {
+ FunctionBar_append("PAUSED", CRT_colors[PAUSED]);
+ }
+}
+
+static void MainPanel_printHeader(Panel* super) {
+ MainPanel* this = (MainPanel*) super;
+ Machine* host = this->state->host;
+ Table_printHeader(host->settings, &super->header);
+}
+
+const PanelClass MainPanel_class = {
+ .super = {
+ .extends = Class(Panel),
+ .delete = MainPanel_delete
+ },
+ .eventHandler = MainPanel_eventHandler,
+ .drawFunctionBar = MainPanel_drawFunctionBar,
+ .printHeader = MainPanel_printHeader
+};
+
+MainPanel* MainPanel_new(void) {
+ MainPanel* this = AllocThis(MainPanel);
+ this->processBar = FunctionBar_new(MainFunctions, NULL, NULL);
+ this->readonlyBar = FunctionBar_new(MainFunctions_ro, NULL, NULL);
+ FunctionBar* activeBar = Settings_isReadonly() ? this->readonlyBar : this->processBar;
+ Panel_init((Panel*) this, 1, 1, 1, 1, Class(Row), false, activeBar);
+ this->keys = xCalloc(KEY_MAX, sizeof(Htop_Action));
+ this->inc = IncSet_new(activeBar);
+
+ Action_setBindings(this->keys);
+ Platform_setBindings(this->keys);
+
+ return this;
+}
+
+void MainPanel_setState(MainPanel* this, State* state) {
+ this->state = state;
+}
+
+void MainPanel_setFunctionBar(MainPanel* this, bool readonly) {
+ this->super.defaultBar = readonly ? this->readonlyBar : this->processBar;
+ this->inc->defaultBar = this->super.defaultBar;
+}
+
+void MainPanel_delete(Object* object) {
+ Panel* super = (Panel*) object;
+ MainPanel* this = (MainPanel*) object;
+ MainPanel_setFunctionBar(this, false);
+ FunctionBar_delete(this->readonlyBar);
+ Panel_done(super);
+ IncSet_delete(this->inc);
+ free(this->keys);
+ free(this);
+}