diff options
Diffstat (limited to 'source3/utils/regedit_dialog.c')
-rw-r--r-- | source3/utils/regedit_dialog.c | 229 |
1 files changed, 212 insertions, 17 deletions
diff --git a/source3/utils/regedit_dialog.c b/source3/utils/regedit_dialog.c index b5e41ee901..7c4a0bb918 100644 --- a/source3/utils/regedit_dialog.c +++ b/source3/utils/regedit_dialog.c @@ -19,7 +19,11 @@ #include "includes.h" #include "regedit_dialog.h" +#include "regedit_valuelist.h" +#include "util_reg.h" +#include "lib/registry/registry.h" #include <stdarg.h> +#include <form.h> static int dialog_free(struct dialog *dia) { @@ -226,30 +230,221 @@ struct dialog *dialog_confirm_new(TALLOC_CTX *ctx, const char *title, return dia; } -void dialog_set_cb(struct dialog *dia, dialogfn fn, void *arg) +static int handle_menu_input(MENU *menu, int c) { - dia->dialogcb = fn; - dia->dialogarg = arg; + ITEM *item; + + switch (c) { + case KEY_LEFT: + menu_driver(menu, REQ_LEFT_ITEM); + break; + case KEY_RIGHT: + menu_driver(menu, REQ_RIGHT_ITEM); + break; + case KEY_ENTER: + case '\n': + item = current_item(menu); + return (int)(uintptr_t)item_userptr(item); + } + + return -1; +} + +int dialog_modal_loop(struct dialog *dia) +{ + int c; + int selection = -1; + + keypad(dia->window, true); + update_panels(); + doupdate(); + + while (selection == -1) { + c = wgetch(dia->window); + selection = handle_menu_input(dia->choices, c); + update_panels(); + doupdate(); + } + + talloc_free(dia); + + return selection; } -void dialog_driver(struct dialog *dia, enum dialog_op op) +static void handle_form_input(FORM *frm, int c) { - switch (op) { - case DIALOG_LEFT: - menu_driver(dia->choices, REQ_LEFT_ITEM); + switch (c) { + case '\n': + form_driver(frm, REQ_NEW_LINE); + break; + case KEY_UP: + form_driver(frm, REQ_UP_CHAR); + break; + case KEY_DOWN: + form_driver(frm, REQ_DOWN_CHAR); + break; + case '\b': + case KEY_BACKSPACE: + form_driver(frm, REQ_DEL_PREV); + break; + case KEY_LEFT: + form_driver(frm, REQ_LEFT_CHAR); break; - case DIALOG_RIGHT: - menu_driver(dia->choices, REQ_RIGHT_ITEM); + case KEY_RIGHT: + form_driver(frm, REQ_RIGHT_CHAR); break; - case DIALOG_ENTER: - if (dia->dialogcb) { - ITEM *item; - int selection; - - item = current_item(dia->choices); - selection = (int)(uintptr_t)item_userptr(item); - dia->dialogcb(dia, selection, dia->dialogarg); + default: + form_driver(frm, c); + break; + } +} + +#define MAX_FIELDS 8 + +enum input_section { + IN_NAME, + IN_DATA, + IN_MENU +}; + +static void fill_value_buffer(TALLOC_CTX *ctx, FIELD *fld, const struct value_item *vitem) +{ + char *tmp; + + switch (vitem->type) { + case REG_DWORD: { + uint32_t v = 0; + if (vitem->data.length >= 4) { + v = IVAL(vitem->data.data, 0); } + tmp = talloc_asprintf(ctx, "0x%x", v); + set_field_buffer(fld, 0, tmp); + talloc_free(tmp); break; } + case REG_SZ: + case REG_EXPAND_SZ: { + const char *s; + + if (!pull_reg_sz(ctx, &vitem->data, &s)) { + break; + } + set_field_buffer(fld, 0, s); + break; + } + + } +} + +static void set_value(TALLOC_CTX *ctx, FIELD *fld, struct registry_key *key, + const struct value_item *vitem) +{ +} + +int dialog_edit_value(TALLOC_CTX *ctx, struct registry_key *key, + const struct value_item *vitem, WINDOW *below) +{ + struct dialog *dia; + const char *choices[] = { + "Ok", + "Cancel", + NULL + }; + char *title; + int nlines, ncols; + int rv = -1; + WINDOW *input_win; + FORM *input; + FIELD *field[MAX_FIELDS]; + enum input_section section; + + title = talloc_asprintf(ctx, "Edit %s value", str_regtype(vitem->type)); + if (title == NULL) { + return -1; + } + + nlines = 15; + ncols = 50; + dia = dialog_choice_center_new(ctx, title, choices, nlines, ncols, below); + if (dia == NULL) { + goto finish; + } + + memset(field, '\0', sizeof(*field) * MAX_FIELDS); + field[0] = new_field(1, ncols - 4, 1, 1, 0, 0); + field[1] = new_field(1, ncols - 4, 4, 1, 0, 0); + + set_field_back(field[0], A_UNDERLINE); + set_field_back(field[1], A_UNDERLINE); + field_opts_off(field[0], O_BLANK | O_AUTOSKIP | O_STATIC); + field_opts_off(field[1], O_BLANK | O_AUTOSKIP | O_STATIC); + + if (vitem) { + set_field_buffer(field[0], 0, vitem->value_name); + field_opts_off(field[0], O_EDIT); + fill_value_buffer(dia, field[1], vitem); + } + + input = new_form(field); + form_opts_off(input, O_NL_OVERLOAD | O_BS_OVERLOAD); + + input_win = derwin(dia->sub_window, nlines - 3, ncols - 3, 0, 0); + + set_form_win(input, dia->sub_window); + set_form_sub(input, input_win); + post_form(input); + mvwprintw(dia->sub_window, 0, 0, "Name"); + mvwprintw(dia->sub_window, 3, 0, "Data"); + + keypad(dia->window, true); + update_panels(); + doupdate(); + + section = IN_NAME; + + while (1) { + int c = wgetch(dia->window); + if (c == '\t') { + switch (section) { + case IN_NAME: + section = IN_DATA; + set_current_field(input, field[1]); + break; + case IN_DATA: + section = IN_MENU; + menu_driver(dia->choices, REQ_FIRST_ITEM); + break; + case IN_MENU: + section = IN_NAME; + set_current_field(input, field[0]); + break; + } + continue; + } + + if (section == IN_NAME || section == IN_DATA) { + handle_form_input(input, c); + } else { + rv = handle_menu_input(dia->choices, c); + if (rv != -1) { + goto finish; + } + } + + update_panels(); + doupdate(); + } + +finish: + if (title) { + talloc_free(title); + } + if (dia) { + talloc_free(dia); + } + if (rv == DIALOG_OK) { + //set_value + } + + return rv; } |