Beispiel #1
0
int t_wgetch(WINDOW *win, t_char *ch)
{
	wint_t c;
	int status = wget_wch(win, &c);
	*ch = (t_char) c;
	return status;
}
Beispiel #2
0
void draw_active_window(Tox *m)
{
    ToxWindow *a = active_window;
    wint_t ch = 0;

    touchwin(a->window);
#ifndef WIN32
    wresize(a->window, LINES - 2, COLS);
#endif

    a->blink = false;
    draw_bar();
    a->onDraw(a, m);

    /* Handle input */
#ifdef HAVE_WIDECHAR
    wget_wch(stdscr, &ch);
#else
    ch = getch();
#endif

    if (ch == '\t' || ch == KEY_BTAB)
        set_next_window((int) ch);
    else if (ch != ERR)
        a->onKey(a, m, ch);
}
Beispiel #3
0
/*
 * Handle character input from the terminal.  Returns non-zero
 * if CTRL-D was pressed, meaning the application should exit.
 */
static int
handle_key_input(int portfd, WINDOW* win)
{
  static const unsigned char kctab[] = { 0x1B, 0x30 }; // ESC 0
  wint_t        wc = L'\0';
  unsigned char kc;

  switch (wget_wch(win, &wc))
  {
    case OK:
      if (wc == L'\4') // C-d: quit
        return 1;
      if (wc == L'\t')
        send_bytes(portfd, kctab, sizeof kctab, win);
      else if ((kc = kc_from_wide_char(wc)))
        send_bytes(portfd, &kc, 1, win);
      else
        flash();
      break;

    case KEY_CODE_YES:
      if (wc >= KEY_MIN && wc < KEY_MIN + N_ELEMENTS(keypad2kc)
          && keypad2kc[wc - KEY_MIN])
        send_bytes(portfd, &keypad2kc[wc - KEY_MIN], 1, win);
      break;

    default:
      break;
  }

  return 0;
}
Beispiel #4
0
void draw_active_window(Tox *m)
{
    ToxWindow *a = active_window;
    a->alert0 = false;
    a->alert1 = false;
    a->alert2 = false;

    wint_t ch = 0;

    draw_bar();

    touchwin(a->window);
#ifndef WIN32
    wresize(a->window, LINES - 2, COLS);
#endif

    a->onDraw(a, m);
    wrefresh(a->window);

    /* Handle input */
#ifdef HAVE_WIDECHAR
    wget_wch(stdscr, &ch);
#else
    ch = getch();
#endif

    if (ch == T_KEY_NEXT || ch == T_KEY_PREV)
        set_next_window((int) ch);
    else if (ch != ERR)
        a->onKey(a, m, ch);
}
Beispiel #5
0
void draw_active_window(Tox *m)
{
    ToxWindow *a = active_window;
    a->alert0 = false;
    a->alert1 = false;
    a->alert2 = false;

    wint_t ch = 0;

    draw_bar();

    touchwin(a->window);
#ifndef WIN32
    wresize(a->window, LINES - 2, COLS);
#endif

    a->onDraw(a, m);
    wrefresh(a->window);

    /* Handle input */
#ifdef HAVE_WIDECHAR
    if (wget_wch(stdscr, &ch) == ERR)
#else
    if ((ch = getch()) == ERR)
#endif
        return;

    if (ch == T_KEY_NEXT || ch == T_KEY_PREV) {
        set_next_window((int) ch);
    } else {
        pthread_mutex_lock(&Winthread.lock);
        a->onKey(a, m, ch);
        pthread_mutex_unlock(&Winthread.lock);
    }
}
Beispiel #6
0
int mvget_wch(int y, int x, wint_t *wch)
{
    PDC_LOG(("mvget_wch() - called\n"));

    if (move(y, x) == ERR)
        return ERR;

    return wget_wch(stdscr, wch);
}
Beispiel #7
0
int mvwget_wch(WINDOW *win, int y, int x, wint_t *wch)
{
    PDC_LOG(("mvwget_wch() - called\n"));

    if (wmove(win, y, x) == ERR)
        return ERR;

    return wget_wch(win, wch);
}
Beispiel #8
0
static int
really_getch(WINDOW *win, int *fkey)
{
    int ch;
#ifdef USE_WIDE_CURSES
    int code;
    mbstate_t state;
    wchar_t my_wchar;
    wint_t my_wint;

    /*
     * We get a wide character, translate it to multibyte form to avoid
     * having to change the rest of the code to use wide-characters.
     */
    if (used_last_getc >= have_last_getc) {
	used_last_getc = 0;
	have_last_getc = 0;
	ch = ERR;
	*fkey = 0;
	code = wget_wch(win, &my_wint);
	my_wchar = (wchar_t) my_wint;
	switch (code) {
	case KEY_CODE_YES:
	    ch = *fkey = my_wchar;
	    last_getc = my_wchar;
	    break;
	case OK:
	    memset(&state, 0, sizeof(state));
	    have_last_getc = (int) wcrtomb(last_getc_bytes, my_wchar, &state);
	    if (have_last_getc < 0) {
		have_last_getc = used_last_getc = 0;
		last_getc_bytes[0] = (char) my_wchar;
	    }
	    ch = (int) CharOf(last_getc_bytes[used_last_getc++]);
	    last_getc = my_wchar;
	    break;
	case ERR:
	    ch = ERR;
	    last_getc = ERR;
	    break;
	default:
	    break;
	}
    } else {
	ch = (int) CharOf(last_getc_bytes[used_last_getc++]);
    }
#else
    ch = wgetch(win);
    last_getc = ch;
    *fkey = (ch > KEY_MIN && ch < KEY_MAX);
#endif
    return ch;
}
Beispiel #9
0
static int
read_char(WINDOW *win, wint_t *c, int timeout)
{
	static const int T = 150;
	static const int IPC_F = 10;

	int i;
	int result = ERR;

	for(i = 0; i <= timeout/T; i++)
	{
		int j;

		if(is_redraw_scheduled())
		{
			modes_redraw();
		}

		if(!is_status_bar_multiline() && !is_in_menu_like_mode() &&
				get_mode() != CMDLINE_MODE)
		{
			check_if_filelists_have_changed(curr_view);
			if(curr_stats.number_of_windows != 1 && !curr_stats.view)
				check_if_filelists_have_changed(other_view);
		}

		check_background_jobs();

		for(j = 0; j < IPC_F; j++)
		{
			ipc_check();
			wtimeout(win, MIN(T, timeout)/IPC_F);

			if((result = wget_wch(win, c)) != ERR)
				break;

			if(is_redraw_scheduled())
			{
				modes_redraw();
			}
		}
		if(result != ERR)
			break;

		timeout -= T;
	}
	return result;
}
Beispiel #10
0
static int
read_char(WINDOW *win, wint_t *c, int timeout)
{
	static const int T = 150;
	static const int IPC_F = 10;

	int i;
	int result = ERR;

	for(i = 0; i <= timeout/T; i++)
	{
		int j;

		process_scheduled_updates();

		if(should_check_views_for_changes())
		{
			check_view_for_changes(curr_view);
			check_view_for_changes(other_view);
		}

		check_background_jobs();

		for(j = 0; j < IPC_F; j++)
		{
			ipc_check();
			wtimeout(win, MIN(T, timeout)/IPC_F);

			if((result = wget_wch(win, c)) != ERR)
			{
				break;
			}

			process_scheduled_updates();
		}
		if(result != ERR)
		{
			break;
		}

		timeout -= T;
	}
	return result;
}
Beispiel #11
0
void draw_active_window(Tox *m)
{
    ToxWindow *a = active_window;
    a->alert = WINDOW_ALERT_NONE;

    wint_t ch = 0;

    draw_bar();

    touchwin(a->window);
    a->onDraw(a, m);

    /* Handle input */
    bool ltr;
#ifdef HAVE_WIDECHAR
    int status = wget_wch(stdscr, &ch);

    if (status == ERR)
        return;

    if (status == OK)
        ltr = iswprint(ch);
    else /* if (status == KEY_CODE_YES) */
        ltr = false;

#else
    ch = getch();

    if (ch == ERR)
        return;

    /* TODO verify if this works */
    ltr = isprint(ch);
#endif /* HAVE_WIDECHAR */

    if (!ltr && (ch == user_settings_->key_next_tab || ch == user_settings_->key_prev_tab)) {
        set_next_window((int) ch);
    } else {
        pthread_mutex_lock(&Winthread.lock);
        a->onKey(a, m, ch, ltr);
        pthread_mutex_unlock(&Winthread.lock);
    }
}
Beispiel #12
0
static wchar_t *nc_getwch(void)
/* gets a key as a wchar_t */
{
    static wchar_t c[2];

#ifdef CONFOPT_WGET_WCH

    /* set timer period */
    if (timer_msecs > 0)
        timeout(timer_msecs);

    if (wget_wch(stdscr, (wint_t *) c) == -1)
        c[0] = (wchar_t) - 1;

#else
    char tmp[MB_CUR_MAX + 1];
    int cc, n = 0;

    /* read one byte */
    cc = wgetch(cw);
    if (has_key(cc)) {
        c[0] = cc;
        return c;
    }

    /* set to non-blocking */
    nodelay(cw, 1);

    /* read all possible following characters */
    tmp[n++] = cc;
    while (n < sizeof(tmp) - 1 && (cc = getch()) != ERR)
        tmp[n++] = cc;

    /* sets input as blocking */
    nodelay(cw, 0);

    tmp[n] = '\0';
    mbstowcs(c, tmp, n);
#endif

    c[1] = '\0';
    return c;
}
Beispiel #13
0
static void
test_inserts(int level)
{
    static bool first = TRUE;

    wint_t ch;
    int code;
    int limit;
    int row = 1;
    int col;
    int row2, col2;
    int length;
    wchar_t buffer[BUFSIZ];
    WINDOW *look = 0;
    WINDOW *work = 0;
    WINDOW *show = 0;
    int margin = (2 * TABSIZE) - 1;
    Options option = ((m_opt ? oMove : oDefault)
		      | ((w_opt || (level > 0)) ? oWindow : oDefault));

    if (first) {
	static char cmd[80];
	setlocale(LC_ALL, "");

	putenv(strcpy(cmd, "TABSIZE=8"));

	initscr();
	(void) cbreak();	/* take input chars one at a time, no wait for \n */
	(void) noecho();	/* don't echo input */
	keypad(stdscr, TRUE);
    }

    limit = LINES - 5;
    if (level > 0) {
	look = newwin(limit, COLS - (2 * (level - 1)), 0, level - 1);
	work = newwin(limit - 2, COLS - (2 * level), 1, level);
	show = newwin(4, COLS, limit + 1, 0);
	box(look, 0, 0);
	wnoutrefresh(look);
	limit -= 2;
    } else {
	work = stdscr;
	show = derwin(stdscr, 4, COLS, limit + 1, 0);
    }
    keypad(work, TRUE);

    for (col = margin + 1; col < COLS; col += TABSIZE)
	mvwvline(work, row, col, '.', limit - 2);

    mvwvline(work, row, margin, ACS_VLINE, limit - 2);
    mvwvline(work, row, margin + 1, ACS_VLINE, limit - 2);
    limit /= 2;

    mvwaddstr(work, 1, 2, "String");
    mvwaddstr(work, limit + 1, 2, "Chars");
    wnoutrefresh(work);

    buffer[length = 0] = '\0';
    legend(show, level, option, buffer, length);
    wnoutrefresh(show);

    doupdate();

    /*
     * Show the characters inserted in color, to distinguish from those that
     * are shifted.
     */
    if (has_colors()) {
	start_color();
	init_pair(1, COLOR_WHITE, COLOR_BLUE);
	wbkgdset(work, COLOR_PAIR(1) | ' ');
    }

    while ((code = wget_wch(work, &ch)) != ERR) {

	if (code == KEY_CODE_YES) {
	    switch (ch) {
	    case KEY_DOWN:
		ch = CTRL('N');
		break;
	    case KEY_BACKSPACE:
		ch = '\b';
		break;
	    default:
		beep();
		continue;
	    }
	} else if (code == ERR) {
	    beep();
	    break;
	}
	if (ch == 'q')
	    break;

	wmove(work, row, margin + 1);
	switch (ch) {
	case 'w':
	    test_inserts(level + 1);

	    touchwin(look);
	    touchwin(work);
	    touchwin(show);

	    wnoutrefresh(look);
	    wnoutrefresh(work);
	    wnoutrefresh(show);

	    doupdate();
	    break;
	case CTRL('N'):
	    if (row < limit) {
		++row;
		/* put the whole string in, all at once */
		col2 = margin + 1;
		switch (option) {
		case oDefault:
		    if (n_opt > 1) {
			for (col = 0; col < length; col += n_opt) {
			    col2 = ColOf(buffer, col, margin);
			    if (move(row, col2) != ERR) {
				InsNStr(buffer + col, LEN(col));
			    }
			}
		    } else {
			if (move(row, col2) != ERR) {
			    InsStr(buffer);
			}
		    }
		    break;
		case oMove:
		    if (n_opt > 1) {
			for (col = 0; col < length; col += n_opt) {
			    col2 = ColOf(buffer, col, margin);
			    MvInsNStr(row, col2, buffer + col, LEN(col));
			}
		    } else {
			MvInsStr(row, col2, buffer);
		    }
		    break;
		case oWindow:
		    if (n_opt > 1) {
			for (col = 0; col < length; col += n_opt) {
			    col2 = ColOf(buffer, col, margin);
			    if (wmove(work, row, col2) != ERR) {
				WInsNStr(work, buffer + col, LEN(col));
			    }
			}
		    } else {
			if (wmove(work, row, col2) != ERR) {
			    WInsStr(work, buffer);
			}
		    }
		    break;
		case oMoveWindow:
		    if (n_opt > 1) {
			for (col = 0; col < length; col += n_opt) {
			    col2 = ColOf(buffer, col, margin);
			    MvWInsNStr(work, row, col2, buffer + col, LEN(col));
			}
		    } else {
			MvWInsStr(work, row, col2, buffer);
		    }
		    break;
		}

		/* do the corresponding single-character insertion */
		row2 = limit + row;
		for (col = 0; col < length; ++col) {
		    col2 = ColOf(buffer, col, margin);
		    switch (option) {
		    case oDefault:
			if (move(row2, col2) != ERR) {
			    InsCh((chtype) buffer[col]);
			}
			break;
		    case oMove:
			MvInsCh(row2, col2, (chtype) buffer[col]);
			break;
		    case oWindow:
			if (wmove(work, row2, col2) != ERR) {
			    WInsCh(work, (chtype) buffer[col]);
			}
			break;
		    case oMoveWindow:
			MvWInsCh(work, row2, col2, (chtype) buffer[col]);
			break;
		    }
		}
	    } else {
		beep();
	    }
	    break;
	case KEY_BACKSPACE:
	    ch = '\b';
	    /* FALLTHRU */
	default:
	    buffer[length++] = ch;
	    buffer[length] = '\0';

	    /* put the string in, one character at a time */
	    col = ColOf(buffer, length - 1, margin);
	    switch (option) {
	    case oDefault:
		if (move(row, col) != ERR) {
		    InsStr(buffer + length - 1);
		}
		break;
	    case oMove:
		MvInsStr(row, col, buffer + length - 1);
		break;
	    case oWindow:
		if (wmove(work, row, col) != ERR) {
		    WInsStr(work, buffer + length - 1);
		}
		break;
	    case oMoveWindow:
		MvWInsStr(work, row, col, buffer + length - 1);
		break;
	    }

	    /* do the corresponding single-character insertion */
	    switch (option) {
	    case oDefault:
		if (move(limit + row, col) != ERR) {
		    InsCh(ch);
		}
		break;
	    case oMove:
		MvInsCh(limit + row, col, ch);
		break;
	    case oWindow:
		if (wmove(work, limit + row, col) != ERR) {
		    WInsCh(work, ch);
		}
		break;
	    case oMoveWindow:
		MvWInsCh(work, limit + row, col, ch);
		break;
	    }

	    wnoutrefresh(work);

	    legend(show, level, option, buffer, length);
	    wnoutrefresh(show);

	    doupdate();
	    break;
	}
    }
    if (level > 0) {
	delwin(show);
	delwin(work);
	delwin(look);
    }
}
Beispiel #14
0
NCURSES_EXPORT(int) (mvwget_wch) (WINDOW * a1, int a2, int a3, wint_t * z)
{
	T((T_CALLED("mvwget_wch(%p,%d,%d,%p)"), (const void *)a1, a2, a3, (const void *)z)); returnCode((wmove(a1,a2,a3) == (-1) ? (-1) : wget_wch(a1,z)));
}
Beispiel #15
0
Datei: base.c Projekt: chazu/stfl
void stfl_form_run(struct stfl_form *f, int timeout)
{
	wchar_t *on_handler = 0;

	pthread_mutex_lock(&f->mtx);

	if (f->event)
		free(f->event);
	f->event = 0;

	if (timeout >= 0 && f->event_queue)
		goto unshift_next_event;

	if (timeout == -2)
		goto unshift_next_event;

	if (!f->root) {
		fprintf(stderr, "STFL Fatal Error: Called stfl_form_run() without root widget.\n");
		abort();
	}

	if (!curses_active)
	{
		initscr();
		cbreak();
		noecho();
		nonl();
		keypad(stdscr, TRUE);
		doupdate();
		start_color();
		use_default_colors();
		wbkgdset(stdscr, ' ');
		curses_active = 1;
	}

	stfl_colorpair_counter = 1;
	f->root->type->f_prepare(f->root, f);

	struct stfl_widget *fw = stfl_gather_focus_widget(f);
	f->current_focus_id = fw ? fw->id : 0;

	getbegyx(stdscr, f->root->y, f->root->x);
	getmaxyx(stdscr, f->root->h, f->root->w);

	if (timeout == -3) {
		WINDOW *dummywin = newwin(0, 0, 0, 0);
		if (dummywin == NULL) {
			fprintf(stderr, "STFL Fatal Error: stfl_form_run() got a NULL pointer from newwin(0, 0, 0, 0).\n");
			abort();
		}
		f->root->type->f_draw(f->root, f, dummywin);
		delwin(dummywin);
		pthread_mutex_unlock(&f->mtx);
		return;
	}

	werase(stdscr);
	f->root->type->f_draw(f->root, f, stdscr);
	if (timeout == -1 && f->root->cur_y != -1 && f->root->cur_x != -1) {
		wmove(stdscr, f->root->cur_y, f->root->cur_x);
	}
	refresh();

	if (timeout < 0) {
		pthread_mutex_unlock(&f->mtx);
		return;
	}

	wtimeout(stdscr, timeout == 0 ? -1 : timeout);
	wmove(stdscr, f->cursor_y, f->cursor_x);

	wint_t wch;
	pthread_mutex_unlock(&f->mtx);
	int rc = wget_wch(stdscr, &wch);
	pthread_mutex_lock(&f->mtx);

	/* fw may be invalid, regather it */
	fw = stfl_gather_focus_widget(f);
	f->current_focus_id = fw ? fw->id : 0;

	struct stfl_widget *w = fw;

	if (rc == ERR) {
		stfl_form_event(f, compat_wcsdup(L"TIMEOUT"));
		goto unshift_next_event;
	}

	wchar_t *on_event = stfl_keyname(wch, rc == KEY_CODE_YES);
	int on_handler_len = wcslen(on_event) + 4;
	on_handler = malloc(on_handler_len * sizeof(wchar_t));
	swprintf(on_handler, on_handler_len, L"on_%ls", on_event);
	free(on_event);

	while (w) {
		const wchar_t *event = stfl_widget_getkv_str(w, on_handler, 0);
		if (event) {
			stfl_form_event(f, compat_wcsdup(event));
			goto unshift_next_event;
		}

		if (w->type->f_process && stfl_widget_getkv_int(w, L"process", 1) && w->type->f_process(w, fw, f, wch, rc == KEY_CODE_YES))
			goto unshift_next_event;

		if (stfl_widget_getkv_int(w, L"modal", 0))
			goto generate_event;

		w = w->parent;
	}

	if (rc != KEY_CODE_YES && wch == L'\t')
	{
		struct stfl_widget *old_fw = fw = stfl_widget_by_id(f->root, f->current_focus_id);

		if (!fw)
			goto generate_event;

		do {
			if (fw->first_child)
				fw = fw->first_child;
			else
			if (fw->next_sibling)
				fw = fw->next_sibling;
			else
			{
				while (fw->parent && !fw->parent->next_sibling)
					fw = fw->parent;
				fw = fw->parent ? fw->parent->next_sibling : 0;
			}

			if (!fw && old_fw)
				fw = f->root;
		} while (fw && !(fw->allow_focus && stfl_widget_getkv_int(fw, L"can_focus", 1)));

		if (old_fw != fw)
		{
			if (old_fw && old_fw->type->f_leave)
				old_fw->type->f_leave(old_fw, f);

			if (fw && fw->type->f_enter)
				fw->type->f_enter(fw, f);

			f->current_focus_id = fw ? fw->id : 0;
		}

		goto unshift_next_event;
	}
	else if (rc == KEY_CODE_YES && wch == KEY_BTAB)
	{
		struct stfl_widget *old_fw = stfl_widget_by_id(f->root, f->current_focus_id);
		struct stfl_widget *tmp_fw = f->root;
		struct stfl_widget *fw = 0;

focus_wrap_around:
		while (tmp_fw && tmp_fw != old_fw)
		{
			if (tmp_fw->allow_focus && stfl_widget_getkv_int(tmp_fw, L"can_focus", 1))
				fw = tmp_fw;

			if (tmp_fw->first_child)
				tmp_fw = tmp_fw->first_child;
			else
			if (tmp_fw->next_sibling)
				tmp_fw = tmp_fw->next_sibling;
			else
			{
				while (tmp_fw->parent && !tmp_fw->parent->next_sibling)
					tmp_fw = tmp_fw->parent;
				tmp_fw = tmp_fw->parent ? tmp_fw->parent->next_sibling : 0;
			}
		}

		if (!fw && old_fw)
		{
			old_fw = f->root->last_child;
			goto focus_wrap_around;
		}

		if (fw && old_fw != fw)
		{
			if (old_fw && old_fw->type->f_leave)
				old_fw->type->f_leave(old_fw, f);

			if (fw && fw->type->f_enter)
				fw->type->f_enter(fw, f);

			f->current_focus_id = fw ? fw->id : 0;
		}

		goto unshift_next_event;
	}

generate_event:
	stfl_form_event(f, stfl_keyname(wch, rc == KEY_CODE_YES));

unshift_next_event:;
	struct stfl_event *e = f->event_queue;
	if (e) {
		f->event_queue = e->next;
		f->event = e->event;
		free(e);
	}

	pthread_mutex_unlock(&f->mtx);
	free(on_handler);
}
Beispiel #16
0
NCURSES_EXPORT(int) (get_wch) (wint_t * z)
{
	T((T_CALLED("get_wch(%p)"), (const void *)z)); returnCode(wget_wch(stdscr,z));
}
Beispiel #17
0
wgetn_wstr(WINDOW *win, wint_t *str, int maxlen)
{
    SCREEN *sp = _nc_screen_of(win);
    TTY buf;
    bool oldnl, oldecho, oldraw, oldcbreak;
    wint_t erasec;
    wint_t killc;
    wint_t *oldstr = str;
    wint_t *tmpstr = str;
    wint_t ch;
    int y, x, code;

    T((T_CALLED("wgetn_wstr(%p,%p, %d)"), win, str, maxlen));

    if (!win)
	returnCode(ERR);

    _nc_get_tty_mode(&buf);

    oldnl = sp->_nl;
    oldecho = sp->_echo;
    oldraw = sp->_raw;
    oldcbreak = sp->_cbreak;
    nl();
    noecho();
    noraw();
    cbreak();

    erasec = (wint_t) erasechar();
    killc = (wint_t) killchar();

    getyx(win, y, x);

    if (is_wintouched(win) || (win->_flags & _HASMOVED))
	wrefresh(win);

    while ((code = wget_wch(win, &ch)) != ERR) {
	/*
	 * Map special characters into key-codes.
	 */
	if (ch == '\r')
	    ch = '\n';
	if (ch == '\n') {
	    code = KEY_CODE_YES;
	    ch = KEY_ENTER;
	}
	if (ch < KEY_MIN) {
	    if (ch == erasec) {
		ch = KEY_BACKSPACE;
		code = KEY_CODE_YES;
	    }
	    if (ch == killc) {
		ch = KEY_EOL;
		code = KEY_CODE_YES;
	    }
	}
	if (code == KEY_CODE_YES) {
	    /*
	     * Some terminals (the Wyse-50 is the most common) generate a \n
	     * from the down-arrow key.  With this logic, it's the user's
	     * choice whether to set kcud=\n for wget_wch(); terminating
	     * *getn_wstr() with \n should work either way.
	     */
	    if (ch == KEY_DOWN || ch == KEY_ENTER) {
		if (oldecho == TRUE
		    && win->_cury == win->_maxy
		    && win->_scroll)
		    wechochar(win, (chtype) '\n');
		break;
	    }
	    if (ch == KEY_LEFT || ch == KEY_BACKSPACE) {
		if (tmpstr > oldstr) {
		    tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho);
		}
	    } else if (ch == KEY_EOL) {
		while (tmpstr > oldstr) {
		    tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho);
		}
	    } else {
		beep();
	    }
	} else if (maxlen >= 0 && tmpstr - oldstr >= maxlen) {
	    beep();
	} else {
	    *tmpstr++ = ch;
	    *tmpstr = 0;
	    if (oldecho == TRUE) {
		int oldy = win->_cury;

		if (wadd_wint(win, tmpstr - 1) == ERR) {
		    /*
		     * We can't really use the lower-right corner for input,
		     * since it'll mess up bookkeeping for erases.
		     */
		    win->_flags &= ~_WRAPPED;
		    waddch(win, (chtype) ' ');
		    tmpstr = WipeOut(win, y, x, oldstr, tmpstr, oldecho);
		    continue;
		} else if (win->_flags & _WRAPPED) {
		    /*
		     * If the last waddch forced a wrap & scroll, adjust our
		     * reference point for erasures.
		     */
		    if (win->_scroll
			&& oldy == win->_maxy
			&& win->_cury == win->_maxy) {
			if (--y <= 0) {
			    y = 0;
			}
		    }
		    win->_flags &= ~_WRAPPED;
		}
		wrefresh(win);
	    }
	}
    }

    win->_curx = 0;
    win->_flags &= ~_WRAPPED;
    if (win->_cury < win->_maxy)
	win->_cury++;
    wrefresh(win);

    /* Restore with a single I/O call, to fix minor asymmetry between
     * raw/noraw, etc.
     */
    sp->_nl = oldnl;
    sp->_echo = oldecho;
    sp->_raw = oldraw;
    sp->_cbreak = oldcbreak;

    (void) _nc_set_tty_mode(&buf);

    *tmpstr = 0;
    if (code == ERR) {
	if (tmpstr == oldstr) {
	    *tmpstr++ = WEOF;
	    *tmpstr = 0;
	}
	returnCode(ERR);
    }

    T(("wgetn_wstr returns %s", _nc_viswibuf(oldstr)));

    returnCode(OK);
}
Beispiel #18
0
/*
 * ekg_getch()
 *
 * czeka na wci¶niêcie klawisza i je¶li wkompilowano obs³ugê pythona,
 * przekazuje informacjê o zdarzeniu do skryptu.
 *
 *  - meta - przedrostek klawisza.
 *
 * @returns:
 *	-2		- ignore that key
 *	ERR		- error
 *	OK		- report a (wide) character
 *	KEY_CODE_YES	- report the pressing of a function key
 *
 */
