1 <chapter id="driver-api">
2 <title>The LCDproc driver API</title>
5 This chapter describes the driver API of v0.5 of LCDproc.
6 At time of this writing, this version is not released and some things might
11 The API consists of several functions to tell the driver that
12 certains actions should be performed, some data, and several functions
13 to retrieve configuration data from the server.
16 <sect1 id="api-overview">
17 <title>OVERVIEW OF OPERATION</title>
20 The API is best descibed by starting with the struct lcd_logical_driver
21 which is defined in server/drivers/lcd.h.
25 The use of the API has changed from v0.4 to v0.5. The default functions that
26 the server put in the pointers in v0.4 do no longer exist. Instead empty
27 functions are the default. If a driver implements a function, the function
28 will be detected by the server. The driver should at least implement all
29 basic functions like driver_chr and driver_str itself, and should also have
30 defined a number of other symbols for the server.
34 I will walk through the driver struct here.
39 typedef struct lcd_logical_driver {
41 //////// Variables to be provided by the driver module
42 // The driver loader will look for symbols with these names !
44 // pointer to a string describing the API version
47 // Does this driver require to be in foreground ?
48 int *stay_in_foreground;// Does this driver require to be in foreground ?
50 / Does this driver support multiple instances ?
51 int *supports_multiple;
53 // What should alternatively be prepended to the function names ?
57 The programmer should define the following symbols:
58 char * api_version = API_VERSION; // <-- this symbol is defined by make
59 int stay_in_foreground = 0; // This driver does not need to be in foreground
60 int supports_multiple = 0; // This driver does not c$support multiple instances
61 char *symbol_prefix = "MyDriver_"; // Driver functions start with MyDriver_
62 And fill these values with the correct values. Upon loading the driver module,
63 the server will locate these symbols and store pointers to them in the
66 Because the drivers are loadable, some kind of version checking should be
67 done. Therefor the server expects the correct version number to be found in
68 the api_version symbol (a string). For the v0.5 version this should be "0.5".
69 If the version is incompatible, the driver will not be loaded. The current
70 API version can always be determined by inserting the compiler define
71 API_VERSION in the code.
74 //////// Functions to be provided by the driver module
76 //// Mandatory functions (necessary for all drivers)
78 // initialize driver: returns >= 0 on success
79 int (*init) (Driver *drvthis);
82 void (*close) (Driver *drvthis);
85 //// Essential output functions (necessary for output drivers)
87 // get display width / height (in characters; 1-based)
88 int (*width) (Driver *drvthis);
89 int (*height) (Driver *drvthis);
92 void (*clear) (Driver *drvthis);
94 // flush screen contents to LCD
95 void (*flush) (Driver *drvthis);
97 // write string s at position (x,y)
98 void (*string) (Driver *drvthis, int x, int y, char *str);
100 // write char c at position (x,y)
101 void (*chr) (Driver *drvthis, int x, int y, char c);
104 //// essential input functions (necessary for input drivers)
106 // get key from driver: returns a string denoting the key pressed
107 const char *(*get_key) (Driver *drvthis);
110 //// Extended output functions (optional; core provides alternatives)
112 // draw a bar from pos (x,y) upward / to the right filling promille of len chars
113 void (*vbar) (Driver *drvthis, int x, int y, int len, int promille, int options);
114 void (*hbar) (Driver *drvthis, int x, int y, int len, int promille, int options);
116 // display (big) number num at horizontal position x
117 void (*num) (Driver *drvthis, int x, int num);
119 // set heartbeat state; animate heartbeat
120 void (*heartbeat) (Driver *drvthis, int state);
122 // draw named icon at position (x,y)
123 void (*icon) (Driver *drvthis, int x, int y, int icon);
125 // set cursor type and move it to position (x,y)
126 void (*cursor) (Driver *drvthis, int x, int y, int type);
129 //// User-defined character functions
131 // set special character / get free characters
132 // - It is currently unclear how this system should work exactly
133 // - The set_char function expects a simple block of data with 1 byte for each pixel-line.
134 // (So that is 8 bytes for a 5x8 char)
135 void (*set_char) (Driver *drvthis, char ch, unsigned char *dat);
136 int (*get_free_chars) (Driver *drvthis);
138 // get width / height of a character cell (in pixels)
139 // - necessary to provide info about cell size to clients
140 // - if not defined, the core will provide alternatives returning default values
141 int (*cellwidth) (Driver *drvthis);
142 int (*cellheight) (Driver *drvthis);
145 //// Hardware functions
147 // get / set the display's contrast
148 int (*get_contrast) (Driver *drvthis);
149 int (*set_contrast) (Driver *drvthis, int promille);
151 // get / set brightness for given backlight state
152 int (*get_brightness) (Driver *drvthis, int state);
153 int (*set_brightness) (Driver *drvthis, int state, int promille);
155 // set backlight state
156 void (*backlight) (Driver *drvthis, int state);
159 void (*output) (Driver *drvthis, int state);
162 //// Informational functions
163 // get a string describing the driver and it's features
164 const char * (*get_info) (Driver *drvthis);
168 //////// Variables in server core, available for drivers
170 // name of the driver instance (name of the config file section)
171 // - do not change from the driver; consider it read-only
172 // - to be used to access the driver's own section in the config file
175 // pointer to the driver instance's private data
176 // - filled by the server by calling store_private_ptr()
177 // - the driver should cast this to it's own private structure pointer
181 //////// Functions in server core, available for drivers
183 // store a pointer to the driver instance's private data
184 int (*store_private_ptr) (struct lcd_logical_driver * driver, void * private_data);
186 // Config file functions, cwprovided by the server
187 // - see configfile.h on how to use these functions
188 // - as sectionname, always use the driver name: drvthis->name
189 char (*config_get_bool) (char * sectionname, char * keyname,
190 int skip, char default_value);
191 int (*config_get_int) (char * sectionname, char * keyname,
192 int skip, int default_value);
193 double (*config_get_float) (char * sectionname, char * keyname,
194 int skip, double default_value);
195 char *(*config_get_string) (char * sectionname, char * keyname,
196 int skip, char * default_value);
197 // Returns a string in server memory space.
199 int config_has_section (char *sectionname);
200 int config_has_key (char *sectionname, char *keyname);
202 // error reporting function
203 // - see drivers/report.h for details
204 void (*report) ( const int level, const char *format, .../*args*/ );
206 // Display properties functions (for drivers that adapt to other loaded drivers)
207 // - the return the size of another already loaded driver
208 // - if no driver is loaded yet, the return values will be 0
209 int (*get_display_width) ();
210 int (*get_display_height) ();
217 <sect1 id="private-data">
218 <title>PRIVATE DATA</title>
221 With the introduction of loadable modules it is necesary to stop using global
222 variables to store a driver's data in. Instead, you should store it in a
223 structure, that you allocate abd store on driver's init. If you don't use
224 this system, but use globals, you get queer results if you run two LCDd
225 daemons on one machine. They will then use the same variables !
229 In the driver's private structure will probably at least be something like:
233 typedef struct my_driver_private {
234 int fd; // file descriptor for the LCD device
235 int width, height; // dimension of the LCD (in characters, 1-based
236 int cellwidth, cellheight; // Size of each LCD cell, in pixels
237 unsigned char *framebuf; // Frame buffer...
242 You allocate and store this structure like this:
248 // Allocate and store private data
249 p = (PrivateData *) malloc(sizeof(PrivateData));
252 if (drvthis->store_private_ptr( drvthis, p ) < 0)
255 // initialize private data
260 (... continue with the rest of your init routine)
264 You retrieve this private data pointer by adding the following code to the
265 beginning of your functions:
269 PrivateData *p = (PrivateData *) drvthis->private_data;
273 Then you can access your data like:
281 <sect1 id="function-details">
282 <title>FUNCTIONS IN DETAIL</title>
286 <funcdef>int <function>(*init)</function></funcdef>
287 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
292 It starts up the LCD, initializes all variables, allocates private data space
293 and stores the pointer by calling store_private_ptr();
298 <funcdef>void <function>(*close)</function></funcdef>
299 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
303 Shut down the connection with the LCD.
304 Called just before unloading the driver.
309 <funcdef>int <function>(*width)</function></funcdef>
310 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
314 Get the screen width in characters.
315 The result is 1-based.
320 <funcdef>int <function>(*height)</function></funcdef>
321 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
325 Get the screen height in character lines.
326 The result is 1-based.
331 <funcdef>void <function>(*clear)</function></funcdef>
332 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
336 Clear the framebuffer.
341 <funcdef>void <function>(*flush)</function></funcdef>
342 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
346 Flush the framebuffer to the LCD.
351 <funcdef>void <function>(*string)</function></funcdef>
352 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
353 <paramdef>int <parameter>x</parameter></paramdef>
354 <paramdef>int <parameter>y</parameter></paramdef>
355 <paramdef>char *<parameter>str</parameter></paramdef>
359 Place string <replaceable>str</replaceable> into position
360 (<replaceable>x</replaceable>,<replaceable>y</replaceable>) in the framebuffer.
361 All coordinates are 1-based, i.e. (1,1) is top left.
362 The driver should check for overflows, i.e. that the positional parameters
363 are within the screen's boundaries and cut off the part of the string
364 that is out of bounds.
369 <funcdef>void <function>(*chr)</function></funcdef>
370 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
371 <paramdef>int <parameter>x</parameter></paramdef>
372 <paramdef>int <parameter>y</parameter></paramdef>
373 <paramdef>char <parameter>c</parameter></paramdef>
377 Place a single character <replaceable>c</replaceable> into position
378 (<replaceable>x</replaceable>,<replaceable>y</replaceable>) in the framebuffer.
379 The driver should check for overflows, i.e. that the positional parameters
380 are within the screen's boundaries and ignore the request if
381 the character is out of bounds.
386 <funcdef>void <function>(*vbar)</function></funcdef>
387 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
388 <paramdef>int <parameter>x</parameter></paramdef>
389 <paramdef>int <parameter>y</parameter></paramdef>
390 <paramdef>int <parameter>len</parameter></paramdef>
391 <paramdef>int <parameter>promille</parameter></paramdef>
392 <paramdef>int <parameter>options</parameter></paramdef>
396 Draw a vertical bar at position (<replaceable>x</replaceable>,<replaceable>y</replaceable>)
397 that has maximal length <replaceable>len</replaceable>, where a fraction of
398 (<replaceable>promille</replaceable> / 1000) is filled.
403 <funcdef>void <function>(*hbar)</function></funcdef>
404 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
405 <paramdef>int <parameter>x</parameter></paramdef>
406 <paramdef>int <parameter>y</parameter></paramdef>
407 <paramdef>int <parameter>len</parameter></paramdef>
408 <paramdef>int <parameter>promille</parameter></paramdef>
409 <paramdef>int <parameter>options</parameter></paramdef>
413 Draw a horizontal bar at position (<replaceable>x</replaceable>,<replaceable>y</replaceable>)
414 that has maximal length <replaceable>len</replaceable>, where a fraction of
415 (<replaceable>promille</replaceable> / 1000) is filled.
420 <funcdef>void <function>(*num)</function></funcdef>
421 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
422 <paramdef>int <parameter>x</parameter></paramdef>
423 <paramdef>int <parameter>num</parameter></paramdef>
427 Display big number <replaceable>num</replaceable> at horizontal position <replaceable>x</replaceable>.
432 <funcdef>void <function>(*heartbeat)</function></funcdef>
433 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
434 <paramdef>int <parameter>state</parameter></paramdef>
438 Sets the heartbeat to the indicated state: 0=off 1=graph1 2=graph2
439 HEARTBEAT_ON to say that we want to display/refresh the heartbeat.
440 The driver choose how to do it. See MtxOrb.c
445 <funcdef>void <function>(*icon)</function></funcdef>
446 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
447 <paramdef>int <parameter>x</parameter></paramdef>
448 <paramdef>int <parameter>y</parameter></paramdef>
449 <paramdef>int <parameter>icon</parameter></paramdef>
453 Draw named icon <replaceable>icon</replaceable> at position
454 (<replaceable>x</replaceable>,<replaceable>y</replaceable>).
459 <funcdef>void <function>(*cursor)</function></funcdef>
460 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
461 <paramdef>int <parameter>x</parameter></paramdef>
462 <paramdef>int <parameter>y</parameter></paramdef>
463 <paramdef>int <parameter>type</parameter></paramdef>
467 Move cursor to position (<replaceable>x</replaceable>,<replaceable>y</replaceable>),
468 setting its type to <replaceable>type</replaceable>.
473 <funcdef>void <function>(*set_char)</function></funcdef>
474 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
475 <paramdef>char <parameter>ch</parameter></paramdef>
476 <paramdef>unsigned char *<parameter>dat</parameter></paramdef>
480 The set_char function expects a simple block of data with 1 byte for each pixel-line.
481 (So that is 8 bytes for a 5x8 char)
486 <funcdef>int <function>(*get_free_chars)</function></funcdef>
487 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
495 <funcdef>int <function>(*cellwidth)</function></funcdef>
496 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
500 Return the width of a character cell in pixels.
501 The result is 1-based.
506 <funcdef>int <function>(*cellheight)</function></funcdef>
507 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
511 Return the height of a character cell in pixels.
512 The result is 1-based.
517 <funcdef>int <function>(*get_contrast)</function></funcdef>
518 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
522 Get the contrast value from the driver.
523 The return value is an integer in the range from 0 to 1000.
524 Many displays do not support getting or setting contrast using software.
529 <funcdef>int <function>(*set_contrast)</function></funcdef>
530 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
531 <paramdef>int <parameter>promille</parameter></paramdef>
535 Sets the contrast to the given value, which is an integer in the range from 0 to 1000.
536 It is up to the driver to map the logical interval [0, 1000] into the
537 interval that the hardware supports.
538 Many displays do not support software setting of contrast.
543 <funcdef>int <function>(*get_brightness)</function></funcdef>
544 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
545 <paramdef>int <parameter>state</parameter></paramdef>
549 Get the brightness value from the driver for the given backlight state.
550 The parameter <parameter>state</parameter> determnies which one
552 The return value is an integer in the range from 0 to 1000.
553 Many displays do not support getting or setting brightness using software.
558 <funcdef>int <function>(*set_brightness)</function></funcdef>
559 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
560 <paramdef>int <parameter>state</parameter></paramdef>
561 <paramdef>int <parameter>promille</parameter></paramdef>
565 Set the brightness for the given backlight state to the value given.
566 Value must be an integer in the range from 0 to 1000.
567 It is up to the driver to map the logical interval [0, 1000] into the
568 interval that the hardware supports.
569 Many displays do not support software setting of brightness.
574 <funcdef>void <function>(*backlight)</function></funcdef>
575 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
576 <paramdef>int <parameter>state</parameter></paramdef>
580 Sets the backlight to the given brightness state.
581 Often hardware can only support two values for the backlight:
583 In that case any value of state > 0 will switch the backlight on.
588 <funcdef>void <function>(*output)</function></funcdef>
589 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
590 <paramdef>int <parameter>state</parameter></paramdef>
594 Sets the output value. Some displays/wirings have a general purpose
595 output, which can be controlled by calling this function. See the
596 'output' command in the 'widget language'.
601 <funcdef>const char *<function>(*get_key)</function></funcdef>
602 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
606 Checks if a key has been pressed on the device.
607 Returns NULL for "no key pressed", or a string describing the pressd key.
608 These characters should match the keypad-layout.
613 <funcdef>const char *<function>(*get_info)</function></funcdef>
614 <paramdef>Driver *<parameter>drvthis</parameter></paramdef>
618 Returns a string describing the driver and its features.
623 <funcdef>char <function>(*config_get_bool)</function></funcdef>
624 <paramdef>char *<parameter>sectionname</parameter></paramdef>
625 <paramdef>char *<parameter>keyname</parameter></paramdef>
626 <paramdef>int <parameter>skip</parameter></paramdef>
627 <paramdef>char <parameter>default_value</parameter></paramdef>
631 Call to server. Retrieve a bool from the config file.
632 Sectionname should be the name of the driver (as in the struct).
633 If the key cannot be found, the default value will be returned.
634 skip should be 0 usually, but if you want to retrieve multiple
635 identical keys, then increase skip to get every next value.
640 <funcdef>int <function>(*config_get_int)</function></funcdef>
641 <paramdef>char *<parameter>sectionname</parameter></paramdef>
642 <paramdef>char *<parameter>keyname</parameter></paramdef>
643 <paramdef>int <parameter>skip</parameter></paramdef>
644 <paramdef>int <parameter>default_value</parameter></paramdef>
648 Call to server. Retrieve an integer from the config file.
653 <funcdef>double <function>(*config_get_float)</function></funcdef>
654 <paramdef>char *<parameter>sectionname</parameter></paramdef>
655 <paramdef>char *<parameter>keyname</parameter></paramdef>
656 <paramdef>int <parameter>skip</parameter></paramdef>
657 <paramdef>double <parameter>default_value</parameter></paramdef>
661 Call to server. Retrieve a float from the config file.
666 <funcdef>char *<function>(*config_get_string)</function></funcdef>
667 <paramdef>char *<parameter>sectionname</parameter></paramdef>
668 <paramdef>char *<parameter>keyname</parameter></paramdef>
669 <paramdef>int <parameter>skip</parameter></paramdef>
670 <paramdef>char *<parameter>default</parameter></paramdef>
674 Call to server. Retrieve a string from the config file.
675 Fill result with a pointer to some available space. You can fill it
676 with a default value. If the key is found, it will be overwritten
677 with the value from the key.
678 Note that you should always first copy the the returned string.
679 It is in the address space of the server, and will be freed at the
685 <funcdef>int <function>config_has_section</function></funcdef>
686 <paramdef>char *<parameter>sectionname</parameter></paramdef>
690 Returns wether a section exists. Does not need to be called prior
691 to a call to a config_get_* function.
696 <funcdef>int <function>config_has_key</function></funcdef>
697 <paramdef>char *<parameter>sectionname</parameter></paramdef>
698 <paramdef>char *<parameter>keyname</parameter></paramdef>
702 Returns the number of times a key exists. Does not need to be called
703 prior to a call to a config_get_* function.
708 First version, Joris Robijn, 20011016