14c8945a0SNathan Whitehorn /*
2*a96ef450SBaptiste Daroussin * $Id: guage.c,v 1.83 2020/03/27 20:54:43 tom Exp $
34c8945a0SNathan Whitehorn *
44c8945a0SNathan Whitehorn * guage.c -- implements the gauge dialog
54c8945a0SNathan Whitehorn *
6*a96ef450SBaptiste Daroussin * Copyright 2000-2019,2020 Thomas E. Dickey
74c8945a0SNathan Whitehorn *
84c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify
94c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public License, version 2.1
104c8945a0SNathan Whitehorn * as published by the Free Software Foundation.
114c8945a0SNathan Whitehorn *
124c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but
134c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of
144c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
154c8945a0SNathan Whitehorn * Lesser General Public License for more details.
164c8945a0SNathan Whitehorn *
174c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public
184c8945a0SNathan Whitehorn * License along with this program; if not, write to
194c8945a0SNathan Whitehorn * Free Software Foundation, Inc.
204c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor
214c8945a0SNathan Whitehorn * Boston, MA 02110, USA.
224c8945a0SNathan Whitehorn *
234c8945a0SNathan Whitehorn * An earlier version of this program lists as authors
244c8945a0SNathan Whitehorn * Marc Ewing, Red Hat Software
254c8945a0SNathan Whitehorn */
264c8945a0SNathan Whitehorn
274c8945a0SNathan Whitehorn #include <dialog.h>
284c8945a0SNathan Whitehorn
294c8945a0SNathan Whitehorn #include <errno.h>
304c8945a0SNathan Whitehorn
314c8945a0SNathan Whitehorn #define MY_LEN (MAX_LEN)/2
324c8945a0SNathan Whitehorn
334c8945a0SNathan Whitehorn #define MIN_HIGH (4)
344c8945a0SNathan Whitehorn #define MIN_WIDE (10 + 2 * (2 + MARGIN))
354c8945a0SNathan Whitehorn
367a1c0d96SNathan Whitehorn #define isMarker(buf) !strncmp(buf, "XXX", (size_t) 3)
374c8945a0SNathan Whitehorn
38682c9e0fSNathan Whitehorn typedef struct _my_obj {
39682c9e0fSNathan Whitehorn DIALOG_CALLBACK obj; /* has to be first in struct */
40682c9e0fSNathan Whitehorn struct _my_obj *next;
414c8945a0SNathan Whitehorn WINDOW *text;
42febdb468SDevin Teske char *title;
434c8945a0SNathan Whitehorn char *prompt;
444c8945a0SNathan Whitehorn char prompt_buf[MY_LEN];
454c8945a0SNathan Whitehorn int percent;
464c8945a0SNathan Whitehorn int height;
474c8945a0SNathan Whitehorn int width;
484c8945a0SNathan Whitehorn char line[MAX_LEN + 1];
494c8945a0SNathan Whitehorn } MY_OBJ;
504c8945a0SNathan Whitehorn
51682c9e0fSNathan Whitehorn static MY_OBJ *all_objects;
52682c9e0fSNathan Whitehorn
53682c9e0fSNathan Whitehorn static int
valid(MY_OBJ * obj)54682c9e0fSNathan Whitehorn valid(MY_OBJ * obj)
55682c9e0fSNathan Whitehorn {
56682c9e0fSNathan Whitehorn MY_OBJ *list = all_objects;
57682c9e0fSNathan Whitehorn int result = 0;
58682c9e0fSNathan Whitehorn
59682c9e0fSNathan Whitehorn while (list != 0) {
60682c9e0fSNathan Whitehorn if (list == obj) {
61682c9e0fSNathan Whitehorn result = 1;
62682c9e0fSNathan Whitehorn break;
63682c9e0fSNathan Whitehorn }
64682c9e0fSNathan Whitehorn list = list->next;
65682c9e0fSNathan Whitehorn }
66682c9e0fSNathan Whitehorn return result;
67682c9e0fSNathan Whitehorn }
68682c9e0fSNathan Whitehorn
69682c9e0fSNathan Whitehorn static void
delink(MY_OBJ * obj)70682c9e0fSNathan Whitehorn delink(MY_OBJ * obj)
71682c9e0fSNathan Whitehorn {
72682c9e0fSNathan Whitehorn MY_OBJ *p = all_objects;
73682c9e0fSNathan Whitehorn MY_OBJ *q = 0;
74682c9e0fSNathan Whitehorn while (p != 0) {
75682c9e0fSNathan Whitehorn if (p == obj) {
76682c9e0fSNathan Whitehorn if (q != 0) {
77682c9e0fSNathan Whitehorn q->next = p->next;
78682c9e0fSNathan Whitehorn } else {
79682c9e0fSNathan Whitehorn all_objects = p->next;
80682c9e0fSNathan Whitehorn }
81682c9e0fSNathan Whitehorn break;
82682c9e0fSNathan Whitehorn }
83682c9e0fSNathan Whitehorn q = p;
84682c9e0fSNathan Whitehorn p = p->next;
85682c9e0fSNathan Whitehorn }
86682c9e0fSNathan Whitehorn }
87682c9e0fSNathan Whitehorn
884c8945a0SNathan Whitehorn static int
read_data(char * buffer,FILE * fp)894c8945a0SNathan Whitehorn read_data(char *buffer, FILE *fp)
904c8945a0SNathan Whitehorn {
914c8945a0SNathan Whitehorn int result;
924c8945a0SNathan Whitehorn
934c8945a0SNathan Whitehorn if (feof(fp)) {
944c8945a0SNathan Whitehorn result = 0;
954c8945a0SNathan Whitehorn } else if (fgets(buffer, MY_LEN, fp) != 0) {
96682c9e0fSNathan Whitehorn DLG_TRACE(("read_data:%s", buffer));
972a3e3873SBaptiste Daroussin buffer[MY_LEN] = '\0';
984c8945a0SNathan Whitehorn dlg_trim_string(buffer);
994c8945a0SNathan Whitehorn result = 1;
1004c8945a0SNathan Whitehorn } else {
1014c8945a0SNathan Whitehorn result = -1;
1024c8945a0SNathan Whitehorn }
1034c8945a0SNathan Whitehorn return result;
1044c8945a0SNathan Whitehorn }
1054c8945a0SNathan Whitehorn
1064c8945a0SNathan Whitehorn static int
decode_percent(char * buffer)1074c8945a0SNathan Whitehorn decode_percent(char *buffer)
1084c8945a0SNathan Whitehorn {
1094c8945a0SNathan Whitehorn char *tmp = 0;
1104c8945a0SNathan Whitehorn long value = strtol(buffer, &tmp, 10);
1114c8945a0SNathan Whitehorn
1124c8945a0SNathan Whitehorn if (tmp != 0 && (*tmp == 0 || isspace(UCH(*tmp))) && value >= 0) {
1134c8945a0SNathan Whitehorn return TRUE;
1144c8945a0SNathan Whitehorn }
1154c8945a0SNathan Whitehorn return FALSE;
1164c8945a0SNathan Whitehorn }
1174c8945a0SNathan Whitehorn
1184c8945a0SNathan Whitehorn static void
repaint_text(MY_OBJ * obj)1194c8945a0SNathan Whitehorn repaint_text(MY_OBJ * obj)
1204c8945a0SNathan Whitehorn {
1214c8945a0SNathan Whitehorn WINDOW *dialog = obj->obj.win;
1224c8945a0SNathan Whitehorn
123f4f33ea0SBaptiste Daroussin if (dialog != 0) {
124*a96ef450SBaptiste Daroussin int i, x;
125*a96ef450SBaptiste Daroussin
1264c8945a0SNathan Whitehorn (void) werase(dialog);
1272a3e3873SBaptiste Daroussin dlg_draw_box2(dialog, 0, 0, obj->height, obj->width, dialog_attr,
1282a3e3873SBaptiste Daroussin border_attr, border2_attr);
1294c8945a0SNathan Whitehorn
1304c8945a0SNathan Whitehorn dlg_draw_title(dialog, obj->title);
1314c8945a0SNathan Whitehorn
132f4f33ea0SBaptiste Daroussin dlg_attrset(dialog, dialog_attr);
133682c9e0fSNathan Whitehorn dlg_draw_helpline(dialog, FALSE);
1344c8945a0SNathan Whitehorn dlg_print_autowrap(dialog, obj->prompt, obj->height, obj->width);
1354c8945a0SNathan Whitehorn
1362a3e3873SBaptiste Daroussin dlg_draw_box2(dialog,
1374c8945a0SNathan Whitehorn obj->height - 4, 2 + MARGIN,
1384c8945a0SNathan Whitehorn 2 + MARGIN, obj->width - 2 * (2 + MARGIN),
1394c8945a0SNathan Whitehorn dialog_attr,
1402a3e3873SBaptiste Daroussin border_attr,
1412a3e3873SBaptiste Daroussin border2_attr);
1424c8945a0SNathan Whitehorn
1434c8945a0SNathan Whitehorn /*
1444c8945a0SNathan Whitehorn * Clear the area for the progress bar by filling it with spaces
1452a3e3873SBaptiste Daroussin * in the gauge-attribute, and write the percentage with that
1464c8945a0SNathan Whitehorn * attribute.
1474c8945a0SNathan Whitehorn */
1484c8945a0SNathan Whitehorn (void) wmove(dialog, obj->height - 3, 4);
149f4f33ea0SBaptiste Daroussin dlg_attrset(dialog, gauge_attr);
1504c8945a0SNathan Whitehorn
1514c8945a0SNathan Whitehorn for (i = 0; i < (obj->width - 2 * (3 + MARGIN)); i++)
1524c8945a0SNathan Whitehorn (void) waddch(dialog, ' ');
1534c8945a0SNathan Whitehorn
1544c8945a0SNathan Whitehorn (void) wmove(dialog, obj->height - 3, (obj->width / 2) - 2);
1554c8945a0SNathan Whitehorn (void) wprintw(dialog, "%3d%%", obj->percent);
1564c8945a0SNathan Whitehorn
1574c8945a0SNathan Whitehorn /*
1584c8945a0SNathan Whitehorn * Now draw a bar in reverse, relative to the background.
1594c8945a0SNathan Whitehorn * The window attribute was useful for painting the background,
1604c8945a0SNathan Whitehorn * but requires some tweaks to reverse it.
1614c8945a0SNathan Whitehorn */
1624c8945a0SNathan Whitehorn x = (obj->percent * (obj->width - 2 * (3 + MARGIN))) / 100;
1632a3e3873SBaptiste Daroussin if ((gauge_attr & A_REVERSE) != 0) {
164f4f33ea0SBaptiste Daroussin dlg_attroff(dialog, A_REVERSE);
1654c8945a0SNathan Whitehorn } else {
166f4f33ea0SBaptiste Daroussin dlg_attrset(dialog, A_REVERSE);
1674c8945a0SNathan Whitehorn }
1684c8945a0SNathan Whitehorn (void) wmove(dialog, obj->height - 3, 4);
1694c8945a0SNathan Whitehorn for (i = 0; i < x; i++) {
1704c8945a0SNathan Whitehorn chtype ch2 = winch(dialog);
1712a3e3873SBaptiste Daroussin if (gauge_attr & A_REVERSE) {
1724c8945a0SNathan Whitehorn ch2 &= ~A_REVERSE;
1734c8945a0SNathan Whitehorn }
1744c8945a0SNathan Whitehorn (void) waddch(dialog, ch2);
1754c8945a0SNathan Whitehorn }
1764c8945a0SNathan Whitehorn
1774c8945a0SNathan Whitehorn (void) wrefresh(dialog);
1784c8945a0SNathan Whitehorn }
1797a1c0d96SNathan Whitehorn }
1804c8945a0SNathan Whitehorn
1817a1c0d96SNathan Whitehorn static bool
handle_input(DIALOG_CALLBACK * cb)1827a1c0d96SNathan Whitehorn handle_input(DIALOG_CALLBACK * cb)
1834c8945a0SNathan Whitehorn {
1847a1c0d96SNathan Whitehorn MY_OBJ *obj = (MY_OBJ *) cb;
1857a1c0d96SNathan Whitehorn bool result;
186f4f33ea0SBaptiste Daroussin bool cleanup = FALSE;
1874c8945a0SNathan Whitehorn int status;
1882a3e3873SBaptiste Daroussin char buf[MY_LEN + 1];
1894c8945a0SNathan Whitehorn
1907a1c0d96SNathan Whitehorn if (dialog_state.pipe_input == 0) {
1917a1c0d96SNathan Whitehorn status = -1;
192f4f33ea0SBaptiste Daroussin cleanup = TRUE;
1937a1c0d96SNathan Whitehorn } else if ((status = read_data(buf, dialog_state.pipe_input)) > 0) {
1944c8945a0SNathan Whitehorn
1954c8945a0SNathan Whitehorn if (isMarker(buf)) {
1964c8945a0SNathan Whitehorn /*
1974c8945a0SNathan Whitehorn * Historically, next line should be percentage, but one of the
1984c8945a0SNathan Whitehorn * worse-written clones of 'dialog' assumes the number is missing.
1994c8945a0SNathan Whitehorn * (Gresham's Law applied to software).
2004c8945a0SNathan Whitehorn */
2014c8945a0SNathan Whitehorn if ((status = read_data(buf, dialog_state.pipe_input)) > 0) {
2024c8945a0SNathan Whitehorn
2034c8945a0SNathan Whitehorn obj->prompt_buf[0] = '\0';
2044c8945a0SNathan Whitehorn if (decode_percent(buf))
2054c8945a0SNathan Whitehorn obj->percent = atoi(buf);
2064c8945a0SNathan Whitehorn else
2074c8945a0SNathan Whitehorn strcpy(obj->prompt_buf, buf);
2084c8945a0SNathan Whitehorn
2094c8945a0SNathan Whitehorn /* Rest is message text */
2104c8945a0SNathan Whitehorn while ((status = read_data(buf, dialog_state.pipe_input)) > 0
2114c8945a0SNathan Whitehorn && !isMarker(buf)) {
2124c8945a0SNathan Whitehorn if (strlen(obj->prompt_buf) + strlen(buf) <
2134c8945a0SNathan Whitehorn sizeof(obj->prompt_buf) - 1) {
2144c8945a0SNathan Whitehorn strcat(obj->prompt_buf, buf);
2154c8945a0SNathan Whitehorn }
2164c8945a0SNathan Whitehorn }
2174c8945a0SNathan Whitehorn
2184c8945a0SNathan Whitehorn if (obj->prompt != obj->prompt_buf)
2194c8945a0SNathan Whitehorn free(obj->prompt);
2204c8945a0SNathan Whitehorn obj->prompt = obj->prompt_buf;
2214c8945a0SNathan Whitehorn }
2224c8945a0SNathan Whitehorn } else if (decode_percent(buf)) {
2234c8945a0SNathan Whitehorn obj->percent = atoi(buf);
2244c8945a0SNathan Whitehorn }
2254c8945a0SNathan Whitehorn } else {
2267a1c0d96SNathan Whitehorn if (feof(dialog_state.pipe_input) ||
2277a1c0d96SNathan Whitehorn (ferror(dialog_state.pipe_input) && errno != EINTR)) {
228f4f33ea0SBaptiste Daroussin cleanup = TRUE;
2297a1c0d96SNathan Whitehorn }
2304c8945a0SNathan Whitehorn }
2314c8945a0SNathan Whitehorn
232f4f33ea0SBaptiste Daroussin repaint_text(obj);
2337a1c0d96SNathan Whitehorn if (status > 0) {
2347a1c0d96SNathan Whitehorn result = TRUE;
2357a1c0d96SNathan Whitehorn } else {
2367a1c0d96SNathan Whitehorn result = FALSE;
237f4f33ea0SBaptiste Daroussin if (cleanup) {
238f4f33ea0SBaptiste Daroussin dlg_remove_callback(cb);
239f4f33ea0SBaptiste Daroussin delink(obj);
240f4f33ea0SBaptiste Daroussin }
2417a1c0d96SNathan Whitehorn }
2427a1c0d96SNathan Whitehorn
2437a1c0d96SNathan Whitehorn return result;
2444c8945a0SNathan Whitehorn }
2454c8945a0SNathan Whitehorn
2464c8945a0SNathan Whitehorn static bool
handle_my_getc(DIALOG_CALLBACK * cb,int ch,int fkey,int * result)2474c8945a0SNathan Whitehorn handle_my_getc(DIALOG_CALLBACK * cb, int ch, int fkey, int *result)
2484c8945a0SNathan Whitehorn {
249f4f33ea0SBaptiste Daroussin bool status = TRUE;
2504c8945a0SNathan Whitehorn
2514c8945a0SNathan Whitehorn *result = DLG_EXIT_OK;
2527a1c0d96SNathan Whitehorn if (cb != 0) {
2534c8945a0SNathan Whitehorn if (!fkey && (ch == ERR)) {
2547a1c0d96SNathan Whitehorn (void) handle_input(cb);
255682c9e0fSNathan Whitehorn /* cb might be freed in handle_input */
256682c9e0fSNathan Whitehorn status = (valid((MY_OBJ *) cb) && (cb->input != 0));
2574c8945a0SNathan Whitehorn }
2584c8945a0SNathan Whitehorn } else {
2594c8945a0SNathan Whitehorn status = FALSE;
2604c8945a0SNathan Whitehorn }
2614c8945a0SNathan Whitehorn return status;
2624c8945a0SNathan Whitehorn }
2634c8945a0SNathan Whitehorn
2644c8945a0SNathan Whitehorn static void
my_cleanup(DIALOG_CALLBACK * cb)2654c8945a0SNathan Whitehorn my_cleanup(DIALOG_CALLBACK * cb)
2664c8945a0SNathan Whitehorn {
2674c8945a0SNathan Whitehorn MY_OBJ *obj = (MY_OBJ *) cb;
2684c8945a0SNathan Whitehorn
269682c9e0fSNathan Whitehorn if (valid(obj)) {
270682c9e0fSNathan Whitehorn if (obj->prompt != obj->prompt_buf) {
2714c8945a0SNathan Whitehorn free(obj->prompt);
272682c9e0fSNathan Whitehorn obj->prompt = obj->prompt_buf;
273682c9e0fSNathan Whitehorn }
274f4f33ea0SBaptiste Daroussin free(obj->title);
275f4f33ea0SBaptiste Daroussin dlg_del_window(obj->obj.win);
276682c9e0fSNathan Whitehorn delink(obj);
277682c9e0fSNathan Whitehorn }
278682c9e0fSNathan Whitehorn }
279682c9e0fSNathan Whitehorn
280682c9e0fSNathan Whitehorn void
dlg_update_gauge(void * objptr,int percent)281682c9e0fSNathan Whitehorn dlg_update_gauge(void *objptr, int percent)
282682c9e0fSNathan Whitehorn {
283682c9e0fSNathan Whitehorn MY_OBJ *obj = (MY_OBJ *) objptr;
284febdb468SDevin Teske bool save_finish_string = dialog_state.finish_string;
285682c9e0fSNathan Whitehorn
286febdb468SDevin Teske dialog_state.finish_string = TRUE;
287682c9e0fSNathan Whitehorn curs_set(0);
288682c9e0fSNathan Whitehorn obj->percent = percent;
289682c9e0fSNathan Whitehorn repaint_text(obj);
290febdb468SDevin Teske dialog_state.finish_string = save_finish_string;
291682c9e0fSNathan Whitehorn }
292682c9e0fSNathan Whitehorn
293682c9e0fSNathan Whitehorn /*
294febdb468SDevin Teske * (Re)Allocates an object and fills it as per the arguments
295682c9e0fSNathan Whitehorn */
296682c9e0fSNathan Whitehorn void *
dlg_reallocate_gauge(void * objptr,const char * title,const char * cprompt,int height,int width,int percent)297febdb468SDevin Teske dlg_reallocate_gauge(void *objptr,
298febdb468SDevin Teske const char *title,
299febdb468SDevin Teske const char *cprompt,
300febdb468SDevin Teske int height,
301febdb468SDevin Teske int width,
302febdb468SDevin Teske int percent)
303febdb468SDevin Teske {
304febdb468SDevin Teske char *prompt = dlg_strclone(cprompt);
305*a96ef450SBaptiste Daroussin MY_OBJ *obj;
306febdb468SDevin Teske bool save_finish_string = dialog_state.finish_string;
307febdb468SDevin Teske
308febdb468SDevin Teske dialog_state.finish_string = TRUE;
309febdb468SDevin Teske dlg_tab_correct_str(prompt);
310febdb468SDevin Teske
311febdb468SDevin Teske if (objptr == 0) {
312febdb468SDevin Teske /* create a new object */
313febdb468SDevin Teske obj = dlg_calloc(MY_OBJ, 1);
314febdb468SDevin Teske assert_ptr(obj, "dialog_gauge");
315febdb468SDevin Teske
316febdb468SDevin Teske dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MIN_WIDE);
317febdb468SDevin Teske dlg_print_size(height, width);
318febdb468SDevin Teske dlg_ctl_size(height, width);
319febdb468SDevin Teske
320febdb468SDevin Teske } else {
321febdb468SDevin Teske /* reuse an existing object */
322febdb468SDevin Teske obj = objptr;
323febdb468SDevin Teske height = obj->height;
324febdb468SDevin Teske width = obj->width;
325febdb468SDevin Teske }
326febdb468SDevin Teske
327febdb468SDevin Teske if (obj->obj.win == 0) {
328febdb468SDevin Teske /* center dialog box on screen */
329febdb468SDevin Teske int x = dlg_box_x_ordinate(width);
330febdb468SDevin Teske int y = dlg_box_y_ordinate(height);
331febdb468SDevin Teske WINDOW *dialog = dlg_new_window(height, width, y, x);
332febdb468SDevin Teske obj->obj.win = dialog;
333febdb468SDevin Teske }
334febdb468SDevin Teske
335febdb468SDevin Teske obj->obj.input = dialog_state.pipe_input;
336febdb468SDevin Teske obj->obj.keep_win = TRUE;
337febdb468SDevin Teske obj->obj.bg_task = TRUE;
338febdb468SDevin Teske obj->obj.handle_getc = handle_my_getc;
339febdb468SDevin Teske obj->obj.handle_input = handle_input;
340febdb468SDevin Teske
341febdb468SDevin Teske if (obj->title == 0 || strcmp(obj->title, title)) {
342febdb468SDevin Teske dlg_finish_string(obj->title);
343febdb468SDevin Teske free(obj->title);
344febdb468SDevin Teske obj->title = dlg_strclone(title);
345febdb468SDevin Teske }
346febdb468SDevin Teske
347febdb468SDevin Teske dlg_finish_string(obj->prompt);
348febdb468SDevin Teske free(obj->prompt);
349febdb468SDevin Teske
350febdb468SDevin Teske obj->prompt = prompt;
351febdb468SDevin Teske obj->percent = percent;
352febdb468SDevin Teske obj->height = height;
353febdb468SDevin Teske obj->width = width;
354febdb468SDevin Teske
355febdb468SDevin Teske /* if this was a new object, link it into the list */
356febdb468SDevin Teske if (objptr == 0) {
357febdb468SDevin Teske obj->next = all_objects;
358febdb468SDevin Teske all_objects = obj;
359febdb468SDevin Teske }
360febdb468SDevin Teske
361febdb468SDevin Teske dialog_state.finish_string = save_finish_string;
362febdb468SDevin Teske return (void *) obj;
363febdb468SDevin Teske }
364febdb468SDevin Teske
365febdb468SDevin Teske void *
dlg_allocate_gauge(const char * title,const char * cprompt,int height,int width,int percent)366682c9e0fSNathan Whitehorn dlg_allocate_gauge(const char *title,
367682c9e0fSNathan Whitehorn const char *cprompt,
368682c9e0fSNathan Whitehorn int height,
369682c9e0fSNathan Whitehorn int width,
370682c9e0fSNathan Whitehorn int percent)
371682c9e0fSNathan Whitehorn {
372febdb468SDevin Teske return dlg_reallocate_gauge(NULL, title, cprompt, height, width, percent);
373682c9e0fSNathan Whitehorn }
374682c9e0fSNathan Whitehorn
375682c9e0fSNathan Whitehorn void
dlg_free_gauge(void * objptr)376682c9e0fSNathan Whitehorn dlg_free_gauge(void *objptr)
377682c9e0fSNathan Whitehorn {
378682c9e0fSNathan Whitehorn MY_OBJ *obj = (MY_OBJ *) objptr;
379682c9e0fSNathan Whitehorn
380682c9e0fSNathan Whitehorn if (valid(obj)) {
381*a96ef450SBaptiste Daroussin if (obj->title)
382*a96ef450SBaptiste Daroussin free(obj->title);
383*a96ef450SBaptiste Daroussin if (obj->prompt)
384*a96ef450SBaptiste Daroussin free(obj->prompt);
385682c9e0fSNathan Whitehorn obj->obj.keep_win = FALSE;
386682c9e0fSNathan Whitehorn dlg_remove_callback(&(obj->obj));
387f4f33ea0SBaptiste Daroussin delink(obj);
3884c8945a0SNathan Whitehorn }
389f4f33ea0SBaptiste Daroussin curs_set(1);
3904c8945a0SNathan Whitehorn }
3914c8945a0SNathan Whitehorn
3924c8945a0SNathan Whitehorn /*
3934c8945a0SNathan Whitehorn * Display a gauge, or progress meter. Starts at percent% and reads stdin. If
3944c8945a0SNathan Whitehorn * stdin is not XXX, then it is interpreted as a percentage, and the display is
3954c8945a0SNathan Whitehorn * updated accordingly. Otherwise the next line is the percentage, and
3964c8945a0SNathan Whitehorn * subsequent lines up to another XXX are used for the new prompt. Note that
3974c8945a0SNathan Whitehorn * the size of the window never changes, so the prompt can not get any larger
3984c8945a0SNathan Whitehorn * than the height and width specified.
3994c8945a0SNathan Whitehorn */
4004c8945a0SNathan Whitehorn int
dialog_gauge(const char * title,const char * cprompt,int height,int width,int percent)4014c8945a0SNathan Whitehorn dialog_gauge(const char *title,
4024c8945a0SNathan Whitehorn const char *cprompt,
4034c8945a0SNathan Whitehorn int height,
4044c8945a0SNathan Whitehorn int width,
4054c8945a0SNathan Whitehorn int percent)
4064c8945a0SNathan Whitehorn {
4074c8945a0SNathan Whitehorn int fkey;
4084c8945a0SNathan Whitehorn int ch, result;
409682c9e0fSNathan Whitehorn void *objptr = dlg_allocate_gauge(title, cprompt, height, width, percent);
410682c9e0fSNathan Whitehorn MY_OBJ *obj = (MY_OBJ *) objptr;
4114c8945a0SNathan Whitehorn
412f4f33ea0SBaptiste Daroussin DLG_TRACE(("# gauge args:\n"));
413f4f33ea0SBaptiste Daroussin DLG_TRACE2S("title", title);
414f4f33ea0SBaptiste Daroussin DLG_TRACE2S("message", cprompt);
415f4f33ea0SBaptiste Daroussin DLG_TRACE2N("height", height);
416f4f33ea0SBaptiste Daroussin DLG_TRACE2N("width", width);
417f4f33ea0SBaptiste Daroussin DLG_TRACE2N("percent", percent);
418f4f33ea0SBaptiste Daroussin
419682c9e0fSNathan Whitehorn dlg_add_callback_ref((DIALOG_CALLBACK **) & obj, my_cleanup);
420682c9e0fSNathan Whitehorn dlg_update_gauge(obj, percent);
4214c8945a0SNathan Whitehorn
4222a3e3873SBaptiste Daroussin dlg_trace_win(obj->obj.win);
4234c8945a0SNathan Whitehorn do {
424682c9e0fSNathan Whitehorn ch = dlg_getc(obj->obj.win, &fkey);
4254c8945a0SNathan Whitehorn #ifdef KEY_RESIZE
4264c8945a0SNathan Whitehorn if (fkey && ch == KEY_RESIZE) {
427682c9e0fSNathan Whitehorn MY_OBJ *oldobj = obj;
428682c9e0fSNathan Whitehorn
429f4f33ea0SBaptiste Daroussin dlg_will_resize(obj->obj.win);
430682c9e0fSNathan Whitehorn
431682c9e0fSNathan Whitehorn obj = dlg_allocate_gauge(title,
432682c9e0fSNathan Whitehorn cprompt,
433682c9e0fSNathan Whitehorn height,
434682c9e0fSNathan Whitehorn width,
435682c9e0fSNathan Whitehorn oldobj->percent);
436682c9e0fSNathan Whitehorn
437682c9e0fSNathan Whitehorn /* avoid breaking new window in dlg_remove_callback */
438682c9e0fSNathan Whitehorn oldobj->obj.caller = 0;
439682c9e0fSNathan Whitehorn oldobj->obj.input = 0;
440682c9e0fSNathan Whitehorn oldobj->obj.keep_win = FALSE;
441682c9e0fSNathan Whitehorn
442682c9e0fSNathan Whitehorn /* remove the old version of the gauge */
443*a96ef450SBaptiste Daroussin _dlg_resize_cleanup(oldobj->obj.win);
444682c9e0fSNathan Whitehorn dlg_remove_callback(&(oldobj->obj));
445682c9e0fSNathan Whitehorn
446682c9e0fSNathan Whitehorn dlg_add_callback_ref((DIALOG_CALLBACK **) & obj, my_cleanup);
447682c9e0fSNathan Whitehorn dlg_update_gauge(obj, obj->percent);
4484c8945a0SNathan Whitehorn }
4494c8945a0SNathan Whitehorn #endif
4504c8945a0SNathan Whitehorn }
451682c9e0fSNathan Whitehorn while (valid(obj) && handle_my_getc(&(obj->obj), ch, fkey, &result));
4524c8945a0SNathan Whitehorn
453682c9e0fSNathan Whitehorn dlg_free_gauge(obj);
4544c8945a0SNathan Whitehorn
4554c8945a0SNathan Whitehorn return (DLG_EXIT_OK);
4564c8945a0SNathan Whitehorn }
457