Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
util.c
Go to the documentation of this file.
1 #include "../../util/util.h"
2 #include <signal.h>
3 #include <stdbool.h>
4 #include <string.h>
5 #include <sys/ttydefaults.h>
6 
7 #include "../../util/cache.h"
8 #include "../../util/debug.h"
9 #include "../browser.h"
10 #include "../keysyms.h"
11 #include "../helpline.h"
12 #include "../ui.h"
13 #include "../util.h"
14 #include "../libslang.h"
15 
16 static void ui_browser__argv_write(struct ui_browser *browser,
17  void *entry, int row)
18 {
19  char **arg = entry;
20  bool current_entry = ui_browser__is_current_entry(browser, row);
21 
22  ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
24  slsmg_write_nstring(*arg, browser->width);
25 }
26 
27 static int popup_menu__run(struct ui_browser *menu)
28 {
29  int key;
30 
31  if (ui_browser__show(menu, " ", "ESC: exit, ENTER|->: Select option") < 0)
32  return -1;
33 
34  while (1) {
35  key = ui_browser__run(menu, 0);
36 
37  switch (key) {
38  case K_RIGHT:
39  case K_ENTER:
40  key = menu->index;
41  break;
42  case K_LEFT:
43  case K_ESC:
44  case 'q':
45  case CTRL('c'):
46  key = -1;
47  break;
48  default:
49  continue;
50  }
51 
52  break;
53  }
54 
55  ui_browser__hide(menu);
56  return key;
57 }
58 
59 int ui__popup_menu(int argc, char * const argv[])
60 {
61  struct ui_browser menu = {
62  .entries = (void *)argv,
65  .write = ui_browser__argv_write,
66  .nr_entries = argc,
67  };
68 
69  return popup_menu__run(&menu);
70 }
71 
72 int ui_browser__input_window(const char *title, const char *text, char *input,
73  const char *exit_msg, int delay_secs)
74 {
75  int x, y, len, key;
76  int max_len = 60, nr_lines = 0;
77  static char buf[50];
78  const char *t;
79 
80  t = text;
81  while (1) {
82  const char *sep = strchr(t, '\n');
83 
84  if (sep == NULL)
85  sep = strchr(t, '\0');
86  len = sep - t;
87  if (max_len < len)
88  max_len = len;
89  ++nr_lines;
90  if (*sep == '\0')
91  break;
92  t = sep + 1;
93  }
94 
95  max_len += 2;
96  nr_lines += 8;
97  y = SLtt_Screen_Rows / 2 - nr_lines / 2;
98  x = SLtt_Screen_Cols / 2 - max_len / 2;
99 
100  SLsmg_set_color(0);
101  SLsmg_draw_box(y, x++, nr_lines, max_len);
102  if (title) {
103  SLsmg_gotorc(y, x + 1);
104  SLsmg_write_string((char *)title);
105  }
106  SLsmg_gotorc(++y, x);
107  nr_lines -= 7;
108  max_len -= 2;
109  SLsmg_write_wrapped_string((unsigned char *)text, y, x,
110  nr_lines, max_len, 1);
111  y += nr_lines;
112  len = 5;
113  while (len--) {
114  SLsmg_gotorc(y + len - 1, x);
115  SLsmg_write_nstring((char *)" ", max_len);
116  }
117  SLsmg_draw_box(y++, x + 1, 3, max_len - 2);
118 
119  SLsmg_gotorc(y + 3, x);
120  SLsmg_write_nstring((char *)exit_msg, max_len);
121  SLsmg_refresh();
122 
123  x += 2;
124  len = 0;
125  key = ui__getch(delay_secs);
126  while (key != K_TIMER && key != K_ENTER && key != K_ESC) {
127  if (key == K_BKSPC) {
128  if (len == 0)
129  goto next_key;
130  SLsmg_gotorc(y, x + --len);
131  SLsmg_write_char(' ');
132  } else {
133  buf[len] = key;
134  SLsmg_gotorc(y, x + len++);
135  SLsmg_write_char(key);
136  }
137  SLsmg_refresh();
138 
139  /* XXX more graceful overflow handling needed */
140  if (len == sizeof(buf) - 1) {
141  ui_helpline__push("maximum size of symbol name reached!");
142  key = K_ENTER;
143  break;
144  }
145 next_key:
146  key = ui__getch(delay_secs);
147  }
148 
149  buf[len] = '\0';
150  strncpy(input, buf, len+1);
151  return key;
152 }
153 
154 int ui__question_window(const char *title, const char *text,
155  const char *exit_msg, int delay_secs)
156 {
157  int x, y;
158  int max_len = 0, nr_lines = 0;
159  const char *t;
160 
161  t = text;
162  while (1) {
163  const char *sep = strchr(t, '\n');
164  int len;
165 
166  if (sep == NULL)
167  sep = strchr(t, '\0');
168  len = sep - t;
169  if (max_len < len)
170  max_len = len;
171  ++nr_lines;
172  if (*sep == '\0')
173  break;
174  t = sep + 1;
175  }
176 
177  max_len += 2;
178  nr_lines += 4;
179  y = SLtt_Screen_Rows / 2 - nr_lines / 2,
180  x = SLtt_Screen_Cols / 2 - max_len / 2;
181 
182  SLsmg_set_color(0);
183  SLsmg_draw_box(y, x++, nr_lines, max_len);
184  if (title) {
185  SLsmg_gotorc(y, x + 1);
186  SLsmg_write_string((char *)title);
187  }
188  SLsmg_gotorc(++y, x);
189  nr_lines -= 2;
190  max_len -= 2;
191  SLsmg_write_wrapped_string((unsigned char *)text, y, x,
192  nr_lines, max_len, 1);
193  SLsmg_gotorc(y + nr_lines - 2, x);
194  SLsmg_write_nstring((char *)" ", max_len);
195  SLsmg_gotorc(y + nr_lines - 1, x);
196  SLsmg_write_nstring((char *)exit_msg, max_len);
197  SLsmg_refresh();
198  return ui__getch(delay_secs);
199 }
200 
201 int ui__help_window(const char *text)
202 {
203  return ui__question_window("Help", text, "Press any key...", 0);
204 }
205 
206 int ui__dialog_yesno(const char *msg)
207 {
208  return ui__question_window(NULL, msg, "Enter: Yes, ESC: No", 0);
209 }
210 
211 static int __ui__warning(const char *title, const char *format, va_list args)
212 {
213  char *s;
214 
215  if (vasprintf(&s, format, args) > 0) {
216  int key;
217 
218  pthread_mutex_lock(&ui__lock);
219  key = ui__question_window(title, s, "Press any key...", 0);
220  pthread_mutex_unlock(&ui__lock);
221  free(s);
222  return key;
223  }
224 
225  fprintf(stderr, "%s\n", title);
226  vfprintf(stderr, format, args);
227  return K_ESC;
228 }
229 
230 static int perf_tui__error(const char *format, va_list args)
231 {
232  return __ui__warning("Error:", format, args);
233 }
234 
235 static int perf_tui__warning(const char *format, va_list args)
236 {
237  return __ui__warning("Warning:", format, args);
238 }
239 
241  .error = perf_tui__error,
242  .warning = perf_tui__warning,
243 };