Beispiel #1
0
void editor::displayAbout()
{
    attroff(-1);
    attron(COLOR_PAIR(patternedtr::COL_META_US));
    mvprintw(3,4, "+---------------------------------+",stdscr);
    mvprintw(15,4,"+---------------------------------+",stdscr);
    attroff(-1);
    attron(COLOR_PAIR(patternedtr::COL_META_US));
    mvprintw(4,4, "  Welcome to PLEBTracker!       v1 ",stdscr);
    mvprintw(5,4, "                                   ",stdscr);
    mvprintw(6,4, "Press TAB to switch windows        ",stdscr);
    mvprintw(7,4, "Press :   to open the command bar  ",stdscr);
    mvprintw(8,4, "                                   ",stdscr);
    mvprintw(9,4, "To view a list of commands, see    ",stdscr);
    mvprintw(10,4,"   the man page for plebtrkraw(1)  ",stdscr);
    mvprintw(11,4,"                                   ",stdscr);
    mvprintw(12,4,"                      -Dan Frazier ",stdscr);
    mvprintw(13,4,"                                   ",stdscr);
    mvprintw(14,4," Press [Space] to continue         ",stdscr);
    editor::lastwin = editor::dialog;
    wint_t ch;
    get_wch(&ch);
    while(ch != ' ' && ch != '\n') get_wch(&ch);

    return;
}
Beispiel #2
0
void editor::inform(const char *message)
{
    int length = strlen(message);
    int msglen = length;
    if(length < 64)
        length = 64;
    attroff(-1);
    attron(COLOR_PAIR(patternedtr::COL_META_US));
    mvprintw(3,4,"+--------------------------------------------------------------+",stdscr);

    mvprintw(8,4,"+--------------------------------------------------------------+",stdscr);
    attroff(-1);
    attron(COLOR_PAIR(patternedtr::COL_META_US));
    mvprintw(4,4,"                                                                ",stdscr);
    mvprintw(5,4,message,stdscr);
    if(msglen < 64)
        for(int i = msglen; i < 64; i++)
            mvprintw(5, 4+i, " ", stdscr);
    mvprintw(6,4,"                                                                ",stdscr);
    mvprintw(7,4," Press [Space] to continue                                      ",stdscr);
    editor::lastwin = editor::dialog;
    wint_t ch;
    get_wch(&ch);
    while(ch != ' ' && ch != '\n') get_wch(&ch);
    return;
}
Beispiel #3
0
bool editor::confirm(const char *message)
{
    int length = strlen(message);
    int msglen = length;
    if(length < 64)
        length = 64;
    attroff(-1);
    attron(COLOR_PAIR(patternedtr::COL_META_US));
    //modify these to output to the length
    mvprintw(3,4,"+--------------------------------------------------------------+",stdscr);
    mvprintw(8,4,"+--------------------------------------------------------------+",stdscr);
    attroff(-1);
    attron(COLOR_PAIR(patternedtr::COL_META_US));
    mvprintw(4,4,"                                                                ",stdscr);
    mvprintw(5,4,message,stdscr);
    if(msglen < 64)
        for(int i = msglen; i < 64; i++)
            mvprintw(5, 4+i, " ", stdscr);
    mvprintw(6,4,"                                                                ",stdscr);
    mvprintw(7,4," Are you sure? [y/n]                                            ",stdscr);
    editor::lastwin = editor::dialog;

    wint_t ch;
    get_wch(&ch);
    while(ch != 'y' && ch != 'n' && ch != 27) get_wch(&ch);

    if(ch == 'y')
        return true;
    return false;
}
Beispiel #4
0
int t_getch(t_char *ch)
{
	wint_t c;
	int status = get_wch(&c);
	*ch = (t_char) c;
	return status;
}
Beispiel #5
0
/* "valid" string.                                              */
wchar_t
prompt_char(int row, int col, const char *promptstr, const char *valid)
{
	wchar_t *w_prompt, *w_valid=NULL, ch;
   
	int code;

	w_prompt = mbstowcs_alloc(promptstr);

	/* if w_promptstr == NULL ?? .... */

	/* Print the prompt.                                        */
	mvaddwstr(row, col, w_prompt);
	clrtoeol();
	refresh();

    if ( valid  != NULL ) {
            w_valid  = mbstowcs_alloc(valid);
    }
	/* Read characters...                                       */
	while ((code = get_wch(&ch)) != ERR) {
		/* If it's not a valid one, beep and get another one.   */
		/* if (index(valid, c) == NULL) { */
        if ( valid  != NULL ) {
		    if (wcsrchr(w_valid, ch) == NULL) {	/* CHANGED !! */
			    beep();
			    continue;
		    }

		    /* Add the character to the screen, and return it.      */
		    AddCh((chtype) ch);
		    refresh();
        }
		goto _exit;
	}
 _exit:
	free(w_prompt);
	refresh();
    if (valid != NULL ) {
	    free(w_valid);
        w_valid= NULL ;
        return (ch);		/* to avoid compiler warning */
    } else {
        return '\0' ;
   }
}
Beispiel #6
0
void interactive(machine *m) {
	/* Set up the ncurses interface */
	ui_info ui;
	initscr();
	start_color();
	raw(); 
	noecho(); 
	keypad(stdscr, true);

	/* Figure out the level of color support, choose attributes accordingly */
	if (has_colors()) {
		if (can_change_color()) {
			/* Best case, programmable colors */
			init_color(CLR_WHITEGRAY, 800, 800, 800); /* dull text */
			init_color(CLR_DARKGRAY, 400, 400, 400);  /* highlighted metal */
			init_color(CLR_DARKESTGRAY, 250, 250, 250); /* darkest metal */
			init_color(CLR_BRIGHTRED, 1000, 400, 400); /* coded text */
			init_pair(CP_WHEEL_PLAIN, CLR_WHITEGRAY, CLR_DARKESTGRAY);
			init_pair(CP_WHEEL_ACTIV, COLOR_WHITE, CLR_DARKGRAY);
			init_pair(CP_PLAIN, COLOR_WHITE, COLOR_BLACK);
			init_pair(CP_CODED, CLR_BRIGHTRED, COLOR_BLACK);
			init_pair(CP_BTN, COLOR_RED, CLR_DARKESTGRAY);
			init_pair(CP_BTNH, COLOR_RED, CLR_DARKGRAY);	
		} else {
			/* Second best, 8 color ncurses */
			init_pair(CP_WHEEL_PLAIN, COLOR_YELLOW, COLOR_BLUE);
			init_pair(CP_WHEEL_ACTIV, COLOR_WHITE, COLOR_RED);
			init_pair(CP_PLAIN, COLOR_WHITE, COLOR_BLACK);
			init_pair(CP_CODED, COLOR_RED, COLOR_BLACK);
			init_pair(CP_BTN, COLOR_RED, COLOR_BLUE);
			init_pair(CP_BTNH, COLOR_BLUE, COLOR_RED);
		}
		ui.attr_plain = COLOR_PAIR(CP_PLAIN);
		ui.attr_coded = COLOR_PAIR(CP_CODED);
		ui.attr_wheel_plain = COLOR_PAIR(CP_WHEEL_PLAIN);
		ui.attr_wheel_activ = COLOR_PAIR(CP_WHEEL_ACTIV) | A_BOLD;
		ui.attr_btn = COLOR_PAIR(CP_BTN);
		ui.attr_btnh = COLOR_PAIR(CP_BTNH);
	} else {
		/* No color fallback */
		ui.attr_plain = A_NORMAL;
		ui.attr_coded = A_BOLD;
		ui.attr_wheel_plain = A_REVERSE;
		ui.attr_wheel_activ = A_REVERSE | A_BOLD | A_UNDERLINE;
		ui.attr_btn = A_REVERSE | A_BOLD;
		ui.attr_btnh = ui.attr_btn;
	}
	ui.attr_lbl = A_NORMAL;
	ui.attr_lblh = A_BOLD;
	ui.chosen_wheel = -1;

	/* Make the windows */
	int topheight = 10 + m->wheelslots;
	int longestname = strlen("ring settings");
	if (longestname < m->longest_wheelname) longestname = m->longest_wheelname;
	int topwidth = 4 * m->wheelslots + 1 + longestname;
	int namelen = wcslen(m->name);
	if (namelen > topwidth) topwidth = namelen;
	ui.w_wheels = newwin(topheight, topwidth, 0, COLS-topwidth);
	int botheight = ((LINES - topheight) / 3) * 3 - 1;
	int botwidth = COLS;
	ui.w_code = newwin(botheight, botwidth, topheight, 0);
	ui.w_pop = newwin(botheight, botwidth, topheight, 0);
	draw_wheels(m, &ui);

  bool enciphering = true;		/* enchiper or dechiper */

	wchar_t plaintext[MAXLINE+1]; /* typed/dechipered text */
	wchar_t ciphertxt[MAXLINE+1]; /* typed/enchipered text */
	memset(plaintext, 0, sizeof(wchar_t)*(MAXLINE+1));
	memset(ciphertxt, 0, sizeof(wchar_t)*(MAXLINE+1));

	int textpos = 0;
  int maxpos = COLS - 2 > MAXLINE ? MAXLINE : COLS - 2;  

	curses_bug_workaround();
	wmove(ui.w_code, 1, 1);

	/* main loop. The first event has to be the KEY_RESIZE, it creates the display! */
	int rc = KEY_CODE_YES;
	wint_t wch = KEY_RESIZE; 
	for (bool active = true; active; rc = active ? get_wch(&wch) : 0) {
		switch (rc) {
			case KEY_CODE_YES:		/* specials */
				switch (wch) {
					case KEY_F(1):
						highlight_wheel(m, &ui, 0);
						break;
					case KEY_F(2):
						highlight_wheel(m, &ui, 1);
						break;
					case KEY_F(3):
						highlight_wheel(m, &ui, 2);
						break;
					case KEY_F(4):
						highlight_wheel(m, &ui, 3);
						break;
					case KEY_F(5):
						highlight_wheel(m, &ui, 4);
						break;
					case KEY_F(6):
						highlight_wheel(m, &ui, 5);
						break;
					case KEY_F(7):
						highlight_wheel(m, &ui, 6);
						break;
					case KEY_F(8):
						highlight_wheel(m, &ui, 7);
						break;
					case KEY_F(9):
						highlight_wheel(m, &ui, 8);
						break;
					case KEY_LEFT:
						highlight_left(m, &ui);
						break;
					case KEY_RIGHT:
						highlight_right(m, &ui);
						break;
					case KEY_F(10):
						highlight_wheel(m, &ui, 9);
						break;
					case KEY_NPAGE:
						next_wheel(m, &ui);
						break;
					case KEY_UP:
						if (ui.chosen_wheel == -1) {		
							/* switch to encoding */
							enciphering = true;
							wmove(ui.w_code, 1, textpos+1);
							wnoutrefresh(ui.w_code);
						} else wheel_turn(m, &ui, -1);
						break;
					case KEY_DOWN:
						if (ui.chosen_wheel == -1) {		
							/* switch to decoding */
							enciphering = false;
							wmove(ui.w_code, 2, textpos+1);
							wnoutrefresh(ui.w_code);
						} else wheel_turn(m, &ui, 1);		
						break;
					case KEY_RESIZE:	/* user resized the xterm - redraw all! */
						curses_bug_workaround();//Remove, and top window blanks out
						/* Must repaint all, as downsizing may blank the terminal */
						
						/* Deal with the code wheel window */
						botheight = ((LINES - topheight) / 3) * 3 - 1;
						botwidth = COLS;
						wresize(ui.w_code, botheight, botwidth);
						wresize(ui.w_pop, botheight, botwidth);
						int oldx = getbegx(ui.w_wheels);
						int newx = COLS-topwidth;
						mvwin(ui.w_wheels, 0, COLS-topwidth); /* move the window */
						/* now clear out the exposed screen area */
						if (newx > oldx) {
							int xlen = newx-oldx;
							char *spc = malloc(xlen+1);
							memset(spc, ' ', xlen);
							spc[xlen] = 0;
							for (int i=0; i < topheight; ++i) mvprintw(i, oldx, spc);
							free(spc); 
						}
						wnoutrefresh(ui.w_wheels);
						curses_bug_workaround(); //Remove, and the cursor will misplaced when upsizing
						

						/* Now the code text window */
						maxpos = COLS - 2 > MAXLINE ? MAXLINE : COLS - 2;  
                  
						if (textpos > maxpos) {
							leftcut(plaintext, textpos - maxpos, maxpos+1);
							leftcut(ciphertxt, textpos - maxpos, maxpos+1);
							textpos = maxpos;
							wattrset(ui.w_code, ui.attr_plain);
							mvwprintw(ui.w_code, 1, 1, "%ls", plaintext);wclrtoeol(ui.w_code);
							wattrset(ui.w_code, ui.attr_coded);
							mvwprintw(ui.w_code, 2, 1, "%ls", ciphertxt);wclrtoeol(ui.w_code);
							if (enciphering) wmove(ui.w_code, 1, textpos+1);
						}

						wnoutrefresh(ui.w_code);
						break;
				}
				break;
			case OK:
				if (iscntrl(wch)) switch (wch) {
					/* ctrl tv change ring settings */
					case 20:
						ringstellung(m, &ui, -1);
						break;
					case 22:
						ringstellung(m, &ui, 1);
						break;
					/* quit on ctrl+c */	
					case 3:
						active = false;
						break;
					/* unselect wheel on enter */
						case '\n':
							highlight_wheel(m, &ui, -1);
							wnoutrefresh(ui.w_code);
							break;
				}							
				/* plain typing */
				else { 
					if (ui.chosen_wheel > -1) highlight_wheel(m, &ui, -1);
					/* Need a line break first? */
					if (textpos >= maxpos) {
						/* add scrolling later !!! for now, just clear */
						textpos = 0;
						memset(plaintext, 0, sizeof(wchar_t)*(MAXLINE+1));
						memset(ciphertxt, 0, sizeof(wchar_t)*(MAXLINE+1));
						if (enciphering) {
							wmove(ui.w_code, 2, textpos+1); wclrtoeol(ui.w_code);
							wmove(ui.w_code, 1, textpos+1); wclrtoeol(ui.w_code);
						} else {
							wmove(ui.w_code, 1, textpos+1); wclrtoeol(ui.w_code);
							wmove(ui.w_code, 2, textpos+1); wclrtoeol(ui.w_code);
						}
					}
					if (enciphering) {
						plaintext[textpos] = wch;
						ciphertxt[textpos] = encipher(m, wch, &ui);
						wattrset(ui.w_code, ui.attr_coded);
						mvwprintw(ui.w_code, 2, 1, "%ls", ciphertxt);
						wattrset(ui.w_code, ui.attr_plain);
						mvwprintw(ui.w_code, 1, 1, "%ls", plaintext);
					} else {
						ciphertxt[textpos] = wch;
						plaintext[textpos] = decipher(m, wch, &ui);
						wattrset(ui.w_code, ui.attr_plain);
						mvwprintw(ui.w_code, 1, 1, "%ls", plaintext);
						wattrset(ui.w_code, ui.attr_coded);
						mvwprintw(ui.w_code, 2, 1, "%ls", ciphertxt);
					}
					textpos++;
					wnoutrefresh(ui.w_wheels);
					wnoutrefresh(ui.w_code);
					break;
				}
		} 
		doupdate();
	}
	endwin();
}
Beispiel #7
0
 /*
    Returns whether we should save our changes or not.

    Edits an existing an entry. This routine is far to big, and handles
    everything, from movement between fields, and editing fields, even
    painting the screen.

 */
