fix mandatory context error message
[lttngtop.git] / src / cursesdisplay.c
CommitLineData
1fc22eb4
JD
1/*
2 * Copyright (C) 2011 Julien Desfossez
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
71bd7ce1
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1fc22eb4
JD
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <signal.h>
21#include <string.h>
22#include <ncurses.h>
23#include <panel.h>
24#include <pthread.h>
25#include <semaphore.h>
26
27#include "cursesdisplay.h"
28#include "lttngtoptypes.h"
b093de8a 29#include "iostreamtop.h"
1fc22eb4
JD
30#include "common.h"
31
32#define DEFAULT_DELAY 15
33#define MAX_LINE_LENGTH 50
34#define MAX_LOG_LINES 4
35
36/* to prevent concurrent updates of the different windows */
37sem_t update_display_sem;
38
39char *termtype;
40WINDOW *footer, *header, *center, *status;
0d91c12a
JD
41WINDOW *pref_panel_window = NULL;
42PANEL *pref_panel, *main_panel;
1fc22eb4 43
0d91c12a 44int pref_panel_visible = 0;
3b15348c 45int pref_line_selected = 0;
1fc22eb4
JD
46
47int last_display_index, currently_displayed_index;
48
49struct processtop *selected_process = NULL;
1fc22eb4
JD
50int selected_ret;
51
52int selected_line = 0; /* select bar position */
53int selected_in_list = 0; /* selection relative to the whole list */
54int list_offset = 0; /* first index in the list to display (scroll) */
55int nb_log_lines = 0;
56char log_lines[MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES];
57
58int max_elements = 80;
59
60int toggle_threads = -1;
61int toggle_pause = -1;
1fc22eb4
JD
62
63int max_center_lines;
635dc837 64GPtrArray *selected_processes;
1fc22eb4
JD
65
66pthread_t keyboard_thread;
67
89f1e0d1
JD
68struct header_view cputopview[4];
69struct header_view iostreamtopview[3];
32647247 70struct header_view fileview[3];
3b15348c 71
1fc22eb4
JD
72void reset_ncurses()
73{
74 curs_set(1);
75 endwin();
76 exit(0);
77}
78
79static void handle_sigterm(int signal)
80{
81 reset_ncurses();
82}
83
84void init_screen()
85{
86 initscr();
87 noecho();
88 halfdelay(DEFAULT_DELAY);
89 nonl();
90 intrflush(stdscr, false);
91 keypad(stdscr, true);
92 curs_set(0);
93
94 if (has_colors()) {
95 start_color();
96 init_pair(1, COLOR_RED, COLOR_BLACK); /* - */
97 init_pair(2, COLOR_GREEN, COLOR_BLACK); /* + */
98 init_pair(3, COLOR_BLACK, COLOR_WHITE); /* keys */
99 init_pair(4, COLOR_WHITE, COLOR_GREEN); /* keys activated */
100 init_pair(5, COLOR_WHITE, COLOR_BLUE); /* select line */
635dc837 101 init_pair(6, COLOR_WHITE, COLOR_GREEN); /* selected process */
1fc22eb4
JD
102 }
103 termtype = getenv("TERM");
104 if (!strcmp(termtype, "xterm") || !strcmp(termtype, "xterm-color") ||
105 !strcmp(termtype, "vt220")) {
106 define_key("\033[H", KEY_HOME);
107 define_key("\033[F", KEY_END);
108 define_key("\033OP", KEY_F(1));
109 define_key("\033OQ", KEY_F(2));
110 define_key("\033OR", KEY_F(3));
111 define_key("\033OS", KEY_F(4));
112 define_key("\0330U", KEY_F(6));
113 define_key("\033[11~", KEY_F(1));
114 define_key("\033[12~", KEY_F(2));
115 define_key("\033[13~", KEY_F(3));
116 define_key("\033[14~", KEY_F(4));
117 define_key("\033[16~", KEY_F(6));
118 define_key("\033[17;2~", KEY_F(18));
119 }
120 signal(SIGTERM, handle_sigterm);
121 mousemask(BUTTON1_CLICKED, NULL);
122 refresh();
123}
124
125WINDOW *create_window(int height, int width, int startx, int starty)
126{
127 WINDOW *win;
128 win = newwin(height, width, startx, starty);
129 box(win, 0 , 0);
130 wrefresh(win);
131 return win;
132}
133
134WINDOW *create_window_no_border(int height, int width, int startx, int starty)
135{
136 WINDOW *win;
137 win = newwin(height, width, startx, starty);
138 wrefresh(win);
139 return win;
140}
141
142void print_digit(WINDOW *win, int digit)
143{
144 if (digit < 0) {
145 wattron(win, COLOR_PAIR(1));
146 wprintw(win, "%d", digit);
147 wattroff(win, COLOR_PAIR(1));
148 } else if (digit > 0) {
149 wattron(win, COLOR_PAIR(2));
150 wprintw(win, "+%d", digit);
151 wattroff(win, COLOR_PAIR(2));
152 } else {
153 wprintw(win, "0");
154 }
155}
156
157void print_digits(WINDOW *win, int first, int second)
158{
159 wprintw(win, "(");
160 print_digit(win, first);
161 wprintw(win, ", ");
162 print_digit(win, second);
163 wprintw(win, ")");
164}
165
166void print_headers(int line, char *desc, int value, int first, int second)
167{
168 wattron(header, A_BOLD);
169 mvwprintw(header, line, 4, "%s", desc);
170 wattroff(header, A_BOLD);
e05a35a6 171 mvwprintw(header, line, 16, "%d", value);
1fc22eb4
JD
172 wmove(header, line, 24);
173 print_digits(header, first, second);
174 wmove(header, line, 40);
175}
176
177void set_window_title(WINDOW *win, char *title)
178{
179 wattron(win, A_BOLD);
180 mvwprintw(win, 0, 1, title);
181 wattroff(win, A_BOLD);
182}
183
184void print_log(char *str)
185{
186 int i;
187 int current_line = 1;
188 int current_char = 1;
189 char *tmp, *tmp2;
190 /* rotate the line buffer */
191 if (nb_log_lines >= MAX_LOG_LINES) {
192 tmp = strndup(log_lines, MAX_LINE_LENGTH * MAX_LOG_LINES + MAX_LOG_LINES);
193 tmp2 = strchr(tmp, '\n');
194 memset(log_lines, '\0', strlen(log_lines));
195 strncat(log_lines, tmp2 + 1, strlen(tmp2) - 1);
196 log_lines[strlen(log_lines)] = '\n';
197 log_lines[strlen(log_lines)] = '\0';
198 free(tmp);
199 }
200 nb_log_lines++;
201
202 strncat(log_lines, str, MAX_LINE_LENGTH - 1);
203
204 if (nb_log_lines < MAX_LOG_LINES)
205 log_lines[strlen(log_lines)] = '\n';
206 log_lines[strlen(log_lines)] = '\0';
207
208 werase(status);
209 box(status, 0 , 0);
210 set_window_title(status, "Status");
211 for (i = 0; i < strlen(log_lines); i++) {
212 if (log_lines[i] == '\n') {
213 wmove(status, ++current_line, 1);
214 current_char = 1;
215 } else {
b093de8a
MB
216 mvwprintw(status, current_line, current_char++, "%c",
217 log_lines[i]);
1fc22eb4
JD
218 }
219 }
220 wrefresh(status);
221}
222
635dc837
JD
223int process_selected(struct processtop *process)
224{
225 int i;
226 struct processtop *stored_process;
227
228 for (i = 0; i < selected_processes->len; i++) {
229 stored_process = g_ptr_array_index(selected_processes, i);
32647247
JD
230 if (!stored_process)
231 return 0;
635dc837
JD
232 if (stored_process->tid == process->tid)
233 return 1;
234 }
235 return 0;
236}
237
238void update_selected_processes()
239{
240 if (process_selected(selected_process)) {
241 g_ptr_array_remove(selected_processes, selected_process);
242 print_log("Process removed");
243 } else {
244 g_ptr_array_add(selected_processes, selected_process);
245 print_log("Process added");
246 }
247}
248
1fc22eb4
JD
249void print_key(WINDOW *win, char *key, char *desc, int toggle)
250{
251 int pair;
252 if (toggle > 0)
253 pair = 4;
254 else
255 pair = 3;
256 wattron(win, COLOR_PAIR(pair));
257 wprintw(footer, "%s", key);
258 wattroff(win, COLOR_PAIR(pair));
259 wprintw(footer, ":%s", desc);
260}
261
262void update_footer()
263{
264 sem_wait(&update_display_sem);
265 werase(footer);
266 wmove(footer, 1, 1);
267 print_key(footer, "F2", "CPUtop ", current_view == cpu);
268 print_key(footer, "F3", "PerfTop ", current_view == perf);
e7be7d41 269 print_key(footer, "F4", "IOTop ", current_view == iostream);
1fc22eb4 270 print_key(footer, "Enter", "Details ", current_view == process_details);
635dc837 271 print_key(footer, "Space", "Highlight ", 0);
d33aae69
JD
272 print_key(footer, "q", "Quit ", 0);
273 print_key(footer, "P", "Pref ", 0);
1fc22eb4
JD
274 print_key(footer, "p", "Pause ", toggle_pause);
275
276 wrefresh(footer);
277 sem_post(&update_display_sem);
278}
279
280void basic_header()
281{
282 werase(header);
283 box(header, 0 , 0);
284 set_window_title(header, "Statistics for interval [gathering data...[");
285 wattron(header, A_BOLD);
286 mvwprintw(header, 1, 4, "CPUs");
e05a35a6 287 mvwprintw(header, 2, 4, "Threads");
dc8f04dd 288 mvwprintw(header, 3, 4, "FDs");
1fc22eb4
JD
289 wattroff(header, A_BOLD);
290 wrefresh(header);
291}
292
91be6bb5
JD
293struct tm format_timestamp(uint64_t timestamp)
294{
295 struct tm tm;
296 uint64_t ts_sec = 0, ts_nsec;
297 time_t time_s;
298
299 ts_nsec = timestamp;
300 ts_sec += ts_nsec / NSEC_PER_SEC;
301 ts_nsec = ts_nsec % NSEC_PER_SEC;
302
303 time_s = (time_t) ts_sec;
304
305 localtime_r(&time_s, &tm);
306
307 return tm;
308}
309
69362330
JD
310static void scale_unit(uint64_t bytes, char *ret)
311{
312 if (bytes >= 1000000000)
313 sprintf(ret, "%" PRIu64 "G", bytes/1000000000);
314 if (bytes >= 1000000)
315 sprintf(ret, "%" PRIu64 "M", bytes/1000000);
316 else if (bytes >= 1000)
317 sprintf(ret, "%" PRIu64 "K", bytes/1000);
318 else
319 sprintf(ret, "%" PRIu64, bytes);
320}
321uint64_t total_io()
322{
323 int i;
324 struct processtop *tmp;
325 uint64_t total = 0;
326
327 for (i = 0; i < data->process_table->len; i++) {
328 tmp = g_ptr_array_index(data->process_table, i);
329 total += tmp->fileread;
330 total += tmp->filewrite;
331 }
332
333 return total;
334}
335
1fc22eb4
JD
336void update_header()
337{
91be6bb5
JD
338 struct tm start, end;
339 uint64_t ts_nsec_start, ts_nsec_end;
69362330 340 char io[4];
91be6bb5
JD
341
342 ts_nsec_start = data->start % NSEC_PER_SEC;
343 start = format_timestamp(data->start);
344
345 ts_nsec_end = data->end % NSEC_PER_SEC;
346 end = format_timestamp(data->end);
347
1fc22eb4
JD
348 werase(header);
349 box(header, 0 , 0);
350 set_window_title(header, "Statistics for interval ");
351 wattron(header, A_BOLD);
91be6bb5
JD
352
353 wprintw(header, "[%02d:%02d:%02d.%09" PRIu64 ", %02d:%02d:%02d.%09" PRIu64 "[",
354 start.tm_hour, start.tm_min, start.tm_sec, ts_nsec_start,
355 end.tm_hour, end.tm_min, end.tm_sec, ts_nsec_end);
1fc22eb4
JD
356 mvwprintw(header, 1, 4, "CPUs");
357 wattroff(header, A_BOLD);
358 wprintw(header, "\t%d\t(max/cpu : %0.2f%)", data->cpu_table->len,
359 100.0/data->cpu_table->len);
e05a35a6 360 print_headers(2, "Threads", data->nbthreads, data->nbnewthreads,
1fc22eb4 361 -1*(data->nbdeadthreads));
dc8f04dd 362 print_headers(3, "FDs", data->nbfiles, data->nbnewfiles,
1fc22eb4 363 -1*(data->nbclosedfiles));
69362330
JD
364 scale_unit(total_io(), io);
365 mvwprintw(header, 3, 43, "%sB/sec", io);
1fc22eb4
JD
366 wrefresh(header);
367}
368
369gint sort_by_cpu_desc(gconstpointer p1, gconstpointer p2)
370{
371 struct processtop *n1 = *(struct processtop **)p1;
372 struct processtop *n2 = *(struct processtop **)p2;
373 unsigned long totaln1 = n1->totalcpunsec;
374 unsigned long totaln2 = n2->totalcpunsec;
375
376 if (totaln1 < totaln2)
377 return 1;
378 if (totaln1 == totaln2)
379 return 0;
380 return -1;
381}
382
3b15348c
JD
383gint sort_by_tid_desc(gconstpointer p1, gconstpointer p2)
384{
385 struct processtop *n1 = *(struct processtop **)p1;
386 struct processtop *n2 = *(struct processtop **)p2;
387 unsigned long totaln1 = n1->tid;
388 unsigned long totaln2 = n2->tid;
389
390 if (totaln1 < totaln2)
391 return 1;
392 if (totaln1 == totaln2)
393 return 0;
394 return -1;
395}
396
397gint sort_by_pid_desc(gconstpointer p1, gconstpointer p2)
398{
399 struct processtop *n1 = *(struct processtop **)p1;
400 struct processtop *n2 = *(struct processtop **)p2;
401 unsigned long totaln1 = n1->pid;
402 unsigned long totaln2 = n2->pid;
403
404 if (totaln1 < totaln2)
405 return 1;
406 if (totaln1 == totaln2)
407 return 0;
408 return -1;
409}
410
89f1e0d1
JD
411gint sort_by_process_read_desc(gconstpointer p1, gconstpointer p2)
412{
413 struct processtop *n1 = *(struct processtop **)p1;
414 struct processtop *n2 = *(struct processtop **)p2;
415 unsigned long totaln1 = n1->fileread;
416 unsigned long totaln2 = n2->fileread;
417
418 if (totaln1 < totaln2)
419 return 1;
420 if (totaln1 == totaln2)
421 return 0;
422 return -1;
423}
424
425gint sort_by_process_write_desc(gconstpointer p1, gconstpointer p2)
426{
427 struct processtop *n1 = *(struct processtop **)p1;
428 struct processtop *n2 = *(struct processtop **)p2;
429 unsigned long totaln1 = n1->filewrite;
430 unsigned long totaln2 = n2->filewrite;
431
432 if (totaln1 < totaln2)
433 return 1;
434 if (totaln1 == totaln2)
435 return 0;
436 return -1;
437}
438
439gint sort_by_process_total_desc(gconstpointer p1, gconstpointer p2)
440{
441 struct processtop *n1 = *(struct processtop **)p1;
442 struct processtop *n2 = *(struct processtop **)p2;
443 unsigned long totaln1 = n1->filewrite + n1->fileread;
444 unsigned long totaln2 = n2->filewrite + n2->fileread;
445
446 if (totaln1 < totaln2)
447 return 1;
448 if (totaln1 == totaln2)
449 return 0;
450 return -1;
451}
452
32647247
JD
453gint sort_by_file_read_desc(gconstpointer p1, gconstpointer p2)
454{
455 struct files *n1 = *(struct files **)p1;
456 struct files *n2 = *(struct files **)p2;
457 unsigned long totaln1;
458 unsigned long totaln2;
459
460 totaln1 = n1->read;
461 totaln2 = n2->read;
462
463 if (totaln1 < totaln2)
464 return 1;
465 if (totaln1 == totaln2)
466 return 0;
467 return -1;
468}
469
470gint sort_by_file_write_desc(gconstpointer p1, gconstpointer p2)
471{
472 struct files *n1 = *(struct files **)p1;
473 struct files *n2 = *(struct files **)p2;
474 unsigned long totaln1;
475 unsigned long totaln2;
476
477 totaln1 = n1->write;
478 totaln2 = n2->write;
479
480 if (totaln1 < totaln2)
481 return 1;
482 if (totaln1 == totaln2)
483 return 0;
484 return -1;
485}
486
487gint sort_by_file_fd_desc(gconstpointer p1, gconstpointer p2)
488{
489 struct files *n1 = *(struct files **)p1;
490 struct files *n2 = *(struct files **)p2;
491 unsigned long totaln1;
492 unsigned long totaln2;
493
494 totaln1 = n1->fd;
495 totaln2 = n2->fd;
496
497 if (totaln1 < totaln2)
498 return 1;
499 if (totaln1 == totaln2)
500 return 0;
501 return -1;
502}
503
1fc22eb4
JD
504gint sort_by_cpu_group_by_threads_desc(gconstpointer p1, gconstpointer p2)
505{
506 struct processtop *n1 = *(struct processtop **)p1;
507 struct processtop *n2 = *(struct processtop **)p2;
508 unsigned long totaln1 = n1->threadstotalcpunsec;
509 unsigned long totaln2 = n2->threadstotalcpunsec;
510
511 if (totaln1 < totaln2)
512 return 1;
513 if (totaln1 == totaln2)
514 return 0;
515 return -1;
516}
517
518void update_cputop_display()
519{
520 int i;
521 int header_offset = 2;
522 struct processtop *tmp;
523 unsigned long elapsed;
524 double maxcputime;
525 int nblinedisplayed = 0;
526 int current_line = 0;
527
528 elapsed = data->end - data->start;
529 maxcputime = elapsed * data->cpu_table->len / 100.0;
530
3b15348c
JD
531 if (cputopview[0].sort == 1)
532 g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
533 else if (cputopview[1].sort == 1)
534 g_ptr_array_sort(data->process_table, sort_by_pid_desc);
535 else if (cputopview[2].sort == 1)
536 g_ptr_array_sort(data->process_table, sort_by_tid_desc);
537 else if (cputopview[3].sort == 1)
538 g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
539 else
540 g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
1fc22eb4
JD
541
542 set_window_title(center, "CPU Top");
543 wattron(center, A_BOLD);
3b15348c
JD
544 mvwprintw(center, 1, 1, cputopview[0].title);
545 mvwprintw(center, 1, 12, cputopview[1].title);
546 mvwprintw(center, 1, 22, cputopview[2].title);
547 mvwprintw(center, 1, 32, cputopview[3].title);
1fc22eb4
JD
548 wattroff(center, A_BOLD);
549
dc8f04dd 550 max_center_lines = LINES - 5 - 7 - 1 - header_offset;
1fc22eb4
JD
551
552 /* iterate the process (thread) list */
553 for (i = list_offset; i < data->process_table->len &&
554 nblinedisplayed < max_center_lines; i++) {
555 tmp = g_ptr_array_index(data->process_table, i);
556
635dc837
JD
557 if (process_selected(tmp)) {
558 wattron(center, COLOR_PAIR(6));
559 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
560 }
1fc22eb4
JD
561 if (current_line == selected_line) {
562 selected_process = tmp;
1fc22eb4
JD
563 wattron(center, COLOR_PAIR(5));
564 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
565 }
566 /* CPU(%) */
567 mvwprintw(center, current_line + header_offset, 1, "%1.2f",
568 tmp->totalcpunsec / maxcputime);
569 /* TGID */
570 mvwprintw(center, current_line + header_offset, 12, "%d", tmp->pid);
571 /* PID */
572 mvwprintw(center, current_line + header_offset, 22, "%d", tmp->tid);
573 /* NAME */
574 mvwprintw(center, current_line + header_offset, 32, "%s", tmp->comm);
635dc837 575 wattroff(center, COLOR_PAIR(6));
1fc22eb4
JD
576 wattroff(center, COLOR_PAIR(5));
577 nblinedisplayed++;
578 current_line++;
579 }
580}
581
582gint sort_perf(gconstpointer p1, gconstpointer p2, gpointer key)
583{
584 struct processtop *n1 = *(struct processtop **) p1;
585 struct processtop *n2 = *(struct processtop **) p2;
586
587 struct perfcounter *tmp1, *tmp2;
588 unsigned long totaln2 = 0;
589 unsigned long totaln1 = 0;
590
591 if (!key)
592 return 0;
593
594 tmp1 = g_hash_table_lookup(n1->perf, key);
595 if (!tmp1)
596 totaln1 = 0;
597 else
598 totaln1 = tmp1->count;
599
600 tmp2 = g_hash_table_lookup(n2->perf, key);
601 if (!tmp2)
602 totaln2 = 0;
603 else
604 totaln2 = tmp2->count;
605
606 if (totaln1 < totaln2)
607 return 1;
608 if (totaln1 == totaln2) {
609 totaln1 = n1->tid;
610 totaln2 = n2->tid;
611 if (totaln1 < totaln2)
612 return 1;
613 return -1;
614 }
615 return -1;
616}
617
618void print_key_title(char *key, int line)
619{
620 wattron(center, A_BOLD);
621 mvwprintw(center, line, 1, "%s\t", key);
622 wattroff(center, A_BOLD);
623}
624
625void update_process_details()
626{
627 unsigned long elapsed;
628 double maxcputime;
d26643ed 629 struct processtop *tmp;
b093de8a
MB
630 struct files *file_tmp;
631 int i, j = 0;
69362330 632 char unit[4];
97514683 633 char filename_buf[COLS];
32647247 634 GPtrArray *newfilearray = g_ptr_array_new();
1fc22eb4
JD
635
636 set_window_title(center, "Process details");
637
638
d26643ed
JD
639 tmp = find_process_tid(data,
640 selected_process->tid,
641 selected_process->comm);
1fc22eb4
JD
642 elapsed = data->end - data->start;
643 maxcputime = elapsed * data->cpu_table->len / 100.0;
644
645 print_key_title("Name", 1);
d26643ed 646 wprintw(center, "%s", selected_process->comm);
1fc22eb4 647 print_key_title("TID", 2);
d26643ed 648 wprintw(center, "%d", selected_process->tid);
1fc22eb4
JD
649 if (!tmp) {
650 print_key_title("Does not exit at this time", 3);
651 return;
652 }
653
654 print_key_title("PID", 3);
655 wprintw(center, "%d", tmp->pid);
656 print_key_title("PPID", 4);
657 wprintw(center, "%d", tmp->ppid);
658 print_key_title("CPU", 5);
659 wprintw(center, "%1.2f %%", tmp->totalcpunsec/maxcputime);
b093de8a
MB
660
661 print_key_title("READ B/s", 6);
69362330
JD
662 scale_unit(tmp->fileread, unit);
663 wprintw(center, "%s", unit);
b093de8a
MB
664
665 print_key_title("WRITE B/s", 7);
69362330
JD
666 scale_unit(tmp->filewrite, unit);
667 wprintw(center, "%s", unit);
b093de8a 668
93d80d35
JD
669 wattron(center, A_BOLD);
670 mvwprintw(center, 8, 1, "FD");
69362330
JD
671 mvwprintw(center, 8, 10, "READ");
672 mvwprintw(center, 8, 17, "WRITE");
673 mvwprintw(center, 8, 24, "FILENAME");
93d80d35
JD
674 wattroff(center, A_BOLD);
675
32647247
JD
676 /*
677 * since the process_files_table array could contain NULL file structures,
678 * and that the positions inside the array is important (it is the FD), we
679 * need to create a temporary array that we can sort.
680 */
681 for (i = 0; i < tmp->process_files_table->len; i++) {
682 file_tmp = g_ptr_array_index(tmp->process_files_table, i);
683 if (file_tmp)
684 g_ptr_array_add(newfilearray, file_tmp);
685 }
686
687 if (fileview[0].sort == 1)
688 g_ptr_array_sort(newfilearray, sort_by_file_fd_desc);
689 else if (fileview[1].sort == 1)
690 g_ptr_array_sort(newfilearray, sort_by_file_read_desc);
691 else if (fileview[2].sort == 1)
692 g_ptr_array_sort(newfilearray, sort_by_file_write_desc);
693 else
694 g_ptr_array_sort(newfilearray, sort_by_file_read_desc);
695
696 for (i = selected_line; i < newfilearray->len &&
97514683 697 i < (selected_line + max_center_lines - 7); i++) {
32647247
JD
698 file_tmp = g_ptr_array_index(newfilearray, i);
699 if (!file_tmp)
700 continue;
701 mvwprintw(center, 9 + j, 1, "%d", file_tmp->fd);
702 scale_unit(file_tmp->read, unit);
703 mvwprintw(center, 9 + j, 10, "%s", unit);
704 scale_unit(file_tmp->write, unit);
705 mvwprintw(center, 9 + j, 17, "%s", unit);
706 snprintf(filename_buf, COLS - 25, "%s", file_tmp->name);
707 mvwprintw(center, 9 + j, 24, "%s", filename_buf);
708 j++;
b093de8a 709 }
32647247 710 g_ptr_array_free(newfilearray, TRUE);
1fc22eb4
JD
711}
712
713void update_perf()
714{
bb053abb 715 int i;
1fc22eb4
JD
716 int nblinedisplayed = 0;
717 int current_line = 0;
718 struct processtop *tmp;
719 int header_offset = 2;
720 int perf_row = 40;
721 struct perfcounter *perfn1, *perfn2;
1fc22eb4
JD
722 char *perf_key = NULL;
723 int value;
85db4618
JD
724 GHashTableIter iter;
725 gpointer key;
1fc22eb4
JD
726
727 set_window_title(center, "Perf Top");
728 wattron(center, A_BOLD);
729 mvwprintw(center, 1, 1, "PID");
730 mvwprintw(center, 1, 11, "TID");
731 mvwprintw(center, 1, 22, "NAME");
732
733 perf_row = 40;
0d91c12a 734 g_hash_table_iter_init(&iter, global_perf_liszt);
85db4618 735 while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) {
1fc22eb4 736 if (perfn1->visible) {
6419078d 737 /* + 5 to strip the "perf_" prefix */
1fc22eb4 738 mvwprintw(center, 1, perf_row, "%s",
6419078d 739 (char *) key + 5);
1fc22eb4
JD
740 perf_row += 20;
741 }
742 if (perfn1->sort) {
85db4618 743 perf_key = (char *) key;
1fc22eb4 744 }
1fc22eb4 745 }
85db4618 746
1fc22eb4
JD
747 wattroff(center, A_BOLD);
748
749 g_ptr_array_sort_with_data(data->process_table, sort_perf, perf_key);
85db4618 750
91be6bb5 751 for (i = 0; i < data->process_table->len &&
1fc22eb4 752 nblinedisplayed < max_center_lines; i++) {
1fc22eb4
JD
753 tmp = g_ptr_array_index(data->process_table, i);
754
635dc837
JD
755 if (process_selected(tmp)) {
756 wattron(center, COLOR_PAIR(6));
757 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
758 }
1fc22eb4
JD
759 if (current_line == selected_line) {
760 selected_process = tmp;
761 wattron(center, COLOR_PAIR(5));
762 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
763 }
764
765 mvwprintw(center, current_line + header_offset, 1, "%d", tmp->pid);
766 mvwprintw(center, current_line + header_offset, 11, "%d", tmp->tid);
767 mvwprintw(center, current_line + header_offset, 22, "%s", tmp->comm);
768
0d91c12a 769 g_hash_table_iter_init(&iter, global_perf_liszt);
1fc22eb4
JD
770
771 perf_row = 40;
85db4618 772 while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) {
1fc22eb4 773 if (perfn1->visible) {
85db4618 774 perfn2 = g_hash_table_lookup(tmp->perf, (char *) key);
1fc22eb4
JD
775 if (perfn2)
776 value = perfn2->count;
777 else
778 value = 0;
b093de8a
MB
779 mvwprintw(center, current_line + header_offset,
780 perf_row, "%d", value);
1fc22eb4
JD
781 perf_row += 20;
782 }
1fc22eb4
JD
783 }
784
635dc837 785 wattroff(center, COLOR_PAIR(6));
1fc22eb4
JD
786 wattroff(center, COLOR_PAIR(5));
787 nblinedisplayed++;
788 current_line++;
789 }
790}
791
1fc22eb4
JD
792void update_iostream()
793{
794 int i;
795 int header_offset = 2;
796 struct processtop *tmp;
797 int nblinedisplayed = 0;
798 int current_line = 0;
b093de8a 799 int total = 0;
69362330 800 char unit[4];
1fc22eb4
JD
801
802 set_window_title(center, "IO Top");
803 wattron(center, A_BOLD);
69362330
JD
804 mvwprintw(center, 1, 1, "PID");
805 mvwprintw(center, 1, 11, "TID");
806 mvwprintw(center, 1, 22, "NAME");
807 mvwprintw(center, 1, 40, "R (B/sec)");
808 mvwprintw(center, 1, 52, "W (B/sec)");
809 mvwprintw(center, 1, 64, "Total");
1fc22eb4
JD
810 wattroff(center, A_BOLD);
811
89f1e0d1
JD
812 if (iostreamtopview[0].sort == 1)
813 g_ptr_array_sort(data->process_table, sort_by_process_read_desc);
814 else if (iostreamtopview[1].sort == 1)
815 g_ptr_array_sort(data->process_table, sort_by_process_write_desc);
816 else if (iostreamtopview[2].sort == 1)
817 g_ptr_array_sort(data->process_table, sort_by_process_total_desc);
818 else
819 g_ptr_array_sort(data->process_table, sort_by_process_total_desc);
1fc22eb4
JD
820
821 for (i = list_offset; i < data->process_table->len &&
822 nblinedisplayed < max_center_lines; i++) {
823 tmp = g_ptr_array_index(data->process_table, i);
824
635dc837
JD
825 if (process_selected(tmp)) {
826 wattron(center, COLOR_PAIR(6));
827 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
828 }
1fc22eb4
JD
829 if (current_line == selected_line) {
830 selected_process = tmp;
1fc22eb4
JD
831 wattron(center, COLOR_PAIR(5));
832 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
833 }
69362330
JD
834 /* TGID */
835 mvwprintw(center, current_line + header_offset, 1, "%d", tmp->pid);
836 /* PID */
837 mvwprintw(center, current_line + header_offset, 11, "%d", tmp->tid);
838 /* NAME */
839 mvwprintw(center, current_line + header_offset, 22, "%s", tmp->comm);
b093de8a 840
1fc22eb4 841 /* READ (bytes/sec) */
69362330
JD
842 scale_unit(tmp->fileread, unit);
843 mvwprintw(center, current_line + header_offset, 40, "%s", unit);
1fc22eb4
JD
844
845 /* WRITE (bytes/sec) */
69362330
JD
846 scale_unit(tmp->filewrite, unit);
847 mvwprintw(center, current_line + header_offset, 52, "%s", unit);
1fc22eb4
JD
848
849 /* TOTAL STREAM */
b093de8a
MB
850 total = tmp->totalfileread + tmp->totalfilewrite;
851
69362330
JD
852 scale_unit(total, unit);
853 mvwprintw(center, current_line + header_offset, 64, "%s", unit);
b093de8a 854
635dc837 855 wattroff(center, COLOR_PAIR(6));
1fc22eb4
JD
856 wattroff(center, COLOR_PAIR(5));
857 nblinedisplayed++;
858 current_line++;
859 }
860}
861
862void update_current_view()
863{
864 sem_wait(&update_display_sem);
865 if (!data)
866 return;
867 update_header();
868
869 werase(center);
870 box(center, 0, 0);
871 switch (current_view) {
872 case cpu:
873 update_cputop_display();
874 break;
875 case perf:
876 update_perf();
877 break;
878 case process_details:
879 update_process_details();
880 break;
1fc22eb4
JD
881 case iostream:
882 update_iostream();
883 break;
884 case tree:
885 update_cputop_display();
886 break;
887 default:
888 break;
889 }
890 update_panels();
891 doupdate();
892 sem_post(&update_display_sem);
893}
894
32647247
JD
895void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_sort)
896{
897 int i;
898 int size;
899
900 if (!data)
901 return;
902 if (pref_panel_window) {
903 del_panel(pref_panel);
904 delwin(pref_panel_window);
905 }
906 size = 3;
907
908 pref_panel_window = create_window(size + 2, 30, 10, 10);
909 pref_panel = new_panel(pref_panel_window);
910
911 werase(pref_panel_window);
912 box(pref_panel_window, 0 , 0);
913 set_window_title(pref_panel_window, "Process Detail Preferences ");
914 wattron(pref_panel_window, A_BOLD);
915 mvwprintw(pref_panel_window, size + 1, 1,
d2fd8c70 916 " 's' : sort, space : toggle");
32647247
JD
917 wattroff(pref_panel_window, A_BOLD);
918
919 if (*line_selected > (size - 1))
920 *line_selected = size - 1;
921 if (toggle_sort == 1) {
922 if (fileview[*line_selected].sort == 1)
923 fileview[*line_selected].reverse = 1;
924 for (i = 0; i < size; i++)
925 fileview[i].sort = 0;
926 fileview[*line_selected].sort = 1;
927 update_current_view();
928 }
929
930 for (i = 0; i < size; i++) {
931 if (i == *line_selected) {
932 wattron(pref_panel_window, COLOR_PAIR(5));
933 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
934 }
935 if (fileview[i].sort == 1)
936 wattron(pref_panel_window, A_BOLD);
d33aae69 937 mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
32647247
JD
938 fileview[i].title);
939 wattroff(pref_panel_window, A_BOLD);
940 wattroff(pref_panel_window, COLOR_PAIR(5));
941
942 }
943 update_panels();
944 doupdate();
945}
946
89f1e0d1
JD
947void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort)
948{
949 int i;
950 int size;
951
952 if (!data)
953 return;
954 if (pref_panel_window) {
955 del_panel(pref_panel);
956 delwin(pref_panel_window);
957 }
958 size = 3;
959
960 pref_panel_window = create_window(size + 2, 30, 10, 10);
961 pref_panel = new_panel(pref_panel_window);
962
963 werase(pref_panel_window);
964 box(pref_panel_window, 0 , 0);
965 set_window_title(pref_panel_window, "IOTop Preferences ");
966 wattron(pref_panel_window, A_BOLD);
967 mvwprintw(pref_panel_window, size + 1, 1,
d2fd8c70 968 " 's' : sort, space : toggle");
89f1e0d1
JD
969 wattroff(pref_panel_window, A_BOLD);
970
971 if (*line_selected > (size - 1))
972 *line_selected = size - 1;
973 if (toggle_sort == 1) {
974 if (iostreamtopview[*line_selected].sort == 1)
975 iostreamtopview[*line_selected].reverse = 1;
976 for (i = 0; i < size; i++)
977 iostreamtopview[i].sort = 0;
978 iostreamtopview[*line_selected].sort = 1;
979 update_current_view();
980 }
981
982 for (i = 0; i < size; i++) {
983 if (i == *line_selected) {
984 wattron(pref_panel_window, COLOR_PAIR(5));
985 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
986 }
987 if (iostreamtopview[i].sort == 1)
988 wattron(pref_panel_window, A_BOLD);
d33aae69 989 mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
89f1e0d1
JD
990 iostreamtopview[i].title);
991 wattroff(pref_panel_window, A_BOLD);
992 wattroff(pref_panel_window, COLOR_PAIR(5));
993
994 }
995 update_panels();
996 doupdate();
997}
998
3b15348c
JD
999void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort)
1000{
1001 int i;
1002 int size;
1003
1004 if (!data)
1005 return;
1006 if (pref_panel_window) {
1007 del_panel(pref_panel);
1008 delwin(pref_panel_window);
1009 }
1010 size = 4;
1011
1012 pref_panel_window = create_window(size + 2, 30, 10, 10);
1013 pref_panel = new_panel(pref_panel_window);
1014
1015 werase(pref_panel_window);
1016 box(pref_panel_window, 0 , 0);
1017 set_window_title(pref_panel_window, "CPUTop Preferences ");
1018 wattron(pref_panel_window, A_BOLD);
1019 mvwprintw(pref_panel_window, size + 1, 1,
d2fd8c70 1020 " 's' : sort, space : toggle");
3b15348c
JD
1021 wattroff(pref_panel_window, A_BOLD);
1022
89f1e0d1
JD
1023 if (*line_selected > (size - 1))
1024 *line_selected = size - 1;
3b15348c
JD
1025 if (toggle_sort == 1) {
1026 /* special case, we don't support sorting by procname for now */
1027 if (*line_selected != 3) {
1028 if (cputopview[*line_selected].sort == 1)
1029 cputopview[*line_selected].reverse = 1;
89f1e0d1 1030 for (i = 0; i < size; i++)
3b15348c
JD
1031 cputopview[i].sort = 0;
1032 cputopview[*line_selected].sort = 1;
1033 update_current_view();
1034 }
1035 }
1036
89f1e0d1 1037 for (i = 0; i < size; i++) {
3b15348c
JD
1038 if (i == *line_selected) {
1039 wattron(pref_panel_window, COLOR_PAIR(5));
1040 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
1041 }
1042 if (cputopview[i].sort == 1)
1043 wattron(pref_panel_window, A_BOLD);
d33aae69 1044 mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
3b15348c
JD
1045 cputopview[i].title);
1046 wattroff(pref_panel_window, A_BOLD);
1047 wattroff(pref_panel_window, COLOR_PAIR(5));
1048
1049 }
1050 update_panels();
1051 doupdate();
1052}
1053
1054void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort)
1fc22eb4 1055{
1e05f0ae
JD
1056 int i;
1057 struct perfcounter *perf;
1058 GList *perflist;
1fc22eb4 1059 int size;
1e05f0ae 1060
1fc22eb4
JD
1061 if (!data)
1062 return;
0d91c12a
JD
1063 if (pref_panel_window) {
1064 del_panel(pref_panel);
1065 delwin(pref_panel_window);
1fc22eb4 1066 }
0d91c12a 1067 size = g_hash_table_size(global_perf_liszt);
1e05f0ae 1068
0d91c12a
JD
1069 pref_panel_window = create_window(size + 2, 30, 10, 10);
1070 pref_panel = new_panel(pref_panel_window);
1fc22eb4 1071
0d91c12a
JD
1072 werase(pref_panel_window);
1073 box(pref_panel_window, 0 , 0);
1074 set_window_title(pref_panel_window, "Perf Preferences ");
1075 wattron(pref_panel_window, A_BOLD);
1076 mvwprintw(pref_panel_window, g_hash_table_size(global_perf_liszt) + 1, 1,
d2fd8c70 1077 " 's' : sort, space : toggle");
0d91c12a 1078 wattroff(pref_panel_window, A_BOLD);
1fc22eb4
JD
1079
1080 if (toggle_sort == 1) {
1081 i = 0;
0d91c12a 1082 perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt));
1fc22eb4 1083 while (perflist) {
0d91c12a 1084 perf = g_hash_table_lookup(global_perf_liszt, perflist->data);
3b15348c 1085 if (i != *line_selected)
1fc22eb4
JD
1086 perf->sort = 0;
1087 else
1088 perf->sort = 1;
1089 i++;
1090 perflist = g_list_next(perflist);
1091 }
1092 update_current_view();
1093 }
1094
1095 i = 0;
0d91c12a 1096 perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt));
1fc22eb4 1097 while (perflist) {
0d91c12a 1098 perf = g_hash_table_lookup(global_perf_liszt, perflist->data);
3b15348c 1099 if (i == *line_selected && toggle_view == 1) {
1fc22eb4
JD
1100 perf->visible = perf->visible == 1 ? 0:1;
1101 update_current_view();
1102 }
3b15348c 1103 if (i == *line_selected) {
0d91c12a
JD
1104 wattron(pref_panel_window, COLOR_PAIR(5));
1105 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
1fc22eb4
JD
1106 }
1107 if (perf->sort == 1)
0d91c12a
JD
1108 wattron(pref_panel_window, A_BOLD);
1109 mvwprintw(pref_panel_window, i + 1, 1, "[%c] %s",
1fc22eb4 1110 perf->visible == 1 ? 'x' : ' ',
b8a1df45 1111 (char *) perflist->data + 5);
0d91c12a
JD
1112 wattroff(pref_panel_window, A_BOLD);
1113 wattroff(pref_panel_window, COLOR_PAIR(5));
1fc22eb4
JD
1114 i++;
1115 perflist = g_list_next(perflist);
1116 }
1117 update_panels();
1118 doupdate();
1119}
1120
3b15348c 1121int update_preference_panel(int *line_selected, int toggle_view, int toggle_sort)
1fc22eb4 1122{
1e05f0ae
JD
1123 int ret = 0;
1124
0d91c12a
JD
1125 switch(current_view) {
1126 case perf:
3b15348c
JD
1127 update_perf_pref(line_selected, toggle_view, toggle_sort);
1128 break;
1129 case cpu:
1130 update_cpu_pref(line_selected, toggle_view, toggle_sort);
0d91c12a 1131 break;
89f1e0d1
JD
1132 case iostream:
1133 update_iostream_pref(line_selected, toggle_view, toggle_sort);
1134 break;
32647247
JD
1135 case process_details:
1136 update_process_detail_pref(line_selected, toggle_view, toggle_sort);
1137 break;
0d91c12a 1138 default:
1e05f0ae 1139 ret = -1;
0d91c12a
JD
1140 break;
1141 }
1e05f0ae
JD
1142
1143 return ret;
0d91c12a
JD
1144}
1145
1146void toggle_pref_panel(void)
1147{
1e05f0ae
JD
1148 int ret;
1149
0d91c12a
JD
1150 if (pref_panel_visible) {
1151 hide_panel(pref_panel);
1152 pref_panel_visible = 0;
1fc22eb4 1153 } else {
3b15348c 1154 ret = update_preference_panel(&pref_line_selected, 0, 0);
1e05f0ae
JD
1155 if (ret < 0)
1156 return;
0d91c12a
JD
1157 show_panel(pref_panel);
1158 pref_panel_visible = 1;
1fc22eb4
JD
1159 }
1160 update_panels();
1161 doupdate();
1162}
1163
1164void display(unsigned int index)
1165{
1166 last_display_index = index;
1167 currently_displayed_index = index;
1168 data = g_ptr_array_index(copies, index);
1169 if (!data)
1170 return;
1171 max_elements = data->process_table->len;
1172 update_current_view();
1173 update_footer();
1174 update_panels();
1175 doupdate();
1176}
1177
1178void pause_display()
1179{
1180 toggle_pause = 1;
1181 print_log("Pause");
1182 sem_wait(&pause_sem);
1183}
1184
1185void resume_display()
1186{
1187 toggle_pause = -1;
1188 print_log("Resume");
1189 sem_post(&pause_sem);
1190}
1191
1192void *handle_keyboard(void *p)
1193{
1194 int ch;
1195 while((ch = getch())) {
1196 switch(ch) {
1197 /* Move the cursor and scroll */
8c05e516 1198 case 'j':
1fc22eb4 1199 case KEY_DOWN:
0d91c12a 1200 if (pref_panel_visible) {
3b15348c
JD
1201 pref_line_selected++;
1202 update_preference_panel(&pref_line_selected, 0, 0);
1fc22eb4
JD
1203 } else {
1204 if (selected_line < (max_center_lines - 1) &&
1205 selected_line < max_elements - 1) {
1206 selected_line++;
1207 selected_in_list++;
1208 } else if (selected_in_list < (max_elements - 1)
1209 && (list_offset < (max_elements - max_center_lines))) {
1210 selected_in_list++;
1211 list_offset++;
1212 }
1213 update_current_view();
1214 }
1215 break;
1216 case KEY_NPAGE:
1fc22eb4 1217 break;
8c05e516 1218 case 'k':
1fc22eb4 1219 case KEY_UP:
0d91c12a 1220 if (pref_panel_visible) {
3b15348c
JD
1221 if (pref_line_selected > 0)
1222 pref_line_selected--;
1223 update_preference_panel(&pref_line_selected, 0, 0);
1fc22eb4
JD
1224 } else {
1225 if (selected_line > 0) {
1226 selected_line--;
1227 selected_in_list--;
1228 } else if (selected_in_list > 0 && list_offset > 0) {
1229 selected_in_list--;
1230 list_offset--;
1231 }
1232 update_current_view();
1233 }
1234 break;
1235 case KEY_PPAGE:
1fc22eb4
JD
1236 break;
1237
1238 /* Navigate the history with arrows */
1239 case KEY_LEFT:
1240 if (currently_displayed_index > 0) {
1241 currently_displayed_index--;
1242 print_log("Going back in time");
1243 } else {
1244 print_log("Cannot rewind, last data is already displayed");
1245 }
1246 data = g_ptr_array_index(copies, currently_displayed_index);
1247 max_elements = data->process_table->len;
1248
1249 /* we force to pause the display when moving in time */
1250 if (toggle_pause < 0)
1251 pause_display();
1252
1253 update_current_view();
1254 update_footer();
1255 break;
1256 case KEY_RIGHT:
1257 if (currently_displayed_index < last_display_index) {
1258 currently_displayed_index++;
1259 print_log("Going forward in time");
1260 data = g_ptr_array_index(copies, currently_displayed_index);
1261 max_elements = data->process_table->len;
1262 update_current_view();
1263 update_footer();
1264 } else {
1265 print_log("Manually moving forward");
1266 sem_post(&timer);
1267 /* we force to resume the refresh when moving forward */
1268 if (toggle_pause > 0)
1269 resume_display();
1270 }
1271
1272 break;
1273 case ' ':
0d91c12a 1274 if (pref_panel_visible) {
3b15348c 1275 update_preference_panel(&pref_line_selected, 1, 0);
635dc837
JD
1276 } else {
1277 update_selected_processes();
1278 update_current_view();
1279 }
1fc22eb4
JD
1280 break;
1281 case 's':
0d91c12a 1282 if (pref_panel_visible)
3b15348c 1283 update_preference_panel(&pref_line_selected, 0, 1);
1fc22eb4
JD
1284 break;
1285
1286 case 13: /* FIXME : KEY_ENTER ?? */
d2fd8c70
JD
1287 if (pref_panel_visible)
1288 break;
041aa219
JD
1289 if (current_view != process_details) {
1290 previous_view = current_view;
1fc22eb4 1291 current_view = process_details;
041aa219
JD
1292 } else {
1293 current_view = previous_view;
1294 previous_view = process_details;
1fc22eb4
JD
1295 }
1296 update_current_view();
1297 break;
1298
1299 case KEY_F(1):
3b15348c
JD
1300 if (pref_panel_visible)
1301 toggle_pref_panel();
1fc22eb4 1302 current_view = cpu;
af54ebcf 1303 selected_line = 0;
1fc22eb4
JD
1304 update_current_view();
1305 break;
1306 case KEY_F(2):
3b15348c
JD
1307 if (pref_panel_visible)
1308 toggle_pref_panel();
1fc22eb4 1309 current_view = cpu;
af54ebcf 1310 selected_line = 0;
1fc22eb4
JD
1311 update_current_view();
1312 break;
1313 case KEY_F(3):
3b15348c
JD
1314 if (pref_panel_visible)
1315 toggle_pref_panel();
1fc22eb4 1316 current_view = perf;
af54ebcf 1317 selected_line = 0;
1fc22eb4
JD
1318 update_current_view();
1319 break;
1320 case KEY_F(4):
3b15348c
JD
1321 if (pref_panel_visible)
1322 toggle_pref_panel();
1fc22eb4 1323 current_view = iostream;
af54ebcf 1324 selected_line = 0;
1fc22eb4
JD
1325 update_current_view();
1326 break;
1327 case KEY_F(10):
1328 case 'q':
1329 reset_ncurses();
1330 break;
1331 case 't':
1332 toggle_threads *= -1;
1333 update_current_view();
1334 break;
1335 case 'p':
1336 if (toggle_pause < 0) {
1337 pause_display();
1338 } else {
1339 resume_display();
1340 }
1341 break;
1342 case 'P':
0d91c12a 1343 toggle_pref_panel();
1fc22eb4 1344 break;
d2fd8c70
JD
1345 /* ESCAPE, but slow to process, don't know why */
1346 case 27:
1347 if (pref_panel_visible)
1348 toggle_pref_panel();
1349 else if (current_view == process_details) {
1350 current_view = previous_view;
1351 previous_view = process_details;
1352 }
1353 update_current_view();
1354 break;
1fc22eb4 1355 default:
b093de8a
MB
1356 if (data)
1357 update_current_view();
1fc22eb4
JD
1358 break;
1359 }
1360 update_footer();
1361 }
1362 return NULL;
1363}
1364
89f1e0d1
JD
1365void init_view_headers()
1366{
1367 cputopview[0].title = strdup("CPU(%)");
1368 cputopview[0].sort = 1;
1369 cputopview[1].title = strdup("TGID");
1370 cputopview[2].title = strdup("PID");
1371 cputopview[3].title = strdup("NAME");
1372
1373 iostreamtopview[0].title = strdup("R (B/sec)");
1374 iostreamtopview[1].title = strdup("W (B/sec)");
1375 iostreamtopview[2].title = strdup("Total (B)");
1376 iostreamtopview[2].sort = 1;
32647247
JD
1377
1378 fileview[0].title = strdup("FD");
1379 fileview[1].title = strdup("READ");
1380 fileview[1].sort = 1;
1381 fileview[2].title = strdup("WRITE");
89f1e0d1
JD
1382}
1383
1fc22eb4
JD
1384void init_ncurses()
1385{
635dc837 1386 selected_processes = g_ptr_array_new();
1fc22eb4 1387 sem_init(&update_display_sem, 0, 1);
89f1e0d1 1388 init_view_headers();
1fc22eb4
JD
1389 init_screen();
1390
dc8f04dd
JD
1391 header = create_window(5, COLS - 1, 0, 0);
1392 center = create_window(LINES - 5 - 7, COLS - 1, 5, 0);
1fc22eb4
JD
1393 status = create_window(MAX_LOG_LINES + 2, COLS - 1, LINES - 7, 0);
1394 footer = create_window(1, COLS - 1, LINES - 1, 0);
1395
1396 print_log("Starting display");
1397
1398 main_panel = new_panel(center);
1fc22eb4
JD
1399
1400 current_view = cpu;
1401
1402 basic_header();
1403 update_footer();
1404
1405 pthread_create(&keyboard_thread, NULL, handle_keyboard, (void *)NULL);
1406}
This page took 0.087169 seconds and 4 git commands to generate.