1999-12-09 23:15:14 +00:00
/*
2001-12-27 23:30:36 +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-02-27 21:20:20 +00:00
* 2003, Joris Robijn
2001-12-27 23:30:36 +00:00
*
*
* Handles keypad (and other?) input from the user.
*/
1999-12-09 23:15:14 +00:00
2001-09-21 21:08:10 +00:00
1999-12-09 23:15:14 +00:00
#include <stdlib.h>
#include <stdio.h>
2001-04-27 02:20:38 +00:00
#include <string.h>
1999-12-09 23:15:14 +00:00
2001-05-25 03:14:27 +00:00
#include "shared/sockets.h"
2001-11-29 14:09:13 +00:00
#include "shared/report.h"
2003-02-28 15:19:58 +00:00
#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
2002-04-26 00:00:31 +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"
2003-02-28 15:19:58 +00:00
#include "render.h" /* For server_msg* */
1999-12-09 23:15:14 +00:00
2003-02-27 21:20:20 +00:00
LinkedList * keylist ;
2003-02-28 15:19:58 +00:00
char * toggle_rotate_key ;
char * prev_screen_key ;
char * next_screen_key ;
char * scroll_up_key ;
char * scroll_down_key ;
2003-02-27 21:20:20 +00:00
/* Local functions */
2000-03-30 20:20:41 +00:00
int server_input ( int key );
2006-04-06 13:25:14 +00:00
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
2002-08-04 20:58:51 +00:00
int input_init ()
1999-12-09 23:15:14 +00:00
{
2002-07-14 20:30:33 +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
2003-02-28 15:19:58 +00:00
/* Get rotate/scroll keys from config file */
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
}
2003-02-27 21:20:20 +00:00
2002-08-04 20:58:51 +00:00
int input_shutdown ()
{
if ( ! keylist ) {
/* Program shutdown before completed startup */
return - 1 ;
}
free ( keylist );
2003-02-28 15:19:58 +00:00
free ( toggle_rotate_key );
free ( prev_screen_key );
free ( next_screen_key );
free ( scroll_up_key );
free ( scroll_down_key );
2002-08-04 20:58:51 +00:00
return 0 ;
}
2003-02-27 21:20:20 +00:00
2002-05-26 19:21:23 +00:00
int
handle_input ()
{
2006-04-06 13:25:14 +00:00
const char * key ;
2002-08-04 20:58:51 +00:00
Screen * current_screen ;
2002-07-14 20:30:33 +00:00
Client * current_client ;
Client * target ;
2002-05-26 19:21:23 +00:00
KeyReservation * kr ;
2002-07-14 20:30:33 +00:00
debug ( RPT_DEBUG , "%s()" , __FUNCTION__ );
2002-05-26 19:21:23 +00:00
2002-08-04 20:58:51 +00:00
current_screen = screenlist_current ();
if ( current_screen )
current_client = current_screen -> client ;
else
current_client = NULL ;
2002-05-26 19:21:23 +00:00
/* Handle all keypresses */
while (( key = drivers_get_key ()) != NULL ) {
/* Find what client wants the key */
2002-07-14 20:30:33 +00:00
kr = input_find_key ( key , current_client );
2002-05-26 19:21:23 +00:00
if ( kr ) {
/* A hit ! */
2002-07-14 20:30:33 +00:00
report ( RPT_DEBUG , "%s: reserved key: \" %.40s \" " , __FUNCTION__ , key );
target = kr -> client ;
} else {
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
}
2002-07-14 20:30:33 +00:00
if ( target == NULL ) {
report ( RPT_DEBUG , "%s: key is for internal client" , __FUNCTION__ );
input_internal_key ( key );
} else {
/* It's an external client */
report ( RPT_DEBUG , "%s: key is for external client on socket %d" , __FUNCTION__ , target -> sock );
2003-02-27 21:20:20 +00:00
input_send_to_client ( target , key );
2002-05-26 19:21:23 +00:00
}
}
return 0 ;
}
2003-02-27 21:20:20 +00:00
2006-04-06 13:25:14 +00:00
void input_send_to_client ( Client * c , const char * key )
2002-05-26 19:21:23 +00:00
{
char * s ;
2002-07-14 20:30:33 +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 */
s = malloc ( strlen ( key ) + strlen ( "key \n " ) + 1 );
sprintf ( s , "key %s \n " , key );
sock_send_string ( c -> sock , s );
free ( s );
}
2003-02-27 21:20:20 +00:00
2002-05-26 19:21:23 +00:00
void
2006-04-06 13:25:14 +00:00
input_internal_key ( const char * key )
2002-05-26 19:21:23 +00:00
{
2003-02-27 21:20:20 +00:00
if ( is_menu_key ( key ) || screenlist_current () == menuscreen ) {
menuscreen_key_handler ( key );
2002-05-26 19:21:23 +00:00
}
else {
2003-02-27 21:20:20 +00:00
/* Keys are for scrolling or rotating */
if ( strcmp ( key , toggle_rotate_key ) == 0 ) {
autorotate = ! autorotate ;
2003-02-28 15:19:58 +00:00
if ( autorotate ) {
server_msg ( "Rotate" , 4 );
} else {
server_msg ( "Hold" , 4 );
}
2003-02-27 21:20:20 +00:00
}
else if ( strcmp ( key , prev_screen_key ) == 0 ) {
screenlist_goto_prev ();
2003-02-28 15:19:58 +00:00
server_msg ( "Prev" , 4 );
2003-02-27 21:20:20 +00:00
}
else if ( strcmp ( key , next_screen_key ) == 0 ) {
screenlist_goto_next ();
2003-02-28 15:19:58 +00:00
server_msg ( "Next" , 4 );
2003-02-27 21:20:20 +00:00
}
else if ( strcmp ( key , scroll_up_key ) == 0 ) {
}
else if ( strcmp ( key , scroll_down_key ) == 0 ) {
}
2002-05-26 19:21:23 +00:00
}
}
2006-04-06 13:25:14 +00:00
int input_reserve_key ( const char * key , bool exclusive , Client * client )
2002-05-26 19:21:23 +00:00
{
KeyReservation * kr ;
2002-07-14 20:30:33 +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.
*/
for ( kr = LL_GetFirst ( keylist ); kr ; kr = LL_GetNext ( keylist )) {
if ( strcmp ( kr -> key , key ) == 0 ) {
if ( kr -> exclusive || exclusive ) {
/* Sorry ! */
return - 1 ;
}
}
}
/* We can now safely add it ! */
kr = malloc ( sizeof ( KeyReservation ));
kr -> key = strdup ( key );
kr -> exclusive = exclusive ;
kr -> client = client ;
LL_Push ( keylist , kr );
2002-07-14 20:30:33 +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 ;
}
2006-04-06 13:25:14 +00:00
void input_release_key ( const char * key , Client * client )
2002-05-26 19:21:23 +00:00
{
KeyReservation * kr ;
2002-07-14 20:30:33 +00:00
debug ( RPT_DEBUG , "%s( key= \" %.40s \" , client=[%d] )" , __FUNCTION__ , key , ( client ? client -> sock : - 1 ));
2002-05-26 19:21:23 +00:00
for ( kr = LL_GetFirst ( keylist ); kr ; kr = LL_GetNext ( keylist )) {
if ( kr -> client == client
&& strcmp ( kr -> key , key ) == 0 ) {
free ( kr -> key );
free ( kr );
LL_DeleteNode ( keylist );
2002-07-14 20:30:33 +00:00
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 ;
}
}
}
void input_release_client_keys ( Client * client )
{
KeyReservation * kr ;
2002-07-14 20:30:33 +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 ) {
2002-07-14 20:30:33 +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 ));
2002-05-26 19:21:23 +00:00
free ( kr -> key );
free ( kr );
LL_DeleteNode ( keylist );
kr = LL_Get ( keylist );
} else {
kr = LL_GetNext ( keylist );
}
}
}
2006-04-06 13:25:14 +00:00
KeyReservation * input_find_key ( const char * key , Client * client )
2002-05-26 19:21:23 +00:00
{
KeyReservation * kr ;
2002-07-14 20:30:33 +00:00
debug ( RPT_DEBUG , "%s( key= \" %.40s \" , client=[%d] )" , __FUNCTION__ , key , ( client ? client -> sock : - 1 ));
2002-05-26 19:21:23 +00:00
for ( kr = LL_GetFirst ( keylist ); kr ; kr = LL_GetNext ( keylist )) {
if ( strcmp ( kr -> key , key ) == 0 ) {
if ( kr -> exclusive || client == kr -> client ) {
return kr ;
}
}
}
return NULL ;
}