char *selfs(char *dev) { #ifndef ARCH_PPC int fsnum=7; #else int fsnum=4; #endif char *fss[] = { "ext2", _("Standard Linux ext2fs filesystem"), "ext3", _("Journaling version of the ext2 filesystem"), "ext4", _("The evolution of the ext3 filesystem"), #ifndef ARCH_PPC "reiserfs", _("Hans Reiser's journaling filesystem"), #endif "jfs", _("Journaled File System"), "xfs", _("SGI's journaling filesystem"), "btrfs", _("B-tree file system (EXPERIMENTAL)") }; dialog_vars.backtitle=gen_backtitle(_("Formatting partitions")); dlg_put_backtitle(); dlg_clear(); dialog_vars.default_item=strdup("ext4"); if(fw_menu(g_strdup_printf(_("Selecting filesystem for %s"), dev), g_strdup_printf(_("Please select the type of filesystem to " "use for %s."), dev), 0, 0, 0, fsnum, fss) == -1) return(NULL); FREE(dialog_vars.default_item); return(strdup(dialog_vars.input_result)); }
char *selformatmode(char *dev) { int modenum=3; char *ret=NULL; char *title=NULL; char *msg=NULL; char *modes[] = { "format", _("Quick format with no bad block checking"), "check", _("Slow format that checks for bad blocks"), "noformat", _("Do not format, just mount the partition") }; dialog_vars.backtitle=gen_backtitle(_("Formatting partitions")); dlg_put_backtitle(); dlg_clear(); title = g_strdup_printf(_("Format %s"), dev); msg = g_strdup_printf(_("If %s has not been formatted, you should " "format it.\n" "NOTE: This will erase all data on %s. Would you like to " "format this partition?"), dev, dev); if (fw_menu(title,msg,0,0,0,modenum,modes) != -1) ret = dialog_vars.input_result; FREE(title); FREE(msg); return ret; }
/* * Display a gauge, or progress meter. Starts at percent% and reads stdin. If * stdin is not XXX, then it is interpreted as a percentage, and the display is * updated accordingly. Otherwise the next line is the percentage, and * subsequent lines up to another XXX are used for the new prompt. Note that * the size of the window never changes, so the prompt can not get any larger * than the height and width specified. */ int dialog_gauge(const char *title, const char *cprompt, int height, int width, int percent) { int fkey; int ch, result; void *objptr = dlg_allocate_gauge(title, cprompt, height, width, percent); MY_OBJ *obj = (MY_OBJ *) objptr; dlg_add_callback_ref((DIALOG_CALLBACK **) & obj, my_cleanup); dlg_update_gauge(obj, percent); dlg_trace_win(obj->obj.win); do { ch = dlg_getc(obj->obj.win, &fkey); #ifdef KEY_RESIZE if (fkey && ch == KEY_RESIZE) { MY_OBJ *oldobj = obj; dlg_mouse_free_regions(); obj = dlg_allocate_gauge(title, cprompt, height, width, oldobj->percent); /* avoid breaking new window in dlg_remove_callback */ oldobj->obj.caller = 0; oldobj->obj.input = 0; oldobj->obj.keep_win = FALSE; /* remove the old version of the gauge */ dlg_clear(); dlg_remove_callback(&(oldobj->obj)); refresh(); dlg_add_callback_ref((DIALOG_CALLBACK **) & obj, my_cleanup); dlg_update_gauge(obj, obj->percent); } #endif } while (valid(obj) && handle_my_getc(&(obj->obj), ch, fkey, &result)); dlg_free_gauge(obj); return (DLG_EXIT_OK); }
GList *selswap(void) { char **arraychk; GList *partlist; arraychk = glist2dialog(partschk); dialog_vars.backtitle=gen_backtitle(_("Setting up swap space")); dlg_put_backtitle(); dlg_clear(); partlist = fw_checklist(_("Setting up swap partitions"), _("Please select which swap partitions you want Frugalware " "to use:"), 0, 0, 0, g_list_length(partschk)/3, arraychk, FLAG_CHECK); return(partlist); }
int run(GList **config) { char *version = get_version(); char *title=NULL; asprintf(&title, _("Welcome to %s"), version); dialog_vars.backtitle=gen_backtitle(_("Welcome")); dlg_put_backtitle(); dlg_clear(); dialog_msgbox(title, _("Welcome among the users of Frugalware!\n\n" "The aim of creating Frugalware was to help you to do your work " "faster and simpler. We hope that you will like our " "product.\n\n" "The Frugalware Developer Team"), 0, 0, 1); FREE(version); return(0); }
/* Goes through the glob contents, looking for zero-length +REQUIRED-BY */ static int read_pkglist(int loops) { FILE *pkg; char line[1024]; char *p; do_init_dialog(); dialog_msgbox(NULL, "Searching for leaves", 5, 23, FALSE); fflush(stdout); pkg=popen("/usr/sbin/pkg query -e \"%#r=0 && %k=0\" \"%n-%v\\t%c\"", "r"); if(!pkg) { fputs("Error executing pkg.\n", stderr); return -1; } while(fgets(line, sizeof(line), pkg)!=NULL) { for(p=strchr(line, 0)-1; p>line && isspace(*p); p--) *p=0; p=strtok(line, "\t"); p=strtok(NULL, "\0"); add_item(line, p?p:""); } if(WEXITSTATUS(pclose(pkg)) && menulen==0) { fputs("pkg returned an error.\n", stderr); return -1; } dlg_clear(); if(menulen==0) { if(loops) dialog_msgbox(NULL, "No new leaves found", 5, 23, TRUE); else dialog_msgbox(NULL, "No leaves found", 5, 19, TRUE); end_dialog(); return(-1); } end_dialog(); return(0); }
/* * Display text from a file in a dialog box. */ int dialog_textbox(const char *title, const char *file, int height, int width) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_GRID_DOWN, 'J' ), DLG_KEYS_DATA( DLGK_GRID_DOWN, 'j' ), DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_DOWN ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'H' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'h' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'L' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_GRID_UP, 'K' ), DLG_KEYS_DATA( DLGK_GRID_UP, 'k' ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_UP ), DLG_KEYS_DATA( DLGK_PAGE_FIRST, 'g' ), DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ), DLG_KEYS_DATA( DLGK_PAGE_LAST, 'G' ), DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ), DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, ' ' ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_PAGE_PREV, 'B' ), DLG_KEYS_DATA( DLGK_PAGE_PREV, 'b' ), DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_BEGIN, '0' ), DLG_KEYS_DATA( DLGK_BEGIN, KEY_BEG ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif long fpos; int x, y, cur_x, cur_y; int key = 0, fkey; int next = 0; int i, code, passed_end; char search_term[MAX_LEN + 1]; MY_OBJ obj; WINDOW *dialog; bool moved; int result = DLG_EXIT_UNKNOWN; int button = dlg_default_button(); int min_width = 12; search_term[0] = '\0'; /* no search term entered yet */ memset(&obj, 0, sizeof(obj)); obj.begin_reached = TRUE; obj.buffer_first = TRUE; obj.end_reached = FALSE; obj.buttons = dlg_exit_label(); /* Open input file for reading */ if ((obj.fd = open(file, O_RDONLY)) == -1) dlg_exiterr("Can't open input file %s", file); /* Get file size. Actually, 'file_size' is the real file size - 1, since it's only the last byte offset from the beginning */ lseek_end(&obj, 0L); /* Restore file pointer to beginning of file after getting file size */ lseek_set(&obj, 0L); read_high(&obj, BUF_SIZE); dlg_button_layout(obj.buttons, &min_width); #ifdef KEY_RESIZE retry: #endif moved = TRUE; dlg_auto_sizefile(title, file, &height, &width, 2, min_width); dlg_print_size(height, width); dlg_ctl_size(height, width); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); dialog = dlg_new_window(height, width, y, x); dlg_register_window(dialog, "textbox", binding); dlg_register_buttons(dialog, "textbox", obj.buttons); dlg_mouse_setbase(x, y); /* Create window for text region, used for scrolling text */ obj.text = dlg_sub_window(dialog, PAGE_LENGTH, PAGE_WIDTH, y + 1, x + 1); /* register the new window, along with its borders */ dlg_mouse_mkbigregion(0, 0, PAGE_LENGTH + 2, width, KEY_MAX, 1, 1, 1 /* lines */ ); dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); dlg_draw_buttons(dialog, PAGE_LENGTH + 2, 0, obj.buttons, button, FALSE, width); (void) wnoutrefresh(dialog); getyx(dialog, cur_y, cur_x); /* Save cursor position */ dlg_attr_clear(obj.text, PAGE_LENGTH, PAGE_WIDTH, dialog_attr); while (result == DLG_EXIT_UNKNOWN) { /* * Update the screen according to whether we shifted up/down by a line * or not. */ if (moved) { if (next < 0) { (void) scrollok(obj.text, TRUE); (void) scroll(obj.text); /* Scroll text region up one line */ (void) scrollok(obj.text, FALSE); print_line(&obj, PAGE_LENGTH - 1, PAGE_WIDTH); (void) wnoutrefresh(obj.text); } else if (next > 0) { /* * We don't call print_page() here but use scrolling to ensure * faster screen update. However, 'end_reached' and * 'page_length' should still be updated, and 'in_buf' should * point to start of next page. This is done by calling * get_line() in the following 'for' loop. */ (void) scrollok(obj.text, TRUE); (void) wscrl(obj.text, -1); /* Scroll text region down one line */ (void) scrollok(obj.text, FALSE); obj.page_length = 0; passed_end = 0; for (i = 0; i < PAGE_LENGTH; i++) { if (!i) { print_line(&obj, 0, PAGE_WIDTH); /* print first line of page */ (void) wnoutrefresh(obj.text); } else (void) get_line(&obj); /* Called to update 'end_reached' and 'in_buf' */ if (!passed_end) obj.page_length++; if (obj.end_reached && !passed_end) passed_end = 1; } } else { print_page(&obj, PAGE_LENGTH, PAGE_WIDTH); } print_position(&obj, dialog, height, width); (void) wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } moved = FALSE; /* assume we'll not move */ next = 0; /* ...but not scroll by a line */ key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; if (!fkey && (code = dlg_char_to_button(key, obj.buttons)) >= 0) { result = dlg_ok_buttoncode(code); break; } if (fkey) { switch (key) { default: if (is_DLGK_MOUSE(key)) { result = dlg_exit_buttoncode(key - M_EVENT); if (result < 0) result = DLG_EXIT_OK; } else { beep(); } break; case DLGK_FIELD_NEXT: button = dlg_next_button(obj.buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, obj.buttons, button, FALSE, width); break; case DLGK_FIELD_PREV: button = dlg_prev_button(obj.buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, obj.buttons, button, FALSE, width); break; case DLGK_ENTER: if (dialog_vars.nook) result = DLG_EXIT_OK; else result = dlg_exit_buttoncode(button); break; case DLGK_PAGE_FIRST: if (!obj.begin_reached) { obj.begin_reached = 1; /* First page not in buffer? */ fpos = ftell_obj(&obj); if (fpos > obj.fd_bytes_read) { /* Yes, we have to read it in */ lseek_set(&obj, 0L); read_high(&obj, BUF_SIZE); } obj.in_buf = 0; moved = TRUE; } break; case DLGK_PAGE_LAST: obj.end_reached = TRUE; /* Last page not in buffer? */ fpos = ftell_obj(&obj); if (fpos < obj.file_size) { /* Yes, we have to read it in */ lseek_end(&obj, -BUF_SIZE); read_high(&obj, BUF_SIZE); } obj.in_buf = obj.bytes_read; back_lines(&obj, (long) PAGE_LENGTH); moved = TRUE; break; case DLGK_GRID_UP: /* Previous line */ if (!obj.begin_reached) { back_lines(&obj, obj.page_length + 1); next = 1; moved = TRUE; } break; case DLGK_PAGE_PREV: /* Previous page */ case DLGK_MOUSE(KEY_PPAGE): if (!obj.begin_reached) { back_lines(&obj, obj.page_length + PAGE_LENGTH); moved = TRUE; } break; case DLGK_GRID_DOWN: /* Next line */ if (!obj.end_reached) { obj.begin_reached = 0; next = -1; moved = TRUE; } break; case DLGK_PAGE_NEXT: /* Next page */ case DLGK_MOUSE(KEY_NPAGE): if (!obj.end_reached) { obj.begin_reached = 0; moved = TRUE; } break; case DLGK_BEGIN: /* Beginning of line */ if (obj.hscroll > 0) { obj.hscroll = 0; /* Reprint current page to scroll horizontally */ back_lines(&obj, obj.page_length); moved = TRUE; } break; case DLGK_GRID_LEFT: /* Scroll left */ if (obj.hscroll > 0) { obj.hscroll--; /* Reprint current page to scroll horizontally */ back_lines(&obj, obj.page_length); moved = TRUE; } break; case DLGK_GRID_RIGHT: /* Scroll right */ if (obj.hscroll < MAX_LEN) { obj.hscroll++; /* Reprint current page to scroll horizontally */ back_lines(&obj, obj.page_length); moved = TRUE; } break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; back_lines(&obj, obj.page_length); /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif } } else { switch (key) { case '/': /* Forward search */ case 'n': /* Repeat forward search */ case '?': /* Backward search */ case 'N': /* Repeat backward search */ moved = perform_search(&obj, height, width, key, search_term); fkey = FALSE; break; default: beep(); break; } } } dlg_del_window(dialog); free(obj.buf); (void) close(obj.fd); dlg_mouse_free_regions(); return result; }
int run(GList **config) { GList *partlist; char **nrdevs, *ptr, *op, *np, *dest; int ret; char my_buffer[MAX_LEN + 1] = ""; detect_parts(0); // select swap partitions to use partlist = selswap(); // format swap partitions if(doswap(partlist, config) == -1) return(-1); // root partition ptr = selrootdev(); if(ptr == NULL) return(-1); if(formatdev(ptr) == -1) return(-1); mountdev(ptr, "/", config); // move temporarily stuff to the final location chdir(TARGETDIR); np = g_strdup_printf("%s/%s", TARGETDIR, "/etc/profile.d"); makepath(np); FREE(np); op = (char*)data_get(*config, "fstab"); np = g_strdup_printf("%s/%s", TARGETDIR, "/etc/fstab"); copyfile(op, np); unlink(op); chmod (np, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); data_put(config, "fstab", strdup(np)); FREE(np); np = g_strdup_printf("%s/%s", TARGETDIR, "/etc/sysconfig"); makepath(np); FREE(np); // so that 1) the user can't mount a partition as /dev because // it'll be used 2) install scriptlets will be able to do // >/dev/null makepath(TARGETDIR "/dev"); makepath(TARGETDIR "/proc"); makepath(TARGETDIR "/sys"); fw_system("mount none -t devtmpfs " TARGETDIR "/dev"); fw_system("mount none -t proc " TARGETDIR "/proc"); fw_system("mount none -t sysfs " TARGETDIR "/sys"); // non-root partitions dialog_vars.backtitle=gen_backtitle(_("Selecting other partitions")); while(1) { dialog_vars.input_result = my_buffer; nrdevs = parts2dialog(parts); dlg_put_backtitle(); dlg_clear(); dialog_vars.cancel_label = _("Continue"); dialog_vars.input_result = my_buffer; dialog_vars.input_result[0]='\0'; ret = dialog_menu( _("Select other Linux partitions for /etc/fstab"), _("You may use your other partitions to distribute your Linux " "system across more than one partition. Currently, you have " "only mounted your / partition. You might want to mount " "directories such as /boot, /home or /usr/local on separate " "partitions. You should not try to mount /usr, /etc, /sbin or " "/bin on their own partitions since they contain utilities " "needed to bring the system up and mount partitions. Also, " "do not reuse a partition that you've already entered before. " "Please select one of the partitions listed below, or if " "you're done, hit Continue."), 0, 0, 0, g_list_length(parts)/2, nrdevs); dialog_vars.cancel_label = '\0'; FREE(nrdevs); if (ret != DLG_EXIT_CANCEL) { if(!strcmp(_("(in use)"), dialog_vars.input_result)) continue; ptr = strdup(dialog_vars.input_result); if(formatdev(ptr) == -1) return(-1); dest = asktowhere(ptr); if(dest == NULL) return(-1); mountdev(ptr, dest, config); FREE(dest); FREE(ptr); } else break; } makepath(g_strdup_printf("%s/%s", TARGETDIR, "/var/log")); np = g_strdup_printf("%s/%s", TARGETDIR, LOGFILE); copyfile(LOGFILE, np); unlink(LOGFILE); chmod (np, S_IRUSR|S_IWUSR); FREE(np); // disable caching for cds // this is needed here since when the cds is loaded we had no // formatted root partition if((char*)data_get(*config, "netinstall")==NULL) { char *pacbindir = g_strdup_printf("%s/frugalware-%s", SOURCEDIR, ARCH); char *ptr; ptr = g_strdup_printf("%s/var/cache/pacman-g2/pkg", TARGETDIR); makepath(ptr); FREE(ptr); disable_cache(pacbindir); FREE(pacbindir); } return(0); }
/* * This is an alternate interface to 'checklist' which allows the application * to read the list item states back directly without putting them in the * output buffer. It also provides for more than two states over which the * check/radio box can display. */ int dlg_checklist(const char *title, const char *cprompt, int height, int width, int list_height, int item_no, DIALOG_LISTITEM * items, const char *states, int flag, int *current_item) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ), DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ), DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ), DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ), DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif ALL_DATA all; int i, j, key2, found, x, y, cur_x, cur_y; int key = 0, fkey; int button = dialog_state.visit_items ? -1 : dlg_default_button(); int choice = dlg_default_listitem(items); int scrollamt = 0; int max_choice; int was_mouse; int use_width, list_width, name_width, text_width; int result = DLG_EXIT_UNKNOWN; int num_states; WINDOW *dialog; char *prompt = dlg_strclone(cprompt); const char **buttons = dlg_ok_labels(); const char *widget_name; memset(&all, 0, sizeof(all)); all.items = items; all.item_no = item_no; dlg_does_output(); dlg_tab_correct_str(prompt); /* * If this is a radiobutton list, ensure that no more than one item is * selected initially. Allow none to be selected, since some users may * wish to provide this flavor. */ if (flag == FLAG_RADIO) { bool first = TRUE; for (i = 0; i < item_no; i++) { if (items[i].state) { if (first) { first = FALSE; } else { items[i].state = 0; } } } widget_name = "radiolist"; } else { widget_name = "checklist"; } #ifdef KEY_RESIZE retry: #endif all.use_height = list_height; use_width = dlg_calc_list_width(item_no, items) + 10; use_width = MAX(26, use_width); if (all.use_height == 0) { /* calculate height without items (4) */ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width); dlg_calc_listh(&height, &all.use_height, item_no); } else { dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + all.use_height, use_width); } dlg_button_layout(buttons, &width); dlg_print_size(height, width); dlg_ctl_size(height, width); /* we need at least two states */ if (states == 0 || strlen(states) < 2) states = " *"; num_states = (int) strlen(states); all.states = states; all.checkflag = flag; x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); dialog = dlg_new_window(height, width, y, x); all.dialog = dialog; dlg_register_window(dialog, widget_name, binding); dlg_register_buttons(dialog, widget_name, buttons); dlg_mouse_setbase(x, y); dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); (void) wattrset(dialog, dialog_attr); dlg_print_autowrap(dialog, prompt, height, width); all.use_width = width - 6; getyx(dialog, cur_y, cur_x); all.box_y = cur_y + 1; all.box_x = (width - all.use_width) / 2 - 1; /* * After displaying the prompt, we know how much space we really have. * Limit the list to avoid overwriting the ok-button. */ if (all.use_height + MIN_HIGH > height - cur_y) all.use_height = height - MIN_HIGH - cur_y; if (all.use_height <= 0) all.use_height = 1; max_choice = MIN(all.use_height, item_no); max_choice = MAX(max_choice, 1); /* create new window for the list */ all.list = dlg_sub_window(dialog, all.use_height, all.use_width, y + all.box_y + 1, x + all.box_x + 1); /* draw a box around the list items */ dlg_draw_box(dialog, all.box_y, all.box_x, all.use_height + 2 * MARGIN, all.use_width + 2 * MARGIN, menubox_border_attr, menubox_border2_attr); text_width = 0; name_width = 0; /* Find length of longest item to center checklist */ for (i = 0; i < item_no; i++) { text_width = MAX(text_width, dlg_count_columns(items[i].text)); name_width = MAX(name_width, dlg_count_columns(items[i].name)); } /* If the name+text is wider than the list is allowed, then truncate * one or both of them. If the name is no wider than 1/4 of the list, * leave it intact. */ use_width = (all.use_width - 6); if (dialog_vars.no_tags) { list_width = MIN(all.use_width, text_width); } else if (dialog_vars.no_items) { list_width = MIN(all.use_width, name_width); } else { if (text_width >= 0 && name_width >= 0 && use_width > 0 && text_width + name_width > use_width) { int need = (int) (0.25 * use_width); if (name_width > need) { int want = (int) (use_width * ((double) name_width) / (text_width + name_width)); name_width = (want > need) ? want : need; } text_width = use_width - name_width; } list_width = (text_width + name_width); } all.check_x = (use_width - list_width) / 2; all.item_x = ((dialog_vars.no_tags ? 0 : (dialog_vars.no_items ? 0 : (2 + name_width))) + all.check_x + 4); /* ensure we are scrolled to show the current choice */ scrollamt = MIN(scrollamt, max_choice + item_no - 1); if (choice >= (max_choice + scrollamt - 1)) { scrollamt = MAX(0, choice - max_choice + 1); choice = max_choice - 1; } print_list(&all, choice, scrollamt, max_choice); /* register the new window, along with its borders */ dlg_mouse_mkbigregion(all.box_y + 1, all.box_x, all.use_height, all.use_width + 2, KEY_MAX, 1, 1, 1 /* by lines */ ); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); dlg_trace_win(dialog); while (result == DLG_EXIT_UNKNOWN) { if (button < 0) /* --visit-items */ wmove(dialog, all.box_y + choice + 1, all.box_x + all.check_x + 2); key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; was_mouse = (fkey && is_DLGK_MOUSE(key)); if (was_mouse) key -= M_EVENT; if (was_mouse && (key >= KEY_MAX)) { getyx(dialog, cur_y, cur_x); i = (key - KEY_MAX); if (i < max_choice) { choice = (key - KEY_MAX); print_list(&all, choice, scrollamt, max_choice); key = ' '; /* force the selected item to toggle */ } else { beep(); continue; } fkey = FALSE; } else if (was_mouse && key >= KEY_MIN) { key = dlg_lookup_key(dialog, key, &fkey); } /* * A space toggles the item status. We handle either a checklist * (any number of items can be selected) or radio list (zero or one * items can be selected). */ if (key == ' ') { int current = scrollamt + choice; int next = items[current].state + 1; if (next >= num_states) next = 0; if (flag == FLAG_CHECK) { /* checklist? */ getyx(dialog, cur_y, cur_x); items[current].state = next; print_item(&all, all.list, &items[scrollamt + choice], states, choice, TRUE); (void) wnoutrefresh(all.list); (void) wmove(dialog, cur_y, cur_x); } else { /* radiolist */ for (i = 0; i < item_no; i++) { if (i != current) { items[i].state = 0; } } if (items[current].state) { getyx(dialog, cur_y, cur_x); items[current].state = next ? next : 1; print_item(&all, all.list, &items[current], states, choice, TRUE); (void) wnoutrefresh(all.list); (void) wmove(dialog, cur_y, cur_x); } else { items[current].state = 1; print_list(&all, choice, scrollamt, max_choice); } } continue; /* wait for another key press */ } /* * Check if key pressed matches first character of any item tag in * list. If there is more than one match, we will cycle through * each one as the same key is pressed repeatedly. */ found = FALSE; if (!fkey) { if (button < 0 || !dialog_state.visit_items) { for (j = scrollamt + choice + 1; j < item_no; j++) { if (check_hotkey(items, j)) { found = TRUE; i = j - scrollamt; break; } } if (!found) { for (j = 0; j <= scrollamt + choice; j++) { if (check_hotkey(items, j)) { found = TRUE; i = j - scrollamt; break; } } } if (found) dlg_flush_getc(); } else if ((j = dlg_char_to_button(key, buttons)) >= 0) { button = j; ungetch('\n'); continue; } } /* * A single digit (1-9) positions the selection to that line in the * current screen. */ if (!found && (key <= '9') && (key > '0') && (key - '1' < max_choice)) { found = TRUE; i = key - '1'; } if (!found) { if (fkey) { found = TRUE; switch (key) { case DLGK_ITEM_FIRST: i = -scrollamt; break; case DLGK_ITEM_LAST: i = item_no - 1 - scrollamt; break; case DLGK_PAGE_PREV: if (choice) i = 0; else if (scrollamt != 0) i = -MIN(scrollamt, max_choice); else continue; break; case DLGK_PAGE_NEXT: i = MIN(choice + max_choice, item_no - scrollamt - 1); break; case DLGK_ITEM_PREV: i = choice - 1; if (choice == 0 && scrollamt == 0) continue; break; case DLGK_ITEM_NEXT: i = choice + 1; if (scrollamt + choice >= item_no - 1) continue; break; default: found = FALSE; break; } } } if (found) { if (i != choice) { getyx(dialog, cur_y, cur_x); if (i < 0 || i >= max_choice) { if (i < 0) { scrollamt += i; choice = 0; } else { choice = max_choice - 1; scrollamt += (i - max_choice + 1); } print_list(&all, choice, scrollamt, max_choice); } else { choice = i; print_list(&all, choice, scrollamt, max_choice); } } continue; /* wait for another key press */ } if (fkey) { switch (key) { case DLGK_ENTER: result = dlg_enter_buttoncode(button); break; case DLGK_FIELD_PREV: button = dlg_prev_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; case DLGK_FIELD_NEXT: button = dlg_next_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif default: if (was_mouse) { if ((key2 = dlg_ok_buttoncode(key)) >= 0) { result = key2; break; } beep(); } } } else { beep(); } } dlg_del_window(dialog); dlg_mouse_free_regions(); free(prompt); *current_item = (scrollamt + choice); return result; }
int run(GList **config) { GList *drives=NULL; int i; int found = 0; char *ptr; umount_if_needed(SOURCEDIR); dialog_vars.backtitle=gen_backtitle(_("Selecting source media")); dlg_put_backtitle(); dlg_clear(); dialog_msgbox(_("Scanning"), _("Scanning for a CD/DVD drive containing " "a Frugalware install disc..."), 0, 0, 0); drives = grep_drives("/proc/sys/dev/cdrom/info"); for (i=0; i<g_list_length(drives); i++) { ptr = get_blkid((char*)g_list_nth_data(drives, i)); if(ptr && !strcmp(ptr, "Frugalware Install")) { LOG("install medium found in %s", (char*)g_list_nth_data(drives, i)); FREE(ptr); ptr = g_strdup_printf("mount -o ro -t iso9660 /dev/%s %s", (char*)g_list_nth_data(drives, i), SOURCEDIR); fw_system(ptr); data_put(config, "srcdev", (char*)g_list_nth_data(drives, i)); dlg_put_backtitle(); dialog_msgbox(_("CD/DVD drive found"), g_strdup_printf(_("A Frugalware install disc was found in device /dev/%s."), (char*)g_list_nth_data(drives, i)), 0, 0, 0); if(is_netinstall(SOURCEDIR)) { data_put(config, "netinstall", ""); LOG("install medium contains no packages, performing a network installation"); } else LOG("install medium contains packages, performing an offline installation"); found = 1; break; } else LOG("skipping non-install medium in %s", (char*)g_list_nth_data(drives, i)); FREE(ptr); } if(!found) { LOG("no package database found, performing a network installation"); data_put(config, "netinstall", ""); } // disable caching for cds if((char*)data_get(*config, "netinstall")==NULL) { char *pacbindir = g_strdup_printf("%s/frugalware-%s", SOURCEDIR, ARCH); disable_cache(pacbindir); FREE(pacbindir); } if(data_get(*config, "srcdev")==NULL) { LOG("no cd/dvd drive found, this is normal if you are running setup from a pendrive or in an emulator"); } return(0); }
int run(GList **config) { #ifdef GTK GtkWidget *label; GtkWidget *tv; GtkTreeIter iter; int i = 0; #endif #ifdef DIALOG dialog_vars.backtitle=gen_backtitle("Selecting language"); dlg_put_backtitle(); dlg_clear(); dialog_vars.default_item=strdup("en_US"); if(fw_menu("Please select your language", "Please select your language from the list. If your language " "is not in the list, you should probably choose English.", 0, 0, 0, LANGSNUM, langs) == -1) return(-1); FREE(dialog_vars.default_item); LOG("selected language: '%s'", dialog_vars.input_result); setenv("LC_ALL", dialog_vars.input_result, 1); setenv("LANG", dialog_vars.input_result, 1); setlocale(LC_ALL, dialog_vars.input_result); bindtextdomain("setup", "/usr/share/locale"); if(!strcmp("en_US", dialog_vars.input_result)) setenv("CHARSET", "iso-8859-1", 1); else if(!strcmp("es_AR", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-1", 1); setcharset("lat1-16.psfu.gz", config); } else if(!strcmp("de_DE", dialog_vars.input_result)) setenv("CHARSET", "iso-8859-15", 1); else if(!strcmp("fr_FR", dialog_vars.input_result)) setenv("CHARSET", "iso-8859-15", 1); else if(!strcmp("id_ID", dialog_vars.input_result)) setenv("CHARSET", "iso-8859-1", 1); else if(!strcmp("it_IT", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-1", 1); setcharset("lat9w-16.psfu.gz", config); } else if(!strcmp("cs_CZ", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-2", 1); setcharset("lat2-16.psfu.gz", config); } else if(!strcmp("hu_HU", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-2", 1); setcharset("lat2a-16.psfu.gz", config); } else if(!strcmp("nl_NL", dialog_vars.input_result)) setenv("CHARSET", "iso-8859-1", 1); else if(!strcmp("pl_PL", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-2", 1); setcharset("lat2-16.psfu.gz", config); } else if(!strcmp("pt_PT", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-1", 1); setcharset("lat1-16.psfu.gz", config); } else if(!strcmp("sk_SK", dialog_vars.input_result)) { setenv("CHARSET", "iso-8859-2", 1); setcharset("lat2-16.psfu.gz", config); } #endif #ifdef GTK tv = create_asklang_view(); gtk_container_add(GTK_CONTAINER(frame), tv); while (i <= LANGSNUM * 2) { gtk_list_store_append(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tv))), &iter); gtk_list_store_set(GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(tv))), &iter, 0, langs[i], 1, langs[i+1], -1); i = i+2; } gtk_widget_show_all(tv); #endif textdomain("setup"); return(0); }
/* * Display a message box. Program will pause and display an "OK" button * if the parameter 'pauseopt' is non-zero. */ int dialog_msgbox(const char *title, const char *cprompt, int height, int width, int pauseopt) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, TRAVERSE_BINDINGS, SCROLLKEY_BINDINGS, END_KEYS_BINDING }; /* *INDENT-ON* */ int x, y, last = 0, page; int button; int key = 0, fkey; int result = DLG_EXIT_UNKNOWN; WINDOW *dialog = 0; char *prompt = dlg_strclone(cprompt); const char **buttons = dlg_ok_label(); int offset = 0; int check; bool show = TRUE; int min_width = (pauseopt == 1 ? 12 : 0); int save_nocancel = dialog_vars.nocancel; #ifdef KEY_RESIZE int req_high; int req_wide; #endif dialog_vars.nocancel = TRUE; button = dlg_default_button(); #ifdef KEY_RESIZE req_high = height; req_wide = width; restart: #endif dlg_button_layout(buttons, &min_width); dlg_tab_correct_str(prompt); dlg_auto_size(title, prompt, &height, &width, (pauseopt == 1 ? 2 : 0), min_width); dlg_print_size(height, width); dlg_ctl_size(height, width); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); #ifdef KEY_RESIZE if (dialog != 0) dlg_move_window(dialog, height, width, y, x); else #endif { dialog = dlg_new_window(height, width, y, x); dlg_register_window(dialog, "msgbox", binding); dlg_register_buttons(dialog, "msgbox", buttons); } page = height - (1 + 3 * MARGIN); dlg_mouse_setbase(x, y); dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_title(dialog, title); wattrset(dialog, dialog_attr); if (pauseopt) { dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n'); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); dlg_draw_helpline(dialog, FALSE); while (result == DLG_EXIT_UNKNOWN) { if (show) { last = dlg_print_scrolled(dialog, prompt, offset, page, width, pauseopt); dlg_trace_win(dialog); show = FALSE; } key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; if (!fkey && (check = dlg_char_to_button(key, buttons)) >= 0) { result = dlg_ok_buttoncode(check); break; } if (fkey) { switch (key) { #ifdef KEY_RESIZE case KEY_RESIZE: dlg_clear(); height = req_high; width = req_wide; show = TRUE; goto restart; #endif case DLGK_FIELD_NEXT: button = dlg_next_button(buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; case DLGK_FIELD_PREV: button = dlg_prev_button(buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; case DLGK_ENTER: result = dlg_ok_buttoncode(button); break; default: if (is_DLGK_MOUSE(key)) { result = dlg_ok_buttoncode(key - M_EVENT); if (result < 0) result = DLG_EXIT_OK; } else if (dlg_check_scrolled(key, last, page, &show, &offset) == 0) { } else { beep(); } break; } } else { beep(); } } } else { dlg_print_scrolled(dialog, prompt, offset, page, width, pauseopt); dlg_draw_helpline(dialog, FALSE); wrefresh(dialog); dlg_trace_win(dialog); result = DLG_EXIT_OK; } dlg_del_window(dialog); dlg_mouse_free_regions(); free(prompt); dialog_vars.nocancel = save_nocancel; return result; }
int run(GList **config) { char **array; char *fn, *ptr, *layout; FILE* fp; int ret = 0; if (layoutl) { g_list_free(layoutl); layoutl = NULL; } find("/usr/share/keymaps/i386"); layoutl = g_list_sort(layoutl, sort_layouts); array = glist4dialog(layoutl, ""); dialog_vars.backtitle=gen_backtitle(_("Configuring the keyboard")); dlg_put_backtitle(); dlg_clear(); /* this string should be the best keyboard layout for the given * language from /usr/share/keymaps/i386 */ dialog_vars.default_item=strdup(_("qwerty/us.map.gz")); if(fw_menu(_("Keyboard map selection"), _("You may select one of the following keyboard maps. If you " "do not select a keyboard map, 'qwerty/us.map.gz' (the US " "keyboard map) is the default. Use the UP/DOWN arrow keys and " "PageUp/PageDown to scroll through the whole list of choices."), 0, 0, 0, g_list_length(layoutl), array) == -1) ret = -1; FREE(dialog_vars.default_item); if(ret == -1) return(ret); layout=strdup(dialog_vars.input_result); FREE(array); // drop .map.gz if(strlen(layout) >= 7) layout[strlen(layout)-7]='\0'; //TODO: maybe there is a proper system call for this? LOG("selected layout '%s'", layout); ptr = g_strdup_printf("loadkeys /usr/share/keymaps/i386/%s.map.gz", layout); fw_system(ptr); FREE(ptr); fn = strdup("/tmp/setup_XXXXXX"); mkstemp(fn); if ((fp = fopen(fn, "w")) == NULL) { perror(_("Could not open output file for writing")); return(1); } fprintf(fp, "# /etc/vconsole.conf\n\n" "# specify the keyboard map, maps are in " "/usr/share/keymaps\n\n"); if(strstr(layout, "/")) fprintf(fp, "KEYMAP=%s\n", strstr(layout, "/")+1); fprintf(fp,"\n# specify the console font\nFONT=lat1-16.psfu.gz\n"); FREE(layout); fclose(fp); data_put(config, "vconsole.conf", fn); return(0); }
/* * This is an alternate interface to 'buildlist' which allows the application * to read the list item states back directly without putting them in the * output buffer. */ int dlg_buildlist(const char *title, const char *cprompt, int height, int width, int list_height, int item_no, DIALOG_LISTITEM * items, const char *states, int order_mode, int *current_item) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ), DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_END ), DLG_KEYS_DATA( DLGK_ITEM_LAST, KEY_LL ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, '+' ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, KEY_DOWN ), DLG_KEYS_DATA( DLGK_ITEM_NEXT, CHR_NEXT ), DLG_KEYS_DATA( DLGK_ITEM_PREV, '-' ), DLG_KEYS_DATA( DLGK_ITEM_PREV, KEY_UP ), DLG_KEYS_DATA( DLGK_ITEM_PREV, CHR_PREVIOUS ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE) ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, DLGK_MOUSE(KEY_NPAGE+KEY_MAX) ), DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE) ), DLG_KEYS_DATA( DLGK_PAGE_PREV, DLGK_MOUSE(KEY_PPAGE+KEY_MAX) ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFTCOL ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHTCOL ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif ALL_DATA all; MY_DATA *data = all.list; int i, j, k, key2, found, x, y, cur_x, cur_y; int key = 0, fkey; bool save_visit = dialog_state.visit_items; int button; int cur_item; int was_mouse; int name_width, text_width, full_width, list_width; int result = DLG_EXIT_UNKNOWN; int num_states; bool first = TRUE; WINDOW *dialog; char *prompt = dlg_strclone(cprompt); const char **buttons = dlg_ok_labels(); const char *widget_name = "buildlist"; (void) order_mode; /* * Unlike other uses of --visit-items, we have two windows to visit. */ if (dialog_state.visit_cols) dialog_state.visit_cols = 2; memset(&all, 0, sizeof(all)); all.items = items; all.item_no = item_no; if (dialog_vars.default_item != 0) { cur_item = dlg_default_listitem(items); } else { if ((cur_item = first_item(&all, 0)) < 0) cur_item = first_item(&all, 1); } button = (dialog_state.visit_items ? (items[cur_item].state ? sRIGHT : sLEFT) : dlg_default_button()); dlg_does_output(); dlg_tab_correct_str(prompt); #ifdef KEY_RESIZE retry: #endif all.use_height = list_height; all.use_width = (2 * (dlg_calc_list_width(item_no, items) + 4 + 2 * MARGIN) + 1); all.use_width = MAX(26, all.use_width); if (all.use_height == 0) { /* calculate height without items (4) */ dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, all.use_width); dlg_calc_listh(&height, &all.use_height, item_no); } else { dlg_auto_size(title, prompt, &height, &width, MIN_HIGH + all.use_height, all.use_width); } dlg_button_layout(buttons, &width); dlg_print_size(height, width); dlg_ctl_size(height, width); /* we need at least two states */ if (states == 0 || strlen(states) < 2) states = " *"; num_states = (int) strlen(states); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); dialog = dlg_new_window(height, width, y, x); dlg_register_window(dialog, widget_name, binding); dlg_register_buttons(dialog, widget_name, buttons); dlg_mouse_setbase(all.base_x = x, all.base_y = y); dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); (void) wattrset(dialog, dialog_attr); dlg_print_autowrap(dialog, prompt, height, width); list_width = (width - 6 * MARGIN - 2) / 2; getyx(dialog, cur_y, cur_x); data[0].box_y = cur_y + 1; data[0].box_x = MARGIN + 1; data[1].box_y = cur_y + 1; data[1].box_x = data[0].box_x + 1 + 2 * MARGIN + list_width; /* * After displaying the prompt, we know how much space we really have. * Limit the list to avoid overwriting the ok-button. */ if (all.use_height + MIN_HIGH > height - cur_y) all.use_height = height - MIN_HIGH - cur_y; if (all.use_height <= 0) all.use_height = 1; for (k = 0; k < 2; ++k) { /* create new window for the list */ data[k].win = dlg_sub_window(dialog, all.use_height, list_width, y + data[k].box_y + 1, x + data[k].box_x + 1); /* draw a box around the list items */ dlg_draw_box(dialog, data[k].box_y, data[k].box_x, all.use_height + 2 * MARGIN, list_width + 2 * MARGIN, menubox_border_attr, menubox_border2_attr); } text_width = 0; name_width = 0; /* Find length of longest item to center buildlist */ for (i = 0; i < item_no; i++) { text_width = MAX(text_width, dlg_count_columns(items[i].text)); name_width = MAX(name_width, dlg_count_columns(items[i].name)); } /* If the name+text is wider than the list is allowed, then truncate * one or both of them. If the name is no wider than 1/4 of the list, * leave it intact. */ all.use_width = (list_width - 6 * MARGIN); if (dialog_vars.no_tags && !dialog_vars.no_items) { full_width = MIN(all.use_width, text_width); } else if (dialog_vars.no_items) { full_width = MIN(all.use_width, name_width); } else { if (text_width >= 0 && name_width >= 0 && all.use_width > 0 && text_width + name_width > all.use_width) { int need = (int) (0.25 * all.use_width); if (name_width > need) { int want = (int) (all.use_width * ((double) name_width) / (text_width + name_width)); name_width = (want > need) ? want : need; } text_width = all.use_width - name_width; } full_width = text_width + name_width; } all.check_x = (all.use_width - full_width) / 2; all.item_x = ((dialog_vars.no_tags ? 0 : (dialog_vars.no_items ? 0 : (name_width + 2))) + all.check_x); /* ensure we are scrolled to show the current choice */ j = MIN(all.use_height, item_no); for (i = 0; i < 2; ++i) { int top_item = 0; if ((items[cur_item].state != 0) == i) { top_item = cur_item - j + 1; if (top_item < 0) top_item = 0; set_top_item(&all, top_item, i); } else { set_top_item(&all, 0, i); } } /* register the new window, along with its borders */ for (i = 0; i < 2; ++i) { dlg_mouse_mkbigregion(data[i].box_y + 1, data[i].box_x, all.use_height, list_width + 2, 2 * KEY_MAX + (i * (1 + all.use_height)), 1, 1, 1 /* by lines */ ); } dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); while (result == DLG_EXIT_UNKNOWN) { int which = (items[cur_item].state != 0); MY_DATA *moi = data + which; int at_top = index2row(&all, moi->top_index, which); int at_end = index2row(&all, -1, which); int at_bot = skip_rows(&all, at_top, all.use_height, which); dlg_trace_msg("\t** state %d:%d top %d (%d:%d:%d) %d\n", cur_item, item_no - 1, moi->top_index, at_top, at_bot, at_end, which); if (first) { print_both(&all, cur_item); dlg_trace_win(dialog); first = FALSE; } if (button < 0) { /* --visit-items */ int cur_row = index2row(&all, cur_item, which); cur_y = (data[which].box_y + cur_row + 1); if (at_top > 0) cur_y -= at_top; cur_x = (data[which].box_x + all.check_x + 1); dlg_trace_msg("\t...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x); wmove(dialog, cur_y, cur_x); } key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; was_mouse = (fkey && is_DLGK_MOUSE(key)); if (was_mouse) key -= M_EVENT; if (!was_mouse) { ; } else if (key >= 2 * KEY_MAX) { i = (key - 2 * KEY_MAX) % (1 + all.use_height); j = (key - 2 * KEY_MAX) / (1 + all.use_height); k = row2index(&all, i + at_top, j); dlg_trace_msg("MOUSE column %d, row %d ->item %d\n", j, i, k); if (k >= 0 && j < 2) { if (j != which) { /* * Mouse click was in the other column. */ moi = data + j; fix_top_item(&all, k, j); } which = j; at_top = index2row(&all, moi->top_index, which); at_bot = skip_rows(&all, at_top, all.use_height, which); cur_item = k; print_both(&all, cur_item); key = KEY_TOGGLE; /* force the selected item to toggle */ } else { beep(); continue; } fkey = FALSE; } else if (key >= KEY_MIN) { if (key > KEY_MAX) { if (which == 0) { key = KEY_RIGHTCOL; /* switch to right-column */ fkey = FALSE; } else { key -= KEY_MAX; } } else { if (which == 1) { key = KEY_LEFTCOL; /* switch to left-column */ fkey = FALSE; } } key = dlg_lookup_key(dialog, key, &fkey); } /* * A space toggles the item status. Normally we put the cursor on * the next available item in the same column. But if there are no * more items in the column, move the cursor to the other column. */ if (key == KEY_TOGGLE) { int new_choice; int new_state = items[cur_item].state + 1; if ((new_choice = next_item(&all, cur_item, which)) == cur_item) { new_choice = prev_item(&all, cur_item, which); } dlg_trace_msg("cur_item %d, new_choice:%d\n", cur_item, new_choice); if (new_state >= num_states) new_state = 0; items[cur_item].state = new_state; if (cur_item == moi->top_index) { set_top_item(&all, new_choice, which); } if (new_choice >= 0) { fix_top_item(&all, cur_item, !which); cur_item = new_choice; } print_both(&all, cur_item); dlg_trace_win(dialog); continue; /* wait for another key press */ } /* * Check if key pressed matches first character of any item tag in * list. If there is more than one match, we will cycle through * each one as the same key is pressed repeatedly. */ found = FALSE; if (!fkey) { if (button < 0 || !dialog_state.visit_items) { for (j = cur_item + 1; j < item_no; j++) { if (check_hotkey(items, j, which)) { found = TRUE; i = j; break; } } if (!found) { for (j = 0; j <= cur_item; j++) { if (check_hotkey(items, j, which)) { found = TRUE; i = j; break; } } } if (found) dlg_flush_getc(); } else if ((j = dlg_char_to_button(key, buttons)) >= 0) { button = j; ungetch('\n'); continue; } } /* * A single digit (1-9) positions the selection to that line in the * current screen. */ if (!found && (key <= '9') && (key > '0') && (key - '1' < at_bot)) { found = TRUE; i = key - '1'; } if (!found && fkey) { switch (key) { case DLGK_FIELD_PREV: if ((button == sRIGHT) && dialog_state.visit_items) { key = DLGK_GRID_LEFT; button = sLEFT; } else { button = dlg_prev_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (button == sRIGHT) { key = DLGK_GRID_RIGHT; } else { continue; } } break; case DLGK_FIELD_NEXT: if ((button == sLEFT) && dialog_state.visit_items) { key = DLGK_GRID_RIGHT; button = sRIGHT; } else { button = dlg_next_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (button == sLEFT) { key = DLGK_GRID_LEFT; } else { continue; } } break; } } if (!found && fkey) { i = cur_item; found = TRUE; switch (key) { case DLGK_GRID_LEFT: i = closest_item(&all, cur_item, 0); fix_top_item(&all, i, 0); break; case DLGK_GRID_RIGHT: i = closest_item(&all, cur_item, 1); fix_top_item(&all, i, 1); break; case DLGK_PAGE_PREV: if (cur_item > moi->top_index) { i = moi->top_index; } else if (moi->top_index != 0) { int temp = at_top; if ((temp -= all.use_height) < 0) temp = 0; i = row2index(&all, temp, which); } break; case DLGK_PAGE_NEXT: if ((at_end - at_bot) < all.use_height) { i = next_item(&all, row2index(&all, at_end, which), which); } else { i = next_item(&all, row2index(&all, at_bot, which), which); at_top = at_bot; set_top_item(&all, next_item(&all, row2index(&all, at_top, which), which), which); at_bot = skip_rows(&all, at_top, all.use_height, which); at_bot = MIN(at_bot, at_end); } break; case DLGK_ITEM_FIRST: i = first_item(&all, which); break; case DLGK_ITEM_LAST: i = last_item(&all, which); break; case DLGK_ITEM_PREV: i = prev_item(&all, cur_item, which); if (stop_prev(&all, cur_item, which)) continue; break; case DLGK_ITEM_NEXT: i = next_item(&all, cur_item, which); break; default: found = FALSE; break; } } if (found) { if (i != cur_item) { int now_at = index2row(&all, i, which); int oops = item_no; int old_item; dlg_trace_msg("<--CHOICE %d\n", i); dlg_trace_msg("<--topITM %d\n", moi->top_index); dlg_trace_msg("<--now_at %d\n", now_at); dlg_trace_msg("<--at_top %d\n", at_top); dlg_trace_msg("<--at_bot %d\n", at_bot); if (now_at >= at_bot) { while (now_at >= at_bot) { if ((at_bot - at_top) >= all.use_height) { set_top_item(&all, next_item(&all, moi->top_index, which), which); } at_top = index2row(&all, moi->top_index, which); at_bot = skip_rows(&all, at_top, all.use_height, which); dlg_trace_msg("...at_bot %d (now %d vs %d)\n", at_bot, now_at, at_end); dlg_trace_msg("...topITM %d\n", moi->top_index); dlg_trace_msg("...at_top %d (diff %d)\n", at_top, at_bot - at_top); if (at_bot >= at_end) { /* * If we bumped into the end, move the top-item * down by one line so that we can display the * last item in the list. */ if ((at_bot - at_top) > all.use_height) { set_top_item(&all, next_item(&all, moi->top_index, which), which); } else if (at_top > 0 && (at_bot - at_top) >= all.use_height) { set_top_item(&all, next_item(&all, moi->top_index, which), which); } break; } if (--oops < 0) { dlg_trace_msg("OOPS-forward\n"); break; } } } else if (now_at < at_top) { while (now_at < at_top) { old_item = moi->top_index; set_top_item(&all, prev_item(&all, moi->top_index, which), which); at_top = index2row(&all, moi->top_index, which); dlg_trace_msg("...at_top %d (now %d)\n", at_top, now_at); dlg_trace_msg("...topITM %d\n", moi->top_index); if (moi->top_index >= old_item) break; if (at_top <= now_at) break; if (--oops < 0) { dlg_trace_msg("OOPS-backward\n"); break; } } } dlg_trace_msg("-->now_at %d\n", now_at); cur_item = i; print_both(&all, cur_item); } dlg_trace_win(dialog); continue; /* wait for another key press */ } if (fkey) { switch (key) { case DLGK_ENTER: result = dlg_enter_buttoncode(button); break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif default: if (was_mouse) { if ((key2 = dlg_ok_buttoncode(key)) >= 0) { result = key2; break; } beep(); } } } else { beep(); } } dialog_state.visit_cols = save_visit; dlg_del_window(dialog); dlg_mouse_free_regions(); free(prompt); *current_item = cur_item; return result; }
int main(int argc, const char **argv) { struct partition_metadata *md; const char *prompt; struct partedit_item *items = NULL; struct gmesh mesh; int i, op, nitems, nscroll; int error; if (strcmp(basename(argv[0]), "sade") == 0) sade_mode = 1; TAILQ_INIT(&part_metadata); init_fstab_metadata(); init_dialog(stdin, stdout); if (!sade_mode) dialog_vars.backtitle = __DECONST(char *, "FreeBSD Installer"); dialog_vars.item_help = TRUE; nscroll = i = 0; /* Revert changes on SIGINT */ signal(SIGINT, sigint_handler); if (strcmp(basename(argv[0]), "autopart") == 0) { /* Guided */ prompt = "Please review the disk setup. When complete, press " "the Finish button."; /* Experimental ZFS autopartition support */ if (argc > 1 && strcmp(argv[1], "zfs") == 0) { part_wizard("zfs"); } else { part_wizard("ufs"); } } else if (strcmp(basename(argv[0]), "scriptedpart") == 0) { error = scripted_editor(argc, argv); prompt = NULL; if (error != 0) { end_dialog(); return (error); } } else { prompt = "Create partitions for FreeBSD. No changes will be " "made until you select Finish."; } /* Show the part editor either immediately, or to confirm wizard */ while (prompt != NULL) { dlg_clear(); dlg_put_backtitle(); error = geom_gettree(&mesh); if (error == 0) items = read_geom_mesh(&mesh, &nitems); if (error || items == NULL) { dialog_msgbox("Error", "No disks found. If you need to " "install a kernel driver, choose Shell at the " "installation menu.", 0, 0, TRUE); break; } get_mount_points(items, nitems); if (i >= nitems) i = nitems - 1; op = diskeditor_show("Partition Editor", prompt, items, nitems, &i, &nscroll); switch (op) { case 0: /* Create */ gpart_create((struct gprovider *)(items[i].cookie), NULL, NULL, NULL, NULL, 1); break; case 1: /* Delete */ gpart_delete((struct gprovider *)(items[i].cookie)); break; case 2: /* Modify */ gpart_edit((struct gprovider *)(items[i].cookie)); break; case 3: /* Revert */ gpart_revert_all(&mesh); while ((md = TAILQ_FIRST(&part_metadata)) != NULL) { if (md->fstab != NULL) { free(md->fstab->fs_spec); free(md->fstab->fs_file); free(md->fstab->fs_vfstype); free(md->fstab->fs_mntops); free(md->fstab->fs_type); free(md->fstab); } if (md->newfs != NULL) free(md->newfs); free(md->name); TAILQ_REMOVE(&part_metadata, md, metadata); free(md); } init_fstab_metadata(); break; case 4: /* Auto */ part_wizard("ufs"); break; } error = 0; if (op == 5) { /* Finished */ dialog_vars.ok_label = __DECONST(char *, "Commit"); dialog_vars.extra_label = __DECONST(char *, "Revert & Exit"); dialog_vars.extra_button = TRUE; dialog_vars.cancel_label = __DECONST(char *, "Back"); op = dialog_yesno("Confirmation", "Your changes will " "now be written to disk. If you have chosen to " "overwrite existing data, it will be PERMANENTLY " "ERASED. Are you sure you want to commit your " "changes?", 0, 0); dialog_vars.ok_label = NULL; dialog_vars.extra_button = FALSE; dialog_vars.cancel_label = NULL; if (op == 0 && validate_setup()) { /* Save */ error = apply_changes(&mesh); if (!error) apply_workaround(&mesh); break; } else if (op == 3) { /* Quit */ gpart_revert_all(&mesh); error = -1; break; } } geom_deletetree(&mesh); free(items); }
/* * Display a dialog box for entering a date */ int dialog_calendar(const char *title, const char *subtitle, int height, int width, int day, int month, int year) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_ENTER, ' ' ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), DLG_KEYS_DATA( DLGK_GRID_DOWN, 'j' ), DLG_KEYS_DATA( DLGK_GRID_DOWN, DLGK_MOUSE(KEY_NPAGE) ), DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_DOWN ), DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_GRID_LEFT, '-' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'h' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, CHR_BACKSPACE ), DLG_KEYS_DATA( DLGK_GRID_LEFT, CHR_PREVIOUS ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, '+' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, CHR_NEXT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_NEXT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_GRID_UP, 'k' ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_PREVIOUS ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_UP ), DLG_KEYS_DATA( DLGK_GRID_UP, DLGK_MOUSE(KEY_PPAGE) ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif BOX dy_box, mn_box, yr_box; int fkey; int key = 0; int key2; int step; int button; int result = DLG_EXIT_UNKNOWN; WINDOW *dialog; time_t now_time = time((time_t *) 0); struct tm current; int state = dlg_default_button(); const char **buttons = dlg_ok_labels(); char *prompt = dlg_strclone(subtitle); int mincols = MIN_WIDE; char buffer[MAX_LEN]; DIALOG_VARS save_vars; dlg_save_vars(&save_vars); dialog_vars.separate_output = TRUE; dlg_does_output(); now_time = time((time_t *) 0); current = *localtime(&now_time); if (day < 0) day = current.tm_mday; if (month < 0) month = current.tm_mon + 1; if (year < 0) year = current.tm_year + 1900; /* compute a struct tm that matches the day/month/year parameters */ if (((year -= 1900) > 0) && (year < 200)) { /* ugly, but I'd like to run this on older machines w/o mktime -TD */ for (;;) { if (year > current.tm_year) { now_time += ONE_DAY * days_in_year(¤t, 0); } else if (year < current.tm_year) { now_time -= ONE_DAY * days_in_year(¤t, -1); } else if (month > current.tm_mon + 1) { now_time += ONE_DAY * days_in_month(¤t, 0); } else if (month < current.tm_mon + 1) { now_time -= ONE_DAY * days_in_month(¤t, -1); } else if (day > current.tm_mday) { now_time += ONE_DAY; } else if (day < current.tm_mday) { now_time -= ONE_DAY; } else { break; } current = *localtime(&now_time); } } dlg_button_layout(buttons, &mincols); #ifdef KEY_RESIZE retry: #endif dlg_auto_size(title, prompt, &height, &width, 0, mincols); height += MIN_HIGH - 1; dlg_print_size(height, width); dlg_ctl_size(height, width); dialog = dlg_new_window(height, width, dlg_box_y_ordinate(height), dlg_box_x_ordinate(width)); dlg_register_window(dialog, "calendar", binding); dlg_register_buttons(dialog, "calendar", buttons); /* mainbox */ dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); (void) wattrset(dialog, dialog_attr); /* text mainbox */ dlg_print_autowrap(dialog, prompt, height, width); /* compute positions of day, month and year boxes */ memset(&dy_box, 0, sizeof(dy_box)); memset(&mn_box, 0, sizeof(mn_box)); memset(&yr_box, 0, sizeof(yr_box)); if (init_object(&dy_box, dialog, (width - DAY_WIDE) / 2, 1 + (height - (DAY_HIGH + BTN_HIGH + (5 * MARGIN))), DAY_WIDE, DAY_HIGH + 1, draw_day, 'D') < 0 || DrawObject(&dy_box) < 0) { return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars); } if (init_object(&mn_box, dialog, dy_box.x, dy_box.y - (HDR_HIGH + 2 * MARGIN), (DAY_WIDE / 2) - MARGIN, HDR_HIGH, draw_month, 'M') < 0 || DrawObject(&mn_box) < 0) { return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars); } if (init_object(&yr_box, dialog, dy_box.x + mn_box.width + 2, mn_box.y, mn_box.width, mn_box.height, draw_year, 'Y') < 0 || DrawObject(&yr_box) < 0) { return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars); } dlg_trace_win(dialog); while (result == DLG_EXIT_UNKNOWN) { BOX *obj = (state == sDAY ? &dy_box : (state == sMONTH ? &mn_box : (state == sYEAR ? &yr_box : 0))); button = (state < 0) ? 0 : state; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); if (obj != 0) dlg_set_focus(dialog, obj->window); key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; if (fkey && (key >= DLGK_MOUSE(KEY_MIN) && key <= DLGK_MOUSE(KEY_MAX))) { key = dlg_lookup_key(dialog, key - M_EVENT, &fkey); } if ((key2 = dlg_char_to_button(key, buttons)) >= 0) { result = key2; } else if (fkey) { /* handle function-keys */ switch (key) { case DLGK_MOUSE('D'): state = sDAY; break; case DLGK_MOUSE('M'): state = sMONTH; break; case DLGK_MOUSE('Y'): state = sYEAR; break; case DLGK_ENTER: result = dlg_enter_buttoncode(button); break; case DLGK_FIELD_PREV: state = dlg_prev_ok_buttonindex(state, sMONTH); break; case DLGK_FIELD_NEXT: state = dlg_next_ok_buttonindex(state, sMONTH); break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif default: step = 0; key2 = -1; if (is_DLGK_MOUSE(key)) { if ((key2 = dlg_ok_buttoncode(key - M_EVENT)) >= 0) { result = key2; break; } else if (key >= DLGK_MOUSE(KEY_MAX)) { state = sDAY; obj = &dy_box; key2 = 1; step = (key - DLGK_MOUSE(KEY_MAX) - day_cell_number(¤t)); } } if (obj != 0) { if (key2 < 0) step = next_or_previous(key, (obj == &dy_box)); if (step != 0) { struct tm old = current; /* see comment regarding mktime -TD */ if (obj == &dy_box) { now_time += ONE_DAY * step; } else if (obj == &mn_box) { if (step > 0) now_time += ONE_DAY * days_in_month(¤t, 0); else now_time -= ONE_DAY * days_in_month(¤t, -1); } else if (obj == &yr_box) { if (step > 0) now_time += (ONE_DAY * days_in_year(¤t, 0)); else now_time -= (ONE_DAY * days_in_year(¤t, -1)); } current = *localtime(&now_time); if (obj != &dy_box && (current.tm_mday != old.tm_mday || current.tm_mon != old.tm_mon || current.tm_year != old.tm_year)) DrawObject(&dy_box); if (obj != &mn_box && current.tm_mon != old.tm_mon) DrawObject(&mn_box); if (obj != &yr_box && current.tm_year != old.tm_year) DrawObject(&yr_box); (void) DrawObject(obj); } } else if (state >= 0) { if (next_or_previous(key, FALSE) < 0) state = dlg_prev_ok_buttonindex(state, sMONTH); else if (next_or_previous(key, FALSE) > 0) state = dlg_next_ok_buttonindex(state, sMONTH); } break; } } } #define DefaultFormat(dst, src) \ sprintf(dst, "%02d/%02d/%0d", \ src.tm_mday, src.tm_mon + 1, src.tm_year + 1900) #ifdef HAVE_STRFTIME if (dialog_vars.date_format != 0) { size_t used = strftime(buffer, sizeof(buffer) - 1, dialog_vars.date_format, ¤t); if (used == 0 || *buffer == '\0') DefaultFormat(buffer, current); } else #endif DefaultFormat(buffer, current); dlg_add_result(buffer); dlg_add_separator(); return CleanupResult(result, dialog, prompt, &save_vars); }
/* * Display text from a file in a dialog box, like in a "tail -f". */ int dialog_tailbox(const char *title, const char *file, int height, int width, int bg_task) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_BEGIN, '0' ), DLG_KEYS_DATA( DLGK_BEGIN, KEY_BEG ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'H' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'h' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'L' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif int fkey; int x, y, result, thigh; WINDOW *dialog, *text; const char **buttons = 0; MY_OBJ *obj; FILE *fd; int min_width = 12; /* Open input file for reading */ if ((fd = fopen(file, "rb")) == NULL) dlg_exiterr("Can't open input file in dialog_tailbox()."); #ifdef KEY_RESIZE retry: #endif dlg_auto_sizefile(title, file, &height, &width, 2, min_width); dlg_print_size(height, width); dlg_ctl_size(height, width); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); thigh = height - ((2 * MARGIN) + (bg_task ? 0 : 2)); dialog = dlg_new_window(height, width, y, x); dlg_mouse_setbase(x, y); /* Create window for text region, used for scrolling text */ text = dlg_sub_window(dialog, thigh, width - (2 * MARGIN), y + MARGIN, x + MARGIN); dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); dlg_draw_bottom_box(dialog); dlg_draw_title(dialog, title); dlg_draw_helpline(dialog, FALSE); if (!bg_task) { buttons = dlg_exit_label(); dlg_button_layout(buttons, &min_width); dlg_draw_buttons(dialog, height - (2 * MARGIN), 0, buttons, FALSE, FALSE, width); } (void) wmove(dialog, thigh, (MARGIN + 1)); (void) wnoutrefresh(dialog); obj = dlg_calloc(MY_OBJ, 1); assert_ptr(obj, "dialog_tailbox"); obj->obj.input = fd; obj->obj.win = dialog; obj->obj.handle_getc = handle_my_getc; obj->obj.handle_input = bg_task ? handle_input : 0; obj->obj.keep_bg = bg_task && dialog_vars.cant_kill; obj->obj.bg_task = bg_task; obj->text = text; obj->buttons = buttons; dlg_add_callback(&(obj->obj)); dlg_register_window(dialog, "tailbox", binding); dlg_register_buttons(dialog, "tailbox", buttons); /* Print last page of text */ dlg_attr_clear(text, thigh, getmaxx(text), dialog_attr); repaint_text(obj); if (bg_task) { result = DLG_EXIT_OK; } else { int ch; do { ch = dlg_getc(dialog, &fkey); #ifdef KEY_RESIZE if (fkey && ch == KEY_RESIZE) { /* reset data */ height = old_height; width = old_width; /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); dlg_button_layout(buttons, &min_width); goto retry; } #endif } while (handle_my_getc(&(obj->obj), ch, fkey, &result)); } dlg_mouse_free_regions(); return result; }
/* * Display a dialog box with two buttons - Yes and No. */ int dialog_yesno(const char *title, const char *cprompt, int height, int width) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_ENTER, ' ' ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_DOWN ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_UP ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), SCROLLKEY_BINDINGS, END_KEYS_BINDING }; /* *INDENT-ON* */ int x, y; int key = 0, fkey; int code; int button = dlg_defaultno_button(); WINDOW *dialog = 0; int result = DLG_EXIT_UNKNOWN; char *prompt = dlg_strclone(cprompt); const char **buttons = dlg_yes_labels(); int min_width = 25; bool show = TRUE; int page, last = 0, offset = 0; #ifdef KEY_RESIZE int req_high = height; int req_wide = width; restart: #endif dlg_tab_correct_str(prompt); dlg_button_layout(buttons, &min_width); dlg_auto_size(title, prompt, &height, &width, 2, min_width); dlg_print_size(height, width); dlg_ctl_size(height, width); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); #ifdef KEY_RESIZE if (dialog != 0) dlg_move_window(dialog, height, width, y, x); else #endif { dialog = dlg_new_window(height, width, y, x); dlg_register_window(dialog, "yesno", binding); dlg_register_buttons(dialog, "yesno", buttons); } dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); dlg_draw_bottom_box(dialog); dlg_draw_title(dialog, title); dlg_draw_helpline(dialog, FALSE); wattrset(dialog, dialog_attr); page = height - (1 + 3 * MARGIN); dlg_draw_buttons(dialog, height - 2 * MARGIN, 0, buttons, button, FALSE, width); while (result == DLG_EXIT_UNKNOWN) { if (show) { last = dlg_print_scrolled(dialog, prompt, offset, page, width, TRUE); show = FALSE; } key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; if ((code = dlg_char_to_button(key, buttons)) >= 0) { result = dlg_ok_buttoncode(code); break; } /* handle function keys */ if (fkey) { switch (key) { case DLGK_FIELD_NEXT: button = dlg_next_button(buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; case DLGK_FIELD_PREV: button = dlg_prev_button(buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; case DLGK_ENTER: result = dlg_yes_buttoncode(button); break; #ifdef KEY_RESIZE case KEY_RESIZE: dlg_clear(); height = req_high; width = req_wide; goto restart; #endif default: if (is_DLGK_MOUSE(key)) { result = dlg_yes_buttoncode(key - M_EVENT); if (result < 0) result = DLG_EXIT_OK; } else if (dlg_check_scrolled(key, last, page, &show, &offset) != 0) { beep(); } break; } } else { beep(); } } dlg_del_window(dialog); dlg_mouse_free_regions(); free(prompt); return result; }