コード例 #1
0
/*
 * Turn on the passed field options.
 */
int
field_opts_on(FIELD *field, Form_Options options)
{
	int i;
	
	FIELD *fp = (field == NULL) ? &_formi_default_field : field;

	  /* not allowed to set opts if the field is the current one */
	if ((field != NULL) && (field->parent != NULL) &&
	    (field->parent->cur_field == field->index))
		return E_CURRENT;
	
	if ((options & O_STATIC) == O_STATIC) {
		for (i = 0; i < fp->nbuf; i++) {
			if (fp->buffers[i].length > fp->cols)
				fp->buffers[i].string[fp->cols] = '\0';
		}
	}
	
	fp->opts |= options;
	
	  /* if appropriate, redraw the field */
	if ((field != NULL) && (field->parent != NULL)
	    && (field->parent->posted == 1)) {
		_formi_redraw_field(field->parent, field->index);
		pos_form_cursor(field->parent);
		wrefresh(field->parent->scrwin);
	}

	return E_OK;
}
コード例 #2
0
ファイル: vuurmuur_conf.c プロジェクト: inliniac/vuurmuur
/*  draw_field_active_mark

    Draws marks before and after the active field. If prev is non-NULL we first
   remove the marks from the previous field.
*/
void draw_field_active_mark(const FIELD *cur, const FIELD *prev,
        WINDOW *formwin, FORM *form, const chtype ch)
{
    int pos_x, pos_y, x, y, off_row, wrk_buff;

    /* safety */
    if (!cur || !formwin || !form)
        return;

    /* if supplied we remove the previous marking */
    if (prev) {
        if (field_info(prev, &y, &x, &pos_y, &pos_x, &off_row, &wrk_buff) < 0)
            return;

        mvwprintw(formwin, pos_y + 1, pos_x, " ");
        mvwprintw(formwin, pos_y + 1, pos_x + x + 3, " ");
    }

    /* draw our marking */
    if (field_info(cur, &y, &x, &pos_y, &pos_x, &off_row, &wrk_buff) < 0)
        return;

    wattron(formwin, ch);
    mvwprintw(formwin, pos_y + 1, pos_x, ">");
    mvwprintw(formwin, pos_y + 1, pos_x + x + 3, "<");
    wattroff(formwin, ch);
    wrefresh(formwin);

    /* restore cursor position */
    pos_form_cursor(form);
    return;
}
コード例 #3
0
ファイル: ui.c プロジェクト: iamjamestl/school
inline void select_form() {
	pos_form_cursor(url_form);
	form_driver(url_form, ' ');
	form_driver(url_form, REQ_LEFT_CHAR);
	form_driver(url_form, REQ_DEL_CHAR);
	wrefresh(input_window);
}
コード例 #4
0
/*
 * Init all the field variables, perform wrapping and other tasks
 * after the field buffer is set.
 */
static int
field_buffer_init(FIELD *field, int buffer, unsigned int len)
{
	int status;
	char *newp;
	
	if (buffer == 0) {
		field->start_char = 0;
		field->start_line = 0;
		field->row_xpos = 0;
		field->cursor_xpos = 0;
		field->cursor_ypos = 0;
		field->row_count = 1; /* must be at least one row  XXX need to shift old rows (if any) to free list??? */
		field->alines->length = len;
		if ((newp = realloc(field->alines->string,
				    (size_t) len + 1)) == NULL)
			return E_SYSTEM_ERROR;
		field->alines->string = newp;
		field->alines->allocated = len + 1;
		strlcpy(field->alines->string, field->buffers[buffer].string,
			(size_t) len + 1);
		field->alines->expanded =
			_formi_tab_expanded_length(field->alines->string,
						   0, field->alines->length);

		field->start_line = field->alines;
		field->cur_line = field->alines;
		
		  /* we have to hope the wrap works - if it does not then the
		     buffer is pretty much borked */
		status = _formi_wrap_field(field, field->cur_line);
		if (status != E_OK)
			return status;

		  /*
		   * calculate the tabs for a single row field, the
		   * multiline case is handled when the wrap is done.
		   */
		if (field->row_count == 1)
			_formi_calculate_tabs(field->alines);

		  /* redraw the field to reflect the new contents. If the field
		   * is attached....
		   */
		if ((field->parent != NULL) && (field->parent->posted == 1)) {
			_formi_redraw_field(field->parent, field->index);
			  /* make sure cursor goes back to current field */
			pos_form_cursor(field->parent);
		}
	}

	return E_OK;
}
コード例 #5
0
ファイル: post.c プロジェクト: sabotage-linux/netbsd-curses
/*
 * Post the form to the screen.
 */
