static void test_redraw(WINDOW *win) { static const char *help[] = { "Commands:", " ^Q/ESC/q - quit", " w - recur in a new window", " ! - overwrite current line using stdio outside curses.", #ifdef NCURSES_VERSION " @ - run \"date\" command, to put its output on screen.", #endif " ^L - call redrawwin() for current window.", " ^W - call wredrawln() for current line/current window.", " arrow-keys - move cursor on the screen", "", "Other control characters are added to the screen in printable form.", "Other printable characters are added to the screen as is.", 0 }; WINDOW *win1; WINDOW *win2; bool done = FALSE; int ch, y, x; int max_y, max_x; int beg_y, beg_x; assert(win != 0); scrollok(win, TRUE); keypad(win, TRUE); getmaxyx(win, max_y, max_x); getbegyx(win, beg_y, beg_x); while (!done) { ch = wgetch(win); getyx(win, y, x); switch (ch) { case 'q': /* FALLTHRU */ case QUIT: case ESCAPE: done = TRUE; break; case 'w': win1 = newwin(max_y, max_x, beg_y, beg_x); win2 = newwin(max_y - 2, max_x - 2, beg_y + 1, beg_x + 1); box(win1, 0, 0); wrefresh(win1); test_redraw(win2); delwin(win2); delwin(win1); touchwin(win); break; case '!': /* * redrawwin() and wredrawln() do not take into account the * possibility that the cursor may have moved. That makes them * cumbersome for using with a shell command. So we simply * trash the current line of the window using backspace/overwrite. */ trash(beg_x, max_x, x + beg_x); break; #ifdef NCURSES_VERSION case '@': /* * For a shell command, we can work around the problem noted above * using mvcur(). It is ifdef'd for NCURSES, since X/Open does * not define the case where the old location is unknown. */ IGNORE_RC(system("date")); mvcur(-1, -1, y, x); break; #endif case CTRL('W'): redrawwin(win); break; case CTRL('L'): wredrawln(win, y, 1); break; case KEY_UP: if (y > 0) wmove(win, y - 1, x); break; case KEY_DOWN: if (y < max_y) wmove(win, y + 1, x); break; case KEY_LEFT: if (x > 0) wmove(win, y, x - 1); break; case KEY_RIGHT: if (x < max_x) wmove(win, y, x + 1); break; case HELP_KEY_1: popup_msg(win, help); break; default: if (ch > KEY_MIN) { waddstr(win, keyname(ch)); waddch(win, '\n'); } else { waddstr(win, unctrl(UChar(ch))); } break; } wnoutrefresh(win); doupdate(); } }
/* * Display text from a file in a dialog box. */ int dialog_textbox(const char *title, const char *file, int height, int width) { /* *INDENT-OFF* */ static DLG_KEYS_BINDING binding[] = { HELPKEY_BINDINGS, ENTERKEY_BINDINGS, DLG_KEYS_DATA( DLGK_GRID_DOWN, 'J' ), DLG_KEYS_DATA( DLGK_GRID_DOWN, 'j' ), DLG_KEYS_DATA( DLGK_GRID_DOWN, KEY_DOWN ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'H' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, 'h' ), DLG_KEYS_DATA( DLGK_GRID_LEFT, KEY_LEFT ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'L' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ), DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ), DLG_KEYS_DATA( DLGK_GRID_UP, 'K' ), DLG_KEYS_DATA( DLGK_GRID_UP, 'k' ), DLG_KEYS_DATA( DLGK_GRID_UP, KEY_UP ), DLG_KEYS_DATA( DLGK_PAGE_FIRST, 'g' ), DLG_KEYS_DATA( DLGK_PAGE_FIRST, KEY_HOME ), DLG_KEYS_DATA( DLGK_PAGE_LAST, 'G' ), DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_END ), DLG_KEYS_DATA( DLGK_PAGE_LAST, KEY_LL ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, ' ' ), DLG_KEYS_DATA( DLGK_PAGE_NEXT, KEY_NPAGE ), DLG_KEYS_DATA( DLGK_PAGE_PREV, 'B' ), DLG_KEYS_DATA( DLGK_PAGE_PREV, 'b' ), DLG_KEYS_DATA( DLGK_PAGE_PREV, KEY_PPAGE ), DLG_KEYS_DATA( DLGK_BEGIN, '0' ), DLG_KEYS_DATA( DLGK_BEGIN, KEY_BEG ), DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), END_KEYS_BINDING }; /* *INDENT-ON* */ #ifdef KEY_RESIZE int old_height = height; int old_width = width; #endif long fpos; int x, y, cur_x, cur_y; int key = 0, fkey; int next = 0; int i, code, passed_end; char search_term[MAX_LEN + 1]; MY_OBJ obj; WINDOW *dialog; bool moved; int result = DLG_EXIT_UNKNOWN; int button = dlg_default_button(); int min_width = 12; search_term[0] = '\0'; /* no search term entered yet */ memset(&obj, 0, sizeof(obj)); obj.begin_reached = TRUE; obj.buffer_first = TRUE; obj.end_reached = FALSE; obj.buttons = dlg_exit_label(); /* Open input file for reading */ if ((obj.fd = open(file, O_RDONLY)) == -1) dlg_exiterr("Can't open input file %s", file); /* Get file size. Actually, 'file_size' is the real file size - 1, since it's only the last byte offset from the beginning */ lseek_end(&obj, 0L); /* Restore file pointer to beginning of file after getting file size */ lseek_set(&obj, 0L); read_high(&obj, BUF_SIZE); dlg_button_layout(obj.buttons, &min_width); #ifdef KEY_RESIZE retry: #endif moved = TRUE; dlg_auto_sizefile(title, file, &height, &width, 2, min_width); dlg_print_size(height, width); dlg_ctl_size(height, width); x = dlg_box_x_ordinate(width); y = dlg_box_y_ordinate(height); dialog = dlg_new_window(height, width, y, x); dlg_register_window(dialog, "textbox", binding); dlg_register_buttons(dialog, "textbox", obj.buttons); dlg_mouse_setbase(x, y); /* Create window for text region, used for scrolling text */ obj.text = dlg_sub_window(dialog, PAGE_LENGTH, PAGE_WIDTH, y + 1, x + 1); /* register the new window, along with its borders */ dlg_mouse_mkbigregion(0, 0, PAGE_LENGTH + 2, width, KEY_MAX, 1, 1, 1 /* lines */ ); dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); dlg_draw_title(dialog, title); dlg_draw_buttons(dialog, PAGE_LENGTH + 2, 0, obj.buttons, button, FALSE, width); (void) wnoutrefresh(dialog); getyx(dialog, cur_y, cur_x); /* Save cursor position */ dlg_attr_clear(obj.text, PAGE_LENGTH, PAGE_WIDTH, dialog_attr); while (result == DLG_EXIT_UNKNOWN) { /* * Update the screen according to whether we shifted up/down by a line * or not. */ if (moved) { if (next < 0) { (void) scrollok(obj.text, TRUE); (void) scroll(obj.text); /* Scroll text region up one line */ (void) scrollok(obj.text, FALSE); print_line(&obj, PAGE_LENGTH - 1, PAGE_WIDTH); (void) wnoutrefresh(obj.text); } else if (next > 0) { /* * We don't call print_page() here but use scrolling to ensure * faster screen update. However, 'end_reached' and * 'page_length' should still be updated, and 'in_buf' should * point to start of next page. This is done by calling * get_line() in the following 'for' loop. */ (void) scrollok(obj.text, TRUE); (void) wscrl(obj.text, -1); /* Scroll text region down one line */ (void) scrollok(obj.text, FALSE); obj.page_length = 0; passed_end = 0; for (i = 0; i < PAGE_LENGTH; i++) { if (!i) { print_line(&obj, 0, PAGE_WIDTH); /* print first line of page */ (void) wnoutrefresh(obj.text); } else (void) get_line(&obj); /* Called to update 'end_reached' and 'in_buf' */ if (!passed_end) obj.page_length++; if (obj.end_reached && !passed_end) passed_end = 1; } } else { print_page(&obj, PAGE_LENGTH, PAGE_WIDTH); } print_position(&obj, dialog, height, width); (void) wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } moved = FALSE; /* assume we'll not move */ next = 0; /* ...but not scroll by a line */ key = dlg_mouse_wgetch(dialog, &fkey); if (dlg_result_key(key, fkey, &result)) break; if (!fkey && (code = dlg_char_to_button(key, obj.buttons)) >= 0) { result = dlg_ok_buttoncode(code); break; } if (fkey) { switch (key) { default: if (is_DLGK_MOUSE(key)) { result = dlg_exit_buttoncode(key - M_EVENT); if (result < 0) result = DLG_EXIT_OK; } else { beep(); } break; case DLGK_FIELD_NEXT: button = dlg_next_button(obj.buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, obj.buttons, button, FALSE, width); break; case DLGK_FIELD_PREV: button = dlg_prev_button(obj.buttons, button); if (button < 0) button = 0; dlg_draw_buttons(dialog, height - 2, 0, obj.buttons, button, FALSE, width); break; case DLGK_ENTER: if (dialog_vars.nook) result = DLG_EXIT_OK; else result = dlg_exit_buttoncode(button); break; case DLGK_PAGE_FIRST: if (!obj.begin_reached) { obj.begin_reached = 1; /* First page not in buffer? */ fpos = ftell_obj(&obj); if (fpos > obj.fd_bytes_read) { /* Yes, we have to read it in */ lseek_set(&obj, 0L); read_high(&obj, BUF_SIZE); } obj.in_buf = 0; moved = TRUE; } break; case DLGK_PAGE_LAST: obj.end_reached = TRUE; /* Last page not in buffer? */ fpos = ftell_obj(&obj); if (fpos < obj.file_size) { /* Yes, we have to read it in */ lseek_end(&obj, -BUF_SIZE); read_high(&obj, BUF_SIZE); } obj.in_buf = obj.bytes_read; back_lines(&obj, (long) PAGE_LENGTH); moved = TRUE; break; case DLGK_GRID_UP: /* Previous line */ if (!obj.begin_reached) { back_lines(&obj, obj.page_length + 1); next = 1; moved = TRUE; } break; case DLGK_PAGE_PREV: /* Previous page */ case DLGK_MOUSE(KEY_PPAGE): if (!obj.begin_reached) { back_lines(&obj, obj.page_length + PAGE_LENGTH); moved = TRUE; } break; case DLGK_GRID_DOWN: /* Next line */ if (!obj.end_reached) { obj.begin_reached = 0; next = -1; moved = TRUE; } break; case DLGK_PAGE_NEXT: /* Next page */ case DLGK_MOUSE(KEY_NPAGE): if (!obj.end_reached) { obj.begin_reached = 0; moved = TRUE; } break; case DLGK_BEGIN: /* Beginning of line */ if (obj.hscroll > 0) { obj.hscroll = 0; /* Reprint current page to scroll horizontally */ back_lines(&obj, obj.page_length); moved = TRUE; } break; case DLGK_GRID_LEFT: /* Scroll left */ if (obj.hscroll > 0) { obj.hscroll--; /* Reprint current page to scroll horizontally */ back_lines(&obj, obj.page_length); moved = TRUE; } break; case DLGK_GRID_RIGHT: /* Scroll right */ if (obj.hscroll < MAX_LEN) { obj.hscroll++; /* Reprint current page to scroll horizontally */ back_lines(&obj, obj.page_length); moved = TRUE; } break; #ifdef KEY_RESIZE case KEY_RESIZE: /* reset data */ height = old_height; width = old_width; back_lines(&obj, obj.page_length); /* repaint */ dlg_clear(); dlg_del_window(dialog); refresh(); dlg_mouse_free_regions(); goto retry; #endif } } else { switch (key) { case '/': /* Forward search */ case 'n': /* Repeat forward search */ case '?': /* Backward search */ case 'N': /* Repeat backward search */ moved = perform_search(&obj, height, width, key, search_term); fkey = FALSE; break; default: beep(); break; } } } dlg_del_window(dialog); free(obj.buf); (void) close(obj.fd); dlg_mouse_free_regions(); return result; }
static ship_t * hitship(int x, int y) /* register a hit on the targeted ship */ { ship_t *sb, *ss; char sym; int oldx, oldy; getyx(stdscr, oldy, oldx); sb = (turn) ? plyship : cpuship; if ((sym = board[OTHER][x][y]) == 0) return ((ship_t *) NULL); for (ss = sb; ss < sb + SHIPTYPES; ++ss) if (ss->symbol == sym) { if (++ss->hits < ss->length) /* still afloat? */ return ((ship_t *) NULL); else { /* sunk! */ int i, j; if (!closepack) for (j = -1; j <= 1; j++) { int bx = ss->x + j * xincr[(ss->dir + 2) % 8]; int by = ss->y + j * yincr[(ss->dir + 2) % 8]; for (i = -1; i <= ss->length; ++i) { int x1, y1; x1 = bx + i * xincr[ss->dir]; y1 = by + i * yincr[ss->dir]; if (ONBOARD(x1, y1)) { hits[turn][x1][y1] = MARK_MISS; if (turn % 2 == PLAYER) { cgoto(y1, x1); #ifdef A_COLOR if (has_colors()) attron(COLOR_PAIR(COLOR_GREEN)); #endif /* A_COLOR */ (void) addch(MARK_MISS); #ifdef A_COLOR attrset(0); #endif /* A_COLOR */ } else { pgoto(y1, x1); (void) addch(SHOWSPLASH); } } } } for (i = 0; i < ss->length; ++i) { int x1 = ss->x + i * xincr[ss->dir]; int y1 = ss->y + i * yincr[ss->dir]; hits[turn][x1][y1] = ss->symbol; if (turn % 2 == PLAYER) { cgoto(y1, x1); (void) addch((chtype) (ss->symbol)); } else { pgoto(y1, x1); #ifdef A_COLOR if (has_colors()) attron(COLOR_PAIR(COLOR_RED)); #endif /* A_COLOR */ (void) addch(SHOWHIT); #ifdef A_COLOR attrset(0); #endif /* A_COLOR */ } } (void) move(oldy, oldx); return (ss); } } (void) move(oldy, oldx); return ((ship_t *) NULL); }
void main() { int x, y, c; struct timer_wait tw; int led_status = LOW; // Default screen resolution (set in config.txt or auto-detected) //fb_init(0, 0); // Sets a specific screen resolution fb_init(32 + 320 + 32, 32 + 200 + 32); fb_fill_rectangle(0, 0, fb_width - 1, fb_height - 1, BORDER_COLOR); initscr(40, 25); cur_fore = WHITE; cur_back = BACKGROUND_COLOR; clear(); mvaddstr(1, 9, "**** RASPBERRY-PI ****"); mvaddstr(3, 7, "BARE-METAL SYSTEM TEMPLATE\r\n"); if (mount("sd:") != 0) { addstrf("\r\nSD CARD NOT MOUNTED (%s)\r\n", strerror(errno)); } usb_init(); if (keyboard_init() != 0) { addstr("\r\nNO KEYBOARD DETECTED\r\n"); } pinMode(16, OUTPUT); register_timer(&tw, 250000); addstr("\r\nREADY\r\n"); while(1) { if ((c = getch()) != -1) { switch(c) { case KEY_UP: getyx(y, x); move(y - 1, x); break; case KEY_DOWN: getyx(y, x); move(y + 1, x); break; case KEY_LEFT: getyx(y, x); x--; if (x < 0) { x = 39; y--; } move(y, x); break; case KEY_RIGHT: getyx(y, x); x++; if (x >= 40) { x = 0; y++; } move(y, x); break; case KEY_HOME: getyx(y, x); move(y, 0); break; case KEY_PGUP: move(0, 0); break; case '\r': addch(c); addch('\n'); break; default: if (c < 0x7F) { addch(c); } break; } } if (compare_timer(&tw)) { led_status = led_status == LOW ? HIGH : LOW; digitalWrite(16, led_status); toggle_cursor(); } refresh(); } }
int get_reply_to_post(infostruct user,char *reply, char *sno){ WINDOW *send_reply; WINDOW *msgwind; char conf; int retval = 2; int x,y; char *header = "*** Send A Reply ***"; int i = 0; char *screen_name; double message_id; char *message; screen_name = (char *)malloc(25 * sizeof(char)); if(screen_name == NULL){ return 1; } /* i dont need this here.. needed in the retweet */ message = (char *)malloc(140 * sizeof(char)); if(message == NULL){ return 1; } echo(); cbreak(); send_reply = newwin(10,80,user.row/2, (user.col - 80)/2); keypad(send_reply,TRUE); msgwind = derwin(send_reply,5,50,4,5 + strlen("Enter reply: ")); keypad(msgwind,TRUE); box(send_reply,0,0); wattron(send_reply,A_BOLD); mvwprintw(send_reply,2,(getmaxx(send_reply) -strlen(header))/2,"%s",header); wattroff(send_reply,A_BOLD); mvwprintw(send_reply,4,5,"%s","Reply to sno :"); wrefresh(send_reply); wscanw(send_reply,"%s",sno); if((message_id = get_message_id(0,sno,&screen_name,&message)) == 1) return 1; mvwprintw(send_reply,4,5,"%s","Enter reply: "); noecho(); wrefresh(send_reply); getyx(send_reply,y,x); touchwin(send_reply); mvwprintw(msgwind,0,0,"@%s " ,screen_name); wrefresh(msgwind); while (1){ int k; if(i > (140 - (int)strlen(screen_name) -2)) wattron(send_reply,COLOR_PAIR(2)); mvwprintw(send_reply,8,76," "); mvwprintw(send_reply,8,76,"%i",140 - strlen(screen_name) - 2 -i); if(i > (140 - (int)strlen(screen_name) -2)) wattroff(send_reply,COLOR_PAIR(2)); wrefresh(send_reply); wrefresh(msgwind); k = wgetch(msgwind); if(k == '\n') break; if ((k == KEY_BACKSPACE) && i > 0){ getyx(msgwind,y,x); /* if on 1st of line 2, please go back to the last of line 1*/ if((i + strlen(screen_name) + 2) == 50){ mvwaddch(msgwind,y-1,49,' '); wmove(msgwind,y-1,49); } else if((i + strlen(screen_name) + 2) == 100){ mvwaddch(msgwind,y-1,49,' '); wmove(msgwind,y-1,49); } else if((i + strlen(screen_name) + 2 ) == 150){ mvwaddch(msgwind,y-1,49,' '); wmove(msgwind,y-1,49); } else { mvwaddch(msgwind,y,x -1,' '); wmove(msgwind,y,x-1); } i = i-1; } else { /* if its at 0 and i press a bcakspace, i dont want anything to happen, without the if, it was printing ^G etc */ if(k != KEY_BACKSPACE){ reply[i] = k; waddch(msgwind,reply[i]); i++; } } } reply[i+1] = '\0'; wrefresh(send_reply); echo(); getyx(send_reply,y,x); mvwprintw(send_reply,getmaxy(send_reply)- 2,5,"%s","Send? [y/N]"); wrefresh(send_reply); do { conf = wgetch(send_reply); if(conf == 'Y' || conf == 'y') retval = 0; else if (conf == 'N' || conf == 'n') retval = 1; }while(conf != 'y' && conf != 'Y' && conf != 'N' && conf != 'n'); noecho(); refresh(); delwin(send_reply); return retval; }
static void wrap_gety(void* ret, void* const* args) { int x, y; getyx(stdscr, y, x); *(int*)ret = y; }
/* * Display a dialog box with a list of options that can be turned on or off * The `flag' parameter is used to select between radiolist and checklist. */ int dialog_checklist(const char *title, const char *cprompt, int height, int width, int list_height, int item_no, char **items, int flag, int separate_output) { int i, j, key2, found, x, y, cur_x, cur_y, box_x, box_y; int key = 0, fkey; int button = 0; int choice = 0; int scrollamt = 0; int max_choice, *status; int use_width, name_width, text_width; int result = DLG_EXIT_UNKNOWN; WINDOW *dialog, *list; char *prompt = strclone(cprompt); const char **buttons = dlg_ok_labels(); tab_correct_str(prompt); if (list_height == 0) { use_width = calc_listw(item_no, items, CHECKBOX_TAGS) + 10; /* calculate height without items (4) */ auto_size(title, prompt, &height, &width, 4, MAX(26, use_width)); calc_listh(&height, &list_height, item_no); } else { auto_size(title, prompt, &height, &width, 4 + list_height, 26); } print_size(height, width); ctl_size(height, width); checkflag = flag; /* Allocate space for storing item on/off status */ status = malloc(sizeof(int) * item_no); assert_ptr(status, "dialog_checklist"); /* Initializes status */ for (i = 0; i < item_no; i++) status[i] = !dlg_strcmp(ItemStatus(i), "on"); max_choice = MIN(list_height, item_no); x = box_x_ordinate(width); y = box_y_ordinate(height); dialog = new_window(height, width, y, x); mouse_setbase(x, y); draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); draw_bottom_box(dialog); draw_title(dialog, title); wattrset(dialog, dialog_attr); print_autowrap(dialog, prompt, height, width); list_width = width - 6; getyx(dialog, cur_y, cur_x); box_y = cur_y + 1; box_x = (width - list_width) / 2 - 1; /* create new window for the list */ list = sub_window(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1); /* draw a box around the list items */ draw_box(dialog, box_y, box_x, list_height + 2 * MARGIN, list_width + 2 * MARGIN, menubox_border_attr, menubox_attr); text_width = 0; name_width = 0; /* Find length of longest item to center checklist */ for (i = 0; i < item_no; i++) { text_width = MAX(text_width, (int) strlen(ItemText(i))); name_width = MAX(name_width, (int) strlen(ItemName(i))); } /* If the name+text is wider than the list is allowed, then truncate * one or both of them. If the name is no wider than 1/4 of the list, * leave it intact. */ use_width = (list_width - 6); if (text_width + name_width > use_width) { int need = 0.25 * use_width; if (name_width > need) { int want = use_width * ((double) name_width) / (text_width + name_width); name_width = (want > need) ? want : need; } text_width = use_width - name_width; } check_x = (use_width - (text_width + name_width)) / 2; item_x = name_width + check_x + 6; /* Print the list */ for (i = 0; i < max_choice; i++) print_item(list, ItemData(i), status[i], i, i == choice); (void) wnoutrefresh(list); /* register the new window, along with its borders */ mouse_mkbigregion(box_y + 1, box_x, list_height, list_width + 2, KEY_MAX, 1, 1, 1 /* by lines */ ); dlg_draw_arrows(dialog, scrollamt, scrollamt + max_choice < item_no - 1, box_x + check_x + 5, box_y, box_y + list_height + 1); dlg_draw_buttons(dialog, height - 2, 0, buttons, 0, FALSE, width); wtimeout(dialog, WTIMEOUT_VAL); while (result == DLG_EXIT_UNKNOWN) { key = mouse_wgetch(dialog, &fkey); if (fkey && (key >= (M_EVENT + KEY_MAX))) { getyx(dialog, cur_y, cur_x); /* De-highlight current item */ print_item(list, ItemData(scrollamt + choice), status[scrollamt + choice], choice, FALSE); /* Highlight new item */ choice = (key - (M_EVENT + KEY_MAX)); print_item(list, ItemData(scrollamt + choice), status[scrollamt + choice], choice, TRUE); (void) wnoutrefresh(list); (void) wmove(dialog, cur_y, cur_x); key = ' '; /* force the selected item to toggle */ fkey = FALSE; } /* * A space toggles the item status. We handle either a checklist * (any number of items can be selected) or radio list (zero or one * items can be selected). */ if (key == ' ') { getyx(dialog, cur_y, cur_x); if (flag == FLAG_CHECK) { /* checklist? */ status[scrollamt + choice] = !status[scrollamt + choice]; print_item(list, ItemData(scrollamt + choice), status[scrollamt + choice], choice, TRUE); } else { /* radiolist */ if (!status[scrollamt + choice]) { for (i = 0; i < item_no; i++) status[i] = FALSE; status[scrollamt + choice] = TRUE; for (i = 0; i < max_choice; i++) print_item(list, ItemData(scrollamt + i), status[scrollamt + i], i, i == choice); } } (void) wnoutrefresh(list); (void) wmove(dialog, cur_y, cur_x); wrefresh(dialog); continue; /* wait for another key press */ } else if (key == ESC) { result = DLG_EXIT_ESC; continue; } if (!fkey) { fkey = TRUE; switch (key) { case '\n': case '\r': key = KEY_ENTER; break; case '-': key = KEY_UP; break; case '+': key = KEY_DOWN; break; case TAB: key = KEY_RIGHT; break; default: fkey = FALSE; break; } } /* * Check if key pressed matches first character of any item tag in * list. If there is more than one match, we will cycle through * each one as the same key is pressed repeatedly. */ found = FALSE; if (!fkey) { for (j = scrollamt + choice + 1; j < item_no; j++) { if (dlg_match_char(dlg_last_getc(), ItemName(j))) { found = TRUE; i = j - scrollamt; break; } } if (!found) { for (j = 0; j <= scrollamt + choice; j++) { if (dlg_match_char(dlg_last_getc(), ItemName(j))) { found = TRUE; i = j - scrollamt; break; } } } if (found) dlg_flush_getc(); } /* * A single digit (1-9) positions the selection to that line in the * current screen. */ if (!found && (key <= '9') && (key > '0') && (key - '1' < max_choice)) { found = TRUE; i = key - '1'; } if (!found) { if (fkey) { found = TRUE; switch (key) { case KEY_HOME: i = -scrollamt; break; case KEY_LL: case KEY_END: i = item_no - 1 - scrollamt; break; case M_EVENT + KEY_PPAGE: case KEY_PPAGE: if (choice) i = 0; else if (scrollamt != 0) i = -MIN(scrollamt, max_choice); else continue; break; case M_EVENT + KEY_NPAGE: case KEY_NPAGE: i = MIN(choice + max_choice, item_no - scrollamt - 1); break; case KEY_UP: i = choice - 1; if (choice == 0 && scrollamt == 0) continue; break; case KEY_DOWN: i = choice + 1; if (scrollamt + choice >= item_no - 1) continue; break; default: found = FALSE; break; } } } if (found) { if (i != choice) { getyx(dialog, cur_y, cur_x); if (i < 0 || i >= max_choice) { #if defined(NCURSES_VERSION_MAJOR) && NCURSES_VERSION_MAJOR < 5 /* * Using wscrl to assist ncurses scrolling is not needed * in version 5.x */ if (i == -1) { if (list_height > 1) { /* De-highlight current first item */ print_item(list, ItemData(scrollamt), status[scrollamt], 0, FALSE); scrollok(list, TRUE); wscrl(list, -1); scrollok(list, FALSE); } scrollamt--; print_item(list, ItemData(scrollamt), status[scrollamt], 0, TRUE); } else if (i == max_choice) { if (list_height > 1) { /* De-highlight current last item before scrolling up */ print_item(list, ItemData(scrollamt + max_choice - 1), status[scrollamt + max_choice - 1], max_choice - 1, FALSE); scrollok(list, TRUE); wscrl(list, 1); scrollok(list, FALSE); } scrollamt++; print_item(list, ItemData(scrollamt + max_choice - 1), status[scrollamt + max_choice - 1], max_choice - 1, TRUE); } else #endif { if (i < 0) { scrollamt += i; choice = 0; } else { choice = max_choice - 1; scrollamt += (i - max_choice + 1); } for (i = 0; i < max_choice; i++) { print_item(list, ItemData(scrollamt + i), status[scrollamt + i], i, i == choice); } } (void) wnoutrefresh(list); dlg_draw_arrows(dialog, scrollamt, scrollamt + choice < item_no - 1, box_x + check_x + 5, box_y, box_y + list_height + 1); } else { /* De-highlight current item */ print_item(list, ItemData(scrollamt + choice), status[scrollamt + choice], choice, FALSE); /* Highlight new item */ choice = i; print_item(list, ItemData(scrollamt + choice), status[scrollamt + choice], choice, TRUE); (void) wnoutrefresh(list); (void) wmove(dialog, cur_y, cur_x); wrefresh(dialog); } } continue; /* wait for another key press */ } if (fkey) { switch (key) { case KEY_ENTER: result = dlg_ok_buttoncode(button); break; case KEY_BTAB: case KEY_LEFT: button = dlg_prev_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; case KEY_RIGHT: button = dlg_next_button(buttons, button); dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); break; default: if (key >= M_EVENT) { if ((key2 = dlg_ok_buttoncode(key - M_EVENT)) >= 0) { result = key2; break; } beep(); } } } else { beep(); } } del_window(dialog); switch (result) { case DLG_EXIT_OK: /* FALLTHRU */ case DLG_EXIT_EXTRA: for (i = 0; i < item_no; i++) { if (status[i]) { if (flag == FLAG_CHECK) { if (separate_output) { dlg_add_result(ItemName(i)); dlg_add_result("\n"); } else { dlg_add_result("\""); dlg_add_result(ItemName(i)); dlg_add_result("\" "); } } else { dlg_add_result(ItemName(i)); } } } break; case DLG_EXIT_HELP: dlg_add_result("HELP "); if (USE_ITEM_HELP(ItemHelp(scrollamt + choice))) { dlg_add_result(ItemHelp(scrollamt + choice)); result = DLG_EXIT_OK; /* this is inconsistent */ } else { dlg_add_result(ItemName(scrollamt + choice)); } break; } mouse_free_regions(); free(status); free(prompt); return result; }
int main() { int p1[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; int win = 0; int pole, remis, tryb; int ch, x = 2, y = 2, exit = 0; //do operacji na kursorze initscr(); cbreak(); noecho();// ja jeeeeeeeeeeeeeeeeeeeeebie, działa! ;d keypad(stdscr, true); //do zabawy kursorem start_color(); beep(); tryb = menu(); while (remis < 9) { rysuj(p1); exit = 0; // todo: przeniesc to do funkcji wczytaj i zrobic sprawdzanie czy nie jest juz zajete pole while (exit<1) { move(y,x); refresh(); ch = getch(); switch (ch) { case KEY_LEFT: x--; move(y, x); refresh(); break; case KEY_RIGHT: x++; move(y, x); refresh(); break; case KEY_UP: y--; move(y, x); refresh(); break; case KEY_DOWN: y++; move(y, x); refresh(); break; case 0xa: getyx(stdscr, y, x); // y = wiersz kursora y = kolumna kursora if (x == 0 && y == 0) { pole = 1; exit = 1; } else if ((x == 2) && (y == 0)) { pole = 2; exit = 1; } else if (x == 4 && y == 0) { pole = 3; exit = 1; } else if (x == 0 && y == 2) { pole = 4; exit = 1; } else if (x == 2 && y == 2) { pole = 5; exit = 1; } else if (x == 4 && y == 2) { pole = 6; exit = 1; } else if (x == 0 && y == 4) { pole = 7; exit = 1; } else if (x == 2 && y == 4) { pole = 8; exit = 1; } else if (x == 4 && y == 4) { pole = 9; exit = 1; } break; } } wczytaj(1, pole, p1); remis++; if (remis == 9) { printw("Remis\n"); break; } win = test(1, p1); if (win > 0) { break; } /* wybór trybu single/multi */ if (tryb == 2) { rysuj(p1); //rysuje planszę po ruchu pierwszego gracza tylko jak jest multiplayer printw("Gracz 2, podaj pole [1-9]:"); scanw("%d", &pole); wczytaj(2, pole, p1); } if (tryb == 1) { pc1(p1); } win = test(2, p1); remis++; if (remis == 9) { printw("Remis\n"); break; } if (win > 0) { rysuj(p1); break; } refresh(); } if (win == 1) { mvprintw(5,0,"Gratulacje! Gracz 1, wygrałeś.\n"); } if (win == 2) { mvprintw(5,0,"Gratulacje! Gracz 2 wygrywa!\n"); } getch(); endwin(); return 0; }
int main(int argc, char *argv[]) { initscr(); cbreak(); noecho(); start_color(); mousemask(BUTTON1_CLICKED, NULL); mouseinterval(0); init_pair(0, COLOR_WHITE, COLOR_BLACK); init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_BLUE, COLOR_BLACK); int x,y; int ch = 0; square turn = GUMA; bool winner = false; WINDOW* win_big = newwin(N+2, N+2, 1, 0); WINDOW* win = derwin(win_big, N, N, 1, 1); Board_curses b(win); MEVENT event; keypad(win, 1); box(win_big, 0, 0); curPlayer(turn); refresh(); wrefresh(win_big); b.print(); wmove(win, 0, 0); while(!winner) { bool restart_loop = false; bool mouse = false; while (!mouse && (ch = wgetch(win)) != '\n') { getyx(win, y, x); switch (ch) { case KEY_UP: if (y > 0) wmove(win, --y, x); break; case KEY_DOWN: if (y < N-1) wmove(win, ++y, x); break; case KEY_LEFT: if (x > 0) wmove(win, y, --x); break; case KEY_RIGHT: if (x < N-1) wmove(win, y, ++x); break; case KEY_MOUSE: if (getmouse(&event) == OK && ( event.bstate & BUTTON1_CLICKED ) ) { event.x -= 1; event.y -= 2; if( event.x < N && event.x >= 0 && event.y < N && event.y >= 0 ) { wmove(win, event.y, event.x); mouse = true; } } break; default: break; } } getyx(win, y, x); try { winner = b.move(turn, x, y); } catch (square_occupied) { restart_loop = true; } if (!restart_loop) { if (!winner) { if (turn == GUMA) turn = BATON; else turn = GUMA; } b.print(); curPlayer(turn); refresh(); wmove(win, y, x); } } endwin(); if (turn == GUMA) puts("Red player is a winrar"); else puts("Blue player is a winrar"); return 0; }
void modify_display ( void ) { int i; int focus = 0; int c; int x,y; int maxx; int maxy __attribute((unused)); int ll_focus_y = 0; int ll_focus_x = 0; WINDOW *mod_win; getmaxyx ( win, maxy, maxx ); mod_win = newwin ( 8, maxx, 0, 0 ); cbreak(); raw(); nonl(); keypad ( mod_win, TRUE ); while ( 1 ) { werase( mod_win ); wrefresh( mod_win ); mvwprintw ( mod_win, 0, 0, "Use arrow keys (or vim cursor keys) to navigate;" ); mvwprintw ( mod_win, 1, 0, "Set sort field (highlighted) with 's', order %s (change with 'r')", parametres.reversesort ? "ascending" : "descending" ); mvwprintw ( mod_win, 2, 0, "go down or press enter to change a field, select with space key"); mvwprintw ( mod_win, 3, 0, "'i' to insert a field, 'a' to append it, 'd' to delete"); wmove ( mod_win, 6, 0 ); for ( i = 0; i < MAX_DISPLAY_FIELDS; i++ ) { wattron ( mod_win, A_REVERSE ); if ( display_fields[i] == NULL ) { break; } if ( display_fields[i]->identifier == parametres.sortby ) { wattroff ( mod_win, A_REVERSE ); } wprintw ( mod_win, display_fields[i]->header_format, display_fields[i]->fieldname ); if ( i == focus ) { wattroff ( mod_win, A_REVERSE ); /* find out where to print the menu in case we need one */ getyx ( mod_win, y, x ); ll_focus_y = y + 1; ll_focus_x = x - display_fields[i]->field_length; /* keep menu inside the current window - in case it would "fall off" off the edge, move it inwards by the width of the menu */ if ( maxx < ( x + MENU_WIDTH ) ) { ll_focus_x = maxx - MENU_WIDTH; } mvwaddch( mod_win, y - 1, x - display_fields[i]->field_length - 1 , ACS_ULCORNER); mvwaddch( mod_win, y + 1, x - display_fields[i]->field_length - 1 , ACS_LLCORNER); mvwaddch( mod_win, y + 1, x -1, ACS_LRCORNER); mvwaddch( mod_win, y - 1, x - 1 , ACS_URCORNER); mvwvline( mod_win, y , x - display_fields[i]->field_length - 1 , ACS_VLINE, 1 ); mvwvline( mod_win, y , x - 1 , ACS_VLINE, 1 ); mvwhline( mod_win, y - 1, x - display_fields[i]->field_length, ACS_HLINE, display_fields[i]->field_length - 1 ); mvwhline( mod_win, y + 1, x - display_fields[i]->field_length, ACS_HLINE, display_fields[i]->field_length - 1 ); wmove ( mod_win, y, x ); } } wrefresh( mod_win ); c = getch(); switch ( c ) { case 'h': case KEY_LEFT: if ( focus > 0 ) { focus--; } break; case 'l': case KEY_RIGHT: if ( display_fields[focus + 1] != NULL ) { focus++; } break; case 's': case 'S': if ( display_fields[focus]->sortable == 1 ) { parametres.sortby = display_fields[focus]->identifier; goto end; } else { printf ( "\a" ); mvwprintw ( mod_win, 5, 0, "%-79s", "Sorry, can't sort by this field"); wrefresh ( mod_win ); sleep ( 1 ); } break; case 'r': case 'R': parametres.reversesort ^= 1; break; case 'd': displayfield_shift_down ( focus ); break; case 'i': /* insert a field */ if ( displayfield_shift_up ( focus + 1 ) != 0 ) { ungetch ( 'j' ); } break; case 'a': /* append a field */ focus++; if ( displayfield_shift_up ( focus ) != 0 ) { ungetch ( 'j' ); } else { focus--; } break; case 'j': case KEY_DOWN: case KEY_ENTER: display_fields[focus] = select_field ( ll_focus_y, ll_focus_x, display_fields[focus] ); goto end; break; case 'q': case 27: /* ESC key */ goto end; break; default: printf ( "\a" ); break; } wattroff ( mod_win, A_REVERSE ); } end: ; keypad ( mod_win, FALSE ); halfdelay ( 30 ); werase( mod_win ); delwin( mod_win ); parametres.requested_fields = 0; for ( i = 0; i < MAX_DISPLAY_FIELDS; i++ ) { if ( display_fields[i] == NULL ) { break; } parametres.requested_fields |= 1 << display_fields[i]->identifier; } }
/*------------------------------------------------------------------------ * Program: piggy3 * * Purpose: Network middleware where a client can connect to the left side * of piggy and piggy can also connect to a server with an address specified * by -raddr option. Alternatively if -noright option is set then piggy will * echo what is read from the left. * * Syntax: piggy -option * * Options: * lacct_addr - specifies what address the server can accept. * raddr - specifies what address piggy should connect to. * noleft - flags that piggy should use stdin for it's left side. * noright - flags that piggy should use stdout for it's right side. * luseport - Port to use for left side server. * loopr - Data from the left that would be written to the right is looped back to the left. * loopl - Data from the right that would be written to the left is looped back to the right. * * The address for lacct_addr and raddr can be a dotted IP address or * a DNS name and the value must directly follow the argument. * * Note: No default address for right side so raddr value or noright * must be set. Laddr defaults to accepting any left side connection * which is equivalent to setting it's value to "*". * * The default port is 36790 *------------------------------------------------------------------------ */ main(int argc,char *argv[]) { /* setup for select */ int input_ready; struct timeval timeout; timeout.tv_sec = .5; /* loop through arguments and set values */ bool no_left = false; /* holds value of command line argument -noleft */ bool no_right = false;/* Holds value of command line argument -no_right */ char *lacct_addr = NULL;/* Holds the address of the left connect as either an IP address or DNS name*/ char *raddr = NULL; /* Holds the address of the left connect as either an IP address or DNS name*/ int lacctport = -1; /* Holds the port number will be accepted on the left connection */ int luseport = -1; /* Holds the port number that will be assigned to the left connection server */ int rport = -1; /* Holds the port number used when making the connection the raddr */ bool loopr = false; /* Holds value of command line argument -loopr */ bool loopl = false; /* Holds value of command line argument -loopl */ int arg_i; for (arg_i = 1; arg_i < argc; arg_i++){ if (strcmp(argv[arg_i],"-noleft") == 0) no_left = true; else if (strcmp(argv[arg_i], "-noright") == 0) no_right = true; else if (strcmp(argv[arg_i], "-laddr") == 0 && (arg_i + 1) < argc) lacct_addr = argv[++arg_i]; /* Note that this will also move arg_i past val */ else if (strcmp(argv[arg_i], "-raddr") == 0 && (arg_i + 1) < argc) raddr = argv[++arg_i]; /* Note that this will also move arg_i past val */ else if (strcmp(argv[arg_i], "-lacctport") == 0 && (arg_i + 1) < argc) lacctport = atoi(argv[++arg_i]); else if (strcmp(argv[arg_i], "-luseport") == 0 && (arg_i + 1) < argc) luseport = atoi(argv[++arg_i]); else if (strcmp(argv[arg_i], "-rport") == 0 && (arg_i + 1) < argc) rport = atoi(argv[++arg_i]); else if (strcmp(argv[arg_i], "-loopr") == 0) loopr = true; else if (strcmp(argv[arg_i], "-loopl") == 0) loopl = true; else fprintf(stderr,"%s is not a valid option. It will be ignored.\n", argv[arg_i]); } /* Check that there is either a left or right address (or both) */ if ( no_left && no_right || argc < 2){ printf("Piggy must have either a left or right side.\n"); exit(EXIT_FAILURE); } /* Map TCP transport protocol name to protocol number */ if ( ((long int)(ptrp = getprotobyname("tcp"))) == 0) { fprintf(stderr, "cannot map \"tcp\" to protocol number"); exit(EXIT_FAILURE); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Set up ncurses /************************************************************************************************************************************/ int i,j,a,b,c,d,nch; chtype ch; char response[132]; ch=(chtype) " "; ls=(chtype) 0; rs=(chtype) 0; ts=(chtype) 0; bs=(chtype) 0; tl=(chtype) 0; tr=(chtype) 0; bl=(chtype) 0; br=(chtype) 0; setlocale(LC_ALL,""); // this has to do with the character set to use initscr(); // must always call this (or newterm) to initialize the // library before any routines that deal with windows // or the screen can be called // set up some foreground / background color pairs cbreak(); // this allows use to get characters as they are typed // without the need for the userpressing the enter key noecho(); // this means the characters typed are not // shown on the screen unless we put them there nonl(); // this means don't translate a newline character // to a carraige return linefeed sequence on output intrflush(stdscr, FALSE); // keypad(stdscr, TRUE); // if (!(LINES==43) || !(COLS==132) ){ if (resizeterm(43,132)==ERR){ clear(); move(0,0); addstr("Piggy3 requires a screen size of 132 columns and 43 rows"); move(1,0); addstr("Set screen size to 132 by 43 and try again"); move(2,0); addstr("Press enter to terminate program"); refresh(); getstr(response); // Pause so we can see the screen endwin(); exit(EXIT_FAILURE); } } clear(); // make sure screen is clear before we start w[0]=newwin(0,0,0,0); touchwin(w[0]); wmove(w[0],0,0); wrefresh(w[0]); // Create the 5 windows a = 18; b=66; c=0; d=0; w[1]=subwin(w[0],a,b,c,d); w[2]=subwin(w[0],a,b,c,b); w[3]=subwin(w[0],a,b,a,c); w[4]=subwin(w[0],a,b,a,b); w[5]=subwin(w[0],7,132,36,c); for (i=1; i < MAXWIN - 1; i++){ ww[i]= b - 1; wh[i]= a - 1; } ww[5]= 131; wh[5]= 6; for (i=1;i < MAXWIN; i++){ wattron(w[i], A_STANDOUT); wborder(w[i],ls,rs,ts,bs,tl,tr,bl,br); wrefresh(w[i]); wattroff(w[i], A_STANDOUT); wrpos[i] = 1; wcpos[i] = 1; } wAddstr(IN_L,"Data arriving from the left:\n"); wAddstr(OUT_R,"Data leaving from left to right:\n"); wAddstr(OUT_L,"Data leaving from right to left:\n"); wAddstr(IN_R,"Data arriving from the right:\n"); wmove(w[IO],1,1);// start curser in IO window at top left wrefresh(w[0]); /*****************************************************************************************************************/ // create initial sockets /*****************************************************************************************************************/ /* Set up for left side of the connection */ /* Acts like a server so programs can connect to piggy */ int left_passive_sock = -1; /* socket descriptors */ /* If luseport is not set then use protoport value */ if (luseport == -1) luseport = PROTOPORT; if (!no_left){ if((left_passive_sock = create_server(luseport)) != -1){ FD_SET(left_passive_sock, &inputs); if (left_passive_sock > max_fd) max_fd = left_passive_sock;} else wAddstr(IO,"An error has occured creating the left connection. Piggy does not have a left side.\n"); } /* Right side of connection */ /* Acts like a client connection to a server */ int right_sock = -1; /* socket descriptor for left side*/ if (!no_right && raddr != NULL){ /* If rport was not set by the command line then use default PROTOPORT */ if (rport == -1) rport = PROTOPORT; if ((right_sock = create_client(raddr, rport)) != -1){ wAddstr(IO,"Piggy has a valid right connection.\n"); FD_SET(right_sock, &inputs); if (right_sock > max_fd) max_fd = right_sock;} else wAddstr(IO,"An error has occured creating the right connection. Piggy does not have a right side.\n"); } else if (!no_right && raddr == NULL){ wAddstr(IO,"Must specify -raddr or set -noright\n"); } /* Main server loop - accept and handle requests */ /* For left side */ int left_sock = -1; /* socket descriptor for accept socket */ char *lconnect_addr = NULL; char left_buf[1000]; /* buffer for string the server reads*/ int left_n = 0; /* number of characters read from input stream */ /* For right side */ int right_passive_sock = -1; /* socket descriptor for right side server */ int ruseport = PROTOPORT; int racctport = -1; char *racct_addr = NULL; char right_buf[1000]; /* buffer for string the server sends */ int right_n = 0; /* number of characters read to go to output stream*/ /* For keyboard input */ char stdin_buf[1000]; /* buffer for insert mode */ int stdin_n = 0; /* number of characters read in insert mode */ char *commands[3]; char command1[10]; char command2[20]; char command3[20]; commands[0] = command1; commands[1] = command2; commands[2] = command3; int command_lengths[3]; int command_i; int command_count; /* set output defaults */ bool outputr = true; bool outputl = false; if (no_right){ outputr = false; outputl = true; } fd_set inputs_loop = inputs; while (1) { wmove(w[IO],wrpos[IO],wcpos[IO]); inputs_loop = inputs; input_ready = select(max_fd+1,&inputs_loop,NULL,NULL,&timeout); /* accepts incoming client from left side and assigns to left_sock */ if (left_passive_sock != -1 && FD_ISSET(left_passive_sock,&inputs_loop)) if ((left_sock = Accept(left_passive_sock,lacct_addr,lacctport)) != -1) wAddstr(IO,"Piggy established a valid left connection.\n"); if (right_passive_sock != -1 && FD_ISSET(right_passive_sock,&inputs_loop)) if ((right_sock = Accept(right_passive_sock,racct_addr,racctport)) != -1) wAddstr(IO,"Piggy established a valid right connection.\n"); /* read input from stdin */ char cur_char; halfdelay(20); if ( (cur_char = wgetch(w[IO])) != ERR){ wrefresh(w[IO]); int cur_y,cur_x; getyx(w[IO],cur_y,cur_x); wrpos[IO]=cur_y; wcpos[IO]=cur_x; /* Process input commands */ /* Insert Mode */ if (cur_char == 'i'){ /* show that the user has entered insert mode */ mvwprintw(w[IO],wh[IO] -1,1,"-- INSERT --"); wrpos[IO]=cur_y; wcpos[IO]=cur_x; wmove(w[IO],wrpos[IO],wcpos[IO]); /* parse input */ while ((cur_char = wgetch(w[IO])) != 27){ if (cur_char == BACKSPACE){ // A backspace if (stdin_n != 0){ --stdin_n; mvwaddch(w[IO],wrpos[IO],wcpos[IO],' '); wmove(w[IO],wrpos[IO],wcpos[IO]); wcpos[IO]--; }} else if (cur_char == ENTER){ // An enter stdin_buf[stdin_n++] = '\n'; if (++wrpos[IO] == wh[IO] - 1) wrpos[IO] = 1; wcpos[IO] = 1; wmove(w[IO],wrpos[IO],wcpos[IO]);} else if ((cur_char >= 32) && (cur_char != 127)){ if (++wcpos[IO] == ww[IO]){ wcpos[IO]=1; if (++wrpos[IO]==wh[IO] -1) wrpos[IO]=1; } stdin_buf[stdin_n++] = cur_char; mvwaddch(w[IO],wrpos[IO],wcpos[IO],cur_char); } wrefresh(w[5]); } /* Clean up */ stdin_buf[stdin_n] = 0;// make it a proper string for (i = 1; i < wh[IO]; i++){ for (j = 1; j < ww[IO]; j++) mvwaddch(w[IO],i,j,' '); } wrpos[IO] = wcpos[IO] = 1; wmove(w[IO],wrpos[IO],wcpos[IO]); } /* Command Mode */ else if (cur_char == ':'){ mvwaddch(w[IO],wh[IO]-1, 1,':'); nocbreak(); echo(); /* Put command into commands[]*/ command_count = 0; for (i = 0; i < 3; i++) command_lengths[i] = 0; while ((cur_char = wgetch(w[IO])) != EOF && cur_char != '\n'){ if (cur_char == ' '){ commands[command_count][command_lengths[command_count]] = '\0'; // make command i proper if (++command_count > 2){ wAddstr(IO,"No valid commands have more than two args."); break; } command_lengths[command_count] = 0; } else commands[command_count][command_lengths[command_count]++] = cur_char; } if (command_lengths[command_count] > 0) commands[command_count][command_lengths[command_count]] = '\0'; cbreak(); noecho(); wrpos[IO] = wh[IO] -1; wcpos[IO] = 1; wClrtoeol(IO); wrpos[IO] = 1; wcpos[IO] =1; wmove(w[IO],wrpos[IO],wcpos[IO]); wrefresh(w[IO]); /* Check if valid command and process it*/ if (strncmp(commands[0],"q",command_lengths[0]) == 0){ /* Close the sockets. */ closesocket(left_sock); closesocket(right_sock); closesocket(left_passive_sock); closesocket(right_passive_sock); /* Put piggy out to paster */ endwin(); exit(0);} else if (strncmp(commands[0],"dropl",command_lengths[0]) == 0){ if (left_passive_sock != -1 || left_sock != -1){ Close(&left_sock); Close(&left_passive_sock); wAddstr(IO,"Dropped the left side connection.\n");} else wAddstr(IO,"No left side connection to drop.\n");} else if (strncmp(commands[0],"dropr",command_lengths[0]) == 0){ if (right_passive_sock != -1 || right_sock != -1){ Close(&right_passive_sock); Close(&right_sock); wAddstr(IO,"Dropped the right side connection.\n");} else wAddstr(IO,"No right side connection to drop.\n");} else if (strncmp(commands[0],"output",command_lengths[0]) == 0){ if (outputr) wAddstr(IO,"The current output direction for insert mode is to the right.\n"); else wAddstr(IO,"The current output direction for insert mode is to the left. \n");} else if (strncmp(commands[0],"outputl",command_lengths[0]) == 0){ outputr = false; outputl = true;} else if (strncmp(commands[0],"outputr",command_lengths[0]) == 0){ outputl = false; outputr = true;} else if (strncmp(commands[0], "lpair", command_lengths[0]) == 0) pair_info(left_passive_sock, left_sock, luseport); else if (strncmp(commands[0], "rpair", command_lengths[0]) == 0) pair_info(right_passive_sock, right_sock, ruseport); else if (strncmp(commands[0],"loopl",command_lengths[0]) == 0){ loopr = false; loopl = true;} else if (strncmp(commands[0],"loopr",command_lengths[0]) == 0){ loopl = false; loopr = true;} else if (strncmp(commands[0],"luseport",command_lengths[0]) == 0){ if (command_lengths[1] > 0) luseport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :luseport\n");} else if (strncmp(commands[0],"ruseport", command_lengths[0]) == 0){ if (command_lengths[1] > 0) ruseport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :ruseport\n");} else if (strncmp(commands[0],"lacctport",command_lengths[0]) == 0){ if (command_lengths[1] > 0) lacctport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :lacctport\n");} else if (strncmp(commands[0],"racctport", command_lengths[0]) == 0){ if (command_lengths[1] > 0) racctport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :racctport.\n");} else if (strncmp(commands[0],"laccptip", command_lengths[0]) == 0){ if (command_lengths[1] > 0) lacct_addr = commands[1]; else wAddstr(IO,"Must specify valid IP number after :lacctip\n");} else if (strncmp(commands[0],"racctip", command_lengths[0]) == 0){ if (command_lengths[1] > 0) racct_addr = commands[1]; else wAddstr(IO,"Must specify valid IP number after :racctip\n");} else if (strncmp(commands[0],"listenl", command_lengths[0]) == 0){ if (left_passive_sock != -1 || left_sock != -1) wAddstr(IO,"Already a left side. Use dropl and try agian\n"); else { /* If luseport is not set then use protoport value */ if (command_lengths[1] > 0) luseport = atoi(commands[1]); if((left_passive_sock = create_server(luseport)) != -1){ FD_SET(left_passive_sock, &inputs); if (left_passive_sock > max_fd) max_fd = left_passive_sock;} else wAddstr(IO,"An error has occured creating the left connection. Piggy does not have a left side.\n"); }} else if (strncmp(commands[0],"listenr",command_lengths[0]) == 0){ if (right_passive_sock != -1 || right_sock != -1) wAddstr(IO,"Already a right side. Use dropr and try agian.\n"); else { /* If port specified use it. else use protoport value */ if (command_lengths[1] > 0) ruseport = atoi(commands[1]); if((right_passive_sock = create_server(ruseport)) != -1){ FD_SET(right_passive_sock, &inputs); if (right_passive_sock > max_fd) max_fd = right_passive_sock;} else wAddstr(IO,"An error has occured creating the right connection. Piggy does not have a right side.\n"); }} else if (strncmp(commands[0],"connectl",command_lengths[0]) == 0){ if (left_passive_sock != -1 || left_sock != -1) wAddstr(IO,"Already a left side. Use dropl and try again.\n"); else { /* Get IP address */ if (command_lengths[1] > 0) lconnect_addr = commands[1]; else wAddstr(IO,"Must specify address or host name to connect to.\n"); /* Get port number */ if (command_lengths[2] > 0) luseport = atoi(commands[2]); else wAddstr(IO,"Must specify port number to connect to.\n"); /* Create socket */ if ((left_sock = create_client(lconnect_addr, luseport)) != -1){ wAddstr(IO,"Piggy has a valid left connection.\n"); FD_SET(right_sock, &inputs); if (left_sock > max_fd) max_fd = left_sock;} else wAddstr(IO,"An error has occured creating the left connection. Piggy does not have a left side.\n"); }} else if (strncmp(commands[0],"connectr",command_lengths[0]) == 0){ if (right_passive_sock != -1 || right_sock != -1) wAddstr(IO,"Already a right side. Use dropr and try again.\n"); else { /* Get IP address */ if (command_lengths[1] > 0) raddr = commands[1]; else wAddstr(IO,"Must specify address or host name to connect to.\n"); /* Get port number */ if (command_lengths[2] > 0) rport = atoi(commands[2]); else wAddstr(IO,"Must specify port number to connect to.\n"); /* Create socket */ if ((right_sock = create_client(raddr, rport)) != -1){ wAddstr(IO,"Piggy has a valid right connection.\n"); FD_SET(right_sock, &inputs); if (right_sock > max_fd) max_fd = right_sock;} else wAddstr(IO,"An error has occured creating the right connection. Piggy does not have a right side.\n"); }} else if ((strncmp(commands[0],"read",command_lengths[0])) == 0){ if (command_lengths[1] > 0){ int read_fd = open(commands[1],O_RDONLY); while ((stdin_n = read(read_fd,stdin_buf,sizeof(stdin_buf))) > 0){ if (outputr && right_sock != -1){ write(right_sock,stdin_buf,stdin_n); wAddnstr(OUT_R,stdin_buf,stdin_n);} else if (outputl && left_sock != -1){ write(left_sock, stdin_buf,stdin_n); wAddnstr(OUT_L,stdin_buf,stdin_n);} } if (stdin_n < 0) wAddstr(IO,"Error reading file\n"); if (stdin_n = 0) wAddstr(IO,"Seccessfully read whole file\n"); /*clean up */ close(read_fd); stdin_n = 0;} else wAddstr(IO,"Must specify name of file to read from\n"); } else wAddstr(IO,"Not a valid command.\n"); wrefresh(w[IO]); } } /* read from left side. */ if (FD_ISSET(left_sock,&inputs_loop)){ if ((left_n = read(left_sock,left_buf,sizeof(left_buf))) == 0){ wAddstr(IO,"Lost connection to left side. \n"); Close(&left_sock);} else // Display input from left to top left corner wAddnstr(IN_L,left_buf,left_n); } /* read from right side. */ if (FD_ISSET(right_sock, &inputs_loop)){ if ((right_n = read(right_sock, right_buf,sizeof(right_buf))) == 0){ wAddstr(IO,"Lost connection to right side. \n"); Close(&right_sock);} else // Display input from right to bottom right corner wAddnstr(IN_R,right_buf,right_n); } /* output contents of stdin_buf */ if (stdin_n != 0){ if (outputr && right_sock != -1){ write(right_sock,stdin_buf,stdin_n); wAddnstr(OUT_R,stdin_buf,stdin_n);} else if (outputl && left_sock != -1){ write(left_sock, stdin_buf,stdin_n); wAddnstr(OUT_L,stdin_buf,stdin_n);} else wAddstr(IO,"Unable to output string. Check your output and loop settings are correct and try again.\n"); stdin_n = 0; } /* Output contents of left and right buffer if data is present */ if (left_n != 0){ if (!loopr && right_sock != -1){ write(right_sock,left_buf,left_n); wAddnstr(OUT_R,left_buf,left_n);} else if (loopr && left_sock != -1){ write(left_sock,left_buf,left_n); wAddnstr(OUT_L,left_buf,left_n);} left_n = 0; } if (right_n != 0){ if (!loopl && left_sock != -1){ write(left_sock,right_buf,right_n); wAddnstr(OUT_L,right_buf,right_n);} else if (loopl && right_sock != -1){ write(right_sock,right_buf,right_n); wAddnstr(OUT_R,right_buf,right_n);} right_n = 0; } } }
static void prompt_onDraw(ToxWindow *self, Tox *m) { curs_set(1); int x, y, x2, y2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); size_t i; for (i = 0; i < prompt_buf_pos; ++i) { if ((prompt_buf[i] == '\n') && (y != 0)) --y; } StatusBar *statusbar = (StatusBar *) self->stb; werase(statusbar->topline); mvwhline(statusbar->topline, 1, 0, '-', x2); wmove(statusbar->topline, 0, 0); if (statusbar->is_online) { int colour = WHITE; char *status_text = "Unknown"; switch(statusbar->status) { case TOX_USERSTATUS_NONE: status_text = "Online"; colour = GREEN; break; case TOX_USERSTATUS_AWAY: status_text = "Away"; colour = YELLOW; break; case TOX_USERSTATUS_BUSY: status_text = "Busy"; colour = RED; break; } wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s ", statusbar->nick); wattron(statusbar->topline, A_BOLD); wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wprintw(statusbar->topline, "[%s]", status_text); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); } else { wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, "%s ", statusbar->nick); wattroff(statusbar->topline, A_BOLD); wprintw(statusbar->topline, "[Offline]"); } wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " | %s |", statusbar->statusmsg); wattroff(statusbar->topline, A_BOLD); wprintw(statusbar->topline, "\n"); wattron(self->window, COLOR_PAIR(GREEN)); mvwprintw(self->window, y, 0, "# "); wattroff(self->window, COLOR_PAIR(GREEN)); mvwprintw(self->window, y, 2, "%s", prompt_buf); wclrtoeol(self->window); wrefresh(self->window); }
int main(int argc, char *argv[]) { int continuer = 1; Commande *commande = malloc(sizeof(commande)); initialiseCommande(commande); // signal(SIGINT, interrupt); Niveau *niveau = malloc(sizeof(niveau)); decompression(choixNiveau(argc, argv), commande, niveau); /*** */ struct sigaction act; memset (&act, '\0', sizeof(act)); /* Use the sa_sigaction field because the handles has two additional parameters */ act.sa_sigaction = &hdl; /* The SA_SIGINFO flag tells sigaction() to use the sa_sigaction field, not sa_handler. */ act.sa_flags = SA_SIGINFO; if (sigaction(SIGINT, &act, NULL) < 0) { perror ("sigaction"); return 1; } /**** */ int ch; int finCommande = 0; initscr(); idlok(stdscr, TRUE); scrollok(stdscr, TRUE); cbreak(); noecho(); keypad(stdscr, TRUE); intrflush(stdscr, FALSE); printw("nom : %s\n", niveau->nom); int x, y; int nbAppuiUp = 0; char *saisie; while(continuer){ finCommande = 0; saisie = malloc(TAILLE_MAX_COMMANDE*sizeof(char)); debutLigne(commande, niveau); while(finCommande == 0){ ch = wgetch(stdscr); if(ch != KEY_UP && ch !=KEY_DOWN) nbAppuiUp = 0; if (ch == KEY_BACKSPACE) { getyx(stdscr, y, x); if(x > strlen(commande->directory)+3){ move(y, x-1); delch(); strcpy(saisie, substr(saisie, 0, strlen(saisie)-1)); } } else if(ch == KEY_LEFT){ getyx(stdscr, y, x); move(y, x-1); } else if(ch == KEY_RIGHT){ getyx(stdscr, y, x); move(y, x+1); } else if (ch == KEY_UP) { nbAppuiUp++; String *temp = malloc(sizeof(String)); temp = niveau->history->premier; if (temp->suivant != NULL) { int i = 0; while(i < nbAppuiUp && temp->suivant != NULL){ temp = temp->suivant; i++; } free(saisie); saisie = malloc(sizeof(char)*TAILLE_MAX_COMMANDE); strcpy(saisie, temp->string); effaceCommande(commande); printw("%s", saisie); } } else if (ch == KEY_DOWN) { nbAppuiUp--; String *temp = malloc(sizeof(String)); temp = niveau->history->premier; if (temp->suivant != NULL) { int i = 0; while(i < nbAppuiUp && temp->suivant != NULL){ temp = temp->suivant; i++; } free(saisie); saisie = malloc(sizeof(char)*TAILLE_MAX_COMMANDE); strcpy(saisie, temp->string); effaceCommande(commande); printw("%s", saisie); } } else if(ch == KEY_DC){ delch(); strcpy(saisie, substr(saisie, 0, strlen(saisie)-1)); } else if(ch == '\t'){ effaceCommande(commande); char *essai = malloc(sizeof(char)*TAILLE_MAX_COMMANDE); if(strlen(autoComplete(saisie, niveau)) == 0) finCommande = 1; else{ strcpy(saisie, strcat(saisie, autoComplete(saisie, niveau))); printw("%s", saisie); } } else if(ch == '\n'){ finCommande = 1; printw("\n"); } else{ printw("%c", ch); sprintf(saisie, "%s%c", saisie, ch); } } strcpy(commande->commande, saisie); execution(commande, niveau); // free(saisie); } endwin(); return 0; }
viewkill() /* Просмотр списка процессов и посылка сигналов /****************************************************************************/ { extern int use_keycap; /* признак использования своей настройки на клавиатуру */ extern int use_colors; /* признак использования цветов */ extern WINDOW *save_scr; /* окно для сохранения экрана */ extern int nosave_ask; /* признак "несохранения" экрана для ask */ extern chtype atr[]; /* раскраска */ extern unsigned char *fnd_str; /* строка для временных данных */ extern size_t fnd_len; /* место, выделенное для fnd_str*/ static char *dmenu="1+ - 2+ - 3+Next - 4+ - 5+ - 6+User - 7+Search- 8+Kill - 9+SigNum- 10+Quit "; static char *name="/tmp/ps_text_XXXXXX"; extern struct win win71; /* окно с запросом */ extern struct win win72; /* окно с ошибкой */ extern struct win win73; /* запрос номера посылаемого сигнала */ extern struct win win75; /* запрос имени пользователя */ extern char user_name[LOGNM_MAX]; /* имя пользователя */ extern uid_t user_eid; /* эффективный UserID или 0, если getuid()==0*/ FILE *file=NULL; int stop=0; /*признак окончания просмотра */ int ch; long nextseek; /* смещение на следующий экран*/ int x; int y; int x_beg=0; /* сдвиг выводимой части текста */ int lines=LINES-3; /* количество строк для вывода */ long firstline=0; /* номер первой выводимой строки файла*/ int find; /* признак поиска */ long srchlnseek; /* смещение до начала строки при поиске*/ long srchseek; /* смещение до символа после первого совпадения*/ long srchseeklast=(-1);/* смещение предыдущего поиска */ int srchln; /* номер строки при поиске */ int old_nosave; /* станое значение nosave_ask */ int i; int fd; /* дескриптор файла со списком процессов */ int len; /* максимальная длина выводимой части имени*/ int need_refr=1; /* признак необходимости перевывода списка*/ char *ptr; /* имя файла для вывода ошибки и для прохода по шаблону */ struct inp_lst inp_lst[2]; /* список ввода для inp_menu()*/ struct inp_lst usr_inp_lst[2]; /* список ввода для inp_menu()*/ extern long linesback(); /* поиск смещения в файле на несколько строк назад */ long *seeks=NULL; /* массив смещений в списке процессов*/ long seeks_len=0; /* количество элементов в seeks */ char *stats=NULL; /* признаки отметки */ int nlines=1; /* количество строк в файле списка процессов*/ int curline=0; /* номер текущей строки */ long nproc; /* номер процесса */ static int sig=15; /* номер сигнала */ static char usr_str[30]={'\0'};/* строка с именем пользователя для ps(1)*/ char *tmp_first; /* для запоминания первой строки*/ int pos; /* для работы с tmp_first */ int next_srch=0; /* признак продолжения поиска без запроса */ /*==========================================================================*/ tmp_first=malloc(COLS); tst_err_malloc(tmp_first,27); /* выполняет exit, если NULL*/ /* обычным пользователям по умолчанию показывать только свои */ if(user_eid && !usr_str[0]){ strncpy(usr_str, user_name, sizeof(usr_str)); usr_str[sizeof(usr_str)-1]='\0'; } usr_inp_lst[0].str=usr_str; /* usr_inp_lst[0].fld_len=...; выставит inp_menu()*/ usr_inp_lst[0].str_len=sizeof(usr_str); usr_inp_lst[0].npunkt=1; usr_inp_lst[1].str=NULL; /* признак конца списка для inp_menu()*/ inp_lst[0].str=(char *)fnd_str; /* inp_lst[0].fld_len=...; выставит inp_menu()*/ inp_lst[0].str_len=fnd_len; inp_lst[0].npunkt=1; inp_lst[1].str=NULL; /* признак конца списка для inp_menu()*/ mktemp(name); old_nosave=nosave_ask; nosave_ask=1; if(old_nosave==0){ delsoob(); overwrite(curscr, save_scr); } attrset(MAIN_PANEL_ATTR); mywbkgd(stdscr, MAIN_PANEL_ATTR); move(0,0); addch(' '); refresh(); clear(); #ifdef NCURSES mywbkgd(stdscr, MAIN_PANEL_ATTR); #endif move(0,0); addch(' '); attrset(MAIN_PANEL_ATTR); mywbkgd(stdscr, MAIN_PANEL_ATTR); refresh(); len=strlen(name); stop=0; while(!stop){ if(need_refr){ need_refr=0; if(file) fclose(file); switch(fork()) { case -1: endwin(); fprintf(stderr, "Can't fork\n"); exit(-1); break; case 0: /* порожденный процесс*/ fd=creat(name, 0777); if(fd<=0){ endwin(); fprintf(stderr, "Can't create file %s\n", name); exit(-1); } dup2(fd, 1); dup2(fd, 2); #ifdef FREEBSD execlp("ps", "ps", "-awwxo", "user pid ppid stat start tty command", NULL); #else if(usr_str[0]) { /* задано имя пользователя для которого смотрятся процессы */ execlp("ps", "ps", "-f", "-u", usr_str, NULL); }else{ execlp("ps", "ps", "-ef", NULL); } #endif fprintf(stderr, "Can't exec to ps\n"); exit(-1); break; default: wait(NULL); break; } if(!(file=fopen(name, "r"))) { /* не открывается файл */ endwin(); fprintf(stderr, "Can't open file %s\n", name); exit(-1); } i=1; pos=0; /* первую строку читаем в tmp_first */ do{ if( (tmp_first[pos] = getc(file)) == '\n') { i++; }else{ if(pos<COLS-1 && !feof(file)) pos++; } }while(i==1 && !feof(file)); tmp_first[pos] = '\0'; while(!feof(file)){ if(getc(file)=='\n') i++; } nlines=i-2; if(i>seeks_len){ if(seeks_len){ free(seeks); free(stats); } seeks_len=i-1; seeks=malloc((i-1)*sizeof(long)); tst_err_malloc(seeks,25); /* выполняет exit, если NULL*/ stats=malloc((i-1)*sizeof(char)); tst_err_malloc(stats,26); /* выполняет exit, если NULL*/ } rewind(file); i=0; while(!feof(file)){ if(getc(file)=='\n'){ seeks[i]=ftell(file); stats[i]='\0'; i++; } } /* проверить корректность текущей строки и первой строки */ if(curline>nlines-1){ curline=nlines-1; if(curline<firstline) firstline=curline; } } mywbkgd(stdscr, MAIN_PANEL_ATTR); /* Заголовок просмотра */ attrset(MAIN_PANEL_TOP_ATTR); move(0,0); if(x_beg){ printw(" Shift: %d", x_beg); } if(firstline>=0) { /* известен номер первой строки*/ printw(" Line: %d", curline+1); }else{ printw(" Line: ?"); } if(usr_str[0]) { /* показываются процессы выбранного пользователя*/ addstr(" User: "******" All users"); } getyx(stdscr, y, x); while(x++<COLS) addch(' '); attrset(MAIN_PANEL_ATTR); /* вывод первой строки */ move(FIRST-1, 0); addstr(tmp_first); fseek(file, seeks[firstline], 0); y=FIRST; while(feof(file)==0 && ferror(file)==0 && y<FIRST+lines){ x=0; if(y-FIRST==curline-firstline) attrset(MAIN_PANEL_PTR_ATTR); do{ ch=getc(file); if(feof(file)==0 && ferror(file)==0){ if((x-x_beg)==COLS) { attrset(MAIN_PANEL_PTR_ATTR); move(y, COLS-1); addch('>'); attrset(MAIN_PANEL_ATTR); }else{ if(ch=='\t'){ x=((x+8)/8)*8-1; ch=' '; } if((x-x_beg)<COLS && ch!='\n'){ if(x>=x_beg){ move(y, (x-x_beg)); if(ch<' ' || ch==0177) { attrset(MAIN_PANEL_PTR_ATTR); ch=CTRL(ch) +'@'; addch(ch); attrset(MAIN_PANEL_ATTR); }else{ addch(ch); } } } } x++; } }while(ch!='\n' && feof(file)==0 && ferror(file)==0); if(y-FIRST==curline-firstline){ /*дописать конец текущей строки*/ if(x) x--; /* при выводе в конце цикла x++ */ if(x<x_beg) { /* эта строка при таком смещении совсем не выводилась*/ x=x_beg; } x-=x_beg; /* теперь это координата в окне */ move(y, x); while(x<COLS){ addch(' '); x++; } attrset(MAIN_PANEL_ATTR); } y++; } /* нарисовать строку с клавишами */ move(LINES-1, 0); attrset(BOTT_LINE_KEYS_ATTR); for(ptr=dmenu;*ptr;ptr++){ switch(*ptr) { case '+': attrset(BOTT_LINE_TEXT_ATTR); break; case '-': attrset(BOTT_LINE_KEYS_ATTR); break; default: addch(*ptr); break; } } refresh(); if(ferror(file)) { /* такое бывает с Symlink на каталог */ ch=ESC; }else{ if(use_keycap) { /*использовать свою настройку на клавиатуру */ ch=getkey_(); }else{ /* использовать стандартные средства curses */ ch=getch(); } } switch(ch) { case K_SD: /*стрелка вниз*/ case KEY_DOWN: /*стрелка вниз*/ srchseeklast=(-1); if(curline<nlines-1){ curline++; if(curline>firstline+lines-1) firstline++; } break; case K_SU: /*стрелка вверх*/ case KEY_UP: /*стрелка вверх*/ srchseeklast=(-1); if(curline>0) curline--; if(curline<firstline) firstline--; break; case K_PAGE_UP: case KEY_PPAGE: srchseeklast=(-1); if(curline>0){ curline-=lines-2; if(curline<0) curline=0; firstline-=lines-2; if(firstline<0) firstline=0; } break; case K_PAGE_DN: case KEY_NPAGE: srchseeklast=(-1); if(curline<nlines-1){ curline+=lines-2; if(curline>nlines-1) curline=nlines-1; firstline+=lines-2; if(firstline>nlines-(lines-2)) firstline=nlines-(lines-2); if(firstline<0) firstline=0; } break; case K_HOME: case KEY_HOME: srchseeklast=(-1); curline=0; firstline=0; break; case K_END: case KEY_END: srchseeklast=(-1); curline=nlines-1; firstline=nlines-(lines-2); if(firstline<0) firstline=0; break; case K_SR: /* Стрелка вправо */ case KEY_RIGHT: /* Стрелка вправо */ srchseeklast=(-1); x_beg++; break; case K_SL: /* Стрелка влево */ case KEY_LEFT: /* Стрелка влево */ srchseeklast=(-1); if(x_beg) x_beg--; break; case K_F6: /* User */ case KEY_F(6): if(inp_menu(usr_inp_lst, &win75, 1, 0)==1 && usr_str[0]) { /* нужно только usr_str[0] */ }else{ usr_str[0] = '\0'; } srchseeklast=(-1); curline=0; firstline=0; need_refr++; break; case K_F3: /* продолжение поиска */ case KEY_F(3): next_srch=1; case K_F7: /* поиск */ case KEY_F(7): if( (next_srch && fnd_str[0]) || (inp_menu(inp_lst, &win71, 1, 0)==1 && fnd_str[0])){ srchlnseek=seeks[curline]; srchln=curline+1; find=0; fseek(file, srchlnseek, 0); while(feof(file)==0 && ferror(file)==0 && find==0){ ch=getc(file); if(!feof(file)){ if(ch=='\n'){ srchln++; srchlnseek=ftell(file); } if( cmp_chrs(ch, fnd_str[0], 0)==0 ){ srchseek=ftell(file); ptr=(char*)fnd_str; if(srchseeklast<srchseek){ /* -1 или предыдущий */ while(feof(file)==0 && *ptr && cmp_chrs(ch, *ptr, 0)==0 ){ ch=getc(file); ptr++; } } if(*ptr=='\0') { /* полное соответствие */ find=1; if(srchseek-srchlnseek>=COLS-2) { /* образец не виден на экране */ x_beg=srchseek-srchlnseek-(COLS/2); }else{ x_beg=0; } srchseeklast=srchseek; curline=srchln-1; if(curline>firstline+lines-1 || curline<firstline) firstline=curline; }else{ /* несоответствие в каком-то (не первом) символе*/ fseek(file, srchseek, 0); /* продолжить поиск с места, где найден совпад.символ*/ } } } } if(!find){ ask(&win72, 2, 0); } } next_srch=0; break; case K_F8: /* посылка сигнала */ case KEY_F(8): need_refr++; fseek(file, seeks[curline], 0); do{ /* пропустить ведущие пробелы*/ ch=getc(file); }while(isspace(ch) && feof(file)==0 && ch!='\n'); /* пропустить имя пользователя */ while(isspace(ch)==0 && feof(file)==0 && ch!='\n'){ ch=getc(file); } /* пропустить пробелы после имени */ while(isspace(ch) && feof(file)==0 && ch!='\n'){ ch=getc(file); } if(isdigit(ch) && feof(file)==0 && ch!='\n') { /* действительно какой-то номер */ fseek(file, -1L, 1); /* вернуться на символ назад */ nproc=(-1); fscanf(file,"%ld", &nproc); if(nproc>=0 && nproc!=getpid()) { if(kill((pid_t)nproc, sig)) beep(); }else{ beep(); beep(); beep(); } }else{ beep(); beep(); beep(); } break; case K_F9: /* посылка сигнала */ case KEY_F(9): if((i=ask(&win73, sig, VERT))>0) sig=i; break; case K_ESC: /*конец работы*/ case ESC: /*конец работы*/ case K_F0: case KEY_F(0): stop++; break; case K_REFRESH: /* клавиша перевывода экрана */ case REFRESH: /* клавиша перевывода экрана */ clearok(stdscr, TRUE); case REREAD: /* клавиша пересчитывания каталога */ case K_REREAD: need_refr++; break; default: beep(); break; } } /* while !stop */ fclose(file); unlink(name); mywbkgd(stdscr, A_NORMAL); wattrset(stdscr, A_NORMAL); /* #ifdef sun */ /* из-зи ошибок в curses или в описании терминала очистка вып-ся не тем цветом*/ move(0,0); addch(' '); refresh(); /* #endif */ clear(); #ifdef NCURSES mywbkgd(stdscr, MAIN_PANEL_ATTR); #endif refresh(); overwrite(save_scr, stdscr); #ifdef FREEBSD touchwin(stdscr); #endif clearok(stdscr, TRUE); refresh(); if(old_nosave==0) nosave_ask=0; if(seeks_len){ free(seeks); free(stats); } free(tmp_first); }
static void prompt_onDraw(ToxWindow *self, Tox *m) { int x2, y2; getmaxyx(self->window, y2, x2); ChatContext *ctx = self->chatwin; line_info_print(self); wclear(ctx->linewin); curs_set(1); if (ctx->len > 0) mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]); StatusBar *statusbar = self->stb; mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2); wmove(statusbar->topline, 0, 0); if (statusbar->is_online) { int colour = WHITE; const char *status_text = "Unknown"; switch (statusbar->status) { case TOX_USERSTATUS_NONE: status_text = "Online"; colour = GREEN; break; case TOX_USERSTATUS_AWAY: status_text = "Away"; colour = YELLOW; break; case TOX_USERSTATUS_BUSY: status_text = "Busy"; colour = RED; break; case TOX_USERSTATUS_INVALID: status_text = "ERROR"; colour = MAGENTA; break; } wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wprintw(statusbar->topline, " [%s]", status_text); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s", statusbar->nick); wattroff(statusbar->topline, A_BOLD); } else { wprintw(statusbar->topline, " [Offline]"); wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s ", statusbar->nick); wattroff(statusbar->topline, A_BOLD); } /* Reset statusbar->statusmsg on window resize */ if (x2 != self->x) { char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {0}; pthread_mutex_lock(&Winthread.lock); tox_get_self_status_message(m, (uint8_t *) statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH); pthread_mutex_unlock(&Winthread.lock); snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); statusbar->statusmsg_len = strlen(statusbar->statusmsg); } self->x = x2; /* Truncate note if it doesn't fit in statusbar */ uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3; if (statusbar->statusmsg_len > maxlen) { statusbar->statusmsg[maxlen - 3] = '\0'; strcat(statusbar->statusmsg, "..."); statusbar->statusmsg_len = maxlen; } if (statusbar->statusmsg[0]) wprintw(statusbar->topline, " - %s", statusbar->statusmsg); mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2); int y, x; getyx(self->window, y, x); (void) x; int new_x = ctx->start ? x2 - 1 : wcswidth(ctx->line, ctx->pos); wmove(self->window, y + 1, new_x); wrefresh(self->window); if (self->help->active) help_onDraw(self); }
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) { ChatContext *ctx = (ChatContext *) self->chatwin; StatusBar *statusbar = (StatusBar *) self->stb; int x, y, y2, x2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); /* BACKSPACE key: Remove one character from line */ if (key == 0x107 || key == 0x8 || key == 0x7f) { if (ctx->pos > 0) { ctx->line[--ctx->pos] = L'\0'; if (x == 0) mvwdelch(self->window, y - 1, x2 - 1); else mvwdelch(self->window, y, x - 1); } } else /* Add printable chars to buffer and print on input space */ #if HAVE_WIDECHAR if (iswprint(key)) { #else if (isprint(key)) { #endif if (ctx->pos < (MAX_STR_SIZE-1)) { mvwaddstr(self->window, y, x, wc_to_char(key)); ctx->line[ctx->pos++] = key; ctx->line[ctx->pos] = L'\0'; } } /* RETURN key: Execute command or print line */ else if (key == '\n') { uint8_t *line = wcs_to_char(ctx->line); line[ctx->pos+1] = '\0'; wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); wclrtobot(self->window); bool close_win = false; if (line[0] == '/') { if (close_win = !strncmp(line, "/close", strlen("/close"))) { int f_num = self->num; delwin(ctx->linewin); delwin(statusbar->topline); del_window(self); disable_chatwin(f_num); } else if (!strncmp(line, "/me ", strlen("/me "))) send_action(self, ctx, m, line + strlen("/me ")); else if (!strncmp(line, "/help", strlen("/help"))) print_chat_help(ctx); else if (!strncmp(line, "/invite", strlen("/invite"))) chat_groupinvite(self, ctx, m, line + strlen("/invite ")); else if(!strncmp(line, "/sendfile ", strlen("/sendfile "))) chat_sendfile(self, ctx, m, line + strlen("/sendfile ")); else execute(ctx->history, self->prompt, m, line, ctx->pos); } else { /* make sure the string has at least non-space character */ if (!string_is_empty(line)) { uint8_t selfname[TOX_MAX_NAME_LENGTH]; tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH); print_time(ctx->history); wattron(ctx->history, COLOR_PAIR(GREEN)); wprintw(ctx->history, "%s: ", selfname); wattroff(ctx->history, COLOR_PAIR(GREEN)); if (line[0] == '>') { wattron(ctx->history, COLOR_PAIR(GREEN)); wprintw(ctx->history, "%s\n", line); wattroff(ctx->history, COLOR_PAIR(GREEN)); } else wprintw(ctx->history, "%s\n", line); if (!statusbar->is_online || tox_sendmessage(m, self->num, line, strlen(line) + 1) == 0) { wattron(ctx->history, COLOR_PAIR(RED)); wprintw(ctx->history, " * Failed to send message.\n"); wattroff(ctx->history, COLOR_PAIR(RED)); } } } if (close_win) { free(ctx); free(statusbar); } else { ctx->line[0] = L'\0'; ctx->pos = 0; } free(line); } } static void chat_onDraw(ToxWindow *self, Tox *m) { curs_set(1); int x, y; getmaxyx(self->window, y, x); ChatContext *ctx = (ChatContext *) self->chatwin; /* Draw status bar */ StatusBar *statusbar = (StatusBar *) self->stb; mvwhline(statusbar->topline, 1, 0, '-', x); wmove(statusbar->topline, 0, 0); /* Draw name, status and note in statusbar */ if (statusbar->is_online) { char *status_text = "Unknown"; int colour = WHITE; TOX_USERSTATUS status = statusbar->status; switch(status) { case TOX_USERSTATUS_NONE: status_text = "Online"; colour = GREEN; break; case TOX_USERSTATUS_AWAY: status_text = "Away"; colour = YELLOW; break; case TOX_USERSTATUS_BUSY: status_text = "Busy"; colour = RED; break; } wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s ", self->name); wattroff(statusbar->topline, A_BOLD); wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wprintw(statusbar->topline, "[%s]", status_text); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); } else { wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " %s ", self->name); wattroff(statusbar->topline, A_BOLD); wprintw(statusbar->topline, "[Offline]"); } /* Reset statusbar->statusmsg on window resize */ if (x != self->x) { uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'}; tox_copy_statusmessage(m, self->num, statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH); snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); statusbar->statusmsg_len = tox_get_statusmessage_size(m, self->num); } self->x = x; /* Truncate note if it doesn't fit in statusbar */ uint16_t maxlen = x - getcurx(statusbar->topline) - 6; if (statusbar->statusmsg_len > maxlen) { statusbar->statusmsg[maxlen] = '\0'; statusbar->statusmsg_len = maxlen; } if (statusbar->statusmsg[0]) { wattron(statusbar->topline, A_BOLD); wprintw(statusbar->topline, " | %s | ", statusbar->statusmsg); wattroff(statusbar->topline, A_BOLD); } wprintw(statusbar->topline, "\n"); mvwhline(ctx->linewin, 0, 0, '_', x); wrefresh(self->window); }
/* * Display text from a file in a dialog box. */ int dialog_textbox(const char *title, const char *tbuf, int initial_height, int initial_width) { int i, x, y, cur_x, cur_y, key = 0; int height, width, boxh, boxw; int passed_end; WINDOW *dialog, *box; begin_reached = 1; end_reached = 0; page_length = 0; hscroll = 0; buf = tbuf; page = buf; /* page is pointer to start of page to be displayed */ do_resize: getmaxyx(stdscr, height, width); if (height < 8 || width < 8) return -ERRDISPLAYTOOSMALL; if (initial_height != 0) height = initial_height; else if (height > 4) height -= 4; else height = 0; if (initial_width != 0) width = initial_width; else if (width > 5) width -= 5; else width = 0; /* center dialog box on screen */ x = (COLS - width) / 2; y = (LINES - height) / 2; draw_shadow(stdscr, y, x, height, width); dialog = newwin(height, width, y, x); keypad(dialog, TRUE); /* Create window for box region, used for scrolling text */ boxh = height - 4; boxw = width - 2; box = subwin(dialog, boxh, boxw, y + 1, x + 1); wattrset(box, dlg.dialog.atr); wbkgdset(box, dlg.dialog.atr & A_COLOR); keypad(box, TRUE); /* register the new window, along with its borders */ draw_box(dialog, 0, 0, height, width, dlg.dialog.atr, dlg.border.atr); wattrset(dialog, dlg.border.atr); mvwaddch(dialog, height - 3, 0, ACS_LTEE); for (i = 0; i < width - 2; i++) waddch(dialog, ACS_HLINE); wattrset(dialog, dlg.dialog.atr); wbkgdset(dialog, dlg.dialog.atr & A_COLOR); waddch(dialog, ACS_RTEE); print_title(dialog, title, width); print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE); wnoutrefresh(dialog); getyx(dialog, cur_y, cur_x); /* Save cursor position */ /* Print first page of text */ attr_clear(box, boxh, boxw, dlg.dialog.atr); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); while ((key != KEY_ESC) && (key != '\n')) { key = wgetch(dialog); switch (key) { case 'E': /* Exit */ case 'e': case 'X': case 'x': case 'q': delwin(box); delwin(dialog); return 0; case 'g': /* First page */ case KEY_HOME: if (!begin_reached) { begin_reached = 1; page = buf; refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); } break; case 'G': /* Last page */ case KEY_END: end_reached = 1; /* point to last char in buf */ page = buf + strlen(buf); back_lines(boxh); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case 'K': /* Previous line */ case 'k': case KEY_UP: if (!begin_reached) { back_lines(page_length + 1); /* We don't call print_page() here but use * scrolling to ensure faster screen update. * However, 'end_reached' and 'page_length' * should still be updated, and 'page' should * point to start of next page. This is done * by calling get_line() in the following * 'for' loop. */ scrollok(box, TRUE); wscrl(box, -1); /* Scroll box region down one line */ scrollok(box, FALSE); page_length = 0; passed_end = 0; for (i = 0; i < boxh; i++) { if (!i) { /* print first line of page */ print_line(box, 0, boxw); wnoutrefresh(box); } else /* Called to update 'end_reached' and 'page' */ get_line(); if (!passed_end) page_length++; if (end_reached && !passed_end) passed_end = 1; } print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } break; case 'B': /* Previous page */ case 'b': case 'u': case KEY_PPAGE: if (begin_reached) break; back_lines(page_length + boxh); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case 'J': /* Next line */ case 'j': case KEY_DOWN: if (!end_reached) { begin_reached = 0; scrollok(box, TRUE); scroll(box); /* Scroll box region up one line */ scrollok(box, FALSE); print_line(box, boxh - 1, boxw); wnoutrefresh(box); print_position(dialog); wmove(dialog, cur_y, cur_x); /* Restore cursor position */ wrefresh(dialog); } break; case KEY_NPAGE: /* Next page */ case ' ': case 'd': if (end_reached) break; begin_reached = 0; refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case '0': /* Beginning of line */ case 'H': /* Scroll left */ case 'h': case KEY_LEFT: if (hscroll <= 0) break; if (key == '0') hscroll = 0; else hscroll--; /* Reprint current page to scroll horizontally */ back_lines(page_length); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case 'L': /* Scroll right */ case 'l': case KEY_RIGHT: if (hscroll >= MAX_LEN) break; hscroll++; /* Reprint current page to scroll horizontally */ back_lines(page_length); refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); break; case KEY_ESC: key = on_key_esc(dialog); break; case KEY_RESIZE: back_lines(height); delwin(box); delwin(dialog); on_key_resize(); goto do_resize; } } delwin(box); delwin(dialog); return key; /* ESC pressed */ }
int calc_main() { char cmd[1005]; char history[HIST][1005]; char einfo[20][30]={ "", "", "矩阵太大", "矩阵宽度不一致", "矩阵长度不一致", "矩阵大小不一致", "除数不能为0", "底数必须为正数", "必须为正方矩阵", "越界错", "矩阵长度必须为1", "表达式出错", "操作数必须不为矩阵", "该矩阵无法求逆", "变量名称错", "变量数目过多", "矩阵输入错误", "单步值不能为0", "表达式出错", ""}; int y,x,res,i,ch,hi,oldmode; oldmode=uinfo.mode; modify_user_mode(CALC); for(i=0;i<HIST;i++) history[i][0]=0; res = get_var("res"); set_var(vars+get_var("%pi"), Pi); set_var(vars+get_var("%e"), exp(1)); clear(); outline("欢迎使用超级计算器1.0 作者:[email protected]\n"); outline("输入exit退出,输入help帮助\n\n"); while(1) { hi=0; getyx(&y, &x); cmd[0]=0; do{ UPDOWN = true; ch = multi_getdata(y, x, scr_cols-1, "> ", cmd, 995, 13, 0,0 ); UPDOWN = false; if(ch==-KEY_UP) { if(hi==HIST) cmd[0]=0; else strncpy(cmd, history[hi], 1000); hi++; if(hi>HIST) hi=0; } else if(ch==-KEY_DOWN) { hi--; if(hi<0) hi=HIST; if(hi==HIST) cmd[0]=0; else strncpy(cmd, history[hi], 1000); } } while(ch<0); y = y-1+ch; if(y>=scr_lns) y = scr_lns-1; move(y, 0); outline("\n"); if(!cmd[0]) continue; if(!strncasecmp(cmd, "exit", 5)) break; if(!strncasecmp(cmd, "quit", 5)) break; for(i=HIST-1;i>0;i--) strncpy(history[i],history[i-1],1000); strncpy(history[0],cmd,1000); if(!strncasecmp(cmd, "help", 5)||!strncasecmp(cmd, "?", 2)) { outline("变量: 1到6个字母,例如x=3\n"); outline("常量: %pi, %e\n"); outline("矩阵: [3,4;5,6] a(3:4,1:5:2) 1:5:0.5\n"); outline("函数: sin,cos,tan,asin,acos,atan,log,exp,ln,fact,\n"); outline(" sinh,cosh,tanh,asinh,acosh,atanh\n"); outline(" abs,sign,sqr,sqrt,round,floor,ceil\n"); outline(" det,inv\n"); outline("操作: + - * / ^ '(转置) .*(矩阵乘) ./(矩阵除) \n"); continue; } if(strchr(cmd, '=')) { i=strchr(cmd, '=')-cmd; if(i<=0||!check_var_name(cmd, i)) { calcerr=19; goto checkcalcerr; } cmd[i]=0; res = get_var(cmd); i++; } else { res = get_var("res"); i=0; } eval(vars+res, cmd+i, 0, strlen(cmd+i)-1); checkcalcerr: if(calcerr) { outline(einfo[calcerr]); outline("\n"); calcerr=0; continue; } else print_var(vars+res); } for(i=0;i<vart;i++) del(vars+i); modify_user_mode(oldmode); return 0; }
int main(int ac, char **av) { int saved_x, saved_y; char *mode; int res; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); conf_parse(av[1]); conf_read(NULL); mode = getenv("MENUCONFIG_MODE"); if (mode) { if (!strcasecmp(mode, "single_menu")) single_menu_mode = 1; } getyx(stdscr, saved_y, saved_x); if (init_dialog(NULL)) { fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); return 1; } set_config_filename(conf_get_configname()); do { conf(&rootmenu); dialog_clear(); if (conf_get_changed()) res = dialog_yesno(NULL, _("Do you wish to save your " "new configuration?\n" "<ESC><ESC> to continue."), 6, 60); else res = -1; } while (res == KEY_ESC); end_dialog(saved_x, saved_y); switch (res) { case 0: if (conf_write(filename)) { fprintf(stderr, _("\n\n" "Error during writing of the configuration.\n" "Your configuration changes were NOT saved." "\n\n")); return 1; } case -1: printf(_("\n\n" "*** End of configuration.\n" "*** Execute 'make' to build or try 'make help'." "\n\n")); break; default: fprintf(stderr, _("\n\n" "Your configuration changes were NOT saved." "\n\n")); } return conf_write_autoconf(); }
/* * Print a string of text in a window, automatically wrap around to the * next line if the string is too long to fit on one line. Newline * characters '\n' are propperly processed. We start on a new line * if there is no room for at least 4 nonblanks following a double-space. */ void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x) { int newl, cur_x, cur_y; int prompt_len, room, wlen; char tempstr[MAX_LEN + 1], *word, *sp, *sp2, *newline_separator = 0; strcpy(tempstr, prompt); prompt_len = strlen(tempstr); if (prompt_len <= width - x * 2) { /* If prompt is short */ wmove(win, y, (width - prompt_len) / 2); waddstr(win, tempstr); } else { cur_x = x; cur_y = y; newl = 1; word = tempstr; while (word && *word) { sp = strpbrk(word, "\n "); if (sp && *sp == '\n') newline_separator = sp; if (sp) *sp++ = 0; /* Wrap to next line if either the word does not fit, or it is the first word of a new sentence, and it is short, and the next word does not fit. */ room = width - cur_x; wlen = strlen(word); if (wlen > room || (newl && wlen < 4 && sp && wlen + 1 + strlen(sp) > room && (!(sp2 = strpbrk(sp, "\n ")) || wlen + 1 + (sp2 - sp) > room))) { cur_y++; cur_x = x; } wmove(win, cur_y, cur_x); waddstr(win, word); getyx(win, cur_y, cur_x); /* Move to the next line if the word separator was a newline */ if (newline_separator) { cur_y++; cur_x = x; newline_separator = 0; } else cur_x++; if (sp && *sp == ' ') { cur_x++; /* double space */ while (*++sp == ' ') ; newl = 1; } else newl = 0; word = sp; } } }
static void test_redraw(WINDOW *win) { WINDOW *win1; WINDOW *win2; bool done = FALSE; int ch, y, x; int max_y, max_x; int beg_y, beg_x; assert(win != 0); scrollok(win, TRUE); keypad(win, TRUE); getmaxyx(win, max_y, max_x); getbegyx(win, beg_y, beg_x); while (!done && win != 0) { ch = wgetch(win); getyx(win, y, x); switch (ch) { case 'q': /* FALLTHRU */ case ESCAPE: done = TRUE; break; case 'w': win1 = newwin(max_y, max_x, beg_y, beg_x); win2 = newwin(max_y - 2, max_x - 2, beg_y + 1, beg_x + 1); box(win1, 0, 0); wrefresh(win1); test_redraw(win2); delwin(win2); delwin(win1); touchwin(win); break; case '!': /* * redrawwin() and wredrawln() do not take into account the * possibility that the cursor may have moved. That makes them * cumbersome for using with a shell command. So we simply * trash the current line of the window using backspace/overwrite. */ trash(beg_x, max_x, x + beg_x); break; #ifdef NCURSES_VERSION case '@': /* * For a shell command, we can work around the problem noted above * using mvcur(). It is ifdef'd for NCURSES, since X/Open does * not define the case where the old location is unknown. */ IGNORE_RC(system("date")); mvcur(-1, -1, y, x); break; #endif case CTRL('W'): redrawwin(win); break; case CTRL('L'): wredrawln(win, y, 1); break; case KEY_UP: if (y > 0) wmove(win, y - 1, x); break; case KEY_DOWN: if (y < max_y) wmove(win, y + 1, x); break; case KEY_LEFT: if (x > 0) wmove(win, y, x - 1); break; case KEY_RIGHT: if (x < max_x) wmove(win, y, x + 1); break; default: if (ch > KEY_MIN) { waddstr(win, keyname(ch)); } else { waddstr(win, unctrl(UChar(ch))); } break; } wnoutrefresh(win); doupdate(); } }
sysdig_table_action sinsp_cursesui::handle_textbox_input(int ch) { bool closing = false; string* str = NULL; bool handled = true; // // Pick the right string based on what we're doing // if(m_output_filtering) { str = &m_manual_filter; } else if(m_output_searching) { str = &m_manual_search_text; } else { if(m_search_caller_interface) { str = m_search_caller_interface->get_last_search_string(); } else { ASSERT(false); } } switch(ch) { case KEY_F(1): m_mainhelp_page = new curses_mainhelp_page(this); return STA_NONE; case KEY_F(2): m_is_filter_sysdig = !m_is_filter_sysdig; *str = ""; m_cursor_pos = 0; render(); return STA_NONE; case KEY_DOWN: case KEY_UP: case KEY_PPAGE: case KEY_NPAGE: if(m_spy_box != NULL) { m_spy_box->handle_input(ch); } else { m_viz->handle_input(ch); } return STA_NONE; case 27: // ESC *str = ""; if(m_spy_box != NULL) { m_spy_box->scroll_to(m_search_start_x, m_search_start_y); m_spy_box->up(); } // FALL THROUGH case '\n': case '\r': case KEY_ENTER: case 6: // CTRL+F case KEY_F(4): closing = true; curs_set(0); if(m_is_filter_sysdig && !m_output_searching) { if(*str != "") { sinsp_filter* f; try { f = new sinsp_filter(m_inspector, *str); } catch(sinsp_exception e) { // // Backup the cursor position // int cx, cy; getyx(stdscr, cy, cx); // // Print the error string // string wstr = "Invalid sysdig filter"; attrset(m_colors[sinsp_cursesui::FAILED_SEARCH]); mvprintw(m_screenh / 2, m_screenw / 2 - wstr.size() / 2, wstr.c_str()); // // Restore the cursor // attrset(m_colors[PANEL_HIGHLIGHT_FOCUS]); move(cy, cx); curs_set(1); closing = false; break; } delete f; } } break; case KEY_BACKSPACE: case 127: if(str->size() > 0) { m_cursor_pos--; move(m_screenh - 1, m_cursor_pos); addch(' '); move(m_screenh - 1, m_cursor_pos); *str = str->substr(0, str->size() - 1); if(str->size() < 2) { if(m_spy_box != NULL) { m_spy_box->scroll_to(m_search_start_x, m_search_start_y); } } break; } else { return STA_NONE; } case KEY_F(3): if(m_search_caller_interface) { if(m_search_caller_interface->on_search_next()) { render(); } else { string wstr = " NOT FOUND "; attrset(m_colors[sinsp_cursesui::FAILED_SEARCH]); mvprintw(m_screenh / 2, m_screenw / 2 - wstr.size() / 2, wstr.c_str()); render(); } } break; default: handled = false; break; } if(ch >= ' ' && ch <= '~') { addch(ch); *str += ch; m_cursor_pos++; } else { if(!handled) { return STA_NONE; } } if(m_output_filtering) { if(!m_is_filter_sysdig) { // // Update the filter in the datatable // m_datatable->set_freetext_filter(*str); // // Refresh the data and the visualization // m_viz->update_data(m_datatable->get_sample(get_time_delta()), true); m_viz->render(true); } } else if(m_output_searching) { sinsp_table_field* skey = m_datatable->search_in_sample(*str); if(skey != NULL) { int32_t selct = m_datatable->get_row_from_key(skey); m_viz->goto_row(selct); m_search_nomatch = false; } else { m_search_nomatch = true; m_viz->render(true); } } else { if(m_search_caller_interface) { if(m_search_caller_interface->on_search_key_pressed(*str)) { render(); } else { string wstr = " NOT FOUND "; attrset(m_colors[sinsp_cursesui::FAILED_SEARCH]); mvprintw(m_screenh / 2, m_screenw / 2 - wstr.size() / 2, wstr.c_str()); render(); } render(); } else { ASSERT(false); } } if(closing) { sysdig_table_action res = STA_NONE; if(m_is_filter_sysdig && !m_output_searching) { res = STA_SWITCH_VIEW; } m_search_nomatch = false; m_output_filtering = false; m_output_searching = false; m_search_caller_interface = NULL; render(); if(res != STA_NONE) { return res; } } return STA_NONE; }
/* * Display a symbol on somebody's window, processing some control * characters while we are at it. */ void display(xwin_t *win, wchar_t *wc) { /* * Alas, can't use variables in C switch statement. * Workaround these 3 cases with goto. */ if (*wc == win->kill) goto kill; else if (*wc == win->cerase) goto cerase; else if (*wc == win->werase) goto werase; switch (*wc) { case L'\n': case L'\r': wadd_wch(win->x_win, makecchar(L'\n')); getyx(win->x_win, win->x_line, win->x_col); wrefresh(win->x_win); return; case 004: if (win == &my_win) { /* Ctrl-D clears the screen. */ werase(my_win.x_win); getyx(my_win.x_win, my_win.x_line, my_win.x_col); wrefresh(my_win.x_win); werase(his_win.x_win); getyx(his_win.x_win, his_win.x_line, his_win.x_col); wrefresh(his_win.x_win); } return; /* Erase character. */ case 010: /* BS */ case 0177: /* DEL */ cerase: wmove(win->x_win, win->x_line, max(--win->x_col, 0)); getyx(win->x_win, win->x_line, win->x_col); waddch(win->x_win, ' '); wmove(win->x_win, win->x_line, win->x_col); getyx(win->x_win, win->x_line, win->x_col); wrefresh(win->x_win); return; case 027: /* ^W */ werase: { /* * On word erase search backwards until we find * the beginning of a word or the beginning of * the line. */ int endcol, xcol, c; endcol = win->x_col; xcol = endcol - 1; while (xcol >= 0) { c = readwin(win->x_win, win->x_line, xcol); if (c != ' ') break; xcol--; } while (xcol >= 0) { c = readwin(win->x_win, win->x_line, xcol); if (c == ' ') break; xcol--; } wmove(win->x_win, win->x_line, xcol + 1); for (int i = xcol + 1; i < endcol; i++) waddch(win->x_win, ' '); wmove(win->x_win, win->x_line, xcol + 1); getyx(win->x_win, win->x_line, win->x_col); wrefresh(win->x_win); return; } case 025: /* ^U */ kill: wmove(win->x_win, win->x_line, 0); wclrtoeol(win->x_win); getyx(win->x_win, win->x_line, win->x_col); wrefresh(win->x_win); return; case L'\f': if (win == &my_win) wrefresh(curscr); return; case L'\7': write(STDOUT_FILENO, wc, sizeof(*wc)); return; } if (iswprint(*wc) || *wc == L'\t') wadd_wch(win->x_win, makecchar(*wc)); else beep(); getyx(win->x_win, win->x_line, win->x_col); wrefresh(win->x_win); }
int get_str(void *vopt, WINDOW *win) { char *opt = (char *) vopt; char *sp; int oy, ox; int i; signed char c; static char buf[MAXSTR]; getyx(win, oy, ox); wrefresh(win); /* * loop reading in the string, and put it in a temporary buffer */ for (sp = buf; (c = readchar()) != '\n' && c != '\r' && c != ESCAPE; wclrtoeol(win), wrefresh(win)) { if (c == -1) continue; else if (c == erasechar() || c == 8 || c == 127) /* process erase character */ { if (sp > buf) { sp--; for (i = (int) strlen(unctrl(*sp)); i; i--) waddch(win, '\b'); } continue; } else if (c == killchar()) /* process kill character */ { sp = buf; wmove(win, oy, ox); continue; } else if (sp == buf) { if (c == '-' && win != stdscr) break; else if (c == '~') { strcpy(buf, home); waddstr(win, home); sp += strlen(home); continue; } } if (sp >= &buf[MAXINP] || !(isprint(c) || c == ' ')) putchar(CTRL('G')); else { *sp++ = c; waddstr(win, unctrl(c)); } } *sp = '\0'; if (sp > buf) /* only change option if something has been typed */ strucpy(opt, buf, (int) strlen(buf)); mvwprintw(win, oy, ox, "%s\n", opt); wrefresh(win); if (win == stdscr) mpos += (int)(sp - buf); if (c == '-') return MINUS; else if (c == ESCAPE) return QUIT; else return NORM; }
static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) { ChatContext *ctx = (ChatContext *) self->chatwin; struct tm *timeinfo = get_time(); int x, y, y2, x2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); /* BACKSPACE key: Remove one character from line */ if (key == 0x107 || key == 0x8 || key == 0x7f) { if (ctx->pos > 0) { ctx->line[--ctx->pos] = L'\0'; if (x == 0) mvwdelch(self->window, y - 1, x2 - 1); else mvwdelch(self->window, y, x - 1); } } else /* Add printable chars to buffer and print on input space */ #if HAVE_WIDECHAR if (iswprint(key)) { #else if (isprint(key)) { #endif if (ctx->pos < (MAX_STR_SIZE-1)) { mvwaddstr(self->window, y, x, wc_to_char(key)); ctx->line[ctx->pos++] = key; ctx->line[ctx->pos] = L'\0'; } } /* RETURN key: Execute command or print line */ else if (key == '\n') { uint8_t *line = wcs_to_char(ctx->line); wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); wclrtobot(self->window); bool close_win = false; if (line[0] == '/') { if (close_win = strncmp(line, "/close", strlen("/close")) == 0) { set_active_window(0); int groupnum = self->num; delwin(ctx->linewin); del_window(self); close_groupchatwin(m, groupnum); } else if (strncmp(line, "/help", strlen("/help")) == 0) print_groupchat_help(ctx); else execute(ctx->history, self->prompt, m, line, ctx->pos); } else { /* make sure the string has at least non-space character */ if (!string_is_empty(line)) { // uint8_t selfname[TOX_MAX_NAME_LENGTH]; // tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH); // wattron(ctx->history, COLOR_PAIR(CYAN)); // wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); // wattroff(ctx->history, COLOR_PAIR(CYAN)); // wattron(ctx->history, COLOR_PAIR(GREEN)); // wprintw(ctx->history, "%s: ", selfname); // wattroff(ctx->history, COLOR_PAIR(GREEN)); // wprintw(ctx->history, "%s\n", line); if (tox_group_message_send(m, self->num, line, strlen(line) + 1) == -1) { wattron(ctx->history, COLOR_PAIR(RED)); wprintw(ctx->history, " * Failed to send message.\n"); wattroff(ctx->history, COLOR_PAIR(RED)); } } } if (close_win) free(ctx); else { ctx->line[0] = L'\0'; ctx->pos = 0; } free(line); } } static void groupchat_onDraw(ToxWindow *self, Tox *m) { curs_set(1); int x, y; getmaxyx(self->window, y, x); ChatContext *ctx = (ChatContext *) self->chatwin; mvwhline(ctx->linewin, 0, 0, '_', x); wrefresh(self->window); }
int main(int argc, char *argv[]) { int ch; int which = 0; int last; bool replaying = FALSE; bool done = FALSE; char **files; while ((ch = getopt(argc, argv, "ir")) != -1) { switch (ch) { case 'i': use_init = TRUE; break; case 'r': replaying = TRUE; break; default: usage(); break; } } initscr(); cbreak(); noecho(); keypad(stdscr, TRUE); curs_set(0); if (has_colors()) { start_color(); for (ch = 0; ch < COLOR_PAIRS; ++ch) { short pair = ch % COLOR_PAIRS; init_pair(pair, COLOR_WHITE, ch % COLORS); } } files = argv + optind; last = argc - optind - 1; if (replaying) { /* * Use the last file as the initial/current screen. */ if (last < 0) { endwin(); printf("No screen-dumps given\n"); ExitProgram(EXIT_FAILURE); } which = last; if (load_screen(files[which]) == ERR) { endwin(); printf("Cannot load screen-dump %s\n", files[which]); ExitProgram(EXIT_FAILURE); } after_load(); while (!done && (ch = getch()) != ERR) { switch (ch) { case 'n': /* * If we got a "next" here, skip to the final screen before * moving to the next process. */ setup_next(); which = last; done = TRUE; break; case 'q': endwin(); cleanup(files); done = TRUE; break; case KEY_BACKSPACE: case '\b': if (--which < 0) which = last; break; case ' ': if (++which > last) which = 0; break; default: beep(); continue; } if (ch == 'q') { ; } else if (scr_restore(files[which]) == ERR) { endwin(); printf("Cannot load screen-dump %s\n", files[which]); cleanup(files); ExitProgram(EXIT_FAILURE); } else { wrefresh(curscr); } } } else { int y; int x; move(2, 0); printw("Use h,j,k,l or arrows to move around the screen\n"); printw("Press 'q' to quit, ' ' to dump a screen\n"); printw("When the last screen has been dumped, press 'n' to run the\n"); printw("screen-loader. That allows only 'q', backspace and ' ' for\n"); printw("stepping through the dumped/restored screens.\n"); getyx(stdscr, y, x); while (!done) { switch (ch = get_command(which, last)) { case 'n': setup_next(); done = TRUE; break; case 'q': endwin(); cleanup(files); done = TRUE; break; case ' ': if (files[which] != 0) { show_what(which + 1, last); if (scr_dump(files[which]) == ERR) { endwin(); printf("Cannot write screen-dump %s\n", files[which]); cleanup(files); done = TRUE; break; } ++which; if (has_colors()) { short pair = which % COLOR_PAIRS; bkgd(COLOR_PAIR(pair)); } } else { beep(); } break; case KEY_LEFT: case 'h': if (--x < 0) x = COLS - 1; break; case KEY_DOWN: case 'j': if (++y >= LINES) y = 1; break; case KEY_UP: case 'k': if (--y < 1) y = LINES - 1; break; case KEY_RIGHT: case 'l': if (++x >= COLS) x = 0; break; } if (!done) { time_t now = time((time_t *) 0); move(0, 0); addstr(ctime(&now)); move(y, x); addch('#' | A_REVERSE); move(y, x); } } } ExitProgram(EXIT_SUCCESS); }
/* * Display a dialog box with a list of options that can be turned on or off */ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int cnt, void *it, unsigned char *result) { int i, j, x, y, cur_x, cur_y, old_x, old_y, box_x, box_y, key = 0, button, choice, l, k, scroll, max_choice, item_no = 0, *status; int redraw_menu = FALSE, cursor_reset = FALSE; int rval = 0, onlist = 1, ok_space, cancel_space; char okButton, cancelButton; WINDOW *dialog, *list; unsigned char **items = NULL; dialogMenuItem *ditems; int list_width, check_x, item_x; /* Allocate space for storing item on/off status */ if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) { endwin(); fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n"); exit(-1); } draw: choice = scroll = button = 0; /* Previous calling syntax, e.g. just a list of strings? */ if (cnt >= 0) { items = it; ditems = NULL; item_no = cnt; /* Initializes status */ for (i = 0; i < item_no; i++) status[i] = !strcasecmp(items[i*3 + 2], "on"); } /* It's the new specification format - fake the rest of the code out */ else { item_no = abs(cnt); ditems = it; if (!items) items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *)); /* Initializes status */ for (i = 0; i < item_no; i++) { status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE; items[i*3] = ditems[i].prompt; items[i*3 + 1] = ditems[i].title; items[i*3 + 2] = status[i] ? "on" : "off"; } } max_choice = MIN(list_height, item_no); check_x = 0; item_x = 0; /* Find length of longest item in order to center checklist */ for (i = 0; i < item_no; i++) { l = strlen(items[i*3]); for (j = 0; j < item_no; j++) { k = strlen(items[j*3 + 1]); check_x = MAX(check_x, l + k + 6); } item_x = MAX(item_x, l); } if (height < 0) height = strheight(prompt)+list_height+4+2; if (width < 0) { i = strwidth(prompt); j = ((title != NULL) ? strwidth(title) : 0); width = MAX(i,j); width = MAX(width,check_x+4)+4; } width = MAX(width,24); if (width > COLS) width = COLS; if (height > LINES) height = LINES; /* center dialog box on screen */ x = (COLS - width)/2; y = (LINES - height)/2; #ifdef HAVE_NCURSES if (use_shadow) draw_shadow(stdscr, y, x, height, width); #endif dialog = newwin(height, width, y, x); if (dialog == NULL) { endwin(); fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x); return -1; } keypad(dialog, TRUE); draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); wattrset(dialog, border_attr); wmove(dialog, height-3, 0); waddch(dialog, ACS_LTEE); for (i = 0; i < width-2; i++) waddch(dialog, ACS_HLINE); wattrset(dialog, dialog_attr); waddch(dialog, ACS_RTEE); wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) waddch(dialog, ' '); if (title != NULL) { wattrset(dialog, title_attr); wmove(dialog, 0, (width - strlen(title))/2 - 1); waddch(dialog, ' '); waddstr(dialog, title); waddch(dialog, ' '); } wattrset(dialog, dialog_attr); wmove(dialog, 1, 2); print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE); list_width = width - 6; getyx(dialog, cur_y, cur_x); box_y = cur_y + 1; box_x = (width - list_width) / 2 - 1; /* create new window for the list */ list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1); if (list == NULL) { delwin(dialog); endwin(); fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width, y + box_y + 1, x + box_x + 1); return -1; } keypad(list, TRUE); /* draw a box around the list items */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr); check_x = (list_width - check_x) / 2; item_x = check_x + item_x + 6; /* Print the list */ for (i = 0; i < max_choice; i++) print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i), list_width, item_x, check_x); wnoutrefresh(list); print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y); display_helpline(dialog, height - 1, width); x = width / 2 - 11; y = height - 2; /* Is this a fancy new style argument string where we get to override * the buttons, or an old style one where they're fixed? */ if (ditems && result) { cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]); print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE); okButton = toupper(ditems[OK_BUTTON].prompt[0]); print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE); } else { cancelButton = 'C'; print_button(dialog, "Cancel", y, x + 14, FALSE); okButton = 'O'; print_button(dialog, " OK ", y, x, TRUE); } wnoutrefresh(dialog); wmove(list, choice, check_x+1); wrefresh(list); /* * XXX Black magic voodoo that allows printing to the checklist * window. For some reason, if this "refresh" code is not in * place, printing to the window from the selected callback * prints "behind" the checklist window. There is probably a * better way to do this. */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr); for (i = 0; i < max_choice; i++) print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i), list_width, item_x, check_x); print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y); wmove(list, choice, check_x+1); wnoutrefresh(dialog); wrefresh(list); /* XXX Black magic XXX */ while (key != ESC) { key = wgetch(dialog); /* Shortcut to OK? */ if (toupper(key) == okButton) { if (ditems) { if (result && ditems[OK_BUTTON].fire) { int st; WINDOW *save; save = dupwin(newscr); st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]); if (st & DITEM_RESTORE) { touchwin(save); wrefresh(save); } delwin(save); } } else if (result) { *result = '\0'; for (i = 0; i < item_no; i++) { if (status[i]) { strcat(result, items[i*3]); strcat(result, "\n"); } } } rval = 0; key = ESC; /* Lemme out! */ break; } /* Shortcut to cancel? */ if (toupper(key) == cancelButton) { if (ditems && result && ditems[CANCEL_BUTTON].fire) { int st; WINDOW *save; save = dupwin(newscr); st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]); if (st & DITEM_RESTORE) { touchwin(save); wrefresh(save); wmove(dialog, cur_y, cur_x); } delwin(save); } rval = 1; key = ESC; /* I gotta go! */ break; } /* Check if key pressed matches first character of any item tag in list */ for (i = 0; i < max_choice; i++) if (key != ' ' && key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0])) break; if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) || KEY_IS_UP(key) || KEY_IS_DOWN(key) || ((key == ' ' || key == '\n' || key == '\r') && onlist)) { /* if moving from buttons to the list, reset and redraw buttons */ if (!onlist) { onlist = 1; button = 0; if (ditems && result) { print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button); print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button); } else { print_button(dialog, "Cancel", y, x + 14, button); print_button(dialog, " OK ", y, x, !button); } wmove(list, choice, check_x+1); wnoutrefresh(dialog); wrefresh(list); } if (key >= '1' && key <= MIN('9', '0'+max_choice)) i = key - '1'; else if (KEY_IS_UP(key)) { if (!choice) { if (scroll) { /* Scroll list down */ getyx(dialog, cur_y, cur_x); /* Save cursor position */ if (list_height > 1) { /* De-highlight current first item before scrolling down */ print_item(list, items[scroll * 3], items[scroll * 3 + 1], status[scroll], 0, FALSE, DREF(ditems, scroll), list_width, item_x, check_x); scrollok(list, TRUE); wscrl(list, -1); scrollok(list, FALSE); } scroll--; print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0, TRUE, DREF(ditems, scroll), list_width, item_x, check_x); print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y); wmove(list, choice, check_x+1); wnoutrefresh(dialog); wrefresh(list); } continue; /* wait for another key press */ } else i = choice - 1; } else if (KEY_IS_DOWN(key)) { if (choice == max_choice - 1) { if (scroll + choice < item_no - 1) { /* Scroll list up */ getyx(dialog, cur_y, cur_x); /* Save cursor position */ if (list_height > 1) { /* De-highlight current last item before scrolling up */ print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1], status[scroll + max_choice - 1], max_choice - 1, FALSE, DREF(ditems, scroll + max_choice - 1), list_width, item_x, check_x); scrollok(list, TRUE); scroll(list); scrollok(list, FALSE); } scroll++; print_item(list, items[(scroll + max_choice - 1) * 3], items[(scroll + max_choice - 1) * 3 + 1], status[scroll + max_choice - 1], max_choice - 1, TRUE, DREF(ditems, scroll + max_choice - 1), list_width, item_x, check_x); print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y); wmove(list, choice, check_x+1); wnoutrefresh(dialog); wrefresh(list); } continue; /* wait for another key press */ } else i = choice + 1; } else if ((key == ' ' || key == '\n' || key == '\r') && onlist) { /* Toggle item status */ char lbra = 0, rbra = 0, mark = 0; getyx(list, old_y, old_x); /* Save cursor position */ if (ditems) { if (ditems[scroll + choice].fire) { int st; WINDOW *save; save = dupwin(newscr); st = ditems[scroll + choice].fire(&ditems[scroll + choice]); /* Call "fire" action */ if (st & DITEM_RESTORE) { touchwin(save); wrefresh(save); } delwin(save); if (st & DITEM_REDRAW) { wclear(list); for (i = 0; i < item_no; i++) status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE; for (i = 0; i < max_choice; i++) { print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice, DREF(ditems, scroll + i), list_width, item_x, check_x); } wnoutrefresh(list); print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y); wrefresh(dialog); } if (st & DITEM_LEAVE_MENU) { /* Allow a fire action to take us out of the menu */ key = ESC; rval = 0; break; } else if (st & DITEM_RECREATE) { delwin(list); delwin(dialog); dialog_clear(); goto draw; } } status[scroll + choice] = ditems[scroll + choice].checked ? ditems[scroll + choice].checked(&ditems[scroll + choice]) : FALSE; lbra = ditems[scroll + choice].lbra; rbra = ditems[scroll + choice].rbra; mark = ditems[scroll + choice].mark; } else status[scroll + choice] = !status[scroll + choice]; wmove(list, choice, check_x); wattrset(list, check_selected_attr); if (!lbra) lbra = '['; if (!rbra) rbra = ']'; if (!mark) mark = 'X'; wprintw(list, "%c%c%c", lbra, status[scroll + choice] ? mark : ' ', rbra); wmove(list, old_y, old_x); /* Restore cursor to previous position */ wrefresh(list); continue; /* wait for another key press */ } if (i != choice) { /* De-highlight current item */ getyx(dialog, cur_y, cur_x); /* Save cursor position */ print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, FALSE, DREF(ditems, scroll + choice), list_width, item_x, check_x); /* Highlight new item */ choice = i; print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice), list_width, item_x, check_x); wmove(list, choice, check_x+1); /* Restore cursor to previous position */ wrefresh(list); } continue; /* wait for another key press */ } switch (key) { case KEY_PPAGE: /* can we go up? */ if (scroll > height - 4) scroll -= (height-4); else scroll = 0; redraw_menu = TRUE; if (!onlist) { onlist = 1; button = 0; } break; case KEY_NPAGE: /* can we go down a full page? */ if (scroll + list_height >= item_no-1 - list_height) { scroll = item_no - list_height; if (scroll < 0) scroll = 0; } else scroll += list_height; redraw_menu = TRUE; if (!onlist) { onlist = 1; button = 0; } break; case KEY_HOME: /* go to the top */ scroll = 0; choice = 0; redraw_menu = TRUE; cursor_reset = TRUE; onlist = 1; break; case KEY_END: /* Go to the bottom */ scroll = item_no - list_height; if (scroll < 0) scroll = 0; choice = max_choice - 1; redraw_menu = TRUE; cursor_reset = TRUE; onlist = 1; break; case TAB: case KEY_BTAB: /* move to next component */ if (onlist) { /* on list, next is ok button */ onlist = 0; if (ditems && result) { print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button); print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button); ok_space = 1; cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6; } else { print_button(dialog, "Cancel", y, x + 14, button); print_button(dialog, " OK ", y, x, !button); ok_space = 3; cancel_space = 15; } if (button) wmove(dialog, y, x + cancel_space); else wmove(dialog, y, x + ok_space); wrefresh(dialog); break; } else if (button) { /* on cancel button, next is list */ button = 0; onlist = 1; redraw_menu = TRUE; break; } /* on ok button, next is cancel button, same as left/right case */ case KEY_LEFT: case KEY_RIGHT: onlist = 0; button = !button; if (ditems && result) { print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button); print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button); ok_space = 1; cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6; } else { print_button(dialog, "Cancel", y, x + 14, button); print_button(dialog, " OK ", y, x, !button); ok_space = 3; cancel_space = 15; } if (button) wmove(dialog, y, x + cancel_space); else wmove(dialog, y, x + ok_space); wrefresh(dialog); break; case ' ': case '\n': case '\r': if (!onlist) { if (ditems) { if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) { int st; WINDOW *save = dupwin(newscr); st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]); if (st & DITEM_RESTORE) { touchwin(save); wrefresh(save); } delwin(save); if (st == DITEM_FAILURE) continue; } } else if (result) { *result = '\0'; for (i = 0; i < item_no; i++) { if (status[i]) { strcat(result, items[i*3]); strcat(result, "\n"); } } } rval = button; key = ESC; /* Bail out! */ break; } /* Let me outta here! */ case ESC: rval = -1; break; /* Help! */ case KEY_F(1): case '?': display_helpfile(); break; } if (redraw_menu) { getyx(list, old_y, old_x); wclear(list); /* * Re-draw a box around the list items. It is required * if amount of list items is smaller than height of listbox. * Otherwise un-redrawn field will be filled with default * screen attributes instead of dialog attributes. */ draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr); for (i = 0; i < max_choice; i++) print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice, DREF(ditems, scroll + i), list_width, item_x, check_x); print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y); /* redraw buttons to fix highlighting */ if (ditems && result) { print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button); print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button); } else { print_button(dialog, "Cancel", y, x + 14, button); print_button(dialog, " OK ", y, x, !button); } wnoutrefresh(dialog); if (cursor_reset) { wmove(list, choice, check_x+1); cursor_reset = FALSE; } else { wmove(list, old_y, old_x); } wrefresh(list); redraw_menu = FALSE; } } delwin(list); delwin(dialog); return rval; }
SetUserData() { NAME userid; ACCOUNT acct, nr; int rc; SHORT flags = 0; PASSWD passcfm; int x, y, grok; char genbuf[256], ans[4]; move(2,0); memset(&nr, 0, sizeof nr); bbs_acctnames(&acctlist, NULL); namecomplete(NULL, acctlist, "Userid to set: ", userid, sizeof(NAME)); if (userid[0] == '\0' || !is_in_namelist(acctlist, userid)) { bbperror(S_NOSUCHUSER, NULL); pressreturn(); return FULLUPDATE; } if ((rc = bbs_get_userinfo(userid, &acct)) != S_OK) { bbperror(rc, NULL); pressreturn(); return FULLUPDATE; } move(3,0); UserDisplay(&acct); getyx(&y, &x); getdata(++y,0,"Change any user information (Y/N)? [N]: ",ans,sizeof(ans), DOECHO, 0); if (ans[0] != 'Y' && ans[0] != 'y') { prints("Record not changed.\n"); pressreturn(); return FULLUPDATE; } sprintf(genbuf, "New userid [%s]: ", acct.userid); do { getdata(y+1, 0, genbuf, nr.userid, sizeof(nr.userid), DOECHO, 0); if (!nr.userid[0]) break; if (grok = CheckUserid(nr.userid)) { move(y+2, 0); prints("Invalid or taken userid. Try again.\n"); } else BITSET(flags, MOD_USERID); } while (grok); y++; do { getdata(y+1,0,"New Password: "******"Confirm Pass: "******"Passwords don't match. Try again.\n"); } else BITSET(flags, MOD_PASSWD); } while (grok); move(y+2, 0); clrtobot(); y+=2; sprintf(genbuf, "New username [%s]: ", acct.username); getdata(y++, 0, genbuf, nr.username, sizeof(nr.username), DOECHO, 0); if (nr.username[0]) BITSET(flags, MOD_USERNAME); sprintf(genbuf, "New terminal type [%s]: ", acct.terminal); getdata(y++, 0, genbuf, nr.terminal, sizeof(nr.terminal), DOECHO, 0); if (nr.terminal[0]) BITSET(flags, MOD_TERMINAL); sprintf(genbuf, "New charset [%s]: ", acct.charset); getdata(y++, 0, genbuf, nr.charset, sizeof(nr.charset), DOECHO, 0); if (nr.charset[0]) BITSET(flags, MOD_CHARSET); sprintf(genbuf, "New real name [%s]: ", acct.realname); getdata(y++, 0, genbuf, nr.realname, sizeof(nr.realname), DOECHO, 0); if (nr.realname[0]) BITSET(flags, MOD_REALNAME); sprintf(genbuf, "New address: "); getdata(y++, 0, genbuf, nr.address, sizeof(nr.address), DOECHO, 0); if (nr.address[0]) BITSET(flags, MOD_ADDRESS); sprintf(genbuf, "New mail address: "); getdata(y++, 0, genbuf, nr.email, sizeof(nr.email), DOECHO, 0); if (nr.email[0]) BITSET(flags, MOD_EMAIL); getdata(y, 0, "Are you sure (Y/N)? [N]: ", ans, sizeof(ans), DOECHO, 0); if (ans[0] == 'Y' || ans[0] == 'y') { rc = bbs_modify_account(acct.userid, &nr, flags); if (rc == S_OK) prints("User data was changed.\n"); else bbperror(rc, "User modify failed"); } else prints("User data not changed.\n"); pressreturn(); return FULLUPDATE; }
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { ChatContext *ctx = self->chatwin; int x, y, y2, x2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); if (x2 <= 0) return; /* ignore non-menu related input if active */ if (self->help->active) { help_onKey(self, key); return; } if (ltr) { /* char is printable */ input_new_char(self, key, x, y, x2, y2); return; } if (line_info_onKey(self, key)) return; input_handle(self, key, x, y, x2, y2); if (key == '\t') { /* TAB key: auto-completes command */ if (ctx->len > 1 && ctx->line[0] == '/') { int diff = complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE); if (diff != -1) { if (x + diff > x2 - 1) { wmove(self->window, y, x + diff); ctx->start += diff; } else { wmove(self->window, y, x + diff); } } else { beep(); } } else { beep(); } } else if (key == '\n') { rm_trailing_spaces_buf(ctx); uint8_t line[MAX_STR_SIZE] = {0}; if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) memset(&line, 0, sizeof(line)); if (!string_is_empty(line)) add_line_to_hist(ctx); line_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0); execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); reset_buf(ctx); } }
int getanswer(char *choices, bool def) { int ch; /* input */ volatile int loop; /* counter */ volatile int oldx, oldy; /* original coordinates on screen */ getyx(stdscr, oldy, oldx); alarm(0); /* make sure alarm is off */ for (loop = 3; loop; --loop) for (loop = 3; loop; --loop) /* try for 3 times */ { if (setjmp(Timeoenv) != 0) /* timed out waiting for response */ { if (def || loop <= 1) /* return default answer */ break; else /* prompt, and try again */ goto YELL; } else /* wait for response */ { clrtoeol(); refresh(); signal(SIGALRM, catchalarm); /* set timeout */ if (Timeout) alarm(7); /* short */ else alarm(600); /* long */ ch = getchar(); alarm(0); /* turn off timeout */ if (ch < 0) { /* caught some signal */ ++loop; continue; } else if (ch == CH_REDRAW) { /* redraw screen */ clearok(stdscr, TRUE); /* force clear screen */ ++loop; /* don't count this input */ continue; } else if (Echo) { addch(ch); /* echo character */ refresh(); } if (islower(ch)) /* convert to upper case */ ch = toupper(ch); if (def || strchr(choices, ch) != NULL) /* valid choice */ return (ch); else if (!def && loop > 1) { /* bad choice; prompt, and try again */ YELL: mvprintw(oldy + 1, 0, "Please choose one of : [%s]\n", choices); move(oldy, oldx); clrtoeol(); continue; } else /* return default answer */ break; } } return (*choices); }