📄 curses.c
字号:
* Never use this function. This function modifies its first argument. The identity of the delimiting character is lost. This function cannot be used on constant strings. * * and on FreeBSD: * * This interface is obsoleted by strsep(3). * * We bad. */ item = strtok(p, " \t\n"); /* Get first item. */ fore = strtok(NULL, " \t\n"); if (!fore) /* only one item */ continue; back = strtok(NULL, " \t\n"); if (!back) /* only two items */ continue; bg = COLOR_BLACK; fg = COLOR_WHITE; /* Check whether fore or back match names of colors. */ for (ii = COLOR_BLACK; ii < sizeof(colors) / sizeof(*colors); ii++) { if (strcasecmp(fore, colors[ii]) == 0) fg = ii; if (strcasecmp(back, colors[ii]) == 0) bg = ii; } /* Check whether item string matches names of items. */ for (ii = 0; ii < sizeof(items) / sizeof(*items); ii++) if (strcasecmp(item, items[ii]) == 0) init_pair(ii + 1, fg, bg); } refresh(); fclose(schemefile); return 0;}void Inter(void){ int incr, dir, dev, key, y = 0;#if HAVE_GETMOUSE MEVENT event;#endif /* HAVE_GETMOUSE */ levelbalmode = 0; /* Find first existing channel. */ for (dev = 0; !((devmask | recmask) & (1 << dev)); dev++); y = CountChannels(dev); current_dev = dev; /* Highlight the label. */ HighlightLabelCurses(); if (devmask & (1 << dev)) { EraseLevel(current_dev); DrawLevel(current_dev); DrawLevelBalMode(current_dev, 0); } PlaceCursor(); signal(SIGALRM, AumixSignalHandler); alarm(REFRESH_PERIOD); for (;;) { key = Getch(); incr = 0; dir = 0; switch (key) { case '.': case ',': case '<': case '>': case '\t': case '\n': levelbalmode = !levelbalmode; attrset(COLOR_PAIR(AXIS_COLOR)); mvaddstr(YOFFSET + CountChannels(current_dev), XOFFSET + menu_width + R_P_WIDTH + level_width, " "); HighlightLabelCurses(); DrawLevelBalMode(current_dev, levelbalmode); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ((levelbalmode) && ((1 << current_dev) & stereodevs)) AdjustBalance(current_dev, 0, (MAXLEVEL / 10) * (key - '0')); else AdjustLevel(current_dev, 0, (MAXLEVEL / 10) * (key - '0')); break; case KEY_UP: case KEY_PPAGE: case KEY_DOWN: case KEY_NPAGE: if (key == KEY_UP || key == KEY_PPAGE) dir = -1; if (!dir) /* if not PgUp or < pressed */ dir = 1; /* un-highlight current label */ EraseLevel(current_dev); DrawLevel(current_dev); attrset(COLOR_PAIR(AXIS_COLOR)); y = CountChannels(current_dev); mvaddstr(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + level_width, " "); attrset(COLOR_PAIR(AXIS_COLOR)); mvaddstr(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + level_width + ARROW_WIDTH, LOCAL_TEXT(dev_label[current_dev])); /* switch to next existing device */ do { if (dir == 1) { current_dev++; /* Wrap around. */ if (current_dev > SOUND_MIXER_NRDEVICES - 1) current_dev = 0; } else { current_dev--; if (current_dev < 0) current_dev = SOUND_MIXER_NRDEVICES - 1; } } while (!((1 << current_dev) & (devmask | recmask))); HighlightLabelCurses(); EraseLevel(current_dev); DrawLevel(current_dev); DrawLevelBalMode(current_dev, levelbalmode); PlaceCursor(); break; case ' ': SwitchRecordPlay(current_dev); break; case '[': if ((levelbalmode) && ((1 << current_dev) & stereodevs)) AdjustBalance(current_dev, 0, 0); else AdjustLevel(current_dev, 0, 0); break; case ']': if ((levelbalmode) && ((1 << current_dev) & stereodevs)) AdjustBalance(current_dev, 0, MAXLEVEL); else AdjustLevel(current_dev, 0, MAXLEVEL); break; case '+': case '-': case KEY_LEFT: case KEY_RIGHT: if ((levelbalmode) && ((1 << current_dev) & stereodevs)) if (key == '+' || key == KEY_RIGHT) AdjustBalance(current_dev, balance_increment, -1); else AdjustBalance(current_dev, -balance_increment, -1); else if (key == '+' || key == KEY_RIGHT) AdjustLevel(current_dev, level_increment, -1); else AdjustLevel(current_dev, -level_increment, -1); break; case '|': AdjustBalance(current_dev, -1, (MAXLEVEL / 2)); break;#if HAVE_GETMOUSE case KEY_MOUSE: if (getmouse(&event) == OK) DoMouse(event.x, event.y, NCURSES_TO_DOMOUSE(event.bstate)); break;#endif /* HAVE_GETMOUSE */ /* Be friendly to pre-ANSI terminals and check after KEY_. */ case CTRL('D'): return; break; case CTRL('L'): case CTRL('R'): InitScreen(); DrawLevelBalMode(current_dev, levelbalmode); HighlightLabelCurses(); break; } key = tolower(key); if (key == *chark) { KeysBox(); } else if (key == *charl) LoadSettings(); else if (key == *charm) ToggleMuting(); else if (key == *charo) Muting(current_dev, MUTE_ONLY); else if (key == *charq) return; else if (key == *chars) SaveSettings(); else if (key == *charu) Muting(MUTE_NO_DEVICE, MUTE_OFF); refresh(); }}void DrawLevelBalModeCurses(int dev, int mode)/* arrow to show whether keyboard commands will adjust level or balance */{ int y; y = CountChannels(dev); attrset(COLOR_PAIR(ACTIVE_COLOR) | ((has_colors()) ? A_BOLD : A_REVERSE)); if ((1 << dev) & devmask) { if ((mode) && ((1 << dev) & stereodevs)) { mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + level_width + ARROW_WIDTH + label_width, '>'); } else { mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + level_width, '<'); } } PlaceCursor();}void DrawLevelCurses(int dev){ int left, right, temp, y = 0; if (!((1 << dev) & devmask) || (dev > SOUND_MIXER_NRDEVICES - 1) || (dev < 0)) return; y = CountChannels(dev); ErrorExitWarn(ReadLevel(dev, &temp), 'e'); left = temp & 0x7F; right = (temp >> 8) & 0x7F; /* * According to curs_refresh(3x), * * The refresh and wrefresh routines (or wnoutrefresh and doupdate) must be called to get actual output to the ter- minal, as other routines merely manipulate data struc- tures. The routine wrefresh copies the named window to the physical terminal screen, taking into account what is already there in order to do optimizations. * * However, when the balance is centred, as it often is, we probably save a few CPU cycles by checking for this rather than letting ncurses take care of it. */ if (left != right) { attrset(COLOR_PAIR(AXIS_COLOR)); mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + left / level_increment, 'L'); mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + right / level_increment, 'R'); } attrset(COLOR_PAIR(HANDLE_COLOR) | ((has_colors()) ? A_BOLD : A_REVERSE)); mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + (left + right) / level_increment / 2, 'O'); PlaceCursor();}void EraseLevelCurses(int dev){ /* Redraw level track. */ int ii, y = 0; if (!((1 << dev) & devmask) || (dev > SOUND_MIXER_NRDEVICES - 1) || (dev < 0)) return; y = CountChannels(dev); attrset(COLOR_PAIR(TRACK_COLOR)); for (ii = 0; ii < level_width; ii++) mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + ii, '+'); PlaceCursor();}void RedrawBalanceCurses(int dev)/* Redraw balance track. */{ int left, right, max, temp, balset, y; y = CountChannels(dev); if ((1 << dev) & stereodevs) { attrset(COLOR_PAIR(TRACK_COLOR)); for (temp = 0; temp < balance_width; temp++) mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + level_width + label_width + ARROW_WIDTH * 2 + temp, '+'); ErrorExitWarn(ReadLevel(dev, &temp), 'e'); left = temp & 0x7F; right = (temp >> 8) & 0x7F; max = (left > right) ? left : right; if (temp) { balset = (left > right) ? (MAXLEVEL / 2) * right / max : MAXLEVEL - ((MAXLEVEL / 2) * left / max); } else { balset = (MAXLEVEL / 2); } attrset(COLOR_PAIR(HANDLE_COLOR) | ((has_colors()) ? A_BOLD : A_REVERSE)); mvaddch(YOFFSET + y, XOFFSET + menu_width + R_P_WIDTH + level_width + ARROW_WIDTH * 2 + label_width + balset / balance_increment, 'O'); PlaceCursor(); }}void DrawRecordPlayCurses(int dev){ attrset((1 << dev) & recsrc ? COLOR_PAIR(RECORD_COLOR) | ((has_colors()) ? A_NORMAL : A_REVERSE) : COLOR_PAIR(PLAY_COLOR)); mvaddch(YOFFSET + CountChannels(dev), XOFFSET + menu_width, ((1 << dev) & recsrc ? 'R' : 'P')); PlaceCursor();}void CloseScreenCurses(void){ if (interactive) { initscr(); /* Calling refresh() will cause a segfault if we do it without initializing the screen. */ clear(); refresh(); endwin(); }}#endif /* HAVE_CURSES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -