diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:58:07 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:58:07 +0000 |
commit | 10eea2ab1bae2a8ec159d81c0446fd8061b33e2b (patch) | |
tree | e8270dd60ec096bee8157dbadf029e15ed584592 /MainPanel.c | |
parent | Initial commit. (diff) | |
download | htop-10eea2ab1bae2a8ec159d81c0446fd8061b33e2b.tar.xz htop-10eea2ab1bae2a8ec159d81c0446fd8061b33e2b.zip |
Adding upstream version 3.3.0.upstream/3.3.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'MainPanel.c')
-rw-r--r-- | MainPanel.c | 247 |
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); +} |