File: driver-api.docbook

package info (click to toggle)
lcdproc 0.5.9-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,088 kB
  • sloc: ansic: 59,645; sh: 1,740; perl: 681; makefile: 417
file content (703 lines) | stat: -rw-r--r-- 22,441 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
<chapter id="driver-api">
  <title>The LCDproc driver API</title>

<para>
  This chapter describes the driver API of v0.5 of LCDproc.
</para>

<sect1 id="api-overview">
  <title>Overview of Operation</title>

<para>
  The API defines functions which drivers may implement to provide certain
  services. If a driver implements a function, the function will be detected by
  the server. For some optional functions the server core provides default
  implementations.
</para>

<para>
  The API consists of functions to:
</para>
<itemizedlist>
  <listitem>
    <para>print data to the display,</para>
  </listitem>
  <listitem>
    <para>set display properties (backlight, brightness, contrast, extra LEDs),</para>
  </listitem>
  <listitem>
    <para>read input from an input device (may be the display), and</para>
  </listitem>
  <listitem>
    <para>inform the server of the driver/display capabilities.</para>
  </listitem>
</itemizedlist>

<para>
  The API is best described by starting with the struct lcd_logical_driver
  which is defined in server/drivers/lcd.h.
</para>

<para>
  Below is a commented version of lcd_logical_driver. Each function is
  described more detailed in <xref linkend="function-details"/>.
</para>

<screen>

typedef struct lcd_logical_driver {

	//////// Variables to be provided by the driver module
	// The driver loader will look for symbols with these names !

	// pointer to a string describing the API version
	char *api_version;

	// Does this driver require to be in foreground ?
	int *stay_in_foreground;

	/ Does this driver support multiple instances ?
	int *supports_multiple;

	// What should alternatively be prepended to the function names ?
	char **symbol_prefix;

	//////// Functions to be provided by the driver module

	//// Mandatory functions (necessary for all drivers)

	// initialize driver: returns &gt;= 0 on success
	int (*init)		(Driver *drvthis);

	// close driver
	void (*close)		(Driver *drvthis);


	//// Essential output functions (necessary for output drivers)

	// get display width / height (in characters; 1-based)
	int (*width)		(Driver *drvthis);
	int (*height)		(Driver *drvthis);

	// clear screen
	void (*clear)		(Driver *drvthis);

	// flush screen contents to LCD
	void (*flush)		(Driver *drvthis);

	// write string s at position (x,y)
	void (*string)		(Driver *drvthis, int x, int y, const char *str);

	// write char c at position (x,y)
	void (*chr)		(Driver *drvthis, int x, int y, char c);


	//// essential input functions (necessary for input drivers)

	// get key from driver: returns a string denoting the key pressed
	const char *(*get_key)	(Driver *drvthis);


	//// Extended output functions (optional; core provides alternatives)

	// draw a bar from pos (x,y) upward / to the right filling promille of len chars
	void (*vbar)		(Driver *drvthis, int x, int y, int len, int promille, int options);
	void (*hbar)		(Driver *drvthis, int x, int y, int len, int promille, int options);

	// display (big) number num at horizontal position x
	void (*num)		(Driver *drvthis, int x, int num);

	// set heartbeat state; animate heartbeat
	void (*heartbeat)	(Driver *drvthis, int state);

	// draw named icon at position (x,y)
	int (*icon)		(Driver *drvthis, int x, int y, int icon);

	// set cursor type and move it to position (x,y)
	void (*cursor)		(Driver *drvthis, int x, int y, int type);


	//// User-defined character functions

	// set special character / get free characters
	// - It is currently unclear how this system should work exactly
	// - The set_char function expects a simple block of data with 1 byte for each pixel-line.
	//   (So that is 8 bytes for a 5x8 char)
	void (*set_char)	(Driver *drvthis, int n, unsigned char *dat);
	int (*get_free_chars)	(Driver *drvthis);

	// get width / height of a character cell (in pixels)
	// - necessary to provide info about cell size to clients
	// - if not defined, the core will provide alternatives returning default values
	int (*cellwidth)	(Driver *drvthis);
	int (*cellheight)	(Driver *drvthis);


	//// Hardware functions

	// get / set the display's contrast
	int (*get_contrast)	(Driver *drvthis);
	void (*set_contrast)	(Driver *drvthis, int promille);

	// get / set brightness for given backlight state
	int (*get_brightness)	(Driver *drvthis, int state);
	void (*set_brightness)	(Driver *drvthis, int state, int promille);

	// set backlight state
	void (*backlight)	(Driver *drvthis, int state);

	// set output
	void (*output)		(Driver *drvthis, int state);


	//// Informational functions
	// get a string describing the driver and it's features
	const char * (*get_info) (Driver *drvthis);



	//////// Variables in server core, available for drivers

	// name of the driver instance (name of the config file section)
	// - do not change from the driver; consider it read-only
	// - to be used to access the driver's own section in the config file
	char * name;

	// pointer to the driver instance's private data
	// - filled by the server by calling store_private_ptr()
	// - the driver should cast this to it's own private structure pointer
	void * private_data;


	//////// Functions in server core, available for drivers

	// store a pointer to the driver instance's private data
	int (*store_private_ptr) (struct lcd_logical_driver * driver, void * private_data);

	// Config file functions, cwprovided by the server
	// - see configfile.h on how to use these functions
	// - as sectionname, always use the driver name: drvthis->name
	short (*config_get_bool) (char * sectionname, char * keyname,
				int skip, short default_value);
	long int (*config_get_int) (char * sectionname, char * keyname,
				int skip, long int default_value);
	double (*config_get_float) (char * sectionname, char * keyname,
				int skip, double default_value);
	const char *(*config_get_string) (char * sectionname, char * keyname,
				int skip, const char * default_value);
				// Returns a string in server memory space.
				// Copy this string.
	int config_has_section	(const char *sectionname);
	int config_has_key	(const char *sectionname, const char *keyname);

	// Display properties functions (for drivers that adapt to other loaded drivers)
	// - the return the size of another already loaded driver
	// - if no driver is loaded yet, the return values will be 0
	int (*get_display_width) ();
	int (*get_display_height) ();
} Driver;

