42
21
#include "shared/sockets.h"
43
22
#include "shared/report.h"
45
#include "drivers/lcd.h"
47
#include "client_data.h"
23
#include "shared/configfile.h"
51
28
#include "screenlist.h"
29
#include "menuscreens.h"
56
#define KeyWanted(a,b) ((a) && strchr((a), (b)))
57
#define CurrentScreen screenlist_current
58
#define FirstClient(a) (client *)LL_GetFirst(a);
59
#define NextClient(a) (client *)LL_GetNext(a);
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;
61
43
int server_input (int key);
63
/* FIXME! The server tends to crash when "E" is pressed.. (?!)
64
* (but only when the joystick driver is the last one on the list...)
67
/* Checks for keypad input, and dispatches it*/
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);
77
if ((key = lcd_ptr->getkey ()) == 0)
80
/*debug (RPT_DEBUG, "handle_input(%c)", (char) key);*/
83
* Does the current screen want the key?
84
* IfTrue: handle and quit
86
* Let ALL clients handle it if they want
87
* Let Server handle it, too
89
* This leads to a unique situation:
90
* First: multiple clients may handle the same key in multiple ways
91
* Second: the server may handle the key differently yet
93
* Solution: Only the current screen can handle the key press.
94
* Alternately, only one client can handle the key press.
97
/* TODO: Interpret and translate keys!*/
99
/* Give current screen a shot at the key first*/
100
s = CurrentScreen ();
102
if (KeyWanted(s->keys, key)) {
103
/* This screen wants this key. Tell it we got one*/
104
snprintf(str, sizeof(str), "key %c\n", key);
105
sock_send_string(s->parent->sock, str);
106
/* Nobody else gets this key*/
109
/* if the current screen doesn't want it,
110
* let the server have it...
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 */
136
s = calloc (1, size);
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);
114
/* Give key to clients who want it*/
116
c = FirstClient(clients);
119
/* If the client should have this keypress...*/
120
if(KeyWanted(c->data->client_keys,key)) {
121
/* Send keypress to client*/
122
snprintf(str, sizeof(str), "key %c\n", key);
123
sock_send_string(c->sock, str);
124
break; /* first come, first serve*/
126
c = NextClient(clients);
129
/* Give server a shot at all keys*/
137
server_input (int key)
139
debug (RPT_INFO, "server_input(%c)", (char) key);
140
report(RPT_INFO, "key %d pressed on device", key);
142
switch ((char) key) {
143
case INPUT_PAUSE_KEY:
144
if (screenlist_action == SCR_HOLD)
145
screenlist_action = 0;
147
screenlist_action = SCR_HOLD;
150
screenlist_action = SCR_BACK;
153
case INPUT_FORWARD_KEY:
154
screenlist_action = SCR_SKIP;
157
case INPUT_MAIN_MENU_KEY:
158
debug (RPT_DEBUG, "got the menu key!");
162
debug (RPT_DEBUG, "server_input: Unused key \"%c\" (%i)", (char) key, 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) {