static int ekg_getch(int meta, unsigned int *ch) {
	int retcode;
#if USE_UNICODE
	retcode = wget_wch(input, ch);
#else
	*ch = wgetch(input);
	retcode = *ch >= KEY_MIN ? KEY_CODE_YES : OK;
#endif

	if (retcode == ERR) return ERR;
	if ((retcode == KEY_CODE_YES) && (*(int *)ch == -1)) return ERR;		/* Esc (delay) no key */

#ifndef HAVE_USABLE_TERMINFO
	/* Debian screen incomplete terminfo workaround */

	if (mouse_initialized == 2 && *ch == 27) { /* escape */
		int tmp;

		if ((tmp = wgetch(input)) != '[')
			ungetch(tmp);
		else if ((tmp = wgetch(input)) != 'M') {
			ungetch(tmp);
			ungetch('[');
		} else
			*ch = KEY_MOUSE;
	}
#endif

	/*
	 * conception is borrowed from Midnight Commander project
	 *    (www.ibiblio.org/mc/)
	 */
#define GET_TIME(tv)	(g_get_current_time(&tv))
#define DIF_TIME(t1,t2) ((t2.tv_sec -t1.tv_sec) *1000+ \
			 (t2.tv_usec-t1.tv_usec)/1000)
	if (*ch == KEY_MOUSE) {
		int btn, mouse_state = 0, x, y;
		static GTimeVal tv1 = { 0, 0 };
		static GTimeVal tv2;
		static int clicks;
		static int last_btn = 0;

		btn = wgetch (input) - 32;

		if (btn == 3 && last_btn) {
			last_btn -= 32;

			switch (last_btn) {
				case 0: mouse_state = (clicks) ? EKG_BUTTON1_DOUBLE_CLICKED : EKG_BUTTON1_CLICKED;	break;
				case 1: mouse_state = (clicks) ? EKG_BUTTON2_DOUBLE_CLICKED : EKG_BUTTON2_CLICKED;	break;
				case 2: mouse_state = (clicks) ? EKG_BUTTON3_DOUBLE_CLICKED : EKG_BUTTON3_CLICKED;	break;
				case 64: mouse_state = EKG_SCROLLED_UP;							break;
				case 65: mouse_state = EKG_SCROLLED_DOWN;						break;
				default:										break;
			}

			last_btn = 0;
			GET_TIME (tv1);
			clicks = 0;

		} else if (!last_btn) {
			GET_TIME (tv2);
			if (tv1.tv_sec && (DIF_TIME (tv1,tv2) < 250)){
				clicks++;
				clicks %= 3;
			} else
				clicks = 0;

			switch (btn) {
				case 0:
				case 1:
				case 2:
				case 64:
				case 65:
					btn += 32;
					break;
				default:
					btn = 0;
					break;
			}

			last_btn = btn;
		} else {
			switch (btn) {
				case 64:
					mouse_state = EKG_SCROLLED_UP;
					break;
				case 65:
					mouse_state = EKG_SCROLLED_DOWN;
					break;
			}
		}

		/* 33 based */
		x = wgetch(input) - 32;
		y = wgetch(input) - 32;

		/* XXX query_emit UI_MOUSE ??? */
		if (mouse_state)
			ncurses_mouse_clicked_handler(x, y, mouse_state);

	}
