8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / powertop / common / suggestions.c
blob348cae502e6b61fe058ae07e2686461a817e9e84
1 /*
2 * Copyright 2009, Intel Corporation
3 * Copyright 2009, Sun Microsystems, Inc
5 * This file is part of PowerTOP
7 * This program file is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program in a file named COPYING; if not, write to the
18 * Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
22 * Authors:
23 * Arjan van de Ven <arjan@linux.intel.com>
24 * Eric C Saxe <eric.saxe@sun.com>
25 * Aubrey Li <aubrey.li@intel.com>
29 * GPL Disclaimer
31 * For the avoidance of doubt, except that if any license choice other
32 * than GPL or LGPL is available it will apply instead, Sun elects to
33 * use only the General Public License version 2 (GPLv2) at this time
34 * for any software where a choice of GPL license versions is made
35 * available with the language indicating that GPLv2 or any later
36 * version may be used, or where a choice of which version of the GPL
37 * is applied is otherwise unspecified.
40 #include <unistd.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include "powertop.h"
47 * Default number of intervals we display a suggestion before moving
48 * to the next.
50 #define PT_SUGG_DEF_SLICE 3
53 * Global pointer to the current suggestion.
55 sugg_t *g_curr_sugg;
58 * Head of the list of suggestions.
60 static sugg_t *sugg;
63 * Add a new suggestion. Only one suggestion per text allowed.
65 void
66 pt_sugg_add(char *text, int weight, char key, char *sb_msg, sugg_func_t *func)
68 sugg_t *new, *n, *pos = NULL;
71 * Text is a required field for suggestions
73 if (text == NULL)
74 return;
76 if (sugg == NULL) {
78 * Creating first element
80 if ((new = calloc(1, sizeof (sugg_t))) == NULL)
81 return;
83 if (sb_msg != NULL)
84 new->sb_msg = strdup(sb_msg);
86 if (text != NULL)
87 new->text = strdup(text);
89 new->weight = weight;
90 new->key = key;
91 new->func = func;
92 new->slice = 0;
94 sugg = new;
95 new->prev = NULL;
96 new->next = NULL;
97 } else {
98 for (n = sugg; n != NULL; n = n->next) {
99 if (strcmp(n->text, text) == 0)
100 return;
102 if (weight > n->weight && pos == NULL)
103 pos = n;
106 * Create a new element
108 if ((new = calloc(1, sizeof (sugg_t))) == NULL)
109 return;
111 if (sb_msg != NULL)
112 new->sb_msg = strdup(sb_msg);
114 new->text = strdup(text);
116 new->weight = weight;
117 new->key = key;
118 new->func = func;
119 new->slice = 0;
121 if (pos == NULL) {
123 * Ordering placed the new element at the end
125 for (n = sugg; n->next != NULL; n = n->next)
128 n->next = new;
129 new->prev = n;
130 new->next = NULL;
131 } else {
132 if (pos == sugg) {
134 * Ordering placed the new element at the start
136 new->next = sugg;
137 new->prev = sugg;
138 sugg->prev = new;
139 sugg = new;
140 } else {
142 * Ordering placed the new element somewhere in
143 * the middle
145 new->next = pos;
146 new->prev = pos->prev;
147 pos->prev->next = new;
148 pos->prev = new;
155 * Removes a suggestion, returning 0 if not found and 1 if so.
158 pt_sugg_remove(sugg_func_t *func)
160 sugg_t *n;
161 int ret = 0;
163 for (n = sugg; n != NULL; n = n->next) {
164 if (n->func == func) {
165 /* Removing the first element */
166 if (n == sugg) {
167 if (sugg->next == NULL) {
168 /* Removing the only element */
169 sugg = NULL;
170 } else {
171 sugg = n->next;
172 sugg->prev = NULL;
174 } else {
175 if (n->next == NULL) {
176 /* Removing the last element */
177 n->prev->next = NULL;
178 } else {
179 /* Removing an intermediate element */
180 n->prev->next = n->next;
181 n->next->prev = n->prev;
186 * If this suggestions is currently being suggested,
187 * remove it and update the screen.
189 if (n == g_curr_sugg) {
190 if (n->sb_msg != NULL) {
191 pt_display_mod_status_bar(n->sb_msg);
192 pt_display_status_bar();
194 if (n->text != NULL)
195 pt_display_suggestions(NULL);
198 free(n);
199 ret = 1;
203 return (ret);
207 * Chose a suggestion to display. The list of suggestions is ordered by weight,
208 * so we only worry about fariness here. Each suggestion, starting with the
209 * first (the 'heaviest') is displayed during PT_SUGG_DEF_SLICE intervals.
211 void
212 pt_sugg_pick(void)
214 sugg_t *n;
216 if (sugg == NULL) {
217 g_curr_sugg = NULL;
218 return;
221 search:
222 for (n = sugg; n != NULL; n = n->next) {
224 if (n->slice++ < PT_SUGG_DEF_SLICE) {
227 * Don't need to re-suggest the current suggestion.
229 if (g_curr_sugg == n && !g_sig_resize)
230 return;
233 * Remove the current suggestion from screen.
235 if (g_curr_sugg != NULL) {
236 if (g_curr_sugg->sb_msg != NULL) {
237 pt_display_mod_status_bar(
238 g_curr_sugg->sb_msg);
239 pt_display_status_bar();
241 if (g_curr_sugg->text != NULL)
242 pt_display_suggestions(NULL);
245 if (n->sb_msg != NULL) {
246 pt_display_mod_status_bar(n->sb_msg);
247 pt_display_status_bar();
250 pt_display_suggestions(n->text);
252 g_curr_sugg = n;
254 return;
259 * All suggestions have run out of slice quotas, so we restart.
261 for (n = sugg; n != NULL; n = n->next)
262 n->slice = 0;
264 goto search;
267 void
268 pt_sugg_as_root(void)
270 pt_sugg_add("Suggestion: run as root to get suggestions"
271 " for reducing system power consumption", 40, NULL, NULL,
272 NULL);