1/*
2 * Copyright (c) 2009 Apple Computer, Inc.  All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <curses.h>
26#include "preferences.h"
27#include "userinput_help.h"
28#include "top.h"
29
30static struct {
31    int yoffset;
32    WINDOW *window;
33    PANEL *panel;
34    WINDOW *state;
35    WINDOW *command;
36    WINDOW *description;
37} help = {
38    .yoffset = 0,
39    .window = NULL,
40    .panel = NULL,
41    .state = NULL,
42    .command = NULL,
43    .description = NULL
44};
45
46static void help_completion(void *tinst, struct user_input_state *s) {
47    user_input_set_state(NULL);
48}
49
50static void help_draw_text_line(const char *statestr, const char *cmdstr,
51				const char *dstr) {
52    mvwaddstr(help.state, help.yoffset, 0, statestr);
53    mvwaddstr(help.command, help.yoffset, 0, cmdstr);
54    mvwaddstr(help.description, help.yoffset, 0, dstr);
55
56    help.yoffset += 1;
57}
58
59static void help_draw_text(void) {
60    char buf[32];
61    const char *user;
62
63    wattron(help.state, A_UNDERLINE);
64    mvwaddstr(help.state, 0, 0, "State");
65    wattroff(help.state, A_UNDERLINE);
66
67    wattron(help.command, A_UNDERLINE);
68    mvwaddstr(help.command, 0, 0, "Command");
69    wattroff(help.command, A_UNDERLINE);
70
71    wattron(help.description, A_UNDERLINE);
72    mvwaddstr(help.description, 0, 0, "Description");
73    wattroff(help.description, A_UNDERLINE);
74
75    help.yoffset += 1;
76
77    help_draw_text_line("", "?", "Display this help screen.");
78    help_draw_text_line(top_prefs_get_mode_string(), "c<mode>", "Set event counting mode to {a|d|e|n}.");
79    help_draw_text_line(top_prefs_get_sort_string(), "o<key>", "Set primary sort key to <key>: [+-]keyname.");
80    help_draw_text_line("", "", "Keyname may be:{pid|command|cpu|csw|time|threads|");
81    help_draw_text_line("", "", "ports|mregion|rprvt|rshrd|rsize|vsize|vprvt|pgrp|");
82    help_draw_text_line("", "", "ppid|state|uid|wq|faults|cow|user|msgsent|msgrecv|");
83    help_draw_text_line("", "", "sysbsd|sysmach|pageins}.");
84    help_draw_text_line(top_prefs_get_secondary_sort_string(), "O<skey>", "Set secondary sort key to <skey> (see o<key>).");
85    help_draw_text_line("", "q", "Quit top.");
86    help_draw_text_line("", "S<sig>\\n<pid>", "Send signal <sig> to pid <pid>.");
87
88    if(-1 == snprintf(buf, sizeof(buf), "%d", top_prefs_get_sleep()))
89	buf[0] = '\0';
90
91    help_draw_text_line(buf, "s<delay>", "Set the delay between updates to <delay> seconds.");
92
93    help_draw_text_line(top_prefs_get_mmr() ? "on" : "off",
94			"r", "Toggle the memory map reporting.");
95
96    user = top_prefs_get_user();
97
98    help_draw_text_line(user ? user : "", "U<user>", "Only display processes owned by <user>, or all.");
99
100    mvwaddstr(help.window, LINES - 1, 0, "Press any key to continue...");
101}
102
103static void help_cleanup(void) {
104    if(help.panel) {
105	del_panel(help.panel);
106	help.panel = NULL;
107    }
108
109    if(help.window) {
110	delwin(help.window);
111	help.window = NULL;
112    }
113
114    if(help.state) {
115	delwin(help.state);
116	help.state = NULL;
117    }
118
119    if(help.command) {
120	delwin(help.command);
121	help.command = NULL;
122    }
123
124    if(help.description) {
125	delwin(help.description);
126	help.description = NULL;
127    }
128}
129
130static void help_draw(void *tinst, struct user_input_state *s, WINDOW *win,
131		       int row, int column) {
132    int c;
133
134    do {
135	help.yoffset = 0;
136	help.window = newwin(LINES, COLS, 0, 0);
137
138	if(NULL == help.window) {
139	    user_input_set_state(NULL);
140	    return;
141	}
142
143	help.panel = new_panel(help.window);
144
145	if(NULL == help.panel) {
146	    help_cleanup();
147	    user_input_set_state(NULL);
148	    return;
149	}
150
151	help.state = derwin(help.window, LINES - 1, 10, /*y*/ 0, /*x*/ 0);
152	help.command = derwin(help.window, LINES - 1, 15, /*y*/ 0,
153			      /*x*/ 10);
154	help.description = derwin(help.window, LINES - 1, COLS - 25, /*y*/ 0,
155				  /*x*/ 25);
156
157	if(NULL == help.state || NULL == help.command || NULL == help.description) {
158	    help_cleanup();
159	    user_input_set_state(NULL);
160	    return;
161	}
162
163	help_draw_text();
164
165	/* Wait for a key press. */
166	wtimeout(help.window, -1);
167	c = wgetch(help.window);
168
169	help_cleanup();
170    } while(KEY_RESIZE == c);
171
172    user_input_set_state(NULL);
173 }
174
175struct user_input_state top_user_input_help_state = {
176    .offset = 0,
177    .completion = help_completion,
178    .draw = help_draw
179};
180