xaizek / pms (License: GPLv3+) (since 2018-12-07)
Older version of Practical Music Search written in C++.
Commit 86c4c604589bbe3e5f2cbb19e0a96a6a4cb6a29f

Start prototyping the input system.
Author: Kim Tore Jensen
Author date (UTC): 2014-09-28 07:31
Committer name: Kim Tore Jensen
Committer date (UTC): 2014-09-28 07:31
Parent(s): c3505168b035febef0dd7df86a3e71f888abe460
Signing key:
Tree: 71c6b8a663596c5ba4ec20b2871acaf0306eeb1b
File Lines added Lines deleted
src/Makefile.am 1 1
src/curses.c 2 18
src/curses.h 2 0
src/input.c 124 0
src/input.h 29 4
src/pms.c 20 8
src/pms.h 1 0
File src/Makefile.am changed (mode: 100644) (index 03d0121..9a8c846)
1 1 bin_PROGRAMS = pms bin_PROGRAMS = pms
2 pms_SOURCES = pms.c curses.c console.c window.c topbar.c
2 pms_SOURCES = pms.c curses.c console.c window.c topbar.c input.c
3 3 pms_CC = @PTHREAD_CC@ pms_CC = @PTHREAD_CC@
4 4 pms_CFLAGS = @PTHREAD_CFLAGS@ pms_CFLAGS = @PTHREAD_CFLAGS@
5 5 pms_LDADD = @PTHREAD_LIBS@ @CURSES_LIB@ @libmpdclient_LIBS@ pms_LDADD = @PTHREAD_LIBS@ @CURSES_LIB@ @libmpdclient_LIBS@
File src/curses.c changed (mode: 100644) (index b2c5437..98e8c51)
... ... void curses_shutdown() {
79 79 endwin(); endwin();
80 80 } }
81 81
82 static void curses_handle_input(int ch) {
83 if (ch == 'q') {
84 shutdown();
85 } else if (ch == KEY_UP) {
86 console_scroll(-1);
87 } else if (ch == KEY_DOWN) {
88 console_scroll(1);
89 } else if (ch == '.') {
90 console(".");
91 }
92 }
93
94 void curses_get_input() {
95 int ch;
96 ch = wgetch(window_statusbar);
97 if (ch != ERR) {
98 curses_handle_input(ch);
99 }
82 int curses_get_input() {
83 return wgetch(window_statusbar);
100 84 } }
101 85
102 86 void pms_curses_lock() { void pms_curses_lock() {
File src/curses.h changed (mode: 100644) (index 35c69a9..9cdaec7)
... ... void curses_shutdown();
38 38 void curses_init_windows(); void curses_init_windows();
39 39 void curses_destroy_windows(); void curses_destroy_windows();
40 40
41 int curses_get_input();
42
41 43 void pms_curses_lock(); void pms_curses_lock();
42 44 void pms_curses_unlock(); void pms_curses_unlock();
File src/input.c added (mode: 100644) (index 0000000..13f48ba)
1 /* vi:set ts=4 sts=4 sw=4 noet:
2 *
3 * Practical Music Search
4 * Copyright (c) 2006-2014 Kim Tore Jensen
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "pms.h"
21 #include <string.h>
22
23 static command_t command;
24
25 static int input_char_get_int(int ch) {
26 if (ch >= 48 && ch <= 57) {
27 return ch-48;
28 } else {
29 return -1;
30 }
31 }
32
33 static int input_char_get_movement(int ch) {
34 if (ch == KEY_UP || ch == 'k') {
35 return INPUT_MOVEMENT_UP;
36 } else if (ch == KEY_DOWN || ch == 'j') {
37 return INPUT_MOVEMENT_DOWN;
38 }
39 return INPUT_MOVEMENT_NONE;
40 }
41
42 static int input_char_get_action(int ch) {
43 if (ch == KEY_UP || ch == 'k') {
44 return INPUT_ACTION_GO;
45 } else if (ch == KEY_DOWN || ch == 'j') {
46 return INPUT_ACTION_GO;
47 } else if (ch == 'q') {
48 return INPUT_ACTION_QUIT;
49 } else if (ch == 'g') {
50 return INPUT_ACTION_GO;
51 }
52 return INPUT_ACTION_NONE;
53 }
54
55 static int input_command_append_multiplier(int multiplier) {
56 multiplier = (command.multiplier*10)+multiplier;
57 if (multiplier > command.multiplier) {
58 command.multiplier = multiplier;
59 console("InputMultiplier set to %d", command.multiplier);
60 }
61 return command.multiplier;
62 }
63
64 static void input_command_append_movement(int movement) {
65 command.movement = movement;
66 console("InputMovement set to %d", command.movement);
67 }
68
69 static void input_command_append_action(int action) {
70 command.action = action;
71 console("InputAction set to %d", command.action);
72 if (command.action != INPUT_ACTION_GO) {
73 input_command_append_movement(INPUT_MOVEMENT_NA);
74 }
75 }
76
77 static int input_ready() {
78 return (command.movement != 0 && command.action != 0);
79 }
80
81 void input_reset() {
82 memset(&command, 0, sizeof(command));
83 }
84
85 command_t * input_get() {
86 int ch;
87 int i;
88 if ((ch = curses_get_input()) == ERR) {
89 return;
90 }
91 if ((i = input_char_get_int(ch)) != -1) {
92 input_command_append_multiplier(i);
93 }
94 if ((i = input_char_get_movement(ch)) != INPUT_MOVEMENT_NONE) {
95 input_command_append_movement(i);
96 }
97 if ((i = input_char_get_action(ch)) != INPUT_ACTION_NONE) {
98 input_command_append_action(i);
99 }
100 if (input_ready()) {
101 if (command.multiplier == 0) {
102 command.multiplier = 1;
103 }
104 return &command;
105 }
106 return NULL;
107 }
108
109 int input_handle(command_t * command) {
110 console("input_handle(): multiplier=%d, movement=%d, action=%d", command->multiplier, command->movement, command->action);
111 if (command->action == INPUT_ACTION_QUIT) {
112 shutdown();
113 return 0;
114 } else if (command->action == INPUT_ACTION_GO) {
115 if (command->movement == INPUT_MOVEMENT_UP) {
116 console_scroll(-command->multiplier);
117 } else if (command->movement == INPUT_MOVEMENT_DOWN) {
118 console_scroll(command->multiplier);
119 }
120 } else {
121 return 0;
122 }
123 return 1;
124 }
File src/input.h copied from file src/topbar.h (similarity 59%) (mode: 100644) (index 798c435..cbd3212)
17 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18 */ */
19 19
20 #include <mpd/client.h>
20 #define INPUT_MOVEMENT_NA -1
21 #define INPUT_MOVEMENT_NONE 0
22 #define INPUT_MOVEMENT_UP 1
23 #define INPUT_MOVEMENT_DOWN 2
21 24
22 void topbar_draw();
23 const char * topbar_mode_str();
24 const char * topbar_playing_str();
25 #define INPUT_ACTION_NONE 0
26 #define INPUT_ACTION_QUIT 1
27 #define INPUT_ACTION_GO 2
28
29 typedef struct {
30 int multiplier;
31 int movement;
32 int action;
33
34 } command_t;
35
36 /*
37 * Reset input command state to default values.
38 */
39 void input_reset();
40
41 /*
42 * Retrieve input
43 */
44 command_t * input_get();
45
46 /*
47 * Perform an action based on a struct command_t.
48 */
49 int input_handle(command_t * command);
File src/pms.c changed (mode: 100644) (index cfe0d4b..c4c93bd)
24 24 #include <signal.h> #include <signal.h>
25 25 #include <sys/select.h> #include <sys/select.h>
26 26 #include <unistd.h> #include <unistd.h>
27 #include <errno.h>
27 28 #include "pms.h" #include "pms.h"
28 29
29 30 struct options_t * options = NULL; struct options_t * options = NULL;
 
... ... void reset_options() {
44 45
45 46 options->server = "localhost"; options->server = "localhost";
46 47 options->port = 0; options->port = 0;
47 options->timeout = 200;
48 options->timeout = 2000;
48 49 options->console_size = 1024; options->console_size = 1024;
49 50
50 51 } }
 
... ... static void signal_init() {
156 157 signal(SIGTERM, signal_kill); signal(SIGTERM, signal_kill);
157 158 } }
158 159
159 int get_input(struct mpd_connection * connection) {
160 int pms_get_pending_input_flags(struct mpd_connection * connection) {
160 161 struct timeval tv; struct timeval tv;
161 int mpd_fd;
162 int mpd_fd = 0;
162 163 int retval; int retval;
163 164 int flags = 0; int flags = 0;
164 165 fd_set fds; fd_set fds;
165 166
166 167 tv.tv_sec = 1; tv.tv_sec = 1;
167 168 tv.tv_usec = 0; tv.tv_usec = 0;
168 mpd_fd = mpd_connection_get_fd(connection);
169
170 if (connection) {
171 mpd_fd = mpd_connection_get_fd(connection);
172 }
169 173
170 174 FD_ZERO(&fds); FD_ZERO(&fds);
171 175 FD_SET(STDIN_FILENO, &fds); FD_SET(STDIN_FILENO, &fds);
 
... ... int get_input(struct mpd_connection * connection) {
174 178 retval = select(mpd_fd+1, &fds, NULL, NULL, &tv); retval = select(mpd_fd+1, &fds, NULL, NULL, &tv);
175 179
176 180 if (retval == -1) { if (retval == -1) {
177 // FIXME
181 console("Error %d in select(): %s", errno, strerror(errno));
182
178 183 } else if (retval > 0) { } else if (retval > 0) {
179 if (FD_ISSET(mpd_fd, &fds)) {
184 if (mpd_fd != 0 && FD_ISSET(mpd_fd, &fds)) {
180 185 flags |= PMS_HAS_INPUT_MPD; flags |= PMS_HAS_INPUT_MPD;
181 186 } }
182 187 if (FD_ISSET(STDIN_FILENO, &fds)) { if (FD_ISSET(STDIN_FILENO, &fds)) {
 
... ... int get_input(struct mpd_connection * connection) {
189 194
190 195 int main(int argc, char** argv) { int main(int argc, char** argv) {
191 196
197 command_t * command = NULL;
192 198 struct mpd_connection * connection = NULL; struct mpd_connection * connection = NULL;
193 199 bool is_idle = false; bool is_idle = false;
194 200 enum mpd_idle flags = -1; enum mpd_idle flags = -1;
 
... ... int main(int argc, char** argv) {
202 208 curses_init(); curses_init();
203 209 console_init(options->console_size); console_init(options->console_size);
204 210 signal_init(); signal_init();
211 input_reset();
205 212 console("%s %s (c) 2006-2014 Kim Tore Jensen <%s>", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_BUGREPORT); console("%s %s (c) 2006-2014 Kim Tore Jensen <%s>", PACKAGE_NAME, PACKAGE_VERSION, PACKAGE_BUGREPORT);
206 213
207 214 while(pms_state->running) { while(pms_state->running) {
 
... ... int main(int argc, char** argv) {
217 224 is_idle = true; is_idle = true;
218 225 } }
219 226
220 input_flags = get_input(connection);
227 input_flags = pms_get_pending_input_flags(connection);
221 228
222 229 if (input_flags & PMS_HAS_INPUT_MPD) { if (input_flags & PMS_HAS_INPUT_MPD) {
223 230 flags = mpd_recv_idle(connection, true); flags = mpd_recv_idle(connection, true);
 
... ... int main(int argc, char** argv) {
226 233 } }
227 234
228 235 if (input_flags & PMS_HAS_INPUT_STDIN) { if (input_flags & PMS_HAS_INPUT_STDIN) {
229 curses_get_input();
236 if ((command = input_get()) != NULL) {
237 while(command->multiplier > 0 && input_handle(command)) {
238 --command->multiplier;
239 }
240 input_reset();
241 }
230 242 } }
231 243
232 244 } }
File src/pms.h changed (mode: 100644) (index 7bd5503..abfde64)
31 31 #include "window.h" #include "window.h"
32 32 #include "console.h" #include "console.h"
33 33 #include "topbar.h" #include "topbar.h"
34 #include "input.h"
34 35
35 36 #define PMS_EXIT_SUCCESS 0 #define PMS_EXIT_SUCCESS 0
36 37 #define PMS_EXIT_MEMORY 1 #define PMS_EXIT_MEMORY 1
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/pms

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/pms

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master