int main(int argc, char* argv[]) { int is_running = 1; int x_terminal_size, y_terminal_size; int is_lurking = 0; int is_yelling = 0; int in_deepsix = 0; int sending_im = 0; int i; /* josh-note: These need to be uncommented for the client connection to work. */ /* int client_id = init_client("Henry"); create a client. */ /* init_user_list(client_id); init the client size user list. */ log_init(); log_writeln(" --------------------------- "); log_writeln(" > Starting BlackChat"); signal(SIGALRM, scroll_ended_handler); for(i = 0; i < 26; i ++) { /* set our message to null */ memset(yell_messages[i], '\0', MAX_MESSAGE_LENGTH * sizeof(wchar_t)); } transcript_buffer = (wchar_t*)malloc(sizeof(wchar_t)*transcript_buffer_size); f_transcript_buffer = (wchar_t*)malloc(sizeof(wchar_t)*f_transcript_buffer_size); memset(client_buffer, '\0', sizeof(client_buffer)); memset(transcript_buffer, '\0', sizeof(transcript_buffer)); get_terminal_size(&x_terminal_size, &y_terminal_size); log_writeln(" > ... detecting current terminal size xy:(%d,%d)", x_terminal_size, y_terminal_size); log_writeln(" > ... initializing ncurses screen in raw mode"); initscr(); // start_color(); init_pair(0, COLOR_WHITE, COLOR_BLACK); init_pair(1, COLOR_GREEN, COLOR_BLACK); init_pair(2, COLOR_YELLOW, COLOR_BLACK); init_pair(3, COLOR_CYAN, COLOR_BLACK); init_pair(4, COLOR_MAGENTA, COLOR_BLACK); raw(); keypad(stdscr, TRUE); noecho(); color_set(0, NULL); log_writeln(" > ... creating transcript and client window"); transcript_window = newwin(TRANSCRIPT_MAX_ROWS,TRANSCRIPT_MAX_COLUMNS, 0,0); fullscreen_transcript_window = newwin(TRANSCRIPT_MAX_ROWS,TRANSCRIPT_MAX_COLUMNS*2, 0,0); client_chat_window = newwin(MAX_ROWS,MAX_COLUMNS,24,0); lurk_win = newwin(MAX_ROWS,MAX_COLUMNS,24,0); yell_win = newwin(23,40,0,0); deepsix_win = newwin(23,40,0,0); im_win = newwin(TRANSCRIPT_MAX_ROWS,TRANSCRIPT_MAX_COLUMNS, 0,0); status_win = newwin(3,40,21,40); info_win = newwin(3,40,0,40); // box(yell_win, '|', '-'); set_yell_message(0, L"Hello World"); set_yell_message(1, L"Yo dog!"); set_yell_message(2, L"Hey everyone!"); set_yell_message(3, L"Whats up?"); set_yell_message(12,L"I agree."); wcolor_set(lurk_win, 4, NULL); wcolor_set(transcript_window, 3, NULL); wcolor_set(client_chat_window, 4, NULL); wcolor_set(yell_win, 2, NULL); wprintw(lurk_win, "Lurking... Use CTRL-L to unLurk or CTRL-Q to quit."); log_writeln(" > ... creating other 9 windows"); init_other_windows(); log_writeln(" > ... [beginning transcript]"); write_to_transcript_window(L"***************************************"); write_to_transcript_window(L"******** Wecome to BlackChat! *********"); write_to_transcript_window(L"***************************************"); set_window_user_name(0, L"chris"); set_window_user_name(1, L"sue"); set_window_user_name(2, L"dan"); set_window_user_name(3, L"joe"); append_text_to_window(0, L"Sup!"); append_text_to_window(1, L"yo everyone, I'm in love with blackchat!"); append_text_to_window(2, L"hey, my name is Dan!"); append_text_to_window(3, L"Hey!?"); can_deepsix_user(0, 0); set_user_status(1, 'L'); set_user_status(2, 'L'); /* Set our info window text. */ wprintw(info_win, " Black Chat v1.0\n"); wprintw(info_win, "UI: Henry Stratmann|Client: Josh Hartman\n"); wprintw(info_win, "Server: Tyler Reid |Protocol: Tim Rhoads\n"); while(is_running) { int ch = getch(); /* wchar_t buf[512]; //get wchar_ts sprintf(buf, "key pressed: '%c' int value: %d\n", ch, ch); write_to_transcript_window(buf); */ //end get wchar_t /* Check if were in "Lurk" mode. */ if(is_lurking) { switch(ch) { case 12: /* lurk-off */ is_lurking = 0; print_client_chat_buffer(); break; case 17: /* quit */ is_running = 0; break; default: wrefresh(lurk_win); } } /* Check if were in IM mode. */ else if(sending_im) { /* TODO: Display list of users (like deepsix) to send IM to. All IM's will be displayed on the main transcript with some type of "marker" indicating that this was an IM. */ if(ch >= 48 && ch <= 57) { /* josh-note: Have josh send IM based on "ch" */ } /* quit */ if(ch == 17) { is_running = 0; } /* exit IM */ sending_im = 0; window_page_up(transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS, transcript_buffer); window_page_up(fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer); } /* Check if were in deepsix mode. */ else if(in_deepsix) { /* kick user */ if(ch >= 48 && ch <= 57) { /* josh-note: Have josh make a "kick_user(ch-48)" command. Also, have josh keep track of who user voted for and display message on transcript as to how user voted and/or if they already voted for the user. */ } /* quit */ if(ch == 17) { is_running = 0; } /* exit deepsix */ in_deepsix = 0; window_page_up(transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS, transcript_buffer); window_page_up(fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer); } /* Check if were yelling. */ else if(is_yelling) { // redrawwin(yell_win); // wrefresh(yell_win); int index = ch - 97; /* Write our comment to our transcript window. */ if(index >= 0 && index < 26) { if( yell_messages[index][0] != '\0' ) { write_to_transcript_window( yell_messages[index] ); } } is_yelling = 0; redrawwin(client_chat_window); wrefresh(client_chat_window); redrawwin(transcript_window); wrefresh(transcript_window); } else { /* Check what keys we pressed. */ switch(ch) { /* * Check if we pressed a control key. */ if(iscntrl(ch)) { case 7: /* CTRL-G */ gaudy_mode_on = (gaudy_mode_on == 1) ? 0 : 1; if(gaudy_mode_on) { client_buffer[ client_cursor_position++ ] = 2; } else { client_buffer[ client_cursor_position++ ] = 3; } /* Print out updates to the window. */ print_client_chat_buffer(); break; case 127:/* Backsapce Key (grok hack) */ case 8: /* CTRL-H */ client_buffer[ wcslen(client_buffer)-1 ] = '\0'; print_client_chat_buffer(); break; case 9: /* CTRL-I / TAB */ if(!sending_im) { sending_im = 1; draw_im_window(); } break; case 10: /* CTRL-J and CTRL-M */ /* UNCOMMENT ME FOR USE WITH SERVER */ { wchar_t *buf = NULL; /* If we had gaudy mode on, we need to disable it. */ if(gaudy_mode_on) { client_buffer[ client_cursor_position++ ] = 3; client_buffer[ client_cursor_position++ ] = ' '; gaudy_mode_on = 0; } /* Get our buffer togther to write to the transcript window. */ buf = (wchar_t*)malloc( (wcslen(L"[Client Says]: ")+wcslen(client_buffer)+1) * sizeof(wchar_t) ); write_to_transcript_window(L"[Client Says]: "); write_to_transcript_window(client_buffer); // sprintf(buf, "[Client Says]: %ls", client_buffer); // write_to_transcript_window(buf); } clear_text_from_client_typing_window(); /* write_out(client_id); enter key is pressed so send a message to the server. */ break; case 11: /* CTRL-K */ { int i; for(i = client_cursor_position+1; i < wcslen(client_buffer); i ++) { client_buffer[i] = '\0'; } } break; case 12: /* CTRL-L */ if(!is_lurking) { redrawwin(lurk_win); wrefresh(lurk_win); is_lurking = 1; } break; case 14: /* CTRL-N */ alarm(5); user_is_scrolling = 1; transcript_current_line ++; window_page_down( transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS, transcript_buffer ); window_page_down( fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer ); break; case 16: /* CTRL-P */ alarm(5); user_is_scrolling = 1; transcript_current_line --; window_page_up( transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS, transcript_buffer ); window_page_up( fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer ); break; case 17: /* CTRL-Q */ log_writeln(" > ... recived quit signal from client"); is_running = 0; break; case 20: /* CTRL-T */ if(transcript_maxed) { transcript_maxed = 0; window_page_up(transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS, transcript_buffer); wclear(fullscreen_transcript_window); wrefresh(fullscreen_transcript_window); } else { transcript_maxed = 1; window_page_up(fullscreen_transcript_window, &transcript_current_line, TRANSCRIPT_MAX_COLUMNS*2, f_transcript_buffer); wclear(transcript_window); wrefresh(transcript_window); } break; case 21: /* CTRL-U */ client_current_line = 0; client_cursor_position = 0; memset(client_buffer, '\0', wcslen(client_buffer)+1); print_client_chat_buffer(); break; case 23: /* CTRL-W */ delete_last_word_in_buffer(client_buffer); print_client_chat_buffer(); break; case 25: /* CTRL-Y */ { if(!is_yelling) { redrawwin(yell_win); wrefresh(yell_win); is_yelling = 1; } } break; case 29: /* CTRL-] */ alarm(0); user_is_scrolling = 0; print_transcript_chat_buffer(); break; case 30: /* CTRL-6 */ if(!in_deepsix) { draw_deepsix_window(); in_deepsix = 1; } break; /* * If we encountered an unkown escape wchar_tcter, break out of here so we don't * print it. */ break; /* TODO: Fix me! */ } #if 0 /* Scroll the clients typing window down. */ case KEY_DOWN: client_current_line ++; if(client_current_line*MAX_COLUMNS > wcslen(client_buffer)) client_current_line --; wclear(client_chat_window); wprintw(client_chat_window, &client_buffer[client_current_line*MAX_COLUMNS]); break; /* Scroll the clients typing window up. */ case KEY_UP: client_current_line --; if(client_current_line < 0) client_current_line = 0; wclear(client_chat_window); wprintw(client_chat_window, &client_buffer[client_current_line*MAX_COLUMNS]); break; #endif /* Delete the previous chracter. */ case KEY_BACKSPACE: /* Check if were deleting the last wchar_tacter. */ if( client_cursor_position == wcslen(client_buffer) ) { client_buffer[ client_cursor_position-1 ] = '\0'; client_cursor_position --; print_client_chat_buffer(); } else { /* If were here, that means were NOT deleting the last wchar_tacter. */ int i; for(i = client_cursor_position-1; i < wcslen(client_buffer); i ++) { client_buffer[i] = client_buffer[i+1]; } client_cursor_position --; print_client_chat_buffer(); } break; /* If were here, that means we didn't press any "special" keys so that means were * trying to write some generic wchar_tacters to our chat window. */ default: /* Make sure we don't print a control wchar_tacter. */ if(!iscntrl(ch)) { /* Check if were inserting a wchar_tacter before the end of our client * typing buffer. */ if( client_cursor_position != wcslen(client_buffer) ) { /* Move all wchar_tacters in front of the cursor up one. */ int i; for(i = wcslen(client_buffer)+1; i > client_cursor_position; i --) { client_buffer[i] = client_buffer[i-1]; } } /* Add the wchar_tacter to our buffer. */ client_buffer[ client_cursor_position++ ] = ch; /* Print our new/updated buffer. */ print_client_chat_buffer(); break; } } } /* Read from the server. */ /* josh-note Uncomment this! */ /* read_from_server(client_id); */ refresh_all_windows(is_lurking); } log_writeln(" > ... [ending transcript]"); log_writeln(" > ... freeing resources"); free_other_windows(); free(transcript_buffer); delwin(transcript_window); delwin(fullscreen_transcript_window); delwin(client_chat_window); delwin(status_win); delwin(info_win); delwin(im_win); delwin(deepsix_win); delwin(yell_win); endwin(); /* josh-note This should be uncommented to close down the client socket. */ /* close_client(client_id); */ log_writeln(" > ... closing client log"); log_writeln(" > ... bye bye for now!"); log_close(); return 0; }
/* layman's scrollable window... */ void show_scroll_win(WINDOW *main_window, const char *title, const char *text) { int res; int total_lines = get_line_no(text); int x, y; int start_x = 0, start_y = 0; int text_lines = 0, text_cols = 0; int total_cols = 0; int win_cols = 0; int win_lines = 0; int i = 0; WINDOW *win; WINDOW *pad; PANEL *panel; /* find the widest line of msg: */ total_lines = get_line_no(text); for (i = 0; i < total_lines; i++) { const char *line = get_line(text, i); int len = get_line_length(line); total_cols = max(total_cols, len+2); } /* create the pad */ pad = newpad(total_lines+10, total_cols+10); wattrset(pad, attributes[SCROLLWIN_TEXT]); fill_window(pad, text); win_lines = min(total_lines+4, LINES-2); win_cols = min(total_cols+2, COLS-2); text_lines = max(win_lines-4, 0); text_cols = max(win_cols-2, 0); /* place window in middle of screen */ y = (LINES-win_lines)/2; x = (COLS-win_cols)/2; win = newwin(win_lines, win_cols, y, x); keypad(win, TRUE); /* show the help in the help window, and show the help panel */ wattrset(win, attributes[SCROLLWIN_BOX]); box(win, 0, 0); wattrset(win, attributes[SCROLLWIN_HEADING]); mvwprintw(win, 0, 3, " %s ", title); panel = new_panel(win); /* handle scrolling */ do { copywin(pad, win, start_y, start_x, 2, 2, text_lines, text_cols, 0); print_in_middle(win, text_lines+2, 0, text_cols, "<OK>", attributes[DIALOG_MENU_FORE]); wrefresh(win); res = wgetch(win); switch (res) { case KEY_NPAGE: case ' ': start_y += text_lines-2; break; case KEY_PPAGE: start_y -= text_lines+2; break; case KEY_HOME: start_y = 0; break; case KEY_END: start_y = total_lines-text_lines; break; case KEY_DOWN: case 'j': start_y++; break; case KEY_UP: case 'k': start_y--; break; case KEY_LEFT: case 'h': start_x--; break; case KEY_RIGHT: case 'l': start_x++; break; } if (res == 10 || res == 27 || res == 'q' || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { break; } if (start_y < 0) start_y = 0; if (start_y >= total_lines-text_lines) start_y = total_lines-text_lines; if (start_x < 0) start_x = 0; if (start_x >= total_cols-text_cols) start_x = total_cols-text_cols; } while (res); del_panel(panel); delwin(win); refresh_all_windows(main_window); }
int dialog_inputbox(WINDOW *main_window, const char *title, const char *prompt, const char *init, char *result, int result_len) { int prompt_lines = 0; int prompt_width = 0; WINDOW *win; WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; int i, x, y; int res = -1; int cursor_position = strlen(init); /* find the widest line of msg: */ prompt_lines = get_line_no(prompt); for (i = 0; i < prompt_lines; i++) { const char *line = get_line(prompt, i); int len = get_line_length(line); prompt_width = max(prompt_width, len); } if (title) prompt_width = max(prompt_width, strlen(title)); /* place dialog in middle of screen */ y = (LINES-(prompt_lines+4))/2; x = (COLS-(prompt_width+4))/2; strncpy(result, init, result_len); /* create the windows */ win = newwin(prompt_lines+6, prompt_width+7, y, x); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); wattrset(form_win, attributes[INPUT_FIELD]); wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result); /* create panels */ panel = new_panel(win); /* show the cursor */ curs_set(1); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(form_win))) { int len = strlen(result); switch (res) { case 10: /* ENTER */ case 27: /* ESCAPE */ case KEY_F(F_HELP): case KEY_F(F_EXIT): case KEY_F(F_BACK): break; case 127: case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], &result[cursor_position], len-cursor_position+1); cursor_position--; } break; case KEY_DC: if (cursor_position >= 0 && cursor_position < len) { memmove(&result[cursor_position], &result[cursor_position+1], len-cursor_position+1); } break; case KEY_UP: case KEY_RIGHT: if (cursor_position < len && cursor_position < min(result_len, prompt_width)) cursor_position++; break; case KEY_DOWN: case KEY_LEFT: if (cursor_position > 0) cursor_position--; break; default: if ((isgraph(res) || isspace(res)) && len-2 < result_len) { /* insert the char at the proper position */ memmove(&result[cursor_position+1], &result[cursor_position], len+1); result[cursor_position] = res; cursor_position++; } else { mvprintw(0, 0, "unknow key: %d\n", res); } break; } wmove(form_win, 0, 0); wclrtoeol(form_win); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result); wmove(form_win, 0, cursor_position); touchwin(win); refresh_all_windows(main_window); if (res == 10) { res = 0; break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } else if (res == KEY_F(F_HELP)) { res = 1; break; } } /* hide the cursor */ curs_set(0); del_panel(panel); delwin(prompt_win); delwin(form_win); delwin(win); return res; }
int btn_dialog(WINDOW *main_window, const char *msg, int btn_num, ...) { va_list ap; char *btn; int btns_width = 0; int msg_lines = 0; int msg_width = 0; int total_width; int win_rows = 0; WINDOW *win; WINDOW *msg_win; WINDOW *menu_win; MENU *menu; ITEM *btns[btn_num+1]; int i, x, y; int res = -1; va_start(ap, btn_num); for (i = 0; i < btn_num; i++) { btn = va_arg(ap, char *); btns[i] = new_item(btn, ""); btns_width += strlen(btn)+1; } va_end(ap); btns[btn_num] = NULL; /* find the widest line of msg: */ msg_lines = get_line_no(msg); for (i = 0; i < msg_lines; i++) { const char *line = get_line(msg, i); int len = get_line_length(line); if (msg_width < len) msg_width = len; } total_width = max(msg_width, btns_width); /* place dialog in middle of screen */ y = (LINES-(msg_lines+4))/2; x = (COLS-(total_width+4))/2; /* create the windows */ if (btn_num > 0) win_rows = msg_lines+4; else win_rows = msg_lines+2; win = newwin(win_rows, total_width+4, y, x); keypad(win, TRUE); menu_win = derwin(win, 1, btns_width, win_rows-2, 1+(total_width+2-btns_width)/2); menu = new_menu(btns); msg_win = derwin(win, win_rows-2, msg_width, 1, 1+(total_width+2-msg_width)/2); set_menu_fore(menu, attributes[DIALOG_MENU_FORE]); set_menu_back(menu, attributes[DIALOG_MENU_BACK]); wattrset(win, attributes[DIALOG_BOX]); box(win, 0, 0); /* print message */ wattrset(msg_win, attributes[DIALOG_TEXT]); fill_window(msg_win, msg); set_menu_win(menu, win); set_menu_sub(menu, menu_win); set_menu_format(menu, 1, btn_num); menu_opts_off(menu, O_SHOWDESC); menu_opts_off(menu, O_SHOWMATCH); menu_opts_on(menu, O_ONEVALUE); menu_opts_on(menu, O_NONCYCLIC); set_menu_mark(menu, ""); post_menu(menu); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(win))) { switch (res) { case KEY_LEFT: menu_driver(menu, REQ_LEFT_ITEM); break; case KEY_RIGHT: menu_driver(menu, REQ_RIGHT_ITEM); break; case 10: /* ENTER */ case 27: /* ESCAPE */ case ' ': case KEY_F(F_BACK): case KEY_F(F_EXIT): break; } touchwin(win); refresh_all_windows(main_window); if (res == 10 || res == ' ') { res = item_index(current_item(menu)); break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } } unpost_menu(menu); free_menu(menu); for (i = 0; i < btn_num; i++) free_item(btns[i]); delwin(win); return res; }
int dialog_inputbox(WINDOW *main_window, const char *title, const char *prompt, const char *init, char **resultp, int *result_len) { int prompt_lines = 0; int prompt_width = 0; WINDOW *win; WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; int i, x, y; int res = -1; int cursor_position = strlen(init); int cursor_form_win; char *result = *resultp; if (strlen(init)+1 > *result_len) { *result_len = strlen(init)+1; *resultp = result = realloc(result, *result_len); } prompt_lines = get_line_no(prompt); for (i = 0; i < prompt_lines; i++) { const char *line = get_line(prompt, i); int len = get_line_length(line); prompt_width = max(prompt_width, len); } if (title) prompt_width = max(prompt_width, strlen(title)); y = (LINES-(prompt_lines+4))/2; x = (COLS-(prompt_width+4))/2; strncpy(result, init, *result_len); win = newwin(prompt_lines+6, prompt_width+7, y, x); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); (void) wattrset(form_win, attributes[INPUT_FIELD]); (void) wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); (void) wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); (void) wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); cursor_form_win = min(cursor_position, prompt_width-1); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); panel = new_panel(win); curs_set(1); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(form_win))) { int len = strlen(result); switch (res) { case 10: case 27: case KEY_F(F_HELP): case KEY_F(F_EXIT): case KEY_F(F_BACK): break; case 127: case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], &result[cursor_position], len-cursor_position+1); cursor_position--; cursor_form_win--; len--; } break; case KEY_DC: if (cursor_position >= 0 && cursor_position < len) { memmove(&result[cursor_position], &result[cursor_position+1], len-cursor_position+1); len--; } break; case KEY_UP: case KEY_RIGHT: if (cursor_position < len) { cursor_position++; cursor_form_win++; } break; case KEY_DOWN: case KEY_LEFT: if (cursor_position > 0) { cursor_position--; cursor_form_win--; } break; case KEY_HOME: cursor_position = 0; cursor_form_win = 0; break; case KEY_END: cursor_position = len; cursor_form_win = min(cursor_position, prompt_width-1); break; default: if ((isgraph(res) || isspace(res))) { if (len+2 > *result_len) { *result_len = len+2; *resultp = result = realloc(result, *result_len); } memmove(&result[cursor_position+1], &result[cursor_position], len-cursor_position+1); result[cursor_position] = res; cursor_position++; cursor_form_win++; len++; } else { mvprintw(0, 0, "unknown key: %d\n", res); } break; } if (cursor_form_win < 0) cursor_form_win = 0; else if (cursor_form_win > prompt_width-1) cursor_form_win = prompt_width-1; wmove(form_win, 0, 0); wclrtoeol(form_win); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); wmove(form_win, 0, cursor_form_win); touchwin(win); refresh_all_windows(main_window); if (res == 10) { res = 0; break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } else if (res == KEY_F(F_HELP)) { res = 1; break; } } curs_set(0); del_panel(panel); delwin(prompt_win); delwin(form_win); delwin(win); return res; }
int dialog_inputbox(WINDOW *main_window, const char *title, const char *prompt, const char *init, char **resultp, int *result_len) { int prompt_lines = 0; int prompt_width = 0; WINDOW *win; WINDOW *prompt_win; WINDOW *form_win; PANEL *panel; int i, x, y, lines, columns, win_lines, win_cols; int res = -1; int cursor_position = strlen(init); int cursor_form_win; char *result = *resultp; getmaxyx(stdscr, lines, columns); if (strlen(init)+1 > *result_len) { *result_len = strlen(init)+1; *resultp = result = realloc(result, *result_len); } /* find the widest line of msg: */ prompt_lines = get_line_no(prompt); for (i = 0; i < prompt_lines; i++) { const char *line = get_line(prompt, i); int len = get_line_length(line); prompt_width = max(prompt_width, len); } if (title) prompt_width = max(prompt_width, strlen(title)); win_lines = min(prompt_lines+6, lines-2); win_cols = min(prompt_width+7, columns-2); prompt_lines = max(win_lines-6, 0); prompt_width = max(win_cols-7, 0); /* place dialog in middle of screen */ y = (lines-win_lines)/2; x = (columns-win_cols)/2; strncpy(result, init, *result_len); /* create the windows */ win = newwin(win_lines, win_cols, y, x); prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2); form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2); keypad(form_win, TRUE); (void) wattrset(form_win, attributes[INPUT_FIELD]); (void) wattrset(win, attributes[INPUT_BOX]); box(win, 0, 0); (void) wattrset(win, attributes[INPUT_HEADING]); if (title) mvwprintw(win, 0, 3, "%s", title); /* print message */ (void) wattrset(prompt_win, attributes[INPUT_TEXT]); fill_window(prompt_win, prompt); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); cursor_form_win = min(cursor_position, prompt_width-1); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); /* create panels */ panel = new_panel(win); /* show the cursor */ curs_set(1); touchwin(win); refresh_all_windows(main_window); while ((res = wgetch(form_win))) { int len = strlen(result); switch (res) { case 10: /* ENTER */ case 27: /* ESCAPE */ case KEY_F(F_HELP): case KEY_F(F_EXIT): case KEY_F(F_BACK): break; case 127: case KEY_BACKSPACE: if (cursor_position > 0) { memmove(&result[cursor_position-1], &result[cursor_position], len-cursor_position+1); cursor_position--; cursor_form_win--; len--; } break; case KEY_DC: if (cursor_position >= 0 && cursor_position < len) { memmove(&result[cursor_position], &result[cursor_position+1], len-cursor_position+1); len--; } break; case KEY_UP: case KEY_RIGHT: if (cursor_position < len) { cursor_position++; cursor_form_win++; } break; case KEY_DOWN: case KEY_LEFT: if (cursor_position > 0) { cursor_position--; cursor_form_win--; } break; case KEY_HOME: cursor_position = 0; cursor_form_win = 0; break; case KEY_END: cursor_position = len; cursor_form_win = min(cursor_position, prompt_width-1); break; default: if ((isgraph(res) || isspace(res))) { /* one for new char, one for '\0' */ if (len+2 > *result_len) { *result_len = len+2; *resultp = result = realloc(result, *result_len); } /* insert the char at the proper position */ memmove(&result[cursor_position+1], &result[cursor_position], len-cursor_position+1); result[cursor_position] = res; cursor_position++; cursor_form_win++; len++; } else { mvprintw(0, 0, "unknown key: %d\n", res); } break; } if (cursor_form_win < 0) cursor_form_win = 0; else if (cursor_form_win > prompt_width-1) cursor_form_win = prompt_width-1; wmove(form_win, 0, 0); wclrtoeol(form_win); mvwprintw(form_win, 0, 0, "%*s", prompt_width, " "); mvwprintw(form_win, 0, 0, "%s", result + cursor_position-cursor_form_win); wmove(form_win, 0, cursor_form_win); touchwin(win); refresh_all_windows(main_window); if (res == 10) { res = 0; break; } else if (res == 27 || res == KEY_F(F_BACK) || res == KEY_F(F_EXIT)) { res = KEY_EXIT; break; } else if (res == KEY_F(F_HELP)) { res = 1; break; } } /* hide the cursor */ curs_set(0); del_panel(panel); delwin(prompt_win); delwin(form_win); delwin(win); return res; }