underline for sorted column in cputop
[lttngtop.git] / src / cursesdisplay.c
index 9821fb40677930e4681aaabd8368735868687633..b63fa9bce3dc32675aed27e5d6f6d1d27bae1785 100644 (file)
@@ -42,7 +42,7 @@ WINDOW *pref_panel_window = NULL;
 PANEL *pref_panel, *main_panel;
 
 int pref_panel_visible = 0;
-int perf_line_selected = 0;
+int pref_line_selected = 0;
 
 int last_display_index, currently_displayed_index;
 
@@ -65,6 +65,10 @@ GPtrArray *selected_processes;
 
 pthread_t keyboard_thread;
 
+struct header_view cputopview[4];
+struct header_view iostreamtopview[3];
+struct header_view fileview[3];
+
 void reset_ncurses()
 {
        curs_set(1);
@@ -223,6 +227,8 @@ int process_selected(struct processtop *process)
 
        for (i = 0; i < selected_processes->len; i++) {
                stored_process = g_ptr_array_index(selected_processes, i);
+               if (!stored_process)
+                       return 0;
                if (stored_process->tid == process->tid)
                        return 1;
        }
@@ -263,8 +269,8 @@ void update_footer()
        print_key(footer, "F4", "IOTop  ", current_view == iostream);
        print_key(footer, "Enter", "Details  ", current_view == process_details);
        print_key(footer, "Space", "Highlight  ", 0);
-       print_key(footer, "q", "Quit ", 0);
-       print_key(footer, "P", "Perf Pref  ", 0);
+       print_key(footer, "q", "Quit ", 0);
+       print_key(footer, "r", "Pref  ", 0);
        print_key(footer, "p", "Pause  ", toggle_pause);
 
        wrefresh(footer);
@@ -374,6 +380,127 @@ gint sort_by_cpu_desc(gconstpointer p1, gconstpointer p2)
        return -1;
 }
 