int
edit_entry(dbrecord * entry, const char *operationDesc, const char *entryDesc)
{
	int *len;
	int col0;
	wchar_t *line=NULL;
	char tbuf[MAXSCREENWIDTH];
	int code = 0;
	wchar_t ch;
	dbbuffer tmp;
	register int i, j, row, col;
    initHeading() ;
	/* Where is "column zero"? To right of longest field name.  */
	col0 = idx.idx_maxlen + 2;

	 clear();		/* Clear the screen.                            */
    initEntryLine() ;
    paintHeading(operationDesc) ;
	/* get max col TODO: change this when sigwhinch */
    /* first time: allocat wchar fulldbdir name
       fulldbdir is a static.*/
	for (row = STARTROW; row < (idx.idx_nlines+STARTROW); row++) { 
		/* print field names.                                   */
		mvaddwstr(row, 0, idx.idx_lines[row-STARTROW]);
	}
	/* Allocate some space in a temporary entry, and copy entry */
	/* to be edited into it.  This way they can abort the edit. */
	/* Here we need to allocate some extra space so we can edit */

	for (i = STARTROW; i < (idx.idx_nlines+STARTROW); i++) {
        int k = i-STARTROW ;
		if (entry->db_lens[k] == 0) {
			/* Allocate memory for this line.                   */
            size_t linelen = (MAXSCREENWIDTH * sizeof(wchar_t));
			tmp.db_lines[k] =
                 (wchar_t *) ymalloc(linelen,
                    "edit_entry","tmp.db_lines[k]" );
            memset(tmp.db_lines[k],0,linelen);
			tmp.db_lens[k] = 0;
		} else {
			/* Copy and print the line from the entry.          */
			tmp.db_lines[k] =
			    wcsFromUnicode_alloc((size_t *) & tmp.db_lens[k],
						 entry->db_lines[k],
						 (int32_t) entry->db_lens[k]);
			if (tmp.db_lines[k] == NULL) {
                yerror( YICU_CONV_ERR ,"edit_entry->wcsFromUnicode_alloc", "tmp.db_lines[k]", YX_EXTERNAL_CAUSE ) ;
			}
			/* reallocates more space to maximum linebuffer size. */
			tmp.db_lines[k] =
			    (wchar_t *) yrealloc(tmp.db_lines[k], (size_t)
						(MAXSCREENWIDTH * sizeof(wchar_t)),"edit_entry","tmp.db_lines[k]");
		}

		move(i, col0);
		clrtoeol();
		if (tmp.db_lens[k] > 0) {
			addwstr(tmp.db_lines[k]);
		}
	}			/* *could* have factored out the index code.              */
	col = col0;
	row = STARTROW;		/* row er hvilke rad i recorden (felt). */

	move(row, col);
	refresh();
	/* Editing entry. We provide basic EMACS-style cntrl chars. */
	while ((code = get_wch(&ch)) != EOF) {
		/* Get the current line and line length.                */
		line = tmp.db_lines[row-STARTROW];
		/* f.p. *len = &tmp.db_lens[row]; */
		len = &tmp.db_lens[row-STARTROW];
		switch (ch) {
		case CTRL('a'):	/* beginning of line            */
			col = col0;
			break;
		case KEY_LEFT:
		case CTRL('b'):	/* back character               */
			if (col > col0)
				col--;
			break;
		case CTRL('d'):	/* delete character             */
			if (col == (col0 + (int)wcslen(line))) {
				col--;
			} else if (*len) {
				/* Calculate position of character in string.   */
				int l = col - col0;

				/* Shuffle the string to the "left".            */
				while (l < *len) {
					line[l] = line[l + 1];
					l++;
				}
				*len -= 1;
				/* Delete the character on the screen.          */
				delch();
                if (col== (col0 + (int)wcslen(line)) ) {
                    --col ;
                }
			}

			break;
		case CTRL('e'):	/* end of line                  */
			col = col0 + *len;
			break;
		case KEY_RIGHT:
		case CTRL('f'):	/* forward character            */
			if ((col - col0) < *len)
				col++;
			break;
		case KEY_BACKSPACE:
		case CTRL('h'):	/* backspace delete             */
		case '\177':
			if (*len && ((col - 1) >= col0)) {
				/* Calculate position of character to delete.   */
				int l = col - col0 - 1;
				if (l < 0)
					break;
				/* Shuffle string "left".                        */
				while (l < *len) {
					line[l] = line[l + 1];
					l++;
				}

				*len -= 1;

				/* Delete the character from the screen.        */
				move(row, --col);
				delch();
			}
			break;
		case CTRL('k'):	/* kill line                    */
			if (len) {
                
			    int l = col - col0;

				line[l] = (wchar_t) '\0';
				*len = l;

				clrtoeol();
			}
			break;
		case CTRL('l'):	/* redraw screen                */
			wrefresh(curscr);
			break;
		case KEY_DOWN:
		case CTRL('n'):	/* next line                    */
			/* Wrap around to the top if necessary.             */
			if (++row >= (idx.idx_nlines+STARTROW))
				row = STARTROW; 
			/* If nothing in this column, move to nearest       */
			/* non-empty column.                                */
			if ((col - col0) > tmp.db_lens[row-STARTROW])
				col = col0 + tmp.db_lens[row-STARTROW];
			line[*len] = (wchar_t) '\0';
			break;
		case KEY_UP:
		case CTRL('p'):	/* previous line                */
			/* Wrap around if necessary.                        */
			if (--row < STARTROW)
				row = (idx.idx_nlines+STARTROW) - 1;

			/* If nothing in this column, move to nearest       */
			/* on-empty column.                                 */
			if ((col - col0) > tmp.db_lens[row-STARTROW])
				col = col0 + tmp.db_lens[row-STARTROW];
			line[*len] = (wchar_t) '\0';
			break;
		case CTRL('['):	/* save entry:  ESC or something...  */
			if (line[*len] != (wchar_t) '\0')
				line[*len] = (wchar_t) '\0';
			sprintf(tbuf, "Save %s entry in database (y/n)? ", entryDesc);
			ch = prompt_char(idx.idx_nlines + 2+ STARTROW, 0, tbuf, "yYnN");

			/* See what they said.                              */
			switch (ch) {
			case '\n':	/* never mind                       */
				move(idx.idx_nlines + 2, 0);
				clrtoeol();
				break;
			case 'Y':	/* save entry                       */
			case 'y':
				/* Copy the temporary entry into the real entry. */
				/* if there isn't anything to copy, then the entry db gets the value
				   NULL, and length 0 */
				for (i = 0; i < idx.idx_nlines; i++) {

					/* remove old contents in entry             */
					if (entry->db_lens[i] > 0) {
						free(entry->db_lines[i]);
						entry->db_lines[i] = NULL;
						entry->db_lens[i] = 0;
					} 
                    
                    if (tmp.db_lens[i] > 0) {
                        entry->db_lens[i]=tmp.db_lens[i] ;
						entry->db_lines[i] =
						    unicodeFromWcs_alloc((size_t *) &entry->db_lens[i],tmp.db_lines[i]);

					    if (entry->db_lines[i] == NULL) {
                            yerror( YICU_CONV_ERR ,"edit_entry->unicodeFromWcs_alloc", "entry->db_lines[i]", YX_EXTERNAL_CAUSE ) ;
                        }
                    } /* had a dangling else bug here ? */
					free(tmp.db_lines[i]);
                    tmp.db_lines[i] = NULL ;
				    tmp.db_lens[i] = 0;
				}
				return (1);
			case 'N':	/* don't save entry                 */
			case 'n':
				/* Free temporary memory.                       */
				for (i = 0; i < idx.idx_nlines; i++) {
					tmp.db_lens[i] = 0;
					free(tmp.db_lines[i]);
					tmp.db_lines[i] = NULL;
				}
				return (0);
			}
			break;
		case '\r':	/* return the string            */
		case '\n':	/* go to next line                  */
			/* Wrap around if necessary.                        */
			if (++row >= (idx.idx_nlines+STARTROW))
				row = STARTROW;
			col = col0;
			break;
		default:	/* something else                   */
			/* User's kill character: accepted to del line too. */
			if (ch == KEY_DL) {
				move(row, col0);
				clrtoeol();
				col = col0;

				*line = (wchar_t) '\0';
				*len = 0;
			} else if (code != KEY_CODE_YES) {
				/* If it's a printable character, insert it into */
				/* the string.                                  */
				if (iswctype(ch, wctype("print"))) {
					if (col == (COLS - 1)) {
						beep();
						break;
					}
					/* Calculate character position.            */
					i = col - col0;

					/* If necessary, move string * to "right"   */
					/* to insert the character.                 */
					if (i < *len) {
						for (j = *len; j >= i; j--)
							line[j + 1] = line[j];
					}

					line[i] = ch;
					*len += 1;
					col++;

					/* Insert the character on the screen.       */
					InsWch((chtype) ch);

				}
			}
			break;
		}

		/* Move to the current row/column.                       */
		move(row, col);
		refresh();
	}
	return (0);
}
Beispiel #8
0
/* TODO: all length calculations of the string must be rebuilt.
 *
 * BUG:
 *          Når jeg står på slutten av linjen så blir cursor pos
 *          justert mot venstre selv om jeg ikke sletter noe.
 *
 * */
