1 /* ncmpc (Ncurses MPD Client)
2  * (c) 2004-2020 The Music Player Daemon Project
3  * Project homepage: http://musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include "config.h"
21 #include "AsyncUserInput.hxx"
22 #include "Command.hxx"
23 #include "Bindings.hxx"
24 #include "GlobalBindings.hxx"
25 #include "ncmpc.hxx"
26 #include "Point.hxx"
27 #include "util/Compiler.h"
28 
29 static bool
ignore_key(int key)30 ignore_key(int key)
31 {
32 	return key == ERR || key == '\0';
33 }
34 
35 gcc_pure
36 static Command
translate_key(int key)37 translate_key(int key)
38 {
39 	return GetGlobalKeyBindings().FindKey(key);
40 }
41 
42 void
OnSocketReady(unsigned)43 AsyncUserInput::OnSocketReady(unsigned) noexcept
44 {
45 	int key = wgetch(&w);
46 	if (ignore_key(key))
47 		return;
48 
49 #ifdef HAVE_GETMOUSE
50 	if (key == KEY_MOUSE) {
51 		MEVENT event;
52 
53 		/* retrieve the mouse event from curses */
54 #ifdef PDCURSES
55 		nc_getmouse(&event);
56 #else
57 		getmouse(&event);
58 #endif
59 
60 		begin_input_event();
61 		do_mouse_event({event.x, event.y}, event.bstate);
62 		end_input_event();
63 
64 		return;
65 	}
66 #endif
67 
68 	Command cmd = translate_key(key);
69 	if (cmd == Command::NONE)
70 		return;
71 
72 	begin_input_event();
73 
74 	if (!do_input_event(socket_event.GetEventLoop(), cmd))
75 		return;
76 
77 	end_input_event();
78 	return;
79 }
80 
AsyncUserInput(EventLoop & event_loop,WINDOW & _w)81 AsyncUserInput::AsyncUserInput(EventLoop &event_loop, WINDOW &_w) noexcept
82 	:socket_event(event_loop, BIND_THIS_METHOD(OnSocketReady),
83 		      SocketDescriptor(STDIN_FILENO)),
84 	 w(_w)
85 {
86 	socket_event.ScheduleRead();
87 }
88 
89 void
keyboard_unread(EventLoop & event_loop,int key)90 keyboard_unread(EventLoop &event_loop, int key)
91 {
92 	if (ignore_key(key))
93 		return;
94 
95 	Command cmd = translate_key(key);
96 	if (cmd != Command::NONE)
97 		do_input_event(event_loop, cmd);
98 }
99