2 * Manage the lists of loaded drivers and perform actions on all drivers.
5 /* This file is part of LCDd, the lcdproc server.
7 * This file is released under the GNU General Public License. Refer to the
8 * COPYING file distributed with this package.
10 * Copyright(c) 2001, Joris Robijn
20 #include <sys/errno.h>
26 #include "shared/LL.h"
27 #include "shared/report.h"
28 #include "shared/configfile.h"
32 #include "drivers/lcd.h"
34 /* lcd.h is used for the driver API definition */
37 LinkedList
*loaded_drivers
= NULL
; /**< list of loaded drivers */
38 DisplayProps
*display_props
= NULL
; /**< properties of the display */
40 #define ForAllDrivers(drv) for (drv = LL_GetFirst(loaded_drivers); drv; drv = LL_GetNext(loaded_drivers))
44 * Load driver based on "DriverPath" config setting and section name or
45 * "File" configuration setting in the driver's section.
46 * \param name Driver section name.
48 * \retval 0 OK, driver is an input driver only.
49 * \retval 1 OK, driver is an output driver.
50 * \retval 2 OK, driver is an output driver that needs to run in the foreground.
53 drivers_load_driver(const char *name
)
60 debug(RPT_DEBUG
, "%s(name=\"%.40s\")", __FUNCTION__
, name
);
63 if (!loaded_drivers
) {
64 /* Create linked list */
65 loaded_drivers
= LL_new();
66 if (!loaded_drivers
) {
67 report(RPT_ERR
, "Error allocating driver list.");
72 /* Retrieve data from config file */
73 s
= config_get_string("server", "DriverPath", 0, "");
74 driverpath
= malloc(strlen(s
) + 1);
75 strcpy(driverpath
, s
);
77 s
= config_get_string(name
, "File", 0, NULL
);
79 filename
= malloc(strlen(driverpath
) + strlen(s
) + 1);
80 strcpy(filename
, driverpath
);
83 filename
= malloc(strlen(driverpath
) + strlen(name
) + strlen(MODULE_EXTENSION
) + 1);
84 strcpy(filename
, driverpath
);
85 strcat(filename
, name
);
86 strcat(filename
, MODULE_EXTENSION
);
90 driver
= driver_load(name
, filename
);
92 /* It failed. The message has already been given by driver_load() */
93 report(RPT_INFO
, "Module %.40s could not be loaded", filename
);
99 /* Add driver to list */
100 LL_Push(loaded_drivers
, driver
);
105 /* If first driver, store display properties */
106 if (driver_does_output(driver
) && !display_props
) {
107 if (driver
->width(driver
) <= 0 || driver
->width(driver
) > LCD_MAX_WIDTH
108 || driver
->height(driver
) <= 0 || driver
->height(driver
) > LCD_MAX_HEIGHT
) {
109 report(RPT_ERR
, "Driver [%.40s] has invalid display size", driver
->name
);
112 /* Allocate new DisplayProps structure */
113 display_props
= malloc(sizeof(DisplayProps
));
114 display_props
->width
= driver
->width(driver
);
115 display_props
->height
= driver
->height(driver
);
117 if (driver
->cellwidth
!= NULL
&& display_props
->cellwidth
> 0)
118 display_props
->cellwidth
= driver
->cellwidth(driver
);
120 display_props
->cellwidth
= LCD_DEFAULT_CELLWIDTH
;
122 if (driver
->cellheight
!= NULL
&& driver
->cellheight(driver
) > 0)
123 display_props
->cellheight
= driver
->cellheight(driver
);
125 display_props
->cellheight
= LCD_DEFAULT_CELLHEIGHT
;
128 /* Return the driver type */
129 if (driver_does_output(driver
)) {
130 if (driver_stay_in_foreground(driver
))
140 * Unload all loaded drivers.
144 drivers_unload_all(void)
148 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
150 while ((driver
= LL_Pop(loaded_drivers
)) != NULL
) {
151 driver_unload(driver
);
159 * Get information from loaded drivers.
160 * \return Pointer to information string of first driver with get_info() function defined,
161 * or the empty string if no driver has a get_info() function.
164 drivers_get_info(void)
168 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
172 return drv
->get_info(drv
);
180 * Clear screen on all loaded drivers.
181 * Call clear() function of all loaded drivers that have a clear() function defined.
188 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
198 * Flush data on all loaded drivers to LCDs.
199 * Call flush() function of all loaded drivers that have a flush() function defined.
206 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
216 * Write string to all loaded drivers.
217 * Call string() function of all loaded drivers that have a flush() function defined.
218 * \param x Horizontal character position (column).
219 * \param y Vertical character position (row).
220 * \param string String that gets written.
223 drivers_string(int x
, int y
, const char *string
)
227 debug(RPT_DEBUG
, "%s(x=%d, y=%d, string=\"%.40s\")", __FUNCTION__
, x
, y
, string
);
231 drv
->string(drv
, x
, y
, string
);
237 * Write a character to all loaded drivers.
238 * Call chr() function of all loaded drivers that have a chr() function defined.
239 * \param x Horizontal character position (column).
240 * \param y Vertical character position (row).
241 * \param c Character that gets written.
244 drivers_chr(int x
, int y
, char c
)
248 debug(RPT_DEBUG
, "%s(x=%d, y=%d, c='%c')", __FUNCTION__
, x
, y
, c
);
252 drv
->chr(drv
, x
, y
, c
);
258 * Draw a vertical bar to all drivers.
259 * For drivers that define a vbar() function, call it;
260 * otherwise call the general driver_alt_vbar() function from the server core.
261 * \param x Horizontal character position (column) of the starting point.
262 * \param y Vertical character position (row) of the starting point.
263 * \param len Number of characters that the bar is long at 100%
264 * \param promille Current length level of the bar in promille.
265 * \param pattern Options (currently unused).
268 drivers_vbar(int x
, int y
, int len
, int promille
, int pattern
)
272 debug(RPT_DEBUG
, "%s(x=%d, y=%d, len=%d, promille=%d, pattern=%d)",
273 __FUNCTION__
, x
, y
, len
, promille
, pattern
);
277 * We need more data in the widget. Requires language update...
283 drv
->vbar(drv
, x
, y
, len
, promille
, pattern
);
285 driver_alt_vbar(drv
, x
, y
, len
, promille
, pattern
);
291 * Draw a horizontal bar to all drivers.
292 * For drivers that define a hbar() function, call it;
293 * otherwise call the general driver_alt_hbar() function from the server core.
294 * \param x Horizontal character position (column) of the starting point.
295 * \param y Vertical character position (row) of the starting point.
296 * \param len Number of characters that the bar is long at 100%
297 * \param promille Current length level of the bar in promille.
298 * \param pattern Options (currently unused).
301 drivers_hbar(int x
, int y
, int len
, int promille
, int pattern
)
305 debug(RPT_DEBUG
, "%s(x=%d, y=%d, len=%d, promille=%d, pattern=%d)",
306 __FUNCTION__
, x
, y
, len
, promille
, pattern
);
310 drv
->hbar(drv
, x
, y
, len
, promille
, pattern
);
312 driver_alt_hbar(drv
, x
, y
, len
, promille
, pattern
);
318 * Write a big number to all output drivers.
319 * For drivers that define a num() function, call it;
320 * otherwise call the general driver_alt_num() function from the server core.
321 * \param x Horizontal character position (column).
322 * \param num Character to write (0 - 10 with 10 representing ':')
325 drivers_num(int x
, int num
)
329 debug(RPT_DEBUG
, "%s(x=%d, num=%d)", __FUNCTION__
, x
, num
);
333 drv
->num(drv
, x
, num
);
335 driver_alt_num(drv
, x
, num
);
341 * Perform heartbeat on all drivers.
342 * For drivers that define a heartbeat() function, call it;
343 * otherwise call the general driver_alt_heartbeat() function from the server core.
344 * \param state Heartbeat state.
347 drivers_heartbeat(int state
)
351 debug(RPT_DEBUG
, "%s(state=%d)", __FUNCTION__
, state
);
355 drv
->heartbeat(drv
, state
);
357 driver_alt_heartbeat(drv
, state
);
363 * Write icon to all drivers.
364 * For drivers that define a icon() function, call it;
365 * otherwise call the general driver_alt_icon() function from the server core.
366 * If the driver's locally defined icon() function returns -1, then also
367 * call the server core's driver_alt_icon().
368 * \param x Horizontal character position (column).
369 * \param y Vertical character position (row).
370 * \param icon synbolic value representing the icon.
373 drivers_icon(int x
, int y
, int icon
)
377 debug(RPT_DEBUG
, "%s(x=%d, y=%d, icon=ICON_%s)", __FUNCTION__
, x
, y
, widget_icon_to_iconname(icon
));
380 /* Does the driver have the icon function ? */
382 /* Try driver call */
383 if (drv
->icon(drv
, x
, y
, icon
) == -1) {
384 /* do alternative call if driver's function does not know the icon */
385 driver_alt_icon(drv
, x
, y
, icon
);
388 /* Also do alternative call if the driver does not have icon function */
389 driver_alt_icon(drv
, x
, y
, icon
);
396 * Set cursor on all loaded drivers.
397 * For drivers that define a cursor() function, call it;
398 * otherwise call the general driver_alt_cursor() function from the server core.
399 * \param x Horizontal cursor position (column).
400 * \param y Vertical cursor position (row).
401 * \param state New cursor state.
404 drivers_cursor(int x
, int y
, int state
)
408 debug(RPT_DEBUG
, "%s(x=%d, y=%d, state=%d)", __FUNCTION__
, x
, y
, state
);
412 drv
->cursor(drv
, x
, y
, state
);
414 driver_alt_cursor(drv
, x
, y
, state
);
420 * Set backlight on all drivers.
421 * Call backlight() function of all drivers that have a backlight() function defined.
422 * \param state New backlight status.
425 drivers_backlight(int state
)
429 debug(RPT_DEBUG
, "%s(state=%d)", __FUNCTION__
, state
);
433 drv
->backlight(drv
, state
);
439 * Set output on all drivers.
440 * Call ouptput() function of all drivers that have an ouptput() function defined.
441 * \param state New ouptut status.
444 drivers_output(int state
)
448 debug(RPT_DEBUG
, "%s(state=%d)", __FUNCTION__
, state
);
452 drv
->output(drv
, state
);
458 * Get key presses from loaded drivers.
459 * \return Pointer to key string for first driver ithat has a get_key() function defined
460 * and for which the get_key() function returns a key; otherwise \c NULL.
463 drivers_get_key(void)
465 /* Find the first input keystroke, if any */
467 const char *keystroke
;
469 debug(RPT_DEBUG
, "%s()", __FUNCTION__
);
473 keystroke
= drv
->get_key(drv
);
474 if (keystroke
!= NULL
) {
475 report(RPT_INFO
, "Driver [%.40s] generated keystroke %.40s", drv
->name
, keystroke
);