blob: e9f06f27da88b06caae5605392b74e1b7e943fa5 [file] [log] [blame]
Benny Baumann8e4ce182023-05-24 11:14:25 +02001/*
2htop - InfoScreen.c
3(C) 2016 Hisham H. Muhammad
4(C) 2020,2022 htop dev team
5Released under the GNU GPLv2+, see the COPYING file
6in the source distribution for its full text.
7*/
8
Benny Baumann0f526292020-09-19 13:55:23 +02009#include "config.h" // IWYU pragma: keep
10
Hisham Muhammad466d4da2016-01-12 06:00:58 -020011#include "InfoScreen.h"
12
Benny Baumann0f526292020-09-19 13:55:23 +020013#include <stdarg.h>
14#include <stdio.h>
Benny Baumann0f526292020-09-19 13:55:23 +020015#include <string.h>
16
Hisham Muhammad466d4da2016-01-12 06:00:58 -020017#include "CRT.h"
18#include "IncSet.h"
19#include "ListItem.h"
Benny Baumann0f526292020-09-19 13:55:23 +020020#include "Object.h"
21#include "ProvideCurses.h"
Benny Baumann872e5422020-10-14 20:21:09 +020022#include "XUtils.h"
Hisham Muhammad466d4da2016-01-12 06:00:58 -020023
Hisham Muhammad466d4da2016-01-12 06:00:58 -020024
Richardd5faf642017-07-22 21:41:19 -050025static const char* const InfoScreenFunctions[] = {"Search ", "Filter ", "Refresh", "Done ", NULL};
Hisham Muhammad466d4da2016-01-12 06:00:58 -020026
Richardd5faf642017-07-22 21:41:19 -050027static const char* const InfoScreenKeys[] = {"F3", "F4", "F5", "Esc"};
Hisham Muhammad466d4da2016-01-12 06:00:58 -020028
Christian Göttsche7e7a53c2020-12-20 16:58:37 +010029static const int InfoScreenEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
Hisham Muhammad466d4da2016-01-12 06:00:58 -020030
Christian Göttsche41eea8a2020-10-07 19:02:15 +020031InfoScreen* InfoScreen_init(InfoScreen* this, const Process* process, FunctionBar* bar, int height, const char* panelHeader) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -020032 this->process = process;
33 if (!bar) {
34 bar = FunctionBar_new(InfoScreenFunctions, InfoScreenKeys, InfoScreenEvents);
35 }
Christian Göttschece9e7fd2021-01-02 23:51:53 +010036 this->display = Panel_new(0, 1, COLS, height, Class(ListItem), false, bar);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020037 this->inc = IncSet_new(bar);
Christian Göttsched37d66b2021-03-12 16:46:55 +010038 this->lines = Vector_new(Vector_type(this->display->items), true, DEFAULT_SIZE);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020039 Panel_setHeader(this->display, panelHeader);
40 return this;
41}
42
43InfoScreen* InfoScreen_done(InfoScreen* this) {
44 Panel_delete((Object*)this->display);
45 IncSet_delete(this->inc);
46 Vector_delete(this->lines);
47 return this;
48}
49
Christian Göttsche11f558f2020-08-20 21:58:14 +020050void InfoScreen_drawTitled(InfoScreen* this, const char* fmt, ...) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -020051 va_list ap;
52 va_start(ap, fmt);
ryenusff455b02020-10-03 00:12:31 +080053
Christian Göttschee3862aa2020-12-16 21:46:11 +010054 char title[COLS + 1];
55 int len = vsnprintf(title, sizeof(title), fmt, ap);
56 va_end(ap);
57
ryenusff455b02020-10-03 00:12:31 +080058 if (len > COLS) {
59 memset(&title[COLS - 3], '.', 3);
60 }
61
Hisham Muhammad466d4da2016-01-12 06:00:58 -020062 attrset(CRT_colors[METER_TEXT]);
63 mvhline(0, 0, ' ', COLS);
Vbfcb8ca2021-01-08 05:11:45 +010064 mvaddstr(0, 0, title);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020065 attrset(CRT_colors[DEFAULT_COLOR]);
Christian Göttschea3cced92020-12-28 23:26:14 +010066 Panel_draw(this->display, true, true, true, false);
Christian Göttschee3862aa2020-12-16 21:46:11 +010067
Hisham Muhammad72ba20f2021-08-31 15:38:52 +100068 IncSet_drawBar(this->inc, CRT_colors[FUNCTION_BAR]);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020069}
70
71void InfoScreen_addLine(InfoScreen* this, const char* line) {
72 Vector_add(this->lines, (Object*) ListItem_new(line, 0));
73 const char* incFilter = IncSet_filter(this->inc);
Daniel Lange7c43e022022-03-25 16:24:24 +010074 if (!incFilter || String_contains_i(line, incFilter, true)) {
Benny Baumann61e14d42020-10-31 23:28:02 +010075 Panel_add(this->display, Vector_get(this->lines, Vector_size(this->lines) - 1));
Benny Baumann45869512020-11-01 01:09:51 +010076 }
Hisham Muhammad466d4da2016-01-12 06:00:58 -020077}
78
79void InfoScreen_appendLine(InfoScreen* this, const char* line) {
Benny Baumann61e14d42020-10-31 23:28:02 +010080 ListItem* last = (ListItem*)Vector_get(this->lines, Vector_size(this->lines) - 1);
Hisham Muhammad466d4da2016-01-12 06:00:58 -020081 ListItem_append(last, line);
82 const char* incFilter = IncSet_filter(this->inc);
Daniel Lange7c43e022022-03-25 16:24:24 +010083 if (incFilter && Panel_get(this->display, Panel_size(this->display) - 1) != (Object*)last && String_contains_i(line, incFilter, true)) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -020084 Panel_add(this->display, (Object*)last);
Benny Baumann45869512020-11-01 01:09:51 +010085 }
Hisham Muhammad466d4da2016-01-12 06:00:58 -020086}
87
88void InfoScreen_run(InfoScreen* this) {
89 Panel* panel = this->display;
90
Benny Baumann61e14d42020-10-31 23:28:02 +010091 if (As_InfoScreen(this)->scan)
92 InfoScreen_scan(this);
93
Hisham Muhammad466d4da2016-01-12 06:00:58 -020094 InfoScreen_draw(this);
95
96 bool looping = true;
97 while (looping) {
98
Christian Göttschea3cced92020-12-28 23:26:14 +010099 Panel_draw(panel, false, true, true, false);
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000100 IncSet_drawBar(this->inc, CRT_colors[FUNCTION_BAR]);
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200101
Hisham Muhammad72ba20f2021-08-31 15:38:52 +1000102 int ch = Panel_getCh(panel);
Daniel Flanagandd334442019-10-31 11:39:12 -0500103
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200104 if (ch == ERR) {
105 if (As_InfoScreen(this)->onErr) {
106 InfoScreen_onErr(this);
107 continue;
108 }
109 }
110
nia2ab8fb82021-07-14 20:17:13 +0200111#ifdef HAVE_GETMOUSE
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200112 if (ch == KEY_MOUSE) {
113 MEVENT mevent;
114 int ok = getmouse(&mevent);
Nathan Scott36ef4d42020-08-19 18:10:16 +1000115 if (ok == OK) {
Youngjae Lee3c618132021-01-14 13:37:46 +0900116 if (mevent.bstate & BUTTON1_RELEASED) {
117 if (mevent.y >= panel->y && mevent.y < LINES - 1) {
118 Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
119 ch = 0;
120 } else if (mevent.y == LINES - 1) {
121 ch = IncSet_synthesizeEvent(this->inc, mevent.x);
122 }
YJ Lee34da6fd2021-01-14 16:25:23 +0900123 }
Youngjae Lee3c618132021-01-14 13:37:46 +0900124 #if NCURSES_MOUSE_VERSION > 1
YJ Lee34da6fd2021-01-14 16:25:23 +0900125 else if (mevent.bstate & BUTTON4_PRESSED) {
Youngjae Lee3c618132021-01-14 13:37:46 +0900126 ch = KEY_WHEELUP;
127 } else if (mevent.bstate & BUTTON5_PRESSED) {
128 ch = KEY_WHEELDOWN;
Jorge Pereira8de04982020-06-11 13:41:13 -0300129 }
YJ Lee34da6fd2021-01-14 16:25:23 +0900130 #endif
Christian Göttschef8208f22020-10-20 13:14:32 +0200131 }
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200132 }
nia2ab8fb82021-07-14 20:17:13 +0200133#endif
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200134
135 if (this->inc->active) {
136 IncSet_handleKey(this->inc, ch, panel, IncSet_getListItemValue, this->lines);
137 continue;
138 }
Daniel Flanagandd334442019-10-31 11:39:12 -0500139
Sohaib Mohamed21cb1c42021-11-04 21:40:39 +0200140 switch (ch) {
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200141 case ERR:
142 continue;
143 case KEY_F(3):
144 case '/':
145 IncSet_activate(this->inc, INC_SEARCH, panel);
146 break;
147 case KEY_F(4):
148 case '\\':
149 IncSet_activate(this->inc, INC_FILTER, panel);
150 break;
151 case KEY_F(5):
152 clear();
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100153 if (As_InfoScreen(this)->scan) {
154 Vector_prune(this->lines);
Benny Baumann45869512020-11-01 01:09:51 +0100155 InfoScreen_scan(this);
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100156 }
Benny Baumann45869512020-11-01 01:09:51 +0100157
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200158 InfoScreen_draw(this);
159 break;
160 case '\014': // Ctrl+L
161 clear();
162 InfoScreen_draw(this);
163 break;
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200164 case 27:
Benny Baumannc49ca612020-11-21 16:59:38 +0100165 case 'q':
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200166 case KEY_F(10):
167 looping = false;
168 break;
169 case KEY_RESIZE:
Benny Baumann61e14d42020-10-31 23:28:02 +0100170 Panel_resize(panel, COLS, LINES - 2);
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100171 if (As_InfoScreen(this)->scan) {
172 Vector_prune(this->lines);
Benny Baumann61e14d42020-10-31 23:28:02 +0100173 InfoScreen_scan(this);
Øystein Hiåsend8d83032021-02-15 20:32:01 +0100174 }
Benny Baumann45869512020-11-01 01:09:51 +0100175
Hisham Muhammad466d4da2016-01-12 06:00:58 -0200176 InfoScreen_draw(this);
177 break;
178 default:
179 if (As_InfoScreen(this)->onKey && InfoScreen_onKey(this, ch)) {
180 continue;
181 }
182 Panel_onKey(panel, ch);
183 }
184 }
185}