Files
lcdproc/server/input.c
T

261 lines
6.1 KiB
C
Raw Normal View History

1999-12-09 23:15:14 +00:00
/*
* input.c
* This file is part of LCDd, the lcdproc server.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 1999, William Ferrell, Scott Scriven
* 2003, Joris Robijn
*
*
* Handles keypad (and other?) input from the user.
*/
1999-12-09 23:15:14 +00:00
1999-12-09 23:15:14 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
1999-12-09 23:15:14 +00:00
#include "shared/sockets.h"
2001-11-29 14:09:13 +00:00
#include "shared/report.h"
#include "shared/configfile.h"
1999-12-09 23:15:14 +00:00
2001-12-30 00:15:25 +00:00
#include "drivers.h"
1999-12-09 23:15:14 +00:00
#include "client.h"
1999-12-09 23:15:14 +00:00
#include "screenlist.h"
2002-05-26 19:21:23 +00:00
#include "menuscreens.h"
1999-12-09 23:15:14 +00:00
#include "input.h"
#include "render.h" /* For server_msg* */
1999-12-09 23:15:14 +00:00
2007-04-02 21:29:53 +00:00
LinkedList *keylist;
char *toggle_rotate_key;
char *prev_screen_key;
char *next_screen_key;
char *scroll_up_key;
char *scroll_down_key;
/* Local functions */
2007-04-02 21:29:53 +00:00
int server_input(int key);
void input_send_to_client(Client *c, const char *key);
void input_internal_key(const char *key);
1999-12-09 23:15:14 +00:00
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
int input_init(void)
1999-12-09 23:15:14 +00:00
{
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s()", __FUNCTION__);
1999-12-09 23:15:14 +00:00
2002-05-26 19:21:23 +00:00
keylist = LL_new();
1999-12-09 23:15:14 +00:00
/* Get rotate/scroll keys from config file */
2007-04-02 21:29:53 +00:00
toggle_rotate_key = strdup(config_get_string("server", "ToggleRotateKey", 0, "Enter"));
prev_screen_key = strdup(config_get_string("server", "PrevScreenKey", 0, "Left"));
next_screen_key = strdup(config_get_string("server", "NextScreenKey", 0, "Right"));
scroll_up_key = strdup(config_get_string("server", "ScrollUpKey", 0, "Up"));
scroll_down_key = strdup(config_get_string("server", "ScrollDownKey", 0, "Down"));
2000-04-03 22:13:57 +00:00
return 0;
1999-12-09 23:15:14 +00:00
}
int input_shutdown()
{
if (!keylist) {
/* Program shutdown before completed startup */
return -1;
}
2007-04-02 21:29:53 +00:00
free(keylist);
2007-04-02 21:29:53 +00:00
free(toggle_rotate_key);
free(prev_screen_key);
free(next_screen_key);
free(scroll_up_key);
free(scroll_down_key);
return 0;
}
2002-05-26 19:21:23 +00:00
int
2007-04-02 21:29:53 +00:00
handle_input(void)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
const char *key;
Screen *current_screen;
Client *current_client;
Client *target;
KeyReservation *kr;
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s()", __FUNCTION__);
2002-05-26 19:21:23 +00:00
current_screen = screenlist_current();
2007-04-02 21:29:53 +00:00
if (current_screen)
current_client = current_screen->client;
else
current_client = NULL;
2002-05-26 19:21:23 +00:00
/* Handle all keypresses */
2007-04-02 21:29:53 +00:00
while ((key = drivers_get_key()) != NULL) {
2002-05-26 19:21:23 +00:00
/* Find what client wants the key */
2007-04-02 21:29:53 +00:00
kr = input_find_key(key, current_client);
2002-05-26 19:21:23 +00:00
if (kr) {
/* A hit ! */
2007-04-02 21:29:53 +00:00
report(RPT_DEBUG, "%s: reserved key: \"%.40s\"", __FUNCTION__, key);
target = kr->client;
} else {
2007-04-02 21:29:53 +00:00
report(RPT_DEBUG, "%s: left over key: \"%.40s\"", __FUNCTION__, key);
/*target = current_client;*/
target = NULL; /* left-over keys are always for internal client */
2002-05-26 19:21:23 +00:00
}
if (target == NULL) {
2007-04-02 21:29:53 +00:00
report(RPT_DEBUG, "%s: key is for internal client", __FUNCTION__);
input_internal_key(key);
} else {
/* It's an external client */
2007-04-02 21:29:53 +00:00
report(RPT_DEBUG, "%s: key is for external client on socket %d", __FUNCTION__, target->sock);
input_send_to_client(target, key);
2002-05-26 19:21:23 +00:00
}
}
return 0;
}
2007-04-02 21:29:53 +00:00
void input_send_to_client(Client *c, const char *key)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
char *s;
2006-04-14 08:04:09 +00:00
size_t size = strlen(key) + sizeof("key %s\n"); // this is large enough
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s(client=[%d], key=\"%.40s\")", __FUNCTION__, c->sock, key);
2002-05-26 19:21:23 +00:00
/* Allocate just as much as we need */
2007-04-02 21:29:53 +00:00
s = calloc(1, size);
2006-04-14 08:04:09 +00:00
if (s != NULL) {
snprintf(s, size, "key %s\n", key);
sock_send_string(c->sock, s);
2007-04-02 21:29:53 +00:00
free(s);
2006-04-14 08:04:09 +00:00
}
else
report(RPT_ERR, "%s: malloc failure", __FUNCTION__);
2002-05-26 19:21:23 +00:00
}
2002-05-26 19:21:23 +00:00
void
2007-04-02 21:29:53 +00:00
input_internal_key(const char *key)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
if (is_menu_key(key) || screenlist_current() == menuscreen) {
menuscreen_key_handler(key);
2002-05-26 19:21:23 +00:00
}
else {
/* Keys are for scrolling or rotating */
2007-04-02 21:29:53 +00:00
if (strcmp(key,toggle_rotate_key) == 0) {
autorotate = !autorotate;
2007-04-02 21:29:53 +00:00
if (autorotate) {
server_msg("Rotate", 4);
} else {
2007-04-02 21:29:53 +00:00
server_msg("Hold", 4);
}
}
2007-04-02 21:29:53 +00:00
else if (strcmp(key,prev_screen_key) == 0) {
screenlist_goto_prev();
server_msg("Prev", 4);
}
2007-04-02 21:29:53 +00:00
else if (strcmp(key,next_screen_key) == 0) {
screenlist_goto_next();
server_msg("Next", 4);
}
2007-04-02 21:29:53 +00:00
else if (strcmp(key,scroll_up_key) == 0) {
}
2007-04-02 21:29:53 +00:00
else if (strcmp(key,scroll_down_key) == 0) {
}
2002-05-26 19:21:23 +00:00
}
}
2007-04-02 21:29:53 +00:00
int input_reserve_key(const char *key, bool exclusive, Client *client)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
KeyReservation *kr;
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s(key=\"%.40s\", exclusive=%d, client=[%d])", __FUNCTION__, key, exclusive, (client?client->sock:-1));
2002-05-26 19:21:23 +00:00
/* Find out if this key is already reserved in a way that interferes
* with the new reservation.
*/
2007-04-02 21:29:53 +00:00
for (kr = LL_GetFirst(keylist); kr; kr = LL_GetNext(keylist)) {
if (strcmp(kr->key, key) == 0) {
2002-05-26 19:21:23 +00:00
if (kr->exclusive || exclusive) {
/* Sorry ! */
return -1;
}
}
}
/* We can now safely add it ! */
2007-04-02 21:29:53 +00:00
kr = malloc(sizeof(KeyReservation));
kr->key = strdup(key);
2002-05-26 19:21:23 +00:00
kr->exclusive = exclusive;
kr->client = client;
LL_Push(keylist, kr);
2007-04-02 21:29:53 +00:00
report(RPT_INFO, "Key \"%.40s\" is now reserved in %s mode by client [%d]", key, (exclusive?"exclusive":"shared"), (client?client->sock:-1));
2002-05-26 19:21:23 +00:00
return 0;
}
2007-04-02 21:29:53 +00:00
void input_release_key(const char *key, Client *client)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
KeyReservation *kr;
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s(key=\"%.40s\", client=[%d])", __FUNCTION__, key, (client?client->sock:-1));
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
for (kr = LL_GetFirst(keylist); kr; kr = LL_GetNext(keylist)) {
2002-05-26 19:21:23 +00:00
if (kr->client == client
2007-04-02 21:29:53 +00:00
&& strcmp(kr->key, key) == 0) {
free(kr->key);
free(kr);
LL_DeleteNode(keylist);
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));
2002-05-26 19:21:23 +00:00
return;
}
}
}
2007-04-02 21:29:53 +00:00
void input_release_client_keys(Client *client)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
KeyReservation *kr;
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s(client=[%d])", __FUNCTION__, (client?client->sock:-1));
2002-05-26 19:21:23 +00:00
kr=LL_GetFirst(keylist);
while (kr) {
if (kr->client == client) {
2007-04-02 21:29:53 +00:00
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));
free(kr->key);
free(kr);
LL_DeleteNode(keylist);
kr = LL_Get(keylist);
2002-05-26 19:21:23 +00:00
} else {
kr = LL_GetNext(keylist);
}
}
}
2007-04-02 21:29:53 +00:00
KeyReservation *input_find_key(const char *key, Client *client)
2002-05-26 19:21:23 +00:00
{
2007-04-02 21:29:53 +00:00
KeyReservation *kr;
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
debug(RPT_DEBUG, "%s(key=\"%.40s\", client=[%d])", __FUNCTION__, key, (client?client->sock:-1));
2002-05-26 19:21:23 +00:00
2007-04-02 21:29:53 +00:00
for (kr = LL_GetFirst(keylist); kr; kr = LL_GetNext(keylist)) {
if (strcmp(kr->key, key) == 0) {
2002-05-26 19:21:23 +00:00
if (kr->exclusive || client==kr->client) {
return kr;
}
}
}
return NULL;
}