+gint sort_by_tid_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct processtop *n1 = *(struct processtop **)p1;
+       struct processtop *n2 = *(struct processtop **)p2;
+       unsigned long totaln1 = n1->tid;
+       unsigned long totaln2 = n2->tid;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_pid_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct processtop *n1 = *(struct processtop **)p1;
+       struct processtop *n2 = *(struct processtop **)p2;
+       unsigned long totaln1 = n1->pid;
+       unsigned long totaln2 = n2->pid;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_process_read_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct processtop *n1 = *(struct processtop **)p1;
+       struct processtop *n2 = *(struct processtop **)p2;
+       unsigned long totaln1 = n1->fileread;
+       unsigned long totaln2 = n2->fileread;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_process_write_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct processtop *n1 = *(struct processtop **)p1;
+       struct processtop *n2 = *(struct processtop **)p2;
+       unsigned long totaln1 = n1->filewrite;
+       unsigned long totaln2 = n2->filewrite;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_process_total_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct processtop *n1 = *(struct processtop **)p1;
+       struct processtop *n2 = *(struct processtop **)p2;
+       unsigned long totaln1 = n1->filewrite + n1->fileread;
+       unsigned long totaln2 = n2->filewrite + n2->fileread;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_file_read_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct files *n1 = *(struct files **)p1;
+       struct files *n2 = *(struct files **)p2;
+       unsigned long totaln1;
+       unsigned long totaln2;
+
+       totaln1 = n1->read;
+       totaln2 = n2->read;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_file_write_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct files *n1 = *(struct files **)p1;
+       struct files *n2 = *(struct files **)p2;
+       unsigned long totaln1;
+       unsigned long totaln2;
+
+       totaln1 = n1->write;
+       totaln2 = n2->write;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
+gint sort_by_file_fd_desc(gconstpointer p1, gconstpointer p2)
+{
+       struct files *n1 = *(struct files **)p1;
+       struct files *n2 = *(struct files **)p2;
+       unsigned long totaln1;
+       unsigned long totaln2;
+
+       totaln1 = n1->fd;
+       totaln2 = n2->fd;
+
+       if (totaln1 < totaln2)
+               return 1;
+       if (totaln1 == totaln2)
+               return 0;
+       return -1;
+}
+
 gint sort_by_cpu_group_by_threads_desc(gconstpointer p1, gconstpointer p2)
 {
        struct processtop *n1 = *(struct processtop **)p1;
@@ -397,18 +524,32 @@ void update_cputop_display()
        double maxcputime;
        int nblinedisplayed = 0;
        int current_line = 0;
+       int column;
 
        elapsed = data->end - data->start;
        maxcputime = elapsed * data->cpu_table->len / 100.0;
 
-       g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
+       if (cputopview[0].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
+       else if (cputopview[1].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_pid_desc);
+       else if (cputopview[2].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_tid_desc);
+       else if (cputopview[3].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
+       else
+               g_ptr_array_sort(data->process_table, sort_by_cpu_desc);
 
        set_window_title(center, "CPU Top");
        wattron(center, A_BOLD);
-       mvwprintw(center, 1, 1, "CPU(%)");
-       mvwprintw(center, 1, 12, "TGID");
-       mvwprintw(center, 1, 22, "PID");
-       mvwprintw(center, 1, 32, "NAME");
+       column = 1;
+       for (i = 0; i < 4; i++) {
+               if (cputopview[i].sort)
+                       wattron(center, A_UNDERLINE);
+               mvwprintw(center, 1, column, cputopview[i].title);
+               wattroff(center, A_UNDERLINE);
+               column += 10;
+       }
        wattroff(center, A_BOLD);
 
        max_center_lines = LINES - 5 - 7 - 1 - header_offset;
@@ -418,7 +559,6 @@ void update_cputop_display()
                        nblinedisplayed < max_center_lines; i++) {
                tmp = g_ptr_array_index(data->process_table, i);
 
-               /* FIXME : random segfault here */
                if (process_selected(tmp)) {
                        wattron(center, COLOR_PAIR(6));
                        mvwhline(center, current_line + header_offset, 1, ' ', COLS-3);
@@ -432,11 +572,11 @@ void update_cputop_display()
                mvwprintw(center, current_line + header_offset, 1, "%1.2f",
                                tmp->totalcpunsec / maxcputime);
                /* TGID */
-               mvwprintw(center, current_line + header_offset, 12, "%d", tmp->pid);
+               mvwprintw(center, current_line + header_offset, 11, "%d", tmp->pid);
                /* PID */
-               mvwprintw(center, current_line + header_offset, 22, "%d", tmp->tid);
+               mvwprintw(center, current_line + header_offset, 21, "%d", tmp->tid);
                /* NAME */
-               mvwprintw(center, current_line + header_offset, 32, "%s", tmp->comm);
+               mvwprintw(center, current_line + header_offset, 31, "%s", tmp->comm);
                wattroff(center, COLOR_PAIR(6));
                wattroff(center, COLOR_PAIR(5));
                nblinedisplayed++;
@@ -496,6 +636,7 @@ void update_process_details()
        int i, j = 0;
        char unit[4];
        char filename_buf[COLS];
+       GPtrArray *newfilearray = g_ptr_array_new();
 
        set_window_title(center, "Process details");
 
@@ -537,20 +678,41 @@ void update_process_details()
        mvwprintw(center, 8, 24, "FILENAME");
        wattroff(center, A_BOLD);
 
-       for (i = selected_line; i < tmp->process_files_table->len &&
+       /*
+        * since the process_files_table array could contain NULL file structures,
+        * and that the positions inside the array is important (it is the FD), we
+        * need to create a temporary array that we can sort.
+        */
+       for (i = 0; i < tmp->process_files_table->len; i++) {
+               file_tmp = g_ptr_array_index(tmp->process_files_table, i);
+               if (file_tmp)
+                       g_ptr_array_add(newfilearray, file_tmp);
+       }
+
+       if (fileview[0].sort == 1)
+               g_ptr_array_sort(newfilearray, sort_by_file_fd_desc);
+       else if (fileview[1].sort == 1)
+               g_ptr_array_sort(newfilearray, sort_by_file_read_desc);
+       else if (fileview[2].sort == 1)
+               g_ptr_array_sort(newfilearray, sort_by_file_write_desc);
+       else
+               g_ptr_array_sort(newfilearray, sort_by_file_read_desc);
+
+       for (i = selected_line; i < newfilearray->len &&
                        i < (selected_line + max_center_lines - 7); i++) {
-               file_tmp = get_file(tmp, i);
-               if (file_tmp != NULL) {
-                       mvwprintw(center, 9 + j, 1, "%d", i);
-                       scale_unit(file_tmp->read, unit);
-                       mvwprintw(center, 9 + j, 10, "%s", unit);
-                       scale_unit(file_tmp->write, unit);
-                       mvwprintw(center, 9 + j, 17, "%s", unit);
-                       snprintf(filename_buf, COLS - 25, "%s", file_tmp->name);
-                       mvwprintw(center, 9 + j, 24, "%s", filename_buf);
-                       j++;
-               }
+               file_tmp = g_ptr_array_index(newfilearray, i);
+               if (!file_tmp)
+                       continue;
+               mvwprintw(center, 9 + j, 1, "%d", file_tmp->fd);
+               scale_unit(file_tmp->read, unit);
+               mvwprintw(center, 9 + j, 10, "%s", unit);
+               scale_unit(file_tmp->write, unit);
+               mvwprintw(center, 9 + j, 17, "%s", unit);
+               snprintf(filename_buf, COLS - 25, "%s", file_tmp->name);
+               mvwprintw(center, 9 + j, 24, "%s", filename_buf);
+               j++;
        }
+       g_ptr_array_free(newfilearray, TRUE);
 }
 
 void update_perf()
@@ -632,21 +794,6 @@ void update_perf()
        }
 }
 
-gint sort_by_ret_desc(gconstpointer p1, gconstpointer p2)
-{
-       struct processtop *n1 = *(struct processtop **)p1;
-       struct processtop *n2 = *(struct processtop **)p2;
-
-       unsigned long totaln1 = n1->totalfileread + n1->totalfilewrite;
-       unsigned long totaln2 = n2->totalfileread + n2->totalfilewrite;
-
-       if (totaln1 < totaln2)
-               return 1;
-       if (totaln1 == totaln2)
-               return 0;
-       return -1;
-}
-
 void update_iostream()
 {
        int i;
@@ -667,7 +814,14 @@ void update_iostream()
        mvwprintw(center, 1, 64, "Total");
        wattroff(center, A_BOLD);
 
-       g_ptr_array_sort(data->process_table, sort_by_ret_desc);
+       if (iostreamtopview[0].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_process_read_desc);
+       else if (iostreamtopview[1].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_process_write_desc);
+       else if (iostreamtopview[2].sort == 1)
+               g_ptr_array_sort(data->process_table, sort_by_process_total_desc);
+       else
+               g_ptr_array_sort(data->process_table, sort_by_process_total_desc);
 
        for (i = list_offset; i < data->process_table->len &&
                        nblinedisplayed < max_center_lines; i++) {
@@ -743,7 +897,166 @@ void update_current_view()
        sem_post(&update_display_sem);
 }
 
-void update_perf_panel(int line_selected, int toggle_view, int toggle_sort)
+void update_process_detail_pref(int *line_selected, int toggle_view, int toggle_sort)
+{
+       int i;
+       int size;
+
+       if (!data)
+               return;
+       if (pref_panel_window) {
+               del_panel(pref_panel);
+               delwin(pref_panel_window);
+       }
+       size = 3;
+
+       pref_panel_window = create_window(size + 2, 30, 10, 10);
+       pref_panel = new_panel(pref_panel_window);
+
+       werase(pref_panel_window);
+       box(pref_panel_window, 0 , 0);
+       set_window_title(pref_panel_window, "Process Detail Preferences ");
+       wattron(pref_panel_window, A_BOLD);
+       mvwprintw(pref_panel_window, size + 1, 1,
+                       " 's' : sort, space : toggle");
+       wattroff(pref_panel_window, A_BOLD);
+
+       if (*line_selected > (size - 1))
+               *line_selected = size - 1;
+       if (toggle_sort == 1) {
+               if (fileview[*line_selected].sort == 1)
+                       fileview[*line_selected].reverse = 1;
+               for (i = 0; i < size; i++)
+                       fileview[i].sort = 0;
+               fileview[*line_selected].sort = 1;
+               update_current_view();
+       }
+
+       for (i = 0; i < size; i++) {
+               if (i == *line_selected) {
+                       wattron(pref_panel_window, COLOR_PAIR(5));
+                       mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
+               }
+               if (fileview[i].sort == 1)
+                       wattron(pref_panel_window, A_BOLD);
+               mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
+                               fileview[i].title);
+               wattroff(pref_panel_window, A_BOLD);
+               wattroff(pref_panel_window, COLOR_PAIR(5));
+
+       }
+       update_panels();
+       doupdate();
+}
+
+void update_iostream_pref(int *line_selected, int toggle_view, int toggle_sort)
+{
+       int i;
+       int size;
+
+       if (!data)
+               return;
+       if (pref_panel_window) {
+               del_panel(pref_panel);
+               delwin(pref_panel_window);
+       }
+       size = 3;
+
+       pref_panel_window = create_window(size + 2, 30, 10, 10);
+       pref_panel = new_panel(pref_panel_window);
+
+       werase(pref_panel_window);
+       box(pref_panel_window, 0 , 0);
+       set_window_title(pref_panel_window, "IOTop Preferences ");
+       wattron(pref_panel_window, A_BOLD);
+       mvwprintw(pref_panel_window, size + 1, 1,
+                       " 's' : sort, space : toggle");
+       wattroff(pref_panel_window, A_BOLD);
+
+       if (*line_selected > (size - 1))
+               *line_selected = size - 1;
+       if (toggle_sort == 1) {
+               if (iostreamtopview[*line_selected].sort == 1)
+                       iostreamtopview[*line_selected].reverse = 1;
+               for (i = 0; i < size; i++)
+                       iostreamtopview[i].sort = 0;
+               iostreamtopview[*line_selected].sort = 1;
+               update_current_view();
+       }
+
+       for (i = 0; i < size; i++) {
+               if (i == *line_selected) {
+                       wattron(pref_panel_window, COLOR_PAIR(5));
+                       mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
+               }
+               if (iostreamtopview[i].sort == 1)
+                       wattron(pref_panel_window, A_BOLD);
+               mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
+                               iostreamtopview[i].title);
+               wattroff(pref_panel_window, A_BOLD);
+               wattroff(pref_panel_window, COLOR_PAIR(5));
+
+       }
+       update_panels();
+       doupdate();
+}
+
+void update_cpu_pref(int *line_selected, int toggle_view, int toggle_sort)
+{
+       int i;
+       int size;
+
+       if (!data)
+               return;
+       if (pref_panel_window) {
+               del_panel(pref_panel);
+               delwin(pref_panel_window);
+       }
+       size = 4;
+
+       pref_panel_window = create_window(size + 2, 30, 10, 10);
+       pref_panel = new_panel(pref_panel_window);
+
+       werase(pref_panel_window);
+       box(pref_panel_window, 0 , 0);
+       set_window_title(pref_panel_window, "CPUTop Preferences ");
+       wattron(pref_panel_window, A_BOLD);
+       mvwprintw(pref_panel_window, size + 1, 1,
+                       " 's' : sort, space : toggle");
+       wattroff(pref_panel_window, A_BOLD);
+
+       if (*line_selected > (size - 1))
+               *line_selected = size - 1;
+       if (toggle_sort == 1) {
+               /* special case, we don't support sorting by procname for now */
+               if (*line_selected != 3) {
+                       if (cputopview[*line_selected].sort == 1)
+                               cputopview[*line_selected].reverse = 1;
+                       for (i = 0; i < size; i++)
+                               cputopview[i].sort = 0;
+                       cputopview[*line_selected].sort = 1;
+                       update_current_view();
+               }
+       }
+
+       for (i = 0; i < size; i++) {
+               if (i == *line_selected) {
+                       wattron(pref_panel_window, COLOR_PAIR(5));
+                       mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
+               }
+               if (cputopview[i].sort == 1)
+                       wattron(pref_panel_window, A_BOLD);
+               mvwprintw(pref_panel_window, i + 1, 1, "[-] %s",
+                               cputopview[i].title);
+               wattroff(pref_panel_window, A_BOLD);
+               wattroff(pref_panel_window, COLOR_PAIR(5));
+
+       }
+       update_panels();
+       doupdate();
+}
+
+void update_perf_pref(int *line_selected, int toggle_view, int toggle_sort)
 {
        int i;
        struct perfcounter *perf;
@@ -760,15 +1073,13 @@ void update_perf_panel(int line_selected, int toggle_view, int toggle_sort)
 
        pref_panel_window = create_window(size + 2, 30, 10, 10);
        pref_panel = new_panel(pref_panel_window);
-       pref_panel_visible = 0;
-       hide_panel(pref_panel);
 
        werase(pref_panel_window);
        box(pref_panel_window, 0 , 0);
        set_window_title(pref_panel_window, "Perf Preferences ");
        wattron(pref_panel_window, A_BOLD);
        mvwprintw(pref_panel_window, g_hash_table_size(global_perf_liszt) + 1, 1,
-                       " 's' to sort");
+                       " 's' : sort, space : toggle");
        wattroff(pref_panel_window, A_BOLD);
 
        if (toggle_sort == 1) {
@@ -776,7 +1087,7 @@ void update_perf_panel(int line_selected, int toggle_view, int toggle_sort)
                perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt));
                while (perflist) {
                        perf = g_hash_table_lookup(global_perf_liszt, perflist->data);
-                       if (i != line_selected)
+                       if (i != *line_selected)
                                perf->sort = 0;
                        else
                                perf->sort = 1;
@@ -790,11 +1101,11 @@ void update_perf_panel(int line_selected, int toggle_view, int toggle_sort)
        perflist = g_list_first(g_hash_table_get_keys(global_perf_liszt));
        while (perflist) {
                perf = g_hash_table_lookup(global_perf_liszt, perflist->data);
-               if (i == line_selected && toggle_view == 1) {
+               if (i == *line_selected && toggle_view == 1) {
                        perf->visible = perf->visible == 1 ? 0:1;
                        update_current_view();
                }
-               if (i == line_selected) {
+               if (i == *line_selected) {
                        wattron(pref_panel_window, COLOR_PAIR(5));
                        mvwhline(pref_panel_window, i + 1, 1, ' ', 30 - 2);
                }
@@ -812,13 +1123,22 @@ void update_perf_panel(int line_selected, int toggle_view, int toggle_sort)
        doupdate();
 }
 
-int update_preference_panel(int line_selected, int toggle_view, int toggle_sort)
+int update_preference_panel(int *line_selected, int toggle_view, int toggle_sort)
 {
        int ret = 0;
 
        switch(current_view) {
                case perf:
-                       update_perf_panel(line_selected, toggle_view, toggle_sort);
+                       update_perf_pref(line_selected, toggle_view, toggle_sort);
+                       break;
+               case cpu:
+                       update_cpu_pref(line_selected, toggle_view, toggle_sort);
+                       break;
+               case iostream:
+                       update_iostream_pref(line_selected, toggle_view, toggle_sort);
+                       break;
+               case process_details:
+                       update_process_detail_pref(line_selected, toggle_view, toggle_sort);
                        break;
                default:
                        ret = -1;
@@ -836,7 +1156,7 @@ void toggle_pref_panel(void)
                hide_panel(pref_panel);
                pref_panel_visible = 0;
        } else {
-               ret = update_preference_panel(perf_line_selected, 0, 0);
+               ret = update_preference_panel(&pref_line_selected, 0, 0);
                if (ret < 0)
                        return;
                show_panel(pref_panel);
@@ -880,11 +1200,11 @@ void *handle_keyboard(void *p)
        while((ch = getch())) {
                switch(ch) {
                /* Move the cursor and scroll */
+               case 'j':
                case KEY_DOWN:
                        if (pref_panel_visible) {
-                               if (perf_line_selected < g_hash_table_size(global_perf_liszt) - 1)
-                                       perf_line_selected++;
-                               update_preference_panel(perf_line_selected, 0, 0);
+                               pref_line_selected++;
+                               update_preference_panel(&pref_line_selected, 0, 0);
                        } else {
                                if (selected_line < (max_center_lines - 1) &&
                                                selected_line < max_elements - 1) {
@@ -900,11 +1220,12 @@ void *handle_keyboard(void *p)
                        break;
                case KEY_NPAGE:
                        break;
+               case 'k':
                case KEY_UP:
                        if (pref_panel_visible) {
-                               if (perf_line_selected > 0)
-                                       perf_line_selected--;
-                               update_preference_panel(perf_line_selected, 0, 0);
+                               if (pref_line_selected > 0)
+                                       pref_line_selected--;
+                               update_preference_panel(&pref_line_selected, 0, 0);
                        } else {
                                if (selected_line > 0) {
                                        selected_line--;
@@ -948,15 +1269,17 @@ void *handle_keyboard(void *p)
                        } else {
                                print_log("Manually moving forward");
                                sem_post(&timer);
-                               /* we force to resume the refresh when moving forward */
-                               if (toggle_pause > 0)
-                                       resume_display();
+                               if (toggle_pause > 0) {
+                                       sem_post(&pause_sem);
+                                       update_current_view();
+                                       sem_wait(&pause_sem);
+                               }
                        }
 
                        break;
                case ' ':
                        if (pref_panel_visible) {
-                               update_preference_panel(perf_line_selected, 1, 0);
+                               update_preference_panel(&pref_line_selected, 1, 0);
                        } else {
                                update_selected_processes();
                                update_current_view();
@@ -964,10 +1287,12 @@ void *handle_keyboard(void *p)
                        break;
                case 's':
                        if (pref_panel_visible)
-                               update_preference_panel(perf_line_selected, 0, 1);
+                               update_preference_panel(&pref_line_selected, 0, 1);
                        break;
 
                case 13: /* FIXME : KEY_ENTER ?? */
+                       if (pref_panel_visible)
+                               break;
                        if (current_view != process_details) {
                                previous_view = current_view;
                                current_view = process_details;
@@ -979,21 +1304,29 @@ void *handle_keyboard(void *p)
                        break;
 
                case KEY_F(1):
+                       if (pref_panel_visible)
+                               toggle_pref_panel();
                        current_view = cpu;
                        selected_line = 0;
                        update_current_view();
                        break;
                case KEY_F(2):
+                       if (pref_panel_visible)
+                               toggle_pref_panel();
                        current_view = cpu;
                        selected_line = 0;
                        update_current_view();
                        break;
                case KEY_F(3):
+                       if (pref_panel_visible)
+                               toggle_pref_panel();
                        current_view = perf;
                        selected_line = 0;
                        update_current_view();
                        break;
                case KEY_F(4):
+                       if (pref_panel_visible)
+                               toggle_pref_panel();
                        current_view = iostream;
                        selected_line = 0;
                        update_current_view();
@@ -1013,9 +1346,19 @@ void *handle_keyboard(void *p)
                                resume_display();
                        }
                        break;
-               case 'P':
+               case 'r':
                        toggle_pref_panel();
                        break;
+               /* ESCAPE, but slow to process, don't know why */
+               case 27:
+                       if (pref_panel_visible)
+                               toggle_pref_panel();
+                       else if (current_view == process_details) {
+                               current_view = previous_view;
+                               previous_view = process_details;
+                       }
+                       update_current_view();
+                       break;
                default:
                        if (data)
                                update_current_view();
@@ -1026,10 +1369,30 @@ void *handle_keyboard(void *p)
        return NULL;
 }
 
+void init_view_headers()
+{
+       cputopview[0].title = strdup("CPU(%)");
+       cputopview[0].sort = 1;
+       cputopview[1].title = strdup("TGID");
+       cputopview[2].title = strdup("PID");
+       cputopview[3].title = strdup("NAME");
+
+       iostreamtopview[0].title = strdup("R (B/sec)");
+       iostreamtopview[1].title = strdup("W (B/sec)");
+       iostreamtopview[2].title = strdup("Total (B)");
+       iostreamtopview[2].sort = 1;
+
+       fileview[0].title = strdup("FD");
+       fileview[1].title = strdup("READ");
+       fileview[1].sort = 1;
+       fileview[2].title = strdup("WRITE");
+}
+
 void init_ncurses()
 {
        selected_processes = g_ptr_array_new();
        sem_init(&update_display_sem, 0, 1);
+       init_view_headers();
        init_screen();
 
        header = create_window(5, COLS - 1, 0, 0);
This page took 0.03144 seconds and 4 git commands to generate.