int
post_form(FORM *form)
{
	int rows, cols, status;
	
	if (form == NULL)
		return E_BAD_ARGUMENT;

	if (form->posted == 1)
		return E_POSTED;

	if ((form->fields == NULL) || (form->fields[0] == NULL))
		return E_NOT_CONNECTED;

	if (form->in_init == 1)
		return E_BAD_STATE;

	if (scale_form(form, &rows, &cols) != E_OK)
		return E_SYSTEM_ERROR;
	
	if ((form->scrwin != NULL) && ((rows > getmaxy(form->scrwin))
				       || (cols > getmaxx(form->scrwin)))) {
		return E_NO_ROOM;
	}

	form->in_init = 1;
	if (form->form_init != NULL)
		form->form_init(form);

	if (form->field_init != NULL)
		form->field_init(form);
	form->in_init = 0;

	_formi_pos_first_field(form);
	if ((status = _formi_draw_page(form)) != E_OK)
		return status;

	form->posted = 1;
	pos_form_cursor(form);
	
	return E_OK;
}
コード例 #6
0
/*
 * Turn off the passed field options.
 */
int
field_opts_off(FIELD *field, Form_Options options)
{
	FIELD *fp = (field == NULL) ? &_formi_default_field : field;

	  /* not allowed to set opts if the field is the current one */
	if ((field != NULL) && (field->parent != NULL) &&
	    (field->parent->cur_field == field->index))
		return E_CURRENT;
	
	fp->opts &= ~options;
	
	  /* if appropriate, redraw the field */
	if ((field != NULL) && (field->parent != NULL)
	    && (field->parent->posted == 1)) {
		_formi_redraw_field(field->parent, field->index);
		pos_form_cursor(field->parent);
		wrefresh(field->parent->scrwin);
	}
	
	return E_OK;
}
コード例 #7
0
/*
 * Create and initialize a new popup. popup_btn_action *must* be filled before
 * this call.
 * @param rows The number of rows for win_body
 * @param cols The number of lines for win_body
 * @param posy Position of the top left corner on the y axis
 * @param posx Position of the top left corner on the x axis
 * @param requests An array of strings to put in the form. This can be null:
 *	only the title and the buttons will be present.
 * @param title A string to print in the popup.
 */