#undef GET_TIME
#undef DIF_TIME
	if (query_emit(NULL, "ui-keypress", ch) == -1)
		return -2; /* -2 - ignore that key */

	return retcode;
}
Beispiel #19
0
/**
 * Read user input.
 *
 * @param prompt Prompt
 * @return The read line (dynamically allocated) or NULL
 */
char *
readline(const char *prompt)
{
    char *out;
    const int sleep_time_milliseconds = 90;
    volatile struct readline_session_context *ctx;
    wchar_t *buf_p = &g_push_back_buf[0];

    ctx = new_session(prompt);
    if (setjmp(g_readline_loc_info) != 0) {
	session_destroy(ctx);
	mutex_unlock(&g_puts_mutex);
	return NULL;
    }

    g_readline_loop    = true;
    g_resize_requested = false;
    g_hist_next = false;
    g_hist_prev = false;

    mutex_lock(&g_puts_mutex);
    write_cmdprompt(ctx->act, ctx->prompt, ctx->prompt_size);
    mutex_unlock(&g_puts_mutex);

    do {
	wint_t wc;

	ctx->insert_mode = (ctx->bufpos != ctx->n_insert);
	ctx->no_bufspc	 = (ctx->n_insert + 1 >= readline_buffersize);

	if (*buf_p) {
	    wc = *buf_p++;
	} else if (wget_wch(ctx->act, &wc) == ERR) {
	    (void) napms(sleep_time_milliseconds);
	    continue;
	}

	mutex_lock(&g_puts_mutex);

	switch (wc) {
	case CTRL_A:
	    while (ctx->bufpos != 0) {
		case_key_left(ctx);
		ctx->insert_mode = (ctx->bufpos != ctx->n_insert);
	    }
	    break;
	case CTRL_E:
	    while (ctx->insert_mode) {
		case_key_right(ctx);
		ctx->insert_mode = (ctx->bufpos != ctx->n_insert);
	    }
	    break;
	case MY_KEY_DLE:
	    window_select_prev();
	    break; /* CTRL+P */
	case MY_KEY_SO:
	    window_select_next();
	    break; /* CTRL+N */
	case KEY_DOWN:
	    g_hist_next = true;
	    session_destroy(ctx);
	    mutex_unlock(&g_puts_mutex);
	    return NULL;
	case KEY_UP:
	    g_hist_prev = true;
	    session_destroy(ctx);
	    mutex_unlock(&g_puts_mutex);
	    return NULL;
	case KEY_LEFT: case MY_KEY_STX:
	    case_key_left(ctx);
	    break;
	case KEY_RIGHT: case MY_KEY_ACK:
	    case_key_right(ctx);
	    break;
	case KEY_BACKSPACE: case MY_KEY_BS:
	    case_key_backspace(ctx);
	    break;
	case KEY_F(5): case BLINK:
	    handle_key(ctx, btowc(BLINK));
	    break;
	case KEY_F(6): case BOLD_ALIAS:
	    handle_key(ctx, btowc(BOLD));
	    break;
	case KEY_F(7): case COLOR:
	    handle_key(ctx, btowc(COLOR));
	    break;
	case KEY_F(8): case NORMAL:
	    handle_key(ctx, btowc(NORMAL));
	    break;
	case KEY_F(9): case REVERSE:
	    handle_key(ctx, btowc(REVERSE));
	    break;
	case KEY_F(10): case UNDERLINE:
	    handle_key(ctx, btowc(UNDERLINE));
	    break;
	case KEY_F(11):
	    cmd_close("");
	    break;
	case KEY_F(12):
	    window_close_all_priv_conv();
	    break;
	case KEY_DC: case MY_KEY_EOT:
	    case_key_dc(ctx);
	    break;
	case KEY_NPAGE:
	    window_scroll_down(g_active_window);
	    break;
	case KEY_PPAGE:
	    window_scroll_up(g_active_window);
	    break;
	case '\t':
	    break;
	case '\n': case KEY_ENTER: case WINDOWS_KEY_ENTER:
	    g_readline_loop = false;
	    break;
	case KEY_RESIZE:
	case MY_KEY_RESIZE:
	    g_resize_requested = true;
	    /*FALLTHROUGH*/
	case '\a':
	    session_destroy(ctx);
	    mutex_unlock(&g_puts_mutex);
	    return NULL;
	default:
	    if (iswprint(wc)) {
		handle_key(ctx, wc);
	    }
	    break;
	}

	mutex_unlock(&g_puts_mutex);
    } while (g_readline_loop);

    if (ctx->n_insert > 0) {
	ctx->buffer[ctx->n_insert] = 0L;
    } else {
	session_destroy(ctx);
	return NULL;
    }

    mutex_lock(&g_puts_mutex);
    write_cmdprompt(ctx->act, "", 0);
    mutex_unlock(&g_puts_mutex);

    out = finalize_out_string(ctx->buffer);
    session_destroy(ctx);

    return out;
}
Beispiel #20
0
int Input::wait(Session &sess) {
    const int KEY_ESC = 27;
    const int KEY_BS = 127;
    const int KEY_TAB = 9;
    const int KEY_ENT = 10;
    wint_t c;
    MEVENT event;

#if NCURSES_MOUSE_VERSION > 1
    mousemask(BUTTON3_PRESSED | BUTTON4_PRESSED | BUTTON5_PRESSED, NULL);
#else
    mousemask(BUTTON3_PRESSED, NULL);
#endif
    
    int& col = sess.col;
    std::wstring& input_str = sess.input_str;
        
    // check if we reached maximum string length
    if (input_str.length() == 1000) {
        return 0;
    }

    wget_wch(win, &c);
    switch (c) {
    case KEY_ESC: // ESC to quit;
    case KEY_TAB: // tab to switch to roster selection mode
    case KEY_UP:   // go back in chat history
    case KEY_DOWN:  // go forward in chat history
    case KEY_MOUSE:
        if (getmouse(&event) == OK) {
            if (event.bstate & BUTTON3_PRESSED) {
                c = KEY_TAB;
            }
#if NCURSES_MOUSE_VERSION > 1
            /* scroll up and down events associated with mouse wheel */
            else if (event.bstate & BUTTON4_PRESSED) {
                c = KEY_UP;
            } else if (event.bstate & BUTTON5_PRESSED) {
                c = KEY_DOWN;
            }
#endif
        }

        return c;
            
    case KEY_BS:
        if (!input_str.empty() && col > 0) {
            col--;
            input_str.erase(col, 1);
            fixed_print_input(input_str, col);
        }
        break;
    case KEY_DC:
        if (!input_str.empty() && col < input_str.length()) {
            input_str.erase(col, 1);
            fixed_print_input(input_str, col);
        }
        break;
            
    case KEY_RIGHT:
        if (col < input_str.length()) {
            col++;
            highlight(col);
        }
        break;
    case KEY_LEFT:
        if (col > 0) {
            col--;
            highlight(col);
        }
        break;
    case KEY_ENT:
        col = 0;
        client->send_message(input_str);
        input_str.clear();
        fixed_print_input(input_str, 1);
        break;
    
    default:
        if (iswprint(c)) {
            input_str.insert(col, 1, c);
            col++;
            fixed_print_input(input_str, col);
        }
        break;
    }
    return 0;
}
Beispiel #21
0
/*
 * __wgetn_wstr --
 *	The actual implementation.
 *	Note that we include a trailing L'\0' for safety, so str will contain
 *	at most n - 1 other characters.
 */
