1 /* 2 * This file is part of g15daemon. 3 * 4 * g15daemon is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * g15daemon is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with g15daemon; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 * (c) 2006-2021 Mike Lampard, Philip Lawatsch, Daniel Menelkir and others 19 * 20 * This daemon listens on localhost port 15550 for client connections, 21 * and arbitrates LCD display. Allows for multiple simultaneous clients. 22 * Client screens can be cycled through by pressing the 'L1' key. 23 */ 24 #ifndef G15DAEMON 25 #define G15DAEMON 26 27 #ifndef BLACKnWHITE 28 #define BLACK 1 29 #define WHITE 0 30 #define BLACKnWHITE 31 #endif 32 33 #define LCD_WIDTH 160 34 #define LCD_HEIGHT 43 35 #define LCD_BUFSIZE 1048 36 37 #ifdef HAVE_CONFIG_H 38 #include <config.h> 39 #endif 40 41 #include <pthread.h> 42 #include <pwd.h> 43 #include <syslog.h> 44 45 #define CLIENT_CMD_GET_KEYSTATE 'k' 46 #define CLIENT_CMD_SWITCH_PRIORITIES 'p' 47 #define CLIENT_CMD_NEVER_SELECT 'n' 48 #define CLIENT_CMD_IS_FOREGROUND 'v' 49 #define CLIENT_CMD_IS_USER_SELECTED 'u' 50 #define CLIENT_CMD_BACKLIGHT 0x80 51 #define CLIENT_CMD_KB_BACKLIGHT 0x8 52 #define CLIENT_CMD_CONTRAST 0x40 53 #define CLIENT_CMD_MKEY_LIGHTS 0x20 54 /* if the following CMD is sent from a client, G15Daemon will not send any MR or G? keypresses via uinput, 55 * all M&G keys must be handled by the client. If the client dies or exits, normal functions resume. */ 56 #define CLIENT_CMD_KEY_HANDLER 0x10 57 58 enum { 59 /* plugin types - LCD plugins are provided with a lcd_t and keystates via EVENT when visible. 60 CORE plugins source and sink events, have no screen associated, and are not able to quit. 61 by design they implement core functionality..CORE_LIBRARY implements graphic and other 62 functions for use by other plugins. 63 */ 64 G15_PLUGIN_NONE = 0, 65 G15_PLUGIN_LCD_CLIENT =1, 66 G15_PLUGIN_CORE_KB_INPUT = 2, 67 G15_PLUGIN_CORE_OS_KB = 3, 68 G15_PLUGIN_LCD_SERVER = 4 69 }; 70 71 enum { 72 /* plugin RETURN values */ 73 G15_PLUGIN_QUIT = -1, 74 G15_PLUGIN_OK = 0 75 }; 76 77 enum { 78 /* plugin EVENT types */ 79 G15_EVENT_KEYPRESS = 1, 80 G15_EVENT_VISIBILITY_CHANGED, 81 G15_EVENT_USER_FOREGROUND, 82 G15_EVENT_MLED, 83 G15_EVENT_BACKLIGHT, 84 G15_EVENT_CONTRAST, 85 G15_EVENT_REQ_PRIORITY, 86 G15_EVENT_CYCLE_PRIORITY, 87 G15_EVENT_EXITNOW, 88 /* core event types */ 89 G15_COREVENT_KEYPRESS_IN, 90 G15_COREVENT_KEYPRESS_OUT 91 }; 92 93 enum { 94 SCR_HIDDEN = 0, 95 SCR_VISIBLE 96 }; 97 98 /* plugin global or local */ 99 enum { 100 G15_PLUGIN_NONSHARED = 0, 101 G15_PLUGIN_SHARED 102 }; 103 104 typedef struct lcd_s lcd_t; 105 typedef struct g15daemon_s g15daemon_t; 106 typedef struct lcdnode_s lcdnode_t; 107 108 typedef struct plugin_event_s plugin_event_t; 109 typedef struct plugin_info_s plugin_info_t; 110 typedef struct plugin_s plugin_t; 111 112 typedef struct config_items_s config_items_t; 113 typedef struct config_section_s config_section_t; 114 typedef struct configfile_s configfile_t; 115 116 typedef struct config_items_s { 117 config_items_t *next; 118 config_items_t *prev; 119 config_items_t *head; 120 char *key; 121 char *value; 122 } 123 config_items_s; 124 125 typedef struct config_section_s { 126 config_section_t *head; 127 config_section_t *next; 128 char *sectionname; 129 config_items_t *items; 130 } 131 config_section_s; 132 133 typedef struct configfile_s { 134 config_section_t *sections; 135 } 136 configfile_s; 137 138 typedef struct plugin_info_s { 139 /* type - see above for valid defines*/ 140 int type; 141 /* short name of the plugin - used only for logging at the moment */ 142 char *name; 143 /* run thread - will be called every update_msecs milliseconds*/ 144 int *(*plugin_run) (void *); 145 unsigned int update_msecs; 146 /* plugin process to be called on close or NULL if there isnt one*/ 147 void *(*plugin_exit) (void *); 148 /* plugin process to be called on EVENT (such as keypress)*/ 149 int *(*event_handler) (void *); 150 /* init func if there is one else NULL*/ 151 int *(*plugin_init) (void *); 152 char *filename; 153 } 154 plugin_info_s; 155 156 typedef struct plugin_s { 157 g15daemon_t *masterlist; 158 unsigned int type; 159 plugin_info_t *info; 160 void *plugin_handle; 161 void *args; 162 } 163 plugin_s; 164 165 typedef struct lcd_s { 166 g15daemon_t *masterlist; 167 int lcd_type; 168 unsigned char buf[LCD_BUFSIZE]; 169 int max_x; 170 int max_y; 171 int connection; 172 unsigned int backlight_state; 173 unsigned int mkey_state; 174 unsigned int contrast_state; 175 unsigned int state_changed; 176 /* set to 1 if user manually selected this screen 0 otherwise */ 177 unsigned int usr_foreground; 178 /* set to 1 if screen is never to be user-selectable */ 179 unsigned int never_select; 180 /* only used for plugins */ 181 plugin_t *g15plugin; 182 } 183 lcd_s; 184 185 typedef struct plugin_event_s { 186 unsigned int event; 187 unsigned long value; 188 lcd_t *lcd; 189 } 190 plugin_event_s; 191 192 struct lcdnode_s { 193 g15daemon_t *list; 194 lcdnode_t *prev; 195 lcdnode_t *next; 196 lcdnode_t *last_priority; 197 lcd_t *lcd; 198 } 199 static lcdnode_s; 200 201 struct g15daemon_s { 202 lcdnode_t *head; 203 lcdnode_t *tail; 204 lcdnode_t *current; 205 void *(*keyboard_handler)(void*); 206 struct passwd *nobody; 207 volatile unsigned long numclients; 208 configfile_t *config; 209 unsigned int kb_backlight_state; // master state 210 unsigned int remote_keyhandler_sock; 211 } 212 static g15daemon_s; 213 214 static pthread_mutex_t lcdlist_mutex; 215 static pthread_mutex_t g15lib_mutex; 216 217 /* server hello */ 218 #define SERV_HELO "G15 daemon HELLO" 219 220 #ifdef G15DAEMON_BUILD 221 /* internal g15daemon-only functions */ 222 void g15daemon_init_refresh(); 223 void g15daemon_quit_refresh(); 224 int uf_write_buf_to_g15(lcd_t *lcd); 225 /* write a pbm format file 'filename' with image contained in 'buf' */ 226 int uf_screendump_pbm(unsigned char *buf,char *filename); 227 int uf_read_keypresses(unsigned int *keypresses, unsigned int timeout); 228 /* return the pid of a running copy of g15daemon, else -1 */ 229 int uf_return_running(); 230 /* create a /var/run/g15daemon.pid file, returning 0 on success else -1 */ 231 int uf_create_pidfile(); 232 /* open & run all plugins in the given directory */ 233 int g15_open_all_plugins(g15daemon_t *masterlist, char *plugin_directory); 234 /* linked lists */ 235 g15daemon_t *ll_lcdlist_init(); 236 void ll_lcdlist_destroy(g15daemon_t **masterlist); 237 /* open and parse config file */ 238 int uf_conf_open(g15daemon_t *list, char *filename); 239 /* write the config file with all keys/sections */ 240 int uf_conf_write(g15daemon_t *list,char *filename); 241 /* free all memory used by the config subsystem */ 242 void uf_conf_free(g15daemon_t *list); 243 /* search the list for valid key called "key" in section named "section" return pointer to item or NULL */ 244 config_items_t* uf_search_confitem(config_section_t *section, char *key); 245 /* generic handler for net clients */ 246 int internal_generic_eventhandler(plugin_event_t *myevent); 247 #endif 248 249 /* the following functions are available for use by plugins */ 250 /* send notification of LCD buffer update */ 251 void g15daemon_send_refresh(lcd_t *lcd); 252 /* wait on notification of LCD buffer update */ 253 void g15daemon_wait_refresh(); 254 /* create a new section */ 255 config_section_t *g15daemon_cfg_load_section(g15daemon_t *masterlist,char *name); 256 /* return string value from key in sectionname */ 257 char* g15daemon_cfg_read_string(config_section_t *section, char *key, char *defaultval); 258 /* return float from key in sectionname */ 259 double g15daemon_cfg_read_float(config_section_t *section, char *key, double defaultval); 260 /* return int from key in sectionname */ 261 int g15daemon_cfg_read_int(config_section_t *section, char *key, int defaultval); 262 /* return bool as int from key in sectionname */ 263 int g15daemon_cfg_read_bool(config_section_t *section, char *key, int defaultval); 264 /* add a new key, or update the value of an already existing key, or return -1 if section doesnt exist */ 265 int g15daemon_cfg_write_string(config_section_t *section, char *key, char *val); 266 int g15daemon_cfg_write_float(config_section_t *section, char *key, double val); 267 int g15daemon_cfg_write_int(config_section_t *section, char *key, int val); 268 /* simply write value as On or Off depending on whether val>0 */ 269 int g15daemon_cfg_write_bool(config_section_t *section, char *key, unsigned int val); 270 /* remoe a key/value pair from named section */ 271 int g15daemon_cfg_remove_key(config_section_t *section, char *key); 272 /* send event to foreground client's eventlistener */ 273 int g15daemon_send_event(void *caller, unsigned int event, unsigned long value); 274 /* open named plugin */ 275 void * g15daemon_dlopen_plugin(char *name,unsigned int library); 276 /* close plugin with handle <handle> */ 277 int g15daemon_dlclose_plugin(void *handle) ; 278 /* syslog wrapper */ 279 int g15daemon_log (int priority, const char *fmt, ...); 280 /* cycle from displayed screen to next on list */ 281 void g15daemon_lcdnode_cycle(g15daemon_t *masterlist); 282 /* add new screen */ 283 lcdnode_t *g15daemon_lcdnode_add(g15daemon_t **masterlist) ; 284 /* remove screen */ 285 void g15daemon_lcdnode_remove (lcdnode_t *oldnode); 286 /* handy function from xine_utils.c */ 287 void *g15daemon_xmalloc(size_t size) ; 288 /* threadsafe sleep */ 289 void g15daemon_sleep(int seconds); 290 /* threadsafe millisecond sleep */ 291 int g15daemon_msleep(int milliseconds) ; 292 /* return current time in milliseconds */ 293 unsigned int g15daemon_gettime_ms(); 294 /* convert 1byte/pixel buffer to internal g15 format */ 295 void g15daemon_convert_buf(lcd_t *lcd, unsigned char * orig_buf); 296 #endif 297