</screen>

</sect1>

<sect1 id="private-data">
  <title>Private Data</title>

<para>
  To support multiple instances it is necessary to stop using global
  variables to store a driver's data in. Instead, you should store it in a
  structure, that you allocate and store on driver's init.
</para>

<para>
  In the driver's private structure will probably at least be something like:
</para>

<screen>
typedef struct MyDriver_private_data {
	int fd;				// file descriptor for the LCD device
        int width, height;		// dimension of the LCD (in characters, 1-based
        int cellwidth, cellheight;	// Size of each LCD cell, in pixels
        unsigned char *framebuf;	// Frame buffer...
} PrivateData;
</screen>

<para>
  You allocate and store this structure like this:
</para>

<screen>
	PrivateData *p;

	// Allocate and store private data
	p = (PrivateData *) malloc(sizeof(PrivateData));
	if (p == NULL)
		return -1;
	if (drvthis->store_private_ptr( drvthis, p ) &lt; 0)
		return -1;

	// initialize private data
	p->fd = -1;
	p->cellheight = 8;
	p->cellwidth = 6;

	(... continue with the rest of your init routine)
</screen>

<para>
  You retrieve this private data pointer by adding the following code to the
  beginning of your functions:
</para>

<screen>
	PrivateData *p = (PrivateData *) drvthis->private_data;
</screen>

<para>
  Then you can access your data like:
</para>
<screen>
	p->framebuf
</screen>

</sect1>

