v0.5 kick-off

This commit is contained in:
robijn
2001-12-30 00:15:25 +00:00
parent c28d25b795
commit 71056ec551
88 changed files with 6638 additions and 5469 deletions
+162 -66
View File
@@ -1,11 +1,9 @@
DG: David GLAUDE as added a few comment for discussing this document.
This document describes the driver API of v0.5 of LCDproc.
At time of this writing, this version is not released and some things might
be changed.
The API consists of several functions to tell the driver that
certains actions should be performed, some data, and several functions
certains actions should be performed, some data, and several functions
to retrieve configuration data from the server.
OVERVIEW OF OPERATION
@@ -16,32 +14,45 @@ which is defined in server/drivers/lcd.h.
The use of the API has changed from v0.4 to v0.5. The default functions that
the server put in the pointers in v0.4 do no longer exist. Instead empty
functions are the default. If a driver implements a function, the function
will be detected by the server. The driver should at least implement all
basic functions like driver_chr and driver_str itself.
will be detected by the server. The driver should at least implement all
basic functions like driver_chr and driver_str itself, and should also have
defined a number of other symbols for the server.
Because the drivers are loadable, some kind of version checking should be done.
Therefor the server expects the correct version number to be returned from the
version function. For the v0.5 version this should be "0.5". If it is wrong,
the driver will not be loaded. This version number can be found in the define
API_VERSION.
I will walk through the driver struct here.
#define drvthis struct lcd_logical_driver * driver
DG: This is very C++ and it is meaningfull in C++ to have
DG: DATA + FUNCTION in the "this" because we have polymorph
DG: and heritage. But in our case we only need private data
DG: in order to support multiple instances.
DG: Or do we want the driver to provide different function
DG: based on the detected hardware (or something like that)?
DG: Except for init and close, I don't see why we don't give
DG: the private data rather than drvthis???
DG: Please explain (again).
typedef struct lcd_logical_driver {
char * name; // Name of this driver. Filled by server.
//////// Variables in the driver module
// The driver loader will look for symbols with these names !
char *api_version;
int *stay_in_foreground; // Does this driver require to be in foreground ?
int *does_input; // Does this driver do output ?
int *does_output; // Does this driver do output ?
The programmer should define the following symbols:
char * api_version = API_VERSION; // <-- this symbol is defined by make
int stay_in_foreground = 0; // This driver does not need to be in foreground
int does_input = 0; // This driver does not do input
int does_output = 1; // But only output
And fill these values with the correct values. Upon loading the driver module,
the server will locate these symbols and store pointers to them in the
driver struct.
Because the drivers are loadable, some kind of version checking should be
done. Therefor the server expects the correct version number to be found in
the api_version symbol (a string). For the v0.5 version this should be "0.5".
If the version is incompatible, the driver will not be loaded. The current
API version can always be determined by inserting the compiler define
API_VERSION in the code.
//////// Functions in the driver module
// Basic functions
char *(*version); // OR CAN WE RETRIEVE A STRING FROM THE MODULE
All these Basic functions should be implemented !
int (*init) (drvthis, char *args);
void (*close) (drvthis);
int (*width) (drvthis);
@@ -51,34 +62,78 @@ typedef struct lcd_logical_driver {
void (*string) (drvthis, int x, int y, char *str);
void (*chr) (drvthis, int x, int y, char c);
// Extended functions
void (*vbar) (drvthis, int x, int y, int len, int promille, int pattern);
void (*hbar) (drvthis, int x, int y, int len, int promille, int pattern);
void (*vbar) (drvthis, int x, int y, int len, int promille, int options);
void (*hbar) (drvthis, int x, int y, int len, int promille, int options);
These functions have been extended since v0.4. They now now expext complete
coordinates, a length (in chars, not pixels!) a promillage (0 to 1000) and an
option.
void (*num) (drvthis, int x, int num);
Draw big numbers on your display. Only 6 positions exist, 1 to 6.
void (*heartbeat) (drvthis, int state);
char (*set_icon) (drvthis, int icon);
DG: I don't like this function...
DG: I would prefer the following definition (like chr)
DG: void (*set_icon) (drvthis, int x, int y, int icon);
Should be called to animate the heartbeat. The driver should thererfor
probably call the icon function below.
void (*icon) (drvthis, int x, int y, int icon);
Tells to place a certain icon at a position.
// Userdef characters
void (*set_char) (drvthis, char ch, char *dat);
int (*get_free_chars) (drvthis);
int (*cellwidth) (drvthis);
int (*cellheight) (drvthis);
Functions to define a character. It is currently unclear how this system
should exactly work. 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.
// Hardware functions
int (*contrast) (drvthis, int contrast);
void (*backlight) (drvthis, int on);
void (*output) (drvthis, int on);
void (*backlight) (drvthis, int brightness);
void (*output) (drvthis, int state);
// Userdef characters, are those still supported ?
//void (*set_char) (drvthis, int n, char *dat);
//int (*cellwidth) (drvthis);
//int (*cellheight) (drvthis);
// Key functions
char *(*get_key) (drvthis);
// Returns a string. Server cannot modify
// this string.
Returns a string. This string is withing driver's memory space and the server
should therefor never try to modify this string.
char * (*get_info) ();
Returns a string describing the driver and it's features.
//////// Variables in server core available for drivers
char * name; // Name of this driver.
void * private_data;
These variables should be taken read-only for the drivers. The name variable
should be used to access the driver's own section in the config file.
The private_data pointer is the pointer to the driver's own data block. This
pointer should be stored using the store_private_ptr function below. The
driver should cast this to it's own private structure pointer.
//////// Functions in server core available for drivers
int (*store_private_ptr) (struct lcd_logical_driver * driver, void * private_data);
Store the driver's private data:
// Config file functions, filled by server
// DO THESE NEED TO BE IN THIS STRUCTURE ?
// LOADABLE MODULES CAN CALL FUNCS IN THE MAIN MODULE ...
char (*config_get_bool) (char * sectionname, char * keyname,
int skip, char default_value);
int (*config_get_int) (char * sectionname, char * keyname,
@@ -86,36 +141,50 @@ DG: void (*set_icon) (drvthis, int x, int y, int icon);
double (*config_get_float) (char * sectionname, char * keyname,
int skip, double default_value);
char *(*config_get_string) (char * sectionname, char * keyname,
int skip, char * default);
int skip, char * default_value);
// Returns a string in server memory space.
// Copy this string.
int config_has_section (char *sectionname);
int config_has_key (char *sectionname, char *keyname);
See configfile.h on how to use these functions. As sectionname, always use the
driver name: drvthis->name
// Reporting function
void (*report) ( const int level, const char *format, .../*args*/ );
Easily usable report functions by including drivers/report.h. See that file
for details.
// Display properties functions (for drivers that adapt to other loaded drivers)
int (*get_display_width) ();
int (*get_display_height) ();
If you have a driver that can adapt its size to the size of an other driver,
it should read these values. If there is no other driver loaded yet, the
returned values will be 0.
// Driver private data
int (*store_private_ptr) (void * private_data);
void * private_data; // Filled by server by calling store_private_ptr()
DG: I think it is the driver that should take care of using the right
DG: private data.
DG: The server need to remember two thing about a driver,
DG: 1) The drvthis wich contain what function to call and is a well define
DG: structure that we get at init time.
DG: drvthis should be the same for every instances of the driver.
DG: 2) private_data wich we remember and receave as a pointer to a black box
DG: and we give it back to the driver in EVERY call.
DG:
DG: Implicitly the driver knows about wich function is what...
DG: But the driver need to know only wich instance is currently "active".
DG:
DG: It does not change much, but we don't need store_private_ptr anymore.
// Driver should cast this to it's own
// private structure pointer
} lcd_logical_driver;
} Driver;
The flush_box and draw_frame functions have been removed for v0.5.
In the private structure will probably at least be:
PRIVATE DATA
With the introduction of loadable modules it is necesary to stop using global
variables to store a driver's data in. Instead, you should store it in a
structure, that you allocate abd store on driver's init. If you don't use
this system, but use globals, you get queer results if you run two LCDd
daemons on one machine. They will then use the same variables !
In the driver's private structure will probably at least be something like:
typedef struct my_driver_private {
@@ -125,23 +194,43 @@ typedef struct my_driver_private {
int cellwidth, cellheight;
// Frame buffer...
char *framebuf;
};
} PrivateData;
You allocate and store this structure like this:
PrivateData * p;
// Alocate and store private data
p = (PrivateData *) malloc( sizeof(PrivateData) );
if( p == NULL )
return -1;
if( drvthis->store_private_ptr( drvthis, p ) < 0 )
return -1;
(... continue with the rest of your init routine)
You retrieve this private data pointer by adding the following code to the
beginning of your functions:
PrivateData * p = (PrivateData*) drvthis->private_data;
Then you can access your data like:
p->framebuf
FUNCTIONS IN DETAIL
char *(*version);
// Return the API version string as the driver knows it.
int (*init) (drvthis, char *args);
// The init function
// Starts up the LCD, initializes all vars. Allocates private data space
// and stores the pointer by calling store_private_ptr();
// The init function should return the correct version number.
void (*close) (drvthis);
// Shuts down the connection with the LCD.
// Called just before unloading the driver.
int (*width) (drvthis);
// Get the screen width.
@@ -158,9 +247,11 @@ void (*flush) (drvthis);
void (*string) (drvthis, int x, int y, char *str);
// Places a string in the framebuffer
// All coordinates are 1-based, (1,1) is top left.
// Driver should check for overflows
void (*chr) (drvthis, int x, int y, char c);
// Places a char in the framebuffer
// Driver should check for overflows
void (*vbar) (drvthis, int x, int len);
// Draws a vertical bar at horizontal position x and with length len.
@@ -178,8 +269,9 @@ void (*heartbeat) (drvthis, int state);
// 0=off 1=graph1 2=graph2
int (*contrast) (drvthis, int contrast);
// Sets the contrast to the given value.
// Sets the contrast to the given value. Values should be 0 to 255.
// Many displays do not support software setting of contrast.
// Use -1 to get the current value returned.
void (*backlight) (drvthis, int on);
// Sets the backlight to brightness 'on'.
@@ -196,6 +288,10 @@ char *(*getkey) ();
// Returns NULL for "no key pressed", or a string describing the pressd key.
// These characters should match the keypad-layout.
char *(*getinfo) ();
// Returns a string describing the driver and its features.
char (*config_get_bool) (char * sectionname, char * keyname,
int skip, char default_value);
// Call to server. Retrieve a bool from the config file.
@@ -218,9 +314,9 @@ char *(*config_get_string) (char * sectionname, char * keyname,
// 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.
// 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.
// next call.
int config_has_section (char *sectionname);
// Returns wether a section exists. Does not need to be called prior