diff --git a/alsamixer/Makefile.am b/alsamixer/Makefile.am
index 3fe7a74..d1021f9 100644
--- a/alsamixer/Makefile.am
+++ b/alsamixer/Makefile.am
@@ -10,6 +10,8 @@ alsamixer_SOURCES = card_select.c card_select.h \
die.c die.h \
mainloop.c mainloop.h \
mem.c mem.h \
+ menu_widget.c menu_widget.h \
+ mixer_clickable.c mixer_clickable.h \
mixer_controls.c mixer_controls.h \
mixer_display.c mixer_display.h \
mixer_widget.c mixer_widget.h \
diff --git a/alsamixer/bindings.h b/alsamixer/bindings.h
index 1e9dd6d..fa2e8d3 100644
--- a/alsamixer/bindings.h
+++ b/alsamixer/bindings.h
@@ -51,7 +51,12 @@ enum mixer_command {
CMD_MIXER_TOGGLE_MUTE,
CMD_MIXER_TOGGLE_CAPTURE,
CMD_MIXER_BALANCE_CONTROL,
- CMD_MIXER_REFRESH
+ CMD_MIXER_REFRESH,
+
+ // Mouse
+ CMD_MIXER_MOUSE_CLICK_MUTE,
+ CMD_MIXER_MOUSE_CLICK_VOLUME_BAR,
+ CMD_MIXER_MOUSE_CLICK_CONTROL_ENUM,
};
enum textbox_command {
diff --git a/alsamixer/card_select.c b/alsamixer/card_select.c
index e970203..6762ecd 100644
--- a/alsamixer/card_select.c
+++ b/alsamixer/card_select.c
@@ -28,10 +28,10 @@
#include "utils.h"
#include "colors.h"
#include "widget.h"
+#include "menu_widget.h"
#include "mixer_widget.h"
#include "device_name.h"
#include "card_select.h"
-#include "bindings.h"
struct card {
struct card *next;
@@ -60,33 +60,15 @@ static void on_key_enter(void)
}
}
-static void on_menu_key(int key)
-{
- if (key < ARRAY_SIZE(textbox_bindings)) {
- key = textbox_bindings[key];
- if (key >= CMD_TEXTBOX___MIN_MENU_COMMAND &&
- key <= CMD_TEXTBOX___MAX_MENU_COMMAND)
- menu_driver(menu, key + KEY_MAX);
- }
-}
-
static void on_handle_key(int key)
{
- switch (key) {
- case 27:
- case KEY_CANCEL:
- case 'q':
- case 'Q':
- list_widget.close();
- break;
- case 10:
- case 13:
- case KEY_ENTER:
- on_key_enter();
- break;
- default:
- on_menu_key(key);
- break;
+ switch (menu_widget_handle_key(menu, key)) {
+ case KEY_ENTER:
+ on_key_enter();
+ break;
+ case KEY_CANCEL:
+ list_widget.close();
+ break;
}
}
diff --git a/alsamixer/mainloop.c b/alsamixer/mainloop.c
index a50109b..e80f232 100644
--- a/alsamixer/mainloop.c
+++ b/alsamixer/mainloop.c
@@ -50,6 +50,7 @@ void initialize_curses(bool use_color)
#endif
window_size_changed(); /* update screen_lines/cols */
init_colors(use_color);
+ mousemask(ALL_MOUSE_EVENTS, NULL);
snd_lib_error_set_handler(black_hole_error_handler);
}
diff --git a/alsamixer/menu_widget.c b/alsamixer/menu_widget.c
new file mode 100644
index 0000000..30940a7
--- /dev/null
+++ b/alsamixer/menu_widget.c
@@ -0,0 +1,63 @@
+#include "menu_widget.h"
+#include "colors.h"
+#include "utils.h"
+#include "bindings.h"
+
+/* Returns
+ * - KEY_CANCEL: close is requested
+ * - KEY_ENTER: item is selected
+ * - -1: no action
+ */
+int menu_widget_handle_key(MENU *menu, int key)
+{
+ MEVENT m;
+
+ switch (key) {
+ case 27:
+ case KEY_CANCEL:
+ case 'q':
+ case 'Q':
+ return KEY_CANCEL;
+ case '\n':
+ case '\r':
+ case KEY_ENTER:
+ return KEY_ENTER;
+
+ case KEY_MOUSE:
+ switch (menu_driver(menu, KEY_MOUSE)) {
+ case E_UNKNOWN_COMMAND:
+ /* If you double-click an item a REQ_TOGGLE_ITEM is generated
+ * and E_UNKNOWN_COMMAND is returned. (man menu_driver) */
+ return KEY_ENTER;
+ case E_REQUEST_DENIED:
+ /* If menu did not handle KEY_MOUSE is has to be removed from
+ * input queue to prevent an infinite loop. */
+ key = wgetch(menu_win(menu));
+ if (key == KEY_MOUSE) {
+ if (getmouse(&m) == ERR)
+ return -1;
+ if (m.bstate & (BUTTON4_PRESSED|BUTTON4_CLICKED))
+ menu_driver(menu, REQ_UP_ITEM);
+#if NCURSES_MOUSE_VERSION > 1
+ else if (m.bstate & (BUTTON5_PRESSED|BUTTON5_CLICKED))
+ menu_driver(menu, REQ_DOWN_ITEM);
+#endif
+ else
+ return KEY_CANCEL;
+ }
+ else if (key > 0)
+ ungetch(key);
+ }
+ return -1;
+
+ default:
+ if (key < ARRAY_SIZE(textbox_bindings)) {
+ key = textbox_bindings[key];
+ if (key >= CMD_TEXTBOX___MIN_MENU_COMMAND &&
+ key <= CMD_TEXTBOX___MAX_MENU_COMMAND)
+ menu_driver(menu, key + KEY_MAX);
+ }
+
+ return -1;
+ }
+}
diff --git a/alsamixer/menu_widget.h b/alsamixer/menu_widget.h
new file mode 100644
index 0000000..ad3ed0e
--- /dev/null
+++ b/alsamixer/menu_widget.h
@@ -0,0 +1,9 @@
+#ifndef MENU_WIDGET_H_INCLUDED
+#define MENU_WIDGET_H_INCLUDED
+
+#include "widget.h"
+#include
+
+int menu_widget_handle_key(MENU *menu, int key);
+
+#endif
diff --git a/alsamixer/mixer_clickable.c b/alsamixer/mixer_clickable.c
new file mode 100644
index 0000000..c772f37
--- /dev/null
+++ b/alsamixer/mixer_clickable.c
@@ -0,0 +1,136 @@
+#include
+#include
+#include "mixer_clickable.h"
+
+extern int screen_cols;
+extern int screen_lines;
+
+static struct clickable_rect *clickable_rects = NULL;
+static unsigned int clickable_rects_count = 0;
+static unsigned int last_rect = 0;
+
+/* Using 0 instead of -1 for marking free rectangles allows us to use
+ * memset for `freeing` all rectangles at once.
+ * Zero is actually a valid coordinate in ncurses, but since we don't have
+ * any clickables in the top line this is fine. */
+#define FREE_MARKER 0
+#define RECT_IS_FREE(RECT) ((RECT).y1 == FREE_MARKER)
+#define RECT_FREE(RECT) ((RECT).y1 = FREE_MARKER)
+
+void clickable_set(int y1, int x1, int y2, int x2, command_enum command, int arg1) {
+ struct clickable_rect* tmp;
+ unsigned int i;
+
+ for (i = last_rect; i < clickable_rects_count; ++i) {
+ if (RECT_IS_FREE(clickable_rects[i])) {
+ last_rect = i;
+ goto SET_CLICKABLE_DATA;
+ }
+ }
+
+ for (i = 0; i < last_rect; ++i) {
+ if (RECT_IS_FREE(clickable_rects[i])) {
+ last_rect = i;
+ goto SET_CLICKABLE_DATA;
+ }
+ }
+
+ last_rect = clickable_rects_count;
+ tmp = realloc(clickable_rects, (clickable_rects_count + 8) * sizeof(*clickable_rects));
+ if (!tmp) {
+ free(clickable_rects);
+ clickable_rects = NULL;
+ clickable_rects_count = 0;
+ last_rect = 0;
+ return;
+ }
+ clickable_rects = tmp;
+#if FREE_MARKER == 0
+ memset(clickable_rects + clickable_rects_count, 0, 8 * sizeof(*clickable_rects));
+#else
+ for (i = clickable_rects_count; i < clickable_rects_count + 8; ++i)
+ RECT_FREE(clickable_rects[i]);
+#endif
+ clickable_rects_count += 8;
+
+SET_CLICKABLE_DATA:
+ clickable_rects[last_rect] = (struct clickable_rect) {
+ .y1 = y1,
+ .x1 = x1,
+ .x2 = x2,
+ .y2 = y2,
+ .command = command,
+ .arg1 = arg1
+ };
+}
+
+void clickable_set_relative(WINDOW *win, int y1, int x1, int y2, int x2, command_enum command, int arg1) {
+ int y, x;
+ getyx(win, y, x);
+ y1 = y + y1;
+ x1 = x + x1;
+ y2 = y + y2;
+ x2 = x + x2;
+ clickable_set(y1, x1, y2, x2, command, arg1);
+}
+
+void clickable_clear(int y1, int x1, int y2, int x2) {
+#define IS_IN_RECT(Y, X) (Y >= y1 && Y <= y2 && X >= x1 && X <= x2)
+ unsigned int i;
+
+ if (x1 == 0 && x2 == -1 && y2 == -1) {
+ if (y1 == 0) {
+ // Optimize case: clear all
+#if FREE_MARKER == 0
+ if (clickable_rects)
+ memset(clickable_rects, 0,
+ clickable_rects_count * sizeof(*clickable_rects));
+#else
+ for (i = 0; i < clickable_rects_count; ++i)
+ RECT_FREE(clickable_rects[i]);
+#endif
+ }
+ else {
+ // Optimize case: clear all lines beyond y1
+ for (i = 0; i < clickable_rects_count; ++i) {
+ if (clickable_rects[i].y2 >= y1)
+ RECT_FREE(clickable_rects[i]);
+ }
+ }
+ return;
+ }
+
+ if (y2 < 0)
+ y2 = screen_lines + y2 + 1;
+ if (x2 < 0)
+ x2 = screen_cols + x2 + 1;
+
+ for (i = 0; i < clickable_rects_count; ++i) {
+ if (!RECT_IS_FREE(clickable_rects[i]) && (
+ IS_IN_RECT(clickable_rects[i].y1, clickable_rects[i].x1) ||
+ IS_IN_RECT(clickable_rects[i].y2, clickable_rects[i].x2)
+ ))
+ {
+ RECT_FREE(clickable_rects[i]);
+ }
+ }
+}
+
+struct clickable_rect* clickable_find(int y, int x) {
+ unsigned int i;
+
+ for (i = 0; i < clickable_rects_count; ++i) {
+ if (
+ !RECT_IS_FREE(clickable_rects[i]) &&
+ y >= clickable_rects[i].y1 &&
+ x >= clickable_rects[i].x1 &&
+ y <= clickable_rects[i].y2 &&
+ x <= clickable_rects[i].x2
+ )
+ {
+ return &clickable_rects[i];
+ }
+ }
+
+ return NULL;
+}
diff --git a/alsamixer/mixer_clickable.h b/alsamixer/mixer_clickable.h
new file mode 100644
index 0000000..792c711
--- /dev/null
+++ b/alsamixer/mixer_clickable.h
@@ -0,0 +1,21 @@
+#ifndef MIXER_CLICKABLE_H
+#define MIXER_CLICKABLE_H
+
+#include CURSESINC
+#include "bindings.h"
+
+struct clickable_rect {
+ short y1;
+ short x1;
+ short y2;
+ short x2;
+ command_enum command;
+ int arg1;
+};
+
+void clickable_set(int y1, int x1, int y2, int x2, command_enum command, int arg1);
+void clickable_set_relative(WINDOW *win, int y1, int x1, int y2, int x2, command_enum command, int arg1);
+void clickable_clear(int y1, int x1, int y2, int x2);
+struct clickable_rect* clickable_find(int y, int x);
+
+#endif
diff --git a/alsamixer/mixer_display.c b/alsamixer/mixer_display.c
index b1f79d0..2f45ab3 100644
--- a/alsamixer/mixer_display.c
+++ b/alsamixer/mixer_display.c
@@ -34,6 +34,7 @@
#include "mixer_widget.h"
#include "mixer_controls.h"
#include "mixer_display.h"
+#include "mixer_clickable.h"
enum align {
ALIGN_LEFT,
@@ -109,6 +110,7 @@ void init_mixer_layout(void)
unsigned int label_width_left, label_width_right;
unsigned int right_x, i;
+ clickable_clear(0, 0, -1, -1);
screen_too_small = screen_lines < 14 || screen_cols < 12;
has_info_items = screen_lines >= 6;
if (!has_info_items)
@@ -135,9 +137,12 @@ void init_mixer_layout(void)
display_string_in_field(1 + i, 2, labels_left[i],
label_width_left, ALIGN_RIGHT);
if (label_width_right)
- for (i = 0; i < 4; ++i)
+ for (i = 0; i < 4; ++i) {
display_string_in_field(1 + i, right_x, labels_right[i],
label_width_right, ALIGN_LEFT);
+ clickable_set(1 + i, right_x, 1 + i, right_x + label_width_right - 1,
+ CMD_MIXER_HELP + i, -1);
+ }
}
void display_card_info(void)
@@ -197,6 +202,7 @@ void display_view_mode(void)
bool has_view_mode;
int i;
+ clickable_clear(3, 0, 3, 30);
if (!has_info_items)
return;
@@ -204,10 +210,10 @@ void display_view_mode(void)
for (i = 0; i < 3; ++i)
widths[i] = get_mbs_width(modes[i]);
if (4 + widths[0] + 6 + widths[1] + 6 + widths[2] + 1 <= info_items_width) {
- wmove(mixer_widget.window, 3, info_items_left);
+ wmove(mixer_widget.window, 3, info_items_left - 1);
wattrset(mixer_widget.window, attr_mixer_text);
for (i = 0; i < 3; ++i) {
- wprintw(mixer_widget.window, "F%c:", '3' + i);
+ wprintw(mixer_widget.window, " F%c:", '3' + i);
if (has_view_mode && (int)view_mode == i) {
wattrset(mixer_widget.window, attr_mixer_active);
wprintw(mixer_widget.window, "[%s]", modes[i]);
@@ -215,8 +221,8 @@ void display_view_mode(void)
} else {
wprintw(mixer_widget.window, " %s ", modes[i]);
}
- if (i < 2)
- waddch(mixer_widget.window, ' ');
+ clickable_set_relative(mixer_widget.window, 0, -(widths[i] + 5), 0, -1,
+ CMD_WITH_ARG(CMD_MIXER_SET_VIEW_MODE, i), -1);
}
} else {
wattrset(mixer_widget.window, attr_mixer_active);
@@ -322,6 +328,7 @@ static void clear_controls_display(void)
{
int i;
+ clickable_clear(5, 0, -1, -1);
wattrset(mixer_widget.window, attr_mixer_frame);
for (i = 5; i < screen_lines - 1; ++i)
mvwprintw(mixer_widget.window, i, 1, "%*s", screen_cols - 2, "");
@@ -483,6 +490,8 @@ static void display_control(unsigned int control_index)
frame_left + c + 1, ch);
}
}
+ clickable_set(base_y - volume_height, frame_left + 1, base_y, frame_left + 2,
+ CMD_MIXER_MOUSE_CLICK_VOLUME_BAR, control_index);
if (control->flags & IS_ACTIVE)
wattrset(mixer_widget.window, attr_mixer_active);
if (!(control->flags & HAS_VOLUME_1)) {
@@ -520,6 +529,8 @@ static void display_control(unsigned int control_index)
switches[1]
? _("O")[0] | (control->flags & IS_ACTIVE ? attr_ctl_nomute : 0)
: _("M")[0] | (control->flags & IS_ACTIVE ? attr_ctl_mute : 0));
+ clickable_set(base_y + 1, frame_left + 1, base_y + 1, frame_left + 2,
+ CMD_MIXER_MOUSE_CLICK_MUTE, control_index);
}
if (control->flags & TYPE_CSWITCH) {
@@ -534,10 +545,14 @@ static void display_control(unsigned int control_index)
wattrset(mixer_widget.window, switches[0] ? attr_ctl_capture : attr_ctl_nocapture);
/* TRANSLATORS: "left"; no more than two characters */
display_string_in_field(cswitch_y - 1, frame_left - 2, switches[0] ? _("L") : "", 2, ALIGN_RIGHT);
+ clickable_set(cswitch_y - 1, frame_left - 2, cswitch_y - 1, frame_left - 1,
+ CMD_WITH_ARG(CMD_MIXER_TOGGLE_CAPTURE, LEFT), control_index);
if (control->flags & IS_ACTIVE)
wattrset(mixer_widget.window, switches[1] ? attr_ctl_capture : attr_ctl_nocapture);
/* TRANSLATORS: "right"; no more than two characters */
display_string_in_field(cswitch_y - 1, frame_left + 4, switches[1] ? _("R") : "", 2, ALIGN_LEFT);
+ clickable_set(cswitch_y - 1, frame_left + 4, cswitch_y - 1, frame_left + 5,
+ CMD_WITH_ARG(CMD_MIXER_TOGGLE_CAPTURE, RIGHT), control_index);
/* TRANSLATORS: no more than eight characters */
s = _("CAPTURE");
if (switches[0] || switches[1]) {
@@ -554,6 +569,8 @@ static void display_control(unsigned int control_index)
wattrset(mixer_widget.window, attr_ctl_nocapture);
display_string_in_field(cswitch_y, frame_left - 2, buf, 8, ALIGN_CENTER);
}
+ clickable_set(cswitch_y, frame_left - 2, cswitch_y, frame_left - 2 + 8,
+ CMD_WITH_ARG(CMD_MIXER_TOGGLE_CAPTURE, LEFT|RIGHT), control_index);
}
if (control->flags & TYPE_ENUM) {
@@ -566,6 +583,8 @@ static void display_control(unsigned int control_index)
if (control->flags & IS_ACTIVE)
wattrset(mixer_widget.window, attr_mixer_active);
display_string_centered_in_control(base_y, col, buf, control_width);
+ clickable_set_relative(mixer_widget.window, 0, -control_name_width, 0, -2,
+ CMD_MIXER_MOUSE_CLICK_CONTROL_ENUM, control_index);
}
if (control_index == focus_control_index) {
@@ -584,6 +603,8 @@ static void display_control(unsigned int control_index)
wattrset(mixer_widget.window, attr_ctl_label_inactive);
}
display_string_centered_in_control(name_y, col, control->name, control_name_width);
+ clickable_set_relative(mixer_widget.window, -1, -control_name_width, 0, -2,
+ CMD_WITH_ARG(CMD_MIXER_FOCUS_CONTROL, control_index), -1);
if (channel_name_y > name_y) {
if (control->flags & IS_MULTICH) {
switch (control->flags & MULTICH_MASK) {
@@ -630,6 +651,10 @@ static void display_scroll_indicators(void)
mvwaddch(mixer_widget.window, y, 0, left);
mvwaddch(mixer_widget.window, y, screen_cols - 1, right);
}
+ clickable_set(y0, 0, y1, 0,
+ CMD_WITH_ARG(CMD_MIXER_PREVIOUS, visible_controls), -1);
+ clickable_set(y0, screen_cols - 1, y1, screen_cols - 1,
+ CMD_WITH_ARG(CMD_MIXER_NEXT, visible_controls), -1);
}
void display_controls(void)
diff --git a/alsamixer/mixer_widget.c b/alsamixer/mixer_widget.c
index b1bd61e..160124f 100644
--- a/alsamixer/mixer_widget.c
+++ b/alsamixer/mixer_widget.c
@@ -34,6 +34,7 @@
#include "proc_files.h"
#include "card_select.h"
#include "volume_mapping.h"
+#include "mixer_clickable.h"
#include "mixer_controls.h"
#include "mixer_display.h"
#include "mixer_widget.h"
@@ -54,6 +55,9 @@ unsigned int current_control_flags;
bool control_values_changed;
bool controls_changed;
+unsigned int mouse_wheel_step = 1;
+bool mouse_wheel_focuses_control = 1;
+
static int elem_callback(snd_mixer_elem_t *elem, unsigned int mask)
{
if (mask == SND_CTL_EVENT_MASK_REMOVE) {
@@ -462,12 +466,95 @@ static void balance_volumes(void)
display_controls();
}
+static int on_mouse_key() {
+ MEVENT m;
+ command_enum cmd = 0;
+ unsigned int channels = LEFT | RIGHT;
+ unsigned int index;
+ struct control *control;
+ struct clickable_rect *rect;
+
+ if (getmouse(&m) == ERR)
+ return 0;
+
+ if (m.bstate & (
+ BUTTON1_PRESSED|BUTTON1_RELEASED|
+ BUTTON2_PRESSED|BUTTON2_RELEASED|
+ BUTTON3_PRESSED|BUTTON3_RELEASED))
+ return 0;
+
+ rect = clickable_find(m.y, m.x);
+ if (rect)
+ cmd = rect->command;
+
+#if NCURSES_MOUSE_VERSION > 1
+ if (m.bstate & (BUTTON4_CLICKED|BUTTON4_PRESSED|BUTTON5_CLICKED|BUTTON5_PRESSED)) {
+ switch (cmd) {
+ case CMD_MIXER_MOUSE_CLICK_CONTROL_ENUM:
+ focus_control_index = rect->arg1;
+ return CMD_WITH_ARG((
+ m.bstate & (BUTTON4_CLICKED|BUTTON4_PRESSED)
+ ? CMD_MIXER_CONTROL_UP
+ : CMD_MIXER_CONTROL_DOWN
+ ), 1);
+
+ case CMD_MIXER_MOUSE_CLICK_VOLUME_BAR:
+ if (mouse_wheel_focuses_control)
+ focus_control_index = rect->arg1;
+
+ default:
+ return CMD_WITH_ARG((
+ m.bstate & (BUTTON4_CLICKED|BUTTON4_PRESSED)
+ ? CMD_MIXER_CONTROL_UP
+ : CMD_MIXER_CONTROL_DOWN
+ ), mouse_wheel_step);
+ }
+ }
+#endif
+
+ /* If the rectangle has got an argument (value != -1) it is used for
+ * setting `focus_control_index` */
+ if (rect && rect->arg1 >= 0)
+ focus_control_index = rect->arg1;
+
+ switch (cmd) {
+ case CMD_MIXER_MOUSE_CLICK_VOLUME_BAR:
+ if (m.bstate & (BUTTON3_CLICKED|BUTTON3_DOUBLE_CLICKED|BUTTON3_TRIPLE_CLICKED))
+ channels = m.x - rect->x1 + 1;
+ return CMD_WITH_ARG(CMD_MIXER_CONTROL_SET_PERCENT_LEFT + channels - 1,
+ (100 * (rect->y2 - m.y) / (rect->y2 - rect->y1)) // volume
+ );
+
+ case CMD_MIXER_MOUSE_CLICK_MUTE:
+ if (m.bstate & (BUTTON3_CLICKED|BUTTON3_DOUBLE_CLICKED|BUTTON3_TRIPLE_CLICKED))
+ channels = m.x - rect->x1 + 1;
+ return CMD_WITH_ARG(CMD_MIXER_TOGGLE_MUTE, channels);
+
+ case CMD_MIXER_MOUSE_CLICK_CONTROL_ENUM:
+ control = get_focus_control(TYPE_ENUM);
+ if (control &&
+ (snd_mixer_selem_get_enum_item(control->elem, 0, &index) >= 0)) {
+ return (index == 0
+ ? CMD_WITH_ARG(CMD_MIXER_CONTROL_UP, 100)
+ : CMD_WITH_ARG(CMD_MIXER_CONTROL_DOWN, 1));
+ }
+ break;
+
+ default:
+ return cmd; // non-mouse command
+ }
+
+ return 0; // failed mouse command
+}
+
static void on_handle_key(int key)
{
int arg;
command_enum cmd;
- if (key < ARRAY_SIZE(mixer_bindings))
+ if (key == KEY_MOUSE)
+ cmd = on_mouse_key();
+ else if (key < ARRAY_SIZE(mixer_bindings))
cmd = mixer_bindings[key];
else
return;
diff --git a/alsamixer/mixer_widget.h b/alsamixer/mixer_widget.h
index 5b1cfcc..3b6f474 100644
--- a/alsamixer/mixer_widget.h
+++ b/alsamixer/mixer_widget.h
@@ -32,6 +32,9 @@ extern unsigned int current_control_flags;
extern bool control_values_changed;
extern bool controls_changed;
+extern unsigned int mouse_wheel_step;
+extern bool mouse_wheel_focuses_control;
+
void create_mixer_object(struct snd_mixer_selem_regopt *selem_regopt);
void create_mixer_widget(void);
void mixer_shutdown(void);
diff --git a/alsamixer/proc_files.c b/alsamixer/proc_files.c
index 9d3fe3f..5ae7ae9 100644
--- a/alsamixer/proc_files.c
+++ b/alsamixer/proc_files.c
@@ -28,42 +28,26 @@
#include "widget.h"
#include "textbox.h"
#include "proc_files.h"
-#include "bindings.h"
+#include "menu_widget.h"
static struct widget proc_widget;
static ITEM *items[7];
static unsigned int items_count;
static MENU *menu;
-static void on_menu_key(int key)
-{
- if (key < ARRAY_SIZE(textbox_bindings)) {
- key = textbox_bindings[key];
- if (key >= CMD_TEXTBOX___MIN_MENU_COMMAND &&
- key <= CMD_TEXTBOX___MAX_MENU_COMMAND)
- menu_driver(menu, key + KEY_MAX);
- }
-}
-
static void on_handle_key(int key)
{
ITEM *item;
- switch (key) {
- case 27:
- case KEY_CANCEL:
- proc_widget.close();
- break;
- case 10:
- case 13:
- case KEY_ENTER:
- item = current_item(menu);
- if (item)
- show_textfile(item_name(item));
- break;
- default:
- on_menu_key(key);
- break;
+ switch (menu_widget_handle_key(menu, key)) {
+ case KEY_ENTER:
+ item = current_item(menu);
+ if (item)
+ show_textfile(item_name(item));
+ break;
+ case KEY_CANCEL:
+ proc_widget.close();
+ break;
}
}