void
prompt_str(int row, int col, const char *promptstr, wchar_t * answer)
{
	wchar_t *line = answer;

	int len, col0;

	/* struct sgttyb _tty ; */
	register int code, i, j;

	/* Converts  the promptstr to a  wide version.              */
	wchar_t *wpromptstr = mbstowcs_alloc(promptstr);

	if (wpromptstr == NULL) {
        yerror( YMBS_WCS_ERR,"prompt_str->mbstowcs_alloc", "wpromptstr", YX_EXTERNAL_CAUSE ) ;
    }

	wchar_t ch;

	/* Print the wide prompt at (row,col).                          */
	mvaddwstr(row, col, wpromptstr);

	refresh();

	/* Calc "column zero", which is at right end of prompt.     */
	col += wcslen(wpromptstr);
	col0 = col;
	mvaddwstr(row, col, answer);
    len = wcslen(answer) ;
    col += len ; 
	/* Read chars till we get what we want. Useris allowed      */
	/* basic EMACS-style line editing.                          */
	while ((code = get_wch(&ch)) != EOF) {
		switch (ch) {
		case CTRL('a'):	/* beginning of line            */
			col = col0;
			break;
		case KEY_LEFT:
		case CTRL('b'):	/* back character               */
			if (col > col0)
				col--;
			break;
		case CTRL('d'):	/* delete character             */
			/*
			 * If there's stuff in the string,
			 * delete this character.
			 */
			if (col == (col0 + (int)wcslen(line))) {
				col--;
			} else if (len) {
				/* Calc string pos of char to delete.           */
				i = col - col0;

				/* Shuffle the string "left" one place.         */
				while (i < len) {
					line[i] = line[i + 1];
					i++;
				}

				/* Delete char on the screen.                   */
				len -= 1;
				delch();	/* prob ok that isn't wide. */
                if (col== (col0 + (int)wcslen(line)) ) {
                    --col ;
                }
			}

			break;
		case CTRL('e'):	/* end of line                  */
			col = col0 + len;
			break;
		case KEY_RIGHT:
		case CTRL('f'):	/* forward character            */
			if ((col - col0) < len)
				col++;
			break;
		case KEY_BACKSPACE:
		case CTRL('h'):	/* backspace delete */
		case '\177':
			/* If stuff in the string, delete char.             */
			if (len && ((col - 1) >= col0)) {
				/* Calc pos in string of char to delete         */
				int l = col - col0 - 1;
				if (l < 0)
					break;
				/* Shuffle the string "left" one place.         */
				while (l < len) {
					line[l] = line[l + 1];
					l++;
				}

				len -= 1;
				/* Delete the character on the screen.          */
				move(row, --col);
				delch();
			}
			break;
		case CTRL('k'):	/* kill line                    */
			/* Clear the string.                                */
			if (len) {
				i = col - col0;

				line[i] = '\0';
				len = i;

				clrtoeol();
			}
			break;
		case CTRL('l'):	/* redraw screen                */
			wrefresh(curscr);
			break;
		case KEY_ENTER:
		case '\r':	/* return the string            */
		case '\n':	/* return the string            */
			line[len] = '\0';
			return;
		default:	/* regular character            */
			if (ch == KEY_DL) {
				move(row, col0);
				clrtoeol();
				col = col0;

				*line = '\0';
				len = 0;
			} else if (code != KEY_CODE_YES) {
				if (iswctype(ch, wctype("print"))) {
					if (col == (COLS - 1)) {
						beep();
						break;
					}
					/* Calculate position of char in string.    */
					i = col - col0;

					/* If we have to, move string "right" one   */
					/* place to insert the character.           */
					if (i < len) {
						for (j = len; j >= i; j--)
							line[j + 1] = line[j];
					}
					line[i] = ch;
					len += 1;
					col++;

					/* Insert the character on the screen.      */
					InsWch((chtype) ch);
					/* ins_wch(&ch); */
				}
			}
			break;
		}

		/* Move the cursor.                                     */
		move(row, col);
		refresh();
	}
}
Beispiel #9
0
Datei: main.c Projekt: Tilka/ncdc
static void handle_input() {
  /* Mapping from get_wch() to input_key_t:
   *  KEY_CODE_YES -> KEY(code)
   *  KEY_CODE_NO:
   *    char == 127           -> KEY(KEY_BACKSPACE)
   *    char <= 31            -> CTRL(char)
   *    !'^['                 -> CHAR(char)
   *    ('^[', !)             -> KEY(KEY_ESCAPE)
   *    ('^[', !CHAR)         -> ignore both characters (1)
   *    ('^[', CHAR && '[')   -> ignore both characters and the character after that (2)
   *    ('^[', CHAR && !'[')  -> ALT(second char)
   *
   * 1. this is something like ctrl+alt+X, which we won't use
   * 2. these codes indicate a 'Key' that somehow wasn't captured with
   *    KEY_CODE_YES. We won't attempt to interpret these ourselves.
   *
   * There are still several unhandled issues:
   * - Ncurses does not catch all key codes, and there is no way of knowing how
   *   many bytes a key code spans. Things like ^[[1;3C won't be handled correctly. :-(
   * - Ncurses can actually return key codes > KEY_MAX, but does not provide
   *   any mechanism for figuring out which key it actually was.
   * - It may be useful to use define_key() for some special (and common) codes
   * - Modifier keys will always be a problem. Most alt+key things work, except
   *   for those that may start a control code. alt+[ is a famous one, but
   *   there are others (like alt+O on my system). This is system-dependent,
   *   and again we have no way of knowing these things. (except perhaps by
   *   reading termcap entries on our own?)
   */

  guint64 key;
  char buf[9];
  int r;
  wint_t code;
  int lastesc = 0, curignore = 0;
  while((r = get_wch(&code)) != ERR) {
    if(curignore) {
      curignore = 0;
      continue;
    }
    // we use SIGWINCH, so KEY_RESIZE can be ignored
    if(r == KEY_CODE_YES && code == KEY_RESIZE)
      continue;
    // backspace (outside of an escape sequence) is often sent as DEL control character, correct this
    if(!lastesc && r != KEY_CODE_YES && code == 127) {
      r = KEY_CODE_YES;
      code = KEY_BACKSPACE;
    }
    // backspace inside an escape sequence is also possible, convert the other way around
    if(lastesc && r == KEY_CODE_YES && code == KEY_BACKSPACE) {
      r = !KEY_CODE_YES;
      code = 127;
    }
    key = r == KEY_CODE_YES ? INPT_KEY(code) : code == 27 ? INPT_ALT(0) : code <= 31 ? INPT_CTRL(ctrl_to_ascii(code)) : INPT_CHAR(code);
    // convert wchar_t into gunichar
    if(INPT_TYPE(key) == 1) {
      if((r = wctomb(buf, code)) < 0)
        g_warning("Cannot encode character 0x%X", code);
      buf[r] = 0;
      key = INPT_CHAR(g_utf8_get_char_validated(buf, -1));
      if(INPT_CODE(key) == (gunichar)-1 || INPT_CODE(key) == (gunichar)-2) {
        g_warning("Invalid UTF-8 sequence in keyboard input. Are you sure you are running a UTF-8 locale?");
        continue;
      }
    }
    // check for escape sequence
    if(lastesc) {
      lastesc = 0;
      if(INPT_TYPE(key) != 1)
        continue;
      if(INPT_CODE(key) == '[') {
        curignore = 1;
        continue;
      }
      key |= (guint64)3<<32; // a not very nice way of saying "turn this key into a INPT_ALT"
      ui_input(key);
      continue;
    }
    if(INPT_TYPE(key) == 3) {
      lastesc = 1;
      continue;
    }
    ui_input(key);
  }
  if(lastesc)
    ui_input(INPT_KEY(KEY_ESCAPE));

  ui_draw();
}