int
__wgetn_wstr(WINDOW *win, wchar_t *wstr, int n)
{
	wchar_t *ostr, ec, kc, sc[ 2 ];
	int oldx, remain;
	wint_t wc;
	cchar_t cc;

	ostr = wstr;
	if ( erasewchar( &ec ) == ERR )
		return ERR;
	if ( killwchar( &kc ) == ERR )
		return ERR;
	sc[ 0 ] = ( wchar_t )btowc( ' ' );
	sc[ 1 ] = L'\0';
	setcchar( &cc, sc, win->wattr, 0, NULL );
	oldx = win->curx;
	remain = n - 1;

	while (wget_wch(win, &wc) != ERR
	       && wc != L'\n' && wc != L'\r') {
#ifdef DEBUG
		__CTRACE(__CTRACE_INPUT,
		    "__wgetn_wstr: win %p, char 0x%x, remain %d\n",
		    win, wc, remain);
#endif
		*wstr = wc;
		touchline(win, win->cury, 1);
		if (wc == ec || wc == KEY_BACKSPACE || wc == KEY_LEFT) {
			*wstr = L'\0';
			if (wstr != ostr) {
				if ((wchar_t)wc == ec) {
					mvwadd_wch(win, win->cury,
						win->curx, &cc);
					wmove(win, win->cury, win->curx - 1);
				}
				if (wc == KEY_BACKSPACE || wc == KEY_LEFT) {
					/* getch() displays the key sequence */
					mvwadd_wch(win, win->cury,
						win->curx - 1, &cc);
					mvwadd_wch(win, win->cury,
						win->curx - 2, &cc);
					wmove(win, win->cury, win->curx - 1);
				}
				wstr--;
				if (n != -1) {
					/* We're counting chars */
					remain++;
				}
			} else { /* str == ostr */
				if (wc == KEY_BACKSPACE || wc == KEY_LEFT)
					/* getch() displays the other keys */
					mvwadd_wch(win, win->cury,
						win->curx - 1, &cc);
				wmove(win, win->cury, oldx);
			}
		} else if (wc == kc) {
			*wstr = L'\0';
			if (wstr != ostr) {
				/* getch() displays the kill character */
				mvwadd_wch(win, win->cury, win->curx - 1, &cc);
				/* Clear the characters from screen and str */
				while (wstr != ostr) {
					mvwadd_wch(win, win->cury,
						win->curx - 1, &cc);
					wmove(win, win->cury, win->curx - 1);
					wstr--;
					if (n != -1)
						/* We're counting chars */
						remain++;
				}
				mvwadd_wch(win, win->cury, win->curx - 1, &cc);
				wmove(win, win->cury, win->curx - 1);
			} else
				/* getch() displays the kill character */
				mvwadd_wch( win, win->cury, oldx, &cc );
			wmove(win, win->cury, oldx);
		} else if (wc >= KEY_MIN && wc <= KEY_MAX) {
			/* get_wch() displays these characters */
			mvwadd_wch( win, win->cury, win->curx - 1, &cc );
			wmove(win, win->cury, win->curx - 1);
		} else {
			if (remain) {
				wstr++;
				remain--;
			} else {
				mvwadd_wch(win, win->cury, win->curx - 1, &cc);
				wmove(win, win->cury, win->curx - 1);
			}
		}
	}

	if (wc == ERR) {
		*wstr = L'\0';
		return ERR;
	}
	*wstr = L'\0';
	return OK;
}
Beispiel #22
0
/*
 * Main Loop
 * Everything is driven from this function with the exception of
 * signals which are handled in signals.c
 */
