underline for sorted column in process detail view
[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{
84c36c18
JD
240 int i;
241 struct processtop *stored_process;
242
635dc837 243 if (process_selected(selected_process)) {
84c36c18
JD
244 for (i = 0; i < selected_processes->len; i++) {
245 stored_process = g_ptr_array_index(selected_processes, i);
246 if (!stored_process)
247 return;
248 if (stored_process->tid == selected_process->tid)
249 g_ptr_array_remove(selected_processes,
250 stored_process);
251 print_log("Process removed");
252 }
635dc837 253 } else {
84c36c18 254 g_ptr_array_add(selected_processes, selected_process);
635dc837
JD
255 print_log("Process added");
256 }
257}
258
1fc22eb4
JD
259void print_key(WINDOW *win, char *key, char *desc, int toggle)
260{
261 int pair;
262 if (toggle > 0)
263 pair = 4;
264 else
265 pair = 3;
266 wattron(win, COLOR_PAIR(pair));
267 wprintw(footer, "%s", key);
268 wattroff(win, COLOR_PAIR(pair));
269 wprintw(footer, ":%s", desc);
270}
271
272void update_footer()
273{
274 sem_wait(&update_display_sem);
275 werase(footer);
276 wmove(footer, 1, 1);
277 print_key(footer, "F2", "CPUtop ", current_view == cpu);
278 print_key(footer, "F3", "PerfTop ", current_view == perf);
e7be7d41 279 print_key(footer, "F4", "IOTop ", current_view == iostream);
1fc22eb4 280 print_key(footer, "Enter", "Details ", current_view == process_details);
635dc837 281 print_key(footer, "Space", "Highlight ", 0);
d33aae69 282 print_key(footer, "q", "Quit ", 0);
f9ff6939 283 print_key(footer, "r", "Pref ", 0);
1fc22eb4
JD
284 print_key(footer, "p", "Pause ", toggle_pause);
285
286 wrefresh(footer);
287 sem_post(&update_display_sem);
288}
289
290void basic_header()
291{
292 werase(header);
293 box(header, 0 , 0);
294 set_window_title(header, "Statistics for interval [gathering data...[");
295 wattron(header, A_BOLD);
296 mvwprintw(header, 1, 4, "CPUs");
e05a35a6 297 mvwprintw(header, 2, 4, "Threads");
dc8f04dd 298 mvwprintw(header, 3, 4, "FDs");
1fc22eb4
JD
299 wattroff(header, A_BOLD);
300 wrefresh(header);
301}
302
91be6bb5
JD
303struct tm format_timestamp(uint64_t timestamp)
304{
305 struct tm tm;
306 uint64_t ts_sec = 0, ts_nsec;
307 time_t time_s;
308
309 ts_nsec = timestamp;
310 ts_sec += ts_nsec / NSEC_PER_SEC;
311 ts_nsec = ts_nsec % NSEC_PER_SEC;
312
313 time_s = (time_t) ts_sec;
314
315 localtime_r(&time_s, &tm);
316
317 return tm;
318}
319
69362330
JD
320static void scale_unit(uint64_t bytes, char *ret)
321{
322 if (bytes >= 1000000000)
323 sprintf(ret, "%" PRIu64 "G", bytes/1000000000);
324 if (bytes >= 1000000)
325 sprintf(ret, "%" PRIu64 "M", bytes/1000000);
326 else if (bytes >= 1000)
327 sprintf(ret, "%" PRIu64 "K", bytes/1000);
328 else
329 sprintf(ret, "%" PRIu64, bytes);
330}
331uint64_t total_io()
332{
333 int i;
334 struct processtop *tmp;
335 uint64_t total = 0;
336
337 for (i = 0; i < data->process_table->len; i++) {
338 tmp = g_ptr_array_index(data->process_table, i);
339 total += tmp->fileread;
340 total += tmp->filewrite;
341 }
342
343 return total;
344}
345
1fc22eb4
JD
346void update_header()
347{
91be6bb5
JD
348 struct tm start, end;
349 uint64_t ts_nsec_start, ts_nsec_end;
69362330 350 char io[4];
91be6bb5
JD
351
352 ts_nsec_start = data->start % NSEC_PER_SEC;
353 start = format_timestamp(data->start);
354
355 ts_nsec_end = data->end % NSEC_PER_SEC;
356 end = format_timestamp(data->end);
357
1fc22eb4
JD
358 werase(header);
359 box(header, 0 , 0);
360 set_window_title(header, "Statistics for interval ");
361 wattron(header, A_BOLD);
91be6bb5
JD
362
363 wprintw(header, "[%02d:%02d:%02d.%09" PRIu64 ", %02d:%02d:%02d.%09" PRIu64 "[",
364 start.tm_hour, start.tm_min, start.tm_sec, ts_nsec_start,
365 end.tm_hour, end.tm_min, end.tm_sec, ts_nsec_end);
1fc22eb4
JD
366 mvwprintw(header, 1, 4, "CPUs");
367 wattroff(header, A_BOLD);
368 wprintw(header, "\t%d\t(max/cpu : %0.2f%)", data->cpu_table->len,
369 100.0/data->cpu_table->len);
e05a35a6 370 print_headers(2, "Threads", data->nbthreads, data->nbnewthreads,
1fc22eb4 371 -1*(data->nbdeadthreads));
dc8f04dd 372 print_headers(3, "FDs", data->nbfiles, data->nbnewfiles,
1fc22eb4 373 -1*(data->nbclosedfiles));
69362330
JD
374 scale_unit(total_io(), io);
375 mvwprintw(header, 3, 43, "%sB/sec", io);
1fc22eb4
JD
376 wrefresh(header);
377}
378
379gint sort_by_cpu_desc(gconstpointer p1, gconstpointer p2)
380{
381 struct processtop *n1 = *(struct processtop **)p1;
382 struct processtop *n2 = *(struct processtop **)p2;
383 unsigned long totaln1 = n1->totalcpunsec;
384 unsigned long totaln2 = n2->totalcpunsec;
385
386 if (totaln1 < totaln2)
387 return 1;
388 if (totaln1 == totaln2)
389 return 0;
390 return -1;
391}
392
3b15348c
JD
393gint sort_by_tid_desc(gconstpointer p1, gconstpointer p2)
394{
395 struct processtop *n1 = *(struct processtop **)p1;
396 struct processtop *n2 = *(struct processtop **)p2;
397 unsigned long totaln1 = n1->tid;
398 unsigned long totaln2 = n2->tid;
399
400 if (totaln1 < totaln2)
401 return 1;
402 if (totaln1 == totaln2)
403 return 0;
404 return -1;
405}
406
407gint sort_by_pid_desc(gconstpointer p1, gconstpointer p2)
408{
409 struct processtop *n1 = *(struct processtop **)p1;
410 struct processtop *n2 = *(struct processtop **)p2;
411 unsigned long totaln1 = n1->pid;
412 unsigned long totaln2 = n2->pid;
413
414 if (totaln1 < totaln2)
415 return 1;
416 if (totaln1 == totaln2)
417 return 0;
418 return -1;
419}
420
89f1e0d1
JD
421gint sort_by_process_read_desc(gconstpointer p1, gconstpointer p2)
422{
423 struct processtop *n1 = *(struct processtop **)p1;
424 struct processtop *n2 = *(struct processtop **)p2;
425 unsigned long totaln1 = n1->fileread;
426 unsigned long totaln2 = n2->fileread;
427
428 if (totaln1 < totaln2)
429 return 1;
430 if (totaln1 == totaln2)
431 return 0;
432 return -1;
433}
434
435gint sort_by_process_write_desc(gconstpointer p1, gconstpointer p2)
436{
437 struct processtop *n1 = *(struct processtop **)p1;
438 struct processtop *n2 = *(struct processtop **)p2;
439 unsigned long totaln1 = n1->filewrite;
440 unsigned long totaln2 = n2->filewrite;
441
442 if (totaln1 < totaln2)
443 return 1;
444 if (totaln1 == totaln2)
445 return 0;
446 return -1;
447}
448
449gint sort_by_process_total_desc(gconstpointer p1, gconstpointer p2)
450{
451 struct processtop *n1 = *(struct processtop **)p1;
452 struct processtop *n2 = *(struct processtop **)p2;
41f5890b
JD
453 unsigned long totaln1 = n1->totalfilewrite + n1->totalfileread;
454 unsigned long totaln2 = n2->totalfilewrite + n2->totalfileread;
89f1e0d1
JD
455
456 if (totaln1 < totaln2)
457 return 1;
458 if (totaln1 == totaln2)
459 return 0;
460 return -1;
461}
462
32647247
JD
463gint sort_by_file_read_desc(gconstpointer p1, gconstpointer p2)
464{
465 struct files *n1 = *(struct files **)p1;
466 struct files *n2 = *(struct files **)p2;
467 unsigned long totaln1;
468 unsigned long totaln2;
469
470 totaln1 = n1->read;
471 totaln2 = n2->read;
472
473 if (totaln1 < totaln2)
474 return 1;
475 if (totaln1 == totaln2)
476 return 0;
477 return -1;
478}
479
480gint sort_by_file_write_desc(gconstpointer p1, gconstpointer p2)
481{
482 struct files *n1 = *(struct files **)p1;
483 struct files *n2 = *(struct files **)p2;
484 unsigned long totaln1;
485 unsigned long totaln2;
486
487 totaln1 = n1->write;
488 totaln2 = n2->write;
489
490 if (totaln1 < totaln2)
491 return 1;
492 if (totaln1 == totaln2)
493 return 0;
494 return -1;
495}
496
497gint sort_by_file_fd_desc(gconstpointer p1, gconstpointer p2)
498{
499 struct files *n1 = *(struct files **)p1;
500 struct files *n2 = *(struct files **)p2;
501 unsigned long totaln1;
502 unsigned long totaln2;
503
504 totaln1 = n1->fd;
505 totaln2 = n2->fd;
506
507 if (totaln1 < totaln2)
508 return 1;
509 if (totaln1 == totaln2)
510 return 0;
511 return -1;
512}
513
1fc22eb4
JD
514gint sort_by_cpu_group_by_threads_desc(gconstpointer p1, gconstpointer p2)
515{
516 struct processtop *n1 = *(struct processtop **)p1;
517 struct processtop *n2 = *(struct processtop **)p2;
518 unsigned long totaln1 = n1->threadstotalcpunsec;
519 unsigned long totaln2 = n2->threadstotalcpunsec;
520
521 if (totaln1 < totaln2)
522 return 1;
523 if (totaln1 == totaln2)
524 return 0;
525 return -1;
526}
527
528void update_cputop_display()
529{
530 int i;
531 int header_offset = 2;
532 struct processtop *tmp;
533 unsigned long elapsed;
534 double maxcputime;
535 int nblinedisplayed = 0;
536 int current_line = 0;
844d1c9c 537 int column;
1fc22eb4
JD
538
539 elapsed = data->end - data->start;
540 maxcputime = elapsed * data->cpu_table->len / 100.0;
541
3b15348c
JD
542 if (cputopview[0].sort == 1)
543 g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
544 else if (cputopview[1].sort == 1)
545 g_ptr_array_sort(data->process_table, sort_by_pid_desc);
546 else if (cputopview[2].sort == 1)
547 g_ptr_array_sort(data->process_table, sort_by_tid_desc);
548 else if (cputopview[3].sort == 1)
549 g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
550 else
551 g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
1fc22eb4
JD
552
553 set_window_title(center, "CPU Top");
554 wattron(center, A_BOLD);
844d1c9c
JD
555 column = 1;
556 for (i = 0; i < 4; i++) {
557 if (cputopview[i].sort)
558 wattron(center, A_UNDERLINE);
559 mvwprintw(center, 1, column, cputopview[i].title);
560 wattroff(center, A_UNDERLINE);
561 column += 10;
562 }
1fc22eb4
JD
563 wattroff(center, A_BOLD);
564
dc8f04dd 565 max_center_lines = LINES - 5 - 7 - 1 - header_offset;
1fc22eb4
JD
566
567 /* iterate the process (thread) list */
568 for (i = list_offset; i < data->process_table->len &&
569 nblinedisplayed < max_center_lines; i++) {
570 tmp = g_ptr_array_index(data->process_table, i);
571
635dc837
JD
572 if (process_selected(tmp)) {
573 wattron(center, COLOR_PAIR(6));
574 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
575 }
1fc22eb4
JD
576 if (current_line == selected_line) {
577 selected_process = tmp;
1fc22eb4
JD
578 wattron(center, COLOR_PAIR(5));
579 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
580 }
581 /* CPU(%) */
582 mvwprintw(center, current_line + header_offset, 1, "%1.2f",
583 tmp->totalcpunsec / maxcputime);
584 /* TGID */
844d1c9c 585 mvwprintw(center, current_line + header_offset, 11, "%d", tmp->pid);
1fc22eb4 586 /* PID */
844d1c9c 587 mvwprintw(center, current_line + header_offset, 21, "%d", tmp->tid);
1fc22eb4 588 /* NAME */
844d1c9c 589 mvwprintw(center, current_line + header_offset, 31, "%s", tmp->comm);
635dc837 590 wattroff(center, COLOR_PAIR(6));
1fc22eb4
JD
591 wattroff(center, COLOR_PAIR(5));
592 nblinedisplayed++;
593 current_line++;
594 }
595}
596
597gint sort_perf(gconstpointer p1, gconstpointer p2, gpointer key)
598{
599 struct processtop *n1 = *(struct processtop **) p1;
600 struct processtop *n2 = *(struct processtop **) p2;
601
602 struct perfcounter *tmp1, *tmp2;
603 unsigned long totaln2 = 0;
604 unsigned long totaln1 = 0;
605
606 if (!key)
607 return 0;
608
609 tmp1 = g_hash_table_lookup(n1->perf, key);
610 if (!tmp1)
611 totaln1 = 0;
612 else
613 totaln1 = tmp1->count;
614
615 tmp2 = g_hash_table_lookup(n2->perf, key);
616 if (!tmp2)
617 totaln2 = 0;
618 else
619 totaln2 = tmp2->count;
620
621 if (totaln1 < totaln2)
622 return 1;
623 if (totaln1 == totaln2) {
624 totaln1 = n1->tid;
625 totaln2 = n2->tid;
626 if (totaln1 < totaln2)
627 return 1;
628 return -1;
629 }
630 return -1;
631}
632
633void print_key_title(char *key, int line)
634{
635 wattron(center, A_BOLD);
951303cc
JD
636 mvwprintw(center, line, 1, "%s", key);
637 mvwprintw(center, line, 30, " ");
1fc22eb4
JD
638 wattroff(center, A_BOLD);
639}
640
641void update_process_details()
642{
643 unsigned long elapsed;
644 double maxcputime;
d26643ed 645 struct processtop *tmp;
b093de8a
MB
646 struct files *file_tmp;
647 int i, j = 0;
69362330 648 char unit[4];
97514683 649 char filename_buf[COLS];
951303cc 650 int line = 1;
cc30e58d 651 int column;
32647247 652 GPtrArray *newfilearray = g_ptr_array_new();
951303cc
JD
653 GHashTableIter iter;
654 struct perfcounter *perfn1, *perfn2;
655 gpointer key;
1fc22eb4
JD
656
657 set_window_title(center, "Process details");
658
659
d26643ed
JD
660 tmp = find_process_tid(data,
661 selected_process->tid,
662 selected_process->comm);
1fc22eb4
JD
663 elapsed = data->end - data->start;
664 maxcputime = elapsed * data->cpu_table->len / 100.0;
665
951303cc 666 print_key_title("Name", line++);
d26643ed 667 wprintw(center, "%s", selected_process->comm);
951303cc 668 print_key_title("TID", line++);
d26643ed 669 wprintw(center, "%d", selected_process->tid);
1fc22eb4
JD
670 if (!tmp) {
671 print_key_title("Does not exit at this time", 3);
672 return;
673 }
674
951303cc 675 print_key_title("PID", line++);
1fc22eb4 676 wprintw(center, "%d", tmp->pid);
951303cc 677 print_key_title("PPID", line++);
1fc22eb4 678 wprintw(center, "%d", tmp->ppid);
951303cc 679 print_key_title("CPU", line++);
1fc22eb4 680 wprintw(center, "%1.2f %%", tmp->totalcpunsec/maxcputime);
b093de8a 681
951303cc 682 print_key_title("READ B/s", line++);
69362330
JD
683 scale_unit(tmp->fileread, unit);
684 wprintw(center, "%s", unit);
b093de8a 685
951303cc 686 print_key_title("WRITE B/s", line++);
69362330
JD
687 scale_unit(tmp->filewrite, unit);
688 wprintw(center, "%s", unit);
b093de8a 689
951303cc
JD
690 g_hash_table_iter_init(&iter, global_perf_liszt);
691 while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) {
692 print_key_title((char *) key, line++);
693 perfn2 = g_hash_table_lookup(tmp->perf, (char *) key);
694 wprintw(center, "%d", perfn2 ? perfn2->count : 0);
695 }
696 line++;
697
93d80d35 698 wattron(center, A_BOLD);
cc30e58d
JD
699 column = 1;
700 for (i = 0; i < 3; i++) {
701 if (fileview[i].sort)
702 wattron(center, A_UNDERLINE);
703 mvwprintw(center, line, column, fileview[i].title);
704 wattroff(center, A_UNDERLINE);
705 column += 10;
706 }
707 mvwprintw(center, line++, column, "FILENAME");
93d80d35
JD
708 wattroff(center, A_BOLD);
709
32647247
JD
710 /*
711 * since the process_files_table array could contain NULL file structures,
712 * and that the positions inside the array is important (it is the FD), we
713 * need to create a temporary array that we can sort.
714 */
715 for (i = 0; i < tmp->process_files_table->len; i++) {
716 file_tmp = g_ptr_array_index(tmp->process_files_table, i);
717 if (file_tmp)
718 g_ptr_array_add(newfilearray, file_tmp);
719 }
720
721 if (fileview[0].sort == 1)
722 g_ptr_array_sort(newfilearray, sort_by_file_fd_desc);
723 else if (fileview[1].sort == 1)
724 g_ptr_array_sort(newfilearray, sort_by_file_read_desc);
725 else if (fileview[2].sort == 1)
726 g_ptr_array_sort(newfilearray, sort_by_file_write_desc);
727 else
728 g_ptr_array_sort(newfilearray, sort_by_file_read_desc);
729
730 for (i = selected_line; i < newfilearray->len &&
951303cc 731 i < (selected_line + max_center_lines - line + 2); i++) {
32647247
JD
732 file_tmp = g_ptr_array_index(newfilearray, i);
733 if (!file_tmp)
734 continue;
951303cc 735 mvwprintw(center, line + j, 1, "%d", file_tmp->fd);
32647247 736 scale_unit(file_tmp->read, unit);
cc30e58d 737 mvwprintw(center, line + j, 11, "%s", unit);
32647247 738 scale_unit(file_tmp->write, unit);
cc30e58d 739 mvwprintw(center, line + j, 21, "%s", unit);
32647247 740 snprintf(filename_buf, COLS - 25, "%s", file_tmp->name);
cc30e58d 741 mvwprintw(center, line + j, 31, "%s", filename_buf);
32647247 742 j++;
b093de8a 743 }
32647247 744 g_ptr_array_free(newfilearray, TRUE);
1fc22eb4
JD
745}
746
747void update_perf()
748{
bb053abb 749 int i;
1fc22eb4
JD
750 int nblinedisplayed = 0;
751 int current_line = 0;
752 struct processtop *tmp;
753 int header_offset = 2;
754 int perf_row = 40;
755 struct perfcounter *perfn1, *perfn2;
1fc22eb4
JD
756 char *perf_key = NULL;
757 int value;
85db4618
JD
758 GHashTableIter iter;
759 gpointer key;
1fc22eb4
JD
760
761 set_window_title(center, "Perf Top");
762 wattron(center, A_BOLD);
763 mvwprintw(center, 1, 1, "PID");
764 mvwprintw(center, 1, 11, "TID");
765 mvwprintw(center, 1, 22, "NAME");
766
767 perf_row = 40;
0d91c12a 768 g_hash_table_iter_init(&iter, global_perf_liszt);
85db4618 769 while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) {
1fc22eb4 770 if (perfn1->visible) {
6419078d 771 /* + 5 to strip the "perf_" prefix */
1fc22eb4 772 mvwprintw(center, 1, perf_row, "%s",
6419078d 773 (char *) key + 5);
1fc22eb4
JD
774 perf_row += 20;
775 }
776 if (perfn1->sort) {
85db4618 777 perf_key = (char *) key;
1fc22eb4 778 }
1fc22eb4 779 }
85db4618 780
1fc22eb4
JD
781 wattroff(center, A_BOLD);
782
783 g_ptr_array_sort_with_data(data->process_table, sort_perf, perf_key);
85db4618 784
91be6bb5 785 for (i = 0; i < data->process_table->len &&
1fc22eb4 786 nblinedisplayed < max_center_lines; i++) {
1fc22eb4
JD
787 tmp = g_ptr_array_index(data->process_table, i);
788
635dc837
JD
789 if (process_selected(tmp)) {
790 wattron(center, COLOR_PAIR(6));
791 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
792 }
1fc22eb4
JD
793 if (current_line == selected_line) {
794 selected_process = tmp;
795 wattron(center, COLOR_PAIR(5));
796 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
797 }
798
799 mvwprintw(center, current_line + header_offset, 1, "%d", tmp->pid);
800 mvwprintw(center, current_line + header_offset, 11, "%d", tmp->tid);
801 mvwprintw(center, current_line + header_offset, 22, "%s", tmp->comm);
802
0d91c12a 803 g_hash_table_iter_init(&iter, global_perf_liszt);
1fc22eb4
JD
804
805 perf_row = 40;
85db4618 806 while (g_hash_table_iter_next (&iter, &key, (gpointer) &perfn1)) {
1fc22eb4 807 if (perfn1->visible) {
85db4618 808 perfn2 = g_hash_table_lookup(tmp->perf, (char *) key);
1fc22eb4
JD
809 if (perfn2)
810 value = perfn2->count;
811 else
812 value = 0;
b093de8a
MB
813 mvwprintw(center, current_line + header_offset,
814 perf_row, "%d", value);
1fc22eb4
JD
815 perf_row += 20;
816 }
1fc22eb4
JD
817 }
818
635dc837 819 wattroff(center, COLOR_PAIR(6));
1fc22eb4
JD
820 wattroff(center, COLOR_PAIR(5));
821 nblinedisplayed++;
822 current_line++;
823 }
824}
825
1fc22eb4
JD
826void update_iostream()
827{
828 int i;
829 int header_offset = 2;
830 struct processtop *tmp;
831 int nblinedisplayed = 0;
832 int current_line = 0;
b093de8a 833 int total = 0;
69362330 834 char unit[4];
41f5890b 835 int column;
1fc22eb4
JD
836
837 set_window_title(center, "IO Top");
838 wattron(center, A_BOLD);
69362330
JD
839 mvwprintw(center, 1, 1, "PID");
840 mvwprintw(center, 1, 11, "TID");
841 mvwprintw(center, 1, 22, "NAME");
41f5890b
JD
842 column = 40;
843 for (i = 0; i < 3; i++) {
844 if (iostreamtopview[i].sort)
845 wattron(center, A_UNDERLINE);
846 mvwprintw(center, 1, column, iostreamtopview[i].title);
847 wattroff(center, A_UNDERLINE);
848 column += 12;
849 }
1fc22eb4 850 wattroff(center, A_BOLD);
41f5890b 851 wattroff(center, A_UNDERLINE);
1fc22eb4 852
89f1e0d1
JD
853 if (iostreamtopview[0].sort == 1)
854 g_ptr_array_sort(data->process_table, sort_by_process_read_desc);
855 else if (iostreamtopview[1].sort == 1)
856 g_ptr_array_sort(data->process_table, sort_by_process_write_desc);
857 else if (iostreamtopview[2].sort == 1)
858 g_ptr_array_sort(data->process_table, sort_by_process_total_desc);
859 else
860 g_ptr_array_sort(data->process_table, sort_by_process_total_desc);
1fc22eb4
JD
861
862 for (i = list_offset; i < data->process_table->len &&
863 nblinedisplayed < max_center_lines; i++) {
864 tmp = g_ptr_array_index(data->process_table, i);
865
635dc837
JD
866 if (process_selected(tmp)) {
867 wattron(center, COLOR_PAIR(6));
868 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
869 }
1fc22eb4
JD
870 if (current_line == selected_line) {
871 selected_process = tmp;
1fc22eb4
JD
872 wattron(center, COLOR_PAIR(5));
873 mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
874 }
69362330
JD
875 /* TGID */
876 mvwprintw(center, current_line + header_offset, 1, "%d", tmp->pid);
877 /* PID */
878 mvwprintw(center, current_line + header_offset, 11, "%d", tmp->tid);
879 /* NAME */
880 mvwprintw(center, current_line + header_offset, 22, "%s", tmp->comm);
b093de8a 881
1fc22eb4 882 /* READ (bytes/sec) */
69362330
JD
883 scale_unit(tmp->fileread, unit);
884 mvwprintw(center, current_line + header_offset, 40, "%s", unit);
1fc22eb4
JD
885
886 /* WRITE (bytes/sec) */
69362330
JD
887 scale_unit(tmp->filewrite, unit);
888 mvwprintw(center, current_line + header_offset, 52, "%s", unit);
1fc22eb4
JD
889
890 /* TOTAL STREAM */
b093de8a
MB
891 total = tmp->totalfileread + tmp->totalfilewrite;
892
69362330
JD
893 scale_unit(total, unit);
894 mvwprintw(center, current_line + header_offset, 64, "%s", unit);
b093de8a 895
635dc837 896 wattroff(center, COLOR_PAIR(6));
1fc22eb4
JD
897 wattroff(center, COLOR_PAIR(5));
898 nblinedisplayed++;
899 current_line++;
900 }
901}
902
903void update_current_view()
904{
905 sem_wait(&update_display_sem);
906 if (!data)
907 return;
908 update_header();
909
910 werase(center);
911 box(center, 0, 0);
912 switch (current_view) {
913 case cpu:
914 update_cputop_display();
915 break;
916 case perf:
917 update_perf();
918 break;
919 case process_details:
920 update_process_details();
921 break;
1fc22eb4
JD
922 case iostream:
923 update_iostream();
924 break;
925 case tree:
926 update_cputop_display();
927 break;
928 default:
929 break;
930 }
931 update_panels();
932 doupdate();
933 sem_post(&update_display_sem);
934}
935
32647247
JD
936void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_sort)
937{
938 int i;
939 int size;
940
941 if (!data)
942 return;
943 if (pref_panel_window) {
944 del_panel(pref_panel);
945 delwin(pref_panel_window);
946 }
947 size = 3;
948
949 pref_panel_window = create_window(size + 2, 30, 10, 10);
950 pref_panel = new_panel(pref_panel_window);
951
952 werase(pref_panel_window);
953 box(pref_panel_window, 0 , 0);
954 set_window_title(pref_panel_window, "Process Detail Preferences ");
955 wattron(pref_panel_window, A_BOLD);
956 mvwprintw(pref_panel_window, size + 1, 1,
d2fd8c70 957 " 's' : sort, space : toggle");
32647247
JD
958 wattroff(pref_panel_window, A_BOLD);
959
960 if (*line_selected > (size - 1))
961 *line_selected = size - 1;
962 if (toggle_sort == 1) {
963 if (fileview[*line_selected].sort == 1)
964 fileview[*line_selected].reverse = 1;
965 for (i = 0; i < size; i++)
966 fileview[i].sort = 0;
967 fileview[*line_selected].sort = 1;
968 update_current_view();
969 }
970
971 for (i = 0; i < size; i++) {
972 if (i == *line_selected) {
973 wattron(pref_panel_window, COLOR_PAIR(5));
974 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
975 }
976 if (fileview[i].sort == 1)
977 wattron(pref_panel_window, A_BOLD);
d33aae69 978 mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
32647247
JD
979 fileview[i].title);
980 wattroff(pref_panel_window, A_BOLD);
981 wattroff(pref_panel_window, COLOR_PAIR(5));
982
983 }
984 update_panels();
985 doupdate();
986}
987
89f1e0d1
JD
988void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort)
989{
990 int i;
991 int size;
992
993 if (!data)
994 return;
995 if (pref_panel_window) {
996 del_panel(pref_panel);
997 delwin(pref_panel_window);
998 }
999 size = 3;
1000
1001 pref_panel_window = create_window(size + 2, 30, 10, 10);
1002 pref_panel = new_panel(pref_panel_window);
1003
1004 werase(pref_panel_window);
1005 box(pref_panel_window, 0 , 0);
1006 set_window_title(pref_panel_window, "IOTop Preferences ");
1007 wattron(pref_panel_window, A_BOLD);
1008 mvwprintw(pref_panel_window, size + 1, 1,
d2fd8c70 1009 " 's' : sort, space : toggle");
89f1e0d1
JD
1010 wattroff(pref_panel_window, A_BOLD);
1011
1012 if (*line_selected > (size - 1))
1013 *line_selected = size - 1;
1014 if (toggle_sort == 1) {
1015 if (iostreamtopview[*line_selected].sort == 1)
1016 iostreamtopview[*line_selected].reverse = 1;
1017 for (i = 0; i < size; i++)
1018 iostreamtopview[i].sort = 0;
1019 iostreamtopview[*line_selected].sort = 1;
1020 update_current_view();
1021 }
1022
1023 for (i = 0; i < size; i++) {
1024 if (i == *line_selected) {
1025 wattron(pref_panel_window, COLOR_PAIR(5));
1026 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
1027 }
1028 if (iostreamtopview[i].sort == 1)
1029 wattron(pref_panel_window, A_BOLD);
d33aae69 1030 mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
89f1e0d1
JD
1031 iostreamtopview[i].title);
1032 wattroff(pref_panel_window, A_BOLD);
1033 wattroff(pref_panel_window, COLOR_PAIR(5));
1034
1035 }
1036 update_panels();
1037 doupdate();
1038}
1039
3b15348c
JD
1040void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort)
1041{
1042 int i;
1043 int size;
1044
1045 if (!data)
1046 return;
1047 if (pref_panel_window) {
1048 del_panel(pref_panel);
1049 delwin(pref_panel_window);
1050 }
1051 size = 4;
1052
1053 pref_panel_window = create_window(size + 2, 30, 10, 10);
1054 pref_panel = new_panel(pref_panel_window);
1055
1056 werase(pref_panel_window);
1057 box(pref_panel_window, 0 , 0);
1058 set_window_title(pref_panel_window, "CPUTop Preferences ");
1059 wattron(pref_panel_window, A_BOLD);
1060 mvwprintw(pref_panel_window, size + 1, 1,
d2fd8c70 1061 " 's' : sort, space : toggle");
3b15348c
JD
1062 wattroff(pref_panel_window, A_BOLD);
1063
89f1e0d1
JD
1064 if (*line_selected > (size - 1))
1065 *line_selected = size - 1;
3b15348c
JD
1066 if (toggle_sort == 1) {
1067 /* special case, we don't support sorting by procname for now */
1068 if (*line_selected != 3) {
1069 if (cputopview[*line_selected].sort == 1)
1070 cputopview[*line_selected].reverse = 1;
89f1e0d1 1071 for (i = 0; i < size; i++)
3b15348c
JD
1072 cputopview[i].sort = 0;
1073 cputopview[*line_selected].sort = 1;
1074 update_current_view();
1075 }
1076 }
1077
89f1e0d1 1078 for (i = 0; i < size; i++) {
3b15348c
JD
1079 if (i == *line_selected) {
1080 wattron(pref_panel_window, COLOR_PAIR(5));
1081 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
1082 }
1083 if (cputopview[i].sort == 1)
1084 wattron(pref_panel_window, A_BOLD);
d33aae69 1085 mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
3b15348c
JD
1086 cputopview[i].title);
1087 wattroff(pref_panel_window, A_BOLD);
1088 wattroff(pref_panel_window, COLOR_PAIR(5));
1089
1090 }
1091 update_panels();
1092 doupdate();
1093}
1094
1095void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort)
1fc22eb4 1096{
1e05f0ae
JD
1097 int i;
1098 struct perfcounter *perf;
1099 GList *perflist;
1fc22eb4 1100 int size;
1e05f0ae 1101
1fc22eb4
JD
1102 if (!data)
1103 return;
0d91c12a
JD
1104 if (pref_panel_window) {
1105 del_panel(pref_panel);
1106 delwin(pref_panel_window);
1fc22eb4 1107 }
0d91c12a 1108 size = g_hash_table_size(global_perf_liszt);
1e05f0ae 1109
0d91c12a
JD
1110 pref_panel_window = create_window(size + 2, 30, 10, 10);
1111 pref_panel = new_panel(pref_panel_window);
1fc22eb4 1112
0d91c12a
JD
1113 werase(pref_panel_window);
1114 box(pref_panel_window, 0 , 0);
1115 set_window_title(pref_panel_window, "Perf Preferences ");
1116 wattron(pref_panel_window, A_BOLD);
1117 mvwprintw(pref_panel_window, g_hash_table_size(global_perf_liszt) + 1, 1,
d2fd8c70 1118 " 's' : sort, space : toggle");
0d91c12a 1119 wattroff(pref_panel_window, A_BOLD);
1fc22eb4
JD
1120
1121 if (toggle_sort == 1) {
1122 i = 0;
0d91c12a 1123 perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt));
1fc22eb4 1124 while (perflist) {
0d91c12a 1125 perf = g_hash_table_lookup(global_perf_liszt, perflist->data);
3b15348c 1126 if (i != *line_selected)
1fc22eb4
JD
1127 perf->sort = 0;
1128 else
1129 perf->sort = 1;
1130 i++;
1131 perflist = g_list_next(perflist);
1132 }
1133 update_current_view();
1134 }
1135
1136 i = 0;
0d91c12a 1137 perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt));
1fc22eb4 1138 while (perflist) {
0d91c12a 1139 perf = g_hash_table_lookup(global_perf_liszt, perflist->data);
3b15348c 1140 if (i == *line_selected && toggle_view == 1) {
1fc22eb4
JD
1141 perf->visible = perf->visible == 1 ? 0:1;
1142 update_current_view();
1143 }
3b15348c 1144 if (i == *line_selected) {
0d91c12a
JD
1145 wattron(pref_panel_window, COLOR_PAIR(5));
1146 mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
1fc22eb4
JD
1147 }
1148 if (perf->sort == 1)
0d91c12a
JD
1149 wattron(pref_panel_window, A_BOLD);
1150 mvwprintw(pref_panel_window, i + 1, 1, "[%c] %s",
1fc22eb4 1151 perf->visible == 1 ? 'x' : ' ',
b8a1df45 1152 (char *) perflist->data + 5);
0d91c12a
JD
1153 wattroff(pref_panel_window, A_BOLD);
1154 wattroff(pref_panel_window, COLOR_PAIR(5));
1fc22eb4
JD
1155 i++;
1156 perflist = g_list_next(perflist);
1157 }
1158 update_panels();
1159 doupdate();
1160}
1161
3b15348c 1162int update_preference_panel(int *line_selected, int toggle_view, int toggle_sort)
1fc22eb4 1163{
1e05f0ae
JD
1164 int ret = 0;
1165
0d91c12a
JD
1166 switch(current_view) {
1167 case perf:
3b15348c
JD
1168 update_perf_pref(line_selected, toggle_view, toggle_sort);
1169 break;
1170 case cpu:
1171 update_cpu_pref(line_selected, toggle_view, toggle_sort);
0d91c12a 1172 break;
89f1e0d1
JD
1173 case iostream:
1174 update_iostream_pref(line_selected, toggle_view, toggle_sort);
1175 break;
32647247
JD
1176 case process_details:
1177 update_process_detail_pref(line_selected, toggle_view, toggle_sort);
1178 break;
0d91c12a 1179 default:
1e05f0ae 1180 ret = -1;
0d91c12a
JD
1181 break;
1182 }
1e05f0ae
JD
1183
1184 return ret;
0d91c12a
JD
1185}
1186
1187void toggle_pref_panel(void)
1188{
1e05f0ae
JD
1189 int ret;
1190
0d91c12a
JD
1191 if (pref_panel_visible) {
1192 hide_panel(pref_panel);
1193 pref_panel_visible = 0;
1fc22eb4 1194 } else {
3b15348c 1195 ret = update_preference_panel(&pref_line_selected, 0, 0);
1e05f0ae
JD
1196 if (ret < 0)
1197 return;
0d91c12a
JD
1198 show_panel(pref_panel);
1199 pref_panel_visible = 1;
1fc22eb4
JD
1200 }
1201 update_panels();
1202 doupdate();
1203}
1204
1205void display(unsigned int index)
1206{
1207 last_display_index = index;
1208 currently_displayed_index = index;
1209 data = g_ptr_array_index(copies, index);
1210 if (!data)
1211 return;
1212 max_elements = data->process_table->len;
1213 update_current_view();
1214 update_footer();
1215 update_panels();
1216 doupdate();
1217}
1218
1219void pause_display()
1220{
1221 toggle_pause = 1;
1222 print_log("Pause");
1223 sem_wait(&pause_sem);
1224}
1225
1226void resume_display()
1227{
1228 toggle_pause = -1;
1229 print_log("Resume");
1230 sem_post(&pause_sem);
1231}
1232
1233void *handle_keyboard(void *p)
1234{
1235 int ch;
1236 while((ch = getch())) {
1237 switch(ch) {
1238 /* Move the cursor and scroll */
8c05e516 1239 case 'j':
1fc22eb4 1240 case KEY_DOWN:
0d91c12a 1241 if (pref_panel_visible) {
3b15348c
JD
1242 pref_line_selected++;
1243 update_preference_panel(&pref_line_selected, 0, 0);
1fc22eb4
JD
1244 } else {
1245 if (selected_line < (max_center_lines - 1) &&
1246 selected_line < max_elements - 1) {
1247 selected_line++;
1248 selected_in_list++;
1249 } else if (selected_in_list < (max_elements - 1)
1250 && (list_offset < (max_elements - max_center_lines))) {
1251 selected_in_list++;
1252 list_offset++;
1253 }
1254 update_current_view();
1255 }
1256 break;
1257 case KEY_NPAGE:
1fc22eb4 1258 break;
8c05e516 1259 case 'k':
1fc22eb4 1260 case KEY_UP:
0d91c12a 1261 if (pref_panel_visible) {
3b15348c
JD
1262 if (pref_line_selected > 0)
1263 pref_line_selected--;
1264 update_preference_panel(&pref_line_selected, 0, 0);
1fc22eb4
JD
1265 } else {
1266 if (selected_line > 0) {
1267 selected_line--;
1268 selected_in_list--;
1269 } else if (selected_in_list > 0 && list_offset > 0) {
1270 selected_in_list--;
1271 list_offset--;
1272 }
1273 update_current_view();
1274 }
1275 break;
1276 case KEY_PPAGE:
1fc22eb4
JD
1277 break;
1278
1279 /* Navigate the history with arrows */
1280 case KEY_LEFT:
1281 if (currently_displayed_index > 0) {
1282 currently_displayed_index--;
1283 print_log("Going back in time");
1284 } else {
1285 print_log("Cannot rewind, last data is already displayed");
1286 }
1287 data = g_ptr_array_index(copies, currently_displayed_index);
1288 max_elements = data->process_table->len;
1289
1290 /* we force to pause the display when moving in time */
1291 if (toggle_pause < 0)
1292 pause_display();
1293
1294 update_current_view();
1295 update_footer();
1296 break;
1297 case KEY_RIGHT:
1298 if (currently_displayed_index < last_display_index) {
1299 currently_displayed_index++;
1300 print_log("Going forward in time");
1301 data = g_ptr_array_index(copies, currently_displayed_index);
1302 max_elements = data->process_table->len;
1303 update_current_view();
1304 update_footer();
1305 } else {
1306 print_log("Manually moving forward");
1307 sem_post(&timer);
3e59e768
JD
1308 if (toggle_pause > 0) {
1309 sem_post(&pause_sem);
1310 update_current_view();
1311 sem_wait(&pause_sem);
1312 }
1fc22eb4
JD
1313 }
1314
1315 break;
1316 case ' ':
0d91c12a 1317 if (pref_panel_visible) {
3b15348c 1318 update_preference_panel(&pref_line_selected, 1, 0);
635dc837
JD
1319 } else {
1320 update_selected_processes();
1321 update_current_view();
1322 }
1fc22eb4
JD
1323 break;
1324 case 's':
0d91c12a 1325 if (pref_panel_visible)
3b15348c 1326 update_preference_panel(&pref_line_selected, 0, 1);
1fc22eb4
JD
1327 break;
1328
1329 case 13: /* FIXME : KEY_ENTER ?? */
d2fd8c70
JD
1330 if (pref_panel_visible)
1331 break;
041aa219
JD
1332 if (current_view != process_details) {
1333 previous_view = current_view;
1fc22eb4 1334 current_view = process_details;
041aa219
JD
1335 } else {
1336 current_view = previous_view;
1337 previous_view = process_details;
1fc22eb4
JD
1338 }
1339 update_current_view();
1340 break;
1341
1342 case KEY_F(1):
3b15348c
JD
1343 if (pref_panel_visible)
1344 toggle_pref_panel();
1fc22eb4 1345 current_view = cpu;
af54ebcf 1346 selected_line = 0;
1fc22eb4
JD
1347 update_current_view();
1348 break;
1349 case KEY_F(2):
3b15348c
JD
1350 if (pref_panel_visible)
1351 toggle_pref_panel();
1fc22eb4 1352 current_view = cpu;
af54ebcf 1353 selected_line = 0;
1fc22eb4
JD
1354 update_current_view();
1355 break;
1356 case KEY_F(3):
3b15348c
JD
1357 if (pref_panel_visible)
1358 toggle_pref_panel();
1fc22eb4 1359 current_view = perf;
af54ebcf 1360 selected_line = 0;
1fc22eb4
JD
1361 update_current_view();
1362 break;
1363 case KEY_F(4):
3b15348c
JD
1364 if (pref_panel_visible)
1365 toggle_pref_panel();
1fc22eb4 1366 current_view = iostream;
af54ebcf 1367 selected_line = 0;
1fc22eb4
JD
1368 update_current_view();
1369 break;
1370 case KEY_F(10):
1371 case 'q':
1372 reset_ncurses();
1373 break;
1374 case 't':
1375 toggle_threads *= -1;
1376 update_current_view();
1377 break;
1378 case 'p':
1379 if (toggle_pause < 0) {
1380 pause_display();
1381 } else {
1382 resume_display();
1383 }
1384 break;
f9ff6939 1385 case 'r':
0d91c12a 1386 toggle_pref_panel();
1fc22eb4 1387 break;
d2fd8c70
JD
1388 /* ESCAPE, but slow to process, don't know why */
1389 case 27:
1390 if (pref_panel_visible)
1391 toggle_pref_panel();
1392 else if (current_view == process_details) {
1393 current_view = previous_view;
1394 previous_view = process_details;
1395 }
1396 update_current_view();
1397 break;
1fc22eb4 1398 default:
b093de8a
MB
1399 if (data)
1400 update_current_view();
1fc22eb4
JD
1401 break;
1402 }
1403 update_footer();
1404 }
1405 return NULL;
1406}
1407
89f1e0d1
JD
1408void init_view_headers()
1409{
1410 cputopview[0].title = strdup("CPU(%)");
1411 cputopview[0].sort = 1;
1412 cputopview[1].title = strdup("TGID");
1413 cputopview[2].title = strdup("PID");
1414 cputopview[3].title = strdup("NAME");
1415
1416 iostreamtopview[0].title = strdup("R (B/sec)");
1417 iostreamtopview[1].title = strdup("W (B/sec)");
1418 iostreamtopview[2].title = strdup("Total (B)");
1419 iostreamtopview[2].sort = 1;
32647247
JD
1420
1421 fileview[0].title = strdup("FD");
1422 fileview[1].title = strdup("READ");
1423 fileview[1].sort = 1;
1424 fileview[2].title = strdup("WRITE");
89f1e0d1
JD
1425}
1426
1fc22eb4
JD
1427void init_ncurses()
1428{
635dc837 1429 selected_processes = g_ptr_array_new();
1fc22eb4 1430 sem_init(&update_display_sem, 0, 1);
89f1e0d1 1431 init_view_headers();
1fc22eb4
JD
1432 init_screen();
1433
dc8f04dd
JD
1434 header = create_window(5, COLS - 1, 0, 0);
1435 center = create_window(LINES - 5 - 7, COLS - 1, 5, 0);
1fc22eb4
JD
1436 status = create_window(MAX_LOG_LINES + 2, COLS - 1, LINES - 7, 0);
1437 footer = create_window(1, COLS - 1, LINES - 1, 0);
1438
1439 print_log("Starting display");
1440
1441 main_panel = new_panel(center);
1fc22eb4
JD
1442
1443 current_view = cpu;
1444
1445 basic_header();
1446 update_footer();
1447
1448 pthread_create(&keyboard_thread, NULL, handle_keyboard, (void *)NULL);
1449}
This page took 0.15615 seconds and 4 git commands to generate.