3 * This file is part of LCDd, the lcdproc server.
5 * This file is released under the GNU General Public License. Refer to the
6 * COPYING file distributed with this package.
8 * Copyright (c) 1999, William Ferrell, Scott Scriven
12 * Handles keypad (and other?) input from the user.
21 #include "shared/sockets.h"
22 #include "shared/report.h"
23 #include "shared/configfile.h"
28 #include "screenlist.h"
29 #include "menuscreens.h"
32 #include "render.h" /* For server_msg* */
36 char *toggle_rotate_key
;
37 char *prev_screen_key
;
38 char *next_screen_key
;
40 char *scroll_down_key
;
43 int server_input(int key
);
44 void input_send_to_client(Client
*c
, const char *key
);
45 void input_internal_key(const char *key
);
50 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
54 /* Get rotate/scroll keys from config file */
55 toggle_rotate_key
= strdup(config_get_string("server", "ToggleRotateKey", 0, "Enter"));
56 prev_screen_key
= strdup(config_get_string("server", "PrevScreenKey", 0, "Left"));
57 next_screen_key
= strdup(config_get_string("server", "NextScreenKey", 0, "Right"));
58 scroll_up_key
= strdup(config_get_string("server", "ScrollUpKey", 0, "Up"));
59 scroll_down_key
= strdup(config_get_string("server", "ScrollDownKey", 0, "Down"));
68 /* Program shutdown before completed startup */
74 free(toggle_rotate_key
);
75 free(prev_screen_key
);
76 free(next_screen_key
);
78 free(scroll_down_key
);
88 Screen
*current_screen
;
89 Client
*current_client
;
93 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
95 current_screen
= screenlist_current();
97 current_client
= current_screen
->client
;
99 current_client
= NULL
;
101 /* Handle all keypresses */
102 while ((key
= drivers_get_key()) != NULL
) {
104 /* Find what client wants the key */
105 kr
= input_find_key(key
, current_client
);
108 report(RPT_DEBUG
, "%s: reserved key: \"%.40s\"", __FUNCTION__
, key
);
111 report(RPT_DEBUG
, "%s: left over key: \"%.40s\"", __FUNCTION__
, key
);
112 /*target = current_client;*/
113 target
= NULL
; /* left-over keys are always for internal client */
115 if (target
== NULL
) {
116 report(RPT_DEBUG
, "%s: key is for internal client", __FUNCTION__
);
117 input_internal_key(key
);
119 /* It's an external client */
120 report(RPT_DEBUG
, "%s: key is for external client on socket %d", __FUNCTION__
, target
->sock
);
121 input_send_to_client(target
, key
);
128 void input_send_to_client(Client
*c
, const char *key
)
131 size_t size
= strlen(key
) + sizeof("key %s\n"); // this is large enough
133 debug(RPT_DEBUG
, "%s(client=[%d], key=\"%.40s\")", __FUNCTION__
, c
->sock
, key
);
135 /* Allocate just as much as we need */
138 snprintf(s
, size
, "key %s\n", key
);
139 sock_send_string(c
->sock
, s
);
143 report(RPT_ERR
, "%s: malloc failure", __FUNCTION__
);
148 input_internal_key(const char *key
)
150 if (is_menu_key(key
) || screenlist_current() == menuscreen
) {
151 menuscreen_key_handler(key
);
154 /* Keys are for scrolling or rotating */
155 if (strcmp(key
,toggle_rotate_key
) == 0) {
156 autorotate
= !autorotate
;
158 server_msg("Rotate", 4);
160 server_msg("Hold", 4);
163 else if (strcmp(key
,prev_screen_key
) == 0) {
164 screenlist_goto_prev();
165 server_msg("Prev", 4);
167 else if (strcmp(key
,next_screen_key
) == 0) {
168 screenlist_goto_next();
169 server_msg("Next", 4);
171 else if (strcmp(key
,scroll_up_key
) == 0) {
173 else if (strcmp(key
,scroll_down_key
) == 0) {
178 int input_reserve_key(const char *key
, bool exclusive
, Client
*client
)
182 debug(RPT_DEBUG
, "%s(key=\"%.40s\", exclusive=%d, client=[%d])", __FUNCTION__
, key
, exclusive
, (client
?client
->sock
:-1));
184 /* Find out if this key is already reserved in a way that interferes
185 * with the new reservation.
187 for (kr
= LL_GetFirst(keylist
); kr
; kr
= LL_GetNext(keylist
)) {
188 if (strcmp(kr
->key
, key
) == 0) {
189 if (kr
->exclusive
|| exclusive
) {
196 /* We can now safely add it ! */
197 kr
= malloc(sizeof(KeyReservation
));
198 kr
->key
= strdup(key
);
199 kr
->exclusive
= exclusive
;
201 LL_Push(keylist
, kr
);
203 report(RPT_INFO
, "Key \"%.40s\" is now reserved in %s mode by client [%d]", key
, (exclusive
?"exclusive":"shared"), (client
?client
->sock
:-1));
208 void input_release_key(const char *key
, Client
*client
)
212 debug(RPT_DEBUG
, "%s(key=\"%.40s\", client=[%d])", __FUNCTION__
, key
, (client
?client
->sock
:-1));
214 for (kr
= LL_GetFirst(keylist
); kr
; kr
= LL_GetNext(keylist
)) {
215 if (kr
->client
== client
216 && strcmp(kr
->key
, key
) == 0) {
219 LL_DeleteNode(keylist
);
220 report(RPT_INFO
, "Key \"%.40s\" was reserved in %s mode by client [%d] and is now released", key
, (kr
->exclusive
?"exclusive":"shared"), (client
?client
->sock
:-1));
226 void input_release_client_keys(Client
*client
)
230 debug(RPT_DEBUG
, "%s(client=[%d])", __FUNCTION__
, (client
?client
->sock
:-1));
232 kr
=LL_GetFirst(keylist
);
234 if (kr
->client
== client
) {
235 report(RPT_INFO
, "Key \"%.40s\" was reserved in %s mode by client [%d] and is now released", kr
->key
, (kr
->exclusive
?"exclusive":"shared"), (client
?client
->sock
:-1));
238 LL_DeleteNode(keylist
);
239 kr
= LL_Get(keylist
);
241 kr
= LL_GetNext(keylist
);
246 KeyReservation
*input_find_key(const char *key
, Client
*client
)
250 debug(RPT_DEBUG
, "%s(key=\"%.40s\", client=[%d])", __FUNCTION__
, key
, (client
?client
->sock
:-1));
252 for (kr
= LL_GetFirst(keylist
); kr
; kr
= LL_GetNext(keylist
)) {
253 if (strcmp(kr
->key
, key
) == 0) {
254 if (kr
->exclusive
|| client
==kr
->client
) {