void popup_new(int rows, int cols, int posy, int posx, char **requests,
		char *title)
{
	int i, cury = 0, curx = 1, tmp, nb_buttons, nb_fields;
	WINDOW *inner;

	win_body = newwin(rows, cols, posy, posx);
	assert(win_body != NULL && popup_btn_action != NULL);
	box(win_body, 0, 0);

	for (nb_buttons = 0; popup_btn_action[nb_buttons]; nb_buttons++);

	popup_items = malloc(sizeof(ITEM *) * (nb_buttons+1));
	assert(popup_items != NULL);
	assert(popup_btn_action != NULL);

	for (i = 0; popup_btn_action[i]; i++) {
		popup_items[i] = new_item(popup_btn_action[i]->key, "");
		assert(popup_items[i] != NULL);
	}

	popup_items[i] = NULL;
	popup_menu = new_menu(popup_items);
	win_menu = derwin(win_body, 3, cols-2, rows-4, 1);
	assert(popup_menu != NULL && win_menu != NULL);
	box(win_menu, 0, 0);
	set_menu_win(popup_menu, win_menu);
	set_menu_format(popup_menu, 1, nb_buttons);
	tmp = popup_menu->fcols * (popup_menu->namelen + popup_menu->spc_rows);
	tmp--;
	inner = derwin(win_menu, 1, tmp, 1, (cols-3-tmp)/2);
	assert(inner != NULL);
	set_menu_sub(popup_menu, inner);
	set_menu_mark(popup_menu, "");
	assert(post_menu(popup_menu) == E_OK);

	mvwprintw(win_body, 1, 2, "%s", title);

	for (nb_fields = 0; requests && requests[nb_fields]; nb_fields++);

	if (nb_fields == 0) {
		popup_fields = NULL;
		popup_form = NULL;
		is_on_button = true;
		return;
	}

	popup_fields = malloc(sizeof(FIELD *) * (nb_fields+1));
	assert(popup_fields != NULL);

	for (i = 0; i < nb_fields && requests[i]; i++) {

		if (i % 2 == 1) {
			popup_fields[i] = new_field(1, 41, cury, curx, 0, 0);
			assert(popup_fields[i] != NULL);
			set_field_buffer(popup_fields[i], 0, strdup(requests[i]));
			cury = cury+1;
			curx = 1;
			field_opts_on(popup_fields[i], O_ACTIVE);
			field_opts_on(popup_fields[i], O_EDIT);
			field_opts_off(popup_fields[i], O_STATIC);
			set_field_back(popup_fields[i], A_UNDERLINE); 
		} else {
			popup_fields[i] = new_field(1, 45, cury, curx, 0, 0);
			assert(popup_fields[i] != NULL);
			set_field_buffer(popup_fields[i], 0, strdup(requests[i]));
			curx = strlen(requests[i]) + 2;
			field_opts_off(popup_fields[i], O_ACTIVE);
			field_opts_off(popup_fields[i], O_EDIT);
		}
	}

	popup_fields[i] = NULL;
	popup_form = new_form(popup_fields);
	assert(popup_form != NULL);
	win_form = derwin(win_body, rows-6, cols-2, 1, 1);
	assert(popup_form != NULL && win_form != NULL);
	assert(set_form_win(popup_form, win_form) == E_OK);

	int diff_rows = popup_form->cols - win_form->_maxx-2;

	/*
	 * There isn't enough rows for the form so we resize win_body and
	 * win_form to fit the form.
	 * This resize isn't needed for the lines (as there is always fery few
	 * of them).
	 */
	if (diff_rows > 0) {
		wresize(win_body, win_body->_maxy, win_body->_maxx + diff_rows);
		wresize(win_form, win_form->_maxy, win_form->_maxx - 2 + diff_rows);
	}

	inner = derwin(win_form, win_form->_maxy-2, win_form->_maxx, 2, 0);
	assert(inner != NULL);
	set_form_sub(popup_form, inner);

	assert(post_form(popup_form) == E_OK);
	is_on_button = false;
	set_menu_fore(popup_menu, A_NORMAL); // "hide" the button
	pos_form_cursor(popup_form);
}
コード例 #8
0
/*
 * This is called by main.c ncurses_action everytime a popup exists.
 * It's used to handle characters input in forms and button pressing.
 */
