/* * Prints a list of posts to the screen */ void drawScreen(LinkScreen *screen) { int i, screenLines; wchar_t *tmpbuf; int bufSize, bufLen; if (screen == NULL) return ; bufSize = sizeof(wchar_t) * (COLS + 1); bufLen = COLS; tmpbuf = malloc(bufSize); memset(tmpbuf, 0, bufSize); for (i = 0; i < bufLen; i++) tmpbuf[i] = L' '; screenLines = screen->offset + screen->displayed + 1; for (i = 0; i < screen->displayed + screen->offset + 1 + screen->linkOpenSize; i++) mvaddwstr(i, 0, tmpbuf); attron(COLOR_PAIR(1)); for(i = screen->offset; i < screenLines; i++) { if(i == screen->selected) attron(COLOR_PAIR(2)); if (i < screen->list->linkCount) { if (screen->screenLineCount <= i) linkScreenRenderLine(screen, i, COLS); mvaddwstr(i - screen->offset, 0, screen->screenLines[i]); } else { mvaddwstr(i - screen->offset, 0, tmpbuf); } if (i == screen->selected) attron(COLOR_PAIR(1)); } if (screen->linkOpen) { if (screen->helpOpen == 0) linkScreenRenderLinkText(screen, tmpbuf, bufLen, screenLines); else linkScreenRenderHelpText(screen, tmpbuf, bufLen, screenLines); } free(tmpbuf); refresh(); }
void linkScreenRenderLinkText (LinkScreen *screen, wchar_t *tmpbuf, int bufLen, int screenLines) { RedditLink *current; int lastLine = screenLines - screen->offset; linkScreenSetupSplit(screen, tmpbuf, bufLen, lastLine); attron(COLOR_PAIR(1)); if (screen->list->linkCount >= screen->selected) { current = screen->list->links[screen->selected]; if (current != NULL) { swprintf(tmpbuf, bufLen, L"%s - %d Score / %d Comments / %s \nTitle: ", current->author, current->score, current->numComments, current->created_utc); mvaddwstr(lastLine + 1, 0, tmpbuf); addwstr(current->wtitleEsc); addch('\n'); swprintf(tmpbuf, bufLen, L"-------\n"); addwstr(tmpbuf); if (current->flags & REDDIT_LINK_IS_SELF) addwstr(&(current->wselftextEsc[current->advance])); else addstr(current->url); } } }
void linkScreenSetupSplit (LinkScreen *screen, wchar_t *tmpbuf, int bufLen, int lastLine) { int i; for (i = 0; i < bufLen; i++) tmpbuf[i] = L'-'; tmpbuf[bufLen] = (wchar_t)0; attron(COLOR_PAIR(2)); mvaddwstr(lastLine, 0, tmpbuf); }
void linkScreenRenderHelpText (LinkScreen *screen, wchar_t *tmpbuf, int bufLen, int screenLines) { int i; int lastLine = screenLines - screen->offset; linkScreenSetupSplit(screen, tmpbuf, bufLen, lastLine); attron(COLOR_PAIR(1)); for(i = 0; i < screen->helpLineCount; i++) mvaddwstr(lastLine + 1 + i, 0, screen->helpText[i]); }
int draw_terminal_ncurses(int tty, int h, int w, int bars, int bw, int bs, int rest, int f[200], int flastd[200]) { int i, n, q; const wchar_t* bh[] = {L"\u2581", L"\u2582", L"\u2583", L"\u2584", L"\u2585", L"\u2586", L"\u2587", L"\u2588"}; // output: check if terminal has been resized if (!tty) { if ( LINES != h || COLS != w) { return -1; } } h = h - 1; for (i = 0; i < bars; i++) { if(f[i] > flastd[i]){//higher then last one if (tty) for (n = flastd[i] / 8; n < f[i] / 8; n++) for (q = 0; q < bw; q++) mvprintw((h - n), i*bw + q + i*bs + rest, "%d",8); else for (n = flastd[i] / 8; n < f[i] / 8; n++) for (q = 0; q < bw; q++) mvaddwstr((h - n), i*bw + q + i*bs + rest, bh[7]); if (f[i] % 8 != 0) { if (tty) for (q = 0; q < bw; q++) mvprintw( (h - n), i*bw + q + i*bs + rest, "%d",(f[i] % 8) ); else for (q = 0; q < bw; q++) mvaddwstr( (h - n), i*bw + q + i*bs + rest, bh[(f[i] % 8) - 1]); } }else if(f[i] < flastd[i]){//lower then last one for (n = f[i] / 8; n < flastd[i]/8 + 1; n++) for (q = 0; q < bw; q++) mvaddstr( (h - n), i*bw + q + i*bs + rest, " "); if (f[i] % 8 != 0) { if (tty) for (q = 0; q < bw; q++) mvprintw((h - f[i] / 8), i*bw + q + i*bs + rest, "%d",(f[i] % 8) ); else for (q = 0; q < bw; q++) mvaddwstr((h - f[i] / 8), i*bw + q + i*bs + rest, bh[(f[i] % 8) - 1]); } } flastd[i] = f[i]; //memmory for falloff func } refresh(); return 0; }
/* paints the heading on the different "screens" with useful data is called upon from: main_menu, and read_database, edit_entry, add_entry, delete_entry, find_entry. */ void paintHeading(const char *modeword) { wchar_t *dbmodistr = NULL ; move(0,0) ; clrtoeol() ; addwstr(wprgname); move(0,15) ; if (modeword != NULL ) { dbmodistr = mbstowcs_alloc(modeword); addwstr(dbmodistr); move(0,40); } addwstr(entriesLine) ; mvaddwstr(1,0,labelline) ; mvaddwstr(1,17, db_dir); mvaddwstr(2,0,databaseline) ; mvaddwstr(2, 17, db_fullname); if (dbmodistr != NULL ) { free(dbmodistr) ; dbmodistr = NULL ; } }
/* "valid" string. */ wchar_t prompt_char(int row, int col, const char *promptstr, const char *valid) { wchar_t *w_prompt, *w_valid=NULL, ch; int code; w_prompt = mbstowcs_alloc(promptstr); /* if w_promptstr == NULL ?? .... */ /* Print the prompt. */ mvaddwstr(row, col, w_prompt); clrtoeol(); refresh(); if ( valid != NULL ) { w_valid = mbstowcs_alloc(valid); } /* Read characters... */ while ((code = get_wch(&ch)) != ERR) { /* If it's not a valid one, beep and get another one. */ /* if (index(valid, c) == NULL) { */ if ( valid != NULL ) { if (wcsrchr(w_valid, ch) == NULL) { /* CHANGED !! */ beep(); continue; } /* Add the character to the screen, and return it. */ AddCh((chtype) ch); refresh(); } goto _exit; } _exit: free(w_prompt); refresh(); if (valid != NULL ) { free(w_valid); w_valid= NULL ; return (ch); /* to avoid compiler warning */ } else { return '\0' ; } }
int draw_terminal_bcircle(int virt, int h, int w, int f[200]) { const wchar_t* bars[] = {L"\u2581", L"\u2582", L"\u2583", L"\u2584", L"\u2585", L"\u2586", L"\u2587", L"\u2588"}; // output: check if terminal has been resized if (virt != 0) { if ( LINES != h || COLS != w) { return -1; } } float deg, width, height; int y, x; /* Convert to int */ width = f[1]/10; height = f[1]/15; int oy, ox; oy = LINES/2 - height/2; ox = COLS/2 - width/2; for (x = 0; x < COLS; x++) { for (y = 0; y < LINES; y++) { mvaddstr(y,x," "); } } /* Draw circle */ for (deg = 0; deg < 360.0f; deg += 1.0f) { x = ox + width+(int)(width * cos(DEGTORAD(deg))); y = oy + height+(int)(height * sin(DEGTORAD(deg))); mvaddwstr(y,x,bars[7]); } refresh(); return 0; }
/* Among other things, 'newtest' demonstrates how to make a Win32a PDCurses app that is a for-real, "pure Windows" version (instead of a console application). Doing this is quite easy, and has certain advantages. If the app is invoked from a command prompt, the only difference you'll see is that the app runs separately (that is, you can continue to use the command prompt, switching between it, your PDCurses/Win32a app, and other processes). Which is the main reason I did it; it meant that I could invoke a PDCurses-based text editor, for example, and still have use of the command line. (NOTE that, for reasons I don't actually understand, this happens when the Visual C++ compiler is used. With MinGW or OpenWatcom, it's still "really" a console app.) To do it, we ensure that the usual main() function has an alternative dummy_main() form, taking the same arguments as main(). We add a WinMain() function, whose sole purpose is to reformulate lpszCmdLine into argc/argv form, and pass it on to dummy_main(). And, of course, we can switch back to a "normal" console app by removing the above #define PURE_WINDOWS_VERSION line. */ #ifdef PURE_WINDOWS_VERSION #undef MOUSE_MOVED #include <windows.h> int dummy_main( int argc, char **argv); int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { char *argv[30]; int i, argc = 1; argv[0] = "newtest"; for( i = 0; lpszCmdLine[i]; i++) if( lpszCmdLine[i] != ' ' && (!i || lpszCmdLine[i - 1] == ' ')) argv[argc++] = lpszCmdLine + i; for( i = 0; lpszCmdLine[i]; i++) if( lpszCmdLine[i] == ' ') lpszCmdLine[i] = '\0'; return dummy_main( argc, (char **)argv); } int dummy_main( int argc, char **argv) #else /* "usual", console-app version: */ int main( int argc, char **argv) #endif { int quit = 0, i, fmt = 0xa, use_slk = 1; bool blink_state = FALSE; int cursor_state_1 = 2, cursor_state_2 = 3; int show_slk_index_line = 0; int redraw = 1; // setlocale(LC_ALL, ".utf8"); ttytype[0] = 25; ttytype[1] = 90; /* Allow 25 to 90 lines... */ ttytype[2] = 80; ttytype[3] = (char)200; /* ...and 80 to 200 columns */ /* (This program gets weird artifacts when smaller than 25x80.) */ for( i = 1; i < argc; i++) if( argv[i][0] == '-') switch( argv[i][1]) { case 's': use_slk = 0; break; case 'l': setlocale( LC_ALL, argv[i] + 2); break; case 'f': sscanf( argv[i] + 2, "%x", &fmt); break; case 'i': show_slk_index_line = 1; break; case 'r': /* allow user-resizable windows */ { int min_lines, max_lines, min_cols, max_cols; if( sscanf( argv[i] + 2, "%d,%d,%d,%d", &min_lines, &max_lines, &min_cols, &max_cols) == 4) { ttytype[0] = min_lines; ttytype[1] = max_lines; ttytype[2] = min_cols; ttytype[3] = max_cols; } } break; default: printf( "Option '%s' unrecognized\n", argv[i]); break; } if( use_slk) slk_init( show_slk_index_line ? 3 : 0); Xinitscr(argc, argv); if( use_slk) slk_setup( show_slk_index_line ? -fmt : fmt); start_color(); # if defined(NCURSES_VERSION) || (defined(PDC_BUILD) && PDC_BUILD > 3000) use_default_colors(); # endif cbreak(); noecho(); clear(); refresh(); #ifdef __PDCURSES__ PDC_set_title( "NewTest: tests various PDCurses features"); #endif keypad( stdscr, TRUE); init_pair( 1, 15, COLOR_BLACK); init_pair( 2, COLOR_BLACK, COLOR_YELLOW); mousemask( ALL_MOUSE_EVENTS, NULL); attrset( COLOR_PAIR( 1)); while( !quit) { char buff[40]; const int color_block_start = 52; const int color_block_size = 14; int c; const char *cursor_state_text[N_CURSORS] = { "Invisible (click to change) ", "Underscore (click to change)", "Block (click to change) ", "Outline (click to change) ", "Caret (click to change) ", "Half-block (click to change)", "Central (click to change) ", "Cross (click to change) ", "Heavy box (click to change) " }; if( redraw) { mvaddstr( 1, COL1, "'Normal' white-on-black"); #ifdef WACS_S1 mvaddwstr( 2, COL1, L"'Normal' text, but wide"); #endif attron( A_BLINK); mvaddstr( 6, 40, "Blinking"); attron( A_BOLD); mvaddstr( 8, 40, "BlinkBold"); attron( A_ITALIC); mvaddstr( 0, COL2, "BlinkBoldItalic"); attrset( COLOR_PAIR( 3)); attron( A_UNDERLINE); #ifdef WACS_S1 mvaddstr( 2, COL1, "Underlined"); addwstr( L"WideUnder"); #endif attrset( COLOR_PAIR( 1)); attron( A_UNDERLINE | A_ITALIC); mvaddstr( 2, COL2, "UnderlinedItalic"); attrset( COLOR_PAIR( 2)); attron( A_BLINK); mvaddstr( 4, COL1, "Black-on-yellow blinking"); attrset( COLOR_PAIR( 1)); move( 4, COL2); text_in_a_box( "Text in a box"); attrset( COLOR_PAIR( 6)); attron( A_STRIKEOUT); mvaddstr( 10, 40, "Strikeout"); attrset( COLOR_PAIR( 1)); for( i = 0; i < 128; i++) { /* Show extended characters: */ char buff[5]; sprintf( buff, "%2x %c", i + 128, (char)(i + 128)); mvaddstr( 5 + i % 16, (i / 16) * 5, buff); } #if(CHTYPE_LONG >= 2) /* "non-standard" 64-bit chtypes */ for( i = 0; i < 3; i++) { /* Demonstrate full RGB color control: */ int j; const char *output_text[3] = { "Red on green to white on black | (you can get full RGB colors when desired,", "Blue on yellow to black on red | with palette coloring still being available)", "White on red to green on blue, underlined and italic" }; const int len = strlen( output_text[i]); move( 21 + i, 1); for( j = 0; j < len; j++) { attr_t output_color; const int oval = j * 31 / len; const int reverse = 31 - oval; if( !i) output_color = A_RGB( 31, oval, oval, 0, reverse, 0); else if( i == 1) output_color = A_RGB( 0, 0, reverse, 31, reverse, 0); else { output_color = A_RGB( reverse, 31, reverse, reverse, 0, oval); output_color |= A_UNDERLINE | A_ITALIC; } attrset( output_color); addch( output_text[i][j]); } } #endif /* #if(CHTYPE_LONG >= 2) */ redraw = 0; } attrset( COLOR_PAIR( 1)); #ifdef MAYBE_TRY_THIS_SOMEWHERE_ELSE mvaddstr( 1, COL3, "Click on cursor descriptions to"); mvaddstr( 2, COL3, "cycle through possible cursors"); mvaddstr( 3, COL3, "Click on colors at left to change"); mvaddstr( 4, COL3, "colors used for under/over/outlining"); mvaddstr( 5, COL3, "Click 'Blink' at bottom to toggle"); mvaddstr( 6, COL3, "'real' blinking vs. 'highlit' blink"); #endif mvaddstr( 19, color_block_start, cursor_state_text[cursor_state_1]); mvaddstr( 20, color_block_start, cursor_state_text[cursor_state_2]); curs_set( (cursor_state_1 << 8) | cursor_state_2); for( i = 0; i < 256; i++) { attrset( COLOR_PAIR( i)); if( i > 2) init_pair((short)i, (short)i, COLOR_BLACK); if( !(i % color_block_size)) move( i / color_block_size, color_block_start); attron( A_REVERSE); addstr( " "); } move( 18, 77); refresh(); c = getch( ); attrset( COLOR_PAIR( 1)); if( c == KEY_RESIZE) { redraw = 1; resize_term( 0, 0); } else if( c == KEY_F(1) || c == 27) quit = 1; else if( c == KEY_F(2)) { blink_state ^= 1; PDC_set_blink( blink_state); } else if( c == KEY_F(3)) /* toggle SLKs */ { use_slk ^= 1; if( use_slk) slk_restore( ); else slk_clear( ); } else if( c >= KEY_F(4) && c < KEY_F(12)) { sscanf( labels[c - KEY_F(1)], "%x", &fmt); if( use_slk) slk_setup( show_slk_index_line ? -fmt : fmt); } if( c != KEY_MOUSE) { sprintf( buff, "Key %s hit ", keyname( c)); mvaddstr( 0, COL1, buff); } else { MEVENT mouse_event; #ifdef __PDCURSES__ nc_getmouse( &mouse_event); #else getmouse( &mouse_event); #endif sprintf( buff, "Mouse at %d x %d: %x ", mouse_event.x, mouse_event.y, (unsigned)mouse_event.bstate); mvaddstr( 0, COL1, buff); if( mouse_event.x >= color_block_start && mouse_event.y <= 256 / color_block_size) { int new_color = (mouse_event.x - color_block_start) / 2 + mouse_event.y * color_block_size; if( new_color >= 256) new_color = -1; PDC_set_line_color( (short)new_color); } else if( mouse_event.x >= color_block_start) { if( mouse_event.y == 19) /* blink/non-blink toggle */ cursor_state_1 = (cursor_state_1 + 1) % N_CURSORS; else if( mouse_event.y == 20) /* cycle cursor state */ cursor_state_2 = (cursor_state_2 + 1) % N_CURSORS; } } } endwin(); return 0; }
/* TODO: all length calculations of the string must be rebuilt. * * BUG: * Når jeg står på slutten av linjen så blir cursor pos * justert mot venstre selv om jeg ikke sletter noe. * * */ void prompt_str(int row, int col, const char *promptstr, wchar_t * answer) { wchar_t *line = answer; int len, col0; /* struct sgttyb _tty ; */ register int code, i, j; /* Converts the promptstr to a wide version. */ wchar_t *wpromptstr = mbstowcs_alloc(promptstr); if (wpromptstr == NULL) { yerror( YMBS_WCS_ERR,"prompt_str->mbstowcs_alloc", "wpromptstr", YX_EXTERNAL_CAUSE ) ; } wchar_t ch; /* Print the wide prompt at (row,col). */ mvaddwstr(row, col, wpromptstr); refresh(); /* Calc "column zero", which is at right end of prompt. */ col += wcslen(wpromptstr); col0 = col; mvaddwstr(row, col, answer); len = wcslen(answer) ; col += len ; /* Read chars till we get what we want. Useris allowed */ /* basic EMACS-style line editing. */ while ((code = get_wch(&ch)) != EOF) { switch (ch) { case CTRL('a'): /* beginning of line */ col = col0; break; case KEY_LEFT: case CTRL('b'): /* back character */ if (col > col0) col--; break; case CTRL('d'): /* delete character */ /* * If there's stuff in the string, * delete this character. */ if (col == (col0 + (int)wcslen(line))) { col--; } else if (len) { /* Calc string pos of char to delete. */ i = col - col0; /* Shuffle the string "left" one place. */ while (i < len) { line[i] = line[i + 1]; i++; } /* Delete char on the screen. */ len -= 1; delch(); /* prob ok that isn't wide. */ if (col== (col0 + (int)wcslen(line)) ) { --col ; } } break; case CTRL('e'): /* end of line */ col = col0 + len; break; case KEY_RIGHT: case CTRL('f'): /* forward character */ if ((col - col0) < len) col++; break; case KEY_BACKSPACE: case CTRL('h'): /* backspace delete */ case '\177': /* If stuff in the string, delete char. */ if (len && ((col - 1) >= col0)) { /* Calc pos in string of char to delete */ int l = col - col0 - 1; if (l < 0) break; /* Shuffle the string "left" one place. */ while (l < len) { line[l] = line[l + 1]; l++; } len -= 1; /* Delete the character on the screen. */ move(row, --col); delch(); } break; case CTRL('k'): /* kill line */ /* Clear the string. */ if (len) { i = col - col0; line[i] = '\0'; len = i; clrtoeol(); } break; case CTRL('l'): /* redraw screen */ wrefresh(curscr); break; case KEY_ENTER: case '\r': /* return the string */ case '\n': /* return the string */ line[len] = '\0'; return; default: /* regular character */ if (ch == KEY_DL) { move(row, col0); clrtoeol(); col = col0; *line = '\0'; len = 0; } else if (code != KEY_CODE_YES) { if (iswctype(ch, wctype("print"))) { if (col == (COLS - 1)) { beep(); break; } /* Calculate position of char in string. */ i = col - col0; /* If we have to, move string "right" one */ /* place to insert the character. */ if (i < len) { for (j = len; j >= i; j--) line[j + 1] = line[j]; } line[i] = ch; len += 1; col++; /* Insert the character on the screen. */ InsWch((chtype) ch); /* ins_wch(&ch); */ } } break; } /* Move the cursor. */ move(row, col); refresh(); } }
/* Among other things, 'newtest' demonstrates how to make a Win32a PDCurses app that is a for-real, "pure Windows" version (instead of a console application). Doing this is quite easy, and has certain advantages. If the app is invoked from a command prompt, the only difference you'll see is that the app runs separately (that is, you can continue to use the command prompt, switching between it, your PDCurses/Win32a app, and other processes). Which is the main reason I did it; it meant that I could invoke a PDCurses-based text editor, for example, and still have use of the command line. (NOTE that, for reasons I don't actually understand, this happens when the Visual C++ compiler is used. With MinGW or OpenWatcom, it's still "really" a console app.) To do it, we ensure that the usual main() function has an alternative dummy_main() form, taking the same arguments as main(). We add a WinMain() function, whose sole purpose is to reformulate lpszCmdLine into argc/argv form, and pass it on to dummy_main(). And, of course, we can switch back to a "normal" console app by removing the above #define PURE_WINDOWS_VERSION line. */ #ifdef PURE_WINDOWS_VERSION #undef MOUSE_MOVED #include <windows.h> int dummy_main( int argc, char **argv); int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { char *argv[30]; int i, argc = 1; argv[0] = "newtest"; for( i = 0; lpszCmdLine[i]; i++) if( lpszCmdLine[i] != ' ' && (!i || lpszCmdLine[i - 1] == ' ')) argv[argc++] = lpszCmdLine + i; for( i = 0; lpszCmdLine[i]; i++) if( lpszCmdLine[i] == ' ') lpszCmdLine[i] = '\0'; return dummy_main( argc, (char **)argv); } int dummy_main( int argc, char **argv) #else /* "usual", console-app version: */ int main( int argc, char **argv) #endif { int quit = 0, i, use_slk = 1; int fmt = 0xa; bool blink_state = FALSE; int cursor_state_1 = 2, cursor_state_2 = 3; int show_slk_index_line = 0; int redraw = 1; unsigned extra_character_to_show = 0; #ifdef PDC_WIDE unsigned unicode_offset = 0x80; #endif /* setlocale(LC_ALL, ".utf8"); */ ttytype[0] = 25; ttytype[1] = 90; /* Allow 25 to 90 lines... */ ttytype[2] = 80; ttytype[3] = (char)200; /* ...and 80 to 200 columns */ /* (This program gets weird artifacts when smaller than 25x80.) */ for( i = 1; i < argc; i++) if( argv[i][0] == '-') switch( argv[i][1]) { case 's': use_slk = 0; break; case 'l': setlocale( LC_ALL, argv[i] + 2); break; case 'e': sscanf( argv[i] + 2, "%x", &extra_character_to_show); break; case 'f': sscanf( argv[i] + 2, "%x", (unsigned *)&fmt); break; case 'i': show_slk_index_line = 1; break; case 'r': /* allow user-resizable windows */ { int min_lines, max_lines, min_cols, max_cols; if( sscanf( argv[i] + 2, "%d,%d,%d,%d", &min_lines, &max_lines, &min_cols, &max_cols) == 4) { ttytype[0] = min_lines; ttytype[1] = max_lines; ttytype[2] = min_cols; ttytype[3] = max_cols; } } break; case 'd': /* set window size before initscr */ { int n_lines, n_cols; if( sscanf( argv[i] + 2, "%d,%d", &n_lines, &n_cols) == 2) resize_term( n_lines, n_cols); } break; #ifdef PDC_WIDE case 'u': sscanf( argv[i] + 2, "%x", &unicode_offset); break; #endif default: printf( "Option '%s' unrecognized\n", argv[i]); break; } if( use_slk) slk_init( show_slk_index_line ? 3 : 0); Xinitscr(argc, argv); if( use_slk) slk_setup( show_slk_index_line ? -fmt : fmt); start_color(); # if defined(NCURSES_VERSION) || (defined(PDC_BUILD) && PDC_BUILD > 3000) use_default_colors(); # endif cbreak(); noecho(); clear(); refresh(); #ifdef __PDCURSES__ PDC_set_title( "NewTest: tests various PDCurses features"); #endif keypad( stdscr, TRUE); init_pair( 1, 15, COLOR_BLACK); init_pair( 2, COLOR_BLACK, COLOR_YELLOW); mousemask( ALL_MOUSE_EVENTS, NULL); attrset( COLOR_PAIR( 1)); while( !quit) { char buff[40]; const int xmax = getmaxx( stdscr); const int ymax = getmaxy( stdscr); int color_block_start = 54, c; int color_block_cols = (xmax - color_block_start) / 2; const int color_block_lines = 19; const char *cursor_state_text[N_CURSORS] = { "Invisible (click to change) ", "Underscore (click to change)", "Block (click to change) ", "Outline (click to change) ", "Caret (click to change) ", "Half-block (click to change)", "Central (click to change) ", "Cross (click to change) ", "Heavy box (click to change) " }; if( color_block_cols < 0) color_block_cols = 0; if( redraw) { mvaddstr( 1, COL1, "'Normal' white-on-black"); #if(CHTYPE_LONG >= 2) /* "non-standard" 64-bit chtypes */ attron( A_DIM); mvaddstr( 2, COL1, "Dimmed text"); attroff( A_DIM); #endif #ifdef PDC_WIDE mvaddwstr( 3, COL1, L"'Normal' text, but wide"); #endif attron( A_BLINK); mvaddstr( 6, 40, "Blinking"); attron( A_BOLD); mvaddstr( 8, 40, "BlinkBold"); attron( A_ITALIC); mvaddstr( 0, COL2, "BlinkBoldItalic"); attrset( COLOR_PAIR( 3)); attron( A_UNDERLINE); #ifdef PDC_WIDE mvaddstr( 1, COL2, "Underlined"); addwstr( L"WideUnder"); #endif attrset( COLOR_PAIR( 1)); attron( A_UNDERLINE | A_ITALIC); mvaddstr( 2, COL2, "UnderlinedItalic"); attrset( COLOR_PAIR( 2)); attron( A_BLINK); mvaddstr( 4, COL1, "Black-on-yellow blinking"); attrset( COLOR_PAIR( 1)); move( 4, COL2); text_in_a_box( "Text in a box"); #ifdef CHTYPE_LONG attrset( COLOR_PAIR( 6)); attron( A_STRIKEOUT); mvaddstr( 10, 40, "Strikeout"); attrset( COLOR_PAIR( 1)); #endif #ifdef PDC_WIDE move( 11, 40); text_in_a_box( "Next Ucode pg"); if( unicode_offset) { move( 12, 40); text_in_a_box( "Prev Ucode pg"); } mvprintw( 13, 40, "U+%04x ", unicode_offset); #endif for( i = 0; i < 128; i++) { /* Show extended characters: */ #ifdef PDC_WIDE wchar_t buff[20]; swprintf( buff, 20, L"%02x ", (unsigned)( i + unicode_offset) & 0xff); mvaddwstr( 5 + i % 16, (i / 16) * 5, buff); if( i + unicode_offset > ' ') addch( (chtype)( i + unicode_offset)); else addch( ' '); addch( ' '); #else char buff[6]; sprintf( buff, "%02x %c", i + 128, (char)(i + 128)); mvaddstr( 5 + i % 16, (i / 16) * 5, buff); #endif } #if(CHTYPE_LONG >= 2) /* "non-standard" 64-bit chtypes */ for( i = 0; i < 3 && i + 21 < ymax; i++) { /* Demonstrate full RGB color control: */ int j; const char *output_text[3] = { "Red on green to white on black | (you can get full RGB colors when desired,", "Blue on yellow to black on red | with palette coloring still being available)", "White on red to green on blue, underlined and italic" }; const int len = (int)strlen( output_text[i]); move( 21 + i, 1); for( j = 0; j < len && j + 1 < xmax; j++) { attr_t output_color; const int oval = j * 31 / len; const int reverse = 31 - oval; if( !i) output_color = A_RGB( 31, oval, oval, 0, reverse, 0); else if( i == 1) output_color = A_RGB( 0, 0, reverse, 31, reverse, 0); else { output_color = A_RGB( reverse, 31, reverse, reverse, 0, oval); output_color |= A_UNDERLINE | A_ITALIC; } attrset( output_color); addch( output_text[i][j]); } } #endif /* #if(CHTYPE_LONG >= 2) */ redraw = 0; attrset( COLOR_PAIR( 1)); if( extra_character_to_show && ymax > 23) mvaddch( 23, 63, (chtype)extra_character_to_show); #ifdef PDC_WIDE for( i = 0; i < 6; i++) { static const wchar_t spanish[] = L"Espa\xf1ol"; const int line = 24 + i / 3; const int col = 5 + 25 * (i % 3); static const wchar_t russian[] = {0x0420, 0x0443, 0x0441, 0x0441, 0x043a, 0x0438, 0x0439, L' ', 0x044f, 0x0437, 0x044b, 0x043a, 0}; static const wchar_t greek[] = {0x0395, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac, 0}; static const wchar_t georgian[] = {0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, L' ', 0x10d4, 0x10dc, 0x10d0, 0}; static const wchar_t fullwidth[] = { 0xff26, 0xff55, 0xff4c, 0xff4c, 0xff57, 0xff49, 0xff44, 0xff54, 0xff48, 0 }; /* "Fullwidth" */ static const wchar_t combining_marks[] = { L'C', L'o', 0x35c, L'm', L'b', 0x30a, L'i', L'n', L'i', 0x304, L'n', 0x30b, 0x329, L'g', 0x310, L' ', L'C', 0x338, L'h', 0x306, L'a', 0x361, L'r', L's', 0x30e, 0x348, 0 }; static const wchar_t *texts[6] = { spanish, russian, greek, georgian, fullwidth, combining_marks}; if( line < ymax && col < xmax) mvaddnwstr( line, 5 + 25 * (i % 3), texts[i], xmax - col); } #endif #ifdef MAYBE_TRY_THIS_SOMEWHERE_ELSE mvaddstr( 1, COL3, "Click on cursor descriptions to"); mvaddstr( 2, COL3, "cycle through possible cursors"); mvaddstr( 3, COL3, "Click on colors at left to change"); mvaddstr( 4, COL3, "colors used for under/over/outlining"); mvaddstr( 5, COL3, "Click 'Blink' at bottom to toggle"); mvaddstr( 6, COL3, "'real' blinking vs. 'highlit' blink"); #endif } mvaddnstr( 19, color_block_start, cursor_state_text[cursor_state_1], xmax - color_block_start); mvaddnstr( 20, color_block_start, cursor_state_text[cursor_state_2], xmax - color_block_start); curs_set( (cursor_state_1 << 8) | cursor_state_2); for( i = 0; i < color_block_cols * color_block_lines; i++) { const int n_color_blocks = 256; attrset( COLOR_PAIR( i >= n_color_blocks ? 2 : i)); if( i > 2 && i < n_color_blocks) init_pair((short)i, (short)i, COLOR_BLACK); if( !(i % color_block_cols)) move( i / color_block_cols, color_block_start); attron( A_REVERSE); addstr( " "); } move( 19, color_block_start - 3); refresh(); c = getch( ); attrset( COLOR_PAIR( 1)); if( c == KEY_RESIZE) { redraw = 1; resize_term( 0, 0); } else if( c == KEY_F(1) || c == 27) quit = 1; else if( c == KEY_F(2)) { blink_state ^= 1; PDC_set_blink( blink_state); } else if( c == KEY_F(3)) /* toggle SLKs */ { use_slk ^= 1; if( use_slk) slk_restore( ); else slk_clear( ); } else if( c >= KEY_F(4) && c < KEY_F(12)) { sscanf( labels[c - KEY_F(1)], "%x", (unsigned *)&fmt); if( use_slk) slk_setup( show_slk_index_line ? -fmt : fmt); } // else if( c == 'w') // PDC_write_screen_to_file( "scrdump.htm", curscr); if( c != KEY_MOUSE) { sprintf( buff, "Key %s hit ", keyname( c)); mvaddstr( 0, COL1, buff); } else { MEVENT mouse_event; #ifdef __PDCURSES__ nc_getmouse( &mouse_event); #else getmouse( &mouse_event); #endif sprintf( buff, "Mouse at %d x %d: %x ", mouse_event.x, mouse_event.y, (unsigned)mouse_event.bstate); mvaddstr( 0, COL1, buff); if( mouse_event.x >= color_block_start && mouse_event.y < color_block_lines) { int new_color = (mouse_event.x - color_block_start) / 2 + mouse_event.y * color_block_cols; if( new_color >= 256) new_color = -1; PDC_set_line_color( (short)new_color); } else if( mouse_event.x >= color_block_start) { int shift = ((mouse_event.bstate & BUTTON_MODIFIER_SHIFT) ? N_CURSORS - 1 : 1); if( mouse_event.y == 19) /* blink/non-blink toggle */ cursor_state_1 = (cursor_state_1 + shift) % N_CURSORS; else if( mouse_event.y == 20) /* cycle cursor state */ cursor_state_2 = (cursor_state_2 + shift) % N_CURSORS; } #ifdef PDC_WIDE else if( mouse_event.x >= 40 && mouse_event.x < 40 + 10) { if( mouse_event.y == 11) { redraw = 1; unicode_offset += 0x80; } else if( mouse_event.y == 12 && unicode_offset) { redraw = 1; unicode_offset -= 0x80; } } #endif } } endwin(); return 0; }
int main(int argc, char *argv[]) { int optc; int option_differences = 0, option_differences_cumulative = 0, option_exec = 0, option_beep = 0, option_color = 0, option_errexit = 0, option_help = 0, option_version = 0; double interval = 2; char *command; wchar_t *wcommand = NULL; char **command_argv; int command_length = 0; /* not including final \0 */ int wcommand_columns = 0; /* not including final \0 */ int wcommand_characters = 0; /* not including final \0 */ watch_usec_t next_loop; /* next loop time in us, used for precise time keeping only */ int pipefd[2]; int status; pid_t child; setlocale(LC_ALL, ""); progname = argv[0]; while ((optc = getopt_long(argc, argv, "+bced::hn:pvtx", longopts, (int *) 0)) != EOF) { switch (optc) { case 'b': option_beep = 1; break; case 'c': option_color = 1; break; case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'e': option_errexit = 1; break; case 'h': option_help = 1; break; case 't': show_title = 0; break; case 'x': option_exec = 1; break; case 'n': { char *str; interval = strtod(optarg, &str); if (!*optarg || *str) do_usage(); if(interval < 0.1) interval = 0.1; if(interval > ~0u/1000000) interval = ~0u/1000000; } break; case 'p': precise_timekeeping = 1; break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf(stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -b, --beep\t\t\t\tbeep if the command has a non-zero exit\n", stderr); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -e, --errexit\t\t\t\texit watch if the command has a non-zero exit\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr); fputs(" -p, --precise\t\t\t\tprecise timing, ignore command run time\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr); fputs(" -x, --exec\t\t\t\tpass command to exec instead of sh\n", stderr); exit(0); } if (optind >= argc) do_usage(); command_argv=&(argv[optind]); /* save for later */ command = strdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); command = realloc(command, command_length + s + 2); /* space and \0 */ endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); command_length += 1 + s; /* space then string length */ command[command_length] = '\0'; } // convert to wide for printing purposes //mbstowcs(NULL, NULL, 0); wcommand_characters = mbstowcs(NULL, command, 0); if(wcommand_characters < 0) { fprintf(stderr, "Unicode Handling Error\n"); exit(1); } wcommand = (wchar_t*)malloc((wcommand_characters+1) * sizeof(wcommand)); if(wcommand == NULL) { fprintf(stderr, "Unicode Handling Error (malloc)\n"); exit(1); } mbstowcs(wcommand, command, wcommand_characters+1); wcommand_columns = wcswidth(wcommand, -1); get_terminal_size(); /* Catch keyboard interrupts so we can put tty back in a sane state. */ signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); signal(SIGWINCH, winch_handler); /* Set up tty for curses use. */ curses_started = 1; initscr(); if (option_color) { if (has_colors()) { start_color(); use_default_colors(); init_ansi_colors(); } else option_color = 0; } nonl(); noecho(); cbreak(); if (precise_timekeeping) next_loop = get_time_usec(); for (;;) { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); char *header; FILE *p; int x, y; int oldeolseen = 1; if (screen_size_changed) { get_terminal_size(); resizeterm(height, width); clear(); /* redrawwin(stdscr); */ screen_size_changed = 0; first_screen = 1; } if (show_title) { // left justify interval and command, // right justify time, clipping all to fit window width int hlen = asprintf(&header, "Every %.1fs: ", interval); // the rules: // width < tsl : print nothing // width < tsl + hlen + 1: print ts // width = tsl + hlen + 1: print header, ts // width < tsl + hlen + 4: print header, ..., ts // width < tsl + hlen + wcommand_columns: print header, truncated wcommand, ..., ts // width > "": print header, wcomand, ts // this is slightly different from how it used to be if(width >= tsl) { if(width >= tsl + hlen + 1) { mvaddstr(0, 0, header); if(width >= tsl + hlen + 2) { if(width < tsl + hlen + 4) { mvaddstr(0, width - tsl - 4, "... "); }else{ if(width < tsl + hlen + wcommand_columns) { // print truncated int avail_columns = width - tsl - hlen; int using_columns = wcommand_columns; int using_characters = wcommand_characters; while(using_columns > avail_columns - 4) { using_characters--; using_columns = wcswidth(wcommand, using_characters); } mvaddnwstr(0, hlen, wcommand, using_characters); mvaddstr(0, width - tsl - 4, "... "); }else{ mvaddwstr(0, hlen, wcommand); } } } } mvaddstr(0, width - tsl + 1, ts); } free(header); } /* allocate pipes */ if (pipe(pipefd)<0) { perror("pipe"); do_exit(7); } /* flush stdout and stderr, since we're about to do fd stuff */ fflush(stdout); fflush(stderr); /* fork to prepare to run command */ child=fork(); if (child<0) { /* fork error */ perror("fork"); do_exit(2); } else if (child==0) { /* in child */ close (pipefd[0]); /* child doesn't need read side of pipe */ close (1); /* prepare to replace stdout with pipe */ if (dup2 (pipefd[1], 1)<0) { /* replace stdout with write side of pipe */ perror("dup2"); exit(3); } dup2(1, 2); /* stderr should default to stdout */ if (option_exec) { /* pass command to exec instead of system */ if (execvp(command_argv[0], command_argv)==-1) { perror("exec"); exit(4); } } else { status=system(command); /* watch manpage promises sh quoting */ /* propagate command exit status as child exit status */ if (!WIFEXITED(status)) { /* child exits nonzero if command does */ exit(1); } else { exit(WEXITSTATUS(status)); } } } /* otherwise, we're in parent */ close(pipefd[1]); /* close write side of pipe */ if ((p=fdopen(pipefd[0], "r"))==NULL) { perror("fdopen"); do_exit(5); } for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0; wint_t carry = WEOF; for (x = 0; x < width; x++) { wint_t c = L' '; int attr = 0; if (!eolseen) { /* if there is a tab pending, just spit spaces until the next stop instead of reading characters */ if (!tabpending) do { if(carry == WEOF) { c = my_getwc(p); }else{ c = carry; carry = WEOF; } }while (c != WEOF && !isprint(c) && c<128 && wcwidth(c) == 0 && c != L'\n' && c != L'\t' && (c != L'\033' || option_color != 1)); if (c == L'\033' && option_color == 1) { x--; process_ansi(p); continue; } if (c == L'\n') if (!oldeolseen && x == 0) { x = -1; continue; } else eolseen = 1; else if (c == L'\t') tabpending = 1; if (x==width-1 && wcwidth(c)==2) { y++; x = -1; //process this double-width carry = c; //character on the next line continue; //because it won't fit here } if (c == WEOF || c == L'\n' || c == L'\t') c = L' '; if (tabpending && (((x + 1) % 8) == 0)) tabpending = 0; } move(y, x); if (option_differences) { cchar_t oldc; in_wch(&oldc); attr = !first_screen && ((wchar_t)c != oldc.chars[0] || (option_differences_cumulative && (oldc.attr & A_ATTRIBUTES))); } if (attr) standout(); addnwstr((wchar_t*)&c,1); if (attr) standend(); if(wcwidth(c) == 0) { x--; } if(wcwidth(c) == 2) { x++; } } oldeolseen = eolseen; } fclose(p); /* harvest child process and get status, propagated from command */ if (waitpid(child, &status, 0)<0) { perror("waitpid"); do_exit(8); }; /* if child process exited in error, beep if option_beep is set */ if ((!WIFEXITED(status) || WEXITSTATUS(status))) { if (option_beep) beep(); if (option_errexit) do_exit(8); } first_screen = 0; refresh(); if (precise_timekeeping) { watch_usec_t cur_time = get_time_usec(); next_loop += USECS_PER_SEC*interval; if (cur_time < next_loop) usleep(next_loop - cur_time); } else usleep(interval * 1000000); } endwin(); return 0; }
/* Returns whether we should save our changes or not. Edits an existing an entry. This routine is far to big, and handles everything, from movement between fields, and editing fields, even painting the screen. */ int edit_entry(dbrecord * entry, const char *operationDesc, const char *entryDesc) { int *len; int col0; wchar_t *line=NULL; char tbuf[MAXSCREENWIDTH]; int code = 0; wchar_t ch; dbbuffer tmp; register int i, j, row, col; initHeading() ; /* Where is "column zero"? To right of longest field name. */ col0 = idx.idx_maxlen + 2; clear(); /* Clear the screen. */ initEntryLine() ; paintHeading(operationDesc) ; /* get max col TODO: change this when sigwhinch */ /* first time: allocat wchar fulldbdir name fulldbdir is a static.*/ for (row = STARTROW; row < (idx.idx_nlines+STARTROW); row++) { /* print field names. */ mvaddwstr(row, 0, idx.idx_lines[row-STARTROW]); } /* Allocate some space in a temporary entry, and copy entry */ /* to be edited into it. This way they can abort the edit. */ /* Here we need to allocate some extra space so we can edit */ for (i = STARTROW; i < (idx.idx_nlines+STARTROW); i++) { int k = i-STARTROW ; if (entry->db_lens[k] == 0) { /* Allocate memory for this line. */ size_t linelen = (MAXSCREENWIDTH * sizeof(wchar_t)); tmp.db_lines[k] = (wchar_t *) ymalloc(linelen, "edit_entry","tmp.db_lines[k]" ); memset(tmp.db_lines[k],0,linelen); tmp.db_lens[k] = 0; } else { /* Copy and print the line from the entry. */ tmp.db_lines[k] = wcsFromUnicode_alloc((size_t *) & tmp.db_lens[k], entry->db_lines[k], (int32_t) entry->db_lens[k]); if (tmp.db_lines[k] == NULL) { yerror( YICU_CONV_ERR ,"edit_entry->wcsFromUnicode_alloc", "tmp.db_lines[k]", YX_EXTERNAL_CAUSE ) ; } /* reallocates more space to maximum linebuffer size. */ tmp.db_lines[k] = (wchar_t *) yrealloc(tmp.db_lines[k], (size_t) (MAXSCREENWIDTH * sizeof(wchar_t)),"edit_entry","tmp.db_lines[k]"); } move(i, col0); clrtoeol(); if (tmp.db_lens[k] > 0) { addwstr(tmp.db_lines[k]); } } /* *could* have factored out the index code. */ col = col0; row = STARTROW; /* row er hvilke rad i recorden (felt). */ move(row, col); refresh(); /* Editing entry. We provide basic EMACS-style cntrl chars. */ while ((code = get_wch(&ch)) != EOF) { /* Get the current line and line length. */ line = tmp.db_lines[row-STARTROW]; /* f.p. *len = &tmp.db_lens[row]; */ len = &tmp.db_lens[row-STARTROW]; switch (ch) { case CTRL('a'): /* beginning of line */ col = col0; break; case KEY_LEFT: case CTRL('b'): /* back character */ if (col > col0) col--; break; case CTRL('d'): /* delete character */ if (col == (col0 + (int)wcslen(line))) { col--; } else if (*len) { /* Calculate position of character in string. */ int l = col - col0; /* Shuffle the string to the "left". */ while (l < *len) { line[l] = line[l + 1]; l++; } *len -= 1; /* Delete the character on the screen. */ delch(); if (col== (col0 + (int)wcslen(line)) ) { --col ; } } break; case CTRL('e'): /* end of line */ col = col0 + *len; break; case KEY_RIGHT: case CTRL('f'): /* forward character */ if ((col - col0) < *len) col++; break; case KEY_BACKSPACE: case CTRL('h'): /* backspace delete */ case '\177': if (*len && ((col - 1) >= col0)) { /* Calculate position of character to delete. */ int l = col - col0 - 1; if (l < 0) break; /* Shuffle string "left". */ while (l < *len) { line[l] = line[l + 1]; l++; } *len -= 1; /* Delete the character from the screen. */ move(row, --col); delch(); } break; case CTRL('k'): /* kill line */ if (len) { int l = col - col0; line[l] = (wchar_t) '\0'; *len = l; clrtoeol(); } break; case CTRL('l'): /* redraw screen */ wrefresh(curscr); break; case KEY_DOWN: case CTRL('n'): /* next line */ /* Wrap around to the top if necessary. */ if (++row >= (idx.idx_nlines+STARTROW)) row = STARTROW; /* If nothing in this column, move to nearest */ /* non-empty column. */ if ((col - col0) > tmp.db_lens[row-STARTROW]) col = col0 + tmp.db_lens[row-STARTROW]; line[*len] = (wchar_t) '\0'; break; case KEY_UP: case CTRL('p'): /* previous line */ /* Wrap around if necessary. */ if (--row < STARTROW) row = (idx.idx_nlines+STARTROW) - 1; /* If nothing in this column, move to nearest */ /* on-empty column. */ if ((col - col0) > tmp.db_lens[row-STARTROW]) col = col0 + tmp.db_lens[row-STARTROW]; line[*len] = (wchar_t) '\0'; break; case CTRL('['): /* save entry: ESC or something... */ if (line[*len] != (wchar_t) '\0') line[*len] = (wchar_t) '\0'; sprintf(tbuf, "Save %s entry in database (y/n)? ", entryDesc); ch = prompt_char(idx.idx_nlines + 2+ STARTROW, 0, tbuf, "yYnN"); /* See what they said. */ switch (ch) { case '\n': /* never mind */ move(idx.idx_nlines + 2, 0); clrtoeol(); break; case 'Y': /* save entry */ case 'y': /* Copy the temporary entry into the real entry. */ /* if there isn't anything to copy, then the entry db gets the value NULL, and length 0 */ for (i = 0; i < idx.idx_nlines; i++) { /* remove old contents in entry */ if (entry->db_lens[i] > 0) { free(entry->db_lines[i]); entry->db_lines[i] = NULL; entry->db_lens[i] = 0; } if (tmp.db_lens[i] > 0) { entry->db_lens[i]=tmp.db_lens[i] ; entry->db_lines[i] = unicodeFromWcs_alloc((size_t *) &entry->db_lens[i],tmp.db_lines[i]); if (entry->db_lines[i] == NULL) { yerror( YICU_CONV_ERR ,"edit_entry->unicodeFromWcs_alloc", "entry->db_lines[i]", YX_EXTERNAL_CAUSE ) ; } } /* had a dangling else bug here ? */ free(tmp.db_lines[i]); tmp.db_lines[i] = NULL ; tmp.db_lens[i] = 0; } return (1); case 'N': /* don't save entry */ case 'n': /* Free temporary memory. */ for (i = 0; i < idx.idx_nlines; i++) { tmp.db_lens[i] = 0; free(tmp.db_lines[i]); tmp.db_lines[i] = NULL; } return (0); } break; case '\r': /* return the string */ case '\n': /* go to next line */ /* Wrap around if necessary. */ if (++row >= (idx.idx_nlines+STARTROW)) row = STARTROW; col = col0; break; default: /* something else */ /* User's kill character: accepted to del line too. */ if (ch == KEY_DL) { move(row, col0); clrtoeol(); col = col0; *line = (wchar_t) '\0'; *len = 0; } else if (code != KEY_CODE_YES) { /* If it's a printable character, insert it into */ /* the string. */ if (iswctype(ch, wctype("print"))) { if (col == (COLS - 1)) { beep(); break; } /* Calculate character position. */ i = col - col0; /* If necessary, move string * to "right" */ /* to insert the character. */ if (i < *len) { for (j = *len; j >= i; j--) line[j + 1] = line[j]; } line[i] = ch; *len += 1; col++; /* Insert the character on the screen. */ InsWch((chtype) ch); } } break; } /* Move to the current row/column. */ move(row, col); refresh(); } return (0); }
void acsTest(WINDOW *win) { static const char *acs_names[] = { "ACS_ULCORNER", "ACS_URCORNER", "ACS_LLCORNER", "ACS_LRCORNER", "ACS_LTEE", "ACS_RTEE", "ACS_TTEE", "ACS_BTEE", "ACS_HLINE", "ACS_VLINE", "ACS_PLUS", #ifdef ACS_D_ULCORNER "ACS_D_ULCORNER", "ACS_D_URCORNER", "ACS_D_LLCORNER", "ACS_D_LRCORNER", "ACS_D_LTEE", "ACS_D_RTEE", "ACS_D_TTEE", "ACS_D_BTEE", "ACS_D_HLINE", "ACS_D_VLINE", "ACS_D_PLUS", "ACS_SD_ULCORNER", "ACS_SD_URCORNER", "ACS_SD_LLCORNER", "ACS_SD_LRCORNER", "ACS_SD_LTEE", "ACS_SD_RTEE", "ACS_SD_TTEE", "ACS_SD_BTEE", "ACS_SD_PLUS", "ACS_DS_ULCORNER", "ACS_DS_URCORNER", "ACS_DS_LLCORNER", "ACS_DS_LRCORNER", "ACS_DS_LTEE", "ACS_DS_RTEE", "ACS_DS_TTEE", "ACS_DS_BTEE", "ACS_DS_PLUS", #endif "ACS_S1", #ifdef ACS_S3 "ACS_S3", "ACS_S7", #endif "ACS_S9", "ACS_DIAMOND", #ifdef ACS_CLUB "ACS_CLUB", "ACS_SPADE", "ACS_HEART", "ACS_LTBOARD", #endif "ACS_BOARD", "ACS_CKBOARD", "ACS_DEGREE", "ACS_PLMINUS", "ACS_BULLET", #ifdef ACS_SM_BULLET "ACS_SM_BULLET", "ACS_MED_BULLET", "ACS_WHITE_BULLET", "ACS_PILCROW", "ACS_SECTION", "ACS_SMILE", "ACS_REV_SMILE", #endif "ACS_LARROW", "ACS_RARROW", "ACS_UARROW", "ACS_DARROW", "ACS_LANTERN", "ACS_BLOCK", #ifdef ACS_LEQUAL "ACS_LEQUAL", "ACS_GEQUAL", "ACS_NEQUAL", "ACS_PI", "ACS_STERLING", #endif #ifdef ACS_CENT "ACS_CENT", "ACS_YEN", "ACS_PESETA", "ACS_ALPHA", "ACS_BETA", "ACS_GAMMA", "ACS_UP_SIGMA", "ACS_LO_SIGMA", "ACS_MU", "ACS_TAU", "ACS_UP_PHI", "ACS_LO_PHI", "ACS_OMEGA", "ACS_DELTA", "ACS_INFINITY", "ACS_THETA", "ACS_EPSILON", "ACS_INTERSECT", "ACS_SUP2", "ACS_SUP_N", "ACS_TRIPLE_BAR", "ACS_APPROX_EQ", "ACS_SQUARE_ROOT", "ACS_NOT", "ACS_REV_NOT", "ACS_HALF", "ACS_QUARTER", "ACS_DIVISION", "ACS_UP_INTEGRAL", "ACS_LO_INTEGRAL", "ACS_UBLOCK", "ACS_BBLOCK", "ACS_LBLOCK", "ACS_RBLOCK", "ACS_A_ORDINAL", "ACS_O_ORDINAL", "ACS_INV_BANG", "ACS_INV_QUERY", "ACS_LEFT_ANG_QU", "ACS_RIGHT_ANG_QU", "ACS_CENTER_SQU", "ACS_F_WITH_HOOK", #endif }; const chtype acs_values[] = { ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER, ACS_LTEE, ACS_RTEE, ACS_TTEE, ACS_BTEE, ACS_HLINE, ACS_VLINE, ACS_PLUS, #ifdef ACS_D_ULCORNER ACS_D_ULCORNER, ACS_D_URCORNER, ACS_D_LLCORNER, ACS_D_LRCORNER, ACS_D_LTEE, ACS_D_RTEE, ACS_D_TTEE, ACS_D_BTEE, ACS_D_HLINE, ACS_D_VLINE, ACS_D_PLUS, ACS_SD_ULCORNER, ACS_SD_URCORNER, ACS_SD_LLCORNER, ACS_SD_LRCORNER, ACS_SD_LTEE, ACS_SD_RTEE, ACS_SD_TTEE, ACS_SD_BTEE, ACS_SD_PLUS, ACS_DS_ULCORNER, ACS_DS_URCORNER, ACS_DS_LLCORNER, ACS_DS_LRCORNER, ACS_DS_LTEE, ACS_DS_RTEE, ACS_DS_TTEE, ACS_DS_BTEE, ACS_DS_PLUS, #endif ACS_S1, #ifdef ACS_S3 ACS_S3, ACS_S7, #endif ACS_S9, ACS_DIAMOND, #ifdef ACS_CLUB ACS_CLUB, ACS_SPADE, ACS_HEART, ACS_LTBOARD, #endif ACS_BOARD, ACS_CKBOARD, ACS_DEGREE, ACS_PLMINUS, ACS_BULLET, #ifdef ACS_SM_BULLET ACS_SM_BULLET, ACS_MED_BULLET, ACS_WHITE_BULLET, ACS_PILCROW, ACS_SECTION, ACS_SMILE, ACS_REV_SMILE, #endif ACS_LARROW, ACS_RARROW, ACS_UARROW, ACS_DARROW, ACS_LANTERN, ACS_BLOCK, #ifdef ACS_LEQUAL ACS_LEQUAL, ACS_GEQUAL, ACS_NEQUAL, ACS_PI, ACS_STERLING, #endif #ifdef ACS_CENT ACS_CENT, ACS_YEN, ACS_PESETA, ACS_ALPHA, ACS_BETA, ACS_GAMMA, ACS_UP_SIGMA, ACS_LO_SIGMA, ACS_MU, ACS_TAU, ACS_UP_PHI, ACS_LO_PHI, ACS_OMEGA, ACS_DELTA, ACS_INFINITY, ACS_THETA, ACS_EPSILON, ACS_INTERSECT, ACS_SUP2, ACS_SUP_N, ACS_TRIPLE_BAR, ACS_APPROX_EQ, ACS_SQUARE_ROOT, ACS_NOT, ACS_REV_NOT, ACS_HALF, ACS_QUARTER, ACS_DIVISION, ACS_UP_INTEGRAL, ACS_LO_INTEGRAL, ACS_UBLOCK, ACS_BBLOCK, ACS_LBLOCK, ACS_RBLOCK, ACS_A_ORDINAL, ACS_O_ORDINAL, ACS_INV_BANG, ACS_INV_QUERY, ACS_LEFT_ANG_QU, ACS_RIGHT_ANG_QU, ACS_CENTER_SQU, ACS_F_WITH_HOOK, #endif }; #if HAVE_WIDE const cchar_t *wacs_values[] = { WACS_ULCORNER, WACS_URCORNER, WACS_LLCORNER, WACS_LRCORNER, WACS_LTEE, WACS_RTEE, WACS_TTEE, WACS_BTEE, WACS_HLINE, WACS_VLINE, WACS_PLUS, #ifdef WACS_D_ULCORNER WACS_D_ULCORNER, WACS_D_URCORNER, WACS_D_LLCORNER, WACS_D_LRCORNER, WACS_D_LTEE, WACS_D_RTEE, WACS_D_TTEE, WACS_D_BTEE, WACS_D_HLINE, WACS_D_VLINE, WACS_D_PLUS, WACS_SD_ULCORNER, WACS_SD_URCORNER, WACS_SD_LLCORNER, WACS_SD_LRCORNER, WACS_SD_LTEE, WACS_SD_RTEE, WACS_SD_TTEE, WACS_SD_BTEE, WACS_SD_PLUS, WACS_DS_ULCORNER, WACS_DS_URCORNER, WACS_DS_LLCORNER, WACS_DS_LRCORNER, WACS_DS_LTEE, WACS_DS_RTEE, WACS_DS_TTEE, WACS_DS_BTEE, WACS_DS_PLUS, #endif WACS_S1, #ifdef WACS_S3 WACS_S3, WACS_S7, #endif WACS_S9, WACS_DIAMOND, #ifdef WACS_CLUB WACS_CLUB, WACS_SPADE, WACS_HEART, WACS_LTBOARD, #endif WACS_BOARD, WACS_CKBOARD, WACS_DEGREE, WACS_PLMINUS, WACS_BULLET, #ifdef WACS_SM_BULLET WACS_SM_BULLET, WACS_MED_BULLET, WACS_WHITE_BULLET, WACS_PILCROW, WACS_SECTION, WACS_SMILE, WACS_REV_SMILE, #endif WACS_LARROW, WACS_RARROW, WACS_UARROW, WACS_DARROW, WACS_LANTERN, WACS_BLOCK, #ifdef WACS_LEQUAL WACS_LEQUAL, WACS_GEQUAL, WACS_NEQUAL, WACS_PI, WACS_STERLING, #endif #ifdef WACS_CENT WACS_CENT, WACS_YEN, WACS_PESETA, WACS_ALPHA, WACS_BETA, WACS_GAMMA, WACS_UP_SIGMA, WACS_LO_SIGMA, WACS_MU, WACS_TAU, WACS_UP_PHI, WACS_LO_PHI, WACS_OMEGA, WACS_DELTA, WACS_INFINITY, WACS_THETA, WACS_EPSILON, WACS_INTERSECT, WACS_SUP2, WACS_SUP_N, WACS_TRIPLE_BAR, WACS_APPROX_EQ, WACS_SQUARE_ROOT, WACS_NOT, WACS_REV_NOT, WACS_HALF, WACS_QUARTER, WACS_DIVISION, WACS_UP_INTEGRAL, WACS_LO_INTEGRAL, WACS_UBLOCK, WACS_BBLOCK, WACS_LBLOCK, WACS_RBLOCK, WACS_A_ORDINAL, WACS_O_ORDINAL, WACS_INV_BANG, WACS_INV_QUERY, WACS_LEFT_ANG_QU, WACS_RIGHT_ANG_QU, WACS_CENTER_SQU, WACS_F_WITH_HOOK, #endif }; static const wchar_t russian[] = {0x0420, 0x0443, 0x0441, 0x0441, 0x043a, 0x0438, 0x0439, L' ', 0x044f, 0x0437, 0x044b, 0x043a, 0}; static const wchar_t greek[] = {0x0395, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac, 0}; static const wchar_t georgian[] = {0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, L' ', 0x10d4, 0x10dc, 0x10d0, 0}; static const wchar_t fullwidth[] = { 0xff26, 0xff55, 0xff4c, 0xff4c, 0xff57, 0xff49, 0xff44, 0xff54, 0xff48, 0 }; /* "Fullwidth" */ #endif int i, tmarg = 1, ncols = COLS / 19; int n_items = sizeof( acs_names) / sizeof( acs_names[0]); int n_rows = (n_items + ncols - 1) / ncols; int col_size = COLS / ncols; i = 0; if( n_rows > LINES / 2 - 4) n_rows = LINES / 2 - 4; while( i < n_items) { int j; attrset(A_BOLD); mvaddstr( 1, (COLS - 23) / 2, "Alternate Character Set"); attrset(A_NORMAL); tmarg = 4; for( j = 0; i + j < n_items && j < n_rows * ncols; j++) { move((j % n_rows) * 2 + tmarg, (j / n_rows) * col_size + col_size / 2 - 7); addch(acs_values[i + j]); printw(" %s", acs_names[i + j]); } mvaddstr(tmarg + n_rows * 2 + 2, 3, "Press any key to continue"); getch(); i += j; clear( ); } #if HAVE_WIDE i = 0; while( i < n_items) { int j; attrset(A_BOLD); mvaddstr( 1, (COLS - 28) / 2, "Wide Alternate Character Set"); attrset(A_NORMAL); tmarg = 4; for( j = 0; i + j < n_items && j < n_rows * ncols; j++) { move((j % n_rows) * 2 + tmarg, (j / n_rows) * col_size + col_size / 2 - 7); add_wch(wacs_values[i + j]); printw(" W%s", acs_names[i + j]); } /* Spanish, Russian, Greek, Georgian, fullwidth */ tmarg += n_rows * 2; mvaddwstr(tmarg, COLS / 8 - 5, L"Espa\xf1ol"); mvaddwstr(tmarg, 3 * (COLS / 8) - 5, russian); mvaddwstr(tmarg, 5 * (COLS / 8) - 5, greek); mvaddwstr(tmarg, 7 * (COLS / 8) - 5, georgian); mvaddwstr(tmarg + 1, COLS / 8 - 5, fullwidth); #if(CHTYPE_LONG >= 2) /* "non-standard" 64-bit chtypes */ mvaddch( tmarg + 1, 7 * (COLS / 8) - 5, (chtype)0x1d11e); #endif /* U+1D11E = musical symbol G clef */ mvaddstr(tmarg + 2, 3, "Press any key to continue"); getch(); i += j; clear( ); } #endif }
void commentScreenDisplay(CommentScreen *screen) { int i, screenLines; wchar_t *tmpbuf; int bufSize, lastLine, bufLen; if (screen == NULL) return ; bufSize = sizeof(wchar_t) * (COLS + 1); bufLen = COLS; tmpbuf = malloc(bufSize); memset(tmpbuf, 0, bufSize); for (i = 0; i < bufLen; i++) tmpbuf[i] = L' '; screenLines = screen->offset + screen->displayed + 1; for (i = 0; i < screen->displayed + screen->offset + 1 + screen->commentOpenSize; i++) mvaddwstr(i, 0, tmpbuf); attron(COLOR_PAIR(1)); for(i = screen->offset; i < screenLines; i++) { if(i == screen->selected) attron(COLOR_PAIR(2)); if (i < screen->lineCount && screen->lines[i]->text != NULL) mvaddwstr(i - screen->offset, 0, screen->lines[i]->text); else mvaddwstr(i - screen->offset, 0, tmpbuf); if (i == screen->selected) attron(COLOR_PAIR(1)); } if (screen->commentOpen) { RedditComment *current; lastLine = screenLines - screen->offset; for (i = lastLine; i < lastLine + screen->commentOpenSize; i++) mvaddwstr(i, 0, tmpbuf); for (i = 0; i < bufLen; i++) tmpbuf[i] = L'-'; tmpbuf[bufLen] = (wchar_t)0; attron(COLOR_PAIR(2)); mvaddwstr(lastLine, 0, tmpbuf); attron(COLOR_PAIR(1)); if (screen->lineCount >= screen->selected) { current = screen->lines[screen->selected]->comment; if (current != NULL) { swprintf(tmpbuf, bufLen, L"%s - %d Score - %s", current->author, current->ups, current->created_utc); mvaddwstr(lastLine + 1, 0, tmpbuf); swprintf(tmpbuf, bufLen, L"-------"); mvaddwstr(lastLine + 2, 0, tmpbuf); mvaddwstr(lastLine + 3, 0, &(current->wbodyEsc[current->advance] )); } } } free(tmpbuf); refresh(); }
int draw_terminal_ncurses(int is_tty, int terminal_height, int terminal_width, int bars_count, int bar_width, int bar_spacing, int rest, const int f[200], int flastd[200], int gradient) { const wchar_t* bar_heights[] = {L"\u2581", L"\u2582", L"\u2583", L"\u2584", L"\u2585", L"\u2586", L"\u2587", L"\u2588"}; #define LAST ((sizeof(bar_heights) / sizeof(bar_heights[0])) - 1) // output: check if terminal has been resized if (!is_tty) { if (LINES != terminal_height || COLS != terminal_width) { return TERMINAL_RESIZED; } } const int height = terminal_height - 1; #define CURRENT_COLUMN bar*bar_width + width + bar*bar_spacing + rest for (int bar = 0; bar < bars_count; bar++) { if (f[bar] > flastd[bar]) { // higher then last frame if (is_tty) { for (int n = flastd[bar] / 8; n < f[bar] / 8; n++) { if (gradient) change_colors(n, height); for (int width = 0; width < bar_width; width++) mvprintw((height - n), CURRENT_COLUMN, "%d", 8); } } else { for (int n = flastd[bar] / 8; n < f[bar] / 8; n++) { if (gradient) change_colors(n, height); for (int width = 0; width < bar_width; width++) mvaddwstr((height - n), CURRENT_COLUMN, bar_heights[LAST]); } } if (gradient) change_colors(f[bar] / 8, height); if (f[bar] % 8) { if (is_tty) { for (int width = 0; width < bar_width; width++) mvprintw((height - f[bar] / 8), CURRENT_COLUMN, "%d", (f[bar] % 8)); } else { for (int width = 0; width < bar_width; width++) mvaddwstr((height - f[bar] / 8), CURRENT_COLUMN, bar_heights[(f[bar] % 8) - 1]); } } } else if(f[bar] < flastd[bar]) { // lower then last frame for (int n = f[bar] / 8; n < flastd[bar]/8 + 1; n++) for (int width = 0; width < bar_width; width++) mvaddstr((height - n), CURRENT_COLUMN, " "); if (f[bar] % 8) { if (gradient) change_colors(f[bar] / 8, height); if (is_tty) { for (int width = 0; width < bar_width; width++) mvprintw((height - f[bar] / 8), CURRENT_COLUMN, "%d", (f[bar] % 8)); } else { for (int width = 0; width < bar_width; width++) mvaddwstr((height - f[bar] / 8), CURRENT_COLUMN, bar_heights[(f[bar] % 8) - 1]); } } } #undef CURRENT_COLUMN flastd[bar] = f[bar]; // memory for falloff func } refresh(); return 0; }
void acsTest(WINDOW *win) { #ifdef ACS_S3 # define ACSNUM 32 #else # define ACSNUM 25 #endif static const char *acs_names[] = { "ACS_ULCORNER", "ACS_URCORNER", "ACS_LLCORNER", "ACS_LRCORNER", "ACS_LTEE", "ACS_RTEE", "ACS_TTEE", "ACS_BTEE", "ACS_HLINE", "ACS_VLINE", "ACS_PLUS", "ACS_S1", "ACS_S9", "ACS_DIAMOND", "ACS_CKBOARD", "ACS_DEGREE", "ACS_PLMINUS", "ACS_BULLET", "ACS_LARROW", "ACS_RARROW", "ACS_UARROW", "ACS_DARROW", "ACS_BOARD", "ACS_LANTERN", "ACS_BLOCK" #ifdef ACS_S3 , "ACS_S3", "ACS_S7", "ACS_LEQUAL", "ACS_GEQUAL", "ACS_PI", "ACS_NEQUAL", "ACS_STERLING" #endif }; chtype acs_values[ACSNUM]; #if HAVE_WIDE cchar_t *wacs_values[] = { WACS_ULCORNER, WACS_URCORNER, WACS_LLCORNER, WACS_LRCORNER, WACS_LTEE, WACS_RTEE, WACS_TTEE, WACS_BTEE, WACS_HLINE, WACS_VLINE, WACS_PLUS, WACS_S1, WACS_S9, WACS_DIAMOND, WACS_CKBOARD, WACS_DEGREE, WACS_PLMINUS, WACS_BULLET, WACS_LARROW, WACS_RARROW, WACS_UARROW, WACS_DARROW, WACS_BOARD, WACS_LANTERN, WACS_BLOCK # ifdef WACS_S3 , WACS_S3, WACS_S7, WACS_LEQUAL, WACS_GEQUAL, WACS_PI, WACS_NEQUAL, WACS_STERLING # endif }; static const wchar_t russian[] = {0x0420, 0x0443, 0x0441, 0x0441, 0x043a, 0x0438, 0x0439, L' ', 0x044f, 0x0437, 0x044b, 0x043a, 0 }; static const wchar_t greek[] = {0x0395, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac, 0 }; static const wchar_t georgian[] = {0x10e5, 0x10d0, 0x10e0, 0x10d7, 0x10e3, 0x10da, 0x10d8, L' ', 0x10d4, 0x10dc, 0x10d0, 0 }; #endif int i, tmarg = (LINES - 22) / 2; attrset(A_BOLD); mvaddstr(tmarg, (COLS - 23) / 2, "Alternate Character Set"); attrset(A_NORMAL); tmarg += 3; #define A(b,c) acs_values[b] = ACS_##c A(0,ULCORNER); A(1,URCORNER); A(2,LLCORNER); A(3,LRCORNER); A(4,LTEE); A(5,RTEE); A(6,TTEE); A(7,BTEE); A(8,HLINE); A(9,VLINE); A(10,PLUS); A(11,S1); A(12,S9); A(13,DIAMOND); A(14,CKBOARD); A(15,DEGREE); A(16,PLMINUS); A(17,BULLET); A(18,LARROW); A(19,RARROW); A(20,UARROW); A(21,DARROW); A(22,BOARD); A(23,LANTERN); A(24,BLOCK); #ifdef ACS_S3 A(25,S3); A(26,S7); A(27,LEQUAL); A(28,GEQUAL); A(29,PI); A(30,NEQUAL); A(31,STERLING); #endif #undef A for (i = 0; i < ACSNUM; i++) { move((i % 8) * 2 + tmarg, (i / 8) * (COLS / 4) + (COLS / 8 - 7)); addch(acs_values[i]); printw(" %s", acs_names[i]); } mvaddstr(tmarg + 18, 3, "Press any key to continue"); getch(); #if HAVE_WIDE clear(); attrset(A_BOLD); mvaddstr(tmarg - 3, (COLS - 28) / 2, "Wide Alternate Character Set"); attrset(A_NORMAL); for (i = 0; i < ACSNUM; i++) { move((i % 8) * 2 + tmarg, (i / 8) * (COLS / 4) + (COLS / 8 - 7)); add_wch(wacs_values[i]); printw(" W%s", acs_names[i]); } /* Spanish, Russian, Greek, Georgian */ mvaddwstr(tmarg + 16, COLS / 8 - 5, L"Espa\xf1ol"); mvaddwstr(tmarg + 16, 3 * (COLS / 8) - 5, russian); mvaddwstr(tmarg + 16, 5 * (COLS / 8) - 5, greek); mvaddwstr(tmarg + 16, 7 * (COLS / 8) - 5, georgian); mvaddstr(tmarg + 18, 3, "Press any key to continue"); getch(); #endif }