<sect1 id="function-details">
  <title>Functions in Detail</title>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*init)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  The init() function.
  It starts up the LCD, initializes all variables, allocates private data space
  and stores the pointer by calling store_private_ptr();
  Returns &lt;0 on error.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*close)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Shut down the connection with the LCD.
  Called just before unloading the driver.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*width)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Get the screen width in characters.
  The result is 1-based.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*height)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Get the screen height in character lines.
  The result is 1-based.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*clear)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Clear the framebuffer.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*flush)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Flush the framebuffer to the LCD.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*string)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>y</parameter></paramdef>
	<paramdef>const char *<parameter>str</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Place string <replaceable>str</replaceable> into position
  (<replaceable>x</replaceable>,<replaceable>y</replaceable>) in the framebuffer.
  All coordinates are 1-based, i.e. (1,1) is top left.
  The driver should check for overflows, i.e. that the positional parameters
  are within the screen's boundaries and cut off the part of the string
  that is out of bounds.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*chr)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>y</parameter></paramdef>
	<paramdef>char <parameter>c</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Place a single character <replaceable>c</replaceable> into position
  (<replaceable>x</replaceable>,<replaceable>y</replaceable>) in the framebuffer.
  The driver should check for overflows, i.e. that the positional parameters
  are within the screen's boundaries and ignore the request if
  the character is out of bounds.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*vbar)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>y</parameter></paramdef>
	<paramdef>int <parameter>len</parameter></paramdef>
	<paramdef>int <parameter>promille</parameter></paramdef>
	<paramdef>int <parameter>options</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Draw a vertical bar at position (<replaceable>x</replaceable>,<replaceable>y</replaceable>)
  that has maximal length <replaceable>len</replaceable>, where a fraction of
  (<replaceable>promille</replaceable> / 1000) is filled.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*hbar)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>y</parameter></paramdef>
	<paramdef>int <parameter>len</parameter></paramdef>
	<paramdef>int <parameter>promille</parameter></paramdef>
	<paramdef>int <parameter>options</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Draw a horizontal bar at position (<replaceable>x</replaceable>,<replaceable>y</replaceable>)
  that has maximal length <replaceable>len</replaceable>, where a fraction of
  (<replaceable>promille</replaceable> / 1000) is filled.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*num)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>num</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Display big number <replaceable>num</replaceable> at horizontal position <replaceable>x</replaceable>.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*heartbeat)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>state</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Sets the heartbeat to the indicated state: 0=off, 1=on.
  Use HEARTBEAT_ON to say that we want to display/refresh the heartbeat.
  The driver choose how to do it.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*icon)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>y</parameter></paramdef>
	<paramdef>int <parameter>icon</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Draw named icon <replaceable>icon</replaceable> at position
  (<replaceable>x</replaceable>,<replaceable>y</replaceable>).
  If the driver returns -1 the server core will draw an appropriate replacement
  character.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*cursor)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>x</parameter></paramdef>
	<paramdef>int <parameter>y</parameter></paramdef>
	<paramdef>int <parameter>type</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Move cursor to position (<replaceable>x</replaceable>,<replaceable>y</replaceable>),
  setting its type to <replaceable>type</replaceable>.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*set_char)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>char <parameter>ch</parameter></paramdef>
	<paramdef>unsigned char *<parameter>dat</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  The set_char function expects a simple block of data with 1 byte for each pixel-line.
  (So that is 8 bytes for a 5x8 char)
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*get_free_chars)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Get total number of custom characters available.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*cellwidth)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Return the width of a character cell in pixels.
  The result is 1-based.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*cellheight)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Return the height of a character cell in pixels.
  The result is 1-based.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*get_contrast)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Get the contrast value from the driver.
  The return value is an integer in the range from 0 to 1000.
  Many displays do not support getting or setting contrast using software.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*set_contrast)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>promille</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Sets the contrast to the given value, which is an integer in the range from 0 to 1000.
  It is up to the driver to map the logical interval [0, 1000] into the
  interval that the hardware supports.
  Many displays do not support software setting of contrast.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*get_brightness)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>state</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Get the brightness value from the driver for the given backlight state.
  The parameter <parameter>state</parameter> determines which one
  is returned.
  The return value is an integer in the range from 0 to 1000.
  Many displays do not support getting or setting brightness using software.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>(*set_brightness)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>state</parameter></paramdef>
	<paramdef>int <parameter>promille</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Set the brightness for the given backlight state to the value given.
  Value must be an integer in the range from 0 to 1000.
  It is up to the driver to map the logical interval [0, 1000] into the
  interval that the hardware supports.
  Many displays do not support software setting of brightness.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*backlight)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>state</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Sets the backlight to the given brightness state.
  Often hardware can only support two values for the backlight:
  on and off.
  In that case any value of state &gt; 0 will switch the backlight on.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>void <function>(*output)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
	<paramdef>int <parameter>state</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Sets the output value. Some displays/wirings have a general purpose
  output, which can be controlled by calling this function. See the
  'output' command in the 'widget language'.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>const char *<function>(*get_key)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Checks if a key has been pressed on the device.
  Returns NULL for "no key pressed", or a string describing the pressed key.
  These characters should match the keypad-layout.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>const char *<function>(*get_info)</function></funcdef>
	<paramdef>Driver *<parameter>drvthis</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Returns a string describing the driver and its features.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>short <function>(*config_get_bool)</function></funcdef>
	<paramdef>char *<parameter>sectionname</parameter></paramdef>
	<paramdef>char *<parameter>keyname</parameter></paramdef>
	<paramdef>int <parameter>skip</parameter></paramdef>
	<paramdef>short <parameter>default_value</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Call to server. Retrieve a bool from the config file.
  Sectionname should be the name of the driver (as in the struct).
  If the key cannot be found, the default value will be returned.
  skip should be 0 usually, but if you want to retrieve multiple
  identical keys, then increase skip to get every next value.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>long int <function>(*config_get_int)</function></funcdef>
	<paramdef>char *<parameter>sectionname</parameter></paramdef>
	<paramdef>char *<parameter>keyname</parameter></paramdef>
	<paramdef>int <parameter>skip</parameter></paramdef>
	<paramdef>long int <parameter>default_value</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Call to server. Retrieve an integer from the config file.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>double <function>(*config_get_float)</function></funcdef>
	<paramdef>char *<parameter>sectionname</parameter></paramdef>
	<paramdef>char *<parameter>keyname</parameter></paramdef>
	<paramdef>int <parameter>skip</parameter></paramdef>
	<paramdef>double <parameter>default_value</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Call to server. Retrieve a float from the config file.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>const char *<function>(*config_get_string)</function></funcdef>
	<paramdef>char *<parameter>sectionname</parameter></paramdef>
	<paramdef>char *<parameter>keyname</parameter></paramdef>
	<paramdef>int <parameter>skip</parameter></paramdef>
	<paramdef>const char *<parameter>default</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Call to server. Retrieve a string from the config file.
  Fill result with a pointer to some available space. You can fill it
  with a default value. If the key is found, it will be overwritten
  with the value from the key.
  Note that you should always first copy the the returned string.
  It is in the address space of the server, and will be freed at the
  next call.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>config_has_section</function></funcdef>
	<paramdef>const char *<parameter>sectionname</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Returns whether a section exists. Does not need to be called prior
  to a call to a config_get_* function.
</para>

<funcsynopsis>
  <funcprototype>
	<funcdef>int <function>config_has_key</function></funcdef>
	<paramdef>const char *<parameter>sectionname</parameter></paramdef>
	<paramdef>const char *<parameter>keyname</parameter></paramdef>
  </funcprototype>
</funcsynopsis>
<para>
  Returns the number of times a key exists. Does not need to be called
  prior to a call to a config_get_* function.
</para>

<screen>
First version, Joris Robijn, 20011016
Corrected and expanded, Peter Marschall 20060411
Sync'd with lcd.h, Markus Dolze, 20090322
</screen>

</sect1>

</chapter>