void popup_driver(int ch)
{
	switch (ch) {
		case KEY_DOWN:
			if (is_on_button || !popup_form)
				break;

			if (popup_form->current == popup_fields[popup_form->maxfield-1])
				switch_to_buttons();
			else
				form_driver(popup_form, REQ_NEXT_FIELD);
			break;

		case KEY_UP:
			if (is_on_button) {
				if (!popup_form)
					break;

				is_on_button = false;
				set_menu_fore(popup_menu, A_NORMAL); // "hide" the button
			} else
				form_driver(popup_form, REQ_PREV_FIELD);
			break;

		case KEY_LEFT:
			if (is_on_button)
				menu_driver(popup_menu, REQ_LEFT_ITEM);
			else
				form_driver(popup_form, REQ_PREV_CHAR);
			break;

		case KEY_RIGHT:
			if (is_on_button)
				menu_driver(popup_menu, REQ_RIGHT_ITEM);
			else
				form_driver(popup_form, REQ_NEXT_CHAR);
			break;

		case 10:
			if (is_on_button)
				driver_buttons(current_item(popup_menu));
			else
				switch_to_buttons();

			break;

		// Delete the char before cursor
		case KEY_BACKSPACE:
		case 127:
			if (!is_on_button)
				form_driver(popup_form, REQ_DEL_PREV);
			break;

		// Delete the char under the cursor
		case KEY_DC:
			if (!is_on_button)
				form_driver(popup_form, REQ_DEL_CHAR);
			break;

		default:
			if (!is_on_button)
				form_driver(popup_form, ch);

			break;

	}

	if (popup_menu) {
		if (is_on_button)
			pos_menu_cursor(popup_menu);
		else
			pos_form_cursor(popup_form);
	}

	wrefresh(win_body);
}
コード例 #9
0
ファイル: driver.c プロジェクト: VargMon/netbsd-curses
int
form_driver(FORM *form, int c)
{
	FIELD *fieldp;
	int update_page, update_field, old_field, old_page, status;
	int start_field;
	unsigned int pos;
	
	if (form == NULL)
		return E_BAD_ARGUMENT;

	if ((form->fields == NULL) || (*(form->fields) == NULL))
		return E_INVALID_FIELD;

	if (form->posted != 1)
		return E_NOT_POSTED;

	if (form->in_init == 1)
		return E_BAD_STATE;


	old_field = start_field = form->cur_field;
	fieldp = form->fields[form->cur_field];
	update_page = update_field = 0;
	status = E_OK;
	
	if (c < REQ_MIN_REQUEST) {
		if (isprint(c) || isblank(c)) {
			do {
				pos = fieldp->start_char + fieldp->row_xpos;
				
			      /* check if we are allowed to edit this field */
				if ((fieldp->opts & O_EDIT) != O_EDIT)
					return E_REQUEST_DENIED;
				
				if ((status =
				     (_formi_add_char(fieldp, pos, c)))
				    == E_REQUEST_DENIED) {
			
					  /*
					   * Need to check here if we
					   * want to autoskip.  we
					   * call the form driver
					   * recursively to pos us on
					   * the next field and then
					   * we loop back to ensure
					   * the next field selected
					   * can have data added to it
					   */
					if ((fieldp->opts & O_AUTOSKIP)
					    != O_AUTOSKIP)
						return E_REQUEST_DENIED;
					status = form_driver(form,
							     REQ_NEXT_FIELD);
					if (status != E_OK)
						return status;

					  /*
					   * check if we have looped
                                           * around all the fields.
                                           * This can easily happen if
                                           * all the fields are full.
					   */
					if (start_field == form->cur_field)
						return E_REQUEST_DENIED;
					
					old_field = form->cur_field;
					fieldp = form->fields[form->cur_field];
					status = _formi_add_char(fieldp,
							fieldp->start_char
							+ fieldp->cursor_xpos,
							c);
				} else if (status == E_INVALID_FIELD)
					  /* char failed validation, just
					   * return the status.
					   */
					return status;
				else if (status == E_NO_ROOM)
					  /* we will get this if the line
					   * wrapping fails.  Deny the
					   * request.
					   */
					return E_REQUEST_DENIED;
			}
			while (status != E_OK);
			update_field = (status == E_OK);
		} else
			return E_REQUEST_DENIED;
	} else {
		if (c > REQ_MAX_COMMAND)
			return E_UNKNOWN_COMMAND;

		if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
			  /* first check the field we are in is ok */
			if (_formi_validate_field(form) != E_OK)
				return E_INVALID_FIELD;

			if (form->field_term != NULL)
				form->field_term(form);

			  /*
			   * if we have a page movement then the form term
			   * needs to be called too
			   */ 
			if ((c <= REQ_LAST_PAGE) && (form->form_term != NULL))
				form->form_term(form);
		}
		
			
		switch (c) {
		case REQ_NEXT_PAGE:
			if (form->page < form->max_page) {
				old_page = form->page;
				form->page++;
				update_page = 1;
				if (_formi_pos_first_field(form) != E_OK) {
					form->page = old_page;
					status = E_REQUEST_DENIED;
				}
			} else
				status = E_REQUEST_DENIED;
			break;
		
		case REQ_PREV_PAGE:
			if (form->page > 0) {
				old_page = form->page;
				form->page--;
				update_page = 1;
				if (_formi_pos_first_field(form) != E_OK) {
					form->page = old_page;
					status = E_REQUEST_DENIED;
				}
			} else
				status = E_REQUEST_DENIED;
			break;
		
		case REQ_FIRST_PAGE:
			old_page = form->page;
			form->page = 0;
			update_page = 1;
			if (_formi_pos_first_field(form) != E_OK) {
				form->page = old_page;
				status = E_REQUEST_DENIED;
			}
			break;
		
		case REQ_LAST_PAGE:
			old_page = form->page;
			form->page = form->max_page - 1;
			update_page = 1;
			if (_formi_pos_first_field(form) != E_OK) {
				form->page = old_page;
				status = E_REQUEST_DENIED;
			}
			break;
		
		case REQ_NEXT_FIELD:
			status = _formi_pos_new_field(form, _FORMI_FORWARD,
						      FALSE);
			update_field = 1;
			break;
		
		case REQ_PREV_FIELD:
			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
						      FALSE);
			update_field = 1;
			break;
		
		case REQ_FIRST_FIELD:
			form->cur_field = 0;
			update_field = 1;
			break;
		
		case REQ_LAST_FIELD:
			form->cur_field = form->field_count - 1;
			update_field = 1;
			break;
		
		case REQ_SNEXT_FIELD:
			status = _formi_pos_new_field(form, _FORMI_FORWARD,
						      TRUE);
			update_field = 1;
			break;
		
		case REQ_SPREV_FIELD:
			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
						      TRUE);
			update_field = 1;
			break;
		
		case REQ_SFIRST_FIELD:
			fieldp = TAILQ_FIRST(&form->sorted_fields);
			form->cur_field = fieldp->index;
			update_field = 1;
			break;
		
		case REQ_SLAST_FIELD:
			fieldp = TAILQ_LAST(&form->sorted_fields,
			    _formi_sort_head);
			form->cur_field = fieldp->index;
			update_field = 1;
			break;

			  /*
			   * The up, down, left and right field traversals
			   * are rolled up into a single function, allow a
			   * fall through to that function.
			   */
		case REQ_LEFT_FIELD:
		case REQ_RIGHT_FIELD:
		case REQ_UP_FIELD:
		case REQ_DOWN_FIELD:
			status = traverse_form_links(form, c);
			update_field = 1;
			break;

			  /* the following commands modify the buffer, check if
			     this is allowed first before falling through. */

		case REQ_DEL_PREV:
			  /*
			   * need to check for the overloading of this
			   * request.  If overload flag set and we are
			   * at the start of field this request turns
			   * into a previous field request. Otherwise
			   * fallthrough to the field handler.
			   */
			if ((form->opts & O_BS_OVERLOAD) == O_BS_OVERLOAD) {
				if ((fieldp->start_char == 0) &&
				    (fieldp->start_line == 0) &&
				    (fieldp->row_xpos == 0)) {
					update_field =
						_formi_manipulate_field(form,
							REQ_PREV_FIELD);
					break;
				}
			}

			  /* FALLTHROUGH */
		case REQ_NEW_LINE:
			  /*
			   * need to check for the overloading of this
			   * request.  If overload flag set and we are
			   * at the start of field this request turns
			   * into a next field request. Otherwise
			   * fallthrough to the field handler.
			   */
			if ((form->opts & O_NL_OVERLOAD) == O_NL_OVERLOAD) {
				if ((fieldp->start_char == 0) &&
				    (fieldp->start_line == 0) &&
				    (fieldp->row_xpos == 0)) {
					update_field =
						_formi_manipulate_field(form,
							REQ_NEXT_FIELD);
					break;
				}
			}

			  /* FALLTHROUGH */
		case REQ_INS_CHAR:
		case REQ_INS_LINE:
		case REQ_DEL_CHAR:
		case REQ_DEL_LINE:
		case REQ_DEL_WORD:
		case REQ_CLR_EOL:
		case REQ_CLR_EOF:
		case REQ_CLR_FIELD:
		case REQ_OVL_MODE:
		case REQ_INS_MODE:
			  /* check if we are allowed to edit the field and fall
			   * through if we are.
			   */
			if ((form->fields[form->cur_field]->opts & O_EDIT) != O_EDIT)
				return E_REQUEST_DENIED;
		
			  /* the following manipulate the field contents, bundle
			     them into one function.... */
			  /* FALLTHROUGH */
		case REQ_NEXT_CHAR:
		case REQ_PREV_CHAR:
		case REQ_NEXT_LINE:
		case REQ_PREV_LINE:
		case REQ_NEXT_WORD:
		case REQ_PREV_WORD:
		case REQ_BEG_FIELD:
		case REQ_END_FIELD:
		case REQ_BEG_LINE:
		case REQ_END_LINE:
		case REQ_LEFT_CHAR:
		case REQ_RIGHT_CHAR:
		case REQ_UP_CHAR:
		case REQ_DOWN_CHAR:
		case REQ_SCR_FLINE:
		case REQ_SCR_BLINE:
		case REQ_SCR_FPAGE:
		case REQ_SCR_BPAGE:
		case REQ_SCR_FHPAGE:
		case REQ_SCR_BHPAGE:
		case REQ_SCR_FCHAR:
		case REQ_SCR_BCHAR:
		case REQ_SCR_HFLINE:
		case REQ_SCR_HBLINE:
		case REQ_SCR_HFHALF:
		case REQ_SCR_HBHALF:
			update_field = _formi_manipulate_field(form, c);
			break;
		
		case REQ_VALIDATION:
			return _formi_validate_field(form);
			  /* NOTREACHED */
			break;
		
		case REQ_PREV_CHOICE:
		case REQ_NEXT_CHOICE:
			update_field = _formi_field_choice(form, c);
			  /* reinit the cursor pos just in case */
			if (update_field == 1) {
				_formi_init_field_xpos(fieldp);
				fieldp->row_xpos = 0;
			}
			break;

		default: /* should not need to do this, but.... */
			return E_UNKNOWN_COMMAND;
			  /* NOTREACHED */
			break;
		}
	}

	  /* call the field and form init functions if required. */
	if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
		if (form->field_init != NULL)
			form->field_init(form);

		  /*
		   * if we have a page movement then the form init
		   * needs to be called too
		   */ 
		if ((c <= REQ_LAST_PAGE) && (form->form_init != NULL))
			form->form_init(form);

		  /*
		   * if there was an error just return now...
		   */
		if (status != E_OK)
			return status;

		  /* if we have no error, reset the various offsets */
		fieldp = form->fields[form->cur_field];
		fieldp->start_char = 0;
		fieldp->start_line = fieldp->alines;
		fieldp->cur_line = fieldp->alines;
		fieldp->row_xpos = 0;
		fieldp->cursor_ypos = 0;
		_formi_init_field_xpos(fieldp);
	}
	
	if (update_field < 0)
		return update_field;

	if (update_field == 1)
		update_page |= _formi_update_field(form, old_field);

	if (update_page == 1)
		_formi_draw_page(form);

	pos_form_cursor(form);

	if ((update_page == 1) || (update_field == 1))
		wrefresh(form->scrwin);
	
	return E_OK;
}
コード例 #10
0
ファイル: filter.c プロジェクト: ewf75/vuurmuur
int
filter_input_box(const int debuglvl, struct vrmr_filter *filter)
{
    WINDOW  *ib_win = NULL;
    PANEL   *my_panels[1];
    FIELD   *cur = NULL,
            *prev = NULL;
    FORM    *my_form = NULL;
    int     height = 0,
            width = 0,
            startx = 0,
            starty = 0,
            max_height = 0,
            max_width = 0,
            ch = 0,
            rows = 0,
            cols = 0,
            quit = 0;
    size_t  i = 0;
    char    not_defined = FALSE;

    /* init fields */
    memset(&FiFi, 0, sizeof(struct FilterFields_));

    /* set the window size */
    getmaxyx(stdscr, max_height, max_width);
    height = 9;
    width = 48;

    /* print on the center of the screen */
    starty = (max_height - height) / 2;
    startx = (max_width - width) / 2;

    /* create window */
    ib_win = create_newwin(height, width, starty, startx, gettext("Filter"), vccnf.color_win);
    if(ib_win == NULL)
    {
        vrmr_error(-1, VR_ERR, gettext("creating window failed."));
        return(-1);
    }

    my_panels[0] = new_panel(ib_win);
    if(my_panels[0] == NULL)
    {
        vrmr_error(-1, VR_ERR, gettext("creating panel failed."));
        return(-1);
    }

    FiFi.n_fields = 2;

    FiFi.fields = (FIELD **)calloc(FiFi.n_fields + 1, sizeof(FIELD *));
    if(FiFi.fields == NULL)
    {
        vrmr_error(-1, VR_ERR, gettext("calloc failed: %s (in: %s:%d)."),
                                strerror(errno), __FUNC__, __LINE__);
        return(-1);
    }

    FiFi.string_fld = (FiFi.fields[0] = new_field(1, 31, 3,  4, 0, 0));
    FiFi.check_fld = (FiFi.fields[1]  = new_field(1,  1, 5,  5, 0, 0));

    set_field_back(FiFi.string_fld, vccnf.color_win_rev);
    field_opts_off(FiFi.string_fld, O_AUTOSKIP);
    set_field_status(FiFi.string_fld, FALSE);
    set_field_buffer_wrap(debuglvl, FiFi.string_fld, 0, filter->str);


    set_field_back(FiFi.check_fld, vccnf.color_win);
    field_opts_off(FiFi.check_fld, O_AUTOSKIP);
    set_field_status(FiFi.check_fld, FALSE);
    set_field_buffer_wrap(debuglvl, FiFi.check_fld, 0, filter->neg ? "X" : " ");

    my_form = new_form(FiFi.fields);
    scale_form(my_form, &rows, &cols);
    keypad(ib_win, TRUE);
    set_form_win(my_form, ib_win);
    set_form_sub(my_form, derwin(ib_win, rows, cols, 1, 2));
    post_form(my_form);

    /* XXX: we really should have a wrapper function to just print
     * in the middle of a window to prevent hacks like this. */
    char *s = gettext("Enter filter (leave empty for no filter)");
    mvwprintw(ib_win, 2, (width - StrLen(s))/2, s);
    mvwprintw(ib_win, 6, 6, "[");
    mvwprintw(ib_win, 6, 8, "]");
    mvwprintw(ib_win, 6, 11, gettext("show lines that don't match"));

    update_panels();
    doupdate();

    if(!(cur = current_field(my_form)))
    {
        vrmr_error(-1, VR_INTERR, "NULL pointer (in: %s:%d).",
                                __FUNC__, __LINE__);
        return(-1);
    }

    while(quit == 0)
    {
        /* draw nice markers */
        draw_field_active_mark(cur, prev, ib_win, my_form, vccnf.color_win_mark|A_BOLD);

        not_defined = 0;

        /* get user input */
        ch = wgetch(ib_win);

        if(cur == FiFi.check_fld)
        {
            if(nav_field_toggleX(debuglvl, my_form, ch) < 0)
                not_defined = 1;
        }
        else if(cur == FiFi.string_fld)
        {
            if(nav_field_simpletext(debuglvl, my_form, ch) < 0)
                not_defined = 1;
        }
        else
        {
            not_defined = 1;
        }

        /* the rest is handled here */
        if(not_defined)
        {
            switch(ch)
            {
                case KEY_UP:

                    form_driver(my_form, REQ_PREV_FIELD);
                    form_driver(my_form, REQ_END_LINE);
                    break;

                case KEY_DOWN:
                case 9: // tab

                    form_driver(my_form, REQ_NEXT_FIELD);
                    form_driver(my_form, REQ_END_LINE);
                    break;

                case 10: // enter

                    if(cur == FiFi.check_fld)
                    {
                        quit = 1;
                    }
                    else
                    {
                        form_driver(my_form, REQ_NEXT_FIELD);
                        form_driver(my_form, REQ_END_LINE);
                    }
                    break;

                case 27:
                case KEY_F(10):
                case 'q':
                case 'Q':

                    quit = 1;
                    break;
            }
        }

        /* before we get the new 'cur', store cur in prev */
        prev = cur;
        if(!(cur = current_field(my_form)))
        {
            vrmr_error(-1, VR_INTERR, "NULL pointer (in: %s).", __FUNC__);
            return(-1);
        }

        /* draw and set cursor */
        wrefresh(ib_win);
        pos_form_cursor(my_form);
    }

    /* save here */
    if(filter_save(debuglvl, filter) < 0)
    {
        vrmr_error(-1, VR_ERR, gettext("setting filter failed."));
    }

    unpost_form(my_form);
    free_form(my_form);

    for(i=0; i < FiFi.n_fields; i++)
    {
        free_field(FiFi.fields[i]);
    }
    free(FiFi.fields);

    del_panel(my_panels[0]);
    destroy_win(ib_win);

    update_panels();
    doupdate();

    return(0);
}