void
main_loop(void)
{
	LOG_FUNC_ENTER;

	int last_result = 0;
	int wait_enter = 0;
	int timeout = cfg.timeout_len;

	buf[0] = L'\0';
	while(1)
	{
		wchar_t c;
		size_t counter;
		int ret;

		is_term_working();

#ifdef _WIN32
		update_win_console();
#endif

		lwin.user_selection = 1;
		rwin.user_selection = 1;

		if(curr_stats.too_small_term > 0)
		{
			touchwin(stdscr);
			wrefresh(stdscr);

			mvwin(status_bar, 0, 0);
			wresize(status_bar, getmaxy(stdscr), getmaxx(stdscr));
			werase(status_bar);
			waddstr(status_bar, "Terminal is too small for vifm");
			touchwin(status_bar);
			wrefresh(status_bar);

#ifndef _WIN32
			pause();
#endif
			continue;
		}
		else if(curr_stats.too_small_term < 0)
		{
			wtimeout(status_bar, 0);
			while(wget_wch(status_bar, (wint_t*)&c) != ERR);
			curr_stats.too_small_term = 0;
			modes_redraw();
			wtimeout(status_bar, cfg.timeout_len);

			wait_enter = 0;
			curr_stats.save_msg = 0;
			status_bar_message("");
		}

		modes_pre();

		/* This waits for timeout then skips if no keypress. */
		ret = read_char(status_bar, (wint_t*)&c, timeout);

		/* Ensure that current working directory is set correctly (some pieces of
		 * code rely on this). */
		(void)vifm_chdir(curr_view->curr_dir);

		if(ret != ERR && pos != ARRAY_LEN(buf) - 2)
		{
			if(c == L'\x1a') /* Ctrl-Z */
			{
				def_prog_mode();
				endwin();
#ifndef _WIN32
				{
					void (*saved_stp_sig_handler)(int) = signal(SIGTSTP, SIG_DFL);
					kill(0, SIGTSTP);
					signal(SIGTSTP, saved_stp_sig_handler);
				}
#endif
				continue;
			}

			if(wait_enter)
			{
				wait_enter = 0;
				curr_stats.save_msg = 0;
				clean_status_bar();
				if(c == L'\x0d')
					continue;
			}

			buf[pos++] = c;
			buf[pos] = L'\0';
		}

		if(wait_enter && ret == ERR)
			continue;

		counter = get_key_counter();
		if(ret == ERR && last_result == KEYS_WAIT_SHORT)
		{
			last_result = execute_keys_timed_out(buf);
			counter = get_key_counter() - counter;
			assert(counter <= pos);
			if(counter > 0)
			{
				memmove(buf, buf + counter,
						(wcslen(buf) - counter + 1)*sizeof(wchar_t));
			}
		}
		else
		{
			if(ret != ERR)
				curr_stats.save_msg = 0;
			last_result = execute_keys(buf);
			counter = get_key_counter() - counter;
			assert(counter <= pos);
			if(counter > 0)
			{
				pos -= counter;
				memmove(buf, buf + counter,
						(wcslen(buf) - counter + 1)*sizeof(wchar_t));
			}
			if(last_result == KEYS_WAIT || last_result == KEYS_WAIT_SHORT)
			{
				if(ret != ERR)
					modupd_input_bar(buf);
				if(last_result == KEYS_WAIT_SHORT && wcscmp(buf, L"\033") == 0)
					timeout = 1;
				if(counter > 0)
					clear_input_bar();

				if(!curr_stats.save_msg && curr_view->selected_files &&
						get_mode() != CMDLINE_MODE)
					print_selected_msg();
				continue;
			}
		}

		timeout = cfg.timeout_len;

		process_scheduled_updates();

		pos = 0;
		buf[0] = L'\0';
		clear_input_bar();

		if(is_status_bar_multiline())
		{
			wait_enter = 1;
			update_all_windows();
			continue;
		}

		/* Ensure that current working directory is set correctly (some pieces of
		 * code rely on this).  PWD could be changed during command execution, but
		 * it should be correct for modes_post() in case of preview modes. */
		(void)vifm_chdir(curr_view->curr_dir);
		modes_post();
	}
}
Beispiel #23
0
int get_wch(wint_t *wch)
{
    PDC_LOG(("get_wch() - called\n"));

    return wget_wch(stdscr, wch);
}
Beispiel #24
0
NCURSES_EXPORT(int) (mvget_wch) (int a1, int a2, wint_t * z)
{
	T((T_CALLED("mvget_wch(%d,%d,%p)"), a1, a2, (const void *)z)); returnCode((wmove(stdscr,a1,a2) == (-1) ? (-1) : wget_wch(stdscr,z)));
}