From 71056ec55106678f01dd610ac08459d1301508d3 Mon Sep 17 00:00:00 2001 From: robijn Date: Sun, 30 Dec 2001 00:15:25 +0000 Subject: [PATCH] v0.5 kick-off --- configure.in | 4 +- docs/API-v0.5.txt | 228 ++-- server/Makefile.am | 2 +- server/client_data.c | 17 +- server/client_data.h | 9 +- server/client_functions.c | 580 ++++----- server/client_functions.h | 3 +- server/client_menu.h | 9 +- server/clients.c | 78 +- server/clients.h | 14 +- server/configfile.c | 55 +- server/configfile.h | 61 +- server/driver.c | 247 ++++ server/driver.h | 47 + server/drivers.c | 651 +++++++--- server/drivers.h | 97 +- server/drivers/CFontz.c | 367 +++--- server/drivers/CFontz.h | 48 +- server/drivers/MtxOrb.c | 598 +++++----- server/drivers/MtxOrb.h | 68 +- server/drivers/bayrad.c | 378 +++--- server/drivers/bayrad.h | 40 +- server/drivers/curses_drv.c | 302 ++--- server/drivers/curses_drv.h | 41 +- server/drivers/debug.c | 261 ++-- server/drivers/debug.h | 45 +- server/drivers/glk.c | 365 +++--- server/drivers/glk.h | 130 +- server/drivers/hd44780-4bit.c | 180 ++- server/drivers/hd44780-4bit.h | 5 +- server/drivers/hd44780-drivers.h | 23 +- server/drivers/hd44780-ext8bit.c | 80 +- server/drivers/hd44780-ext8bit.h | 5 +- server/drivers/hd44780-low.h | 100 +- server/drivers/hd44780-serialLpt.c | 117 +- server/drivers/hd44780-serialLpt.h | 5 +- server/drivers/hd44780-winamp.c | 82 +- server/drivers/hd44780-winamp.h | 8 +- server/drivers/hd44780.c | 701 ++++++----- server/drivers/hd44780.h | 48 +- server/drivers/joy.c | 73 +- server/drivers/joy.h | 9 +- server/drivers/lb216.c | 263 ++-- server/drivers/lb216.h | 39 +- server/drivers/lcd.c | 40 +- server/drivers/lcd.h | 242 ++-- server/drivers/lcd_lib.c | 33 +- server/drivers/lcdm001.c | 322 +++-- server/drivers/lcdm001.h | 25 +- server/drivers/lircin.c | 32 +- server/drivers/lircin.h | 8 +- server/drivers/report.h | 37 + server/drivers/sed1330.c | 1776 ++++++++++++++-------------- server/drivers/sed1330.h | 52 +- server/drivers/sed1520.c | 243 ++-- server/drivers/sed1520.h | 30 +- server/drivers/stv5730.c | 267 +++-- server/drivers/stv5730.h | 28 +- server/drivers/t6963.c | 226 ++-- server/drivers/t6963.h | 41 +- server/drivers/text.c | 282 ++--- server/drivers/text.h | 21 +- server/drivers/wirz-sli.c | 295 +++-- server/drivers/wirz-sli.h | 46 +- server/input.c | 119 +- server/input.h | 14 +- server/main.c | 334 +++--- server/main.h | 6 +- server/menu.c | 138 +-- server/menu.h | 7 +- server/menus.c | 99 +- server/menus.h | 5 +- server/parse.c | 102 +- server/parse.h | 1 - server/render.c | 286 ++--- server/render.h | 1 - server/screen.c | 31 +- server/screen.h | 1 - server/screenlist.c | 77 +- server/screenlist.h | 1 - server/serverscreens.c | 80 +- server/serverscreens.h | 1 - server/sock.c | 59 +- server/sock.h | 3 +- server/widget.c | 81 +- server/widget.h | 19 +- shared/report.c | 12 +- shared/report.h | 101 +- 88 files changed, 6638 insertions(+), 5469 deletions(-) create mode 100644 server/driver.c create mode 100644 server/driver.h create mode 100644 server/drivers/report.h diff --git a/configure.in b/configure.in index 18aa12d..404a99a 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(clients/lcdproc/batt.c) -AM_INIT_AUTOMAKE(lcdproc, dev) +AM_INIT_AUTOMAKE(lcdproc, 0.5beta) AM_CONFIG_HEADER(config.h) AC_CANONICAL_HOST @@ -132,7 +132,7 @@ AC_DEFINE_UNQUOTED(LCDPORT, $LCDPORT) AC_DEFINE_UNQUOTED(PROTOCOL_VERSION, "0.3") -AC_DEFINE_UNQUOTED(API_VERSION, "0.4") +AC_DEFINE_UNQUOTED(API_VERSION, "0.5beta") AC_ARG_WITH(loadmax, diff --git a/docs/API-v0.5.txt b/docs/API-v0.5.txt index a5b45ac..889dc6f 100644 --- a/docs/API-v0.5.txt +++ b/docs/API-v0.5.txt @@ -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 diff --git a/server/Makefile.am b/server/Makefile.am index eab2699..7f1648b 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS=drivers sbin_PROGRAMS=LCDd -LCDd_SOURCES= client_data.c client_data.h client_functions.c client_functions.h client_menu.h clients.c clients.h input.c input.h main.c main.h menu.c menu.h menus.c menus.h parse.c parse.h render.c render.h screen.c screen.h screenlist.c screenlist.h serverscreens.c serverscreens.h sock.c sock.h widget.c widget.h configfile.c configfile.h drivers.c drivers.h +LCDd_SOURCES= client_data.c client_data.h client_functions.c client_functions.h client_menu.h clients.c clients.h input.c input.h main.c main.h menu.c menu.h menus.c menus.h parse.c parse.h render.c render.h screen.c screen.h screenlist.c screenlist.h serverscreens.c serverscreens.h sock.c sock.h widget.c widget.h configfile.c configfile.h drivers.c drivers.h driver.c driver.h LCDd_LDADD = drivers/libLCDdrivers.a ../shared/libLCDstuff.a @LIBCURSES@ @LIBIRMAN@ @LIBLIRC_CLIENT@ @LIBSVGA@ INCLUDES = -I$(top_srcdir) diff --git a/server/client_data.c b/server/client_data.c index ce4c8fb..e04e638 100644 --- a/server/client_data.c +++ b/server/client_data.c @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * * * Creates and destroys a client's data structures. These are mainly @@ -68,15 +67,15 @@ client_data_destroy (client_data * d) d->ack = 0; - // Clean up the name... + /* Clean up the name...*/ if (d->name) free (d->name); - // Clean up the key list... + /* Clean up the key list...*/ if (d->client_keys) free (d->client_keys); - // Clean up the screenlist... + /* Clean up the screenlist...*/ debug( RPT_DEBUG, "client_data_destroy: Cleaning screenlist"); ResetScreenList (d->screenlist); do { @@ -84,20 +83,20 @@ client_data_destroy (client_data * d) if (s) { debug( RPT_DEBUG, "client_data_destroy: removing screen %s", s->id); - // FIXME? This shouldn't be handled here... - // Now, remove it from the screenlist... + /* FIXME? This shouldn't be handled here... + * Now, remove it from the screenlist...*/ if (screenlist_remove_all (s) < 0) { - // Not a serious error.. + /* Not a serious error..*/ report( RPT_ERR, "client_data_destroy: Error dequeueing screen"); return 0; } - // Free its memory... + /* Free its memory...*/ screen_destroy (s); } } while (MoreScreens(d->screenlist)); DestroyScreenList(d->screenlist); - // TODO: clean up the rest of the data... + /* TODO: clean up the rest of the data...*/ return 0; } diff --git a/server/client_data.h b/server/client_data.h index dd39eee..aa7c51f 100644 --- a/server/client_data.h +++ b/server/client_data.h @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * */ @@ -20,17 +19,17 @@ typedef struct client_data { int ack; char *name; - // and other stuff... doesn't matter yet + /* and other stuff... doesn't matter yet*/ LinkedList *screenlist; - // list of requested keys... + /* list of requested keys...*/ char *client_keys ; LinkedList *menulist; } client_data; -// sets up an existing (empty) client_data struct +/* sets up an existing (empty) client_data struct*/ int client_data_init (client_data * d); -// destroys members of a client's data +/* destroys members of a client's data*/ int client_data_destroy (client_data * d); #endif diff --git a/server/client_functions.c b/server/client_functions.c index be7feee..a37a62f 100644 --- a/server/client_functions.c +++ b/server/client_functions.c @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * * * This contains definitions for all the functions which clients can run. @@ -27,7 +26,7 @@ #include "shared/report.h" #include "shared/sockets.h" -#include "drivers/lcd.h" +#include "drivers.h" #include "main.h" #include "render.h" @@ -60,7 +59,7 @@ client_function commands[] = { {"menu_add_item", menu_add_item_func}, {"menu_del_item", menu_del_item_func}, {"menu_set_item", menu_set_item_func}, - // Misc stuff... + /* Misc stuff...*/ {"backlight", backlight_func}, {"output", output_func}, {"noop", noop_func}, @@ -69,19 +68,19 @@ client_function commands[] = { {NULL, NULL}, }; -// Remember: argc counts all arguments, including the command name; -// so it will actually be one more than the number of arguments given -// to the command... +/* Remember: argc counts all arguments, including the command name; + * so it will actually be one more than the number of arguments given + * to the command...*/ #define NoArguments (argc == 1) #define AnyArguments (argc != 1) #define MoreArgumentsThan(a) (argc > (a)) -// TODO: Maybe more error-checking for "->"'s? +/* TODO: Maybe more error-checking for "->"'s?*/ -/////////////////////////////////////////////////////////////////////////// -// Debugging only.. prints out a list of arguments it receives -// +/*************************************************************** + * Debugging only.. prints out a list of arguments it receives + */ int test_func_func (client * c, int argc, char **argv) { @@ -96,19 +95,19 @@ test_func_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// The client must say "hello" before doing anything else. -// -// It returns a string of info about the server to the client -// -// usage: hello -// +/*************************************************************** + * The client must say "hello" before doing anything else. + * + * It returns a string of info about the server to the client + * + * usage: hello + */ int hello_func (client * c, int argc, char **argv) { char str[256]; - // TODO: Give *real* info about the server/lcd... + /* TODO: Give *real* info about the server/lcd...*/ if (AnyArguments) { sock_send_string (c->sock, "huh? extra parameters ignored\n"); @@ -118,11 +117,12 @@ hello_func (client * c, int argc, char **argv) memset(str, '\0', sizeof(str)); snprintf (str, sizeof(str), "connect LCDproc %s protocol %s lcd wid %i hgt %i cellwid %i cellhgt %i\n", - version, protocol_version, lcd_ptr->wid, lcd_ptr->hgt, lcd_ptr->cellwid, lcd_ptr->cellhgt); + version, protocol_version, display_props->width, display_props->height, display_props->cellwidth, display_props->cellheight); -// lcdproc (client) depends on the above format... -// snprintf (str, sizeof(str), "connect LCDproc %s protocol %s LCD %ix%i with cells %ix%i\n", -// version, protocol_version, lcd.wid, lcd.hgt, lcd.cellwid, lcd.cellhgt); +/* lcdproc (client) depends on the above format... + * snprintf (str, sizeof(str), "connect LCDproc %s protocol %s LCD %ix%i with cells %ix%i\n", + * version, protocol_version, lcd.wid, lcd.hgt, lcd.cellwid, lcd.cellhgt); + */ sock_send_string (c->sock, str); @@ -132,11 +132,11 @@ hello_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// sets info about the client, such as its name -// -// usage: client_set -name -// +/*************************************************** + * sets info about the client, such as its name + * + * usage: client_set -name + */ int client_set_func (client * c, int argc, char **argv) { @@ -166,12 +166,12 @@ client_set_func (client * c, int argc, char **argv) do { char *p; - // This bit of code means that "-name" is the same as "name"... + /* This bit of code means that "-name" is the same as "name"...*/ p = argv[i]; if (*p == '-') p++; - // Handle the "name" parameter + /* Handle the "name" parameter*/ if (strcmp (p, "name") == 0) { i++; if (argv[i] == '\0') { @@ -187,7 +187,7 @@ client_set_func (client * c, int argc, char **argv) debug(RPT_DEBUG, "client_set: name=\"%s\"", argv[i]); - // set the name... + /* set the name...*/ if (c->data->name) free (c->data->name); @@ -195,7 +195,7 @@ client_set_func (client * c, int argc, char **argv) sock_send_string(c->sock, "huh? error allocating memory!\n"); } else { sock_send_string(c->sock, "success\n"); - i++; // bypass argument (name string) + i++; /* bypass argument (name string)*/ } } } else { @@ -207,12 +207,12 @@ client_set_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Tells the server the client would like to accept keypresses -// of a particular type -// -// usage: client_add_key -// +/****************************************************************** + * Tells the server the client would like to accept keypresses + * of a particular type + * + * usage: client_add_key + */ int client_add_key_func (client * c, int argc, char **argv) { @@ -237,14 +237,15 @@ client_add_key_func (client * c, int argc, char **argv) debug(RPT_DEBUG, "client_add_key: current client will handle key(s) %s", keys); if (!c->data->client_keys) { - // No keys list, create a new one + /* No keys list, create a new one*/ c->data->client_keys = strdup( keys ); } else { - // Add supplied keys to existing list - // NOTE: There could be duplicates in the resulting list - // That's OK, it's the existence of the key in the list - // that's important. We'll be more careful in the delete - // key function. + /* Add supplied keys to existing list + * NOTE: There could be duplicates in the resulting list + * That's OK, it's the existence of the key in the list + * that's important. We'll be more careful in the delete + * key function. + */ char * new ; int new_len = strlen(c->data->client_keys) + strlen(keys) + 1 ; @@ -267,12 +268,12 @@ client_add_key_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Tells the server the client would NOT like to accept keypresses -// of a particular type -// -// usage: client_del_key -// +/********************************************************************* + + Tells the server the client would NOT like to accept keypresses + * of a particular type + * + * usage: client_del_key + */ int client_del_key_func (client * c, int argc, char **argv) { @@ -295,22 +296,23 @@ client_del_key_func (client * c, int argc, char **argv) debug(RPT_DEBUG, "client_del_key: Deleting key(s) %s from client_keys", keys); if (c->data->client_keys) { - // Client has keys, remove keys from the list - // NOTE: We let malloc/realloc remember the length - // of the allocated storage. If keys are later - // added, realloc (in add_key above) will make - // sure there is enough space at c->data->client_keys + /* Client has keys, remove keys from the list + * NOTE: We let malloc/realloc remember the length + * of the allocated storage. If keys are later + * added, realloc (in add_key above) will make + * sure there is enough space at c->data->client_keys + */ char * from ; char * to ; to = from = c->data->client_keys ; while( *from ) { - // Is this key to be deleted from the list? + /* Is this key to be deleted from the list?*/ if( strchr( keys, *from ) ) { - // Yes, skip it + /* Yes, skip it*/ ++from ; } else { - // No, save it + /* No, save it*/ *to++ = *from++ ; } } @@ -321,16 +323,16 @@ client_del_key_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Tells the server the client would like to accept keypresses -// of a particular type when the given screen is active on the display -// -// screen_add_key -// +/********************************************************************** + * Tells the server the client would like to accept keypresses + * of a particular type when the given screen is active on the display + * + * screen_add_key + */ int screen_add_key_func (client * c, int argc, char **argv) { - //widget * w ; /* Keys are stored on a WID_KEYS widget */ + /*widget * w ;*/ /* Keys are stored on a WID_KEYS widget */ screen * s ; /* Attached to a specific screen */ char * id ; /* Screen ID */ char * keys ; /* Keys wanted */ @@ -357,23 +359,24 @@ screen_add_key_func (client * c, int argc, char **argv) keys = argv[2]; debug(RPT_DEBUG, "screen_add_key: Adding key(s) %s to screen %s", keys, id); - // Find the screen + /* Find the screen*/ s = screen_find (c, id); if (!s) { sock_send_string (c->sock, "huh? Invalid screen id\n"); return 0; } - // Save the keys + /* Save the keys*/ if (!s->keys) { - // Save supplied key list + /* Save supplied key list*/ s->keys = strdup( keys ); } else { - // Add supplied keys to existing list - // NOTE: There could be duplicates in the resulting list - // That's OK, it's the existence of the key in the list - // that's important. We'll be more careful in the delete - // key function. + /* Add supplied keys to existing list + * NOTE: There could be duplicates in the resulting list + * That's OK, it's the existence of the key in the list + * that's important. We'll be more careful in the delete + * key function. + */ char * new ; new = realloc( s->keys, strlen(s->keys) + strlen(keys) +1 ); if( new ) { @@ -393,16 +396,16 @@ screen_add_key_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Tells the server the client would NOT like to accept keypresses -// of a particular type when the given screen is active on the display -// -// usage: screen_del_key -// +/************************************************************************* + * Tells the server the client would NOT like to accept keypresses + * of a particular type when the given screen is active on the display + * + * usage: screen_del_key + */ int screen_del_key_func (client * c, int argc, char **argv) { - //widget * w ; /* Keys are stored on a WID_KEYS widget */ + /*widget * w ;*/ /* Keys are stored on a WID_KEYS widget */ screen * s ; /* Attached to a specific screen */ char * id ; /* Screen ID */ char * keys ; /* Keys wanted */ @@ -429,7 +432,7 @@ screen_del_key_func (client * c, int argc, char **argv) keys = argv[2] ; debug(RPT_DEBUG, "screen_del_key: Deleting key(s) %s from screen %s", keys, id); - // Find the screen + /* Find the screen*/ s = screen_find (c, id); if (!s) { @@ -437,28 +440,29 @@ screen_del_key_func (client * c, int argc, char **argv) return 0; } - // Do we have keys? + /* Do we have keys?*/ if (s->keys) { - // Have keys, remove keys from the list - // NOTE: We let malloc/realloc remember the length - // of the allocated storage. If keys are later - // added, realloc (in add_key above) will make - // sure there is enough space at s->keys + /* Have keys, remove keys from the list + * NOTE: We let malloc/realloc remember the length + * of the allocated storage. If keys are later + * added, realloc (in add_key above) will make + * sure there is enough space at s->keys + */ char * from ; char * to ; to = from = s->keys ; while( *from ) { - // Is this key to be deleted from the list? + /* Is this key to be deleted from the list?*/ if( strchr( keys, *from ) ) { - // Yes, skip it + /* Yes, skip it*/ ++from ; } else { - // No, save it + /* No, save it*/ *to++ = *from++ ; } } - to = '\0'; // terminates the new keys string... + to = '\0'; /* terminates the new keys string...*/ } sock_send_string(c->sock, "success\n"); @@ -466,11 +470,11 @@ screen_del_key_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Tells the server the client has another screen to offer -// -// usage: screen_add -// +/*************************************************************** + * Tells the server the client has another screen to offer + * + * usage: screen_add + */ int screen_add_func (client * c, int argc, char **argv) { @@ -510,11 +514,11 @@ screen_add_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Client requests that the server forget about a screen -// -// usage: screen_del -// +/**************************************************************** + * Client requests that the server forget about a screen + * + * usage: screen_del + */ int screen_del_func (client * c, int argc, char **argv) { @@ -534,7 +538,7 @@ screen_del_func (client * c, int argc, char **argv) debug (RPT_DEBUG, "screen_del: Deleting screen %s", argv[1]); - // Enforce bounds limits on argv[1] + /* Enforce bounds limits on argv[1]*/ memset(scr, '\0', sizeof(scr)); strncpy(scr, argv[1], sizeof(scr) - 1); @@ -551,12 +555,13 @@ screen_del_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Configures info about a particular screen, such as its -// name, priority, or duration -// -// usage: screen_set [ -priority ] [ -name ] [ -duration ] -// [ -wid ] [ -hgt ] [ -heartbeat ] +/*************************************************************** + * Configures info about a particular screen, such as its + * name, priority, or duration + * + * usage: screen_set [ -priority ] [ -name ] [ -duration ] + * [ -wid ] [ -hgt ] [ -heartbeat ] + */ int screen_set_func (client * c, int argc, char **argv) { @@ -583,25 +588,26 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? Invalid screen id\n"); return 0; } - // Handle the rest of the parameters + /* Handle the rest of the parameters*/ for (i = 2; i < argc; i++) { char *p; - // The following code allows us to use p for comparisions, - // ignoring a (valid) single leading '-' - reduces string comparisons - // by half. + /* The following code allows us to use p for comparisions, + * ignoring a (valid) single leading '-' - reduces string comparisons + * by half. + */ p = argv[i]; if (*p == '-') p++; - // Handle the "name" parameter + /* Handle the "name" parameter*/ if (strcmp (p, "name") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: name=\"%s\"", argv[i]); - // set the name... + /* set the name...*/ if (s->name) free (s->name); s->name = strdup (argv[i]); @@ -610,13 +616,13 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? -name requires a parameter\n"); } } - // Handle the "priority" parameter + /* Handle the "priority" parameter*/ else if (strcmp (p, "priority") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: priority=\"%s\"", argv[i]); - // set the priority... + /* set the priority...*/ number = atoi (argv[i]); if (number > 0) s->priority = number; @@ -625,13 +631,13 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? -priority requires a parameter\n"); } } - // Handle the "duration" parameter + /* Handle the "duration" parameter*/ else if (strcmp (p, "duration") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: duration=\"%s\"", argv[i]); - // set the duration... + /* set the duration...*/ number = atoi (argv[i]); if (number > 0) s->duration = number; @@ -640,13 +646,13 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? -duration requires a parameter\n"); } } - // Handle the "heartbeat" parameter + /* Handle the "heartbeat" parameter*/ else if (strcmp (p, "heartbeat") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: heartbeat=\"%s\"", argv[i]); - // set the heartbeat type... + /* set the heartbeat type...*/ if (0 == strcmp (argv[i], "on")) s->heartbeat = HEART_ON; if (0 == strcmp (argv[i], "heart")) @@ -666,13 +672,13 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? -heartbeat requires a parameter\n"); } } - // Handle the "wid" parameter + /* Handle the "wid" parameter*/ else if (strcmp (p, "wid") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: wid=\"%s\"", argv[i]); - // set the duration... + /* set the duration...*/ number = atoi (argv[i]); if (number > 0) s->wid = number; @@ -682,13 +688,13 @@ screen_set_func (client * c, int argc, char **argv) } } - // Handle the "hgt" parameter + /* Handle the "hgt" parameter*/ else if (strcmp (p, "hgt") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: hgt=\"%s\"", argv[i]); - // set the duration... + /* set the duration...*/ number = atoi (argv[i]); if (number > 0) s->hgt = number; @@ -697,15 +703,16 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? -hgt requires a parameter\n"); } } - // Handle the "timeout" parameter + /* Handle the "timeout" parameter*/ else if (strcmp (p, "timeout") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: timeout=\"%s\"", argv[i]); - // set the duration... + /* set the duration...*/ number = atoi (argv[i]); - // Add the timeout value (count of TIME_UNITS) - // to struct, TIME_UNIT is 1/8th of a second + /* Add the timeout value (count of TIME_UNITS) + * to struct, TIME_UNIT is 1/8th of a second + */ if (number > 0) { s->timeout = number; report(RPT_NOTICE, "Timeout set."); @@ -716,12 +723,12 @@ screen_set_func (client * c, int argc, char **argv) } } - // Handle the backlight parameter + /* Handle the backlight parameter*/ else if (strcmp (argv[i], "backlight") == 0) { if (argc > i + 1) { i++; debug (RPT_DEBUG, "screen_set: backlight=\"%s\"", argv[i]); - // set the backlight status based on what the client has set + /* set the backlight status based on what the client has set*/ switch(c->backlight_state) { case BACKLIGHT_OPEN: if (strcmp ("on", argv[i]) == 0) @@ -744,7 +751,7 @@ screen_set_func (client * c, int argc, char **argv) s->backlight_state |= BACKLIGHT_FLASH; break; default: - //If the backlight is not OPEN then inherit its state + /*If the backlight is not OPEN then inherit its state*/ s->backlight_state = c->backlight_state; break; } @@ -753,15 +760,15 @@ screen_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? -backlight requires a parameter\n"); } } else sock_send_string (c->sock, "huh? invalid parameter\n"); - }// done checking argv + }/* done checking argv*/ return 0; } -/////////////////////////////////////////////////////////////////////////// -// Adds a widget to a screen, but doesn't give it a value -// -// usage: widget_add [ -in ] -// +/************************************************************************* + * Adds a widget to a screen, but doesn't give it a value + * + * usage: widget_add [ -in ] + */ int widget_add_func (client * c, int argc, char **argv) { @@ -805,7 +812,7 @@ widget_add_func (client * c, int argc, char **argv) type = argv[3]; - // Check for additional flags... + /* Check for additional flags...*/ if (argc > 4) { char *p; @@ -813,7 +820,7 @@ widget_add_func (client * c, int argc, char **argv) if (*p == '-') p++; - // Handle the "in" flag to place widgets in a container... + /* Handle the "in" flag to place widgets in a container...*/ if (strcmp (p, "in")) { if (argc < 6) { sock_send_string (c->sock, "huh? Specify a frame to place widget in\n"); @@ -823,7 +830,7 @@ widget_add_func (client * c, int argc, char **argv) } } - // Add the widget and set its type... + /* Add the widget and set its type...*/ err = widget_add (s, wid, type, in, c->sock); if (err == 0) sock_send_string(c->sock, "success\n"); @@ -835,11 +842,11 @@ widget_add_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Removes a widget from a screen, and forgets about it -// -// usage: widget_del -// +/******************************************************************* + * Removes a widget from a screen, and forgets about it + * + * usage: widget_del + */ int widget_del_func (client * c, int argc, char **argv) { @@ -888,14 +895,14 @@ widget_del_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Configures information about a widget, such as its size, shape, -// contents, position, speed, etc... -// -// Ack! This is long! -// -// widget_set -// +/******************************************************************** + * Configures information about a widget, such as its size, shape, + * contents, position, speed, etc... + * + * Ack! This is long! + * + * widget_set + */ int widget_set_func (client * c, int argc, char **argv) { @@ -913,10 +920,11 @@ widget_set_func (client * c, int argc, char **argv) if (!c->data->ack) return 1; - // If there weren't enough parameters... - // We can't test for too many, since each widget may have a - // different number - plus, if the argument count is wrong, what ELSE - // could be wrong...? + /* If there weren't enough parameters... + * We can't test for too many, since each widget may have a + * different number - plus, if the argument count is wrong, what ELSE + * could be wrong...? + */ if (argc < 4) { switch (argc) { @@ -943,7 +951,7 @@ widget_set_func (client * c, int argc, char **argv) w = widget_find (s, wid); if (!w) { sock_send_string (c->sock, "huh? Invalid widget id\n"); - // Client Debugging... + /* Client Debugging...*/ { int i; report( RPT_WARNING, "huh? Invalid widget id (%s)", wid); @@ -952,17 +960,17 @@ widget_set_func (client * c, int argc, char **argv) } return 0; } - // FIXME? Shouldn't this be handled in widget.c? + /* FIXME? Shouldn't this be handled in widget.c?*/ i = 3; switch (w->type) { - case WID_STRING: // String takes "x y text" + case WID_STRING: /* String takes "x y text"*/ if (argc != i + 3) sock_send_string (c->sock, "huh? Wrong number of arguments\n"); else { if ((!isdigit ((unsigned int) argv[i][0])) || (!isdigit ((unsigned int) argv[i + 1][0]))) { sock_send_string (c->sock, "huh? Invalid coordinates\n"); - } else // Set all the data... + } else /* Set all the data...*/ { x = atoi (argv[i]); y = atoi (argv[i + 1]); @@ -980,7 +988,7 @@ widget_set_func (client * c, int argc, char **argv) } } break; - case WID_HBAR: // Hbar takes "x y length" + case WID_HBAR: /* Hbar takes "x y length"*/ if (argc != i + 3) sock_send_string (c->sock, "huh? Wrong number of arguments\n"); else { @@ -999,7 +1007,7 @@ widget_set_func (client * c, int argc, char **argv) sock_send_string(c->sock, "success\n"); } break; - case WID_VBAR: // Vbar takes "x y length" + case WID_VBAR: /* Vbar takes "x y length"*/ if (argc != i + 3) sock_send_string (c->sock, "huh? Wrong number of arguments\n"); else { @@ -1018,7 +1026,7 @@ widget_set_func (client * c, int argc, char **argv) sock_send_string(c->sock, "success\n"); } break; - case WID_ICON: // Icon takes "x y binary_data" + case WID_ICON: /* Icon takes "x y binary_data"*/ if (argc != i + 3) sock_send_string (c->sock, "huh? Wrong number of arguments\n"); else { @@ -1030,12 +1038,12 @@ widget_set_func (client * c, int argc, char **argv) y = atoi (argv[i + 1]); w->x = x; w->y = y; - // TODO: Parse binary data and copy it to widget's data... + /* TODO: Parse binary data and copy it to widget's data...*/ } } sock_send_string (c->sock, "huh? Widget type not yet implemented\n"); break; - case WID_TITLE: // title takes "text" + case WID_TITLE: /* title takes "text"*/ if (argc != i + 1) sock_send_string (c->sock, "huh? Wrong number of arguments\n"); else { @@ -1050,7 +1058,7 @@ widget_set_func (client * c, int argc, char **argv) sock_send_string(c->sock, "success\n"); } break; - case WID_SCROLLER: // Scroller takes "left top right bottom direction speed text" + case WID_SCROLLER: /* Scroller takes "left top right bottom direction speed text"*/ if (argc != i + 7) { sock_send_string (c->sock, "huh? Wrong number of arguments\n"); } else { @@ -1061,18 +1069,18 @@ widget_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? Invalid coordinates\n"); } else { left = atoi (argv[i]); - //debug("left: %d",left); + /*debug("left: %d",left);*/ top = atoi (argv[i + 1]); - //debug("top: %d",top); + /*debug("top: %d",top);*/ right = atoi (argv[i + 2]); - //debug("right: %d",right); + /*debug("right: %d",right);*/ bottom = atoi (argv[i + 3]); - //debug("bottom: %d",bottom); + /*debug("bottom: %d",bottom);*/ direction = (int) (argv[i + 4][0]); - //debug("dir: %c",(char)direction); + /*debug("dir: %c",(char)direction);*/ speed = atoi (argv[i + 5]); - //debug("speed: %d",speed); - // Direction must be v or h + /*debug("speed: %d",speed);*/ + /* Direction must be v or h*/ if (((char) direction != 'h') && ((char) direction != 'v')) { sock_send_string (c->sock, "huh? Invalid direction\n"); } else { @@ -1096,7 +1104,7 @@ widget_set_func (client * c, int argc, char **argv) } } break; - case WID_FRAME: // Frame takes "left top right bottom wid hgt direction speed" + case WID_FRAME: /* Frame takes "left top right bottom wid hgt direction speed"*/ if (argc != i + 8) { sock_send_string (c->sock, "huh? Wrong number of arguments\n"); } else { @@ -1109,22 +1117,22 @@ widget_set_func (client * c, int argc, char **argv) sock_send_string (c->sock, "huh? Invalid coordinates\n"); } else { left = atoi (argv[i]); - //debug("left: %d",left); + /*debug("left: %d",left);*/ top = atoi (argv[i + 1]); - //debug("top: %d",top); + /*debug("top: %d",top);*/ right = atoi (argv[i + 2]); - //debug("right: %d",right); + /*debug("right: %d",right);*/ bottom = atoi (argv[i + 3]); - //debug("bottom: %d",bottom); + /*debug("bottom: %d",bottom);*/ width = atoi (argv[i + 4]); - //debug("right: %d",right); + /*debug("right: %d",right);*/ height = atoi (argv[i + 5]); - //debug("bottom: %d",bottom); + /*debug("bottom: %d",bottom);*/ direction = (int) (argv[i + 6][0]); - //debug("dir: %c",(char)direction); + /*debug("dir: %c",(char)direction);*/ speed = atoi (argv[i + 7]); - //debug("speed: %d",speed); - // Direction must be v or h + /*debug("speed: %d",speed);*/ + /* Direction must be v or h*/ if (((char) direction != 'h') && ((char) direction != 'v')) { sock_send_string (c->sock, "huh? Invalid direction\n"); } else { @@ -1142,7 +1150,7 @@ widget_set_func (client * c, int argc, char **argv) } } break; - case WID_NUM: // Num takes "x num" + case WID_NUM: /* Num takes "x num"*/ if (argc != i + 2) sock_send_string (c->sock, "huh? Wrong number of arguments\n"); else { @@ -1169,11 +1177,11 @@ widget_set_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Adds a menu to the client; handled by the server... -// -// usage: menu_add ...? -// +/************************************************************* + * Adds a menu to the client; handled by the server... + * + * usage: menu_add ...? + */ int menu_add_func (client * c, int argc, char **argv) { @@ -1186,11 +1194,11 @@ menu_add_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Removes a client's menu and all contents from the server -// -// usage: menu_del ...? -// +/**************************************************************** + * Removes a client's menu and all contents from the server + * + * usage: menu_del ...? + */ int menu_del_func (client * c, int argc, char **argv) { @@ -1203,13 +1211,13 @@ menu_del_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Sets info about a menu, but not its items -// -// For example, should the menu be top-level, or buried somewhere? -// -// usage: menu_set ...? -// +/*********************************************************************** + * Sets info about a menu, but not its items + * + * For example, should the menu be top-level, or buried somewhere? + * + * usage: menu_set ...? + */ int menu_set_func (client * c, int argc, char **argv) { @@ -1222,11 +1230,11 @@ menu_set_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Adds an item to a menu -// -// usage: menu_add_item ...? -// +/************************************************************************* + * Adds an item to a menu + * + * usage: menu_add_item ...? + */ int menu_add_item_func (client * c, int argc, char **argv) { @@ -1239,10 +1247,11 @@ menu_add_item_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Deletes an item from a menu -// -// usage: menu_del_item ...? +/************************************************************************* + * Deletes an item from a menu + * + + usage: menu_del_item ...? + */ int menu_del_item_func (client * c, int argc, char **argv) { @@ -1255,13 +1264,13 @@ menu_del_item_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Sets the info about a menu item -// -// For example, text displayed, widget type, value, etc... -// -// usage: menu_set_item ...? -// +/************************************************************************** + * Sets the info about a menu item + * + * For example, text displayed, widget type, value, etc... + * + * usage: menu_set_item ...? + */ int menu_set_item_func (client * c, int argc, char **argv) { @@ -1274,11 +1283,11 @@ menu_set_item_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -// Toggles the backlight, if enabled. -// -// usage: backlight -// +/*************************************************************************** + * Toggles the backlight, if enabled. + * + * usage: backlight + */ int backlight_func (client * c, int argc, char **argv) { @@ -1300,7 +1309,7 @@ backlight_func (client * c, int argc, char **argv) debug (RPT_DEBUG, "backlight(%s)", argv[1]); - backlight = (backlight && 1); // only preserves ON/OFF bit + backlight = (backlight && 1); /* only preserves ON/OFF bit*/ if (strcmp ("on", argv[1]) == 0) { c->backlight_state = BACKLIGHT_ON; @@ -1327,19 +1336,18 @@ backlight_func (client * c, int argc, char **argv) } -//////////////////////////////////////////////////////////////////////////// -// Sets the state of the output port (such as on MtxOrb LCDs) -// -// usage: output -// -// +/**************************************************************************** + * Sets the state of the output port (such as on MtxOrb LCDs) + * + * usage: output + */ #define ALL_OUTPUTS_ON -1 #define ALL_OUTPUTS_OFF 0 int output_func (client * c, int argc, char **argv) { - //int rc = 0; + /*int rc = 0;*/ char str[128]; if (argc != 2) { @@ -1358,25 +1366,28 @@ output_func (client * c, int argc, char **argv) long out; char *endptr, *p; - // Note that there is no valid range set for - // output_state; thus a value in the 12 digits - // is not considered out of range. + /* Note that there is no valid range set for + * output_state; thus a value in the 12 digits + * is not considered out of range. + */ errno = 0; - // errno is set here, because if strtol does not result in - // ERANGE (out of range error) it will not set errno (!). - // At least, this is the case with glibc 2.1.3 ... + /* errno is set here, because if strtol does not result in + * ERANGE (out of range error) it will not set errno (!). + * At least, this is the case with glibc 2.1.3 ... + */ p = argv[1]; out = strtol(p, &endptr, 0); - // From the man page for strtol(3) - // - // In particular, if *nptr is not `\0' but **endptr is - // `\0' on return, the entire string is valid. - // - // In this case, argv[1] is *nptr, and &endptr is **endptr. + /* From the man page for strtol(3) + * + * In particular, if *nptr is not `\0' but **endptr is + * `\0' on return, the entire string is valid. + * + * In this case, argv[1] is *nptr, and &endptr is **endptr. + */ if (errno) { int space; @@ -1399,22 +1410,22 @@ output_func (client * c, int argc, char **argv) sock_send_string(c->sock, "success\n"); - // Makes sense to me to set the output immediately; - // however, the outputs are currently set in - // draw_screen(screen * s, int timer) - // Whatever for? + /* Makes sense to me to set the output immediately; + * however, the outputs are currently set in + * draw_screen(screen * s, int timer) + * Whatever for? */ - // lcd_ptr->output (output_state); + /* drivers_output (output_state); */ report(RPT_NOTICE, "output states changed"); return 0; } -/////////////////////////////////////////////////////////////////////////// -// info_func -// -// usage: info -// +/**************************************************************************** + * info_func + * + * usage: info + */ int info_func (client * c, int argc, char **argv) { @@ -1425,18 +1436,18 @@ info_func (client * c, int argc, char **argv) } memset(str, '\0', sizeof(str)); - snprintf (str, sizeof(str), (char*) lcd_ptr->getinfo()); + snprintf (str, sizeof(str)-1, (char*) drivers_get_info()); sock_send_string (c->sock, str); return 0; } -/////////////////////////////////////////////////////////////////////////// -// sleep_func -// -// usage: sleep -// +/******************************************************************************* + * sleep_func + * + * usage: sleep + */ int sleep_func (client * c, int argc, char **argv) { @@ -1458,19 +1469,21 @@ sleep_func (client * c, int argc, char **argv) errno = 0; - // errno is set here, because if strtol does not result in - // ERANGE (out of range error) it will not set errno (!). - // At least, this is the case with glibc 2.1.3 ... + /* errno is set here, because if strtol does not result in + * ERANGE (out of range error) it will not set errno (!). + * At least, this is the case with glibc 2.1.3 ... + */ p = argv[1]; out = strtol(p, &endptr, 0); - // From the man page for strtol(3) - // - // In particular, if *nptr is not `\0' but **endptr is - // `\0' on return, the entire string is valid. - // - // In this case, argv[1] is *nptr, and &endptr is **endptr. + /* From the man page for strtol(3) + * + * In particular, if *nptr is not `\0' but **endptr is + * `\0' on return, the entire string is valid. + * + * In this case, argv[1] is *nptr, and &endptr is **endptr. + */ if (errno) { int space; @@ -1492,27 +1505,28 @@ sleep_func (client * c, int argc, char **argv) return 0; } - // Repeat until no more remains - should normally be zero - // on exit the first time... + /* Repeat until no more remains - should normally be zero + * on exit the first time...*/ snprintf(str, sizeof(str), "sleeping %d seconds\n", secs); sock_send_string (c->sock, str); - // whoops.... if this takes place as planned, ALL screens - // will "freeze" for the alloted time... - // - // while ((secs = sleep(secs)) > 0) - // ; + /* whoops.... if this takes place as planned, ALL screens + * will "freeze" for the alloted time... + * + * while ((secs = sleep(secs)) > 0) + */ ; sock_send_string (c->sock, "huh? ignored (not fully implemented)\n"); return 0; } -/////////////////////////////////////////////////////////////////////////// -// Does nothing, returns "noop complete" message -// -// This is useful for shell scripts or programs that want to talk -// with LCDproc and not get deadlocked. Send a noop after each -// command and look for the "noop complete" message. +/***************************************************************************** + * Does nothing, returns "noop complete" message + * + * This is useful for shell scripts or programs that want to talk + * with LCDproc and not get deadlocked. Send a noop after each + * command and look for the "noop complete" message. + */ int noop_func (client * c, int argc, char **argv) { @@ -1520,8 +1534,4 @@ noop_func (client * c, int argc, char **argv) return 0; } -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// +/*end of client_functions.c*/ diff --git a/server/client_functions.h b/server/client_functions.h index 5912ebb..ecc6656 100644 --- a/server/client_functions.h +++ b/server/client_functions.h @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * */ @@ -23,7 +22,7 @@ typedef struct client_function { int (*function) (client * c, int argc, char **argv); } client_function; -// FIXME? Do these really need to be visible from other sources? +/* FIXME? Do these really need to be visible from other sources?*/ int test_func_func (client * c, int argc, char **argv); int hello_func (client * c, int argc, char **argv); int client_set_func (client * c, int argc, char **argv); diff --git a/server/client_menu.h b/server/client_menu.h index ba588f5..3c74a84 100644 --- a/server/client_menu.h +++ b/server/client_menu.h @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * */ @@ -27,10 +26,10 @@ typedef struct client_menu { typedef struct client_menu_item { char id[]; - int type; // Title, function, submenu, slider, checkbox, etc... - int value; // Holds stuff like "true", 43, etc... - char text[]; // Text to display here... - char child[]; // For the "submenu" type + int type; /* Title, function, submenu, slider, checkbox, etc...*/ + int value; /* Holds stuff like "true", 43, etc...*/ + char text[]; /* Text to display here...*/ + char child[]; /* For the "submenu" type*/ } client_menu; #endif diff --git a/server/clients.c b/server/clients.c index 813ccd1..862b97b 100644 --- a/server/clients.c +++ b/server/clients.c @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * * * Inits/shuts down client system, @@ -31,7 +30,7 @@ LinkedList *clients; -// Initialize and kill client list... +/* Initialize and kill client list...*/ int client_init () { @@ -53,9 +52,10 @@ client_shutdown () debug (RPT_INFO, "client_shutdown()"); - // Free all client structures... - // Note that the regular list loop doesn't work here, because - // client_destroy() calls LL_Remove() + /* Free all client structures... + * Note that the regular list loop doesn't work here, because + * client_destroy() calls LL_Remove() + */ for (c = LL_Pop (clients); c; c = LL_Pop (clients)) { debug (RPT_DEBUG, "client_shutdown: ..."); if (c) { @@ -70,7 +70,7 @@ client_shutdown () } } - // Then, free the list... + /* Then, free the list...*/ LL_Destroy (clients); debug (RPT_DEBUG, "client_shutdown: done"); @@ -78,10 +78,11 @@ client_shutdown () return 0; } -// A client is identified by the file descriptor -// associated with it. -// -// Create and destroy clients.... +/* A client is identified by the file descriptor + + associated with it. + * + * Create and destroy clients.... + */ client * client_create (int sock) { @@ -89,28 +90,28 @@ client_create (int sock) debug (RPT_DEBUG, "client_create(%i)", sock); - // Allocate new client... + /* Allocate new client...*/ c = malloc (sizeof (client)); if (!c) { report (RPT_ERR, "client_create: error allocating new client"); return NULL; } - // Init struct members + /* Init struct members*/ c->sock = 0; c->data = NULL; c->messages = NULL; c->sock = sock; - c->backlight_state = backlight; //By default we get the server setting + c->backlight_state = backlight; /*By default we get the server setting*/ - // Set up message list... + /*Set up message list...*/ c->messages = LL_new (); if (!c->messages) { report (RPT_ERR, "client_create: error allocating message list"); free (c); return NULL; } - // TODO: allocate and init client data... + /*TODO: allocate and init client data...*/ c->data = malloc (sizeof (client_data)); if (!c->data) { report (RPT_ERR, "client_create: error allocating client data"); @@ -120,7 +121,7 @@ client_create (int sock) } else if (client_data_init (c->data) < 0) { return NULL; } - // TODO: Check for errors while adding the client to the list? + /*TODO: Check for errors while adding the client to the list?*/ LL_Push (clients, (void *) c); return c; @@ -138,7 +139,7 @@ client_destroy (client * c) if (!c) return -1; - // Eat the rest of the incoming requests... + /*Eat the rest of the incoming requests...*/ debug (RPT_DEBUG, "client_destroy: get_messages"); while ((str = client_get_message (c))) { if (str) { @@ -147,19 +148,19 @@ client_destroy (client * c) } } - // close socket... + /*close socket...*/ if (c->sock) { - // sock_send_string (c->sock, "bye\n"); + /*sock_send_string (c->sock, "bye\n");*/ close(c->sock); report(RPT_NOTICE, "closed socket for #%d", c->sock); } err = LL_Destroy (c->messages); - // Free client's other data + /*Free client's other data*/ client_data_destroy (c->data); - // Remove the client from the clients list... + /*Remove the client from the clients list...*/ LL_Remove (clients, c); free (c); @@ -167,7 +168,7 @@ client_destroy (client * c) return 0; } -// Add and remove messages from the client's queue... +/*Add and remove messages from the client's queue...*/ int client_add_message (client * c, char *message) { @@ -175,7 +176,7 @@ client_add_message (client * c, char *message) char *dup; char *str, *cp; char delimiters[] = "\n\r\0"; -// int len; +/* int len;*/ debug(RPT_DEBUG, "client_add_message(%s)", message); @@ -184,31 +185,32 @@ client_add_message (client * c, char *message) if (!message) return -1; -// len = strlen(message); -// if(len < 1) return 0; +/* len = strlen(message); + * if(len < 1) return 0; + */ - // Copy the string to avoid overwriting the original... + /* Copy the string to avoid overwriting the original...*/ dup = strdup (message); if (!dup) { report(RPT_ERR, "client_add_message: Error allocating new string"); return -1; } - // Now split the string into lines and enqueue each one... + /* Now split the string into lines and enqueue each one...*/ for (str = strtok (dup, delimiters); str; str = strtok (NULL, delimiters)) { cp = strdup (str); debug (RPT_DEBUG, "client_add_message: %s", cp); err += LL_Enqueue (c->messages, (void *) cp); } - //debug(RPT_DEBUG, "client_add_message(%s): %i errors", message, err); - free (dup); // Fixed memory leak... + /*debug(RPT_DEBUG, "client_add_message(%s): %i errors", message, err);*/ + free (dup); /* Fixed memory leak...*/ - // Err is the number of errors encountered... + /* Err is the number of errors encountered...*/ return err; } -// Woo-hoo! A simple function. :) +/* Woo-hoo! A simple function. :)*/ char * client_get_message (client * c) { @@ -221,23 +223,23 @@ client_get_message (client * c) str = (char *) LL_Dequeue (c->messages); - //debug(RPT_DEBUG, "client_get_message: \"%s\"", str); + /*debug(RPT_DEBUG, "client_get_message: \"%s\"", str);*/ return str; } -// Get and set the client's data... +/* Get and set the client's data...*/ int client_set (client * c, void *data) { - // You know, I really doubt this function will be useful... + /* You know, I really doubt this function will be useful...*/ return 0; } void * client_get (client * c) { - // But this one might be handy... + /* But this one might be handy...*/ return NULL; } @@ -247,14 +249,14 @@ client_find_sock (int sock) { client *c; -// debug(RPT_INFO, "client_find_sock(%i)", sock); +/* debug(RPT_INFO, "client_find_sock(%i)", sock);*/ LL_Rewind (clients); do { c = (client *) LL_Get (clients); -// debug(RPT_DEBUG, "client_find_sock: ... %i ...", c->sock); +/* debug(RPT_DEBUG, "client_find_sock: ... %i ...", c->sock);*/ if (c->sock == sock) { -// debug(RPT_DEBUG, "client_find_sock: ..! %i !..", c->sock); +/* debug(RPT_DEBUG, "client_find_sock: ..! %i !..", c->sock);*/ return c; } } while (LL_Next (clients) == 0); diff --git a/server/clients.h b/server/clients.h index d1d9a1f..a794bba 100644 --- a/server/clients.h +++ b/server/clients.h @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * */ @@ -27,24 +26,25 @@ typedef struct client { extern LinkedList *clients; -// Initialize and kill client list... +/* Initialize and kill client list...*/ int client_init (); int client_shutdown (); -// Create and destroy clients.... +/* Create and destroy clients....*/ client *client_create (int sock); int client_destroy (client * c); -// Add and remove messages from the client's queue... +/* Add and remove messages from the client's queue...*/ int client_add_message (client * c, char *message); char *client_get_message (client * c); -// Get and set the client's data... -// Not used at all yet, and may never be. Oh, well. +/* Get and set the client's data... + * Not used at all yet, and may never be. Oh, well. + */ int client_set (client * c, void *data); void *client_get (client * c); -// Search for a client with a particular filedescriptor... +/* Search for a client with a particular filedescriptor...*/ client *client_find_sock (int sock); #endif diff --git a/server/configfile.c b/server/configfile.c index 7ed32d6..ee4b402 100644 --- a/server/configfile.c +++ b/server/configfile.c @@ -34,7 +34,7 @@ typedef struct section { static section * first_section = NULL; -// Yes there is a static. It's C after all :) +/* Yes there is a static. It's C after all :)*/ section * find_section( char * sectionname ); @@ -44,7 +44,7 @@ key * add_key( section * s, char * keyname, char * value ); int process_config( section ** current_section, char (*get_next_char)(), char modify_section_allowed, char * source_descr ); -//// EXTERNAL FUNCTIONS //// +/**** EXTERNAL FUNCTIONS ****/ #define FILECHUNKSIZE 10 @@ -56,11 +56,11 @@ int config_read_file( char *filename ) int pos=0; section * curr_section = NULL; - // We use a nested fuction to transfer the characters from buffer to parser + /* We use a nested fuction to transfer the characters from buffer to parser*/ char get_next_char() { if( pos>=bytesread ) { if( !( bytesread = fread( buf, 1, FILECHUNKSIZE, f ))) { - // We're at the end + /* We're at the end*/ return 0; } pos = 0; @@ -82,12 +82,12 @@ int config_read_file( char *filename ) int config_read_string( char *sectionname, char *str ) -// All the config parameters are placed in the given section in memory. +/* All the config parameters are placed in the given section in memory.*/ { int pos=0; section * s; - // We use a nested fuction to transfer the characters from buffer to parser + /* We use a nested fuction to transfer the characters from buffer to parser*/ char get_next_char() { return str[pos++]; } @@ -115,9 +115,10 @@ char *config_get_string( char * sectionname, char * keyname, return k->value; -/* This is the safer way: +/* This is the safer way:*/ - // Reallocate memory space for the return value + /* Reallocate memory space for the return value*/ + /* string_storage = realloc( string_storage, ( strlen( k->value ) / 256 + 1) * 256 ); strcpy( string_storage, k->value ); @@ -164,7 +165,7 @@ long int config_get_int( char *sectionname, char *keyname, v = strtol( k->value, &v_end, 0 ); if( v_end-(k->value) != strlen(k->value) ) { - // Conversion not succesful + /* Conversion not succesful*/ return default_value; } return v; @@ -186,7 +187,7 @@ double config_get_float( char *sectionname, char *keyname, v = strtod( k->value, &v_end ); if( v_end-(k->value) != strlen(k->value) ) { - // Conversion not succesful + /* Conversion not succesful*/ return default_value; } return v; @@ -214,7 +215,7 @@ int config_has_key( char *sectionname, char *keyname ) for( k=s->first_key; k; k=k->next_key ) { - // Did we find the right key ? + /* Did we find the right key ?*/ if( strcasecmp( k->name, keyname ) == 0 ) { count ++; } @@ -229,7 +230,7 @@ void config_clear() } -//// INTERNAL FUNCTIONS //// +/**** INTERNAL FUNCTIONS ****/ section * find_section( char * sectionname ) { @@ -240,7 +241,7 @@ section * find_section( char * sectionname ) return s; } } - return NULL; // not found + return NULL; /* not found*/ } section * add_section( char * sectionname ) @@ -266,12 +267,12 @@ key * find_key( section * s, char * keyname, int skip ) int count = 0; key * last_key = NULL; - // Check for NULL section + /* Check for NULL section*/ if(!s) return NULL; for( k=s->first_key; k; k=k->next_key ) { - // Did we find the right key ? + /* Did we find the right key ?*/ if( strcasecmp( k->name, keyname ) == 0 ) { if( count == skip ) { return k; @@ -284,7 +285,7 @@ key * find_key( section * s, char * keyname, int skip ) if( skip == -1 ) { return last_key; } - return NULL; // not found + return NULL; /* not found*/ } key * add_key( section * s, char * keyname, char * value ) @@ -307,7 +308,7 @@ key * add_key( section * s, char * keyname, char * value ) } -// Parser states +/* Parser states*/ #define ST_INITIAL 0 #define ST_IGNORE 1 #define ST_SECTIONNAME 2 @@ -321,7 +322,7 @@ key * add_key( section * s, char * keyname, char * value ) #define ST_INVALID_QUOTEDVALUE 31 #define ST_END 99 -// Limits +/* Limits*/ #define MAXSECTIONNAMELENGTH 40 #define MAXKEYNAMELENGTH 40 #define MAXVALUELENGTH 200 @@ -346,7 +347,7 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo ch = get_next_char(); - // Secretly keep count of the line numbers + /* Secretly keep count of the line numbers*/ if( ch == '\n' ) { line_nr ++; } @@ -363,11 +364,11 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo case ';': case '=': case ']': - // It's a comment or an error + /* It's a comment or an error*/ state = ST_IGNORE; break; case '[': - // It's a section name + /* It's a section name*/ state = ST_SECTIONNAME; sectionname[0] = 0; sectionname_pos = 0; @@ -375,7 +376,7 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo case 0: break; default: - // It's a keyname + /* It's a keyname*/ state = ST_KEYNAME; keyname[0] = ch; keyname[1] = 0; @@ -465,7 +466,7 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo switch( ch ) { case '\n': state = ST_INITIAL; - //case ' ': + /*case ' ':*/ } break; case ST_VALUE: @@ -486,15 +487,15 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo case '\r': case '\t': case ' ': - // Value complete ! + /* Value complete !*/ if( ! *current_section ) { report( RPT_WARNING, "Data before any section on line %d of %s with key: %s", line_nr, source_descr, keyname ); } else { - // Store the value + /* Store the value*/ k = add_key( *current_section, keyname, value ); } - // And be ready for next thing... + /* And be ready for next thing...*/ state = ST_INITIAL; break; default: @@ -539,7 +540,7 @@ int process_config( section ** current_section, char (*get_next_char)(), char mo case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; - // default: litteral + /* default: litteral*/ } quote = 0; } diff --git a/server/configfile.h b/server/configfile.h index 194b4cc..4bde8a5 100644 --- a/server/configfile.h +++ b/server/configfile.h @@ -20,52 +20,59 @@ #endif int config_read_file( char *filename ); -// Opens the specified file and reads everything into memory. -// Returns -1 on parsing errors. -// Returns -2 if the file could not be opened or a read error occured. -// Returns -16 if a malloc went wrong. +/* Opens the specified file and reads everything into memory. + * Returns -1 on parsing errors. + * Returns -2 if the file could not be opened or a read error occured. + * Returns -16 if a malloc went wrong. + */ int config_read_string( char *sectionname, char *str ); -// Reads everything in the string into memory. -// Returns -1 on parsing errors. -// Returns -16 if a malloc went wrong. +/* Reads everything in the string into memory. + * Returns -1 on parsing errors. + * Returns -16 if a malloc went wrong. + */ unsigned char config_get_bool( char *sectionname, char *keyname, int skip, unsigned char default_value ); -// Tries to interpret a value in the config file as a boolean. -// 0, false, no, n = false -// 1, true, yes, y = true -// If the key is not found or cannot be interpreted, the given default value is -// returned. -// The skip value can be used to iterate over multiple values with the same -// key. Should be 0 to get the first one, 1 for the second etc. and -1 for the -// last. +/* Tries to interpret a value in the config file as a boolean. + * 0, false, no, n = false + * 1, true, yes, y = true + * If the key is not found or cannot be interpreted, the given default value is + * returned. + * The skip value can be used to iterate over multiple values with the same + * key. Should be 0 to get the first one, 1 for the second etc. and -1 for the + * last. + */ long int config_get_int( char *sectionname, char *keyname, int skip, long int default_value ); -// Tries to interpret a value in the config file as an integer. +/* Tries to interpret a value in the config file as an integer.*/ double config_get_float( char *sectionname, char *keyname, int skip, double default_value ); -// Tries to interpret a value in the config file as a float. +/* Tries to interpret a value in the config file as a float.*/ char *config_get_string( char * sectionname, char * keyname, int skip, char * default_value ); -// Returns a pointer to the string associated with the specified key. -// The string should never be modified, and used only short-term. You can -// for example scan it or copy it. In successive calls this function can -// re-use the data space ! +/* Returns a pointer to the string associated with the specified key. + * The string should never be modified, and used only short-term. You can + * for example scan it or copy it. In successive calls this function can + * re-use the data space ! + */ int config_has_section( char *sectionname ); -// Checks if a specified section exists. -// Returns whether it exists. +/* Checks if a specified section exists. + * Returns whether it exists. + */ int config_has_key( char *sectionname, char *keyname ); -// Checks if a specified key within the specified section exists. -// Returns the number of times the key exists. +/* Checks if a specified key within the specified section exists. + * Returns the number of times the key exists. + */ void config_clear(); -// Clears all data stored by the config_read_* functions. -// Should be called if the config should be reread. +/* Clears all data stored by the config_read_* functions. + * Should be called if the config should be reread. + */ #endif diff --git a/server/driver.c b/server/driver.c new file mode 100644 index 0000000..5b970b9 --- /dev/null +++ b/server/driver.c @@ -0,0 +1,247 @@ +/* + * driver.c + * This file is part of LCDd, the lcdproc server. + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 2001, Joris Robijn + * + * + * This code does all actions on the driver object. + * + */ + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shared/report.h" +#include "configfile.h" + +#include "driver.h" +#include "drivers.h" +#include "drivers/lcd.h" +/* lcd.h is used for the driver API definition */ + +void * lcd_find_init (char *driver); /* HACK TO USE THIS WHILE NO LOADABLE DRIVERS */ + + +/* Functions for the driver */ +static int request_display_width(); +static int request_display_height(); +static int driver_store_private_ptr(Driver * driver, void * private_data); + + +Driver * +driver_load( char * name, char * filename, char * args ) +{ + void (*driver_init)(); + Driver * driver = NULL; + int res; + + debug( RPT_DEBUG, "Loading driver [%.40s]", name ); + + /* Allocate memory for new driver struct */ + driver = malloc( sizeof( Driver )); + memset( driver, 0, sizeof (Driver)); + + /* Load the driver modules and fill the symbols */ + if( driver_bind_module( driver ) < 0 ) { + report( RPT_ERR, "Driver [%.40s] load failed", name ); + free( driver ); + return NULL; + } + + /* Find the driver in the array of driver types OLD CODE IS CALLED HERE */ + if ((driver_init = lcd_find_init(name)) == NULL) { + /* Driver not found */ + report( RPT_ERR, "Unknown driver [%.40s]", name); + return NULL; + } + driver->init = (int (*)(Driver*,char*)) driver_init; + + /* And store its name and filename */ + driver->name = malloc( strlen( name ) + 1 ); + strcpy( driver->name, name ); + driver->filename = malloc( strlen( filename ) + 1 ); + strcpy( driver->filename, filename ); + + /* Call the init function */ + report( RPT_DEBUG, "Calling driver [%.40s] init function", driver->name ); + res = driver->init( driver, args ); + if( res < 0 ) { + report( RPT_ERR, "Driver [%.40s] init failed, return code < 0", driver->name ); + /* Driver load failed, don't add driver to list + * Free driver structure again + */ + free( driver->name ); + free( driver->filename ); + free( driver ); + return NULL; + } + + /* Check if necesary functions are filled + * SHOULD BE DONE BEFORE CALLING INIT WHEN WE HAVE LOADABLE DRIVERS + */ + if( ! driver_has_obligatory_symbols( driver ) ) { + report( RPT_ERR, "Driver [%.40s] does not have all obligatory symbols", driver->name ); + driver_unload( driver ); + return NULL; + } + debug( RPT_NOTICE, "Driver [%.40s] loaded", driver->name ); + + return driver; +} + + +int +driver_unload( Driver * driver ) +{ + debug( RPT_NOTICE, "Closing driver [%.40s]", driver->name ); + if( driver->close ) + driver->close (driver); + + /* FUTURE: UNLOAD THE LOADED MODULE */ + driver_unbind_module( driver ); + + /* Free its data */ + free( driver->filename ); + free( driver->name ); + free( driver ); + debug( RPT_DEBUG, "Driver unloaded" ); + + return 0; +} + + +int +driver_bind_module( Driver * driver ) +{ + /* Clear the struct, including all functions */ + memset( driver, 0, sizeof(Driver) ); + + /* FUTURE: GET THE SYMBOLS FROM THE DRIVER MODULE */ + + + + /* Add our exported functions */ + + /* Config file functions */ + driver->config_get_bool = config_get_bool; + driver->config_get_int = config_get_int; + driver->config_get_float = config_get_float; + driver->config_get_string = config_get_string; + driver->config_has_section = config_has_section; + driver->config_has_key = config_has_key; + + /* Reporting */ + driver->report = report; + + /* Driver private data */ + driver->store_private_ptr = driver_store_private_ptr; + + /* Display size request */ + driver->request_display_width = request_display_width; + driver->request_display_height = request_display_height; + + return 0; +} + + +int +driver_unbind_module( Driver * driver ) +{ + return 0; +} + + +bool +driver_has_obligatory_symbols( Driver * driver ) +{ + if( driver->api_version == NULL + || driver->stay_in_foreground == NULL + || driver->supports_multiple == NULL ) { + report( RPT_ERR, "Driver [%.40s] misses symbols", driver->name ); + return 0; + } + + if( driver_does_output(driver) + && ( driver->width == NULL + || driver->height == NULL + || driver->clear == NULL + || driver->string == NULL + || driver->chr == NULL )) { + report( RPT_ERR, "Driver [%.40s] does output but misses a obligatory function", driver->name ); + return 0; + } + return 1; +} + + +bool +driver_does_output( Driver * driver ) +{ + return (driver->width != NULL + || driver->height != NULL + || driver->clear != NULL + || driver->string != NULL + || driver->chr != NULL ) ? 1 : 0; +} + + +bool +driver_does_input( Driver * driver ) +{ + return (driver->getkey != NULL + || driver->get_key != NULL ) ? 1 : 0; +} + + +bool +driver_stay_in_foreground( Driver * driver ) +{ + return *driver->stay_in_foreground; +} + + +bool +driver_supports_multiple( Driver * driver ) +{ + return *driver->supports_multiple; +} + + +static int +driver_store_private_ptr(Driver * driver, void * private_data) +{ + report( RPT_INFO, "driver_store_private_ptr( driver=%p, ptr=%p )", driver, private_data ); + + driver->private_data = private_data; + return 0; +} + + +static int +request_display_width() +{ + if( !display_props ) + return 0; + return display_props->width; +} + + +static int +request_display_height() +{ + if( !display_props ) + return 0; + return display_props->height; +} diff --git a/server/driver.h b/server/driver.h new file mode 100644 index 0000000..dfa3c4e --- /dev/null +++ b/server/driver.h @@ -0,0 +1,47 @@ +/* + * driver.h + * This file is part of LCDd, the lcdproc server. + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 2001, Joris Robijn + * + */ + +#ifndef DRIVER_H +#define DRIVER_H + +#include "drivers/lcd.h" + +#define bool int + + +Driver * +driver_load( char * name, char * filename, char * args ); + +int +driver_unload( Driver * driver ); + +int +driver_bind_module( Driver * driver ); + +int +driver_unbind_module( Driver * driver ); + +bool +driver_has_obligatory_symbols( Driver * driver ); + +bool +driver_does_output( Driver * driver ); + +bool +driver_does_input( Driver * driver ); + +bool +driver_support_multiple( Driver * driver ); + +bool +driver_stay_in_foreground( Driver * driver ); + +#endif diff --git a/server/drivers.c b/server/drivers.c index 0469eaa..12f47cd 100644 --- a/server/drivers.c +++ b/server/drivers.c @@ -1,191 +1,462 @@ -/* - * driver.c - * This file is part of LCDd, the lcdproc server. - * - * This file is released under the GNU General Public License. Refer to the - * COPYING file distributed with this package. - * - * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn - * - * - * This code does all driver handling, loading, initializing, unloading. - * - */ - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "shared/LL.h" -#include "shared/report.h" -#include "configfile.h" - -#include "drivers/lcd.h" -// lcd.h is used for the driver API definition - - -LinkedList * loaded_drivers = NULL; - -long int empty_function() { return 0; } - -static int fill_driver_functions( lcd_logical_driver * driver ); - -static int store_private_ptr(struct lcd_logical_driver * driver, void * private_data); - -int -load_driver ( char * name, char * filename, char * args ) -{ - int res; - void (*driver_init)(); - lcd_logical_driver * driver; - - report( RPT_INFO, "load_driver(%s,%s,%s)", name, filename, args ); - - // First driver ? - if( !loaded_drivers ) { - // Create linked list - loaded_drivers = LL_new (); - if( !loaded_drivers ) { - report( RPT_ERR, "Error allocating driver list." ); - return -1; - } - } - - - // Find the driver in the array of driver types - if ((driver_init = (void *) lcd_find_init(name)) == NULL) { - // Driver not found - report( RPT_ERR, "invalid driver: %s", name); - return -1; - } - - - // Allocate memory for new driver struct - driver = malloc( sizeof( lcd_logical_driver )); - //memset( driver, 0, sizeof (lcd_logical_driver )); - - lcd_ptr = driver; - - fill_driver_functions( driver ); - - - // Rebind the init function and call it - driver->init = driver_init; - - res = driver->init( driver, args ); - if( res < 0 ) { - report( RPT_ERR, "Driver load failed, return code < 0" ); - // driver load failed, don't add driver to list - return -1; - } - - // Add driver to list - LL_Push( loaded_drivers, driver ); - - // Check the driver type - if( !driver->daemonize ) { - return 2; - } - - return 1; // We can't see if it's an input driver only... -} - +/* + * drivers.c + * This file is part of LCDd, the lcdproc server. + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 2001, Joris Robijn + * + * + * This code manages the lists of loaded drivers and does actions on all drivers. + * + */ -int -unload_all_drivers () -{ - lcd_logical_driver * driver; - - report( RPT_INFO, "unload_all_driver()"); - - while( (driver = LL_Pop( loaded_drivers )) != NULL ) { - debug( RPT_DEBUG, "driver->close %p", driver ); - driver->close(); - } - - return 0; -} - - -static int -fill_driver_functions( lcd_logical_driver * driver ) -{ - driver->wid = LCD_STD_WIDTH; - driver->hgt = LCD_STD_HEIGHT; - - driver->cellwid = LCD_STD_CELL_WIDTH; - driver->cellhgt = LCD_STD_CELL_HEIGHT; - - driver->framebuf = NULL; - driver->nextkey = NULL; - - driver->daemonize = 1; - - // Set pointers to empty function - - // Basic functions - driver->init = empty_function; - driver->close = empty_function; - - driver->getinfo = empty_function; - // and don't forget other get_* functions later... - - driver->clear = empty_function; - driver->flush = empty_function; - driver->string = empty_function; - driver->chr = empty_function; - - // Extended functions - driver->init_vbar = empty_function; - driver->vbar = empty_function; - driver->init_hbar = empty_function; - driver->hbar = empty_function; - driver->init_num = empty_function; - driver->num = empty_function; - driver->heartbeat = empty_function; - - // Hardware functions - driver->contrast = empty_function; - driver->backlight = empty_function; - driver->output = empty_function; - - // Uesrdef character functions - driver->set_char = empty_function; - driver->icon = empty_function; - - // Key functions - driver->getkey = empty_function; - - // Ancient functions - driver->flush_box = empty_function; - driver->draw_frame = empty_function; - - // Config file functions - driver->config_get_bool = config_get_bool; - driver->config_get_int = config_get_int; - driver->config_get_float = config_get_float; - driver->config_get_string = config_get_string; - driver->config_has_section = config_has_section; - driver->config_has_key = config_has_key; - - // Driver private data - driver->store_private_ptr = store_private_ptr; - - return 0; -} - - -static int -store_private_ptr(struct lcd_logical_driver * driver, void * private_data) -{ - driver->private_data = private_data; - return 0; -} +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "shared/LL.h" +#include "shared/report.h" + +#include "drivers.h" +#include "driver.h" +#include "drivers/lcd.h" +/* lcd.h is used for the driver API definition */ + + +LinkedList * loaded_drivers = NULL; +DisplayProps * display_props = NULL; + +#define ForAllDrivers(drv) for( drv = LL_GetFirst(loaded_drivers); drv; drv = LL_GetNext(loaded_drivers) ) + + +int +drivers_load_driver( char * name, char * filename, char * args ) +{ + Driver * driver; + + report( RPT_INFO, "drivers_load_driver( name=\"%.40s\", filename=\"%.80s\", args=\"%.80s\")", name, filename, args ); + + /* First driver ? */ + if( !loaded_drivers ) { + /* Create linked list */ + loaded_drivers = LL_new (); + if( !loaded_drivers ) { + report( RPT_ERR, "Error allocating driver list." ); + return -1; + } + } + + /* Load the module */ + driver = driver_load( name, filename, args ); + if( driver == NULL ) + /* It failed. The message has already been given by driver_load() */ + return -1; + + /* Add driver to list */ + LL_Push( loaded_drivers, driver ); + + /* If first driver, store display properties */ + if( driver_does_output(driver) && !display_props ) { + if( driver->width(driver) <= 0 || driver->width(driver) > LCD_MAX_WIDTH + || driver->height(driver) <= 0 || driver->height(driver) > LCD_MAX_HEIGHT ) { + report( RPT_ERR, "Driver [%.40s] has invalid display size", driver->name ); + } + + /* Allocate new DisplayProps structure */ + display_props = malloc( sizeof( DisplayProps )); + display_props->width = driver->width(driver); + display_props->height = driver->height(driver); + + if( driver->cellwidth != NULL && display_props->cellwidth > 0 ) + display_props->cellwidth = driver->cellwidth(driver); + else + display_props->cellwidth = LCD_DEFAULT_CELLWIDTH; + + if( driver->cellheight != NULL && driver->cellheight(driver) > 0 ) + display_props->cellheight = driver->cellheight(driver); + else + display_props->cellheight = LCD_DEFAULT_CELLHEIGHT; + } + + /* Return the driver type */ + if( driver_does_output(driver) ) { + if( driver_stay_in_foreground(driver) ) + return 2; + else + return 1; + } + return 0; +} + + +int +drivers_unload_all() +{ + Driver * driver; + + report( RPT_INFO, "unload_all_driver()"); + + while( (driver = LL_Pop( loaded_drivers )) != NULL ) { + driver_unload( driver ); + } + + return 0; +} + + +char * +drivers_get_info() +{ + Driver *drv; + + report( RPT_INFO, "drivers_getinfo()" ); + + ForAllDrivers(drv) { + if( drv->get_info ) { + return drv->get_info( drv ); + } + } + return ""; +} + + +void +drivers_clear() +{ + Driver *drv; + + report( RPT_INFO, "drivers_clear()" ); + + ForAllDrivers(drv) { + if( drv->clear ) + drv->clear( drv ); + } +} + + +void +drivers_flush() +{ + Driver *drv; + + report( RPT_INFO, "drivers_flush()" ); + + ForAllDrivers(drv) { + if( drv->flush ) + drv->flush( drv ); + } +} + + +void +drivers_string( int x, int y, char * string ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_string( x=%d, y=%d, string=\"%.40s\" )", x, y, string ); + + ForAllDrivers(drv) { + if( drv->string ) + drv->string( drv, x, y, string ); + } +} + + +void +drivers_chr( int x, int y, char c ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_chr( x=%d, y=%d, c='%c' )", x, y, c ); + + ForAllDrivers(drv) { + if( drv->chr ) + drv->chr( drv, x, y, c ); + } +} + + +void +drivers_init_vbar() /* TO BE REMOVED */ +{ + Driver *drv; + + report( RPT_INFO, "drivers_init_vbar()" ); + + ForAllDrivers(drv) { + if( drv->init_vbar ) + drv->init_vbar(drv); + } +} + + +void +drivers_init_hbar() /* TO BE REMOVED */ +{ + Driver *drv; + + report( RPT_INFO, "drivers_init_hbar()" ); + + ForAllDrivers(drv) { + if( drv->init_hbar ) + drv->init_hbar(drv); + } +} + + +void +drivers_init_num() /* TO BE REMOVED */ +{ + Driver *drv; + + report( RPT_INFO, "drivers_init_num()" ); + + ForAllDrivers(drv) { + if( drv->init_num ) + drv->init_num( drv ); + } +} + + +void +drivers_vbar( int x, int y, int len, int promille, int pattern ) +{ + Driver *drv; + + int old_len; + + report( RPT_INFO, "drivers_vbar( x=%d, y=%d, len=%d, promille=%d, pattern=%d )", x, y, len, promille, pattern ); + + /* NEW FUNCTIONS + * + * We need more data in the widget. Requires language update... + */ + + + ForAllDrivers(drv) { + if( drv->vbar ) { + drv->vbar( drv, x, y, len, promille, pattern ); + } + } + + /* OLD FUNCTIONS + * + * We need to convert the bar lengths, because the displays can + * have different pixels per char + */ + + old_len = (long) - display_props->cellheight * len * promille / 1000; + + ForAllDrivers(drv) { + if( drv->old_vbar ) { + drv->old_vbar( drv, x, old_len ); + } + } + +} + + +void +drivers_hbar( int x, int y, int len, int promille, int pattern ) +{ + Driver *drv; + int old_len; + + report( RPT_INFO, "drivers_hbar( x=%d, y=%d, len=%d, promille=%d, pattern=%d )", x, y, len, promille, pattern ); + + /* NEW FUNCTIONS */ + + ForAllDrivers(drv) { + if( drv->hbar ) { + drv->hbar( drv, x, y, len, promille, pattern ); + } + } + + /* OLD FUNCTIONS + * + * We need to convert the bar lengths, because the displays can + * have different pixels per char + */ + + old_len = (long) display_props->cellwidth * len * promille / 1000; + + ForAllDrivers(drv) { + if( drv->old_hbar ) { + drv->old_hbar( drv, x, y, old_len ); + } + } +} + + +void +drivers_num( int x, int num ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_num( x=%d, num=%d )", x, num ); + + ForAllDrivers(drv) { + if( drv->num ) + drv->num( drv, x, num ); + } +} + + +void +drivers_heartbeat( int state ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_heartbeat( state=%d )", state ); + + ForAllDrivers(drv) { + if( drv->heartbeat ) + drv->heartbeat( drv, state ); + } +} + + +void +drivers_icon( int x, int y, int icon ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_icon( x=%d, y=%d, icon=%d )", x, y, icon ); + + ForAllDrivers(drv) { + if( drv->icon ) + drv->icon( drv, x, y, icon ); + } +} + + +void +drivers_set_char( char ch, char *dat ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_set_char( ch=%d, dat=%p )", ch, dat ); + + ForAllDrivers(drv) { + if( drv->set_char ) + drv->set_char( drv, ch, dat ); + } +} + + +int +drivers_get_contrast() +{ + Driver *drv; + int res; + + report( RPT_INFO, "drivers_get_contrast()" ); + + ForAllDrivers(drv) { + if( drv->get_contrast ) { + res = drv->get_contrast( drv ); + report( RPT_INFO, "Driver [%.40s] gave contrast value %d", drv->name, res ); + return res; + } + } + report( RPT_INFO, "Did not get any contrast value" ); + return -1; +} + + +void +drivers_set_contrast( int promille ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_contrast( contrast=%d )", promille ); + + ForAllDrivers(drv) { + if( drv->set_contrast ) + drv->set_contrast( drv, promille ); + } +} + + +void +drivers_backlight( int brightness ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_backlight( brightness=%d )", brightness ); + + ForAllDrivers(drv) { + if( drv->backlight ) + drv->backlight( drv, brightness ); + } +} + + +void +drivers_output( int state ) +{ + Driver *drv; + + report( RPT_INFO, "drivers_output( state=%d )", state ); + + ForAllDrivers(drv) { + if( drv->output ) + drv->output( drv, state ); + } +} + + +char * +drivers_get_key() +{ + /* Find the first input keystroke, if any */ + Driver *drv; + char * keystroke; + + report( RPT_INFO, "drivers_get_key()" ); + + ForAllDrivers(drv) { + if( drv->get_key ) { + keystroke = drv->get_key( drv ); + if( keystroke != NULL ) { + report( RPT_INFO, "Driver [%.40s] generated keystroke %.40s", drv->name, keystroke ); + return keystroke; + } + } + } + return NULL; +} + + +char +drivers_getkey() /* TO BE REMOVED AS SOON AS INPUT ROUTINES ACCEPT STRINGS */ +{ + Driver *drv; + char * s; + char ch; + + report( RPT_INFO, "drivers_getkey()" ); + + ForAllDrivers(drv) { + if( drv->get_key ) { + s = drv->get_key(drv); + if( s ) + return s[0]; /* It returns the first char only ! a hack ! */ + } + else if( drv->getkey ) { + ch = drv->getkey(drv); + if( ch ) + return ch; + } + } + return 0; +} diff --git a/server/drivers.h b/server/drivers.h index c024e50..f0da12f 100644 --- a/server/drivers.h +++ b/server/drivers.h @@ -5,18 +5,95 @@ * This file is released under the GNU General Public License. Refer to the * COPYING file distributed with this package. * - * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn + * Copyright (c) 2001, Joris Robijn * */ -int -load_driver( char * name, char * filename, char * args ); -// returns: -// <0 error -// 0 ok, driver is an input driver only -// 1 ok, driver is an output driver -// 2 ok, driver is an output driver that needs to run in the foreground +#ifndef DRIVERS_H +#define DRIVERS_H + +#include "drivers/lcd.h" + +typedef struct DisplayProps { + int width, height; + int cellwidth, cellheight; +} DisplayProps; + +extern DisplayProps * display_props; + +#define bool int + int -unload_all_drivers(); +drivers_load_driver( char * name, char * filename, char * args ); +/* returns: + * <0 error + * 0 ok, driver is an input driver only + * 1 ok, driver is an output driver + * 2 ok, driver is an output driver that needs to run in the foreground + */ + +int +drivers_unload_all(); + +char * +drivers_get_info(); + +void +drivers_clear(); + +void +drivers_flush(); + +void +drivers_string( int x, int y, char * string ); + +void +drivers_chr( int x, int y, char c ); + +void +drivers_init_vbar(); /* TO BE REMOVED */ + +void +drivers_init_hbar(); /* TO BE REMOVED */ + +void +drivers_init_num(); /* TO BE REMOVED */ + +void +drivers_vbar( int x, int y, int len, int promille, int pattern ); + +void +drivers_hbar( int x, int y, int len, int promille, int pattern ); + +void +drivers_num( int x, int num ); + +void +drivers_heartbeat( int state ); + +void +drivers_icon( int x, int y, int icon ); + +void +drivers_set_char( char ch, char *dat ); + +int +drivers_get_contrast(); + +void +drivers_set_contrast( int contrast ); + +void +drivers_backlight( int brightness ); + +void +drivers_output( int state ); + +char * +drivers_get_key(); + +char +drivers_getkey(); + +#endif diff --git a/server/drivers/CFontz.c b/server/drivers/CFontz.c index 1dc6d1a..ccb7542 100644 --- a/server/drivers/CFontz.c +++ b/server/drivers/CFontz.c @@ -35,10 +35,12 @@ #include "lcd.h" #include "CFontz.h" -#include "render.h" +//#include "drv_base.h" +//#include "shared/debug.h" #include "shared/str.h" -#include "shared/report.h" -#include "server/configfile.h" +#include "report.h" +//#include "server/configfile.h" + static int custom = 0; typedef enum { @@ -49,25 +51,36 @@ typedef enum { } custom_type; static int fd; +static char *framebuf = NULL; +static int width = 0; +static int height = 0; +static int cellwidth = DEFAULT_CELL_WIDTH; +static int cellheight = DEFAULT_CELL_HEIGHT; +static int contrast = DEFAULT_CONTRAST; static int brightness = DEFAULT_BRIGHTNESS; static int offbrightness = DEFAULT_OFFBRIGHTNESS; static int newfirmware = 0; +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "CFontz_"; + +// Internal functions static void CFontz_linewrap (int on); static void CFontz_autoscroll (int on); static void CFontz_hidecursor (); static void CFontz_reboot (); -static void CFontz_heartbeat (int type); -// TODO: Get rid of this variable? -lcd_logical_driver *CFontz; + // TODO: Get the frame buffers working right ///////////////////////////////////////////////////////////////// // Opens com port and sets baud correctly... // int -CFontz_init (lcd_logical_driver * driver, char *args) +CFontz_init (Driver * drvthis, char *args) { struct termios portset; int tmp, w, h; @@ -78,57 +91,52 @@ CFontz_init (lcd_logical_driver * driver, char *args) int speed = DEFAULT_SPEED; char size[200] = DEFAULT_SIZE; - CFontz = driver; - - debug(RPT_INFO, "CFontz: init(%p,%s)", driver, args ); - - // TODO: replace DriverName with driver->name when that field exists. - #define DriverName "CFontz" - + debug(RPT_INFO, "CFontz: init(%p,%s)", drvthis, args ); /*Read config file*/ /*Which serial device should be used*/ - strncpy(device, config_get_string ( DriverName , "Device" , 0 , DEFAULT_DEVICE),sizeof(device)); + strncpy(device, drvthis->config_get_string ( drvthis->name , "Device" , 0 , DEFAULT_DEVICE),sizeof(device)); device[sizeof(device)-1]=0; debug (RPT_INFO,"CFontz: Using device: %s", device); /*Which size*/ - strncpy(size, config_get_string ( DriverName , "Size" , 0 , DEFAULT_SIZE),sizeof(size)); + strncpy(size, drvthis->config_get_string ( drvthis->name , "Size" , 0 , DEFAULT_SIZE),sizeof(size)); size[sizeof(size)-1]=0; if( sscanf(size , "%dx%d", &w, &h ) != 2 || (w <= 0) || (w > LCD_MAX_WIDTH) || (h <= 0) || (h > LCD_MAX_HEIGHT)) { report (RPT_WARNING, "CFontz_init: Cannot read size: %s. Using default value.\n", size); sscanf( DEFAULT_SIZE , "%dx%d", &w, &h ); + } else { + width = w; + height = h; } - driver->wid = w; - driver->hgt = h; /*Which contrast*/ - if (0<=config_get_int ( DriverName , "Contrast" , 0 , DEFAULT_CONTRAST) && config_get_int ( DriverName , "Contrast" , 0 , DEFAULT_CONTRAST) <= 255) { - contrast = config_get_int ( DriverName , "Contrast" , 0 , DEFAULT_CONTRAST); + if (0<=drvthis->config_get_int ( drvthis->name , "Contrast" , 0 , DEFAULT_CONTRAST) && drvthis->config_get_int ( drvthis->name , "Contrast" , 0 , DEFAULT_CONTRAST) <= 255) { + contrast = drvthis->config_get_int ( drvthis->name , "Contrast" , 0 , DEFAULT_CONTRAST); } else { report (RPT_WARNING, "CFontz_init: Contrast must between 0 and 255. Using default value.\n"); } /*Which backlight brightness*/ - if (0<=config_get_int ( DriverName , "Brightness" , 0 , DEFAULT_BRIGHTNESS) && config_get_int ( DriverName , "Brightness" , 0 , DEFAULT_BRIGHTNESS) <= 255) { - brightness = config_get_int ( DriverName , "Brightness" , 0 , DEFAULT_BRIGHTNESS); + if (0<=drvthis->config_get_int ( drvthis->name , "Brightness" , 0 , DEFAULT_BRIGHTNESS) && drvthis->config_get_int ( drvthis->name , "Brightness" , 0 , DEFAULT_BRIGHTNESS) <= 255) { + brightness = drvthis->config_get_int ( drvthis->name , "Brightness" , 0 , DEFAULT_BRIGHTNESS); } else { report (RPT_WARNING, "CFontz_init: Brightness must between 0 and 255. Using default value.\n"); } /*Which backlight-off "brightness"*/ - if (0<=config_get_int ( DriverName , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS) && config_get_int ( DriverName , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS) <= 255) { - offbrightness = config_get_int ( DriverName , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS); + if (0<=drvthis->config_get_int ( drvthis->name , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS) && drvthis->config_get_int ( drvthis->name , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS) <= 255) { + offbrightness = drvthis->config_get_int ( drvthis->name , "OffBrightness" , 0 , DEFAULT_OFFBRIGHTNESS); } else { report (RPT_WARNING, "CFontz_init: OffBrightness must between 0 and 255. Using default value.\n"); } /*Which speed*/ - tmp = config_get_int ( DriverName , "Speed" , 0 , DEFAULT_SPEED); + tmp = drvthis->config_get_int ( drvthis->name , "Speed" , 0 , DEFAULT_SPEED); if (tmp == 1200) speed = B1200; else if (tmp == 2400) speed = B2400; else if (tmp == 9600) speed = B9600; @@ -136,12 +144,12 @@ CFontz_init (lcd_logical_driver * driver, char *args) } /*New firmware version?*/ - if(config_get_bool( DriverName , "NewFirmware" , 0 , 0)) { + if(drvthis->config_get_bool( drvthis->name , "NewFirmware" , 0 , 0)) { newfirmware = 1; } /*Reboot display?*/ - if (config_get_bool( DriverName , "Reboot" , 0 , 0)) { + if (drvthis->config_get_bool( drvthis->name , "Reboot" , 0 , 0)) { report (RPT_INFO, "LCDd: rebooting CrystalFontz LCD...\n"); reboot = 1; } @@ -178,10 +186,8 @@ CFontz_init (lcd_logical_driver * driver, char *args) tcsetattr (fd, TCSANOW, &portset); // Make sure the frame buffer is there... - if (!CFontz->framebuf) - CFontz->framebuf = (unsigned char *) - malloc (CFontz->wid * CFontz->hgt); - memset (CFontz->framebuf, ' ', CFontz->wid * CFontz->hgt); + framebuf = (unsigned char *) malloc (width * height); + memset (framebuf, ' ', width * height); // Set display-specific stuff.. if (reboot) { @@ -193,84 +199,107 @@ CFontz_init (lcd_logical_driver * driver, char *args) CFontz_hidecursor (); CFontz_linewrap (1); CFontz_autoscroll (0); - CFontz_backlight (backlight_brightness); + //CFontz_backlight (drvthis, backlight_brightness); // render.c variables should not be used in drivers ! - // Set the functions the driver supports... + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->clear = CFontz_clear; - driver->string = CFontz_string; - driver->chr = CFontz_chr; - driver->vbar = CFontz_vbar; - driver->init_vbar = CFontz_init_vbar; - driver->hbar = CFontz_hbar; - driver->init_hbar = CFontz_init_hbar; - driver->num = CFontz_num; + // Set the functions the driver supports - driver->init = CFontz_init; - driver->close = CFontz_close; - driver->flush = CFontz_flush; - driver->flush_box = CFontz_flush_box; - driver->contrast = CFontz_contrast; - driver->backlight = CFontz_backlight; - driver->set_char = CFontz_set_char; - driver->icon = CFontz_icon; - driver->draw_frame = CFontz_draw_frame; + drvthis->clear = CFontz_clear; + drvthis->string = CFontz_string; + drvthis->chr = CFontz_chr; + drvthis->old_vbar = CFontz_vbar; + drvthis->init_vbar = CFontz_init_vbar; + drvthis->old_hbar = CFontz_hbar; + drvthis->init_hbar = CFontz_init_hbar; + drvthis->num = CFontz_num; - CFontz_contrast (contrast); + drvthis->init = CFontz_init; + drvthis->close = CFontz_close; + drvthis->flush = CFontz_flush; + drvthis->get_contrast = CFontz_get_contrast; + drvthis->set_contrast = CFontz_set_contrast; + drvthis->backlight = CFontz_backlight; + drvthis->set_char = CFontz_set_char; + drvthis->old_icon = CFontz_icon; + drvthis->heartbeat = CFontz_heartbeat; - driver->cellwid = DEFAULT_CELL_WIDTH; - driver->cellhgt = DEFAULT_CELL_HEIGHT; + CFontz_set_contrast (drvthis, contrast); - driver->heartbeat = CFontz_heartbeat; report (RPT_DEBUG, "CFontz_init: done\n"); - return fd; + return 0; } ///////////////////////////////////////////////////////////////// // Clean-up // -void -CFontz_close () +MODULE_EXPORT void +CFontz_close (Driver * drvthis) { close (fd); - if (CFontz->framebuf) - free (CFontz->framebuf); - - CFontz->framebuf = NULL; + if(framebuf) free (framebuf); + framebuf = NULL; } -void -CFontz_flush () +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +CFontz_width (Driver *drvthis) { - CFontz_draw_frame (CFontz->framebuf); + return width; } -void -CFontz_flush_box (int lft, int top, int rgt, int bot) +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +CFontz_height (Driver *drvthis) { - int y; - char out[LCD_MAX_WIDTH]; + return height; +} -// printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot); +////////////////////////////////////////////////////////////////// +// Flushes all output to the lcd... +// +MODULE_EXPORT void +CFontz_flush (Driver * drvthis) +{ + char out[LCD_MAX_WIDTH * LCD_MAX_HEIGHT]; + int i; - for (y = top; y <= bot; y++) { - snprintf (out, sizeof(out), "%c%c%c", 17, lft, y); - write (fd, out, 4); - write (fd, CFontz->framebuf + (y * CFontz->wid) + lft, rgt - lft + 1); + // Custom characters start at 128, not at 0. + /* + for(i=0; i= 0) framebuf[i] += 128; + } + */ + for (i = 0; i < height; i++) { + snprintf (out, sizeof(out), "%c%c%c", 17, 0, i); + write (fd, out, 3); + write (fd, framebuf + (width * i), width); } - + /* + snprintf(out, sizeof(out), "%c", 1); + write(fd, out, 1); + write(fd, framebuf, width*height); + */ } ///////////////////////////////////////////////////////////////// // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -CFontz_chr (int x, int y, char c) +MODULE_EXPORT void +CFontz_chr (Driver * drvthis, int x, int y, char c) { y--; x--; @@ -280,38 +309,51 @@ CFontz_chr (int x, int y, char c) // For V2 of the firmware to get the block to display right if (newfirmware && c==-1) { - c=214; + c=214; } - CFontz->framebuf[(y * CFontz->wid) + x] = c; + framebuf[(y * width) + x] = c; +} + +///////////////////////////////////////////////////////////////// +// Returns current contrast +// This is only the locally stored contrast, the contrast value +// cannot be retrieved from the LCD. +// Value 0 to 1000. +// +MODULE_EXPORT int +CFontz_get_contrast (Driver * drvthis) +{ + return contrast; } ///////////////////////////////////////////////////////////////// // Changes screen contrast (0-255; 140 seems good) +// Value 0 to 100. // -int -CFontz_contrast (int contrast) +MODULE_EXPORT void +CFontz_set_contrast (Driver * drvthis, int promille) { - int realcontrast; char out[4]; - static int status = 140; - if (contrast > 0) { - status = contrast; - realcontrast = (((int) (status)) * 100) / 255; - snprintf (out, sizeof(out), "%c%c", 15, realcontrast); - write (fd, out, 3); - } + // Check it + if( promille < 0 || promille > 1000 ) + return; - return status; + // Store it + contrast = promille; + + // And do it + snprintf (out, sizeof(out), "%c%c", 15, (unsigned char) (promille / 10) ); // converted to be 0 to 100 + write (fd, out, 3); } ///////////////////////////////////////////////////////////////// // Sets the backlight on or off -- can be done quickly for // an intermediate brightness... // -void -CFontz_backlight (int on) +MODULE_EXPORT void +CFontz_backlight (Driver * drvthis, int on) { char out[4]; if (on) { @@ -375,8 +417,8 @@ CFontz_reboot () ///////////////////////////////////////////////////////////////// // Sets up for vertical bars. Call before CFontz->vbar() // -void -CFontz_init_vbar () +MODULE_EXPORT void +CFontz_init_vbar (Driver * drvthis) { char a[] = { 0, 0, 0, 0, 0, 0, @@ -450,13 +492,13 @@ CFontz_init_vbar () }; if (custom != vbar) { - CFontz_set_char (1, a); - CFontz_set_char (2, b); - CFontz_set_char (3, c); - CFontz_set_char (4, d); - CFontz_set_char (5, e); - CFontz_set_char (6, f); - CFontz_set_char (7, g); + CFontz_set_char (drvthis, 1, a); + CFontz_set_char (drvthis, 2, b); + CFontz_set_char (drvthis, 3, c); + CFontz_set_char (drvthis, 4, d); + CFontz_set_char (drvthis, 5, e); + CFontz_set_char (drvthis, 6, f); + CFontz_set_char (drvthis, 7, g); custom = vbar; } } @@ -464,8 +506,8 @@ CFontz_init_vbar () ///////////////////////////////////////////////////////////////// // Inits horizontal bars... // -void -CFontz_init_hbar () +MODULE_EXPORT void +CFontz_init_hbar (Driver * drvthis) { char a[] = { @@ -530,12 +572,12 @@ CFontz_init_hbar () }; if (custom != hbar) { - CFontz_set_char (1, a); - CFontz_set_char (2, b); - CFontz_set_char (3, c); - CFontz_set_char (4, d); - CFontz_set_char (5, e); - CFontz_set_char (6, f); + CFontz_set_char (drvthis, 1, a); + CFontz_set_char (drvthis, 2, b); + CFontz_set_char (drvthis, 3, c); + CFontz_set_char (drvthis, 4, d); + CFontz_set_char (drvthis, 5, e); + CFontz_set_char (drvthis, 6, f); custom = hbar; } } @@ -543,19 +585,19 @@ CFontz_init_hbar () ///////////////////////////////////////////////////////////////// // Draws a vertical bar... // -void -CFontz_vbar (int x, int len) +MODULE_EXPORT void +CFontz_vbar (Driver * drvthis, int x, int len) { char map[9] = { 32, 1, 2, 3, 4, 5, 6, 7, 255 }; int y; - for (y = CFontz->hgt; y > 0 && len > 0; y--) { - if (len >= CFontz->cellhgt) - CFontz_chr (x, y, 255); + for (y = height; y > 0 && len > 0; y--) { + if (len >= cellheight) + CFontz_chr (drvthis, x, y, 255); else - CFontz_chr (x, y, map[len]); + CFontz_chr (drvthis, x, y, map[len]); - len -= CFontz->cellhgt; + len -= cellheight; } } @@ -563,18 +605,18 @@ CFontz_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void -CFontz_hbar (int x, int y, int len) +MODULE_EXPORT void +CFontz_hbar (Driver * drvthis, int x, int y, int len) { char map[7] = { 32, 1, 2, 3, 4, 5, 6 }; - for (; x <= CFontz->wid && len > 0; x++) { - if (len >= CFontz->cellwid) - CFontz_chr (x, y, map[6]); + for (; x <= width && len > 0; x++) { + if (len >= cellwidth) + CFontz_chr (drvthis, x, y, map[6]); else - CFontz_chr (x, y, map[len]); + CFontz_chr (drvthis, x, y, map[len]); - len -= CFontz->cellwid; + len -= cellwidth; } @@ -584,8 +626,8 @@ CFontz_hbar (int x, int y, int len) ///////////////////////////////////////////////////////////////// // Writes a big number. // -void -CFontz_num (int x, int num) +MODULE_EXPORT void +CFontz_num (Driver * drvthis, int x, int num) { char out[5]; snprintf (out, sizeof(out), "%c%c%c", 28, x, num); @@ -599,8 +641,8 @@ CFontz_num (int x, int num) // // The input is just an array of characters... // -void -CFontz_set_char (int n, char *dat) +MODULE_EXPORT void +CFontz_set_char (Driver * drvthis, int n, char *dat) { char out[4]; int row, col; @@ -614,18 +656,18 @@ CFontz_set_char (int n, char *dat) snprintf (out, sizeof(out), "%c%c", 25, n); write (fd, out, 2); - for (row = 0; row < CFontz->cellhgt; row++) { + for (row = 0; row < cellheight; row++) { letter = 0; - for (col = 0; col < CFontz->cellwid; col++) { + for (col = 0; col < cellheight; col++) { letter <<= 1; - letter |= (dat[(row * CFontz->cellwid) + col] > 0); + letter |= (dat[(row * cellheight) + col] > 0); } write (fd, &letter, 1); } } -void -CFontz_icon (int which, char dest) +MODULE_EXPORT void +CFontz_icon (Driver * drvthis, int which, char dest) { char icons[3][6 * 8] = { { @@ -665,51 +707,16 @@ CFontz_icon (int which, char dest) if (custom == bign) custom = beat; - CFontz_set_char (dest, &icons[which][0]); -} - -///////////////////////////////////////////////////////////// -// Blasts a single frame onscreen, to the lcd... -// -// Input is a character array, sized CFontz->wid*CFontz->hgt -// -void -CFontz_draw_frame (char *dat) -{ - char out[LCD_MAX_WIDTH * LCD_MAX_HEIGHT]; - int i; - - if (!dat) - return; - - // Custom characters start at 128, not at 0. - /* - for(i=0; iwid*CFontz->hgt; i++) - { - if(dat[i] < 32 && dat[i] >= 0) dat[i] += 128; - } - */ - - for (i = 0; i < CFontz->hgt; i++) { - snprintf (out, sizeof(out), "%c%c%c", 17, 0, i); - write (fd, out, 3); - write (fd, dat + (CFontz->wid * i), CFontz->wid); - } - /* - snprintf(out, sizeof(out), "%c", 1); - write(fd, out, 1); - write(fd, dat, CFontz->wid*CFontz->hgt); - */ - + CFontz_set_char (drvthis, dest, &icons[which][0]); } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -CFontz_clear () +MODULE_EXPORT void +CFontz_clear (Driver * drvthis) { - memset (CFontz->framebuf, ' ', CFontz->wid * CFontz->hgt); + memset (framebuf, ' ', width * height); } @@ -717,8 +724,8 @@ CFontz_clear () // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -CFontz_string (int x, int y, char string[]) +MODULE_EXPORT void +CFontz_string (Driver * drvthis, int x, int y, char string[]) { int i; @@ -727,7 +734,7 @@ CFontz_string (int x, int y, char string[]) for (i = 0; string[i]; i++) { - + // For V2 of the firmware to get the block to display right if (newfirmware && string[i]==-1) { string[i]=214; @@ -735,17 +742,17 @@ CFontz_string (int x, int y, char string[]) // Check for buffer overflows... - if ((y * CFontz->wid) + x + i > (CFontz->wid * CFontz->hgt)) + if ((y * width) + x + i > (width * height)) break; - CFontz->framebuf[(y * CFontz->wid) + x + i] = string[i]; + framebuf[(y * width) + x + i] = string[i]; } } ///////////////////////////////////////////////////////////// // Does the heartbeat... // -static void -CFontz_heartbeat (int type) +MODULE_EXPORT void +CFontz_heartbeat (Driver *drvthis, int type) { static int timer = 0; int whichIcon; @@ -760,13 +767,13 @@ CFontz_heartbeat (int type) // This defines a custom character EVERY time... // not efficient... is this necessary? - CFontz_icon (whichIcon, 0); + CFontz_icon (drvthis, whichIcon, 0); // Put character on screen... - CFontz_chr (CFontz->wid, 1, 0); + CFontz_chr (drvthis, width, 1, 0); // change display... - CFontz_flush (); + CFontz_flush (drvthis); } timer++; diff --git a/server/drivers/CFontz.h b/server/drivers/CFontz.h index 11f97eb..a47bc0b 100644 --- a/server/drivers/CFontz.h +++ b/server/drivers/CFontz.h @@ -1,34 +1,40 @@ #ifndef CFONTZ_H #define CFONTZ_H -extern lcd_logical_driver *CFontz; - -int CFontz_init (lcd_logical_driver * driver, char *device); -void CFontz_close (); -void CFontz_flush (); -void CFontz_flush_box (int lft, int top, int rgt, int bot); -void CFontz_chr (int x, int y, char c); -int CFontz_contrast (int contrast); -void CFontz_backlight (int on); -void CFontz_init_vbar (); -void CFontz_init_hbar (); -void CFontz_vbar (int x, int len); -void CFontz_hbar (int x, int y, int len); -void CFontz_init_num (); -void CFontz_num (int x, int num); -void CFontz_set_char (int n, char *dat); -void CFontz_icon (int which, char dest); -void CFontz_draw_frame (char *dat); -void CFontz_clear (void); -void CFontz_string (int x, int y, char string[]); +#include "lcd.h" #define DEFAULT_CELL_WIDTH 6 #define DEFAULT_CELL_HEIGHT 8 -#define DEFAULT_CONTRAST 140 +#define DEFAULT_CONTRAST 560 #define DEFAULT_DEVICE "/dev/lcd" #define DEFAULT_SPEED B9600 #define DEFAULT_BRIGHTNESS 60 #define DEFAULT_OFFBRIGHTNESS 0 #define DEFAULT_SIZE "20x4" + + int CFontz_init (Driver * drvthis, char *device); +MODULE_EXPORT void CFontz_close (Driver * drvthis); +MODULE_EXPORT int CFontz_width (Driver * drvthis); +MODULE_EXPORT int CFontz_height (Driver * drvthis); +MODULE_EXPORT void CFontz_clear (Driver * drvthis); +MODULE_EXPORT void CFontz_flush (Driver * drvthis); +MODULE_EXPORT void CFontz_string (Driver * drvthis, int x, int y, char string[]); +MODULE_EXPORT void CFontz_chr (Driver * drvthis, int x, int y, char c); + +MODULE_EXPORT void CFontz_vbar (Driver * drvthis, int x, int len); +MODULE_EXPORT void CFontz_hbar (Driver * drvthis, int x, int y, int len); +MODULE_EXPORT void CFontz_num (Driver * drvthis, int x, int num); +MODULE_EXPORT void CFontz_heartbeat (Driver *drvthis, int type); +MODULE_EXPORT void CFontz_icon (Driver * drvthis, int which, char dest); + +MODULE_EXPORT void CFontz_set_char (Driver * drvthis, int n, char *dat); + +MODULE_EXPORT int CFontz_get_contrast (Driver * drvthis); +MODULE_EXPORT void CFontz_set_contrast (Driver * drvthis, int contrast); +MODULE_EXPORT void CFontz_backlight (Driver * drvthis, int on); + +MODULE_EXPORT void CFontz_init_vbar (Driver * drvthis); +MODULE_EXPORT void CFontz_init_hbar (Driver * drvthis); + #endif diff --git a/server/drivers/MtxOrb.c b/server/drivers/MtxOrb.c index 234474d..b112b6a 100644 --- a/server/drivers/MtxOrb.c +++ b/server/drivers/MtxOrb.c @@ -25,11 +25,10 @@ # include "config.h" #endif -#include "render.h" #include "lcd.h" #include "lcd_lib.h" #include "MtxOrb.h" -#include "drv_base.h" +//#include "drv_base.h" // I don't want to break anything here so let's do it step by step //#define USE_REPORT @@ -42,6 +41,7 @@ #endif #include "shared/str.h" +#include "input.h" #define IS_LCD_DISPLAY (MtxOrb_type == MTXORB_LCD) #define IS_LKD_DISPLAY (MtxOrb_type == MTXORB_LKD) @@ -107,44 +107,29 @@ static int clear = 1; static int def[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static int use[9] = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; -static void MtxOrb_linewrap (int on); -static void MtxOrb_autoscroll (int on); -static void MtxOrb_cursorblink (int on); -static void MtxOrb_string (int x, int y, char *string); +static char *framebuf = NULL; +static int width = LCD_DEFAULT_WIDTH; +static int height = LCD_DEFAULT_HEIGHT; +static int cellwidth = LCD_DEFAULT_CELLWIDTH; +static int cellheight = LCD_DEFAULT_CELLHEIGHT; +static int contrast = DEFAULT_CONTRAST; -/* - * This does not belong to MtxOrb.h except if used externaly - * Having them here reduce the number of warning. - */ -static void MtxOrb_clear (); -static void MtxOrb_close (); -static void MtxOrb_flush (); -static void MtxOrb_flush_box (int lft, int top, int rgt, int bot); -static void MtxOrb_chr (int x, int y, char c); -static int MtxOrb_contrast (int contrast); -static void MtxOrb_backlight (int on); -static void MtxOrb_output (int on); -static void MtxOrb_init_vbar (); -static void MtxOrb_init_hbar (); -static void MtxOrb_vbar (int x, int len); -static void MtxOrb_hbar (int x, int y, int len); -static void MtxOrb_init_num (); -static void MtxOrb_num (int x, int num); -static void MtxOrb_set_char (int n, char *dat); -static void MtxOrb_icon (int which, char dest); -static void MtxOrb_draw_frame (char *dat); -static char MtxOrb_getkey (); -static char * MtxOrb_getinfo (); -static void MtxOrb_heartbeat (int type); -static int MtxOrb_ask_bar (int type); -static void MtxOrb_set_known_char (int car, int type); -/* - * End of what was in MtxOrb.h - */ +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "MtxOrb_"; + + +static int MtxOrb_ask_bar (Driver *drvthis, int type); +static void MtxOrb_set_known_char (Driver * drvthis, int car, int type); +static void MtxOrb_linewrap (Driver *drvthis, int on); +static void MtxOrb_autoscroll (Driver *drvthis, int on); +static void MtxOrb_cursorblink (Driver *drvthis, int on); // Very private function that clear internal definition. static void -MtxOrb_clear_custom () +MtxOrb_clear_custom (Driver *drvthis) { int pos; @@ -155,7 +140,7 @@ MtxOrb_clear_custom () } static int -MtxOrb_set_type (char * str) { +MtxOrb_parse_type (char * str) { char c; c = str[0]; @@ -182,7 +167,7 @@ MtxOrb_set_type (char * str) { } static int -MtxOrb_get_speed (char *arg) { +MtxOrb_parse_speed (char *arg) { int speed; switch (atoi(arg)) { @@ -218,7 +203,7 @@ MtxOrb_usage (void) { } int -MtxOrb_set_contrast (char * str) { +MtxOrb_parse_contrast (char * str) { int contrast; contrast = atoi (str); @@ -229,8 +214,6 @@ MtxOrb_set_contrast (char * str) { return contrast; } -// TODO: Get rid of this variable? Probably not... -lcd_logical_driver *MtxOrb; // set by MtxOrb_init(); doesn't seem to be used anywhere // TODO: Get the frame buffers working right ///////////////////////////////////////////////////////////////// @@ -239,7 +222,7 @@ lcd_logical_driver *MtxOrb; // set by MtxOrb_init(); doesn't seem to be used any // Called to initialize driver settings // int -MtxOrb_init (lcd_logical_driver * driver, char *args) +MtxOrb_init (Driver *drvthis, char *args) { char *argv[64]; // Notice: 64 arguments - overflows? int argc; @@ -254,8 +237,6 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) MtxOrb_type = MTXORB_LKD; // Assume it's an LCD w/keypad - MtxOrb = driver; - //debug("MtxOrb_init: Args(all): %s\n", args); argc = get_args (argv, args, 64); @@ -274,16 +255,16 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) strncpy(device, optarg, sizeof(device)); break; case 's': - speed = MtxOrb_get_speed(optarg); + speed = MtxOrb_parse_speed(optarg); break; case 'c': - contrast = MtxOrb_set_contrast(optarg); + contrast = MtxOrb_parse_contrast(optarg); break; case 'h': MtxOrb_usage(); return -1; case 't': - MtxOrb_set_type(optarg); + MtxOrb_type = MtxOrb_parse_type(optarg); default: MtxOrb_usage(); return -1; @@ -312,14 +293,14 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) fprintf (stderr, "MtxOrb_init: %s requires an argument\n", argv[i]); return -1; } - contrast = MtxOrb_set_contrast (argv[++i]); + contrast = MtxOrb_parse_contrast (argv[++i]); break; case 's': if (i + 1 > argc) { fprintf (stderr, "MtxOrb_init: %s requires an argument\n", argv[i]); return -1; } - speed = MtxOrb_get_speed (argv[++i]); + speed = MtxOrb_parse_speed (argv[++i]); break; case 'h': MtxOrb_usage(); @@ -348,8 +329,8 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) hgt = (*p - '0'); - MtxOrb->wid = wid; - MtxOrb->hgt = hgt; + width = wid; + height = hgt; } break; case 'b': @@ -358,7 +339,7 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) return -1; } i++; - MtxOrb_type = MtxOrb_set_type(argv[i]); + MtxOrb_type = MtxOrb_parse_type(argv[i]); break; default: printf ("Invalid parameter: %s\n", argv[i]); @@ -408,54 +389,61 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) tcsetattr (fd, TCSANOW, &portset); // Make sure the frame buffer is there... - if (!MtxOrb->framebuf) - MtxOrb->framebuf = (unsigned char *) - malloc (MtxOrb->wid * MtxOrb->hgt); - memset (MtxOrb->framebuf, ' ', MtxOrb->wid * MtxOrb->hgt); + if (!framebuf) + framebuf = (unsigned char *) + malloc (width * height); + memset (framebuf, ' ', width * height); /* * Configure display */ - MtxOrb_linewrap (DEFAULT_LINEWRAP); - MtxOrb_autoscroll (DEFAULT_AUTOSCROLL); - MtxOrb_cursorblink (DEFAULT_CURSORBLINK); - MtxOrb_contrast (contrast); + MtxOrb_linewrap (drvthis, DEFAULT_LINEWRAP); + MtxOrb_autoscroll (drvthis, DEFAULT_AUTOSCROLL); + MtxOrb_cursorblink (drvthis, DEFAULT_CURSORBLINK); + MtxOrb_set_contrast (drvthis, contrast); /* * Configure the display functions */ - driver->clear = MtxOrb_clear; - driver->string = MtxOrb_string; - driver->chr = MtxOrb_chr; - driver->vbar = MtxOrb_vbar; - driver->init_vbar = MtxOrb_init_vbar; - driver->hbar = MtxOrb_hbar; - driver->init_hbar = MtxOrb_init_hbar; - driver->num = MtxOrb_num; - driver->init_num = MtxOrb_init_num; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->init = MtxOrb_init; - driver->close = MtxOrb_close; - driver->flush = MtxOrb_flush; - driver->flush_box = MtxOrb_flush_box; - driver->contrast = MtxOrb_contrast; - driver->backlight = MtxOrb_backlight; - driver->output = MtxOrb_output; - driver->set_char = MtxOrb_set_char; - driver->icon = MtxOrb_icon; - driver->draw_frame = MtxOrb_draw_frame; + // Set the functions the driver supports + drvthis->clear = MtxOrb_clear; + drvthis->string = MtxOrb_string; + drvthis->chr = MtxOrb_chr; + drvthis->old_vbar = MtxOrb_vbar; + drvthis->init_vbar = MtxOrb_init_vbar; + drvthis->old_hbar = MtxOrb_hbar; + drvthis->init_hbar = MtxOrb_init_hbar; + drvthis->num = MtxOrb_num; + drvthis->init_num = MtxOrb_init_num; - driver->getkey = MtxOrb_getkey; - driver->getinfo = MtxOrb_getinfo; - driver->heartbeat = MtxOrb_heartbeat; + drvthis->init = MtxOrb_init; + drvthis->close = MtxOrb_close; + drvthis->width = MtxOrb_width; + drvthis->height = MtxOrb_height; + drvthis->flush = MtxOrb_flush; + drvthis->get_contrast = MtxOrb_get_contrast; + drvthis->set_contrast = MtxOrb_set_contrast; + drvthis->backlight = MtxOrb_backlight; + drvthis->output = MtxOrb_output; + drvthis->set_char = MtxOrb_set_char; + drvthis->old_icon = MtxOrb_icon; - return fd; + drvthis->getkey = MtxOrb_getkey; + drvthis->get_info = MtxOrb_get_info; + drvthis->heartbeat = MtxOrb_heartbeat; + + return 0; } -#define ValidX(x) if ((x) > MtxOrb->wid) { (x) = MtxOrb->wid; } else (x) = (x) < 1 ? 1 : (x); -#define ValidY(y) if ((y) > MtxOrb->hgt) { (y) = MtxOrb->hgt; } else (y) = (y) < 1 ? 1 : (y); +#define ValidX(x) if ((x) > width) { (x) = width; } else (x) = (x) < 1 ? 1 : (x); +#define ValidY(y) if ((y) > height) { (y) = height; } else (y) = (y) < 1 ? 1 : (y); // TODO: Check this quick hack to detect clear of the screen. ///////////////////////////////////////////////////////////////// @@ -463,11 +451,11 @@ MtxOrb_init (lcd_logical_driver * driver, char *args) // forget bar caracter not in use anymore and reuse the // slot for another bar caracter. // -static void -MtxOrb_clear () +MODULE_EXPORT void +MtxOrb_clear (Driver *drvthis) { - if (MtxOrb->framebuf != NULL) - memset (MtxOrb->framebuf, ' ', (MtxOrb->wid * MtxOrb->hgt)); + if (framebuf != NULL) + memset (framebuf, ' ', (width * height)); //write(fd, "\x0FE" "X", 2); // instant clear... clear = 1; @@ -483,15 +471,14 @@ MtxOrb_clear () ///////////////////////////////////////////////////////////////// // Clean-up // -static void -MtxOrb_close () +MODULE_EXPORT void +MtxOrb_close (Driver *drvthis) { close (fd); - if (MtxOrb->framebuf) - free (MtxOrb->framebuf); - - MtxOrb->framebuf = NULL; + if (framebuf) + free (framebuf); + framebuf = NULL; #ifdef USE_REPORT debug(RPT_DEBUG, "MtxOrb: closed"); @@ -501,8 +488,26 @@ MtxOrb_close () #endif } -static void -MtxOrb_string (int x, int y, char *string) +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +MtxOrb_width (Driver *drvthis) +{ + return width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +MtxOrb_height (Driver *drvthis) +{ + return height; +} + +MODULE_EXPORT void +MtxOrb_string (Driver *drvthis, int x, int y, char *string) { int offset, siz; @@ -510,11 +515,11 @@ MtxOrb_string (int x, int y, char *string) ValidY(y); x--; y--; // Convert 1-based coords to 0-based... - offset = (y * MtxOrb->wid) + x; - siz = (MtxOrb->wid * MtxOrb->hgt) - offset - 1; + offset = (y * width) + x; + siz = (width * height) - offset - 1; siz = siz > strlen(string) ? strlen(string) : siz; - memcpy(MtxOrb->framebuf + offset, string, siz); + memcpy(framebuf + offset, string, siz); #ifdef USE_REPORT debug(RPT_DEBUG, "MtxOrb: printed string at (%d,%d)", x, y); @@ -524,10 +529,65 @@ MtxOrb_string (int x, int y, char *string) #endif } -static void -MtxOrb_flush () +MODULE_EXPORT void +MtxOrb_flush (Driver *drvthis) { - MtxOrb_draw_frame (MtxOrb->framebuf); + char out[12]; + int i,j,mv = 1; + static char *old = NULL; + char *p, *q; + + if (old == NULL) { + old = malloc(width * height); + + write(fd, "\x0FEG\x01\x01", 4); + write(fd, framebuf, width * height); + + strncpy(old, framebuf, width * height); + + return; + + } else { + /* CODE TEMPORARY DISABLED (joris) + UNSURE IF IT STILL WORKS NOW + if (! new_framebuf(drvthis, old)) + return; + */ + } + + p = framebuf; + q = old; + + for (i = 1; i <= height; i++) { + for (j = 1; j <= width; j++) { + + if ((*p == *q) && (*p > 8)) + mv = 1; + else { + // Draw characters that have changed, as well + // as custom characters. We know not if a custom + // character has changed. + + if (mv == 1) { + snprintf(out, sizeof(out), "\x0FEG%c%c", j, i); + write (fd, out, 4); + mv = 0; + } + write (fd, p, 1); + } + p++; + q++; + } + } + + + //for (i = 0; i < height; i++) { + // snprintf (out, sizeof(out), "\x0FEG\x001%c", i + 1); + // write (fd, out, 4); + // write (fd, framebuf + (width * i), width); + //} + + strncpy(old, framebuf, width * height); #ifdef USE_REPORT debug(RPT_DEBUG, "MtxOrb: frame buffer flushed"); @@ -537,33 +597,12 @@ MtxOrb_flush () #endif } -static void -MtxOrb_flush_box (int lft, int top, int rgt, int bot) -{ - int y; - char out[LCD_MAX_WIDTH]; - - for (y = top; y <= bot; y++) { - snprintf (out, sizeof(out), "\x0FEG%c%c", lft, y); - write (fd, out, 4); - write (fd, MtxOrb->framebuf + (y * MtxOrb->wid) + lft, rgt - lft + 1); - -#ifdef USE_REPORT - debug(RPT_DEBUG, "MtxOrb: frame buffer box flushed"); -#else - if (debug_level > 4) - syslog(LOG_DEBUG, "MtxOrb: frame buffer box flushed"); -#endif - } - -} - ///////////////////////////////////////////////////////////////// // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -static void -MtxOrb_chr (int x, int y, char c) +MODULE_EXPORT void +MtxOrb_chr (Driver *drvthis, int x, int y, char c) { #ifdef USE_REPORT #else @@ -584,8 +623,8 @@ MtxOrb_chr (int x, int y, char c) // write to frame buffer y--; x--; // translate to 0-index - offset = (y * MtxOrb->wid) + x; - MtxOrb->framebuf[offset] = c; + offset = (y * width) + x; + framebuf[offset] = c; #ifdef USE_REPORT debug(RPT_DEBUG, "writing character %02X to position (%d,%d)", c, x, y); @@ -601,42 +640,52 @@ MtxOrb_chr (int x, int y, char c) #endif } +MODULE_EXPORT int +MtxOrb_get_contrast (Driver *drvthis) +{ + return contrast; +} + ///////////////////////////////////////////////////////////////// // Changes screen contrast (0-255; 140 seems good) // note: works only for LCD displays // Is it better to use the brightness for VFD/VKD displays ? // -static int -MtxOrb_contrast (int contrast) +MODULE_EXPORT void +MtxOrb_set_contrast (Driver *drvthis, int promille) { char out[4]; + int real_contrast; - // validate contrast value - if (contrast > 255) - contrast = 255; - if (contrast < 0) - contrast = 0; + // Check it + if( promille < 0 || promille > 1000 ) + return; + + // Store it + contrast = promille; + + real_contrast = (int) ((long)promille * 255 / 1000 ); + + // And do it if (IS_LCD_DISPLAY || IS_LKD_DISPLAY) { - snprintf (out, sizeof(out), "\x0FEP%c", contrast); + snprintf (out, sizeof(out), "\x0FEP%c", real_contrast); write (fd, out, 3); #ifdef USE_REPORT - debug(RPT_DEBUG, "MtxOrb: contrast set to %d", contrast); + debug(RPT_DEBUG, "MtxOrb: contrast set to %d", real_contrast); #else if (debug_level > 3) - syslog(LOG_DEBUG, "MtxOrb: contrast set to %d", contrast); + syslog(LOG_DEBUG, "MtxOrb: contrast set to %d", real_contrast); #endif } else { #ifdef USE_REPORT - debug(RPT_DEBUG, "MtxOrb: contrast not set to %d - not LCD or LKD display", contrast); + debug(RPT_DEBUG, "MtxOrb: contrast not set to %d - not LCD or LKD display", real_contrast); #else if (debug_level > 3) - syslog(LOG_DEBUG, "MtxOrb: contrast not set to %d - not LCD or LKD display", contrast); + syslog(LOG_DEBUG, "MtxOrb: contrast not set to %d - not LCD or LKD display", real_contrast); #endif } - - return contrast; } ///////////////////////////////////////////////////////////////// @@ -652,8 +701,8 @@ MtxOrb_contrast (int contrast) #define BACKLIGHT_OFF 0 #define BACKLIGHT_ON 1 -static void -MtxOrb_backlight (int on) +MODULE_EXPORT void +MtxOrb_backlight (Driver *drvthis, int on) { static int backlight_state = 1; @@ -663,7 +712,7 @@ MtxOrb_backlight (int on) backlight_state = on; switch (on) { - case BACKLIGHT_ON: + case BACKLIGHT_ON: write (fd, "\x0FE" "F", 2); #ifdef USE_REPORT debug(RPT_DEBUG, "MtxOrb: backlight turned on"); @@ -672,7 +721,7 @@ MtxOrb_backlight (int on) syslog(LOG_DEBUG, "MtxOrb: backlight turned on"); #endif break; - case BACKLIGHT_OFF: + case BACKLIGHT_OFF: if (IS_VKD_DISPLAY || IS_VFD_DISPLAY) { #ifdef USE_REPORT debug(RPT_DEBUG, "MtxOrb: backlight ignored - not LCD or LKD display"); @@ -707,8 +756,8 @@ MtxOrb_backlight (int on) // displays with keypad have 6 outputs but the one without kepad // have only one output // NOTE: length of command are different -static void -MtxOrb_output (int on) +MODULE_EXPORT void +MtxOrb_output (Driver *drvthis, int on) { char out[5]; static int output_state = -1; @@ -752,7 +801,7 @@ MtxOrb_output (int on) // Toggle the built-in linewrapping feature // static void -MtxOrb_linewrap (int on) +MtxOrb_linewrap (Driver *drvthis, int on) { if (on) { write (fd, "\x0FE" "C", 2); @@ -779,7 +828,7 @@ MtxOrb_linewrap (int on) // Toggle the built-in automatic scrolling feature // static void -MtxOrb_autoscroll (int on) +MtxOrb_autoscroll (Driver *drvthis, int on) { if (on) { write (fd, "\x0FEQ", 2); @@ -807,7 +856,7 @@ MtxOrb_autoscroll (int on) // Toggle cursor blink on/off // static void -MtxOrb_cursorblink (int on) +MtxOrb_cursorblink (Driver *drvthis, int on) { if (on) { write (fd, "\x0FES", 2); @@ -833,8 +882,8 @@ MtxOrb_cursorblink (int on) ///////////////////////////////////////////////////////////////// // Sets up for vertical bars. Call before lcd.vbar() // -static void -MtxOrb_init_vbar () +MODULE_EXPORT void +MtxOrb_init_vbar (Driver *drvthis) { custom = bar; } @@ -842,8 +891,8 @@ MtxOrb_init_vbar () ///////////////////////////////////////////////////////////////// // Inits horizontal bars... // -static void -MtxOrb_init_hbar () +MODULE_EXPORT void +MtxOrb_init_hbar (Driver *drvthis) { custom = bar; } @@ -851,8 +900,8 @@ MtxOrb_init_hbar () ///////////////////////////////////////////////////////////////// // Returns string with general information about the display // -static char * -MtxOrb_getinfo (void) +MODULE_EXPORT char * +MtxOrb_get_info (Driver *drvthis) { char in = 0; static char info[255]; @@ -864,10 +913,10 @@ MtxOrb_getinfo (void) int retval; #ifdef USE_REPORT - debug(RPT_DEBUG, "MtxOrb: getinfo"); + debug(RPT_DEBUG, "MtxOrb: get_info"); #else if (debug_level > 3) - syslog(LOG_DEBUG, "MtxOrb: getinfo"); + syslog(LOG_DEBUG, "MtxOrb: get_info"); #endif memset(info, '\0', sizeof(info)); @@ -983,8 +1032,8 @@ MtxOrb_getinfo (void) // Draws a vertical bar... // This is the new version ussing dynamic icon alocation // -static void -MtxOrb_vbar (int x, int len) +MODULE_EXPORT void +MtxOrb_vbar (Driver *drvthis, int x, int len) { unsigned char mapu[9] = { barw, baru1, baru2, baru3, baru4, baru5, baru6, baru7, barb }; unsigned char mapd[9] = { barw, bard1, bard2, bard3, bard4, bard5, bard6, bard7, barb }; @@ -1003,23 +1052,23 @@ MtxOrb_vbar (int x, int len) // REMOVE THE PREVIOUS LINE FOR TESTING ONLY... if (len > 0) { - for (y = MtxOrb->hgt; y > 0 && len > 0; y--) { - if (len >= MtxOrb->cellhgt) - MtxOrb_chr (x, y, 255); + for (y = height; y > 0 && len > 0; y--) { + if (len >= cellheight) + MtxOrb_chr (drvthis, x, y, 255); else - MtxOrb_chr (x, y, MtxOrb_ask_bar (mapu[len])); + MtxOrb_chr (drvthis, x, y, MtxOrb_ask_bar (drvthis, mapu[len])); - len -= MtxOrb->cellhgt; + len -= cellheight; } } else { len = -len; - for (y = 2; y <= MtxOrb->hgt && len > 0; y++) { - if (len >= MtxOrb->cellhgt) - MtxOrb_chr (x, y, 255); + for (y = 2; y <= height && len > 0; y++) { + if (len >= cellheight) + MtxOrb_chr (drvthis, x, y, 255); else - MtxOrb_chr (x, y, MtxOrb_ask_bar (mapd[len])); + MtxOrb_chr (drvthis, x, y, MtxOrb_ask_bar (drvthis, mapd[len])); - len -= MtxOrb->cellhgt; + len -= cellheight; } } @@ -1030,8 +1079,8 @@ MtxOrb_vbar (int x, int len) // Draws a horizontal bar to the right. // This is the new version ussing dynamic icon alocation // -static void -MtxOrb_hbar (int x, int y, int len) +MODULE_EXPORT void +MtxOrb_hbar (Driver *drvthis, int x, int y, int len) { unsigned char mapr[6] = { barw, barr1, barr2, barr3, barr4, barb }; unsigned char mapl[6] = { barw, barl1, barl2, barl3, barl4, barb }; @@ -1047,24 +1096,24 @@ MtxOrb_hbar (int x, int y, int len) #endif if (len > 0) { - for (; x <= MtxOrb->wid && len > 0; x++) { - if (len >= MtxOrb->cellwid) - MtxOrb_chr (x, y, 255); + for (; x <= width && len > 0; x++) { + if (len >= cellwidth) + MtxOrb_chr (drvthis, x, y, 255); else - MtxOrb_chr (x, y, MtxOrb_ask_bar (mapr[len])); + MtxOrb_chr (drvthis, x, y, MtxOrb_ask_bar (drvthis, mapr[len])); - len -= MtxOrb->cellwid; + len -= cellwidth; } } else { len = -len; for (; x > 0 && len > 0; x--) { - if (len >= MtxOrb->cellwid) - MtxOrb_chr (x, y, 255); + if (len >= cellwidth) + MtxOrb_chr (drvthis, x, y, 255); else - MtxOrb_chr (x, y, MtxOrb_ask_bar (mapl[len])); + MtxOrb_chr (drvthis, x, y, MtxOrb_ask_bar (drvthis, mapl[len])); - len -= MtxOrb->cellwid; + len -= cellwidth; } } @@ -1079,8 +1128,8 @@ MtxOrb_hbar (int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets up for big numbers. // -static void -MtxOrb_init_num () +MODULE_EXPORT void +MtxOrb_init_num (Driver *drvthis) { #ifdef USE_REPORT debug(RPT_DEBUG, "MtxOrb: init for big numbers"); @@ -1092,7 +1141,7 @@ MtxOrb_init_num () if (custom != bign) { write (fd, "\x0FEn", 2); custom = bign; - MtxOrb_clear_custom (); + MtxOrb_clear_custom (drvthis); } } @@ -1106,14 +1155,14 @@ MtxOrb_init_num () // // TODO: Before the desinitive solution we need to make the caracter // hiden behind the hardware bignum dirty so that they get cleaned -// when draw_frame is called. There is no dirty char so I will use 254 +// when draw_frame is called. There is no dirty char so I will use 254 // hoping nowone is using that char. GLU ///////////////////////////////////////////////////////////////// // Writes a big number. // -static void -MtxOrb_num (int x, int num) +MODULE_EXPORT void +MtxOrb_num (Driver *drvthis, int x, int num) { int y, dx; char out[5]; @@ -1131,7 +1180,7 @@ MtxOrb_num (int x, int num) // Make this space dirty as far as frame buffer knows. for (y = 1; y < 5; y++) for (dx = 0; dx < 3; dx++) - MtxOrb_chr (x + dx, y, DIRTY_CHAR); + MtxOrb_chr (drvthis, x + dx, y, DIRTY_CHAR); } @@ -1147,7 +1196,7 @@ MtxOrb_num (int x, int num) // TODO: _icon should not call this directly, this is why we define // so frequently the heartbeat custom char. GLU // -// TODO: We make one 3 bytes write folowed by MtxOrb->cellhgt one byte +// TODO: We make one 3 bytes write folowed by cellheight one byte // write. This should be done in one single write. GLU #define MAX_CUSTOM_CHARS 7 @@ -1157,8 +1206,8 @@ MtxOrb_num (int x, int num) // // The input is just an array of characters... // -static void -MtxOrb_set_char (int n, char *dat) +MODULE_EXPORT void +MtxOrb_set_char (Driver *drvthis, int n, char *dat) { char out[4]; int row, col; @@ -1172,15 +1221,15 @@ MtxOrb_set_char (int n, char *dat) snprintf (out, sizeof(out), "\x0FEN%c", n); write (fd, out, 3); - for (row = 0; row < MtxOrb->cellhgt; row++) { + for (row = 0; row < cellheight; row++) { letter = 0; - for (col = 0; col < MtxOrb->cellwid; col++) { + for (col = 0; col < cellwidth; col++) { // shift to make room for new scan line data letter <<= 1; // Now read a single bit of data // -- one entry in dat[] -- // and add it to the binary data in "letter" - letter |= (dat[(row * MtxOrb->cellwid) + col] > 0); + letter |= (dat[(row * cellwidth) + col] > 0); } write (fd, &letter, 1); // write one character for each row } @@ -1191,81 +1240,15 @@ MtxOrb_set_char (int n, char *dat) // // TODO (DONE): Don't make direct call to caracter definition if the caracter is // already defined. GLU -static void -MtxOrb_icon (int which, char dest) +MODULE_EXPORT void +MtxOrb_icon (Driver *drvthis, int which, char dest) { if (custom == bign) custom = beat; - MtxOrb_set_known_char (dest, START_ICON+which); + MtxOrb_set_known_char (drvthis, dest, START_ICON+which); } -///////////////////////////////////////////////////////////// -// Blasts a single frame onscreen, to the lcd... -// -// Input is a character array, sized lcd.wid*lcd.hgt -// -static void -MtxOrb_draw_frame (char *dat) -{ - char out[12]; - int i,j,mv = 1; - static char *old = NULL; - char *p, *q; - - if (!dat) - return; - - if (old == NULL) { - old = malloc(MtxOrb->wid * MtxOrb->hgt); - - write(fd, "\x0FEG\x01\x01", 4); - write(fd, dat, MtxOrb->wid * MtxOrb->hgt); - - strncpy(old, dat, MtxOrb->wid * MtxOrb->hgt); - - return; - - } else { - if (! new_framebuf(MtxOrb, old)) - return; - } - - p = dat; - q = old; - - for (i = 1; i <= MtxOrb->hgt; i++) { - for (j = 1; j <= MtxOrb->wid; j++) { - - if ((*p == *q) && (*p > 8)) - mv = 1; - else { - // Draw characters that have changed, as well - // as custom characters. We know not if a custom - // character has changed. - - if (mv == 1) { - snprintf(out, sizeof(out), "\x0FEG%c%c", j, i); - write (fd, out, 4); - mv = 0; - } - write (fd, p, 1); - } - p++; - q++; - } - } - - - //for (i = 0; i < MtxOrb->hgt; i++) { - // snprintf (out, sizeof(out), "\x0FEG\x001%c", i + 1); - // write (fd, out, 4); - // write (fd, dat + (MtxOrb->wid * i), MtxOrb->wid); - //} - - strncpy(old, dat, MtxOrb->wid * MtxOrb->hgt); -} - -// TODO: Recover the code for I2C connectivity to MtxOrb +// TODO: Recover the code for I2C connectivity to MtxOrb // and don't query the LCD if it does not support keypad. // Otherwise crash of the LCD and/or I2C bus. // @@ -1273,12 +1256,31 @@ MtxOrb_draw_frame (char *dat) // returns one character from the keypad... // (A-Z) on success, 0 on failure... // -static char -MtxOrb_getkey () +MODULE_EXPORT char +MtxOrb_getkey (Driver *drvthis) { char in = 0; read (fd, &in, 1); + switch (in) { + case KEY_LEFT: + in = INPUT_BACK_KEY; + break; + case KEY_RIGHT: + in = INPUT_FORWARD_KEY; + break; + case KEY_DOWN: + in = INPUT_MAIN_MENU_KEY; + break; + case KEY_F1: + in = INPUT_PAUSE_KEY; + break; + /*TODO: add more translations here (if neccessary)*/ + default: + in = 0; + break; + } + return in; } @@ -1292,7 +1294,7 @@ MtxOrb_getkey () // completely tested, just a quick hack. // static int -MtxOrb_ask_bar (int type) +MtxOrb_ask_bar (Driver *drvthis, int type) { int i; int last_not_in_use; @@ -1331,7 +1333,7 @@ MtxOrb_ask_bar (int type) if (pos != 8) { // A caracter is found (Best match could solve our problem). // REMOVE: fprintf(stderr, "GLU: MtxOrb_ask_bar| found at %d.\n", pos); if (def[pos] != type) { - MtxOrb_set_known_char (pos, type); // Define a new graphic caracter. + MtxOrb_set_known_char (drvthis, pos, type); // Define a new graphic caracter. def[pos] = type; // Remember that now the caracter is available. } if (!use[pos]) { // If the caracter is no yet in use (but defined). @@ -1433,8 +1435,8 @@ MtxOrb_ask_bar (int type) ///////////////////////////////////////////////////////////// // Does the heartbeat... // -static void -MtxOrb_heartbeat (int type) +MODULE_EXPORT void +MtxOrb_heartbeat (Driver *drvthis, int type) { int the_icon=255; static int timer = 0; @@ -1451,13 +1453,13 @@ MtxOrb_heartbeat (int type) // This defines a custom character EVERY time... // not efficient... is this necessary? // MtxOrb_icon (whichIcon, 0); - the_icon=MtxOrb_ask_bar (whichIcon+START_ICON); + the_icon=MtxOrb_ask_bar (drvthis, whichIcon+START_ICON); // Put character on screen... - MtxOrb_chr (MtxOrb->wid, 1, the_icon); + MtxOrb_chr (drvthis, width, 1, the_icon); // change display... - MtxOrb_flush (); + MtxOrb_flush (drvthis); } timer++; @@ -1468,11 +1470,11 @@ MtxOrb_heartbeat (int type) // Sets up a well known character for use. // static void -MtxOrb_set_known_char (int car, int type) +MtxOrb_set_known_char (Driver *drvthis, int car, int type) { char all_bar[25][5 * 8] = { { - 0, 0, 0, 0, 0, // char u1[] = + 0, 0, 0, 0, 0, // char u1[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1481,7 +1483,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, }, { - 0, 0, 0, 0, 0, // char u2[] = + 0, 0, 0, 0, 0, // char u2[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1490,7 +1492,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, { - 0, 0, 0, 0, 0, // char u3[] = + 0, 0, 0, 0, 0, // char u3[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1499,7 +1501,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, { - 0, 0, 0, 0, 0, // char u4[] = + 0, 0, 0, 0, 0, // char u4[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1508,7 +1510,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, { - 0, 0, 0, 0, 0, // char u5[] = + 0, 0, 0, 0, 0, // char u5[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, @@ -1517,7 +1519,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, { - 0, 0, 0, 0, 0, // char u6[] = + 0, 0, 0, 0, 0, // char u6[] = 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1526,7 +1528,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, { - 0, 0, 0, 0, 0, // char u7[] = + 0, 0, 0, 0, 0, // char u7[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1535,7 +1537,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }, { - 1, 1, 1, 1, 1, // char d1[] = + 1, 1, 1, 1, 1, // char d1[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1544,7 +1546,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { - 1, 1, 1, 1, 1, // char d2[] = + 1, 1, 1, 1, 1, // char d2[] = 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1553,7 +1555,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { - 1, 1, 1, 1, 1, // char d3[] = + 1, 1, 1, 1, 1, // char d3[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, @@ -1562,7 +1564,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { - 1, 1, 1, 1, 1, // char d4[] = + 1, 1, 1, 1, 1, // char d4[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1571,7 +1573,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { - 1, 1, 1, 1, 1, // char d5[] = + 1, 1, 1, 1, 1, // char d5[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1580,7 +1582,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { - 1, 1, 1, 1, 1, // char d6[] = + 1, 1, 1, 1, 1, // char d6[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1589,7 +1591,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { - 1, 1, 1, 1, 1, // char d7[] = + 1, 1, 1, 1, 1, // char d7[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1598,7 +1600,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, }, { - 1, 0, 0, 0, 0, // char r1[] = + 1, 0, 0, 0, 0, // char r1[] = 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, @@ -1607,7 +1609,7 @@ MtxOrb_set_known_char (int car, int type) 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, }, { - 1, 1, 0, 0, 0, // char r2[] = + 1, 1, 0, 0, 0, // char r2[] = 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, @@ -1616,7 +1618,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, }, { - 1, 1, 1, 0, 0, // char r3[] = + 1, 1, 1, 0, 0, // char r3[] = 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, @@ -1625,7 +1627,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, }, { - 1, 1, 1, 1, 0, // char r4[] = + 1, 1, 1, 1, 0, // char r4[] = 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, @@ -1634,7 +1636,7 @@ MtxOrb_set_known_char (int car, int type) 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, }, { - 0, 0, 0, 0, 1, // char l1[] = + 0, 0, 0, 0, 1, // char l1[] = 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, @@ -1643,7 +1645,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, { - 0, 0, 0, 1, 1, // char l2[] = + 0, 0, 0, 1, 1, // char l2[] = 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, @@ -1652,7 +1654,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, }, { - 0, 0, 1, 1, 1, // char l3[] = + 0, 0, 1, 1, 1, // char l3[] = 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, @@ -1661,7 +1663,7 @@ MtxOrb_set_known_char (int car, int type) 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, }, { - 0, 1, 1, 1, 1, // char l4[] = + 0, 1, 1, 1, 1, // char l4[] = 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, @@ -1699,6 +1701,6 @@ MtxOrb_set_known_char (int car, int type) } }; - MtxOrb_set_char (car, &all_bar[type][0]); + MtxOrb_set_char (drvthis, car, &all_bar[type][0]); } diff --git a/server/drivers/MtxOrb.h b/server/drivers/MtxOrb.h index f772486..38ee6a9 100644 --- a/server/drivers/MtxOrb.h +++ b/server/drivers/MtxOrb.h @@ -1,41 +1,53 @@ #ifndef MTXORB_H #define MTXORB_H -extern lcd_logical_driver *MtxOrb; +#include "lcd.h" -int MtxOrb_init (lcd_logical_driver * driver, char *device); -/* - * Just like in hd44780 those function are assing by _init ... -static void MtxOrb_clear (); -static void MtxOrb_close (); -static void MtxOrb_flush (); -static void MtxOrb_flush_box (int lft, int top, int rgt, int bot); -static void MtxOrb_chr (int x, int y, char c); -static int MtxOrb_contrast (int contrast); -static void MtxOrb_backlight (int on); -static void MtxOrb_output (int on); -static void MtxOrb_init_vbar (); -static void MtxOrb_init_hbar (); -static void MtxOrb_vbar (int x, int len); -static void MtxOrb_hbar (int x, int y, int len); -static void MtxOrb_init_num (); -static void MtxOrb_num (int x, int num); -static void MtxOrb_set_char (int n, char *dat); -static void MtxOrb_icon (int which, char dest); -static void MtxOrb_draw_frame (char *dat); -static char MtxOrb_getkey (); -static char * MtxOrb_getinfo (); -static void MtxOrb_heartbeat (int type); + int MtxOrb_init (Driver *drvthis, char *device); +MODULE_EXPORT void MtxOrb_close (Driver *drvthis); +MODULE_EXPORT int MtxOrb_width (Driver *drvthis); +MODULE_EXPORT int MtxOrb_height (Driver *drvthis); +MODULE_EXPORT void MtxOrb_clear (Driver *drvthis); +MODULE_EXPORT void MtxOrb_flush (Driver *drvthis); +MODULE_EXPORT void MtxOrb_string (Driver *drvthis, int x, int y, char *string); +MODULE_EXPORT void MtxOrb_chr (Driver *drvthis, int x, int y, char c); -static int MtxOrb_ask_bar (int type); -static void MtxOrb_set_known_char (int car, int type); -*/ +MODULE_EXPORT void MtxOrb_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void MtxOrb_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void MtxOrb_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void MtxOrb_icon (Driver *drvthis, int which, char dest); +MODULE_EXPORT void MtxOrb_heartbeat (Driver *drvthis, int type); -#define DEFAULT_CONTRAST 120 +MODULE_EXPORT void MtxOrb_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT int MtxOrb_get_contrast (Driver *drvthis); +MODULE_EXPORT void MtxOrb_set_contrast (Driver *drvthis, int promille); +MODULE_EXPORT void MtxOrb_backlight (Driver *drvthis, int on); +MODULE_EXPORT void MtxOrb_output (Driver *drvthis, int on); + +MODULE_EXPORT char MtxOrb_getkey (Driver *drvthis); +MODULE_EXPORT char * MtxOrb_get_info (Driver *drvthis); + +MODULE_EXPORT void MtxOrb_init_vbar (Driver *drvthis); +MODULE_EXPORT void MtxOrb_init_hbar (Driver *drvthis); +MODULE_EXPORT void MtxOrb_init_num (Driver *drvthis); + +#define DEFAULT_CONTRAST 480 #define DEFAULT_DEVICE "/dev/lcd" #define DEFAULT_SPEED B19200 #define DEFAULT_LINEWRAP 1 #define DEFAULT_AUTOSCROLL 1 #define DEFAULT_CURSORBLINK 0 + +/* These are the keys for a (possibly) broken LK202-25...*/ +#define KEY_UP 'I' +#define KEY_DOWN 'F' +#define KEY_LEFT 'K' +#define KEY_RIGHT 'A' +#define KEY_F1 'N' +/* TODO: add more if you've got any more ;) or correct the settings + * the actual translation is done in MtxOrb_getkey() + */ + #endif diff --git a/server/drivers/bayrad.c b/server/drivers/bayrad.c index 4bcebf1..58b5a2b 100644 --- a/server/drivers/bayrad.c +++ b/server/drivers/bayrad.c @@ -30,24 +30,27 @@ #endif #include "lcd.h" #include "bayrad.h" -#include "drv_base.h" +//#include "drv_base.h" #include "shared/str.h" ////////////////////////////////////////////////////////////////////////// ////////////////////// Base "class" to derive from /////////////////////// ////////////////////////////////////////////////////////////////////////// -lcd_logical_driver *bayrad; static int fd; - +static int width = 0; +static int height = 0; +static int cellwidth = 5; +static int cellheight = 8; +static char *framebuf = NULL; ///////////////////////////////////////////////////////////// /* Declare a bunch of global, static custom character data */ ///////////////////////////////////////////////////////////// -char bar_up[7][5*8] = { +char bar_up[7][5*8] = { { - 0,0,0,0,0, // char u1[] = + 0,0,0,0,0, // char u1[] = 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, @@ -57,7 +60,7 @@ char bar_up[7][5*8] = { 1,1,1,1,1, }, { - 0,0,0,0,0, // char u2[] = + 0,0,0,0,0, // char u2[] = 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, @@ -66,7 +69,7 @@ char bar_up[7][5*8] = { 1,1,1,1,1, 1,1,1,1,1, },{ - 0,0,0,0,0, // char u3[] = + 0,0,0,0,0, // char u3[] = 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, @@ -75,7 +78,7 @@ char bar_up[7][5*8] = { 1,1,1,1,1, 1,1,1,1,1, },{ - 0,0,0,0,0, // char u4[] = + 0,0,0,0,0, // char u4[] = 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, @@ -84,7 +87,7 @@ char bar_up[7][5*8] = { 1,1,1,1,1, 1,1,1,1,1, },{ - 0,0,0,0,0, // char u5[] = + 0,0,0,0,0, // char u5[] = 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,1, @@ -93,7 +96,7 @@ char bar_up[7][5*8] = { 1,1,1,1,1, 1,1,1,1,1, },{ - 0,0,0,0,0, // char u6[] = + 0,0,0,0,0, // char u6[] = 0,0,0,0,0, 1,1,1,1,1, 1,1,1,1,1, @@ -102,7 +105,7 @@ char bar_up[7][5*8] = { 1,1,1,1,1, 1,1,1,1,1, },{ - 0,0,0,0,0, // char u7[] = + 0,0,0,0,0, // char u7[] = 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, @@ -115,7 +118,7 @@ char bar_up[7][5*8] = { char bar_down[7][5*8] = { /* Presently, this is not used */ { - 1,1,1,1,1, // char d1[] = + 1,1,1,1,1, // char d1[] = 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, @@ -124,7 +127,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ 0,0,0,0,0, 0,0,0,0,0, },{ - 1,1,1,1,1, // char d2[] = + 1,1,1,1,1, // char d2[] = 1,1,1,1,1, 0,0,0,0,0, 0,0,0,0,0, @@ -133,7 +136,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ 0,0,0,0,0, 0,0,0,0,0, },{ - 1,1,1,1,1, // char d3[] = + 1,1,1,1,1, // char d3[] = 1,1,1,1,1, 1,1,1,1,1, 0,0,0,0,0, @@ -142,7 +145,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ 0,0,0,0,0, 0,0,0,0,0, },{ - 1,1,1,1,1, // char d4[] = + 1,1,1,1,1, // char d4[] = 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, @@ -151,7 +154,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ 0,0,0,0,0, 0,0,0,0,0, },{ - 1,1,1,1,1, // char d5[] = + 1,1,1,1,1, // char d5[] = 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, @@ -160,7 +163,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ 0,0,0,0,0, 0,0,0,0,0, },{ - 1,1,1,1,1, // char d6[] = + 1,1,1,1,1, // char d6[] = 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, @@ -169,7 +172,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ 0,0,0,0,0, 0,0,0,0,0, },{ - 1,1,1,1,1, // char d7[] = + 1,1,1,1,1, // char d7[] = 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, @@ -181,7 +184,7 @@ char bar_down[7][5*8] = { /* Presently, this is not used */ char bar_right[4][5*8] = { { - 1,0,0,0,0, // char r1[] = + 1,0,0,0,0, // char r1[] = 1,0,0,0,0, 1,0,0,0,0, 1,0,0,0,0, @@ -190,7 +193,7 @@ char bar_right[4][5*8] = { 1,0,0,0,0, 1,0,0,0,0, },{ - 1,1,0,0,0, // char r2[] = + 1,1,0,0,0, // char r2[] = 1,1,0,0,0, 1,1,0,0,0, 1,1,0,0,0, @@ -199,7 +202,7 @@ char bar_right[4][5*8] = { 1,1,0,0,0, 1,1,0,0,0, },{ - 1,1,1,0,0, // char r3[] = + 1,1,1,0,0, // char r3[] = 1,1,1,0,0, 1,1,1,0,0, 1,1,1,0,0, @@ -208,7 +211,7 @@ char bar_right[4][5*8] = { 1,1,1,0,0, 1,1,1,0,0, },{ - 1,1,1,1,0, // char r4[] = + 1,1,1,1,0, // char r4[] = 1,1,1,1,0, 1,1,1,1,0, 1,1,1,1,0, @@ -220,7 +223,7 @@ char bar_right[4][5*8] = { char bar_left[4][5*8] = { /* Presently, this is not used. */ { - 0,0,0,0,1, // char l1[] = + 0,0,0,0,1, // char l1[] = 0,0,0,0,1, 0,0,0,0,1, 0,0,0,0,1, @@ -229,7 +232,7 @@ char bar_left[4][5*8] = { /* Presently, this is not used. */ 0,0,0,0,1, 0,0,0,0,1, },{ - 0,0,0,1,1, // char l2[] = + 0,0,0,1,1, // char l2[] = 0,0,0,1,1, 0,0,0,1,1, 0,0,0,1,1, @@ -238,7 +241,7 @@ char bar_left[4][5*8] = { /* Presently, this is not used. */ 0,0,0,1,1, 0,0,0,1,1, },{ - 0,0,1,1,1, // char l3[] = + 0,0,1,1,1, // char l3[] = 0,0,1,1,1, 0,0,1,1,1, 0,0,1,1,1, @@ -247,7 +250,7 @@ char bar_left[4][5*8] = { /* Presently, this is not used. */ 0,0,1,1,1, 0,0,1,1,1, },{ - 0,1,1,1,1, // char l4[] = + 0,1,1,1,1, // char l4[] = 0,1,1,1,1, 0,1,1,1,1, 0,1,1,1,1, @@ -268,7 +271,7 @@ char icons[3][5*8] = { 1,0,0,0,1, 1,1,0,1,1, 1,1,1,1,1, - }, + }, { 1,1,1,1,1, // Filled Heart @@ -280,7 +283,7 @@ char icons[3][5*8] = { 1,1,0,1,1, 1,1,1,1,1, }, - + { 0,0,0,0,0, // Ellipsis 0,0,0,0,0, @@ -291,19 +294,25 @@ char icons[3][5*8] = { 0,0,0,0,0, 1,0,1,0,1, }, - + }; +// Vars for the server core +MODULE_EXPORT char * api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "bayrad_"; //////////////////////////////////////////////////////////// // init() should set up any device-specific stuff, and // point all the function pointers. -int bayrad_init(struct lcd_logical_driver *driver, char *args) +int +bayrad_init(Driver *drvthis, char *args) { - char device[256]; + char device[256]; int speed=B9600; char *argv[64]; int argc; @@ -312,31 +321,28 @@ int bayrad_init(struct lcd_logical_driver *driver, char *args) int tmp; //printf("bayrad_init()\n"); - bayrad = driver; strcpy(device, "/dev/lcd"); - driver->wid = 20; - driver->hgt = 2; + width = 20; + height = 2; - // You must use driver->framebuf here, but may use lcd.framebuf later. - if(!driver->framebuf) - driver->framebuf = malloc(driver->wid * driver->hgt); + framebuf = malloc(width * height); - if(!driver->framebuf) + if(!framebuf) { - bayrad_close(); + bayrad_close(drvthis); fprintf(stderr, "\nError: unable to create BayRAD framebuffer.\n"); return -1; } - memset(driver->framebuf, ' ', driver->wid*driver->hgt); + memset(framebuf, ' ', width * height); - driver->cellwid = 5; - driver->cellhgt = 8; + //cellheight = 5; + //cellwidth = 8; /*-----------------------------------------------------*/ //fprintf(stderr, "bayrad_init: Args(all): %s\n", args); - + argc = get_args(argv, args, 64); /* @@ -345,7 +351,7 @@ int bayrad_init(struct lcd_logical_driver *driver, char *args) printf("Arg(%i): %s\n", i, argv[i]); } */ - + for(i=0; i argc) + if(i + 1 > argc) { fprintf(stderr, "bayrad_init: %s requires an argument\n", argv[i]); return -1; } tmp = atoi(argv[++i]); - if(tmp==1200) + if(tmp==1200) speed=B1200; - else if(tmp==2400) + else if(tmp==2400) speed=B2400; - else if(tmp==9600) + else if(tmp==9600) speed=B9600; - else if(tmp==19200) + else if(tmp==19200) speed=B19200; - else + else { fprintf(stderr, "bayrad_init: %s argument must be 1200, 2400, 9600 or 19200. Using default value.\n", argv[i]); @@ -393,12 +399,12 @@ int bayrad_init(struct lcd_logical_driver *driver, char *args) { printf("Invalid parameter: %s\n", argv[i]); } - + } - + // Set up io port correctly, and open it... - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (fd == -1) + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd == -1) { fprintf(stderr, "bayrad_init: failed (%s)\n", strerror(errno)); return -1; @@ -442,71 +448,96 @@ int bayrad_init(struct lcd_logical_driver *driver, char *args) write(fd, "\x80\x86\x00\x1a\x1e", 5); // sync,reset to type 0, clear screen, home - driver->clear = bayrad_clear; - driver->string = bayrad_string; - driver->chr = bayrad_chr; - driver->vbar = bayrad_vbar; - driver->init_vbar = bayrad_init_vbar; - driver->hbar = bayrad_hbar; - driver->init_hbar = bayrad_init_hbar; - //driver->num = NULL; //bayrad_num; - //driver->init_num = NULL; //bayrad_init_num; - driver->init = bayrad_init; - driver->close = bayrad_close; - driver->flush = bayrad_flush; - driver->flush_box = bayrad_flush_box; - //driver->contrast = NULL; - driver->backlight = bayrad_backlight; - driver->set_char = bayrad_set_char; - driver->icon = bayrad_icon; - driver->draw_frame = bayrad_draw_frame; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->getkey = bayrad_getkey; - - - return fd; + // Set the functions the driver supports + drvthis->clear = bayrad_clear; + drvthis->string = bayrad_string; + drvthis->chr = bayrad_chr; + drvthis->old_vbar = bayrad_vbar; + drvthis->init_vbar = bayrad_init_vbar; + drvthis->old_hbar = bayrad_hbar; + drvthis->init_hbar = bayrad_init_hbar; + //drvthis->num = NULL; //bayrad_num; + //drvthis->init_num = NULL; //bayrad_init_num; + drvthis->init = bayrad_init; + drvthis->close = bayrad_close; + drvthis->flush = bayrad_flush; + drvthis->backlight = bayrad_backlight; + drvthis->set_char = bayrad_set_char; + drvthis->old_icon = bayrad_icon; + + drvthis->getkey = bayrad_getkey; + + + return 0; } -// Below here, you may use either lcd.framebuf or driver->framebuf.. +// Below here, you may use either lcd.framebuf or drvthis->framebuf.. // lcd.framebuf will be set to the appropriate buffer before calling // your driver. -void bayrad_close() +MODULE_EXPORT void +bayrad_close(Driver * drvthis) { - if(bayrad->framebuf != NULL) - free(bayrad->framebuf); - - bayrad->framebuf = NULL; + //fprintf(stderr, "\nClosing BayRAD.\n"); write(fd, "\x8e\x00", 2); // Backlight OFF - //fprintf(stderr, "\nClosing BayRAD.\n"); + if(framebuf) free(framebuf); + framebuf = NULL; - close(fd); + close(fd); } + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +bayrad_width(Driver * drvthis) +{ + return width; +} + + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +bayrad_height(Driver * drvthis) +{ + return height; +} + + ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void bayrad_clear() +MODULE_EXPORT void +bayrad_clear(Driver * drvthis) { - memset(bayrad->framebuf, ' ', bayrad->wid*bayrad->hgt); - + memset(framebuf, ' ', width * height); + } ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -void bayrad_flush() +MODULE_EXPORT void +bayrad_flush(Driver * drvthis) { - //fprintf(stderr, "\nBayRAD flush"); + //fprintf(stderr, "\nBayRAD flush"); write(fd, "\x80\x1e", 2); //sync, home - write(fd, bayrad->framebuf, 20); + write(fd, framebuf, 20); write(fd, "\x1e\x0a", 2); //home, LF - write(fd, bayrad->framebuf+20, 20); + write(fd, framebuf+20, 20); return; } @@ -515,7 +546,8 @@ void bayrad_flush() // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void bayrad_string(int x, int y, char string[]) +MODULE_EXPORT void +bayrad_string(Driver * drvthis, int x, int y, char string[]) { int i; unsigned char c; @@ -524,11 +556,11 @@ void bayrad_string(int x, int y, char string[]) x -= 1; // Convert 1-based coords to 0-based... y -= 1; - + for(i=0; string[i]; i++) { // Check for buffer overflows... - if((y*bayrad->wid) + x + i > (bayrad->wid*bayrad->hgt)) + if((y*width) + x + i > (width*height)) break; c = (unsigned char) string[i]; @@ -538,14 +570,14 @@ void bayrad_string(int x, int y, char string[]) //c &= 0x7F; fprintf(stderr, "\nIllegal char %#x requested in bayrad_string()!\n", c); c = ' '; - + } if(c < 8) /* The custom characters are mapped at 0x98 - 0x9F, */ c += 0x98; /* as 0x07 makes a beep instead of printing a character */ - bayrad->framebuf[(y*bayrad->wid) + x + i] = c; + framebuf[(y*width) + x + i] = c; } } @@ -553,8 +585,9 @@ void bayrad_string(int x, int y, char string[]) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,2). // -void bayrad_chr(int x, int y, char c) -{ +MODULE_EXPORT void +bayrad_chr(Driver * drvthis, int x, int y, char c) +{ unsigned char ch; //fprintf(stderr, "\nPutting char %c (%#x) at %i, %i", c, c, x, y); @@ -571,13 +604,14 @@ void bayrad_chr(int x, int y, char c) /* No shifting the custom chars here, so bayrad_chr() can beep */ - bayrad->framebuf[(y*bayrad->wid) + x] = ch; + framebuf[(y*width) + x] = ch; } ////////////////////////////////////////////////////////////////////// // Turns the lcd backlight on or off... // -void bayrad_backlight(int on) +MODULE_EXPORT void +bayrad_backlight(Driver * drvthis, int on) { /* This violates the LCDd driver model, but it does leave the @@ -601,18 +635,19 @@ void bayrad_backlight(int on) ////////////////////////////////////////////////////////////////////// // Tells the driver to get ready for vertical bargraphs. // -void bayrad_init_vbar() +MODULE_EXPORT void +bayrad_init_vbar(Driver * drvthis) { //printf("Init Vertical bars.\n"); - bayrad_set_char(1, bar_up[0]); - bayrad_set_char(2, bar_up[1]); - bayrad_set_char(3, bar_up[2]); - bayrad_set_char(4, bar_up[3]); - bayrad_set_char(5, bar_up[4]); - bayrad_set_char(6, bar_up[5]); - bayrad_set_char(7, bar_up[6]); - + bayrad_set_char(drvthis, 1, bar_up[0]); + bayrad_set_char(drvthis, 2, bar_up[1]); + bayrad_set_char(drvthis, 3, bar_up[2]); + bayrad_set_char(drvthis, 4, bar_up[3]); + bayrad_set_char(drvthis, 5, bar_up[4]); + bayrad_set_char(drvthis, 6, bar_up[5]); + bayrad_set_char(drvthis, 7, bar_up[6]); + return; } @@ -620,14 +655,15 @@ void bayrad_init_vbar() ////////////////////////////////////////////////////////////////////// // Tells the driver to get ready for horizontal bargraphs. // -void bayrad_init_hbar() +MODULE_EXPORT void +bayrad_init_hbar(Driver * drvthis) { - //printf("Init Horizontal bars.\n"); + //printf("Init Horizontal bars.\n"); - bayrad_set_char(1, bar_right[0]); - bayrad_set_char(2, bar_right[1]); - bayrad_set_char(3, bar_right[2]); - bayrad_set_char(4, bar_right[3]); + bayrad_set_char(drvthis, 1, bar_right[0]); + bayrad_set_char(drvthis, 2, bar_right[1]); + bayrad_set_char(drvthis, 3, bar_right[2]); + bayrad_set_char(drvthis, 4, bar_right[3]); return; } @@ -635,7 +671,8 @@ return; ////////////////////////////////////////////////////////////////////// // Tells the driver to get ready for big numbers, if possible. // -void bayrad_init_num() +MODULE_EXPORT void +bayrad_init_num(Driver * drvthis) { // printf("Big Numbers.\n"); } @@ -643,7 +680,8 @@ void bayrad_init_num() ////////////////////////////////////////////////////////////////////// // Draws a big (4-row) number. // -void bayrad_num(int x, int num) +MODULE_EXPORT void +bayrad_num(Driver * drvthis, int x, int num) { // printf("BigNum(%i, %i)\n", x, num); } @@ -651,7 +689,8 @@ void bayrad_num(int x, int num) ////////////////////////////////////////////////////////////////////// // Changes the font data of character n. // -void bayrad_set_char(int n, char *dat) +MODULE_EXPORT void +bayrad_set_char(Driver * drvthis, int n, char *dat) { char out[4]; int row, col; @@ -663,7 +702,7 @@ void bayrad_set_char(int n, char *dat) return; - if(!dat) + if(!dat) return; n = 0x40 + (n * 8); /* Set n to the proper location in CG RAM */ @@ -671,14 +710,14 @@ void bayrad_set_char(int n, char *dat) /* Set the LCD to accept data for rewrite-able char n */ snprintf(out, sizeof(out), "\x88%c", n); write(fd, out, 2); - - for(row=0; rowcellhgt; row++) + + for(row=0; rowcellwid; col++) + for(col=0; colcellwid) + col] > 0); + letter |= (dat[(row*cellwidth) + col] > 0); } write(fd, &letter, 1); } @@ -692,58 +731,60 @@ return; ///////////////////////////////////////////////////////////////// // Draws a vertical bar, from the bottom of the screen up. // -void bayrad_vbar(int x, int len) +MODULE_EXPORT void +bayrad_vbar(Driver * drvthis, int x, int len) { int y = 2; //fprintf(stderr, "\nVbar at %i, length %i", x, len); - if(len >= bayrad->cellhgt) + if(len >= cellheight) { - bayrad_chr(x, y, 0xFF); - len -= bayrad->cellhgt; + bayrad_chr(drvthis, x, y, 0xFF); + len -= cellheight; y = 1; } - + if(!len) return; - - if(len > bayrad->cellhgt) + + if(len > cellheight) { - bayrad_chr(x, y, '^'); /* Show we've gone off the chart */ + bayrad_chr(drvthis, x, y, '^'); /* Show we've gone off the chart */ return; } - + /* init_vbar sets custom chars 1 - 7. Height 8 is char 0xFF. */ if(len == 8) - bayrad_chr(x, y, 0xFF); + bayrad_chr(drvthis, x, y, 0xFF); else - bayrad_chr(x, y, (len+0x98)); - + bayrad_chr(drvthis, x, y, (len+0x98)); + return; } ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void bayrad_hbar(int x, int y, int len) +MODULE_EXPORT void +bayrad_hbar(Driver * drvthis, int x, int y, int len) { //fprintf(stderr, "\nHbar at %i,%i; length %i", x, y, len); - while((x <= bayrad->wid) && (len > 0)) + while((x <= cellwidth) && (len > 0)) { - if(len < bayrad->cellwid) + if(len < cellwidth) { - bayrad_chr(x, y, 0x98 + len); + bayrad_chr(drvthis, x, y, 0x98 + len); break; } - bayrad_chr(x, y, 0xFF); - len -= bayrad->cellwid; + bayrad_chr(drvthis, x, y, 0xFF); + len -= cellwidth; x++; } - + return; } @@ -751,54 +792,27 @@ void bayrad_hbar(int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets character 0 to an icon... // -void bayrad_icon(int which, char dest) +MODULE_EXPORT void +bayrad_icon(Driver * drvthis, int which, char dest) { - //printf("Char %i set to icon %i\n", dest, which); - bayrad_set_char(dest, &icons[which][0]); + //printf("Char %i set to icon %i\n", dest, which); + bayrad_set_char(drvthis, dest, &icons[which][0]); return; } -////////////////////////////////////////////////////////////////////// -// Send a rectangular area to the display. -// -// I've just called bayrad_flush() because there's not much point yet -// in flushing less than the entire framebuffer. -// -void bayrad_flush_box(int lft, int top, int rgt, int bot) -{ - bayrad_flush(); - -} - -////////////////////////////////////////////////////////////////////// -// Draws the framebuffer on the display. -// - -void bayrad_draw_frame(char *dat) -{ - - //fprintf(stderr, "\nBayRAD draw frame"); - - write(fd, "\x80\x1e", 2); // NOP, home - write(fd, bayrad->framebuf, 20); - write(fd, "\n", 1); - write(fd, bayrad->framebuf+20, 20); - -} - - ////////////////////////////////////////////////////////////////////// // Tries to read a character from an input device... // // Return 0 for "nothing available". // -char bayrad_getkey() -{ +MODULE_EXPORT char +bayrad_getkey(Driver * drvthis) +{ fd_set brfdset; - struct timeval twait; + struct timeval twait; char readchar; int retval; @@ -809,7 +823,7 @@ char bayrad_getkey() /* with received keypad characters. */ FD_ZERO(&brfdset); FD_SET(fd, &brfdset); - + twait.tv_sec = 0; twait.tv_usec = 0; @@ -817,9 +831,9 @@ char bayrad_getkey() { retval = read(fd, &readchar, 1); if(retval > 0) - { + { //fprintf(stderr, "Received char %c", readchar); - + if(readchar == 'Y') { write(fd, "\x8e\x0f", 2); @@ -828,7 +842,7 @@ char bayrad_getkey() { write(fd, "\x8e\x00", 2); } - + } /* if read returned data */ else { /* Read error */ @@ -837,7 +851,7 @@ char bayrad_getkey() } /* if select */ else { - ;//fprintf(stderr, "No BayRAD data present."); + ;//fprintf(stderr, "No BayRAD data present."); } return readchar; diff --git a/server/drivers/bayrad.h b/server/drivers/bayrad.h index 64023a7..189e66f 100644 --- a/server/drivers/bayrad.h +++ b/server/drivers/bayrad.h @@ -8,24 +8,28 @@ #ifndef _BAYRAD_H #define _BAYRAD_H -extern lcd_logical_driver *bayrad; +#include "lcd.h" -int bayrad_init(struct lcd_logical_driver *driver, char *args); -void bayrad_close(); -void bayrad_clear(); -void bayrad_flush(); -void bayrad_string(int x, int y, char string[]); -void bayrad_chr(int x, int y, char c); -int bayrad_contrast(int contrast); -void bayrad_backlight(int on); -void bayrad_vbar(int x, int len); -void bayrad_init_vbar(); -void bayrad_hbar(int x, int y, int len); -void bayrad_init_hbar(); -void bayrad_set_char(int n, char *dat); -void bayrad_icon(int which, char dest); -void bayrad_flush_box(int lft, int top, int rgt, int bot); -void bayrad_draw_frame(char *dat); -char bayrad_getkey(); + int bayrad_init(Driver * drvthis, char *args); +MODULE_EXPORT void bayrad_close(Driver * drvthis); +MODULE_EXPORT int bayrad_width(Driver * drvthis); +MODULE_EXPORT int bayrad_height(Driver * drvthis); +MODULE_EXPORT void bayrad_clear(Driver * drvthis); +MODULE_EXPORT void bayrad_flush(Driver * drvthis); +MODULE_EXPORT void bayrad_string(Driver * drvthis, int x, int y, char string[]); +MODULE_EXPORT void bayrad_chr(Driver * drvthis, int x, int y, char c); + +MODULE_EXPORT void bayrad_vbar(Driver * drvthis, int x, int len); +MODULE_EXPORT void bayrad_hbar(Driver * drvthis, int x, int y, int len); +MODULE_EXPORT void bayrad_icon(Driver * drvthis, int which, char dest); + +MODULE_EXPORT void bayrad_set_char(Driver * drvthis, int n, char *dat); + +MODULE_EXPORT void bayrad_backlight(Driver * drvthis, int promille); + +MODULE_EXPORT char bayrad_getkey(Driver * drvthis); + +MODULE_EXPORT void bayrad_init_vbar(Driver * drvthis); +MODULE_EXPORT void bayrad_init_hbar(Driver * drvthis); #endif diff --git a/server/drivers/curses_drv.c b/server/drivers/curses_drv.c index f73729c..c64d81e 100644 --- a/server/drivers/curses_drv.c +++ b/server/drivers/curses_drv.c @@ -22,13 +22,13 @@ /* Different implementations of (n)curses available on: -OpenBSD: +OpenBSD: http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libcurses/ ncurses -NetBSD: +NetBSD: http://cvsweb.netbsd.org/bsdweb.cgi/basesrc/lib/libcurses/ curses : does not define ACS_S3, ACS_S7, wcolor_set() or redrawwin(). - it is possible to make a: + it is possible to make a: #define ACS_S3 (_acs_char['p']) #define ACS_S7 (_acs_char['r']) FreeBSD: @@ -38,7 +38,7 @@ RedHat, Debian, (most distros) Linux: ncurses SunOS (5.5.1): curses : does not define ACS_S3, ACS_S7 or wcolor_set(). - it is possible to make a: + it is possible to make a: #define ACS_S3 (acs_map['p']) #define ACS_S7 (acs_map['r']) */ @@ -63,11 +63,10 @@ SunOS (5.5.1): #include "shared/str.h" -#include "render.h" #include "lcd.h" #include "curses_drv.h" -#include "shared/report.h" -#include "configfile.h" +#include "report.h" +//#include "configfile.h" // ACS_S9 and ACS_S1 are defined as part of XSI Curses standard, Issue 4. // However, ACS_S3 and ACS_S7 are not; these definitions were created to support @@ -85,7 +84,7 @@ SunOS (5.5.1): # else # define ACS_S3 ACS_S1 // Last resort # endif -# endif +# endif #endif #ifndef ACS_S7 @@ -97,17 +96,16 @@ SunOS (5.5.1): # else # define ACS_S7 ACS_S9 // Last resort # endif -# endif +# endif #endif -lcd_logical_driver *curses_drv; - // Character used for title bars... #define PAD '#' // #define PAD ACS_BLOCK -int ELLIPSIS = 7; -void curses_drv_restore_screen (void); +int ELLIPSIS = 7; // Should this go in PrivateData ? +void curses_drv_restore_screen (Driver *drvthis); + ////////////////////////////////////////////////////////////////////////// ////////////////////// For Curses Terminal Output //////////////////////// @@ -117,7 +115,7 @@ static char icon_char = '@'; static WINDOW *lcd_win; /*this is really ugly ;) but works ;)*/ -static char num_icon [10][4][3] = {{{' ','_',' '}, /*0*/ +static char num_icon [10][4][3] = {{{' ','_',' '}, /*0*/ {'|',' ','|'}, {'|','_','|'}, {' ',' ',' '}}, @@ -222,13 +220,22 @@ set_background_color (char * buf) { #define TOP_LEFT_X 7 #define TOP_LEFT_Y 7 -int current_color_pair, current_border_pair, curses_backlight_state = 0; +static int current_color_pair, current_border_pair, curses_backlight_state = 0; +static int width, height; + + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "curses_drv_"; + int -curses_drv_init (struct lcd_logical_driver *driver, char *args) +curses_drv_init (Driver *drvthis, char *args) { char buf[256]; - int wid=0, hgt=0; + int w, h; // Colors.... chtype back_color = DEFAULT_BACKGROUND_COLOR, @@ -239,26 +246,34 @@ curses_drv_init (struct lcd_logical_driver *driver, char *args) int screen_begx = CONF_DEF_TOP_LEFT_X, screen_begy = CONF_DEF_TOP_LEFT_Y; - curses_drv = driver; - - // TODO: replace DriverName with driver->name when that field exists. - #define DriverName "curses" + // Set display sizes + if( drvthis->request_display_width() > 0 + && drvthis->request_display_height() > 0 ) { + // Use size from primary driver + width = drvthis->request_display_width(); + height = drvthis->request_display_height(); + } + else { + // Use default size + width = LCD_DEFAULT_WIDTH; + height = LCD_DEFAULT_HEIGHT; + } /*Get settings from config file*/ /*Get color settings*/ /*foreground color*/ - strncpy(buf, config_get_string ( DriverName , "foreground" , 0 , CONF_DEF_FOREGR),sizeof(buf)); + strncpy(buf, drvthis->config_get_string ( drvthis->name , "foreground" , 0 , CONF_DEF_FOREGR),sizeof(buf)); buf[sizeof(buf)-1]=0; fore_color = set_foreground_color(buf); debug( RPT_DEBUG, "CURSES: using foreground color: %s", buf); /*background color*/ - strncpy(buf, config_get_string ( DriverName , "background" , 0 , CONF_DEF_BACKGR),sizeof(buf)); + strncpy(buf, drvthis->config_get_string ( drvthis->name , "background" , 0 , CONF_DEF_BACKGR),sizeof(buf)); buf[sizeof(buf)-1]=0; back_color = set_background_color(buf); debug( RPT_DEBUG, "CURSES: using background color: %s", buf); /*backlight color*/ - strncpy(buf, config_get_string ( DriverName , "backlight" , 0 , CONF_DEF_BACKLIGHT), sizeof(buf)); + strncpy(buf, drvthis->config_get_string ( drvthis->name , "backlight" , 0 , CONF_DEF_BACKLIGHT), sizeof(buf)); buf[sizeof(buf)-1]=0; backlight_color = set_background_color(buf); debug( RPT_DEBUG, "CURSES: using backlight color: %s", buf); @@ -267,25 +282,28 @@ curses_drv_init (struct lcd_logical_driver *driver, char *args) // Or maybe don't do so? - Rene Wagner /*Get size settings*/ - strncpy(buf, config_get_string ( DriverName , "size" , 0 , CONF_DEF_SIZE), sizeof(buf)); + strncpy(buf, drvthis->config_get_string ( drvthis->name , "size" , 0 , CONF_DEF_SIZE), sizeof(buf)); buf[sizeof(buf)-1]=0; - if( sscanf(buf , "%dx%d", &wid, &hgt ) != 2 - || (wid <= 0) - || (hgt <= 0)) { - report (RPT_WARNING, "CURSES: Cannot read size: %s. Using default value %s.\n", buf, CONF_DEF_SIZE); - sscanf( CONF_DEF_SIZE , "%dx%d", &wid, &hgt ); + if( sscanf(buf , "%dx%d", &w, &h ) != 2 + || (w <= 0) + || (h <= 0)) { + report (RPT_WARNING, "CURSES: Cannot read size: %s. Using default value.\n", buf); + //sscanf( CONF_DEF_SIZE , "%dx%d", &width, &height ); + // default value is already set + } + else { + width = w; + height = h; } - driver->wid = wid; - driver->hgt = hgt; /*Get position settings*/ - if (0<=config_get_int ( DriverName , "topleftx" , 0 , CONF_DEF_TOP_LEFT_X) && config_get_int ( DriverName , "topleftx" , 0 , CONF_DEF_TOP_LEFT_X) <= 255) { - screen_begx = config_get_int ( DriverName , "topleftx" , 0 , CONF_DEF_TOP_LEFT_X); + if (0<=drvthis->config_get_int ( drvthis->name , "topleftx" , 0 , CONF_DEF_TOP_LEFT_X) && drvthis->config_get_int ( drvthis->name , "topleftx" , 0 , CONF_DEF_TOP_LEFT_X) <= 255) { + screen_begx = drvthis->config_get_int ( drvthis->name , "topleftx" , 0 , CONF_DEF_TOP_LEFT_X); } else { report (RPT_WARNING, "CURSES: topleftx must between 0 and 255. Using default value %d.\n",CONF_DEF_TOP_LEFT_X); } - if (0<=config_get_int ( DriverName , "toplefty" , 0 , CONF_DEF_TOP_LEFT_Y) && config_get_int ( DriverName , "toplefty" , 0 , CONF_DEF_TOP_LEFT_Y) <= 255) { - screen_begy = config_get_int ( DriverName , "toplefty" , 0 , CONF_DEF_TOP_LEFT_Y); + if (0<=drvthis->config_get_int ( drvthis->name , "toplefty" , 0 , CONF_DEF_TOP_LEFT_Y) && drvthis->config_get_int ( drvthis->name , "toplefty" , 0 , CONF_DEF_TOP_LEFT_Y) <= 255) { + screen_begy = drvthis->config_get_int ( drvthis->name , "toplefty" , 0 , CONF_DEF_TOP_LEFT_Y); } else { report (RPT_WARNING, "CURSES: toplefty must between 0 and 255. Using default value %d.\n",CONF_DEF_TOP_LEFT_Y); } @@ -302,8 +320,8 @@ curses_drv_init (struct lcd_logical_driver *driver, char *args) intrflush (stdscr, FALSE); keypad (stdscr, TRUE); - lcd_win = newwin(curses_drv->hgt + 2, - curses_drv->wid + 2, + lcd_win = newwin(height + 2, + width + 2, screen_begy, screen_begx); @@ -325,38 +343,41 @@ curses_drv_init (struct lcd_logical_driver *driver, char *args) current_border_pair = 3; } - curses_drv_clear (); + curses_drv_clear (drvthis); - driver->daemonize = 0; // don't daemonize... + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - // Override output functions... - driver->clear = curses_drv_clear; - driver->string = curses_drv_string; - driver->chr = curses_drv_chr; - driver->vbar = curses_drv_vbar; - //driver->init_vbar = NULL; - driver->hbar = curses_drv_hbar; - //driver->init_hbar = NULL; - driver->num = curses_drv_num; - driver->init_num = curses_drv_init_num; + // Set the functions the driver supports + drvthis->init = curses_drv_init; + drvthis->close = curses_drv_close; + drvthis->width = curses_drv_width; + drvthis->height = curses_drv_height; + drvthis->clear = curses_drv_clear; + drvthis->flush = curses_drv_flush; + drvthis->string = curses_drv_string; + drvthis->chr = curses_drv_chr; - driver->init = curses_drv_init; - driver->close = curses_drv_close; - driver->flush = curses_drv_flush; - driver->flush_box = curses_drv_flush_box; - //driver->contrast = NULL; - driver->backlight = curses_drv_backlight; - //driver->set_char = NULL; - driver->icon = curses_drv_icon; - driver->draw_frame = curses_drv_draw_frame; + drvthis->old_vbar = curses_drv_vbar; + //drvthis->init_vbar = NULL; + drvthis->old_hbar = curses_drv_hbar; + //drvthis->init_hbar = NULL; + drvthis->num = curses_drv_num; + //drvthis->init_num = curses_drv_init_num; - driver->getkey = curses_drv_getkey; - driver->heartbeat = curses_drv_heartbeat; + drvthis->backlight = curses_drv_backlight; + //drvthis->set_char = NULL; + drvthis->old_icon = curses_drv_icon; // NEEDS TO BE CHANGED ! + + drvthis->getkey = curses_drv_getkey; + drvthis->heartbeat = curses_drv_heartbeat; // Change the character used for "..." ELLIPSIS = '~'; - return 200; // 200 is arbitrary. (must be 1 or more) + return 0; } static void @@ -383,8 +404,8 @@ curses_drv_wborder (WINDOW *win) { #endif } -void -curses_drv_close () +MODULE_EXPORT void +curses_drv_close (Driver *drvthis) { // Note that the program leaves a screen on // the display to be left behind after closing; @@ -397,62 +418,69 @@ curses_drv_close () move (0, 0); endwin (); curs_set(1); +} - if (curses_drv->framebuf != NULL) - free (curses_drv->framebuf); - - curses_drv->framebuf = NULL; +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +curses_drv_width (Driver *drvthis) +{ + return width; +} +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +curses_drv_height (Driver *drvthis) +{ + return height; } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -curses_drv_clear () +MODULE_EXPORT void +curses_drv_clear (Driver *drvthis) { wbkgdset(lcd_win, COLOR_PAIR(current_color_pair) | ' '); curses_drv_wborder (lcd_win); werase (lcd_win); } -#define ValidX(x) { if ((x) > curses_drv->wid) { (x) = curses_drv->wid; } else (x) = (x) < 1 ? 1 : x; } -#define ValidY(y) { if ((y) > curses_drv->hgt) { (y) = curses_drv->hgt; } else (y) = (y) < 1 ? 1 : y; } +#define ValidX(x) { if ((x) > width) { (x) = width; } else (x) = (x) < 1 ? 1 : x; } +#define ValidY(y) { if ((y) > height) { (y) = height; } else (y) = (y) < 1 ? 1 : y; } -void -curses_drv_backlight (int on) +MODULE_EXPORT void +curses_drv_backlight (Driver *drvthis, int promille) { - if (curses_backlight_state == on) + if (curses_backlight_state == promille) return; // no backlight: pairs 2, 3 // backlight: pairs 4, 5 - switch (on) { - case 0: - curses_backlight_state = 0; - current_color_pair = 2; - current_border_pair = 3; - break; - case 1: - curses_backlight_state = 1; - current_color_pair = 4; - current_border_pair = 5; - break; - default: - return; - break; + curses_backlight_state = promille; + + if (promille) { + current_color_pair = 4; + current_border_pair = 5; + } + else { + current_color_pair = 2; + current_border_pair = 3; } - curses_drv_clear(); + curses_drv_clear(drvthis); } ///////////////////////////////////////////////////////////////// // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -curses_drv_string (int x, int y, char *string) +MODULE_EXPORT void +curses_drv_string (Driver *drvthis, int x, int y, char *string) { //int i; unsigned char *p; @@ -483,8 +511,8 @@ curses_drv_string (int x, int y, char *string) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -curses_drv_chr (int x, int y, char c) +MODULE_EXPORT void +curses_drv_chr (Driver *drvthis, int x, int y, char c) { int ch; @@ -504,7 +532,7 @@ curses_drv_chr (int x, int y, char c) if ((ch = getch ()) != ERR) if (ch == 0x0C) { - curses_drv_restore_screen(); + curses_drv_restore_screen(drvthis); ungetch(ch); } @@ -514,8 +542,8 @@ curses_drv_chr (int x, int y, char c) ///////////////////////////////////////////////////////////////// // Sets up for big numbers. // -void -curses_drv_init_num () +MODULE_EXPORT void +curses_drv_init_num (Driver *drvthis) { ; } @@ -523,47 +551,47 @@ curses_drv_init_num () ///////////////////////////////////////////////////////////////// // Writes a big number. // -void -curses_drv_num (int x, int num) +MODULE_EXPORT void +curses_drv_num (Driver *drvthis, int x, int num) { int y, dx; for (y = 1; y < 5; y++) for (dx = 0; dx < 3; dx++) - curses_drv_chr (x + dx, y, num_icon[num][y-1][dx]); + curses_drv_chr (drvthis, x + dx, y, num_icon[num][y-1][dx]); // printf("%1d",num); } ///////////////////////////////////////////////////////////////// // Draws a vertical bar; erases entire column onscreen. // -void -curses_drv_vbar (int x, int len) +MODULE_EXPORT void +curses_drv_vbar (Driver *drvthis, int x, int len) { int y; char map[] = { ACS_S9, ACS_S9, ACS_S7, ACS_S7, ACS_S3, ACS_S3, ACS_S1, ACS_S1 }; ValidX(x); -#define MAX_LINES (curses_drv->cellhgt * curses_drv->hgt) +#define MAX_LINES (LCD_DEFAULT_CELLHEIGHT * height) len = len > (MAX_LINES - 1) ? (MAX_LINES - 1) : len; len = len < 0 ? 0 : len; // len is the length of the bar (in pixels/scanlines) - // y is one character line (cellhgt pixels/scanlines) + // y is one character line (cellheight pixels/scanlines) - for (y = curses_drv->hgt; y > 0 && len > 0; y--) { + for (y = height; y > 0 && len > 0; y--) { - if (len >= curses_drv->cellhgt) { + if (len >= LCD_DEFAULT_CELLHEIGHT) { // write a "full" block to the screen... //curses_drv_chr (x, y, '8'); - curses_drv_chr (x, y, ACS_BLOCK); - len -= curses_drv->cellhgt; + curses_drv_chr (drvthis, x, y, ACS_BLOCK); + len -= LCD_DEFAULT_CELLHEIGHT; } else { // write a partial block... - curses_drv_chr (x, y, map[len-1]); + curses_drv_chr (drvthis, x, y, map[len-1]); break; } @@ -577,16 +605,16 @@ curses_drv_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void -curses_drv_hbar (int x, int y, int len) +MODULE_EXPORT void +curses_drv_hbar (Driver *drvthis, int x, int y, int len) { - for (; x <= curses_drv->wid && len > 0; x++) { - if (len >= curses_drv->cellwid) - curses_drv_chr (x, y, '='); + for (; x <= width && len > 0; x++) { + if (len >= LCD_DEFAULT_CELLWIDTH) + curses_drv_chr (drvthis, x, y, '='); else - curses_drv_chr (x, y, '-'); + curses_drv_chr (drvthis, x, y, '-'); - len -= curses_drv->cellwid; + len -= LCD_DEFAULT_CELLWIDTH; } // move(y-1, x-1); @@ -596,8 +624,8 @@ curses_drv_hbar (int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets character 0 to an icon... // -void -curses_drv_icon (int which, char dest) +MODULE_EXPORT void +curses_drv_icon (Driver *drvthis, int which, char dest) { if (dest == 0) switch (which) { @@ -617,8 +645,8 @@ curses_drv_icon (int which, char dest) ///////////////////////////////////////////////////////////// // Does the heartbeat... // -void -curses_drv_heartbeat (int type) +MODULE_EXPORT void +curses_drv_heartbeat (Driver *drvthis, int type) { static int timer = 0; int whichIcon; @@ -633,13 +661,13 @@ curses_drv_heartbeat (int type) // This defines a custom character EVERY time... // not efficient... is this necessary? - curses_drv_icon (whichIcon, 0); + curses_drv_icon (drvthis, whichIcon, 0); // Put character on screen... - curses_drv_chr (curses_drv->wid, 1, 0); + curses_drv_chr (drvthis, width, 1, 0); // change display... - curses_drv_flush (); + curses_drv_flush (drvthis); } timer++; @@ -649,26 +677,14 @@ curses_drv_heartbeat (int type) ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -void -curses_drv_flush () -{ - curses_drv_draw_frame (curses_drv->framebuf); -} - -void -curses_drv_flush_box (int lft, int top, int rgt, int bot) -{ - curses_drv_flush (); -} - -void -curses_drv_draw_frame (char *dat) +MODULE_EXPORT void +curses_drv_flush (Driver *drvthis) { int c; if ((c = getch ()) != ERR) if (c == 0x0C) { - curses_drv_restore_screen(); + curses_drv_restore_screen(drvthis); ungetch (c); } @@ -676,8 +692,9 @@ curses_drv_draw_frame (char *dat) wrefresh (lcd_win); } -char -curses_drv_getkey () + +MODULE_EXPORT char +curses_drv_getkey (Driver *drvthis) { int i; @@ -685,7 +702,7 @@ curses_drv_getkey () switch(i) { case 0x0C: - curses_drv_restore_screen(); + curses_drv_restore_screen(drvthis); return 0; break; case KEY_LEFT: @@ -710,7 +727,8 @@ curses_drv_getkey () } void -curses_drv_restore_screen () { +curses_drv_restore_screen (Driver *drvthis) { + erase(); refresh(); #ifdef CURSES_HAS_REDRAWWIN diff --git a/server/drivers/curses_drv.h b/server/drivers/curses_drv.h index 6fd5f8f..3b74f3e 100644 --- a/server/drivers/curses_drv.h +++ b/server/drivers/curses_drv.h @@ -1,31 +1,34 @@ #ifndef LCD_CURSES_H #define LCD_CURSES_H -extern lcd_logical_driver *curses_drv; +#include "lcd.h" -int curses_drv_init (struct lcd_logical_driver *driver, char *args); -void curses_drv_backlight (int on); -void curses_drv_close (); -void curses_drv_clear (); -void curses_drv_flush (); -void curses_drv_string (int x, int y, char string[]); -void curses_drv_chr (int x, int y, char c); -void curses_drv_vbar (int x, int len); -void curses_drv_hbar (int x, int y, int len); -void curses_drv_icon (int which, char dest); -void curses_drv_flush (); -void curses_drv_flush_box (int lft, int top, int rgt, int bot); -void curses_drv_draw_frame (char *dat); -char curses_drv_getkey (); -void curses_drv_init_num (); -void curses_drv_num (int x, int num); -void curses_drv_heartbeat (int type); + int curses_drv_init (Driver * drvthis, char *args); +MODULE_EXPORT void curses_drv_close (Driver *drvthis); +MODULE_EXPORT int curses_drv_width (Driver *drvthis); +MODULE_EXPORT int curses_drv_height (Driver *drvthis); +MODULE_EXPORT void curses_drv_clear (Driver *drvthis); +MODULE_EXPORT void curses_drv_flush (Driver *drvthis); +MODULE_EXPORT void curses_drv_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void curses_drv_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void curses_drv_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void curses_drv_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void curses_drv_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void curses_drv_heartbeat (Driver *drvthis, int type); +MODULE_EXPORT void curses_drv_icon (Driver *drvthis, int which, char dest); + +MODULE_EXPORT void curses_drv_backlight (Driver *drvthis, int on); + +MODULE_EXPORT char curses_drv_getkey (Driver *drvthis); + +MODULE_EXPORT void curses_drv_init_num (Driver *drvthis); /*Default settings for config file parsing*/ #define CONF_DEF_FOREGR "blue" #define CONF_DEF_BACKGR "cyan" #define CONF_DEF_BACKLIGHT "red" -#define CONF_DEF_SIZE "20x4" +#define CONF_DEF_SIZE "20x4" // currently not used, LCD_DEFAULT_WIDTH etc. is used #define CONF_DEF_TOP_LEFT_X 7 #define CONF_DEF_TOP_LEFT_Y 7 diff --git a/server/drivers/debug.c b/server/drivers/debug.c index 5306508..9e3e846 100644 --- a/server/drivers/debug.c +++ b/server/drivers/debug.c @@ -6,9 +6,28 @@ #include #include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "lcd.h" #include "debug.h" -#include "shared/report.h" +#include "report.h" + + +// Variables +static char *framebuf = NULL; +static int width = LCD_DEFAULT_WIDTH; +static int height = LCD_DEFAULT_HEIGHT; + + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "debug_"; + + ////////////////////////////////////////////////////////////////////////// ////////////////////// For Debugging Output ////////////////////////////// @@ -17,86 +36,127 @@ // TODO: somehow allow access to the driver->framebuffer to each // function... -static lcd_logical_driver *debug_drv; - int -debug_init (struct lcd_logical_driver *driver, char *args) +debug_init (Driver *drvthis, char *args) { report (RPT_INFO, "debug_init()"); - debug_drv = driver; + framebuf = malloc (width * height); - debug_clear (); + debug_clear (drvthis); - driver->daemonize = 0; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->clear = debug_clear; - driver->string = debug_string; - driver->chr = debug_chr; - driver->vbar = debug_vbar; - driver->hbar = debug_hbar; - driver->init_num = debug_init_num; - driver->num = debug_num; + // Set the functions the driver supports + drvthis->clear = debug_clear; + drvthis->string = debug_string; + drvthis->chr = debug_chr; + drvthis->old_vbar = debug_vbar; + drvthis->old_hbar = debug_hbar; + drvthis->init_num = debug_init_num; + drvthis->num = debug_num; - driver->init = debug_init; - driver->close = debug_close; - driver->flush = debug_flush; - driver->flush_box = debug_flush_box; - driver->contrast = debug_contrast; - driver->backlight = debug_backlight; - driver->set_char = debug_set_char; - driver->icon = debug_icon; - driver->init_vbar = debug_init_vbar; - driver->init_hbar = debug_init_hbar; - driver->draw_frame = debug_draw_frame; + drvthis->init = debug_init; + drvthis->close = debug_close; + drvthis->width = debug_width; + drvthis->height = debug_height; + drvthis->flush = debug_flush; + drvthis->set_contrast = debug_set_contrast; + drvthis->backlight = debug_backlight; + drvthis->set_char = debug_set_char; + drvthis->old_icon = debug_icon; + drvthis->init_vbar = debug_init_vbar; + drvthis->init_hbar = debug_init_hbar; - driver->getkey = debug_getkey; + drvthis->getkey = debug_getkey; - return 200; // 200 is arbitrary. (must be 1 or more) + return 0; } -void -debug_close () +///////////////////////////////////////////////////////////////// +// Closes the driver +// +MODULE_EXPORT void +debug_close (Driver *drvthis) { report (RPT_INFO, "debug_close()"); - if (debug_drv->framebuf) { - report (RPT_DEBUG, "frame buffer: %010X", (int) debug_drv->framebuf); - free (debug_drv->framebuf); - } + if(framebuf) free (framebuf); + framebuf = NULL; +} - debug_drv->framebuf = NULL; +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +debug_width (Driver *drvthis) +{ + return width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +debug_height (Driver *drvthis) +{ + return height; } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -debug_clear () +MODULE_EXPORT void +debug_clear (Driver *drvthis) { report (RPT_INFO, "clear()"); - memset (debug_drv->framebuf, ' ', debug_drv->wid * debug_drv->hgt); + memset (framebuf, ' ', width * height); } ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -void -debug_flush () +MODULE_EXPORT void +debug_flush (Driver *drvthis) { + int i, j; + char out[LCD_MAX_WIDTH]; + report (RPT_INFO, "flush()"); - debug_drv->draw_frame (); + for (i = 0; i < width; i++) { + out[i] = '-'; + } + out[width] = 0; + //report (RPT_DEBUG, "+%s+", out); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + out[j] = framebuf[j + (i * width)]; + } + out[width] = 0; + //report (RPT_DEBUG, "|%s|", out); + + } + + for (i = 0; i < width; i++) { + out[i] = '-'; + } + out[width] = 0; + //report (RPT_DEBUG, "+%s+", out); } ///////////////////////////////////////////////////////////////// // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -debug_string (int x, int y, char string[]) +MODULE_EXPORT void +debug_string (Driver *drvthis, int x, int y, char string[]) { int i; @@ -106,7 +166,7 @@ debug_string (int x, int y, char string[]) y --; x --; // Convert 1-based coords to 0-based... for (i = 0; string[i]; i++) { - debug_drv->framebuf[(y * debug_drv->wid) + x + i] = string[i]; + framebuf[(y * width) + x + i] = string[i]; } } @@ -114,54 +174,53 @@ debug_string (int x, int y, char string[]) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -debug_chr (int x, int y, char c) +MODULE_EXPORT void +debug_chr (Driver *drvthis, int x, int y, char c) { report (RPT_DEBUG, "char(%i,%i,%c)", x, y, c); x--; y--; - debug_drv->framebuf[(y * debug_drv->wid) + x] = c; + framebuf[(y * width) + x] = c; } -int -debug_contrast (int contrast) +MODULE_EXPORT void +debug_set_contrast (Driver *drvthis, int promille) { - report (RPT_INFO, "contrast(%i)", contrast); - return 0; + report (RPT_INFO, "set_contrast(%i)", promille); } -void -debug_backlight (int on) +MODULE_EXPORT void +debug_backlight (Driver *drvthis, int on) { report (RPT_INFO, "backlight(%i)", on); } -void -debug_init_vbar () +MODULE_EXPORT void +debug_init_vbar (Driver *drvthis) { - report (LOG_INFO, "init_vbar()"); + report (RPT_INFO, "init_vbar()"); } -void -debug_init_hbar () +MODULE_EXPORT void +debug_init_hbar (Driver *drvthis) { report (RPT_INFO, "init_hbar()"); } -void -debug_init_num () +MODULE_EXPORT void +debug_init_num (Driver *drvthis) { report (RPT_INFO, "init_bignum()"); } -void -debug_num (int x, int num) +MODULE_EXPORT void +debug_num (Driver *drvthis, int x, int num) { report (RPT_INFO, "big number(%i,%i)", x, num); } -void -debug_set_char (int n, char *dat) +MODULE_EXPORT void +debug_set_char (Driver *drvthis, int n, char *dat) { report (RPT_INFO, "set_char(%i,data)", n); } @@ -169,17 +228,17 @@ debug_set_char (int n, char *dat) ///////////////////////////////////////////////////////////////// // Draws a vertical bar; erases entire column onscreen. // -void -debug_vbar (int x, int len) +MODULE_EXPORT void +debug_vbar (Driver *drvthis, int x, int len) { int y; report (RPT_INFO, "vbar(%i,%i)", x, len); - for (y = debug_drv->hgt; y > 0 && len > 0; y--) { - debug_chr (x, y, '|'); + for (y = height; y > 0 && len > 0; y--) { + debug_chr (drvthis, x, y, '|'); - len -= debug_drv->cellhgt; + len -= LCD_DEFAULT_CELLHEIGHT; } } @@ -187,15 +246,15 @@ debug_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void -debug_hbar (int x, int y, int len) +MODULE_EXPORT void +debug_hbar (Driver *drvthis, int x, int y, int len) { report (RPT_INFO, "hbar(%i,%i,%i)", x, y, len); - for (; x < debug_drv->wid && len > 0; x++) { - debug_chr (x, y, '-'); + for (; x < width && len > 0; x++) { + debug_chr (drvthis, x, y, '-'); - len -= debug_drv->cellwid; + len -= LCD_DEFAULT_CELLWIDTH; } } @@ -203,59 +262,17 @@ debug_hbar (int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets character 0 to an icon... // -void -debug_icon (int which, char dest) +MODULE_EXPORT void +debug_icon (Driver *drvthis, int which, char dest) { report (RPT_INFO, "icon(%i,%i", which, dest); } -void -debug_flush_box (int lft, int top, int rgt, int bot) -{ - report (RPT_INFO, "flush_box(%i,%i,%i,%i)", lft, top, rgt, bot); - - debug_flush (); -} - -void -debug_draw_frame (char *dat) -{ - int i, j; - - char out[LCD_MAX_WIDTH]; - - report (RPT_INFO, "draw_frame(data)"); - - if (!dat) - return; - -// report (RPT_DEBUG, "Frame (%ix%i): %s", debug_drv->wid, debug_drv->hgt, dat); - - for (i = 0; i < debug_drv->wid; i++) { - out[i] = '-'; - } - out[debug_drv->wid] = 0; - //report (RPT_DEBUG, "+%s+", out); - - for (i = 0; i < debug_drv->hgt; i++) { - for (j = 0; j < debug_drv->wid; j++) { - out[j] = dat[j + (i * debug_drv->wid)]; - } - out[debug_drv->wid] = 0; - //report (RPT_DEBUG, "|%s|", out); - - } - - for (i = 0; i < debug_drv->wid; i++) { - out[i] = '-'; - } - out[debug_drv->wid] = 0; - //report (RPT_DEBUG, "+%s+", out); - -} - -char -debug_getkey () +///////////////////////////////////////////////////////////////// +// Return a keypress +// +MODULE_EXPORT char +debug_getkey (Driver *drvthis) { report (RPT_INFO, "getkey()"); return 0; diff --git a/server/drivers/debug.h b/server/drivers/debug.h index 373367f..9bdf4a0 100644 --- a/server/drivers/debug.h +++ b/server/drivers/debug.h @@ -1,24 +1,31 @@ #ifndef LCD_DEBUG_H #define LCD_DEBUG_H -int debug_init (struct lcd_logical_driver *driver, char *args); -void debug_close (); -void debug_clear (); -void debug_flush (); -void debug_string (int x, int y, char string[]); -void debug_chr (int x, int y, char c); -int debug_contrast (int contrast); -void debug_backlight (int on); -void debug_init_vbar (); -void debug_init_hbar (); -void debug_init_num (); -void debug_vbar (int x, int len); -void debug_hbar (int x, int y, int len); -void debug_num (int x, int num); -void debug_set_char (int n, char *dat); -void debug_icon (int which, char dest); -void debug_flush_box (int lft, int top, int rgt, int bot); -void debug_draw_frame (char *dat); -char debug_getkey (); +#include "lcd.h" + + int debug_init (Driver *drvthis, char *args); +MODULE_EXPORT void debug_close (Driver *drvthis); +MODULE_EXPORT int debug_width (Driver *drvthis); +MODULE_EXPORT int debug_height (Driver *drvthis); +MODULE_EXPORT void debug_clear (Driver *drvthis); +MODULE_EXPORT void debug_flush (Driver *drvthis); +MODULE_EXPORT void debug_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void debug_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void debug_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void debug_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void debug_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void debug_icon (Driver *drvthis, int which, char dest); + +MODULE_EXPORT void debug_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT void debug_set_contrast (Driver *drvthis, int promille); +MODULE_EXPORT void debug_backlight (Driver *drvthis, int promille); + +MODULE_EXPORT char debug_getkey (Driver *drvthis); + +MODULE_EXPORT void debug_init_vbar (Driver *drvthis); +MODULE_EXPORT void debug_init_hbar (Driver *drvthis); +MODULE_EXPORT void debug_init_num (Driver *drvthis); #endif diff --git a/server/drivers/glk.c b/server/drivers/glk.c index 6c4926e..1c79997 100644 --- a/server/drivers/glk.c +++ b/server/drivers/glk.c @@ -40,34 +40,40 @@ static unsigned char CGRAM[8] = { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0 //////////////////// Matrix Orbital Graphical Driver ///////////////////// ////////////////////////////////////////////////////////////////////////// -lcd_logical_driver *glk; - static unsigned char * screen_contents = NULL ; -int fontselected = 0 ; -int gpo_count = 0 ; +static int fontselected = 0 ; +static int gpo_count = 0 ; + +static char *framebuf = NULL; +static int width = 0; +static int height = 0; +static int cellwidth = LCD_DEFAULT_CELLWIDTH; +static int cellheight = LCD_DEFAULT_CELLHEIGHT; +static int contrast; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "glk_"; -// TODO: Get lcd.framebuf to properly work as whatever driver is running... //////////////////////////////////////////////////////////// // init() should set up any device-specific stuff, and // point all the function pointers. -int glk_init(struct lcd_logical_driver *driver, char *args) +int +glk_init(Driver *drvthis, char *args) { char * argv[64]; int argc; char * device = "/dev/lcd" ; - int contrast = 140; speed_t speed = B19200 ; - int i ; - int width ; - int height ; + contrast = 560; // printf("glk_init()\n"); - glk = driver; - argc = get_args( argv, args, 64 ); for( i = 0 ; i < argc; ++i ) { if( 0 == strcmp( argv[i], "-d") @@ -120,7 +126,7 @@ int glk_init(struct lcd_logical_driver *driver, char *args) "LCDproc Matrix-Orbital GLK Graphical LCD driver\n" "\n" "-d, --device select the serial device to use [/dev/lcd]\n" -"-c, --contrast set the initial contrast value [140]\n" +"-c, --contrast set the initial contrast value [560]\n" "-s, --speed set the serial port speed [19200]\n" "-h, --help display this help text\n" ); @@ -168,22 +174,17 @@ int glk_init(struct lcd_logical_driver *driver, char *args) return( -1 ); }; }; - driver->wid = width ; - driver->hgt = height ; - // You must use driver->framebuf here, but may use lcd.framebuf later. - if(!driver->framebuf) { - driver->framebuf = malloc(driver->wid * driver->hgt); - }; - screen_contents = malloc( driver->wid * driver->hgt ); + framebuf = malloc(width * height); + screen_contents = malloc( width * height ); - if(driver->framebuf == NULL || screen_contents == NULL ) { + if(framebuf == NULL || screen_contents == NULL ) { fprintf( stderr, "glk: Unable to allocate memory for screen buffers\n" ); - glk_close(); + glk_close(drvthis); return -1; } - memset(driver->framebuf, ' ', driver->wid*driver->hgt); + memset(framebuf, ' ', width*height); // glk_clear(); // glkputl( PortFD, GLKCommand, 0x58, EOF ); @@ -203,70 +204,92 @@ int glk_init(struct lcd_logical_driver *driver, char *args) glkputl( PortFD, GLKCommand, 0x7e, 1, GLKCommand, 0x41, EOF ); // Set contrast - glk_contrast( contrast ); + glk_set_contrast( drvthis, contrast ); - driver->cellwid = 5; - driver->cellhgt = 8; - - driver->clear = glk_clear; - driver->string = glk_string; - driver->chr = glk_chr; - driver->vbar = glk_vbar; - driver->init_vbar = glk_init_vbar; - driver->hbar = glk_hbar; - driver->init_hbar = glk_init_hbar; - driver->num = glk_num ; - driver->init_num = glk_init_num ; - - driver->init = glk_init; - driver->close = glk_close; - driver->flush = glk_flush; - driver->flush_box = glk_flush_box; - driver->contrast = glk_contrast; - driver->backlight = glk_backlight; - driver->output = glk_output; - driver->set_char = glk_set_char; - driver->icon = glk_icon; - driver->draw_frame = glk_draw_frame; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->getkey = glk_getkey; - - - return 200; // 200 is arbitrary. (must be 1 or more) + // Set the functions the driver supports + drvthis->clear = glk_clear; + drvthis->string = glk_string; + drvthis->chr = glk_chr; + drvthis->old_vbar = glk_vbar; + drvthis->init_vbar = glk_init_vbar; + drvthis->old_hbar = glk_hbar; + drvthis->init_hbar = glk_init_hbar; + drvthis->num = glk_num ; + drvthis->init_num = glk_init_num ; + + drvthis->init = glk_init; + drvthis->close = glk_close; + drvthis->flush = glk_flush; + drvthis->get_contrast = glk_get_contrast; + drvthis->set_contrast = glk_set_contrast; + drvthis->backlight = glk_backlight; + drvthis->output = glk_output; + drvthis->set_char = glk_set_char; + drvthis->old_icon = glk_icon; + + drvthis->getkey = glk_getkey; + + return 0; } -// Below here, you may use either lcd.framebuf or driver->framebuf.. -// lcd.framebuf will be set to the appropriate buffer before calling -// your driver. - -void glk_close() +///////////////////////////////////////////////////////////////// +// Close the driver +// +MODULE_EXPORT void +glk_close(Driver *drvthis) { - if(glk->framebuf != NULL) free(glk->framebuf); - - glk->framebuf = NULL; - glkclose( PortFD ) ; + + if(framebuf) free(framebuf); + framebuf = NULL; } + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +glk_width (Driver *drvthis) +{ + return width; +} + + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +glk_height (Driver *drvthis) +{ + return height; +} + + ///////////////////////////////////////////////////////////////// // Clears the LCD screen // #define CLEARCOUNT (1000000) static int clearcount = 0 ; -void glk_clear_forced() +void glk_clear_forced(Driver *drvthis) { // puts( "REALLY CLEARING the display" ); clearcount = CLEARCOUNT ; glkputl( PortFD, GLKCommand, 0x58, EOF ); - memset(screen_contents, ' ', glk->wid*glk->hgt); + memset(screen_contents, ' ', width*height); } -void glk_clear() +MODULE_EXPORT void +glk_clear(Driver *drvthis) { // puts( "glk_clear( )" ); - memset(glk->framebuf, ' ', glk->wid*glk->hgt); + memset(framebuf, ' ', width*height); if( --clearcount < 0 ) { - glk_clear_forced( ); + glk_clear_forced(drvthis); }; } @@ -274,10 +297,47 @@ void glk_clear() ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -void glk_flush() +MODULE_EXPORT void +glk_flush(Driver *drvthis) { // puts( "glk_flush( )" ); - glk->draw_frame(glk->framebuf); + char * p ; + char * q ; + int x, y ; + int xs ; + char * ps = NULL ; + +// printf( "flush()\n" ); + + p = framebuf ; + q = screen_contents ; + + for( y = 0 ; y < height ; ++y ) { + xs = -1 ; /* XStart not set */ + for( x = 0 ; x < width ; ++x ) { + if( *q == *p && xs >= 0 ) { + /* Write accumulated string */ + glkputl( PortFD, GLKCommand, 0x79, xs*6+1, y*8, EOF ); + glkputa( PortFD, x - xs, ps ); +// printf( "draw_frame: Writing at (%d,%d) for %d\n", xs, y, x-xs ); + xs = -1 ; + } else if( *q != *p && xs < 0 ) { + /* Start new string of changes */ + ps = p ; + xs = x ; + }; + *q++ = *p++ ; /* Update screen_contents from framebuf */ + }; + if( xs >= 0 ) { + /* Write accumulated line */ + glkputl( PortFD, GLKCommand, 0x79, xs*6+1, y*8, EOF ); + glkputa( PortFD, width - xs, ps ); +// printf( "draw_frame: Writing at (%d,%d) for %d\n", xs, y, width-xs ); + }; + + }; /* For y */ + + return ; } @@ -285,18 +345,19 @@ void glk_flush() // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void glk_string(int x, int y, char string[]) +MODULE_EXPORT void +glk_string(Driver *drvthis, int x, int y, char string[]) { char * p ; // printf( "glk_string( %d, %d, \"%s\" )\n", x, y, string ); - if( x > glk->wid || y > glk->hgt ) { + if( x > width || y > height ) { return ; }; - for( p = string ; *p && x <= glk->wid ; ++x, ++p ) { - glk_chr( x, y, *p ); + for( p = string ; *p && x <= width ; ++x, ++p ) { + glk_chr( drvthis, x, y, *p ); }; } @@ -305,7 +366,8 @@ void glk_string(int x, int y, char string[]) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void glk_chr(int x, int y, char c) +MODULE_EXPORT void +glk_chr(Driver *drvthis, int x, int y, char c) { int myc = (unsigned char) c ; x -= 1; // Convert 1-based coords to 0-based... @@ -319,7 +381,7 @@ void glk_chr(int x, int y, char c) /* Set font metrics */ glkputl( PortFD, GLKCommand, 0x32, 1, 0, 1, 1, 32, EOF ); /* Clear the screen */ - glk_clear_forced( ); + glk_clear_forced(drvthis); }; if( myc >= 0 && myc <= 15 ) { @@ -335,9 +397,22 @@ void glk_chr(int x, int y, char c) fprintf( stderr, "Attempt to write %d to (%d,%d)\n", myc, x, y ); myc = 133 ; }; - - glk->framebuf[(y*glk->wid) + x] = myc; + framebuf[(y*width) + x] = myc; + +} + + +///////////////////////////////////////////////////////////////// +// Returns current contrast +// This is only the locally stored contrast, the contrast value +// cannot be retrieved from the LCD. +// Value 0 to 1000. +// +MODULE_EXPORT int +glk_get_contrast(Driver *drvthis) +{ + return contrast; } @@ -345,22 +420,26 @@ void glk_chr(int x, int y, char c) // Sets the contrast of the display. Value is 0-255, where 140 is // what I consider "just right". // -int glk_contrast(int contrast) +MODULE_EXPORT void +glk_set_contrast(Driver *drvthis, int promille) { - static int saved_contrast = 140 ; + // Check it + if( contrast < 0 || contrast > 1000 ) + return; - if( contrast > 0 && contrast < 256 ) { - saved_contrast = contrast ; + // Store it + contrast = promille; + + // Do it // printf("Contrast: %i\n", contrast); - glkputl( PortFD, GLKCommand, 0x50, contrast, EOF ); - }; - return( saved_contrast ); + glkputl( PortFD, GLKCommand, 0x50, (int) ((long)promille * 255 / 1000), EOF ); } ////////////////////////////////////////////////////////////////////// // Turns the lcd backlight on or off... // -void glk_backlight(int on) +MODULE_EXPORT void +glk_backlight(Driver *drvthis, int on) { if(on) { // printf("Backlight ON\n"); @@ -373,8 +452,8 @@ void glk_backlight(int on) ////////////////////////////////////////////////////////////////////// // Sets general purpose outputs on or off -void -glk_output(int on) +MODULE_EXPORT void +glk_output(Driver *drvthis, int on) { if( gpo_count < 2 ) { if( on ) { glkputl( PortFD, GLKCommand, 'W', EOF ); @@ -395,7 +474,8 @@ glk_output(int on) ////////////////////////////////////////////////////////////////////// // Tells the driver to get ready for vertical bargraphs. // -void glk_init_vbar() +MODULE_EXPORT void +glk_init_vbar(Driver *drvthis) { // printf("Vertical bars.\n"); } @@ -403,7 +483,8 @@ void glk_init_vbar() ////////////////////////////////////////////////////////////////////// // Tells the driver to get ready for horizontal bargraphs. // -void glk_init_hbar() +MODULE_EXPORT void +glk_init_hbar(Driver *drvthis) { // printf("Horizontal bars.\n"); } @@ -411,7 +492,8 @@ void glk_init_hbar() ////////////////////////////////////////////////////////////////////// // Tells the driver to get ready for big numbers, if possible. // -void glk_init_num() +MODULE_EXPORT void +glk_init_num(Driver *drvthis) { // printf("Big Numbers.\n"); if( fontselected != 3 ) { @@ -421,23 +503,25 @@ void glk_init_num() /* Set font metrics */ glkputl( PortFD, GLKCommand, 0x32, 1, 0, 1, 1, 32, EOF ); /* Clear the screen */ - glk_clear_forced( ); + glk_clear_forced(drvthis); }; } ////////////////////////////////////////////////////////////////////// // Draws a big (4-row) number. // -void glk_num(int x, int num) +MODULE_EXPORT void +glk_num(Driver *drvthis, int x, int num) { // printf("BigNum(%i, %i)\n", x, num); - glk->framebuf[x-1] = num + '0' ; + framebuf[x-1] = num + '0' ; } ////////////////////////////////////////////////////////////////////// // Changes the font data of character n. // -void glk_set_char(int n, char *dat) +MODULE_EXPORT void +glk_set_char(Driver *drvthis, int n, char *dat) { printf("Set Character %i\n", n); } @@ -445,15 +529,16 @@ void glk_set_char(int n, char *dat) ///////////////////////////////////////////////////////////////// // Draws a vertical bar, from the bottom of the screen up. // -void glk_vbar(int x, int len) +MODULE_EXPORT void +glk_vbar(Driver *drvthis, int x, int len) { - int y = glk->hgt ; + int y = height ; // printf( "glk_vbar( %d, %d )\n", x, len ); - while( len > glk->cellhgt ) { - glk_chr( x, y, 255 ); + while( len > cellheight ) { + glk_chr( drvthis, x, y, 255 ); --y ; - len -= glk->cellhgt ; + len -= cellheight ; }; if( y >= 0 ) { @@ -468,23 +553,24 @@ void glk_vbar(int x, int len) case 6 : lastc = 143 ; break ; default: lastc = 133 ; break ; }; - glk_chr( x, y, lastc ); + glk_chr( drvthis, x, y, lastc ); }; } ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void glk_hbar(int x, int y, int len) +MODULE_EXPORT void +glk_hbar(Driver *drvthis, int x, int y, int len) { // printf( "glk_hbar( %d, %d, %d )\n", x, y, len ); - while( len > glk->cellwid ) { - glk_chr( x, y, 255 ); + while( len > cellwidth ) { + glk_chr( drvthis, x, y, 255 ); ++x ; - len -= glk->cellwid ; + len -= cellwidth ; }; - if( x <= glk->wid ) { + if( x <= width ) { int lastc ; switch( len ) { case 0 : lastc = ' ' ; break ; @@ -494,7 +580,7 @@ void glk_hbar(int x, int y, int len) case 4 : lastc = 137 ; break ; default: lastc = 133 ; break ; }; - glk_chr( x, y, lastc ); + glk_chr( drvthis, x, y, lastc ); }; } @@ -502,7 +588,8 @@ void glk_hbar(int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets character 0 to an icon... // -void glk_icon(int which, char dest) +MODULE_EXPORT void +glk_icon(Driver *drvthis, int which, char dest) { unsigned char old, new ; unsigned char * p ; @@ -529,11 +616,11 @@ void glk_icon(int which, char dest) old = CGRAM[(int)dest] ; CGRAM[(int)dest] = new ; - p = glk->framebuf ; + p = framebuf ; q = screen_contents ; /* Replace all old icons with new icon in new frame */ - for( count = glk->wid * glk->hgt ; count ; --count ) { + for( count = width * height ; count ; --count ) { if( *q == old ) { // printf( "icon %d to %d at %d\n", old, new, q - screen_contents ); *p = new ; @@ -545,77 +632,19 @@ void glk_icon(int which, char dest) } -////////////////////////////////////////////////////////////////////// -// Send a rectangular area to the display. -// -// I've just called glk_flush() because there's not much point yet -// in flushing less than the entire framebuffer. -// -void glk_flush_box(int lft, int top, int rgt, int bot) -{ -// printf("glk_flush_box( %d, %d, %d, %d )\n", lft, top, rgt, bot ); - glk_flush( ); -} - -////////////////////////////////////////////////////////////////////// -// Draws the framebuffer on the display. -// -// The commented-out code is from the text driver. -// -void glk_draw_frame(char *dat) -{ - char * p ; - char * q ; - int x, y ; - int xs ; - char * ps = NULL ; - -// printf( "glk_draw_frame( %p ) glk->framebuf = %p\n", dat, glk->framebuf ); - - p = glk->framebuf ; - q = screen_contents ; - - for( y = 0 ; y < glk->hgt ; ++y ) { - xs = -1 ; /* XStart not set */ - for( x = 0 ; x < glk->wid ; ++x ) { - if( *q == *p && xs >= 0 ) { - /* Write accumulated string */ - glkputl( PortFD, GLKCommand, 0x79, xs*6+1, y*8, EOF ); - glkputa( PortFD, x - xs, ps ); -// printf( "draw_frame: Writing at (%d,%d) for %d\n", xs, y, x-xs ); - xs = -1 ; - } else if( *q != *p && xs < 0 ) { - /* Start new string of changes */ - ps = p ; - xs = x ; - }; - *q++ = *p++ ; /* Update screen_contents from glk->framebuf */ - }; - if( xs >= 0 ) { - /* Write accumulated line */ - glkputl( PortFD, GLKCommand, 0x79, xs*6+1, y*8, EOF ); - glkputa( PortFD, glk->wid - xs, ps ); -// printf( "draw_frame: Writing at (%d,%d) for %d\n", xs, y, glk->wid-xs ); - }; - - }; /* For y */ - - return ; -} - - ////////////////////////////////////////////////////////////////////// // Tries to read a character from an input device... // // Return 0 for "nothing available". // -char glk_getkey() +MODULE_EXPORT char +glk_getkey(Driver *drvthis) { int c ; static int key = -1 ; static struct timeval lastkey ; struct timeval now ; - + // puts( "glk_getkey( )" ); c = glkgetc( PortFD ); diff --git a/server/drivers/glk.h b/server/drivers/glk.h index 900339f..7fbd55f 100644 --- a/server/drivers/glk.h +++ b/server/drivers/glk.h @@ -1,119 +1,33 @@ #ifndef GLK_H #define GLK_H -/******************************************************************** - How to make a driver for LCDproc +#include "lcd.h" - Note: Insert the name of your driver in place of the phrase "new_driver". - - 1. Copy drv_base.c and drv_base.h to new_driver.c and new_driver.h. + int glk_init(Driver *drvthis, char *args); +MODULE_EXPORT void glk_close(Driver *drvthis); +MODULE_EXPORT int glk_width(Driver *drvthis); +MODULE_EXPORT int glk_height(Driver *drvthis); +MODULE_EXPORT void glk_clear(Driver *drvthis); +MODULE_EXPORT void glk_flush(Driver *drvthis); +MODULE_EXPORT void glk_string(Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void glk_chr(Driver *drvthis, int x, int y, char c); - 2. Decide which functions you want to override, which ones you want - to leave alone, and which ones you don't want at all. If you - write your own driver functions, they will get called when - appropriate. Or, you can let the default driver "drv_base" - handle a function for you. But, if you really don't want a - function, you can completely prevent your driver from providing - it. This is discussed in step 5. - - 2.1. Remove all functions which you don't want to override, and the - ones you don't want at all. +MODULE_EXPORT void glk_vbar(Driver *drvthis, int x, int len); +MODULE_EXPORT void glk_hbar(Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void glk_num(Driver *drvthis, int x, int num); +MODULE_EXPORT void glk_icon(Driver *drvthis, int which, char dest); - 3. Rename all functions from "drv_base_*" to "new_driver_*". +MODULE_EXPORT void glk_set_char(Driver *drvthis, int n, char *dat); - 4. Write the new driver functions. - Be sure to do one of the following in/for your new_driver_close(): - - free the framebuffer lcd.framebuf - - let the default driver handle close() - - call drv_base_close() - This will ensure that the frame buffer gets freed. +MODULE_EXPORT int glk_get_contrast(Driver *drvthis); +MODULE_EXPORT void glk_set_contrast(Driver *drvthis, int promille); +MODULE_EXPORT void glk_backlight(Driver *drvthis, int on); +MODULE_EXPORT void glk_output(Driver *drvthis, int on); - 5. Register your functions in your new_driver_init(), like the following: - driver->clear = new_driver_clear; // We want to handle this one - driver->string = (void *)-1; // Leave this to the default - driver->getkey = NULL; // This should never get called - - The convention here is to set NULL for all the functions which - your driver doesn't handle (and which you don't want the default - functions to be called for). Or, set -1 to indicate that the - driver should support the function but can use the default - behavior in drv_base.c. Or, to indicate that your driver should - handle a function, just set it like clear() above. - - 6. Add the driver to lcd.c, in the physical drivers section, protected - by an #ifdef like the rest of the drivers are. - - 7. Add your driver to the Makefile, and Makefile.config, in the same - style as the existing ones. - - - Notes: - - Don't call lcd.whatever() functions within your driver. This causes - a lot of potentially puzzling problems. - - However, feel free to access lcd.framebuf in your driver (but not in - your init() function!). It will always point to the frame buffer - you should be writing to. This will usually be your own frame - buffer, but could potentially be another frame buffer, if another - driver wants to access your functions. - - Your driver will be provided with a frame buffer which contains one - byte per character on the LCD. The default is a 20x4, so that's 80 - bytes. You can free this and reallocate it to something else if you - need to. A graphical driver may want to do this, for example. - - If you don't set a function pointer, it will default to NULL, since - they get nullified before the driver's init() is called. - - Assume that your driver may be added or removed dynamically, and - that more than one instance may exist at a time. In other words, it - should init and close cleanly, and not depend on global variables. - - Special arguments will be passed through the "args" variable to your - _init() function. This is just a string, and you determine the - syntax of it. Please document the syntax so that it can easily be - included in the lcdproc config file. I suggest arguments such as - "port=0x378" or "-device /dev/ttyS0". These come directly from the - lcdproc server config file, so they should be human-readable. An - example may look like this: - - # Set up two MtxOrb LCD's and a curses display on VT 2 - Driver MtxOrb -device /dev/ttyS0 -keypad on - Driver curses -color off -size 20x4 -vt 2 - Driver MtxOrb -device /dev/ttyS3 -size 20x2 -keypad off - # Before you ask, no, not all of these options are implemented yet. - - Also, the driver API (if it can be called that) may change soon. - There seem to be several functions which just don't do anything - important... and there are other potential improvements too. - - And... When in doubt, look at how the other drivers do it. :) - -******************************************************************/ - -extern lcd_logical_driver *glk; - -int glk_init(struct lcd_logical_driver *driver, char *args); -void glk_close(); -void glk_clear(); -void glk_flush(); -void glk_string(int x, int y, char string[]); -void glk_chr(int x, int y, char c); -int glk_contrast(int contrast); -void glk_backlight(int on); -void glk_output(int on); -void glk_vbar(int x, int len); -void glk_init_vbar(); -void glk_hbar(int x, int y, int len); -void glk_init_hbar(); -void glk_num(int x, int num); -void glk_init_num(); -void glk_set_char(int n, char *dat); -void glk_icon(int which, char dest); -void glk_flush_box(int lft, int top, int rgt, int bot); -void glk_draw_frame(char *dat); -char glk_getkey(); +MODULE_EXPORT char glk_getkey(Driver *drvthis); +MODULE_EXPORT void glk_init_vbar(Driver *drvthis); +MODULE_EXPORT void glk_init_hbar(Driver *drvthis); +MODULE_EXPORT void glk_init_num(Driver *drvthis); #endif diff --git a/server/drivers/hd44780-4bit.c b/server/drivers/hd44780-4bit.c index bed0828..bf92499 100644 --- a/server/drivers/hd44780-4bit.c +++ b/server/drivers/hd44780-4bit.c @@ -61,7 +61,7 @@ */ #include "hd44780-4bit.h" -#include "hd44780.h" +#include "hd44780-low.h" #include "lpt-port.h" #include "port.h" @@ -76,9 +76,9 @@ // HD44780_senddata // HD44780_readkeypad -void lcdstat_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch); -void lcdstat_HD44780_backlight (unsigned char state); -unsigned char lcdstat_HD44780_readkeypad (unsigned int YData); +void lcdstat_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); +void lcdstat_HD44780_backlight (PrivateData *p, unsigned char state); +unsigned char lcdstat_HD44780_readkeypad (PrivateData *p, unsigned int YData); #define RS 0x10 #define RW 0x20 @@ -88,88 +88,86 @@ unsigned char lcdstat_HD44780_readkeypad (unsigned int YData); #define BL 0x20 // note that the above bits are all meant for the data port of LPT -static unsigned char EnMask[] = { EN1, EN2, EN3, STRB, LF, INIT, SEL }; +static const unsigned char EnMask[] = { EN1, EN2, EN3, STRB, LF, INIT, SEL }; #define ALLEXT (STRB|LF|INIT|SEL) // The above bits are on the control port of LPT -static unsigned int lptPort; -static char stuckinputs = 0; // if an input line is stuck, it will be ignored -static char backlight_bit = 0; // default to low to enable three displays - // initialisation function int -hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port) +hd_init_4bit (Driver *drvthis) { + PrivateData *p = (PrivateData*) drvthis->private_data; + HD44780_functions *hd44780_functions = p->hd44780_functions; + int enableLines = EN1 | EN2; // Reserve the port registers - lptPort = port; - port_access(lptPort); - port_access(lptPort+1); - port_access(lptPort+2); + port_access(p->port); + port_access(p->port+1); + port_access(p->port+2); hd44780_functions->senddata = lcdstat_HD44780_senddata; hd44780_functions->backlight = lcdstat_HD44780_backlight; hd44780_functions->readkeypad = lcdstat_HD44780_readkeypad; // powerup the lcd now - if (extIF) { + if (p->extIF) { enableLines |= EN3; - port_out (lptPort + 2, 0 ^ OUTMASK); + port_out (p->port + 2, 0 ^ OUTMASK); } - port_out (lptPort, 0x03); - if( delayBus ) hd44780_functions->uPause (1); + port_out (p->port, 0x03); + if( p->delayBus ) hd44780_functions->uPause (p, 1); - port_out (lptPort, enableLines | 0x03); - if (extIF) - port_out (lptPort + 2, ALLEXT ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, 0x03); - if (extIF) - port_out (lptPort + 2, 0 ^ OUTMASK); - hd44780_functions->uPause (4100); + port_out (p->port, enableLines | 0x03); + if (p->extIF) + port_out (p->port + 2, ALLEXT ^ OUTMASK); + if( p->delayBus ) hd44780_functions->uPause (p, 1); + port_out (p->port, 0x03); + if (p->extIF) + port_out (p->port + 2, 0 ^ OUTMASK); + hd44780_functions->uPause (p, 4100); - port_out (lptPort, enableLines | 0x03); - if (extIF) - port_out (lptPort + 2, ALLEXT ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, 0x03); - if (extIF) - port_out (lptPort + 2, 0 ^ OUTMASK); - hd44780_functions->uPause (100); + port_out (p->port, enableLines | 0x03); + if (p->extIF) + port_out (p->port + 2, ALLEXT ^ OUTMASK); + if( p->delayBus ) hd44780_functions->uPause (p, 1); + port_out (p->port, 0x03); + if (p->extIF) + port_out (p->port + 2, 0 ^ OUTMASK); + hd44780_functions->uPause (p, 100); - port_out (lptPort, enableLines | 0x03); - if (extIF) - port_out (lptPort + 2, ALLEXT ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, 0x03); - if (extIF) - port_out (lptPort + 2, 0 ^ OUTMASK); - hd44780_functions->uPause (40); + port_out (p->port, enableLines | 0x03); + if (p->extIF) + port_out (p->port + 2, ALLEXT ^ OUTMASK); + if( p->delayBus ) hd44780_functions->uPause (p, 1); + port_out (p->port, 0x03); + if (p->extIF) + port_out (p->port + 2, 0 ^ OUTMASK); + hd44780_functions->uPause (p, 40); // now in 8-bit mode... set 4-bit mode - port_out (lptPort, 0x02); - if( delayBus ) hd44780_functions->uPause (1); + port_out (p->port, 0x02); + if( p->delayBus ) hd44780_functions->uPause (p, 1); - port_out (lptPort, enableLines | 0x02); - if (extIF) - port_out (lptPort + 2, ALLEXT ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, 0x02); - if (extIF) - port_out (lptPort + 2, 0 ^ OUTMASK); - hd44780_functions->uPause (40); + port_out (p->port, enableLines | 0x02); + if (p->extIF) + port_out (p->port + 2, ALLEXT ^ OUTMASK); + if( p->delayBus ) hd44780_functions->uPause (p, 1); + port_out (p->port, 0x02); + if (p->extIF) + port_out (p->port + 2, 0 ^ OUTMASK); + hd44780_functions->uPause (p, 40); // Set up two-line, small character (5x8) mode - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | TWOLINE | SMALLCHAR ); - hd44780_functions->uPause (40); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | TWOLINE | SMALLCHAR ); + hd44780_functions->uPause (p, 40); - common_init (); + common_init (p); - if (have_keypad) { + if (p->have_keypad) { // Remember which input lines are stuck - stuckinputs = lcdstat_HD44780_readkeypad (0); + p->stuckinputs = lcdstat_HD44780_readkeypad (p, 0); } return 0; @@ -177,7 +175,7 @@ hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver // lcdstat_HD44780_senddata void -lcdstat_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch) +lcdstat_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { unsigned char enableLines = 0, portControl = 0; unsigned char h = (ch >> 4) & 0x0f; // high and low nibbles @@ -188,7 +186,7 @@ lcdstat_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned else //if (flags == RS_DATA) portControl = RS; - portControl |= backlight_bit; + portControl |= p->backlight_bit; if (displayID <= 3) { if (displayID == 0) @@ -196,64 +194,64 @@ lcdstat_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned else enableLines = EnMask[displayID - 1]; - port_out (lptPort, portControl | h); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, enableLines | portControl | h); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, portControl | h); + port_out (p->port, portControl | h); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port, enableLines | portControl | h); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port, portControl | h); - port_out (lptPort, portControl | l); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, enableLines | portControl | l); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort, portControl | l); + port_out (p->port, portControl | l); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port, enableLines | portControl | l); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port, portControl | l); } - if (extIF && (displayID == 0 || displayID >= 4)) { + if (p->extIF && (displayID == 0 || displayID >= 4)) { if (displayID == 0) enableLines = ALLEXT; else enableLines = EnMask[(displayID - 1)]; - port_out (lptPort, portControl | h); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort + 2, enableLines ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort + 2, 0 ^ OUTMASK); + port_out (p->port, portControl | h); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port + 2, enableLines ^ OUTMASK); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port + 2, 0 ^ OUTMASK); - port_out (lptPort, portControl | l); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort + 2, enableLines ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort + 2, 0 ^ OUTMASK); + port_out (p->port, portControl | l); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port + 2, enableLines ^ OUTMASK); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port + 2, 0 ^ OUTMASK); } } -void lcdstat_HD44780_backlight (unsigned char state) +void lcdstat_HD44780_backlight (PrivateData *p, unsigned char state) { - backlight_bit = (state?0:0x20); // D5 line + p->backlight_bit = (state?0:0x20); // D5 line - port_out (lptPort, backlight_bit); + port_out (p->port, p->backlight_bit); } -unsigned char lcdstat_HD44780_readkeypad (unsigned int YData) +unsigned char lcdstat_HD44780_readkeypad (PrivateData *p, unsigned int YData) { unsigned char readval; // 10 bits output or 6 bits if >=3 displays // Convert the positive logic to the negative logic on the LPT port - port_out (lptPort, ~YData & 0x003F ); - if (!extIF) { - port_out (lptPort + 2, ( ((~YData & 0x03C0) << 6 )) ^ OUTMASK); + port_out (p->port, ~YData & 0x003F ); + if (!p->extIF) { + port_out (p->port + 2, ( ((~YData & 0x03C0) << 6 )) ^ OUTMASK); } - if( delayBus ) hd44780_functions->uPause (1); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); // Read inputs - readval = ~ port_in (lptPort + 1) ^ INMASK; + readval = ~ port_in (p->port + 1) ^ INMASK; // Put port back into idle state for backlight - port_out (lptPort, backlight_bit); + port_out (p->port, p->backlight_bit); // And convert value back. - return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~stuckinputs; + return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~p->stuckinputs; } diff --git a/server/drivers/hd44780-4bit.h b/server/drivers/hd44780-4bit.h index c5d821a..fbb2f3b 100644 --- a/server/drivers/hd44780-4bit.h +++ b/server/drivers/hd44780-4bit.h @@ -1,10 +1,9 @@ #ifndef HD_LCDSTAT_H #define HD_LCDSTAT_H -#include "lcd.h" /* for lcd_logical_driver */ -#include "hd44780-low.h" /* for HD44780_functions */ +#include "lcd.h" /* for Driver */ // initialise this particular driver -int hd_init_4bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port); +int hd_init_4bit (Driver *drvthis); #endif diff --git a/server/drivers/hd44780-drivers.h b/server/drivers/hd44780-drivers.h index 877804c..717bed4 100644 --- a/server/drivers/hd44780-drivers.h +++ b/server/drivers/hd44780-drivers.h @@ -17,31 +17,20 @@ #include "hd44780-winamp.h" // add new connection type header files here -enum connectionType { HD_4bit, HD_8bit, HD_serialLpt, HD_winamp, - // add new connection types here - - HD_unknown -}; - -static struct ConnectionMapping { - enum connectionType type; - char *connectionTypeStr; - int (*init_fn) (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port); - const char *helpMsg; -} connectionMapping[] = { +static const ConnectionMapping connectionMapping[] = { // connectionType enumerator // string to identify connection on command line // your initialisation function // help string for your particular connection { - HD_4bit, "4bit", hd_init_4bit, "\t-e\t--extended\tEnable three or more displays\n"}, { - HD_8bit, "8bit", hd_init_ext8bit, "\tnone\n"}, { - HD_serialLpt, "serialLpt", hd_init_serialLpt, "\tnone\n"}, { - HD_winamp, "winamp", hd_init_winamp, "\t-e\t--extended\tEnable three or more displays\n"}, + "4bit", hd_init_4bit, "\tnone\n"}, { + "8bit", hd_init_ext8bit, "\tnone\n"}, { + "serialLpt", hd_init_serialLpt, "\tnone\n"}, { + "winamp", hd_init_winamp, "\tnone\n"}, // add new connection types and their string specifier here // default, end of structure element (do not delete) { - HD_unknown, "", NULL, ""} + NULL, NULL, NULL} }; #endif diff --git a/server/drivers/hd44780-ext8bit.c b/server/drivers/hd44780-ext8bit.c index 3200f0f..e3bbac9 100644 --- a/server/drivers/hd44780-ext8bit.c +++ b/server/drivers/hd44780-ext8bit.c @@ -52,7 +52,7 @@ */ #include "hd44780-ext8bit.h" -#include "hd44780.h" +#include "hd44780-low.h" #include "lpt-port.h" #include "port.h" @@ -67,57 +67,55 @@ // HD44780_senddata // HD44780_readkeypad -void lcdtime_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch); -void lcdtime_HD44780_backlight (unsigned char state); -unsigned char lcdtime_HD44780_readkeypad (unsigned int YData); +void lcdtime_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); +void lcdtime_HD44780_backlight (PrivateData *p, unsigned char state); +unsigned char lcdtime_HD44780_readkeypad (PrivateData *p, unsigned int YData); #define RS STRB #define RW LF #define EN1 INIT #define BL SEL -static unsigned int lptPort; -static char stuckinputs = 0; // if an input line is stuck, it will be ignored -static char backlight_bit = 0; - static int semid; // initialise the driver int -hd_init_ext8bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port) +hd_init_ext8bit (Driver *drvthis) { + PrivateData *p = (PrivateData*) drvthis->private_data; + HD44780_functions *hd44780_functions = p->hd44780_functions; + semid = sem_get (); // Reserve the port registers - lptPort = port; - port_access(lptPort); - port_access(lptPort+1); - port_access(lptPort+2); + port_access(p->port); + port_access(p->port+1); + port_access(p->port+2); hd44780_functions->senddata = lcdtime_HD44780_senddata; hd44780_functions->backlight = lcdtime_HD44780_backlight; hd44780_functions->readkeypad = lcdtime_HD44780_readkeypad; // setup the lcd in 8 bit mode - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT); - hd44780_functions->uPause (4100); - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT); - hd44780_functions->uPause (100); - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR); - hd44780_functions->uPause (40); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT); + hd44780_functions->uPause (p, 4100); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT); + hd44780_functions->uPause (p, 100); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR); + hd44780_functions->uPause (p, 40); - common_init (); + common_init (p); - if (have_keypad) { + if (p->have_keypad) { // Remember which input lines are stuck - stuckinputs = lcdtime_HD44780_readkeypad (0); + p->stuckinputs = lcdtime_HD44780_readkeypad (p, 0); } return 0; } // lcdtime_HD44780_senddata void -lcdtime_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch) +lcdtime_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { unsigned char enableLines = 0, portControl; @@ -129,28 +127,28 @@ lcdtime_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned else //if (iflags == RS_DATA) portControl = RS; - portControl |= backlight_bit; + portControl |= p->backlight_bit; sem_wait (semid); - port_out (lptPort + 2, portControl ^ OUTMASK); - port_out (lptPort, ch); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort + 2, (enableLines|portControl) ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); - port_out (lptPort + 2, portControl ^ OUTMASK); + port_out (p->port + 2, portControl ^ OUTMASK); + port_out (p->port, ch); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port + 2, (enableLines|portControl) ^ OUTMASK); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); + port_out (p->port + 2, portControl ^ OUTMASK); sem_signal (semid); } -void lcdtime_HD44780_backlight (unsigned char state) +void lcdtime_HD44780_backlight (PrivateData *p, unsigned char state) { - backlight_bit = (state?0:SEL); + p->backlight_bit = (state?0:SEL); // Semaphores not needed because backlight will not go together with // the bacrgraph anyway... - port_out (lptPort + 2, backlight_bit ^ OUTMASK); + port_out (p->port + 2, p->backlight_bit ^ OUTMASK); } -unsigned char lcdtime_HD44780_readkeypad (unsigned int YData) +unsigned char lcdtime_HD44780_readkeypad (PrivateData *p, unsigned int YData) { unsigned char readval; @@ -158,19 +156,19 @@ unsigned char lcdtime_HD44780_readkeypad (unsigned int YData) // 10 bits output or 8 bits if >=3 displays // Convert the positive logic to the negative logic on the LPT port - port_out (lptPort, ~YData & 0x00FF ); - if (!extIF) { - port_out (lptPort + 2, ( ((~YData & 0x0100) >> 8) | ((~YData & 0x0200) >> 6)) ^ OUTMASK); + port_out (p->port, ~YData & 0x00FF ); + if (!p->extIF) { + port_out (p->port + 2, ( ((~YData & 0x0100) >> 8) | ((~YData & 0x0200) >> 6)) ^ OUTMASK); } - if( delayBus ) hd44780_functions->uPause (1); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); // Read inputs - readval = ~ port_in (lptPort + 1) ^ INMASK; + readval = ~ port_in (p->port + 1) ^ INMASK; // Put port back into idle state for backlight - port_out (lptPort, backlight_bit ^ OUTMASK); + port_out (p->port, p->backlight_bit ^ OUTMASK); sem_signal (semid); // And convert value back. - return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~stuckinputs; + return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~p->stuckinputs; } diff --git a/server/drivers/hd44780-ext8bit.h b/server/drivers/hd44780-ext8bit.h index a3c3c1d..856b984 100644 --- a/server/drivers/hd44780-ext8bit.h +++ b/server/drivers/hd44780-ext8bit.h @@ -1,10 +1,9 @@ #ifndef HD_EXT8BIT_H #define HD_EXT8BIT_H -#include "lcd.h" /* for lcd_logical_driver */ -#include "hd44780-low.h" /* for HD44780_functions */ +#include "lcd.h" /* for Driver */ // initialise this particular driver -int hd_init_ext8bit (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port); +int hd_init_ext8bit (Driver *driver); #endif diff --git a/server/drivers/hd44780-low.h b/server/drivers/hd44780-low.h index 55bedff..e4e332f 100644 --- a/server/drivers/hd44780-low.h +++ b/server/drivers/hd44780-low.h @@ -6,40 +6,124 @@ enum ifWidth { IF_4bit, IF_8bit }; -//void common_init (enum ifWidth ifwidth); -void common_init (); +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +# if TIME_WITH_SYS_TIME +# include +# include +# else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +# endif + + +//struct hwDependentFns; + +// Maximum sizes of the keypad +// DO NOT CHANGE THESE 2 VALUES, unless you change the functions too +#define KEYPAD_MAXX 5 +#define KEYPAD_MAXY 11 + +typedef struct ConnectionMapping { + char *name; + int (*init_fn) (Driver *drvthis); + const char *helpMsg; +} ConnectionMapping; + +typedef struct driver_private_data { + + unsigned int port; + + int width, height; + int cellwidth, cellheight; + + // The framebuffer + char *framebuf; + + // For incremental updates store last lcd contents + char *lcd_contents; + + // Connection type data + int connectiontype_index; + struct hwDependentFns *hd44780_functions; + + // spanList[line number] = display line number is in + int *spanList; + int numLines; + + // dispVOffset is a cumulative sized array of line numbers for each display. + // use this to determine the vertical positioning on a given display + int *dispVOffset; + int numDisplays; + + // dispSizes is the vertical size of each display. This is the same as the + // input span list but is kept to save some cpu cycles. + int *dispSizes; + + // Keypad, backlight extended interface and delay options + char have_keypad; // off by default + char have_backlight; // off by default + char extIF; // off by default + int delayMult; // Delay multiplier for slow displays + char delayBus; // Delay if the computer can send data too fast over + // its bus to LPT port + + // keyMapDirect contains an array of the ascii-codes that should be generated + // when a directly connected key is pressed (not in matrix). + char *keyMapDirect[KEYPAD_MAXX]; + + // keyMapMatrix contrains an array with arrays of the ascii-codes that should be generated + // when a key in the matrix is pressed. + char *keyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX]; + + char pressed_key; + int pressed_key_repetitions; + struct timeval pressed_key_time; + + int stuckinputs; + + int backlight_bit; + +} PrivateData; // Structures holding pointers to HD44780 specific functions typedef struct hwDependentFns { // microsec pauses - void (*uPause) (int microSecondsTenths); + void (*uPause) (PrivateData *p, int usecs); // Senddata to the LCD // dispID - display to send data to (0 = all displays) // flags - data or instruction command (RS_DATA | RS_INSTR) // ch - character to display or instruction value - void (*senddata) (unsigned char dispID, unsigned char flags, unsigned char ch); + void (*senddata) (PrivateData *p, unsigned char dispID, unsigned char flags, unsigned char ch); // Switch the backlight on or off // state - to be or not to be on - void (*backlight) (unsigned char state); + void (*backlight) (PrivateData *p, unsigned char state); // Read the keypad // Ydata - the up to 11 bits that should be put on the Y side of the matrix // return - the up to 5 bits that are read out on the X side of the matrix - unsigned char (*readkeypad) (unsigned int Ydata); + unsigned char (*readkeypad) (PrivateData *p, unsigned int Ydata); // Scan the keypad and return a scancode. // The code is the Yvalue in the high nibble and the Xvalue in the low nibble. // A subdriver should do only one of two things: // - set readkeypad; or // - override scankeypad. - unsigned char (*scankeypad) (); + unsigned char (*scankeypad) (PrivateData *p); } HD44780_functions; /* for want of a better name :-) */ -extern HD44780_functions *hd44780_functions; + +void common_init (PrivateData *p); + // commands for senddata #define RS_DATA 0x00 diff --git a/server/drivers/hd44780-serialLpt.c b/server/drivers/hd44780-serialLpt.c index 34c4deb..359ec09 100644 --- a/server/drivers/hd44780-serialLpt.c +++ b/server/drivers/hd44780-serialLpt.c @@ -50,7 +50,7 @@ */ #include "hd44780-serialLpt.h" -#include "hd44780.h" +#include "hd44780-low.h" #include "lpt-port.h" #include "port.h" @@ -60,12 +60,12 @@ #include // Hardware specific functions -void lcdserLpt_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch); -void lcdserLpt_HD44780_backlight (unsigned char state); +void lcdserLpt_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); +void lcdserLpt_HD44780_backlight (PrivateData *p, unsigned char state); -unsigned char lcdserLpt_HD44780_scankeypad (); -void rawshift (unsigned char r); -void shiftreg (unsigned char displayID, unsigned char r); +unsigned char lcdserLpt_HD44780_scankeypad (PrivateData *p); +void rawshift (PrivateData *p, unsigned char r); +void shiftreg (PrivateData *p, unsigned char displayID, unsigned char r); #define RS 32 #define LCDDATA 8 @@ -73,50 +73,46 @@ void shiftreg (unsigned char displayID, unsigned char r); #define EN1 4 #define EN2 32 -static unsigned int lptPort; -static char backlight_bit = 0; - // Initialisation int -hd_init_serialLpt (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port) +hd_init_serialLpt (Driver *drvthis) { + PrivateData *p = (PrivateData*) drvthis->private_data; + HD44780_functions *hd44780_functions = p->hd44780_functions; unsigned char enableLines = EN1 | EN2; // Reserve the port registers - lptPort = port; - port_access(lptPort); - port_access(lptPort+1); - port_access(lptPort+2); + port_access(p->port); + port_access(p->port+1); + port_access(p->port+2); hd44780_functions->senddata = lcdserLpt_HD44780_senddata; hd44780_functions->backlight = lcdserLpt_HD44780_backlight; hd44780_functions->scankeypad = lcdserLpt_HD44780_scankeypad; // setup the lcd in 4 bit mode - shiftreg (enableLines, 3); - hd44780_functions->uPause (15000); + shiftreg (p, enableLines, 3); + hd44780_functions->uPause (p, 15000); - shiftreg (enableLines, 3); - hd44780_functions->uPause (5000); + shiftreg (p, enableLines, 3); + hd44780_functions->uPause (p, 5000); - shiftreg (enableLines, 3); - hd44780_functions->uPause (100); + shiftreg (p, enableLines, 3); + hd44780_functions->uPause (p, 150); - shiftreg (enableLines, 3); - hd44780_functions->uPause (100); + shiftreg (p, enableLines, 2); + hd44780_functions->uPause (p, 100); - shiftreg (enableLines, 2); - hd44780_functions->uPause (100); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_4BIT | TWOLINE | SMALLCHAR); + hd44780_functions->uPause (p, 40); - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_4BIT | TWOLINE | SMALLCHAR); - - common_init (); + common_init (p); return 0; } void -lcdserLpt_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch) +lcdserLpt_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { unsigned char enableLines; unsigned char portControl = 0; @@ -134,24 +130,24 @@ lcdserLpt_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign else portControl = 0; - shiftreg (enableLines, portControl | h); - shiftreg (enableLines, portControl | l); + shiftreg (p, enableLines, portControl | h); + shiftreg (p, enableLines, portControl | l); // Restore line status for backlight - port_out (lptPort, backlight_bit ); + port_out (p->port, p->backlight_bit ); } void -lcdserLpt_HD44780_backlight (unsigned char state) +lcdserLpt_HD44780_backlight (PrivateData *p, unsigned char state) { // Store new state - backlight_bit = (state?LCDDATA:0); + p->backlight_bit = (state?LCDDATA:0); // Set line status for backlight - port_out (lptPort, backlight_bit ); + port_out (p->port, p->backlight_bit ); } -unsigned char lcdserLpt_HD44780_scankeypad () +unsigned char lcdserLpt_HD44780_scankeypad (PrivateData *p) { // Unfortunately just bit shifting does not work with the 2-wire version... @@ -162,36 +158,41 @@ unsigned char lcdserLpt_HD44780_scankeypad () int i; unsigned int scancode = 0; - // While scanning the keypad, the 2-wire version executes the 0xFF - // command. This command sets the cursor position, so it's harmless. + // While scanning the keypad, the 2-wire version will place the + // character 0xFF on the current cursor position. Therefor we fisrt + // set the cursor position to -1, so it's harmless. // I could not prevent this, while staying compatible with both // wiring versions. // Clear the shiftregister, needed for 3-wire version - rawshift(0); - hd44780_functions->uPause (2); + rawshift(p, 0); + p->hd44780_functions->uPause (p, 1); - readval = ~ port_in (lptPort + 1) ^ INMASK; + readval = ~ port_in (p->port + 1) ^ INMASK; inputs_zero = ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ); if( inputs_zero == 0 ) { // No keys were pressed // Restore line status for backlight. - port_out (lptPort, backlight_bit ); + port_out (p->port, p->backlight_bit ); return 0; } + // Set cursor position to -1 + p->hd44780_functions->senddata (p, 0, RS_INSTR, POSITION | 127); + p->hd44780_functions->uPause (p, 40); + // Scan the keypad while sending the first half of the command (high nibble) for (i = 7; i >= 0; i--) { /* MSB first */ - port_out (lptPort, LCDDATA); /*set up data */ - port_out (lptPort, LCDDATA | LCDCLOCK); /*rising edge of clock */ + port_out (p->port, LCDDATA); /*set up data */ + port_out (p->port, LCDDATA | LCDCLOCK); /*rising edge of clock */ - hd44780_functions->uPause (2); + p->hd44780_functions->uPause (p, 2); if( !scancode ) { // Read input line(s) - readval = ~ port_in (lptPort + 1) ^ INMASK; + readval = ~ port_in (p->port + 1) ^ INMASK; keybits = ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ); if( keybits != inputs_zero ) { shiftingbit = 1; @@ -207,40 +208,40 @@ unsigned char lcdserLpt_HD44780_scankeypad () } // Wait for 2-wire version to clear the latch... - hd44780_functions->uPause (6); + p->hd44780_functions->uPause (p, 6); // And again for the second half of the command (low nibble). // Needed for 2-wire version. - rawshift (0xFF); + rawshift (p, 0xFF); // Wait for 2-wire version to clear the latch... - hd44780_functions->uPause (6); + p->hd44780_functions->uPause (p, 6); // Restore line status for backlight. - port_out (lptPort, backlight_bit ); + port_out (p->port, p->backlight_bit ); return scancode; } /* this function sends r out onto the shift register */ void -rawshift (unsigned char r) +rawshift (PrivateData *p, unsigned char r) { int i; for (i = 7; i >= 0; i--) { /* MSB first */ - port_out (lptPort, ((r >> i) & 1) * LCDDATA); /*set up data */ - port_out (lptPort, (((r >> i) & 1) * LCDDATA) | LCDCLOCK); /*rising edge of clock */ + port_out (p->port, ((r >> i) & 1) * LCDDATA); /*set up data */ + port_out (p->port, (((r >> i) & 1) * LCDDATA) | LCDCLOCK); /*rising edge of clock */ } } // enableLines = value on parallel port to toggle the correct display void -shiftreg (unsigned char enableLines, unsigned char r) +shiftreg (PrivateData *p, unsigned char enableLines, unsigned char r) { - rawshift (r | 0x80); // highest bit always set to 1 for Clear for 2-wire version - port_out (lptPort, enableLines); // latch it, to correct display - hd44780_functions->uPause (1); - port_out (lptPort, 0); // for 3-wire version - hd44780_functions->uPause (5); // wait for 2-wire version to clear the latch... + rawshift (p, r | 0x80); // highest bit always set to 1 for Clear for 2-wire version + port_out (p->port, enableLines); // latch it, to correct display + p->hd44780_functions->uPause (p, 1); + port_out (p->port, 0); // for 3-wire version + p->hd44780_functions->uPause (p, 5); // wait for 2-wire version to clear the latch... } diff --git a/server/drivers/hd44780-serialLpt.h b/server/drivers/hd44780-serialLpt.h index efc7d2f..8eb3253 100644 --- a/server/drivers/hd44780-serialLpt.h +++ b/server/drivers/hd44780-serialLpt.h @@ -1,10 +1,9 @@ #ifndef HD_SERIALLPT_H #define HD_SERIALLPT_H -#include "lcd.h" /* for lcd_logical_driver */ -#include "hd44780-low.h" /* for HD44780_functions */ +#include "lcd.h" /* for Driver */ // initialise this particular driver -int hd_init_serialLpt (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port); +int hd_init_serialLpt (Driver *drvthis); #endif diff --git a/server/drivers/hd44780-winamp.c b/server/drivers/hd44780-winamp.c index 9829d76..110c8c4 100644 --- a/server/drivers/hd44780-winamp.c +++ b/server/drivers/hd44780-winamp.c @@ -59,7 +59,7 @@ */ #include "hd44780-winamp.h" -#include "hd44780.h" +#include "hd44780-low.h" #include "lpt-port.h" #include "port.h" @@ -74,9 +74,9 @@ // HD44780_senddata // HD44780_readkeypad -void lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch); -void lcdwinamp_HD44780_backlight (unsigned char state); -unsigned char lcdwinamp_HD44780_readkeypad (unsigned int YData); +void lcdwinamp_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch); +void lcdwinamp_HD44780_backlight (PrivateData *p, unsigned char state); +unsigned char lcdwinamp_HD44780_readkeypad (PrivateData *p, unsigned int YData); #define EN1 STRB #define EN2 SEL @@ -85,41 +85,45 @@ unsigned char lcdwinamp_HD44780_readkeypad (unsigned int YData); #define RS INIT #define BL SEL -static unsigned char EnMask[] = { EN1, EN2, EN3 }; - -static unsigned int lptPort; -static char stuckinputs = 0; // if an input line is stuck, it will be ignored -static char backlight_bit = 0; // default to low to enable two displays +static const unsigned char EnMask[] = { EN1, EN2, EN3 }; // initialise the driver int -hd_init_winamp (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port) +hd_init_winamp (Driver *drvthis) { + PrivateData *p = (PrivateData*) drvthis->private_data; + HD44780_functions *hd44780_functions = p->hd44780_functions; + // Reserve the port registers - lptPort = port; - port_access(lptPort); - port_access(lptPort+1); - port_access(lptPort+2); + port_access(p->port); + port_access(p->port+1); + port_access(p->port+2); hd44780_functions->senddata = lcdwinamp_HD44780_senddata; hd44780_functions->backlight = lcdwinamp_HD44780_backlight; hd44780_functions->readkeypad = lcdwinamp_HD44780_readkeypad; // setup the lcd in 8 bit mode - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT); - hd44780_functions->uPause (4100); - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT); - hd44780_functions->uPause (100); - hd44780_functions->senddata (0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR); - hd44780_functions->uPause (40); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT); + hd44780_functions->uPause (p, 4100); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT); + hd44780_functions->uPause (p, 100); + hd44780_functions->senddata (p, 0, RS_INSTR, FUNCSET | IF_8BIT | TWOLINE | SMALLCHAR); + hd44780_functions->uPause (p, 40); + + common_init (p); + + if (p->have_keypad) { + // Remember which input lines are stuck + p->stuckinputs = lcdwinamp_HD44780_readkeypad (p, 0); + } - common_init (); return 0; } // lcdwinamp_HD44780_senddata void -lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsigned char ch) +lcdwinamp_HD44780_senddata (PrivateData *p, unsigned char displayID, unsigned char flags, unsigned char ch) { unsigned char enableLines = 0, portControl; @@ -128,25 +132,25 @@ lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign else portControl = 0; - portControl |= backlight_bit; + portControl |= p->backlight_bit; if (displayID == 0) - enableLines = EnMask[0] | EnMask[1] | ((extIF) ? EnMask[2] : 0); + enableLines = EnMask[0] | EnMask[1] | ((p->extIF) ? EnMask[2] : 0); else enableLines = EnMask[displayID - 1]; // 40 nS setup time for RS valid to EN high, so set RS - port_out (lptPort + 2, portControl ^ OUTMASK); + port_out (p->port + 2, portControl ^ OUTMASK); // Output the actual data - port_out (lptPort, ch); + port_out (p->port, ch); - if( delayBus ) hd44780_functions->uPause (1); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); // then set EN high - port_out (lptPort + 2, (enableLines|portControl) ^ OUTMASK); + port_out (p->port + 2, (enableLines|portControl) ^ OUTMASK); - if( delayBus ) hd44780_functions->uPause (1); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); // 80 nS setup from valid data to EN low will be met without any delay // unless you are running a REALLY FAST ISA bus (like 75 MHZ!) @@ -155,34 +159,34 @@ lcdwinamp_HD44780_senddata (unsigned char displayID, unsigned char flags, unsign // ABOVE TEXT ignored now, using delays if delayBus is specified // Set EN low and we're done... - port_out (lptPort + 2, portControl ^ OUTMASK); + port_out (p->port + 2, portControl ^ OUTMASK); // 10 nS data hold time provided by the length of ISA write for EN } -void lcdwinamp_HD44780_backlight (unsigned char state) +void lcdwinamp_HD44780_backlight (PrivateData *p, unsigned char state) { - backlight_bit = (state?0:nSEL); + p->backlight_bit = (state?0:nSEL); - port_out (lptPort + 2, backlight_bit ^ OUTMASK); + port_out (p->port + 2, p->backlight_bit ^ OUTMASK); } -unsigned char lcdwinamp_HD44780_readkeypad (unsigned int YData) +unsigned char lcdwinamp_HD44780_readkeypad (PrivateData *p, unsigned int YData) { unsigned char readval; // 8 bits output // Convert the positive logic to the negative logic on the LPT port - port_out (lptPort, ~YData & 0x00FF ); + port_out (p->port, ~YData & 0x00FF ); - if( delayBus ) hd44780_functions->uPause (1); + if( p->delayBus ) p->hd44780_functions->uPause (p, 1); // Read inputs - readval = ~ port_in (lptPort + 1) ^ INMASK; + readval = ~ port_in (p->port + 1) ^ INMASK; // Set output back to idle state for backlight - port_out (lptPort + 2, backlight_bit ^ OUTMASK ); + port_out (p->port + 2, p->backlight_bit ^ OUTMASK ); // And convert value back. - return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~stuckinputs; + return ( (readval >> 4 & 0x03) | (readval >> 5 & 0x04) | (readval >> 3 & 0x08) | (readval << 1 & 0x10) ) & ~p->stuckinputs; } diff --git a/server/drivers/hd44780-winamp.h b/server/drivers/hd44780-winamp.h index 96ca8ed..90d1ecf 100644 --- a/server/drivers/hd44780-winamp.h +++ b/server/drivers/hd44780-winamp.h @@ -1,11 +1,9 @@ #ifndef HD_WINAMP_H #define HD_WINAMP_H -#include "lcd.h" /* for lcd_logical_driver */ -#include "hd44780-low.h" /* for HD44780_functions */ +#include "lcd.h" /* for Driver */ -// initialise this particular driver, args is probably not used but keep -// for consistency -int hd_init_winamp (HD44780_functions * hd44780_functions, lcd_logical_driver * driver, char *args, unsigned int port); +// initialise this particular driver +int hd_init_winamp (Driver *drvthis); #endif diff --git a/server/drivers/hd44780.c b/server/drivers/hd44780.c index c4e935c..4420064 100644 --- a/server/drivers/hd44780.c +++ b/server/drivers/hd44780.c @@ -42,126 +42,85 @@ * 1997 Matthias Prinke */ + +// Uncomment one of the lines below to select your desired delay generation +// mechanism. If both defines are commented, the original I/O read timing +// loop is used. Using DELAY_NANOSLEEP seems to provide the best performance. +//#define DELAY_GETTIMEOFDAY +#define DELAY_NANOSLEEP +//#define DELAY_IOCALLS + +// Default parallel port address +#define LPTPORT 0x378 + +// Autorepeat values +#define KEYPAD_AUTOREPEAT_DELAY 500 +#define KEYPAD_AUTOREPEAT_FREQ 15 + + #include #include #include #include #include #include + #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include "port.h" -#include "timing.h" #include "shared/str.h" -#include "render.h" #include "lcd.h" #include "hd44780.h" -// #include "drv_base.h" +#include "port.h" +#include "timing.h" #include "hd44780-low.h" #include "hd44780-drivers.h" #include "hd44780-charmap.h" -// default parallel port address -#ifndef LPTPORT -#define LPTPORT 0x378 +// Only one alternate delay method at a time, please ;-) +#if defined DELAY_GETTIMEOFDAY +# undef DELAY_NANOSLEEP +#elif defined DELAY_NANOSLEEP +# include +# include #endif -unsigned int port = LPTPORT; -lcd_logical_driver *HD44780; -HD44780_functions *hd44780_functions; +static char *defaultKeyMapDirect[KEYPAD_MAXX] = { "A", "B", "C", "D", "E" }; -// default value -static enum connectionType connection = HD_4bit; -static int connectiontype_index = 0; - -// spanList[line number] = display line number is in -static int *spanList = NULL; -static int numLines = 0; - -// dispVOffset is a cumulative sized array of line numbers for each display. -// use this to determine the vertical positioning on a given display -static int *dispVOffset = NULL; -static int numDisplays = 0; - -// dispSizes is the vertical size of each display. This is the same as the -// input span list but is kept to save some cpu cycles. -static int *dispSizes = NULL; - -// Keypad, backlight extended interface and delay options -char have_keypad = 0; // off by default -char have_backlight = 0; // off by default -char extIF = 0; // off by default -char delayBus = 0; // Delay if the computer can send data too fast over -int delayMult = 0; // Delay multiplier for slow displays - // its bus to LPT port - - // These vars is not static, so it's accessable from - // all sub-drivers - // Indeed, this should become cleaner... later... - -// Autorepeat values -#define KEYPAD_AUTOREPEAT_DELAY 500 -#define KEYPAD_AUTOREPEAT_FREQ 15 - -// keyMapDirect contains an array of the ascii-codes that should be generated -// when a directly connected key is pressed (not in matrix). -static char keyMapDirect[KEYPAD_MAXX] = { 'A', 'B', 'C', 'D', 'E' }; - -// keyMapMatrix contrains an array with arrays of the ascii-codes that should be generated -// when a key in the matrix is pressed. -static char keyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = { - { '1', '2', '3', 'A', 'E' }, - { '4', '5', '6', 'B', 'F' }, - { '7', '8', '9', 'C', 'G' }, - { '*', '0', '#', 'D', 'H' }, - { 'I', 'J', 'K', 'L', 'M' }, - { 'N', 'O', 'P', 'Q', 'R' }, - { 'S', 'T', 'U', 'V', 'W' }, - { 'X', 'Y', 'Z', 'a', 'b' }, - { 'c', 'd', 'e', 'f', 'g' }, - { 'h', 'i', 'j', 'k', 'l' }, - { 'm', 'n', 'o', 'p', 'q' }}; - -static char pressed_key = 0; -static int pressed_key_repetitions = 0; -static struct timeval pressed_key_time; - -// for incremental updates store last lcd contents -static char * lcd_contents = (char *) 0; +static char *defaultKeyMapMatrix[KEYPAD_MAXY][KEYPAD_MAXX] = { + { "1", "2", "3", "A", "E" }, + { "4", "5", "6", "B", "F" }, + { "7", "8", "9", "C", "G" }, + { "*", "0", "#", "D", "H" }, + { NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL }}; // function declarations -void HD44780_close (); -void HD44780_flush (); -void HD44780_clear (); -void HD44780_chr (int x, int y, char ch); -void HD44780_string (int x, int y, char *s); -void HD44780_flush_box (int lft, int top, int rgt, int bot); -void HD44780_backlight (int on); -void HD44780_init_vbar (); -void HD44780_init_hbar (); -void HD44780_vbar (int x, int len); -void HD44780_hbar (int x, int y, int len); -void HD44780_init_num (); -void HD44780_num (int x, int num); -void HD44780_heartbeat (int type); -void HD44780_set_char (int n, char *dat); -void HD44780_icon (int which, char dest); -void HD44780_draw_frame (char *dat); -char HD44780_getkey (); - -void HD44780_position (int x, int y); -unsigned char HD44780_scankeypad(); +void HD44780_position (Driver *drvthis, int x, int y); +static void uPause (PrivateData *p, int usecs); +unsigned char HD44780_scankeypad(PrivateData *p); static int parse_span_list (int *spanListArray[], int *spLsize, int *dispOffsets[], int *dOffsize, int *dispSizeArray[], char *spanlist); +// Vars for the server core +MODULE_EXPORT char * api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; // because of port access problems +MODULE_EXPORT int supports_multiple = 1; // yes, we have no global variables (except for constants) +MODULE_EXPORT char *symbol_prefix = "HD44780_"; + + ///////////////////////////////////////////////////////////////// // Opens com port and sets baud correctly... // int -HD44780_init (lcd_logical_driver * driver, char *args) +HD44780_init (Driver * drvthis, char *args) { // TODO: remove the two magic numbers below // TODO: single point of return @@ -169,64 +128,75 @@ HD44780_init (lcd_logical_driver * driver, char *args) //int i; char buf[40]; char *s; + int i; + PrivateData *p; - HD44780 = driver; + // Alocate and store private data + p = (PrivateData *) malloc( sizeof( PrivateData) ); + if( ! p ) + return -1; + if( drvthis->store_private_ptr( drvthis, p ) ) + return -1; - // TODO: replace DriverName with driver->name when that field exists. - #define DriverName "HD44780" + // Clear data struct + memset( p, 0, sizeof(*p) ); + p->cellheight = 8; + p->cellwidth = 5; //// READ THE CONFIG FILE - port = driver->config_get_int( DriverName, "port", 0, 0x278 ); - extIF = driver->config_get_bool( DriverName, "extended", 0, 0 ); - have_keypad = driver->config_get_bool( DriverName, "keypad", 0, 0 ); - have_backlight = driver->config_get_bool( DriverName, "backlight", 0, 0 ); - delayMult = driver->config_get_int( DriverName, "delaymult", 0, 1 ); - delayBus = driver->config_get_bool( DriverName, "delaybus", 0, 1 ); + p->port = drvthis->config_get_int( drvthis->name, "port", 0, LPTPORT ); + p->extIF = drvthis->config_get_bool( drvthis->name, "extended", 0, 0 ); + p->have_keypad = drvthis->config_get_bool( drvthis->name, "keypad", 0, 0 ); + p->have_backlight = drvthis->config_get_bool( drvthis->name, "backlight", 0, 0 ); + p->delayMult = drvthis->config_get_int( drvthis->name, "delaymult", 0, 1 ); + p->delayBus = drvthis->config_get_bool( drvthis->name, "delaybus", 0, 1 ); // Get and search for the connection type - s = driver->config_get_string( DriverName, "connectiontype", 0, "4bit" ); - for (connectiontype_index = 0; strcmp (s, connectionMapping[connectiontype_index].connectionTypeStr) != 0 && connectionMapping[connectiontype_index].type != HD_unknown; ++connectiontype_index); - - if (connectionMapping[connectiontype_index].type == HD_unknown) { + s = drvthis->config_get_string( drvthis->name, "connectiontype", 0, "4bit" ); + for (i = 0; connectionMapping[i].name != NULL && strcmp (s, connectionMapping[i].name) != 0; i++); + if (connectionMapping[i].name == NULL) { fprintf (stderr, "HD44780_init: Unknown connection type: %s\n", s); return -1; // fatal error - } else - connection = connectionMapping[connectiontype_index].type; + } else { + p->connectiontype_index = i; + } // Get and parse vspan only when specified - s = driver->config_get_string( DriverName, "vspan", 0, "" ); + s = drvthis->config_get_string( drvthis->name, "vspan", 0, "" ); if( s[0] != 0 ) { - if (parse_span_list (&spanList, &numLines, &dispVOffset, &numDisplays, &dispSizes, s) == -1) { + if (parse_span_list (&(p->spanList), &(p->numLines), &(p->dispVOffset), &(p->numDisplays), &(p->dispSizes), s) == -1) { fprintf (stderr, "HD44780_init: invalid vspan value: %s\n", s ); return -1; } } // Get and parse size - s = driver->config_get_string( DriverName, "size", 0, "20x4" ); - if( sscanf( s, "%dx%d", &(driver->wid), &(driver->hgt) ) != 2 ) { + s = drvthis->config_get_string( drvthis->name, "size", 0, "20x4" ); + if( sscanf( s, "%dx%d", &(p->width), &(p->height) ) != 2 + || (p->width <= 0) || (p->width > LCD_MAX_WIDTH) + || (p->height <= 0) || (p->height > LCD_MAX_HEIGHT)) { fprintf( stderr, "HD44780_init: Cannot read size: %s\n", s ); } // default case for when spans aren't indicated - // - add a sanity check against HD44780->hgt ?? - if (numLines == 0) { - if ((spanList = (int *) malloc (sizeof (int) * HD44780->hgt))) { + // - add a sanity check against p->height ?? + if (p->numLines == 0) { + if ((p->spanList = (int *) malloc (sizeof (int) * p->height))) { int i; - for (i = 0; i < HD44780->hgt; ++i) { - spanList[i] = 1; - numLines = HD44780->hgt; + for (i = 0; i < p->height; ++i) { + p->spanList[i] = 1; + p->numLines = p->height; } } else fprintf (stderr, "Error mallocing for span list\n"); } - if (numDisplays == 0) { - if ((dispVOffset = (int *) malloc (sizeof (int))) && (dispSizes = (int *) malloc (sizeof (int)))) { - dispVOffset[0] = 0; - dispSizes[0] = HD44780->hgt; - numDisplays = 1; + if (p->numDisplays == 0) { + if ((p->dispVOffset = (int *) malloc (sizeof (int))) && (p->dispSizes = (int *) malloc (sizeof (int)))) { + p->dispVOffset[0] = 0; + p->dispSizes[0] = p->height; + p->numDisplays = 1; } else fprintf (stderr, "Error mallocing for display sizes list\n"); } @@ -234,70 +204,133 @@ HD44780_init (lcd_logical_driver * driver, char *args) if (timing_init() == -1) return -1; - // Make sure the frame buffer is there... - if (!HD44780->framebuf) - HD44780->framebuf = (unsigned char *) malloc (HD44780->wid * HD44780->hgt); +#if defined DELAY_NANOSLEEP + // Change to Round-Robin scheduling for nanosleep + { + // Set priority to 1 + struct sched_param param; + param.sched_priority=1; + if (( sched_setscheduler(0, SCHED_RR, ¶m)) == -1) { + fprintf (stderr, "HD44780_init: failed (%s)\n", strerror (errno)); + return -1; + } + } +#endif - if (!HD44780->framebuf) { + // Allocate framebuffer + p->framebuf = (unsigned char *) malloc (p->width * p->height); + if (!p->framebuf) { //HD44780_close(); return -1; } // Allocate and clear the buffer for incremental updates - lcd_contents = (unsigned char *) malloc (HD44780->wid * HD44780->hgt); - if (!lcd_contents) { + p->lcd_contents = (unsigned char *) malloc (p->width * p->height); + if (!p->lcd_contents) { return -1; } - memset(lcd_contents, ' ', HD44780->wid * HD44780->hgt); + memset(p->lcd_contents, ' ', p->width * p->height); + // Backlight ? + if ( p->have_backlight ) { + drvthis->backlight = HD44780_backlight; + } + // Keypad ? + if ( p->have_keypad ) { + int x, y; + + drvthis->getkey = HD44780_getkey; + + // Read keymap + for( x=0; xkeyMapDirect[x] = defaultKeyMapDirect[x]; + + // Read config value + sprintf( buf, "keydirect_%1d", x+1 ); + s = drvthis->config_get_string( drvthis->name, buf, 0, NULL ); + + // Was a key specified in the config file ? + if( s ) { + p->keyMapDirect[x] = (char *) malloc( strlen(s)+1 ); + strcpy( p->keyMapDirect[x], s ); + //report( RPT_INFO, "HD44780: Direct key %d: \"%s\"", x, s ); + } + } + + for( x=0; xkeyMapMatrix[y][x] = defaultKeyMapMatrix[y][x]; + + // Read config value + sprintf( buf, "keymatrix_%1d_%d", x+1, y+1 ); + s = drvthis->config_get_string( drvthis->name, buf, 0, NULL ); + + // Was a key specified in the config file ? + if( s ) { + p->keyMapMatrix[y][x] = (char *) malloc( strlen(s)+1 ); + strcpy( p->keyMapMatrix[y][x], s ); + //report( RPT_INFO, "HD44780: Matrix key %d %d: \"%s\"", x, y, s ); + } + } + } + } + + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; // Set the functions the driver supports... // These are the default HD44780 functions - driver->init = HD44780_init; - driver->close = HD44780_close; - driver->flush = HD44780_flush; - driver->clear = HD44780_clear; - driver->chr = HD44780_chr; - driver->string = HD44780_string; - driver->flush_box = HD44780_flush_box; // TO BE REMOVED - //driver->contrast = HD44780_contrast; // contrast is set by potmeter we assume + drvthis->init = HD44780_init; + drvthis->close = HD44780_close; + drvthis->width = HD44780_width; + drvthis->height = HD44780_height; + drvthis->flush = HD44780_flush; + drvthis->clear = HD44780_clear; + drvthis->chr = HD44780_chr; + drvthis->string = HD44780_string; + //drvthis->flush_box = HD44780_flush_box; // TO BE REMOVED + //drvthis->contrast = HD44780_contrast; // contrast is set by potmeter we assume - //driver->output = HD44780_output; // not implemented - driver->init_vbar = HD44780_init_vbar; - driver->init_hbar = HD44780_init_hbar; - driver->vbar = HD44780_vbar; - driver->hbar = HD44780_hbar; - driver->init_num = HD44780_init_num; - driver->num = HD44780_num; - driver->heartbeat = HD44780_heartbeat; - driver->set_char = HD44780_set_char; - driver->icon = HD44780_icon; - driver->draw_frame = HD44780_draw_frame; // TO BE REMOVED + //drvthis->output = HD44780_output; // not implemented + drvthis->init_vbar = HD44780_init_vbar; + drvthis->init_hbar = HD44780_init_hbar; + drvthis->old_vbar = HD44780_vbar; + drvthis->old_hbar = HD44780_hbar; + drvthis->init_num = HD44780_init_num; + drvthis->num = HD44780_num; + drvthis->heartbeat = HD44780_heartbeat; + drvthis->set_char = HD44780_set_char; + drvthis->old_icon = HD44780_icon; + //drvthis->draw_frame = HD44780_draw_frame; // TO BE REMOVED - if ( have_backlight ) { - driver->backlight = HD44780_backlight; - } - if ( have_keypad ) { - driver->getkey = HD44780_getkey; - } - - if ((hd44780_functions = (HD44780_functions *) malloc (sizeof (HD44780_functions))) == NULL) { + if ((p->hd44780_functions = (HD44780_functions *) malloc (sizeof (HD44780_functions))) == NULL) { + fprintf (stderr, "Error mallocing for function struct"); return -1; } - hd44780_functions->uPause = timing_uPause; - hd44780_functions->scankeypad = HD44780_scankeypad; + p->hd44780_functions->uPause = uPause; + p->hd44780_functions->scankeypad = HD44780_scankeypad; - connectionMapping[connectiontype_index].init_fn (hd44780_functions, driver, args, port); + // Do connection type specific display init + connectionMapping[p->connectiontype_index].init_fn (drvthis); - HD44780_clear (); - sprintf (buf, "HD44780 %dx%d", HD44780->wid, HD44780->hgt ); - HD44780_string (1, 1, buf); - sprintf (buf, "LPT 0x%x %s %s", port, (have_backlight?"bl":""), (have_keypad?"key":"") ); - HD44780_string (1, 2, buf); - HD44780_flush (); - sleep (1); + // Display startup parameters on the LCD + HD44780_clear (drvthis); + sprintf (buf, "HD44780 %dx%d", p->width, p->height ); + HD44780_string (drvthis, 1, 1, buf); + sprintf (buf, "LPT 0x%x %s %s", p->port, (p->have_backlight?"bl":""), (p->have_keypad?"key":"") ); + HD44780_string (drvthis, 1, 2, buf); + HD44780_flush (drvthis); + sleep (2); - return port; + return 1; } ///////////////////////////////////////////////////////////////// @@ -307,38 +340,73 @@ HD44780_init (lcd_logical_driver * driver, char *args) // the connectiontype should do this. // void -common_init () +common_init (PrivateData *p) { - hd44780_functions->senddata (0, RS_INSTR, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK); - hd44780_functions->uPause (40*delayMult); - hd44780_functions->senddata (0, RS_INSTR, CLEAR); - hd44780_functions->uPause (1600*delayMult); - hd44780_functions->senddata (0, RS_INSTR, HOMECURSOR); - hd44780_functions->uPause (1600*delayMult); + p->hd44780_functions->senddata (p, 0, RS_INSTR, ONOFFCTRL | DISPON | CURSOROFF | CURSORNOBLINK); + p->hd44780_functions->uPause (p, 40); + p->hd44780_functions->senddata (p, 0, RS_INSTR, CLEAR); + p->hd44780_functions->uPause (p, 1600); + p->hd44780_functions->senddata (p, 0, RS_INSTR, HOMECURSOR); + p->hd44780_functions->uPause (p, 1600); +} + +///////////////////////////////////////////////////////////////// +// Delay a number of microseconds +// +void +uPause (PrivateData *p, int usecs) +{ + timing_uPause( usecs * p->delayMult ); } ///////////////////////////////////////////////////////////////// // Clean-up // -void HD44780_close() +MODULE_EXPORT void +HD44780_close(Driver *drvthis) { - free( HD44780->framebuf ); - free( lcd_contents ); + PrivateData *p = (PrivateData *) drvthis->private_data; + + if(p->framebuf) free( p->framebuf ); + if(p->lcd_contents) free( p->lcd_contents ); + free( p ); + drvthis->store_private_ptr( drvthis, NULL ); +} + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +HD44780_width (Driver *drvthis) +{ + PrivateData * p = (PrivateData*) drvthis->private_data; + return p->width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +HD44780_height (Driver *drvthis) +{ + PrivateData * p = (PrivateData*) drvthis->private_data; + return p->height; } ///////////////////////////////////////////////////////////////// // Set position (not part of API) // -// x and y here are for the virtual HD44780->hgt x HD44780->wid display +// x and y here are for the virtual p->height x p->width display void -HD44780_position (int x, int y) +HD44780_position (Driver *drvthis, int x, int y) { - int dispID = spanList[y]; - int relY = y - dispVOffset[dispID - 1]; + PrivateData *p = (PrivateData *) drvthis->private_data; + int dispID = p->spanList[y]; + int relY = y - p->dispVOffset[dispID - 1]; int DDaddr; // 16x1 is a special case - if (dispSizes[dispID - 1] == 1 && HD44780->wid == 16) { + if (p->dispSizes[dispID - 1] == 1 && p->width == 16) { if (x >= 8) { x -= 8; relY = 1; @@ -347,47 +415,75 @@ HD44780_position (int x, int y) DDaddr = x + (relY % 2) * 0x40; if ((relY % 4) >= 2) - DDaddr += HD44780->wid; + DDaddr += p->width; - hd44780_functions->senddata (dispID, RS_INSTR, POSITION | DDaddr); - hd44780_functions->uPause (40*delayMult); // Minimum exec time for all commands + p->hd44780_functions->senddata (p, dispID, RS_INSTR, POSITION | DDaddr); + p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands } ///////////////////////////////////////////////////////////////// // Flush the framebuffer to the display // -void -HD44780_flush () +MODULE_EXPORT void +HD44780_flush (Driver *drvthis) { - HD44780_draw_frame (HD44780->framebuf); + PrivateData *p = (PrivateData *) drvthis->private_data; + int x, y; + int wid = p->width; + char ch; + char drawing; + + // Update LCD incrementally by comparing with last contents + for (y=0; yheight; y++) { + drawing = 0; + for (x=0 ; xframebuf[(y * wid) + x]; + if( ch != p->lcd_contents[(y*wid)+x] ) { + if( !drawing || x % 8 == 0 ) { // x%8 is for 16x1 displays ! + drawing = 1; + HD44780_position(drvthis,x,y); + } + p->hd44780_functions->senddata (p, p->spanList[y], RS_DATA, HD44780_charmap[(unsigned char)ch]); + p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands + p->lcd_contents[(y*wid)+x] = ch; + } + else { + drawing = 0; + } + } + } } ///////////////////////////////////////////////////////////////// // Clear the framebuffer // -void HD44780_clear () +MODULE_EXPORT void +HD44780_clear (Driver *drvthis) { - memset(HD44780->framebuf, ' ', HD44780->wid * HD44780->hgt); + PrivateData *p = (PrivateData *) drvthis->private_data; + memset(p->framebuf, ' ', p->width * p->height); } ///////////////////////////////////////////////////////////////// // Place a character in the framebuffer // -void -HD44780_chr (int x, int y, char ch) +MODULE_EXPORT void +HD44780_chr (Driver *drvthis, int x, int y, char ch) { + PrivateData *p = (PrivateData *) drvthis->private_data; y--; x--; - HD44780->framebuf[ (y * HD44780->wid) + x] = ch; + p->framebuf[ (y * p->width) + x] = ch; } ///////////////////////////////////////////////////////////////// // Place a string in the framebuffer // -void -HD44780_string (int x, int y, char *s) +MODULE_EXPORT void +HD44780_string (Driver *drvthis, int x, int y, char *s) { + PrivateData *p = (PrivateData *) drvthis->private_data; int i; x --; // Convert 1-based coords to 0-based @@ -395,52 +491,30 @@ HD44780_string (int x, int y, char *s) for (i = 0; s[i]; i++) { // Check for buffer overflows... - if ((y * HD44780->wid) + x + i > (HD44780->wid * HD44780->hgt)) + if ((y * p->width) + x + i > (p->width * p->height)) break; - HD44780->framebuf[(y*HD44780->wid) + x + i] = s[i]; + p->framebuf[(y*p->width) + x + i] = s[i]; } } -///////////////////////////////////////////////////////////////// -// Flush box -// -// TO BE REMOVED -// -void -HD44780_flush_box (int lft, int top, int rgt, int bot) -{ - int x, y; - - // printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot); - - for (y = top; y <= bot; y++) { - HD44780_position (lft, y); - //printf("\n%d,%d :",lft,y); - for (x = lft; x <= rgt; x++) { - - hd44780_functions->senddata (spanList[y], RS_DATA, HD44780->framebuf[(y * HD44780->wid) + x]); - hd44780_functions->uPause (40*delayMult); // Minimum exec time for all commands - } - //write(fd, HD44780->framebuf[(y*HD44780->wid)+lft, rgt-lft+1]); - } - -} - ///////////////////////////////////////////////////////////////// // Sets the backlight on or off // -void -HD44780_backlight (int on) +MODULE_EXPORT void +HD44780_backlight (Driver *drvthis, int on) { - hd44780_functions->backlight (on); + PrivateData *p = (PrivateData *) drvthis->private_data; + p->hd44780_functions->backlight (p, on); } ///////////////////////////////////////////////////////////////// // Sets up for vertical bars. Call before HD44780->vbar() // -void -HD44780_init_vbar () +MODULE_EXPORT void +HD44780_init_vbar (Driver *drvthis) { + //PrivateData *p = (PrivateData *) drvthis->private_data; + char a[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -512,21 +586,22 @@ HD44780_init_vbar () 1, 1, 1, 1, 1, }; - HD44780_set_char (1, a); - HD44780_set_char (2, b); - HD44780_set_char (3, c); - HD44780_set_char (4, d); - HD44780_set_char (5, e); - HD44780_set_char (6, f); - HD44780_set_char (7, g); + HD44780_set_char (drvthis, 1, a); + HD44780_set_char (drvthis, 2, b); + HD44780_set_char (drvthis, 3, c); + HD44780_set_char (drvthis, 4, d); + HD44780_set_char (drvthis, 5, e); + HD44780_set_char (drvthis, 6, f); + HD44780_set_char (drvthis, 7, g); } ///////////////////////////////////////////////////////////////// // Inits horizontal bars... // -void -HD44780_init_hbar () +MODULE_EXPORT void +HD44780_init_hbar (Driver *drvthis) { + //PrivateData *p = (PrivateData *) drvthis->private_data; char a[] = { 1, 0, 0, 0, 0, @@ -569,29 +644,30 @@ HD44780_init_hbar () 1, 1, 1, 1, 0, }; - HD44780_set_char (1, a); - HD44780_set_char (2, b); - HD44780_set_char (3, c); - HD44780_set_char (4, d); + HD44780_set_char (drvthis, 1, a); + HD44780_set_char (drvthis, 2, b); + HD44780_set_char (drvthis, 3, c); + HD44780_set_char (drvthis, 4, d); } ///////////////////////////////////////////////////////////////// // Draws a vertical bar... // -void -HD44780_vbar (int x, int len) +MODULE_EXPORT void +HD44780_vbar (Driver *drvthis, int x, int len) { + PrivateData *p = (PrivateData *) drvthis->private_data; char map[9] = { 32, 1, 2, 3, 4, 5, 6, 7, 255 }; int y; - for (y = HD44780->hgt; y > 0 && len > 0; y--) { - if (len >= HD44780->cellhgt) - HD44780_chr (x, y, 255); + for (y = p->height; y > 0 && len > 0; y--) { + if (len >= p->cellheight) + HD44780_chr (drvthis, x, y, 255); else - HD44780_chr (x, y, map[len]); + HD44780_chr (drvthis, x, y, map[len]); - len -= HD44780->cellhgt; + len -= p->cellheight; } } @@ -599,18 +675,19 @@ HD44780_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void -HD44780_hbar (int x, int y, int len) +MODULE_EXPORT void +HD44780_hbar (Driver *drvthis, int x, int y, int len) { + PrivateData *p = (PrivateData *) drvthis->private_data; char map[6] = { 32, 1, 2, 3, 4, 255 }; - for (; x <= HD44780->wid && len > 0; x++) { - if (len >= HD44780->cellwid) - HD44780_chr (x, y, 255); + for (; x <= p->width && len > 0; x++) { + if (len >= p->cellwidth) + HD44780_chr (drvthis, x, y, 255); else - HD44780_chr (x, y, map[len]); + HD44780_chr (drvthis, x, y, map[len]); - len -= HD44780->cellwid; + len -= p->cellwidth; } } @@ -618,8 +695,8 @@ HD44780_hbar (int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets up for big numbers. // -void -HD44780_init_num () +MODULE_EXPORT void +HD44780_init_num (Driver *drvthis) { } @@ -627,19 +704,21 @@ HD44780_init_num () ///////////////////////////////////////////////////////////////// // Writes a big number. // -void -HD44780_num (int x, int num) +MODULE_EXPORT void +HD44780_num (Driver *drvthis, int x, int num) { - int offset = HD44780->wid * ( HD44780->hgt / 2 ); - HD44780->framebuf[x+offset] = num + '0'; + PrivateData *p = (PrivateData *) drvthis->private_data; + int offset = p->width * ( p->height / 2 ); + p->framebuf[x+offset] = num + '0'; } ///////////////////////////////////////////////////////////// // Does the heartbeat... // -void -HD44780_heartbeat (int type) +MODULE_EXPORT void +HD44780_heartbeat (Driver *drvthis, int type) { + PrivateData *p = (PrivateData *) drvthis->private_data; static int timer = 0; int whichIcon; static int saved_type = HEARTBEAT_ON; @@ -653,13 +732,13 @@ HD44780_heartbeat (int type) // This defines a custom character EVERY time... // not efficient... is this necessary? - HD44780_icon (whichIcon, 0); + HD44780_icon (drvthis, whichIcon, 0); // Put character on screen... - HD44780_chr (HD44780->wid, 1, 0); + HD44780_chr (drvthis, p->width, 1, 0); // change display... - HD44780_flush (); + HD44780_flush (drvthis); } timer++; @@ -673,9 +752,10 @@ HD44780_heartbeat (int type) // // The input is just an array of characters... // -void -HD44780_set_char (int n, char *dat) +MODULE_EXPORT void +HD44780_set_char (Driver *drvthis, int n, char *dat) { + PrivateData *p = (PrivateData *) drvthis->private_data; int row, col; int letter; @@ -684,26 +764,27 @@ HD44780_set_char (int n, char *dat) if (!dat) return; - hd44780_functions->senddata (0, RS_INSTR, SETCHAR | n * 8); - hd44780_functions->uPause (40*delayMult); // Minimum exec time for all commands + p->hd44780_functions->senddata (p, 0, RS_INSTR, SETCHAR | n * 8); + p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands - for (row = 0; row < HD44780->cellhgt; row++) { + for (row = 0; row < p->cellheight; row++) { letter = 0; - for (col = 0; col < HD44780->cellwid; col++) { + for (col = 0; col < p->cellwidth; col++) { letter <<= 1; - letter |= (dat[(row * HD44780->cellwid) + col] > 0); + letter |= (dat[(row * p->cellwidth) + col] > 0); } - hd44780_functions->senddata (0, RS_DATA, letter); - hd44780_functions->uPause (40*delayMult); // Minimum exec time for all commands + p->hd44780_functions->senddata (p, 0, RS_DATA, letter); + p->hd44780_functions->uPause (p, 40); // Minimum exec time for all commands } } ///////////////////////////////////////////////////////////// // Set default icon into a userdef char // -void -HD44780_icon (int which, char dest) +MODULE_EXPORT void +HD44780_icon (Driver *drvthis, int which, char dest) { + //PrivateData *p = (PrivateData *) drvthis->private_data; char icons[3][5 * 8] = { { 1, 1, 1, 1, 1, // Empty Heart @@ -740,63 +821,29 @@ HD44780_icon (int which, char dest) }; - HD44780_set_char (dest, &icons[which][0]); -} - -///////////////////////////////////////////////////////////// -// Blasts a single frame onscreen, to the lcd... -// -// Input is a character array, sized HD44780->wid*hgt -// -// TO BE REMOVED (move it into flush()) -void -HD44780_draw_frame (char *dat) -{ - int x, y; - int wid = HD44780->wid; - char drawing; - - if (!dat) - return; - - // Update LCD incrementally by comparing with last contents - for (y=0; yhgt; y++) { - drawing = 0; - for (x=0 ; xsenddata( spanList[y], RS_DATA, HD44780_charmap[(unsigned char)dat[(y * wid) + x]]); - hd44780_functions->uPause (40*delayMult); // Minimum exec time for all commands - lcd_contents[(y*wid)+x] = dat[(y*wid)+x]; - } - else { - drawing = 0; - } - } - } + HD44780_set_char (drvthis, dest, &icons[which][0]); } ///////////////////////////////////////////////////////////// // Get a key from the keypad (if there is one) // -char HD44780_getkey() +MODULE_EXPORT char +HD44780_getkey(Driver *drvthis) { + PrivateData *p = (PrivateData *) drvthis->private_data; unsigned char scancode; char ch; struct timeval curr_time, time_diff; gettimeofday(&curr_time,NULL); - scancode = hd44780_functions->scankeypad(); + scancode = p->hd44780_functions->scankeypad(p); if( scancode ) { if( scancode & 0xF0 ) { - ch = keyMapMatrix[((scancode&0xF0)>>4)-1][(scancode&0x0F)-1]; + ch = ( p->keyMapMatrix[((scancode&0xF0)>>4)-1][(scancode&0x0F)-1] )[0]; } else { - ch = keyMapDirect[scancode - 1]; + ch = ( p->keyMapDirect[scancode - 1] )[0]; } } else { @@ -804,26 +851,26 @@ char HD44780_getkey() } if (ch) { - if (ch == pressed_key) { - timersub (&curr_time, &pressed_key_time, &time_diff); - if (((time_diff.tv_usec / 1000 + time_diff.tv_sec * 1000) - KEYPAD_AUTOREPEAT_DELAY) < 1000 * pressed_key_repetitions / KEYPAD_AUTOREPEAT_FREQ ) { + if (ch == p->pressed_key) { + timersub (&curr_time, &(p->pressed_key_time), &time_diff); + if (((time_diff.tv_usec / 1000 + time_diff.tv_sec * 1000) - KEYPAD_AUTOREPEAT_DELAY) < 1000 * p->pressed_key_repetitions / KEYPAD_AUTOREPEAT_FREQ ) { // The key is already pressed quite some time // but it's not yet time to return a repeated keypress return 0; } // Otherwise a keypress will be returned - pressed_key_repetitions ++; + p->pressed_key_repetitions ++; } else { // It's a new keypress - pressed_key_time = curr_time; - pressed_key_repetitions = 0; + p->pressed_key_time = curr_time; + p->pressed_key_repetitions = 0; printf( "Key: %c (%d,%d)\n", ch, scancode&0x0F, (scancode&0xF0)>>4 ); } } // Store the key for the next round - pressed_key = ch; + p->pressed_key = ch; return ch; } @@ -831,7 +878,7 @@ char HD44780_getkey() ///////////////////////////////////////////////////////////// // Scan the keypad // -unsigned char HD44780_scankeypad() +unsigned char HD44780_scankeypad(PrivateData *p) { unsigned int keybits; unsigned int shiftcount; @@ -844,7 +891,7 @@ unsigned char HD44780_scankeypad() // First check if a directly connected key is pressed // Put all zeros on Y of keypad - keybits = hd44780_functions->readkeypad (0); + keybits = p->hd44780_functions->readkeypad (p, 0); if (keybits) { // A directly connected key was pressed @@ -862,7 +909,7 @@ unsigned char HD44780_scankeypad() // Now check the matrix // First check with all 1's Ypattern = (1 << KEYPAD_MAXY) - 1; - if( hd44780_functions->readkeypad (Ypattern)) { + if( p->hd44780_functions->readkeypad (p, Ypattern)) { // Yes, a key on the matrix is pressed // OK, now we know a key is pressed. @@ -874,14 +921,14 @@ unsigned char HD44780_scankeypad() Yval = 0; for (exp=3; exp>=0; exp--) { Ypattern = ((1 << (1 << exp)) - 1) << Yval; - keybits = hd44780_functions->readkeypad (Ypattern); + keybits = p->hd44780_functions->readkeypad (p, Ypattern); if (!keybits) { Yval += (1 << exp); } } // Which key is pressed in that row ? - keybits = hd44780_functions->readkeypad (1<hd44780_functions->readkeypad (p, 1< 2 LCDs -extern char delayBus; // non-zero if axtra delays for the bus speed - // should be inserted. +MODULE_EXPORT void HD44780_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void HD44780_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void HD44780_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void HD44780_heartbeat (Driver *drvthis, int type); +MODULE_EXPORT void HD44780_icon (Driver *drvthis, int which, char dest); -int HD44780_init (struct lcd_logical_driver *driver, char *args); -/* The following methods can all be hidden. They are used through function ptrs -void HD44780_close(); -void HD44780_flush(); -void HD44780_flush_box(int lft, int top, int rgt, int bot); -int HD44780_contrast(int contrast); -void HD44780_backlight(int on); -void HD44780_init_vbar(); -void HD44780_init_hbar(); -void HD44780_vbar(int x, int len); -void HD44780_hbar(int x, int y, int len); -void HD44780_init_num(); -void HD44780_num(int x, int num); -void HD44780_set_char(int n, char *dat); -void HD44780_icon(int which, char dest); -void HD44780_draw_frame(char *dat); -*/ +MODULE_EXPORT void HD44780_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT void HD44780_backlight (Driver *drvthis, int on); + +MODULE_EXPORT char HD44780_getkey (Driver *drvthis); + +MODULE_EXPORT void HD44780_init_vbar (Driver *drvthis); +MODULE_EXPORT void HD44780_init_hbar (Driver *drvthis); +MODULE_EXPORT void HD44780_init_num (Driver *drvthis); #endif diff --git a/server/drivers/joy.c b/server/drivers/joy.c index a3f4706..942fd22 100644 --- a/server/drivers/joy.c +++ b/server/drivers/joy.c @@ -21,26 +21,25 @@ #include #include #include -#include #include #ifndef JSIOCGNAME #define JSIOCGNAME(len) _IOC(_IOC_READ, 'j', 0x13, len) /* get identifier string */ #endif -#include "shared/debug.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "lcd.h" +#include "joy.h" +#include "report.h" #include "shared/str.h" #define NAME_LENGTH 128 #define JOY_DEFAULT_DEVICE "/dev/js0" -#include "lcd.h" -#include "joy.h" - -lcd_logical_driver *joy; - int fd; -extern int debug_level; struct js_event js; @@ -49,25 +48,30 @@ char buttons = 2; int jsversion = 0x000800; char jsname[NAME_LENGTH] = "Unknown"; -int *axis; -int *button; +int *axis = NULL; +int *button = NULL; // Configured for a Gravis Gamepad (2 axis, 4 button) char *axismap = "EFGHIJKLMNOPQRST"; char *buttonmap = "BDACEFGHIJKLMNOP"; +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "joy_"; + + //////////////////////////////////////////////////////////// // init() should set up any device-specific stuff, and // point all the function pointers. int -joy_init (struct lcd_logical_driver *driver, char *args) +joy_init (Driver *drvthis, char *args) { char device[256]; char *argv[64]; int argc, i; - joy = driver; - strcpy (device, JOY_DEFAULT_DEVICE); argc = get_args (argv, args, 64); @@ -101,8 +105,14 @@ joy_init (struct lcd_logical_driver *driver, char *args) } - driver->getkey = joy_getkey; - driver->close = joy_close; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; + + // Set the functions the driver supports + drvthis->getkey = joy_getkey; + drvthis->close = joy_close; if ((fd = open (device, O_RDONLY)) < 0) return -1; @@ -113,40 +123,33 @@ joy_init (struct lcd_logical_driver *driver, char *args) ioctl (fd, JSIOCGBUTTONS, &buttons); ioctl (fd, JSIOCGNAME (NAME_LENGTH), jsname); - if (debug_level > 2) { - syslog(LOG_DEBUG, "Joystick (%s) has %d axes and %d buttons. Driver version is %d.%d.%d.\n", - jsname, axes, buttons, - jsversion >> 16, (jsversion >> 8) & 0xff, jsversion & 0xff); - } + report (RPT_NOTICE, "Joystick (%s) has %d axes and %d buttons. Driver version is %d.%d.%d.\n", + jsname, axes, buttons, + jsversion >> 16, (jsversion >> 8) & 0xff, jsversion & 0xff); if ((axis = calloc (axes, sizeof (int))) == NULL) { - syslog(LOG_ERR, "joystick: could not allocate memory for axes"); + report (RPT_ERR, "joystick: could not allocate memory for axes"); return -1; } if ((button = calloc (buttons, sizeof (char))) == NULL) { - syslog(LOG_ERR, "joystick: could not allocate memory for buttons"); + report (RPT_ERR, "joystick: could not allocate memory for buttons"); return -1; } - return fd; // 200 is arbitrary. (must be 1 or more) + return 0; } -void -joy_close () +MODULE_EXPORT void +joy_close (Driver *drvthis) { - if (joy->framebuf != NULL) - free (joy->framebuf); - close (fd); - joy->framebuf = NULL; - // Why do I have so much trouble getting memory freed without segfaults?? // Use gdb and find out :) In preliminary testing, this seemed to work... - if (axis) free(axis); - if (button) free(button); + if(axis) free(axis); + if(button) free(button); } @@ -155,8 +158,8 @@ joy_close () // // Return 0 for "nothing available". // -char -joy_getkey () +MODULE_EXPORT char +joy_getkey (Driver *drvthis) { int i; int err; @@ -165,7 +168,7 @@ joy_getkey () return 0; } else if (err != sizeof (struct js_event)) { - syslog(LOG_ERR, "error reading joystick input"); + report(RPT_ERR, "error reading joystick input"); return 0; } diff --git a/server/drivers/joy.h b/server/drivers/joy.h index a84b792..2b22ef6 100644 --- a/server/drivers/joy.h +++ b/server/drivers/joy.h @@ -1,10 +1,11 @@ #ifndef LCD_JOY_H #define LCD_JOY_H -extern lcd_logical_driver *joy; +#include "lcd.h" -int joy_init (struct lcd_logical_driver *driver, char *args); -void joy_close (); -char joy_getkey (); + int joy_init (Driver *drvthis, char *args); +MODULE_EXPORT void joy_close (Driver *drvthis); + +MODULE_EXPORT char joy_getkey (Driver *drvthis); #endif diff --git a/server/drivers/lb216.c b/server/drivers/lb216.c index 32711ea..c364e57 100644 --- a/server/drivers/lb216.c +++ b/server/drivers/lb216.c @@ -26,18 +26,17 @@ # include "config.h" #endif -#ifdef HAVE_NCURSES_H -# include -#else -# include -#endif +//#ifdef HAVE_NCURSES_H +//# include +//#else +//# include +//#endif -#include "shared/str.h" -#include "shared/debug.h" #include "lcd.h" #include "lb216.h" -#include "drv_base.h" -#include "render.h" +#include "shared/str.h" +#include "report.h" +//#include "drv_base.h" static int custom=0; typedef enum { @@ -47,20 +46,30 @@ typedef enum { beat = 8 } custom_type; - static int fd; +static char *framebuf = NULL; +static int width = LCD_DEFAULT_WIDTH; +static int height = LCD_DEFAULT_HEIGHT; +static int cellwidth = LCD_DEFAULT_CELLWIDTH; +static int cellheight = LCD_DEFAULT_CELLHEIGHT; static void LB216_hidecursor(); static void LB216_reboot(); -// TODO: Get rid of this variable? -lcd_logical_driver *LB216; +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "LB216_"; + + // TODO: Get the frame buffers working right ///////////////////////////////////////////////////////////////// // Opens com port and sets baud correctly... // -int LB216_init(lcd_logical_driver *driver, char *args) +int +LB216_init(Driver * drvthis, char *args) { char *argv[64]; int argc; @@ -71,8 +80,8 @@ int LB216_init(lcd_logical_driver *driver, char *args) char device[256] = "/dev/lcd"; int speed=B9600; + int backlight_brightness = 255; - LB216 = driver; //debug("LB216_init: Args(all): %s\n", args); @@ -153,6 +162,7 @@ int LB216_init(lcd_logical_driver *driver, char *args) } + // Set up io port correctly, and open it... fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); if (fd == -1) @@ -184,12 +194,11 @@ int LB216_init(lcd_logical_driver *driver, char *args) // Do it... tcsetattr(fd, TCSANOW, &portset); - // Make sure the frame buffer is there... - if (!LB216->framebuf) - LB216->framebuf = (unsigned char *) - malloc (LB216->wid * LB216->hgt); - memset (LB216->framebuf, ' ', LB216->wid * LB216->hgt); + if (framebuf) + framebuf = (unsigned char *) + malloc (width * height); + memset (framebuf, ' ', width * height); // Set display-specific stuff.. if(reboot) @@ -200,36 +209,34 @@ int LB216_init(lcd_logical_driver *driver, char *args) } sleep(1); LB216_hidecursor(); - LB216_backlight(backlight_brightness); + LB216_backlight(drvthis, backlight_brightness); - // Set the functions the driver supports... + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->clear = LB216_clear; - driver->string = LB216_string; - driver->chr = LB216_chr; - driver->vbar = LB216_vbar; - driver->init_vbar = LB216_init_vbar; - driver->hbar = LB216_hbar; - driver->init_hbar = LB216_init_hbar; - //driver->num = NULL; - //driver->init_num = NULL; + // Set the functions the driver supports + drvthis->clear = LB216_clear; + drvthis->string = LB216_string; + drvthis->chr = LB216_chr; + drvthis->old_vbar = LB216_vbar; + drvthis->init_vbar = LB216_init_vbar; + drvthis->old_hbar = LB216_hbar; + drvthis->init_hbar = LB216_init_hbar; + //drvthis->num = NULL; + //drvthis->init_num = NULL; - driver->init = LB216_init; - driver->close = LB216_close; - driver->flush = LB216_flush; - //driver->flush_box = NULL; - //driver->contrast = NULL; - driver->backlight = LB216_backlight; - driver->set_char = LB216_set_char; - driver->icon = LB216_icon; - driver->draw_frame = LB216_draw_frame; + drvthis->init = LB216_init; + drvthis->close = LB216_close; + drvthis->width = LB216_width; + drvthis->height = LB216_height; + drvthis->flush = LB216_flush; + drvthis->backlight = LB216_backlight; + drvthis->set_char = LB216_set_char; + drvthis->old_icon = LB216_icon; - LB216->cellwid = 5; - LB216->cellhgt = 8; - - debug("LB216: foo!\n"); - - return fd; + return 0; } @@ -237,28 +244,66 @@ int LB216_init(lcd_logical_driver *driver, char *args) ///////////////////////////////////////////////////////////////// // Clean-up // -void LB216_close() +MODULE_EXPORT void +LB216_close(Driver * drvthis) { close (fd); - if(LB216->framebuf) free(LB216->framebuf); + if(framebuf) free(framebuf); + framebuf = NULL; +} - LB216->framebuf = NULL; +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +LB216_width (Driver *drvthis) +{ + return width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +LB216_height (Driver *drvthis) +{ + return height; } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -LB216_clear () +MODULE_EXPORT void +LB216_clear (Driver * drvthis) { - memset (LB216->framebuf, ' ', LB216->wid * LB216->hgt); - + memset (framebuf, ' ', width * height); } -void LB216_flush() + +///////////////////////////////////////////////////////////////// +// Flushes the framebuffer to the LCD +// +MODULE_EXPORT void +LB216_flush(Driver * drvthis) { - LB216_draw_frame(LB216->framebuf); + char out[LCD_MAX_WIDTH * LCD_MAX_HEIGHT]; + int i,j; + + snprintf (out, sizeof(out), "%c%c", 254,80); + write(fd, out, 2); + + for(j=0; j=2) { + snprintf (out, sizeof(out),"%c%c",254,148+(64*(j-2))); + } else { + snprintf (out, sizeof(out),"%c%c",254,128+(64*(j))); + } + write(fd, out, 2); + for(i=0; i= 0) c += 128; -// LB216->framebuf[(y*LB216->wid) + x] = c; +// framebuf[(y*width) + x] = c; // char chr[1]; // snprintf (chr, sizeof(chr), "%c", c); @@ -282,7 +328,7 @@ void LB216_chr(int x, int y, char c) char chr[2]; chr[0] = c; chr[1] = 0; - LB216_string (x, y, chr); + LB216_string (drvthis, x, y, chr); } @@ -290,7 +336,8 @@ void LB216_chr(int x, int y, char c) // Sets the backlight on or off -- can be done quickly for // an intermediate brightness... // -void LB216_backlight(int on) +MODULE_EXPORT void +LB216_backlight(Driver * drvthis, int on) { char out[4]; if(on) @@ -326,36 +373,8 @@ static void LB216_reboot() } -///////////////////////////////////////////////////////////// -// Blasts a single frame onscreen, to the lcd... -// -// Input is a character array, sized LB216->wid*LB216->hgt -// -void LB216_draw_frame(char *dat) -{ - char out[LCD_MAX_WIDTH * LCD_MAX_HEIGHT]; - int i,j; - - if(!dat) return; - - snprintf (out, sizeof(out), "%c%c", 254,80); - write(fd, out, 2); - - for(j=0; jhgt; j++) { - if (j>=2) { - snprintf (out, sizeof(out),"%c%c",254,148+(64*(j-2))); - } else { - snprintf (out, sizeof(out),"%c%c",254,128+(64*(j))); - } - write(fd, out, 2); - for(i=0; iwid; i++) { - snprintf (out, sizeof(out),"%c",dat[i+(j*LB216->wid)]); - write(fd, out, 1); - } - } -} - -void LB216_string (int x, int y, char string[]) +MODULE_EXPORT void +LB216_string (Driver * drvthis, int x, int y, char string[]) { int i; char c; @@ -369,7 +388,7 @@ void LB216_string (int x, int y, char string[]) { case '\254': c = '#'; break; } - LB216->framebuf[(y*LB216->wid) + x+i] = c; + framebuf[(y*width) + x+i] = c; } } @@ -377,7 +396,8 @@ void LB216_string (int x, int y, char string[]) ///////////////////////////////////////////////////////////////// // Sets up for vertical bars. Call before LB216->vbar() // -void LB216_init_vbar() +MODULE_EXPORT void +LB216_init_vbar(Driver * drvthis) { char a[] = { 0,0,0,0,0, @@ -451,13 +471,13 @@ void LB216_init_vbar() }; if(custom!=vbar) { - LB216_set_char(1,a); - LB216_set_char(2,b); - LB216_set_char(3,c); - LB216_set_char(4,d); - LB216_set_char(5,e); - LB216_set_char(6,f); - LB216_set_char(7,g); + LB216_set_char(drvthis, 1,a); + LB216_set_char(drvthis, 2,b); + LB216_set_char(drvthis, 3,c); + LB216_set_char(drvthis, 4,d); + LB216_set_char(drvthis, 5,e); + LB216_set_char(drvthis, 6,f); + LB216_set_char(drvthis, 7,g); custom=vbar; } } @@ -465,7 +485,8 @@ void LB216_init_vbar() ///////////////////////////////////////////////////////////////// // Inits horizontal bars... // -void LB216_init_hbar() +MODULE_EXPORT void +LB216_init_hbar(Driver * drvthis) { char a[] = { @@ -520,11 +541,11 @@ void LB216_init_hbar() }; if(custom!=hbar) { - LB216_set_char(1,a); - LB216_set_char(2,b); - LB216_set_char(3,c); - LB216_set_char(4,d); - LB216_set_char(5,e); + LB216_set_char(drvthis, 1,a); + LB216_set_char(drvthis, 2,b); + LB216_set_char(drvthis, 3,c); + LB216_set_char(drvthis, 4,d); + LB216_set_char(drvthis, 5,e); custom=hbar; } } @@ -532,18 +553,19 @@ void LB216_init_hbar() ///////////////////////////////////////////////////////////////// // Draws a vertical bar... // -void LB216_vbar(int x, int len) +MODULE_EXPORT void +LB216_vbar(Driver * drvthis, int x, int len) { char map[9] = {32, 1, 2, 3, 4, 5, 6, 7, 255 }; int y; - for(y=LB216->hgt; y > 0 && len>0; y--) + for(y=height; y > 0 && len>0; y--) { - if(len >= LB216->cellhgt) LB216_chr(x, y, 255); - else LB216_chr(x, y, map[len]); + if(len >= cellheight) LB216_chr(drvthis, x, y, 255); + else LB216_chr(drvthis, x, y, map[len]); - len -= LB216->cellhgt; + len -= cellheight; } } @@ -551,17 +573,18 @@ void LB216_vbar(int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void LB216_hbar(int x, int y, int len) +MODULE_EXPORT void +LB216_hbar(Driver * drvthis, int x, int y, int len) { char map[7] = { 32, 1, 2, 3, 4, 5 }; - for(; x<=LB216->wid && len>0; x++) + for(; x<=width && len>0; x++) { - if(len >= LB216->cellwid) LB216_chr(x,y,map[5]); - else LB216_chr(x, y, map[len]); + if(len >= cellwidth) LB216_chr(drvthis, x,y,map[5]); + else LB216_chr(drvthis, x, y, map[len]); //printf ("%d,",len); - len -= LB216->cellwid; + len -= cellwidth; } // printf ("\n"); @@ -576,7 +599,8 @@ void LB216_hbar(int x, int y, int len) // // The input is just an array of characters... // -void LB216_set_char(int n, char *dat) +MODULE_EXPORT void +LB216_set_char(Driver * drvthis, int n, char *dat) { char out[4]; int row, col; @@ -589,20 +613,21 @@ void LB216_set_char(int n, char *dat) snprintf (out, sizeof(out), "%c%c", 254, n); write(fd, out, 2); - for(row=0; rowcellhgt; row++) + for(row=0; rowcellwid; col++) + for(col=0; colcellwid) + col] > 0); + letter |= (dat[(row*cellwidth) + col] > 0); } snprintf (out, sizeof(out),"%c",letter); write(fd, out, 1); } } -void LB216_icon(int which, char dest) +MODULE_EXPORT void +LB216_icon(Driver * drvthis, int which, char dest) { char icons[3][8*8] = { { @@ -641,5 +666,5 @@ void LB216_icon(int which, char dest) }; if(custom==bign) custom=beat; - LB216_set_char(dest, &icons[which][0]); + LB216_set_char(drvthis, dest, &icons[which][0]); } diff --git a/server/drivers/lb216.h b/server/drivers/lb216.h index 91f7d1c..ac59fd1 100644 --- a/server/drivers/lb216.h +++ b/server/drivers/lb216.h @@ -1,25 +1,28 @@ #ifndef LB216_H #define LB216_H +#include "lcd.h" -extern lcd_logical_driver *LB216; + int LB216_init(Driver * drvthis, char *device); +MODULE_EXPORT void LB216_close(Driver * drvthis); +MODULE_EXPORT int LB216_width (Driver *drvthis); +MODULE_EXPORT int LB216_height (Driver *drvthis); +MODULE_EXPORT void LB216_clear (Driver * drvthis); +MODULE_EXPORT void LB216_flush(Driver * drvthis); +MODULE_EXPORT void LB216_string (Driver * drvthis, int x, int y, char string[]); +MODULE_EXPORT void LB216_chr(Driver * drvthis, int x, int y, char c) ; -int LB216_init(lcd_logical_driver *driver, char *device); -void LB216_clear (); -void LB216_close(); -void LB216_string (int x, int y, char string[]); -void LB216_flush(); -void LB216_flush_box(int lft, int top, int rgt, int bot); -void LB216_chr(int x, int y, char c) ; -void LB216_backlight(int on); -void LB216_init_vbar(); -void LB216_init_hbar(); -void LB216_vbar(int x, int len); -void LB216_hbar(int x, int y, int len); -void LB216_init_num(); -void LB216_num(int x, int num); -void LB216_set_char(int n, char *dat); -void LB216_icon(int which, char dest); -void LB216_draw_frame(char *dat); +MODULE_EXPORT void LB216_vbar(Driver * drvthis, int x, int len); +MODULE_EXPORT void LB216_hbar(Driver * drvthis, int x, int y, int len); +MODULE_EXPORT void LB216_num(Driver * drvthis, int x, int num); +MODULE_EXPORT void LB216_icon(Driver * drvthis, int which, char dest); + +MODULE_EXPORT void LB216_set_char(Driver * drvthis, int n, char *dat); + +MODULE_EXPORT void LB216_backlight(Driver * drvthis, int on); + +MODULE_EXPORT void LB216_init_vbar(Driver * drvthis); +MODULE_EXPORT void LB216_init_hbar(Driver * drvthis); +MODULE_EXPORT void LB216_init_num(Driver * drvthis); #endif diff --git a/server/drivers/lcd.c b/server/drivers/lcd.c index dace4dc..c62a114 100644 --- a/server/drivers/lcd.c +++ b/server/drivers/lcd.c @@ -36,6 +36,7 @@ #include "lcd.h" +/* static int lcd_drv_init (lcd_logical_driver * driver, char *args); static void lcd_drv_close (); static void lcd_drv_clear (); @@ -59,6 +60,7 @@ static char lcd_drv_getkey (); static char lcd_drv_getkey_loop (); static char *lcd_drv_getinfo (); static void lcd_drv_heartbeat (int type); +*/ /* * Add all of the driver's header files in... @@ -153,7 +155,8 @@ static void lcd_drv_heartbeat (int type); // TODO: Make a Windows server, and clients...? -lcd_logical_driver lcd, *lcd_root = NULL, *lcd_ptr = NULL; +//Driver *lcd_root = NULL; +//Driver *lcd_ptr = NULL; // TODO: Add multiple names for the same driver? // @@ -267,15 +270,20 @@ lcd_list_drivers (void) { // // This was eliminated; everything // done here is to be replaced by the use of lcd_add_driver()... + +/* int lcd_init (char *args) { return 0; } +*/ // This sets up all of the "wrapper" driver functions // which call all of the drivers in turn. // + +/* static int lcd_drv_init (struct lcd_logical_driver *driver, char *args) { @@ -379,6 +387,7 @@ lcd_drv_patch_init (struct lcd_logical_driver *driver) return 0; } +*/ /* * This function can be replaced later with something @@ -386,6 +395,7 @@ lcd_drv_patch_init (struct lcd_logical_driver *driver) * */ + void * lcd_find_init (char *driver) { int i; @@ -401,11 +411,13 @@ lcd_find_init (char *driver) { return NULL; } + // TODO: lcd_remove_driver() -struct lcd_logical_driver * +/* +Driver * lcd_allocate_driver () { - struct lcd_logical_driver *driver; + Driver *driver; //int driver_size; // This bit of fakery allows us to use lcd as the first @@ -414,7 +426,7 @@ lcd_allocate_driver () { #define FirstTime (lcd_ptr->framebuf == NULL) - if ((driver = malloc(sizeof(lcd_logical_driver))) == NULL) { + if ((driver = malloc(sizeof(Driver))) == NULL) { syslog(LOG_ERR, "error allocating driver space!"); return NULL; } @@ -432,6 +444,7 @@ lcd_allocate_driver () { // it. This is the function which calls, for example, // MtxOrb_init. The specifics come from the drivers[] array. + static char (*main_getkey) () = NULL; int @@ -507,19 +520,7 @@ lcd_add_driver (char *driver, char *args) } return -1; } - -// TODO: Put lcd_shutdown in the shutdown function... -int -lcd_shutdown () -{ - //lcd_logical_driver *driver; - - // This does not shutdown any input sources; - // is that sufficient? - lcd_root->close (); - - return 0; -} +*/ ////////////////////////////////////////////////////////////////////// // All functions below here call their respective driver functions... @@ -563,6 +564,7 @@ lcd_shutdown () // lcd_drv_getkey () // lcd_drv_getinfo () +/* static void lcd_drv_close () { @@ -686,9 +688,10 @@ lcd_drv_getkey () // This loops through all defined getkeys, returning // the first input that it finds, if any. + static char lcd_drv_getkey_loop () { - lcd_logical_driver *driver; + Driver *driver; char c; if ((c = main_getkey()) != 0) @@ -708,3 +711,4 @@ lcd_drv_heartbeat (int type) ; } +*/ \ No newline at end of file diff --git a/server/drivers/lcd.h b/server/drivers/lcd.h index 7b3d1db..9c229fa 100644 --- a/server/drivers/lcd.h +++ b/server/drivers/lcd.h @@ -1,104 +1,200 @@ +/* + * client.h + * This file is part of LCDd, the lcdproc server. + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 1999, William Ferrell, Scott Scriven + * 2001, Joris Robijn + * + * + * This file defines the LCDd-driver API + * It is written to facilitate loadable driver modules. + * There should be no further interaction between driver and server core + * other that via this API. + * + * DO NOT MIX DRIVER ALLOCATED AND CORE ALLOCATED MEMORY. + * With this I mean that the server core should NEVER WRITE in memory + * allocated by the driver, and vice versa. Also the driver resp. core + * should free or realloc the memory that it has allocated. You can always + * simply copy a string if its data space is not 'yours'. + */ + #ifndef LCD_H #define LCD_H -// Maximum supported sizes +/* Maximum supported sizes */ #define LCD_MAX_WIDTH 256 #define LCD_MAX_HEIGHT 256 -// Standard supported sizes -#define LCD_STD_WIDTH 20 -#define LCD_STD_HEIGHT 4 -#define LCD_STD_CELL_WIDTH 5 -#define LCD_STD_CELL_HEIGHT 8 +/* Standard supported sizes */ +#define LCD_DEFAULT_WIDTH 20 +#define LCD_DEFAULT_HEIGHT 4 +#define LCD_DEFAULT_CELLWIDTH 5 +#define LCD_DEFAULT_CELLHEIGHT 8 -void lcd_list_drivers (void); -int lcd_init (char *args); -int lcd_add_driver (char *driver, char *args); -int lcd_shutdown (); +/* Backlight data */ +#define BACKLIGHT_OFF 0 +#define BACKLIGHT_ON 1 +#define BACKLIGHT_WARNING 2 +#define BACKLIGHT_RED_ALERT 3 + +// Icons for icon function +#define ICON_BLOCK_FILLED 0 +#define ICON_HEART_OPEN 8 +#define ICON_HEART_FILLED 9 + +/* Heartbeat data, taken from render.h */ +/* ??? What do all these mean ? */ +#define HEART_OFF 1 +#define HEART_ON 2 +#define HEART_OPEN 3 +#define HEARTBEAT_OFF HEART_OFF +#define HEARTBEAT_ON HEART_ON +#define HEARTBEAT_OPEN HEART_OPEN + +/* Patterns for hbar / vbar */ +#define BAR_POS 0x001 /* default */ +#define BAR_NEG 0x002 +#define BAR_POS_AND_NEG 0x003 +#define BAR_PATTERN_FILLED 0x000 +#define BAR_PATTERN_OPEN 0x010 +#define BAR_PATTERN_STRIPED 0x020 +#define BAR_WITH_PERCENTAGE 0x100 + +/* Cursor types */ +#define CURSOR_OFF 0 +#define CURSOR_DEFAULT_ON 1 +#define CURSOR_BLOCK 4 +#define CURSOR_UNDER 5 + +/* What does the shared module handle look like on the current platform? */ +#define MODULE_HANDLE void* +/* And how do we define the exported functions */ +#define MODULE_EXPORT static +/* WHILE NOT MODULES static BECAUSE OTHERWISE WE HAVE MULTIPLE IDENTICAL SYMBOLS */ -///////////////////////////////////////////////////////////////// -// Driver functions / info held here... -// -// Feel free to override any/all functions here with real driver -// functions... -// typedef struct lcd_logical_driver { - // Size in cells of the LCD - int wid, hgt; - // Size of each LCD cell, in pixels - int cellwid, cellhgt; - // Frame buffer... - char *framebuf; - // Daemonizable? Usually yes... - int daemonize; + /* Ancient variables */ - // Pointer to next input function... - //lcd_logical_driver *nextkey; - void *nextkey; + /* For explanation of variables and functions see docs/API-v0.5.txt */ - // Functions which might be the same for all drivers... - void (*clear) (); - void (*string) (int x, int y, char lcd[]); + /******** Variables in the driver module ********/ + /* The driver loader will look for symbols with these names ! */ - void (*chr) (int x, int y, char c); - void (*vbar) (int x, int len); - void (*hbar) (int x, int y, int len); - void (*init_num) (); - void (*num) (int x, int num); + char *api_version; + int *stay_in_foreground; /* Does this driver require to be in foreground ? */ + int *supports_multiple; /* Does this driver support multiple instances ? */ + char *func_prefix; /* What should be prepended to the function names ? */ + + + /******** Functions in the driver module ********/ + /* The driver loader will look for symbols with these names ! */ + + /* Basic functions */ + int (*init) (struct lcd_logical_driver* drvthis, char *args); + void (*close) (struct lcd_logical_driver* drvthis); + int (*width) (struct lcd_logical_driver* drvthis); + int (*height) (struct lcd_logical_driver* drvthis); + void (*clear) (struct lcd_logical_driver* drvthis); + void (*flush) (struct lcd_logical_driver* drvthis); + void (*string) (struct lcd_logical_driver* drvthis, int x, int y, char *str); + void (*chr) (struct lcd_logical_driver* drvthis, int x, int y, char c); + + /* Extended functions */ + void (*vbar) (struct lcd_logical_driver* drvthis, int x, int y, int len, int promille, int pattern); + void (*hbar) (struct lcd_logical_driver* drvthis, int x, int y, int len, int promille, int pattern); + void (*num) (struct lcd_logical_driver* drvthis, int x, int num); + void (*heartbeat) (struct lcd_logical_driver* drvthis, int state); + void (*icon) (struct lcd_logical_driver* drvthis, int x, int y, int icon); + void (*cursor) (struct lcd_logical_driver* drvthis, int x, int y, int state); + + /* Userdef characters, are those still supported ? */ + void (*set_char) (struct lcd_logical_driver* drvthis, int n, char *dat); + int (*get_free_chars) (struct lcd_logical_driver* drvthis); + int (*cellwidth) (struct lcd_logical_driver* drvthis); + int (*cellheight) (struct lcd_logical_driver* drvthis); + + /* Hardware functions */ + int (*get_contrast) (struct lcd_logical_driver* drvthis); + void (*set_contrast) (struct lcd_logical_driver* drvthis, int promille); + int (*get_brightness) (struct lcd_logical_driver* drvthis, int state); + void (*set_brightness) (struct lcd_logical_driver* drvthis, int state, int promille); + void (*backlight) (struct lcd_logical_driver* drvthis, int on); + void (*output) (struct lcd_logical_driver* drvthis, int state); + + /* Key functions */ + char *(*get_key) (struct lcd_logical_driver* drvthis); + /* Returns a string. Server cannot modify + this string. */ + + char * (*get_info) (); + + + /* OLD FUNCTIONS */ + void (*old_vbar) (struct lcd_logical_driver* drvthis, int x, int len); + void (*old_hbar) (struct lcd_logical_driver* drvthis, int x, int y, int len); + void (*old_icon) (struct lcd_logical_driver* drvthis, int which, char dest); + /* THESE 3 TO BE REMOVED */ - // Functions which should probably be implemented in each driver... - int (*init) (struct lcd_logical_driver * driver, char *args); - void (*close) (); - void (*flush) (); - void (*flush_box) (int lft, int top, int rgt, int bot); - int (*contrast) (int contrast); - void (*backlight) (int on); - void (*output) (int on); - void (*set_char) (int n, char *dat); - void (*icon) (int which, char dest); void (*init_vbar) (); void (*init_hbar) (); + void (*init_num) (); void (*draw_frame) (); + void (*flush_box) (int lft, int top, int rgt, int bot); + /* THESE 4 TO BE REMOVED */ - // Returns 0 for "no key pressed", or (A-Z). + /* Returns 0 for "no key pressed", or (A-Z). */ char (*getkey) (); + /* TO BE REMOVED, IS RENAMED AND CHANGED */ - // Returns pointer to static string. - char * (*getinfo) (); - // Puts up a heartbeat... - void (*heartbeat) (int type); - // more? + /******** Variables in server core available for drivers ********/ - // Config file functions, filled by server - char (*config_get_bool) (char * sectionname, char * keyname, - int skip, char default_value); - int (*config_get_int) (char * sectionname, char * keyname, - int skip, int default_value); - 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_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); + char * name; /* Name of this driver */ + char * filename; /* Filename of the shared module */ + + MODULE_HANDLE module_handle; /* The handle of the loaded shared module + Is platform specific */ + + void * private_data; /* Filled by server by calling store_private_ptr() + Driver should cast this to it's own + private structure pointer */ + + + /******** Functions in server core available for drivers ********/ - // Driver private data int (*store_private_ptr) (struct lcd_logical_driver * driver, void * private_data); - void * private_data; // Filled by server by calling store_private_ptr() - // Driver should cast this to it's own - // private structure pointer + /* Store the driver's private data */ -} lcd_logical_driver; + /* Configfile functions */ + /* See configfile.h for descriptions and usage. */ -typedef struct lcd_physical_driver { + unsigned char (*config_get_bool)( char *sectionname, char *keyname, int skip, unsigned char 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 ); + char *( *config_get_string) ( char *sectionname, char *keyname, int skip, char *default_value ); + int (*config_has_section) ( char *sectionname ); + int (*config_has_key) ( char *sectionname, char *keyname ); + + /* Reporting function */ + /* Easily usable by including drivers/report.h */ + void (*report) ( const int level, const char *format, .../*args*/ ); + + /* Display properties functions (for drivers that adapt to other loaded drivers) */ + int (*request_display_width) (); + int (*request_display_height) (); + +} Driver; + + +void lcd_list_drivers (void); /* TO BE REMOVED WHEN WE HAVE LOADABLE MODULES */ + +typedef struct lcd_physical_driver { /* TO BE REMOVED WHEN WE HAVE LOADABLE MODULES */ char *name; int (*init) (struct lcd_logical_driver * driver, char *device); } lcd_physical_driver; -//extern lcd_logical_driver lcd; -extern lcd_logical_driver *lcd_ptr; - #endif diff --git a/server/drivers/lcd_lib.c b/server/drivers/lcd_lib.c index 6e0921b..2be8b05 100644 --- a/server/drivers/lcd_lib.c +++ b/server/drivers/lcd_lib.c @@ -20,6 +20,9 @@ // driver code or headers or something... #define MAX_CUSTOM_CHARS 16 +/* +ANY DRIVER SHOULD SIMPLY FREE ITS FRAMEBUFFER AT CLOSE() +NO CHECKING FOR NULL NEEDED void free_framebuf (struct lcd_logical_driver *driver) { if (!driver) @@ -30,7 +33,10 @@ free_framebuf (struct lcd_logical_driver *driver) { driver->framebuf = NULL; } +*/ +/* +NEED TO BE ADAPTED TO NEW SITUATION void clear_framebuf (struct lcd_logical_driver *driver) { int framebuf_size; @@ -41,7 +47,10 @@ clear_framebuf (struct lcd_logical_driver *driver) { framebuf_size = driver->wid * driver->hgt; memset (driver->framebuf, ' ', framebuf_size); } +*/ +/* +NEED TO BE ADAPTED TO NEW SITUATION int new_framebuf (struct lcd_logical_driver *driver, char *oldbuf) { int i; @@ -59,7 +68,10 @@ new_framebuf (struct lcd_logical_driver *driver, char *oldbuf) { } return 0; } +*/ +/* +NEED TO BE ADAPTED TO NEW SITUATION void insert_str_framebuf (struct lcd_logical_driver *driver, int x, int y, char *string) { //int i; @@ -85,7 +97,10 @@ insert_str_framebuf (struct lcd_logical_driver *driver, int x, int y, char *stri pos = (driver->framebuf + (y * driver->wid) + x); strcpy(pos, buf); } +*/ +/* +NEED TO BE ADAPTED TO NEW SITUATION void insert_chr_framebuf (struct lcd_logical_driver *driver, int x, int y, char c) { if (!driver) @@ -101,6 +116,7 @@ insert_chr_framebuf (struct lcd_logical_driver *driver, int x, int y, char c) { driver->framebuf[(y * driver->wid) + x] = c; } +*/ void output_heartbeat (struct lcd_logical_driver *driver, int type) { @@ -113,17 +129,26 @@ output_heartbeat (struct lcd_logical_driver *driver, int type) { if (type == HEARTBEAT_ON) { // Set this to pulsate like a real heart beat... - whichIcon = (! ((timer + 4) & 5)); + if ( (timer + 4) & 5 ) { + whichIcon = ICON_HEART_OPEN; + } + else { + whichIcon = ICON_HEART_FILLED; + } + driver->icon (driver, driver->width(driver), 1, whichIcon); + + /* OLD CODE // This defines a custom character EVERY time... // not efficient... is this necessary? - driver->icon (whichIcon, 0); + driver->icon (driver, whichIcon, 0); // Put character on screen... - driver->chr (driver->wid, 1, 0); + driver->chr (driver, driver->wid, 1, 0); + */ // change display... - driver->flush (); + driver->flush (driver); } timer++; diff --git a/server/drivers/lcdm001.c b/server/drivers/lcdm001.c index 5f49d47..b7d8ce4 100644 --- a/server/drivers/lcdm001.c +++ b/server/drivers/lcdm001.c @@ -42,6 +42,11 @@ #include #include #include + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + # if TIME_WITH_SYS_TIME # include # include @@ -56,37 +61,24 @@ #include "lcd.h" #include "lcdm001.h" #include "shared/str.h" -#include "shared/report.h" -#include "configfile.h" -#include "render.h" +#include "report.h" +//#include "configfile.h" -// Moved here from lcdm001.h to reduce the number of warning. -static void lcdm001_close (); -static void lcdm001_clear (); -static void lcdm001_flush (); -static void lcdm001_string (int x, int y, char string[]); -static void lcdm001_chr (int x, int y, char c); -static void lcdm001_output (int on); -static void lcdm001_vbar (int x, int len); -static void lcdm001_hbar (int x, int y, int len); -static void lcdm001_num (int x, int num); -static void lcdm001_icon (int which, char dest); -static void lcdm001_flush_box (int lft, int top, int rgt, int bot); -static void lcdm001_draw_frame (char *dat); -static char lcdm001_getkey (); -// End of extract from lcdm001.h by David GLAUDE. -static void lcdm001_heartbeat (int type); -#define NotEnoughArgs (i + 1 > argc) - -lcd_logical_driver *lcdm001; int fd; static int clear = 1; static char icon_char = '@'; static char pause_key = DOWN_KEY, back_key = LEFT_KEY, forward_key = RIGHT_KEY, main_menu_key = UP_KEY; +static char *framebuf = NULL; +static int width = LCD_DEFAULT_WIDTH; +static int height = LCD_DEFAULT_HEIGHT; +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "lcdm001_"; -/*this is really ugly ;) but works ;)*/ static char num_icon [10][4][3] = {{{' ','_',' '}, /*0*/ {'|',' ','|'}, {'|','_','|'}, @@ -127,27 +119,25 @@ static char num_icon [10][4][3] = {{{' ','_',' '}, /*0*/ {'|','_','|'}, {' ','_','|'}, {' ',' ',' '}}}; -/*end of ugly code ;) Rene Wagner*/ -static void lcdm001_cursorblink (int on); -static void lcdm001_string (int x, int y, char *string); -static char lcdm001_parse_keypad_setting ( char * sectionname, char * keyname, char * default_value ); +static void lcdm001_cursorblink (Driver *drvthis, int on); +static char lcdm001_parse_keypad_setting ( Driver *drvthis, char * keyname, char * default_value ); -#define ValidX(x) if ((x) > lcdm001->wid) { (x) = lcdm001->wid; } else (x) = (x) < 1 ? 1 : (x); -#define ValidY(y) if ((y) > lcdm001->hgt) { (y) = lcdm001->hgt; } else (y) = (y) < 1 ? 1 : (y); +#define ValidX(x) if ((x) > width) { (x) = width; } else (x) = (x) < 1 ? 1 : (x); +#define ValidY(y) if ((y) > height) { (y) = height; } else (y) = (y) < 1 ? 1 : (y); // Parse one key from the configfile -static char lcdm001_parse_keypad_setting (char * sectionname, char * keyname, char * default_value) +static char lcdm001_parse_keypad_setting (Driver *drvthis, char * keyname, char * default_value) { char return_val = 0; - if (strcmp( config_get_string ( sectionname, keyname, 0, default_value), "LeftKey")==0) { + if (strcmp( drvthis->config_get_string ( drvthis->name, keyname, 0, default_value), "LeftKey")==0) { return_val=LEFT_KEY; - } else if (strcmp( config_get_string ( sectionname, keyname, 0, default_value), "RightKey")==0) { + } else if (strcmp( drvthis->config_get_string ( drvthis->name, keyname, 0, default_value), "RightKey")==0) { return_val=RIGHT_KEY; - } else if (strcmp( config_get_string ( sectionname, keyname, 0, default_value), "UpKey")==0) { + } else if (strcmp( drvthis->config_get_string ( drvthis->name, keyname, 0, default_value), "UpKey")==0) { return_val=UP_KEY; - } else if (strcmp( config_get_string ( sectionname, keyname, 0, default_value), "DownKey")==0) { + } else if (strcmp( drvthis->config_get_string ( drvthis->name, keyname, 0, default_value), "DownKey")==0) { return_val=DOWN_KEY; } else { report (RPT_WARNING, "LCDM001: Invalid config file setting for %s. Using default value %s.\n", keyname, default_value); @@ -164,10 +154,9 @@ static char lcdm001_parse_keypad_setting (char * sectionname, char * keyname, ch return return_val; } -// Set cursorblink on/off -// +/* Set cursorblink on/off */ static void -lcdm001_cursorblink (int on) +lcdm001_cursorblink (Driver *drvthis, int on) { if (on) { write (fd, "~K1", 3); @@ -179,13 +168,14 @@ lcdm001_cursorblink (int on) } -// TODO: Get lcd.framebuf to properly work as whatever driver is running... +/* TODO: Get lcd.framebuf to properly work as whatever driver is running...*/ -//////////////////////////////////////////////////////////// -// init() should set up any device-specific stuff, and -// point all the function pointers. +/********************************************************************* + * init() should set up any device-specific stuff, and + * point all the function pointers. + */ int -lcdm001_init (struct lcd_logical_driver *driver, char *args) +lcdm001_init (Driver *drvthis, char *args) { char device[200]; int speed=B38400; @@ -193,48 +183,28 @@ lcdm001_init (struct lcd_logical_driver *driver, char *args) char out[5]=""; - lcdm001 = driver; + debug( RPT_INFO, "LCDM001: init(%p,%s)", drvthis, args ); - debug( RPT_INFO, "LCDM001: init(%p,%s)", driver, args ); + framebuf = malloc (width * height); - driver->wid = 20; - driver->hgt = 4; - - // You must use driver->framebuf here, but may use lcd.framebuf later. - if (!driver->framebuf) { - driver->framebuf = malloc (driver->wid * driver->hgt); - } - - if (!driver->framebuf) { - lcdm001_close (); + if (!framebuf) { report(RPT_ERR, "\nError: unable to create LCDM001 framebuffer.\n"); return -1; } -// Debugging... -// if(lcd.framebuf) printf("Frame buffer: %i\n", (int)lcd.framebuf); - - memset (driver->framebuf, ' ', driver->wid * driver->hgt); -// lcdm001_clear(); - - driver->cellwid = 5; - driver->cellhgt = 8; - - // TODO: replace DriverName with driver->name when that field exists. - #define DriverName "lcdm001" + memset (framebuf, ' ', width * height); // READ CONFIG FILE: // which serial device should be used - strncpy(device, config_get_string ( DriverName , "Device" , 0 , "/dev/lcd"), sizeof(device)); + strncpy(device, drvthis->config_get_string ( drvthis->name , "Device" , 0 , "/dev/lcd"),sizeof(device)); device[sizeof(device)-1]=0; report (RPT_INFO,"LCDM001: Using device: %s", device); // keypad settings - pause_key = lcdm001_parse_keypad_setting (DriverName, "PauseKey", "DownKey"); - back_key = lcdm001_parse_keypad_setting (DriverName, "BackKey", "LeftKey"); - forward_key = lcdm001_parse_keypad_setting (DriverName, "ForwardKey", "RightKey"); - main_menu_key = lcdm001_parse_keypad_setting (DriverName, "MainMenuKey", "UpKey"); - + pause_key = lcdm001_parse_keypad_setting (drvthis, "PauseKey", "DownKey"); + back_key = lcdm001_parse_keypad_setting (drvthis, "BackKey", "LeftKey"); + forward_key = lcdm001_parse_keypad_setting (drvthis, "ForwardKey", "RightKey"); + main_menu_key = lcdm001_parse_keypad_setting (drvthis, "MainMenuKey", "UpKey"); // Set up io port correctly, and open it... debug( RPT_DEBUG, "LCDM001: Opening serial device: %s", device); @@ -256,10 +226,10 @@ lcdm001_init (struct lcd_logical_driver *driver, char *args) } tcgetattr(fd, &portset); #ifdef HAVE_CFMAKERAW - // The easy way + /* The easy way: */ cfmakeraw( &portset ); #else - // The hard way + /* The hard way: */ portset.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON ); portset.c_oflag &= ~OPOST; @@ -275,59 +245,60 @@ lcdm001_init (struct lcd_logical_driver *driver, char *args) // Reset and clear the LCDM001 write (fd, "~C", 2); //Set cursorblink default - lcdm001_cursorblink (DEFAULT_CURSORBLINK); + lcdm001_cursorblink (drvthis, DEFAULT_CURSORBLINK); // Turn all LEDs off snprintf (out, sizeof(out), "\%cL%c%c", 126, 0, 0); write (fd, out, 4); - /* - * Configure the display functions - */ - driver->daemonize = 1; // daemonize. + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->clear = lcdm001_clear; - driver->string = lcdm001_string; - driver->chr = lcdm001_chr; - driver->vbar =lcdm001_vbar; + // Set the functions the driver supports + drvthis->clear = lcdm001_clear; + drvthis->width = lcdm001_width; + drvthis->height = lcdm001_height; + drvthis->string = lcdm001_string; + drvthis->chr = lcdm001_chr; + drvthis->old_vbar =lcdm001_vbar; //init_vbar is not needed - driver->hbar = lcdm001_hbar; + drvthis->old_hbar = lcdm001_hbar; //init_hbar is not needed - driver->num = lcdm001_num; + drvthis->num = lcdm001_num; //init_num is not needed - driver->init = lcdm001_init; - driver->close = lcdm001_close; - driver->flush = lcdm001_flush; - driver->flush_box = lcdm001_flush_box; + drvthis->init = lcdm001_init; + drvthis->close = lcdm001_close; + drvthis->flush = lcdm001_flush; //contrast and backlight are not implemented as //changing the contrast or the state of the backlight //is not supported by the device - //Well ... you could make use of your screw driver and + //Well ... you could make use of your screw drvthis and //soldering iron ;) - driver->output = lcdm001_output; + drvthis->output = lcdm001_output; //set_char is not implemented as custom chars are not //supported by the device - driver->icon = lcdm001_icon; - driver->draw_frame = lcdm001_draw_frame; + drvthis->old_icon = lcdm001_icon; - driver->getkey = lcdm001_getkey; - driver->heartbeat = lcdm001_heartbeat; + drvthis->getkey = lcdm001_getkey; + drvthis->heartbeat = lcdm001_heartbeat; - return fd; + return 0; } -// Below here, you may use either lcd.framebuf or driver->framebuf.. -// lcd.framebuf will be set to the appropriate buffer before calling -// your driver. +/* Below here, you may use either lcd.framebuf or driver->framebuf.. + * lcd.framebuf will be set to the appropriate buffer before calling + * your driver. + */ -static void -lcdm001_close () +MODULE_EXPORT void +lcdm001_close (Driver *drvthis) { char out[5]; - if (lcdm001->framebuf != NULL) - free (lcdm001->framebuf); + if(framebuf) free (framebuf); + framebuf = NULL; - lcdm001->framebuf = NULL; //switch off all LEDs snprintf (out, sizeof(out), "\%cL%c%c", 126, 0, 0); write (fd, out, 4); @@ -336,14 +307,32 @@ lcdm001_close () report (RPT_INFO, "LCDM001: closed"); } +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +lcdm001_width (Driver *drvthis) +{ + return width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +lcdm001_height (Driver *drvthis) +{ + return height; +} + ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -static void -lcdm001_clear () +MODULE_EXPORT void +lcdm001_clear (Driver *drvthis) { - if (lcdm001->framebuf != NULL) - memset (lcdm001->framebuf, ' ', (lcdm001->wid * lcdm001->hgt)); + if (framebuf != NULL) + memset (framebuf, ' ', (width * height)); write (fd, "~C", 2); // instant clear... clear = 1; @@ -354,38 +343,24 @@ lcdm001_clear () ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -void -lcdm001_flush () +MODULE_EXPORT void +lcdm001_flush (Driver *drvthis) { - lcdm001_draw_frame(lcdm001->framebuf); + // Next 4 lines are moved from draw_frame (Joris) + + //TODO: Check whether this is still correct + + write(fd,framebuf,80); debug (RPT_DEBUG, "LCDM001: frame buffer flushed"); } -////////////////////////////////////////////////////////////////////// -// Send a rectangular area to the display. -// - -static void -lcdm001_flush_box (int lft, int top, int rgt, int bot) -{ - int y; - char out[LCD_MAX_WIDTH]; - - for (y = top; y <= bot; y++) { - snprintf (out, sizeof(out), "%cP%c%c", 126, lft, y); - write (fd, out, 4); - write (fd, lcdm001->framebuf + (y * lcdm001->wid) + lft, rgt - lft + 1); - } - debug (RPT_DEBUG, "LCDM001: frame buffer box flushed"); -} - ///////////////////////////////////////////////////////////////// // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -static void -lcdm001_chr (int x, int y, char c) +MODULE_EXPORT void +lcdm001_chr (Driver *drvthis, int x, int y, char c) { char buf[64]; // char out[10]; int offset; @@ -400,8 +375,8 @@ lcdm001_chr (int x, int y, char c) // write to frame buffer y--; x--; // translate to 0-coords - offset = (y * lcdm001->wid) + x; - lcdm001->framebuf[offset] = c; + offset = (y * width) + x; + framebuf[offset] = c; snprintf(buf, sizeof(buf), "LCDM001: writing character %02X to position (%d,%d)", c, x, y); debug (RPT_DEBUG, buf); @@ -411,8 +386,8 @@ lcdm001_chr (int x, int y, char c) // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -static void -lcdm001_string (int x, int y, char string[]) +MODULE_EXPORT void +lcdm001_string (Driver *drvthis, int x, int y, char *string) { int offset, siz; @@ -420,53 +395,53 @@ lcdm001_string (int x, int y, char string[]) ValidY(y); x--; y--; // Convert 1-based coords to 0-based... - offset = (y * lcdm001->wid) + x; - siz = (lcdm001->wid * lcdm001->hgt) - offset - 1; + offset = (y * width) + x; + siz = (width * height) - offset - 1; siz = siz > strlen(string) ? strlen(string) : siz; - memcpy(lcdm001->framebuf + offset, string, siz); + memcpy(framebuf + offset, string, siz); debug (RPT_DEBUG, "LCDM001: printed string at (%d,%d)", x, y); } ///////////////////////////////////////////////////////////////// // Controls LEDs -static void -lcdm001_output (int on) +MODULE_EXPORT void +lcdm001_output (Driver *drvthis, int state) { char out[5]; int one = 0, two = 0; - if (on<=255) + if (state<=255) { - one=on; + one=state; two=0; } else { - one = on & 0xff; - two = (on >> 8) & 0xff; + one = state & 0xff; + two = (state >> 8) & 0xff; } snprintf (out, sizeof(out), "~L%c%c",one,two); write(fd,out,4); - debug (RPT_DEBUG, "LCDM001: current LED state: %d", on); + debug (RPT_DEBUG, "LCDM001: current LED state: %d", state); } ///////////////////////////////////////////////////////////////// // Draws a vertical bar, from the bottom of the screen up. // -static void -lcdm001_vbar(int x, int len) +MODULE_EXPORT void +lcdm001_vbar(Driver *drvthis, int x, int len) { int y = 4; debug (RPT_DEBUG , "LCDM001: vertical bar at %d set to %d", x, len); - while (len >= 8) + while (len >= LCD_DEFAULT_CELLHEIGHT) { - lcdm001_chr(x, y, 0xFF); - len -= 8; + lcdm001_chr(drvthis, x, y, 0xFF); + len -= LCD_DEFAULT_CELLHEIGHT; y--; } @@ -480,8 +455,8 @@ lcdm001_vbar(int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -static void -lcdm001_hbar(int x, int y, int len) +MODULE_EXPORT void +lcdm001_hbar(Driver *drvthis, int x, int y, int len) { ValidX(x); @@ -491,16 +466,16 @@ lcdm001_hbar(int x, int y, int len) //TODO: Improve this function - while((x <= lcdm001->wid) && (len > 0)) + while((x <= width) && (len > 0)) { - if(len < lcdm001->cellwid) + if(len < LCD_DEFAULT_CELLWIDTH) { //lcdm001_chr(x, y, 0x98 + len); break; } - lcdm001_chr(x, y, 0xFF); - len -= lcdm001->cellwid; + lcdm001_chr(drvthis, x, y, 0xFF); + len -= LCD_DEFAULT_CELLWIDTH; x++; } @@ -510,7 +485,8 @@ lcdm001_hbar(int x, int y, int len) ///////////////////////////////////////////////////////////////// // Writes a big number. // -static void lcdm001_num (int x, int num) +MODULE_EXPORT void +lcdm001_num (Driver *drvthis, int x, int num) { int y, dx; @@ -520,14 +496,14 @@ static void lcdm001_num (int x, int num) for (y = 1; y < 5; y++) for (dx = 0; dx < 3; dx++) - lcdm001_chr (x + dx, y, num_icon[num][y-1][dx]); + lcdm001_chr (drvthis, x + dx, y, num_icon[num][y-1][dx]); } ///////////////////////////////////////////////////////////////// // Sets character 0 to an icon... // -void -lcdm001_icon (int which, char dest) +MODULE_EXPORT void +lcdm001_icon (Driver *drvthis, int which, char dest) { /*Heartbeat workaround: @@ -549,27 +525,13 @@ lcdm001_icon (int which, char dest) } } -////////////////////////////////////////////////////////////////////// -// Draws the framebuffer on the display. -// -// The commented-out code is from the text driver. -// -void -lcdm001_draw_frame (char *dat) -{ - - //TODO: Check whether this is still correct - - write(fd,lcdm001->framebuf,80); -} - ////////////////////////////////////////////////////////////////////// // Tries to read a character from an input device... // // Return 0 for "nothing available". // -static char -lcdm001_getkey () +MODULE_EXPORT char +lcdm001_getkey (Driver *drvthis) { char in = 0; read (fd, &in, 1); @@ -589,8 +551,8 @@ lcdm001_getkey () ///////////////////////////////////////////////////////////// // Does the heartbeat... // -static void -lcdm001_heartbeat (int type) +MODULE_EXPORT void +lcdm001_heartbeat (Driver *drvthis, int type) { static int timer = 0; int whichIcon; @@ -605,13 +567,13 @@ lcdm001_heartbeat (int type) // This defines a custom character EVERY time... // not efficient... is this necessary? - lcdm001_icon (whichIcon, 0); + lcdm001_icon (drvthis, whichIcon, 0); // Put character on screen... - lcdm001_chr (lcdm001->wid, 1, 0); + lcdm001_chr (drvthis, width, 1, 0); // change display... - lcdm001_flush (); + lcdm001_flush (drvthis); } timer++; diff --git a/server/drivers/lcdm001.h b/server/drivers/lcdm001.h index 8194f51..757f4f8 100644 --- a/server/drivers/lcdm001.h +++ b/server/drivers/lcdm001.h @@ -30,10 +30,27 @@ lcdm001.h ******************************************************************/ -// REMOVE: I don't thing this is actualy needed. -// extern lcd_logical_driver *lcdm001; +/* REMOVE: I don't thing this is actualy needed. */ +/* extern lcd_logical_driver *lcdm001; */ -int lcdm001_init (struct lcd_logical_driver *driver, char *args); + int lcdm001_init (struct lcd_logical_driver *driver, char *args); +MODULE_EXPORT void lcdm001_close (Driver *drvthis); +MODULE_EXPORT int lcdm001_width (Driver *drvthis); +MODULE_EXPORT int lcdm001_height (Driver *drvthis); +MODULE_EXPORT void lcdm001_clear (Driver *drvthis); +MODULE_EXPORT void lcdm001_flush (Driver *drvthis); +MODULE_EXPORT void lcdm001_string (Driver *drvthis, int x, int y, char *string); +MODULE_EXPORT void lcdm001_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void lcdm001_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void lcdm001_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void lcdm001_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void lcdm001_icon (Driver *drvthis, int which, char dest); +MODULE_EXPORT void lcdm001_heartbeat (Driver *drvthis, int type); + +MODULE_EXPORT void lcdm001_output (Driver *drvthis, int on); + +MODULE_EXPORT char lcdm001_getkey (Driver *drvthis); #define DEFAULT_DEVICE "/dev/lcd" #define DEFAULT_CURSORBLINK 0 @@ -41,7 +58,7 @@ int lcdm001_init (struct lcd_logical_driver *driver, char *args); /*Heartbeat workaround set chars to be displayed instead of "normal" icons*/ -#define OPEN_HEART ' ' //This combination is at least visible +#define OPEN_HEART ' ' /* This combination is at least visible */ #define FILLED_HEART '*' #define PAD 255 diff --git a/server/drivers/lircin.c b/server/drivers/lircin.c index 28ac1ac..7776bd1 100644 --- a/server/drivers/lircin.c +++ b/server/drivers/lircin.c @@ -17,7 +17,6 @@ #define __u32 unsigned int #define __u8 unsigned char -#include "shared/debug.h" #include "shared/str.h" #define NAME_LENGTH 128 @@ -33,12 +32,17 @@ struct sockaddr_un addr; static struct lirc_config *config; +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "LB216_"; + + ////////////////////////////////////////////////////////////////////////// ////////////////////// Base "class" to derive from /////////////////////// ////////////////////////////////////////////////////////////////////////// -lcd_logical_driver *lircin; - //void sigterm(int sig) //{ // ir_free_commands(); @@ -46,8 +50,8 @@ lcd_logical_driver *lircin; // raise(sig); //} -void -lircin_close () +MODULE_EXPORT void +lircin_close (Driver * drvthis) { lirc_freeconfig (config); lirc_deinit (); @@ -58,8 +62,8 @@ lircin_close () // // Return 0 for "nothing available". // -char -lircin_getkey () +MODULE_EXPORT char +lircin_getkey (Driver * drvthis) { char key; char *ir, *cmd; @@ -84,15 +88,19 @@ lircin_getkey () // init() should set up any device-specific stuff, and // point all the function pointers. int -lircin_init (struct lcd_logical_driver *driver, char *args) +lircin_init (Driver * drvthis, char *args) { /* assign funktions */ - lircin = driver; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->getkey = lircin_getkey; - driver->close = lircin_close; + // Set the functions the driver supports + drvthis->getkey = lircin_getkey; + drvthis->close = lircin_close; /* open socket to lirc */ @@ -113,5 +121,5 @@ lircin_init (struct lcd_logical_driver *driver, char *args) fcntl (fd, F_SETFL, O_NONBLOCK); fcntl (fd, F_SETFD, FD_CLOEXEC); - return 1; // 200 is arbitrary. (must be 1 or more) + return 0; } diff --git a/server/drivers/lircin.h b/server/drivers/lircin.h index 78e44dd..8331768 100644 --- a/server/drivers/lircin.h +++ b/server/drivers/lircin.h @@ -1,10 +1,10 @@ #ifndef LCD_LIRCIN_H #define LCD_LIRCIN_H -extern lcd_logical_driver *lircin; +#include "lcd.h" -int lircin_init (struct lcd_logical_driver *driver, char *args); -void lircin_close (); -char lircin_getkey (); + int lircin_init (Driver * drvthis, char *args); +MODULE_EXPORT void lircin_close (Driver * drvthis); +MODULE_EXPORT char lircin_getkey (Driver * drvthis); #endif diff --git a/server/drivers/report.h b/server/drivers/report.h new file mode 100644 index 0000000..5291af3 --- /dev/null +++ b/server/drivers/report.h @@ -0,0 +1,37 @@ +#ifndef REPORT_H +#define REPORT_H + +/* DEBUGGING / REPORTING FOR DRIVERS + * + * This file uses the reporting functions from the server core. + * See the file shared/report.h for details. + * + * This file assumes that the drivers have a drvthis parameter that contains the + * current driver structure. It redefines report to make its use simple: + * + * report( RPT_ERR, "report this: %s", str ); + * debug( RPT_ERR, "report this if debug enabled: %s", str ); + * + */ + +// Reporting levels +#define RPT_CRIT 0 +#define RPT_ERR 1 +#define RPT_WARNING 2 +#define RPT_NOTICE 3 +#define RPT_INFO 4 +#define RPT_DEBUG 5 + +#define report drvthis->report +// This assumes drvthis is locally defined... Anyone has a better idea ? + +static inline void dont_report( const int level, const char *format, .../*args*/ ) +{} // The idea is that this gets optimized out + +#ifdef DEBUG +# define debug report +#else +# define debug dont_report +#endif /*DEBUG*/ + +#endif diff --git a/server/drivers/sed1330.c b/server/drivers/sed1330.c index 87d4a18..6986049 100644 --- a/server/drivers/sed1330.c +++ b/server/drivers/sed1330.c @@ -1,872 +1,904 @@ -/* - * Driver for SED1330 graphical displays - * - * This driver drives the LCD in text mode. - * Probably the driver can easily be adapted to work for 1335 and 1336 too. - * - * Moved the delay timing code by Charles Steinkuehler to timing.h. - * Guillaume Filion , December 2001 - * - * This file is released under the GNU General Public License. Refer to the - * COPYING file distributed with this package. - * - * Copyright (c) 2001, Joris Robijn pin LPT port - * ^RESET 1 1 ^STROBE - * ^RD 2 +5V - * ^WR 3 16 ^INIT - * SEL1 4 GND - * SEL2 5 GND - * ^CS 6 GND - * A0 7 17 ^SELECT_IN - * D0 8 2 D0 - * D1 9 3 D1 - * D2 10 4 D2 - * D3 11 5 D3 - * D4 12 6 D4 - * D5 13 7 D5 - * D6 14 8 D6 - * D7 15 9 D7 - * Vdd 16 +5V - * Vss 17 GND 18..25 GND - * V0 18 potmeter - * Vlc 19 -24V - * Frame 20 GND - * 10 ^ACK - * GND 11 BUSY - * 12 PAPEREND - * 13 ^SELECT - * 14 ^LF - * 15 ^ERROR - * - * Or ordered by the LPT port pins: - * LCD pin? <---> pin LPT port - * ^RESET 1 1 ^STROBE - * 14 ^LF - * D0 8 2 D0 - * 15 ^ERROR - * D1 9 3 D1 - * ^WR 3 16 ^INIT - * D2 10 4 D2 - * A0 7 17 ^SELECT_IN - * D3 11 5 D3 - * Vss 17 GND 18..25 GND - * D4 12 6 D4 - * D5 13 7 D5 - * D6 14 8 D6 - * D7 15 9 D7 - * 10 ^ACK - * GND 11 BUSY - * 12 PAPEREND - * 13 ^SELECT - * Vdd 16 +5V - * ^RD 2 +5V - * Frame 20 GND - * SEL1 4 GND - * SEL2 5 GND - * ^CS 6 GND - * Vlc 19 -24V (not required for G242C) - * V0 18 potmeter - * - * The potmeter should be connected like this on these display modules: - * - * === GND - * | - * .-. - * | | - * | |5k - * '-' - * | - * | - * .-.10k potmeter - * | | - * | |<----------------o V0 - * | | - * '-' - * | - * O Vlc (= -24V ) - * - * The G242C generates -24V internally. It is available on Vlc. - * - * To generate -24 from the +5V without an external power source, you can - * use the following circuit. - * - * 5V O------+----------+ pinout: - * | | _____ - * | --- 100uF | _ | - * | --- 10V | (_) | <-3 - * | | |_____| - * | +--------+--------+--------+ | max | - * |5 | | | | | 724 | - * --------- === GND C - | |_____| - * | | C coil | | | ||||| - * | | C 47uH | |10k | |||||. - * | |4 | - | | | | - * | MAX724 |--------------+ | | 12345 - * | or | | | | - * | MAX726 |1 | | |+ - * | |-----------------------+ --- 47uF - * | | | | --- 50V - * | | | | | - * --------- | - | - * |2 |3 | | | | - * | | '---, | |1k | - * --- | SB160 / \ - | - * 100nF--- | ^T^ | | - * | | | | | - * +-----+----------------+--------+--------+----O -24V out - * - * - * - * - * Config options - * ============== - * - * With the display= option you should specify what display module you have. - * Accepted values are: - * display=G121C - * display=G242C - * display=G321D - * - * The port= value should be set to the LPT port address that the LCD is - * connected to. Examples: - * port=0x378 - * port=0x278 - * port=0x3BC - * - */ - -#include "sed1330.h" -#include "port.h" -#include "lpt-port.h" -#include "lcd.h" -#include "shared/str.h" -#include "shared/report.h" -#include "configfile.h" -#include "timing.h" -#define uPause timing_uPause - -#include -#include -#include - -// LPT lines -#define A0 SEL -#define nRESET STRB -#define nWR INIT - -// Command definitions -#define CMD_SYSTEM_SET 0x40 -#define CMD_SLEEP_IN 0x53 -#define CMD_DISP_DIS 0x58 -#define CMD_DISP_EN 0x59 -#define CMD_SCROLL 0x44 -#define CMD_CSR_FORM 0x5D -#define CMD_CGRAM_ADR 0x5C -#define CMD_CSR_DIR_R 0x4C -#define CMD_CSR_DIR_L 0x4D -#define CMD_CSR_DIR_U 0x4E -#define CMD_CSR_DIR_D 0x4F -#define CMD_HDOT_SCR 0x5A -#define CMD_OVLAY 0x5B -#define CMD_CSRW 0x46 -#define CMD_CSRR 0x47 -#define CMD_MWRITE 0x42 -#define CMD_MREAD 0x43 - -// Data definitions -#define MAXKEYS 8 -#define TYPE_G321D 1 -#define TYPE_G121C 2 -#define TYPE_G242C 3 - -#define SCR1_L 0x00 // Memory locations -#define SCR1_H 0x00 -#define SCR2_L 0x00 -#define SCR2_H 0x06 - -#define CHARWIDTH 6 -#define CHARHEIGHT 10 -#define PIXELSPERBYTE CHARWIDTH -// The above should be (CHARWIDTH/2) if CHARWIDTH > 8 - -typedef struct private_data { - int type; - int port; - char * keymap[MAXKEYS]; - char * framebuf_text; - char * lcd_contents_text; - char * framebuf_graph; - char * lcd_contents_graph; - int graph_width, graph_height; - int cursor_x, cursor_y; - char cursor_state; - int bytesperline; -} private_data; - - -// Local functions -void uPause (int usecs); -void sed1330_command( char command, int datacount, char * data ); -void sed1330_update_cursor(); -void sed1330_rect ( int x1, int y1, int x2, int y2, char pattern ); -inline void sed1330_set_pixel( int x, int y ); -inline void sed1330_clear_pixel( int x, int y ); - - -// Global vars -static lcd_logical_driver * sed1330; - -///////////////////////////////////////////////////////////////// -// Init the driver and display -// -int -sed1330_init( lcd_logical_driver * driver, char *args ) -{ - char * s; - int port, i; - private_data * data; - - sed1330 = driver; - - - debug( RPT_INFO, "SED1330: init(%p,%s)", driver, args ); - - // TODO: replace DriverName with driver->name when that field exists. - #define DriverName "sed1330" - - - // Alocate and store private data - data = (private_data *) malloc( sizeof( private_data) ); - if( ! data ) - return -1; - if( driver->store_private_ptr( driver, data ) ) - return -1; - - // Clear keymap - memset( data->keymap, 0, sizeof(data->keymap) ); - - // READ THE CONFIG FILE - - // Port - port = config_get_int( DriverName, "port", 0, 0x278 ); - data->port = port; - - // Type - s = driver->config_get_string( DriverName, "type", 0, NULL ); - if( !s ) { - report( RPT_ERR, "SED1330: you need to specify the display type" ); - } else if( strcmp( s, "G321D" ) == 0 ) { - data->type = TYPE_G321D; - data->graph_width = 320; - data->graph_height = 200; - } else if( strcmp( s, "G121C" ) == 0 ) { - data->type = TYPE_G121C; - data->graph_width = 128; - data->graph_height = 128; - } else if( strcmp( s, "G242C" ) == 0 ) { - data->type = TYPE_G242C; - data->graph_width = 240; - data->graph_height = 128; - } else { - report( RPT_ERR, "SED1330: Unknown display type: %s", s ); - return -1; - } - driver->wid = data->graph_width / CHARWIDTH; - driver->hgt = data->graph_height / CHARHEIGHT; - data->bytesperline = (data->graph_width - 1 ) / CHARWIDTH + 1; - - report( RPT_INFO, "SED1330: Using LCD type: %s", s ); - report( RPT_INFO, "SED1330: Text size: %dx%d", driver->wid, driver->hgt ); - - - // Keymap - for( i=0; iconfig_get_string( DriverName, buf, 0, NULL ); - if( s ) { - data->keymap[i] = (char *) malloc( strlen(s)+1 ); - strcpy( data->keymap[i], s ); - report( RPT_INFO, "SED1330: Key %d: \"%s\"", i, s ); - - } else { - data->keymap[i] = ""; // Pointing to an constant empty string - } - } - - // Init cursor data - data->cursor_x = 1; - data->cursor_y = 1; - data->cursor_state = 1; - - // Allocate framebuffer - data->framebuf_text = (unsigned char *) malloc( data->bytesperline * driver->hgt ); - if( ! data->framebuf_text ) - return -1; - memset( data->framebuf_text, ' ', data->bytesperline * driver->hgt); - - data->lcd_contents_text = (unsigned char *) malloc( data->bytesperline * driver->hgt ); - if( ! data->lcd_contents_text ) - return -1; - memset( data->lcd_contents_text, 0, data->bytesperline * driver->hgt); - - data->framebuf_graph = (unsigned char *) malloc( data->bytesperline * data->graph_height ); - if( ! data->framebuf_graph ) - return -1; - memset( data->framebuf_graph, 0, data->bytesperline * data->graph_height ); - - data->lcd_contents_graph = (unsigned char *) malloc( data->bytesperline * data->graph_height ); - if( ! data->lcd_contents_graph ) - return -1; - memset( data->lcd_contents_graph, 0xFF, data->bytesperline * data->graph_height ); - - - // Arrange for access to port - debug( RPT_DEBUG, "SED1330: getting port access" ); - port_access(data->port); - port_access(data->port+1); - port_access(data->port+2); - - if (timing_init() == -1) - return -1; - - // Set the functions the driver supports... - driver->init = sed1330_init; - driver->close = sed1330_close; - driver->flush = sed1330_flush; - driver->clear = sed1330_clear; - driver->chr = sed1330_chr; - driver->string = sed1330_string; - //driver->init_vbar = sed1330_init_vbar; - //driver->init_hbar = sed1330_init_hbar; - driver->vbar = sed1330_vbar; - driver->hbar = sed1330_hbar; - //driver->init_num = sed1330_init_num; - driver->num = sed1330_num; - driver->heartbeat = sed1330_heartbeat; - //driver->set_char = sed1330_set_char; - //driver->icon = sed1330_icon; - - // driver->contrast = sed1330_contrast; // contrast is set by potmeter we assume - // driver->output = sed1330_output; // not implemented - - // driver->flush_box = sed1330_flush_box; // NOT SUPPORTED ANYMORE - // driver->draw_frame = sed1330_draw_frame; // NOT SUPPORTED ANYMORE - - - // INITIALIZE THE LCD - // End reset-state - debug( RPT_DEBUG, "SED1330: initializing LCD" ); - port_out( port+2, (nWR) ^ OUTMASK ); // raise ^RD and ^WR - port_out( port+2, (nRESET|nWR) ^ OUTMASK ); // lower RESET - uPause( 200 ); - port_out( port+2, (nWR) ^ OUTMASK ); // raise RESET - uPause( 200 ); - port_out( port+2, (nRESET|nWR) ^ OUTMASK ); // lower RESET - uPause( 3000 ); - - switch( data->type ) { - case TYPE_G321D: - sed1330_command( CMD_SYSTEM_SET, 8, ((char[8]) {0x30,0x80+CHARWIDTH-1,CHARHEIGHT-1,0x34,0x38,0xC7,0x36,0x00}) ); // Set textmode 53x20 - sed1330_command( CMD_SCROLL, 10, ((char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7}) ); // screen1 and screen2 memory locations - break; - case TYPE_G121C: - sed1330_command( CMD_SYSTEM_SET, 8, ((char[8]) {0x30,0x80+CHARWIDTH-1,CHARHEIGHT-1,0x14,0x18,0x7F,0x16,0x00}) ); // Set textmode 21x12 - sed1330_command( CMD_SCROLL, 10, ((char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7}) ); // screen1 and screen2 memory locations - break; - case TYPE_G242C: - sed1330_command( CMD_SYSTEM_SET, 8, ((char[8]) {0x30,0x80+CHARWIDTH-1,CHARHEIGHT-1,0x27,0x2B,0x7F,0x29,0x00}) ); // Set textmode 40x12 - sed1330_command( CMD_SCROLL, 10, ((char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7}) ); // screen1 and screen2 memory locations - break; - default: - return -1; - } - sed1330_command( CMD_CSR_FORM, 2, ((char[2]) {0x04,0x07}) ); // 5x8 cursor - sed1330_command( CMD_HDOT_SCR, 1, ((char[1]) {0x00}) ); // horizontal pixel shift=0 - sed1330_command( CMD_OVLAY, 1, ((char[1]) {0x01}) ); // XOR mode, screen1 text, screen3 text (screen2 and screen4 are always graph) - sed1330_command( CMD_DISP_DIS, 1, ((char[1]) {0x17}) ); // display off, set cursor slow, screen1 on, screen2 on, screen3 off - sed1330_command( CMD_CSR_DIR_R, 0, NULL ); // cursor move right - - sed1330_flush(); // Clear the contents of the LCD - - sed1330_command( CMD_DISP_EN, 0, NULL ); // And display on - - return 0; -} - -///////////////////////////////////////////////////////////////// -// Send a command and accompanying data -// INTERNAL -// -void -sed1330_command( char command, int datacount, char * data ) -{ - private_data * private_data = sed1330->private_data; - int i; - int port = private_data->port; - - debug( RPT_INFO, "sed1330_command %x #data=%d", command, datacount ); - - port_out( port+2, (nRESET|nWR|A0) ^ OUTMASK ); // set A0 to indicate command - port_out( port, command ); // set up data - //uPause( 1 ); - port_out( port+2, (nRESET|A0) ^ OUTMASK ); // activate ^WR - uPause( 1 ); - port_out( port+2, (nRESET|nWR|A0) ^ OUTMASK ); // deactivate ^WR again - - - port_out( port+2, (nRESET|nWR) ^ OUTMASK ); // clear A0 to indicate data - - for( i=0; iprivate_data; - int cursor_pos; - char csrloc[2]; - char csrform[2]; - char disp_en; - char fc; // named after CF register in SED1330 - - debug( RPT_INFO, "sed1330_update_cursor" ); - - cursor_pos = (data->cursor_y-1) * data->bytesperline + (data->cursor_x-1) + 256 * SCR1_H + SCR1_L; - csrloc[0] = cursor_pos % 256; - csrloc[1] = cursor_pos / 256; - - switch( data->cursor_state ) { - case 0: // Off - fc = 0; - csrform[0] = 0x04; - csrform[1] = 0x07; - break; - case 1: // Underlined - fc = 2; - csrform[0] = 0x04; - csrform[1] = 0x07; - break; - case 2: // Block - fc = 2; - break; - csrform[0] = 0x84; - csrform[1] = 0x07; - } - disp_en = 0x14 + fc; - - sed1330_command( CMD_CSRW, 2, csrloc ); - sed1330_command( CMD_DISP_EN, 1, &disp_en ); // cursor on - sed1330_command( CMD_CSR_FORM, 2, csrform ); // 5x8 cursor -} - - -///////////////////////////////////////////////////////////////// -// Close the display -// -void -sed1330_close() -{ - debug( RPT_INFO, "sed1330_close" ); - - //sed1330_command( CMD_DISP_DIS, 0, NULL ); // display off - //port_out( port+2, (nWR) ^ OUTMASK ); // give LCD reset signal - // LCD now will not respond anymore - - // We should take the -24V away before removing the 5V ! -} - - -///////////////////////////////////////////////////////////////// -// Clear the framebuffer -// -void -sed1330_clear() -{ - private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_clear" ); - - memset( data->framebuf_text, ' ', data->bytesperline * sed1330->hgt); - memset( data->framebuf_graph, 0, data->bytesperline * data->graph_height ); -} - - -///////////////////////////////////////////////////////////////// -// Place a string in the framebuffer -// -void -sed1330_string( int x, int y, char *str ) -{ - private_data * data = sed1330->private_data; - char * start; - int len; - - debug( RPT_INFO, "sed1330_string x=%d y=%d s=\"%s\"", x, y, str ); - - if( y > sed1330->hgt ) { - return; // outside framebuf_textfer - } - // Calculate where to start and length to write - start = data->framebuf_text + (y-1)*data->bytesperline + (x-1); - len = strlen(str); - if( sed1330->wid < len ) { - len = sed1330->wid; - } - - memcpy( start, str, len ); -} - - -///////////////////////////////////////////////////////////////// -// Place a character in the framebuffer -// -void -sed1330_chr( int x, int y, char c ) -{ - private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_chr x=%d y=%d c='%c'", x, y, c ); - - if( y > sed1330->hgt || x > sed1330->wid ) { - return; // outside framebuf_textfer - } - data->framebuf_text[(y-1)*data->bytesperline + (x-1)] = c; -} - - -///////////////////////////////////////////////////////////////// -// Flush the framebuffer to the display -// -void -sed1330_flush() -{ - private_data * data = sed1330->private_data; - unsigned int pos, start_pos, nr_equal, fblen, len, cursor_pos; - char csrloc[2]; - - debug( RPT_INFO, "sed1330_flush" ); - - sed1330_command( CMD_DISP_EN, 1, ((char[1]) {0x16}) ); // cursor off - - fblen = data->bytesperline * sed1330->hgt; - for( pos=0; poslcd_contents_text[pos] == data->framebuf_text[pos] ) { - nr_equal ++; - } else { - nr_equal = 0; - } - } - len = pos - start_pos - nr_equal; - if( len > 0 ) { - cursor_pos = start_pos + 256 * SCR1_H + SCR1_L; - csrloc[0] = cursor_pos % 256; - csrloc[1] = cursor_pos / 256; - sed1330_command( CMD_CSRW, 2, csrloc ); - sed1330_command( CMD_MWRITE, len, data->framebuf_text + start_pos ); - memcpy( data->lcd_contents_text + start_pos, data->framebuf_text + start_pos, len ); - } - } - - fblen = data->bytesperline * data->graph_height; - for( pos=0; poslcd_contents_graph[pos] == data->framebuf_graph[pos] ) { - nr_equal ++; - } else { - nr_equal = 0; - } - } - len = pos - start_pos - nr_equal; - if( len > 0 ) { - cursor_pos = start_pos + 256 * SCR2_H + SCR2_L; - csrloc[0] = cursor_pos % 256; - csrloc[1] = cursor_pos / 256; - sed1330_command( CMD_CSRW, 2, csrloc ); - sed1330_command( CMD_MWRITE, len, data->framebuf_graph + start_pos ); - memcpy( data->lcd_contents_graph + start_pos, data->framebuf_graph + start_pos, len ); - } - } - - - sed1330_update_cursor(); -} - - -///////////////////////////////////////////////////////////////// -// Let the cursor go to a certain location -// -void sed1330_cursor( int x, int y, char state ) -{ - private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_cursor x=%d y=%d state='%c'", x, y, state ); - - data->cursor_x = x; - data->cursor_y = y; - data->cursor_state = state; - - sed1330_update_cursor(); -} - - -///////////////////////////////////////////////////////////////// -// Sets the backlight on or off -// -void -sed1330_backlight( int on ) -{ - //private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_backlight on='%c'", on ); - // unimplemented -} - - -///////////////////////////////////////////////////////////////// -// Draws a rectangle -// INTERNAL -// -void -sed1330_rect ( int x1, int y1, int x2, int y2, char pattern ) -// pattern: 0=empty 1=filled later more patterns ? -{ - //private_data * data = sed1330->private_data; - int x, y; - - debug( RPT_INFO, "sed1330_rect x1=%d y1=%d x2=%d y2=%d pattern=%d", x1, y1, x2, y2, (int) pattern ); - - // Swap coordinates if needed - if( x1>x2 ) { - int swap; - swap=x1; - x1=x2; - x2=swap; - } - if( y1>y2 ) { - int swap; - swap=y1; - y1=y2; - y2=swap; - } - for( x=x1; x<=x2; x++ ) { - for( y=y1; y<=y2; y++ ) { - sed1330_set_pixel( x, y ); - } - } -} - - -///////////////////////////////////////////////////////////////// -// Draws a rectangle -// INTERNAL -// -void -sed1330_line ( int x1, int y1, int x2, int y2, char pattern ) -// pattern: 0=empty 1=filled later more patterns ? -{ - //private_data * data = sed1330->private_data; - int x, y; - - debug( RPT_INFO, "sed1330_rect x1=%d y1=%d x2=%d y2=%d pattern=%d", x1, y1, x2, y2, (int) pattern ); - - // Swap coordinates if needed - if( x1>x2 ) { - int swap; - swap=x1; - x1=x2; - x2=swap; - } - if( y1>y2 ) { - int swap; - swap=y1; - y1=y2; - y2=swap; - } - // Do we have an angle of more or less than 45 degrees ? - if( x2-x1 >= y2-y1 ) { - // Mostly horizontal - for( x=x1; x<=x2; x++ ) { - y = x * (y2-y1) / (x2-x1); - switch( pattern ) { - case 0: - sed1330_clear_pixel( x, y ); - break; - case 1: - sed1330_set_pixel( x, y ); - break; - } - } - } - else { - // Mostly vertical - for( y=y1; y<=y2; y++ ) { - x = y * (x2-x1) / (y2-y1) ; - switch( pattern ) { - case 0: - sed1330_clear_pixel( x, y ); - break; - case 1: - sed1330_set_pixel( x, y ); - break; - } - } - } -} - - -///////////////////////////////////////////////////////////////// -// Sets a specified pixel -// INTERNAL -// -inline void -sed1330_set_pixel( int x, int y ) -// x, y are graph LCD coordinates, 0-based -{ - private_data * data = sed1330->private_data; - unsigned int bytepos; - char bitmask; - - //debug( RPT_INFO, "sed1330_set_pixel x=%d y=%d", x, y ); - - bytepos = y*data->bytesperline + x/PIXELSPERBYTE; - bitmask = 0x80 >> (x % PIXELSPERBYTE); - data->framebuf_graph[bytepos] |= bitmask; -} - - -///////////////////////////////////////////////////////////////// -// clears a specified pixel -// INTERNAL -// -inline void -sed1330_clear_pixel( int x, int y ) -// x, y are graph LCD coordinates, 0-based -{ - private_data * data = sed1330->private_data; - int bytepos; - char bitmask; - - //debug( RPT_INFO, "sed1330_clear_pixel x=%d y=%d", x, y ); - - bytepos = y*data->bytesperline + x/PIXELSPERBYTE; - bitmask = 0x80 >> (x % PIXELSPERBYTE); - data->framebuf_graph[bytepos] &= ~bitmask; -} - - -///////////////////////////////////////////////////////////////// -// Draws a vertical bar at the bottom -// -void -sed1330_vbar( int x, int len ) -{ - private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_hbar x=%d len=%d", x, len ); - - sed1330_rect ( (x-1) * CHARWIDTH, data->graph_height-1, x * CHARWIDTH - 1, data->graph_height-1 - ((long) len * CHARHEIGHT / sed1330->cellhgt ), 1 ); -} - - -///////////////////////////////////////////////////////////////// -// Draws a horizontal bar to the right (len=pos) -// or to the left (len=neg) -// -void -sed1330_hbar( int x, int y, int len ) -{ - //private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_hbar x=%d y=%d len=%d", x, y, len ); - - sed1330_rect ( (x-1) * CHARWIDTH, (y-1) * CHARHEIGHT, x * CHARWIDTH + len, y * CHARHEIGHT - 1, 1 ); -} - - -///////////////////////////////////////////////////////////////// -// Writes a big number. -// -void -sed1330_num( int x, int num ) -{ - //private_data * data = sed1330->private_data; - - debug( RPT_INFO, "sed1330_bignum x=%d num=%d", x, num ); - - -} - - -///////////////////////////////////////////////////////////// -// Does the heartbeat... -// -void -sed1330_heartbeat( int type ) -{ - private_data * data = sed1330->private_data; - static int timer = 0; - int pos; - int whichIcon; - int n; - - char heartdata[2][CHARHEIGHT] = { - { 0xFF, 0xFF, 0xAF, 0x07, 0x8F, 0xDF, 0xFF, 0xFF, 0x00, 0x00 }, - { 0xFF, 0xAF, 0x07, 0x07, 0x07, 0x8F, 0xDF, 0xFF, 0x00, 0x00 } - }; - - report( RPT_INFO, "sed1330_heartbeat type=%d", type ); - - data->framebuf_text[sed1330->wid-1] = ' '; - whichIcon = (! ((timer + 4) & 5)); - - pos = sed1330->wid - 1; - for( n=0; nframebuf_graph[pos] = heartdata[whichIcon][n]; - pos += data->bytesperline; - } - - timer++; -} +/* + * Driver for SED1330 graphical displays + * + * This driver drives the LCD in text mode. + * Probably the driver can easily be adapted to work for 1335 and 1336 too. + * + * Moved the delay timing code by Charles Steinkuehler to timing.h. + * Guillaume Filion , December 2001 + * + * This file is released under the GNU General Public License. Refer to the + * COPYING file distributed with this package. + * + * Copyright (c) 2001, Joris Robijn pin LPT port + * ^RESET 1 1 ^STROBE + * ^RD 2 +5V + * ^WR 3 16 ^INIT + * SEL1 4 GND + * SEL2 5 GND + * ^CS 6 GND + * A0 7 17 ^SELECT_IN + * D0 8 2 D0 + * D1 9 3 D1 + * D2 10 4 D2 + * D3 11 5 D3 + * D4 12 6 D4 + * D5 13 7 D5 + * D6 14 8 D6 + * D7 15 9 D7 + * Vdd 16 +5V + * Vss 17 GND 18..25 GND + * V0 18 potmeter + * Vlc 19 -24V + * Frame 20 GND + * 10 ^ACK + * GND 11 BUSY + * 12 PAPEREND + * 13 ^SELECT + * 14 ^LF + * 15 ^ERROR + * + * Or ordered by the LPT port pins: + * LCD pin? <---> pin LPT port + * ^RESET 1 1 ^STROBE + * 14 ^LF + * D0 8 2 D0 + * 15 ^ERROR + * D1 9 3 D1 + * ^WR 3 16 ^INIT + * D2 10 4 D2 + * A0 7 17 ^SELECT_IN + * D3 11 5 D3 + * Vss 17 GND 18..25 GND + * D4 12 6 D4 + * D5 13 7 D5 + * D6 14 8 D6 + * D7 15 9 D7 + * 10 ^ACK + * GND 11 BUSY + * 12 PAPEREND + * 13 ^SELECT + * Vdd 16 +5V + * ^RD 2 +5V + * Frame 20 GND + * SEL1 4 GND + * SEL2 5 GND + * ^CS 6 GND + * Vlc 19 -24V (not required for G242C) + * V0 18 potmeter + * + * The potmeter should be connected like this on these display modules: + * + * === GND + * | + * .-. + * | | + * | |5k + * '-' + * | + * | + * .-.10k potmeter + * | | + * | |<----------------o V0 + * | | + * '-' + * | + * O Vlc (= -24V ) + * + * The G242C generates -24V internally. It is available on Vlc. + * + * To generate -24 from the +5V without an external power source, you can + * use the following circuit. + * + * 5V O------+----------+ pinout: + * | | _____ + * | --- 100uF | _ | + * | --- 10V | (_) | <-3 + * | | |_____| + * | +--------+--------+--------+ | max | + * |5 | | | | | 724 | + * --------- === GND C - | |_____| + * | | C coil | | | ||||| + * | | C 47uH | |10k | |||||. + * | |4 | - | | | | + * | MAX724 |--------------+ | | 12345 + * | or | | | | + * | MAX726 |1 | | |+ + * | |-----------------------+ --- 47uF + * | | | | --- 50V + * | | | | | + * --------- | - | + * |2 |3 | | | | + * | | '---, | |1k | + * --- | SB160 / \ - | + * 100nF--- | ^T^ | | + * | | | | | + * +-----+----------------+--------+--------+----O -24V out + * + * + * + * + * Config options + * ============== + * + * With the display= option you should specify what display module you have. + * Accepted values are: + * display=G121C + * display=G242C + * display=G321D + * + * The port= value should be set to the LPT port address that the LCD is + * connected to. Examples: + * port=0x378 + * port=0x278 + * port=0x3BC + * + */ + +#include "lcd.h" +#include "sed1330.h" + +#include "port.h" +#include "lpt-port.h" +#include "shared/str.h" +#include "shared/report.h" +#include "configfile.h" +#include "timing.h" +#define uPause timing_uPause + +#include +#include +#include + +// LPT lines +#define A0 SEL +#define nRESET STRB +#define nWR INIT + +// Command definitions +#define CMD_SYSTEM_SET 0x40 +#define CMD_SLEEP_IN 0x53 +#define CMD_DISP_DIS 0x58 +#define CMD_DISP_EN 0x59 +#define CMD_SCROLL 0x44 +#define CMD_CSR_FORM 0x5D +#define CMD_CGRAM_ADR 0x5C +#define CMD_CSR_DIR_R 0x4C +#define CMD_CSR_DIR_L 0x4D +#define CMD_CSR_DIR_U 0x4E +#define CMD_CSR_DIR_D 0x4F +#define CMD_HDOT_SCR 0x5A +#define CMD_OVLAY 0x5B +#define CMD_CSRW 0x46 +#define CMD_CSRR 0x47 +#define CMD_MWRITE 0x42 +#define CMD_MREAD 0x43 + +// Data definitions +#define MAXKEYS 8 +#define TYPE_G321D 1 +#define TYPE_G121C 2 +#define TYPE_G242C 3 + +#define SCR1_L 0x00 // Memory locations +#define SCR1_H 0x00 +#define SCR2_L 0x00 +#define SCR2_H 0x06 + +#define CHARWIDTH 6 +#define CHARHEIGHT 10 +#define PIXELSPERBYTE CHARWIDTH +// The above should be (CHARWIDTH/2) if CHARWIDTH > 8 + +typedef struct p { + int type; + int port; + char * keymap[MAXKEYS]; + char * framebuf_text; + char * lcd_contents_text; + char * framebuf_graph; + char * lcd_contents_graph; + int width, height; + //int cellwidth, cellheight; + int graph_width, graph_height; + int cursor_x, cursor_y; + char cursor_state; + int bytesperline; +} PrivateData; + + +// Vars for the server core +MODULE_EXPORT char * api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 1; +MODULE_EXPORT int supports_multiple = 1; // yes, we have no global variables (except for constants) +MODULE_EXPORT char *symbol_prefix = "sed1330_"; + + +// Local functions +void uPause (int usecs); +void sed1330_command( PrivateData * p, char command, int datacount, char * data ); +void sed1330_update_cursor( PrivateData * p ); +void sed1330_rect( PrivateData * p, int x1, int y1, int x2, int y2, char pattern ); +inline void sed1330_set_pixel( PrivateData * p, int x, int y ); +inline void sed1330_clear_pixel( PrivateData * p, int x, int y ); + + +///////////////////////////////////////////////////////////////// +// Init the driver and display +// +int +sed1330_init( Driver * drvthis, char *args ) +{ + char * s; + int port, i; + PrivateData * p; + + debug( RPT_INFO, "SED1330: init(%p,%s)", drvthis, args ); + + // TODO: replace DriverName with driver->name when that field exists. + + + // Alocate and store private p + p = (PrivateData *) malloc( sizeof(PrivateData) ); + if( ! p ) + return -1; + if( drvthis->store_private_ptr( drvthis, p ) ) + return -1; + + // Clear keymap + memset( p->keymap, 0, sizeof(p->keymap) ); + + // READ THE CONFIG FILE + + // Port + port = config_get_int( drvthis->name, "port", 0, 0x278 ); + p->port = port; + + // Type + s = drvthis->config_get_string( drvthis->name, "type", 0, NULL ); + if( !s ) { + report( RPT_ERR, "SED1330: you need to specify the display type" ); + } else if( strcmp( s, "G321D" ) == 0 ) { + p->type = TYPE_G321D; + p->graph_width = 320; + p->graph_height = 200; + } else if( strcmp( s, "G121C" ) == 0 ) { + p->type = TYPE_G121C; + p->graph_width = 128; + p->graph_height = 128; + } else if( strcmp( s, "G242C" ) == 0 ) { + p->type = TYPE_G242C; + p->graph_width = 240; + p->graph_height = 128; + } else { + report( RPT_ERR, "SED1330: Unknown display type: %s", s ); + return -1; + } + p->width = p->graph_width / CHARWIDTH; + p->height = p->graph_height / CHARHEIGHT; + p->bytesperline = (p->graph_width - 1 ) / CHARWIDTH + 1; + + report( RPT_INFO, "SED1330: Using LCD type: %s", s ); + report( RPT_INFO, "SED1330: Text size: %dx%d", p->width, p->height ); + + + // Keymap + for( i=0; iconfig_get_string( drvthis->name, buf, 0, NULL ); + if( s ) { + p->keymap[i] = (char *) malloc( strlen(s)+1 ); + strcpy( p->keymap[i], s ); + report( RPT_INFO, "SED1330: Key %d: \"%s\"", i, s ); + + } else { + p->keymap[i] = ""; // Pointing to an constant empty string + } + } + + // Init cursor p + p->cursor_x = 1; + p->cursor_y = 1; + p->cursor_state = 1; + + // Allocate framebuffer + p->framebuf_text = (unsigned char *) malloc( p->bytesperline * p->height ); + if( ! p->framebuf_text ) + return -1; + memset( p->framebuf_text, ' ', p->bytesperline * p->height); + + p->lcd_contents_text = (unsigned char *) malloc( p->bytesperline * p->height ); + if( ! p->lcd_contents_text ) + return -1; + memset( p->lcd_contents_text, 0, p->bytesperline * p->height); + + p->framebuf_graph = (unsigned char *) malloc( p->bytesperline * p->graph_height ); + if( ! p->framebuf_graph ) + return -1; + memset( p->framebuf_graph, 0, p->bytesperline * p->graph_height ); + + p->lcd_contents_graph = (unsigned char *) malloc( p->bytesperline * p->graph_height ); + if( ! p->lcd_contents_graph ) + return -1; + memset( p->lcd_contents_graph, 0xFF, p->bytesperline * p->graph_height ); + + + // Arrange for access to port + debug( RPT_DEBUG, "SED1330: getting port access" ); + port_access(p->port); + port_access(p->port+1); + port_access(p->port+2); + + if (timing_init() == -1) + return -1; + + // Set variables for server + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->api_version = api_version; + drvthis->supports_multiple = &supports_multiple; + + // Set the functions the driver supports... + drvthis->init = sed1330_init; + drvthis->close = sed1330_close; + + drvthis->width = sed1330_width; + drvthis->height = sed1330_height; + + drvthis->flush = sed1330_flush; + drvthis->clear = sed1330_clear; + drvthis->chr = sed1330_chr; + drvthis->string = sed1330_string; + //drvthis->init_vbar = sed1330_init_vbar; + //drvthis->init_hbar = sed1330_init_hbar; + drvthis->vbar = sed1330_vbar; + drvthis->hbar = sed1330_hbar; + //drvthis->init_num = sed1330_init_num; + drvthis->num = sed1330_num; + drvthis->heartbeat = sed1330_heartbeat; + //drvthis->set_char = sed1330_set_char; + //drvthis->icon = sed1330_icon; + + // drvthis->contrast = sed1330_contrast; // contrast is set by potmeter we assume + // drvthis->output = sed1330_output; // not implemented + + // drvthis->flush_box = sed1330_flush_box; // NOT SUPPORTED ANYMORE + // drvthis->draw_frame = sed1330_draw_frame; // NOT SUPPORTED ANYMORE + + + // INITIALIZE THE LCD + // End reset-state + debug( RPT_DEBUG, "SED1330: initializing LCD" ); + port_out( port+2, (nWR) ^ OUTMASK ); // raise ^RD and ^WR + port_out( port+2, (nRESET|nWR) ^ OUTMASK ); // lower RESET + uPause( 200 ); + port_out( port+2, (nWR) ^ OUTMASK ); // raise RESET + uPause( 200 ); + port_out( port+2, (nRESET|nWR) ^ OUTMASK ); // lower RESET + uPause( 3000 ); + + switch( p->type ) { + case TYPE_G321D: + sed1330_command( p, CMD_SYSTEM_SET, 8, ((char[8]) {0x30,0x80+CHARWIDTH-1,CHARHEIGHT-1,0x34,0x38,0xC7,0x36,0x00}) ); // Set textmode 53x20 + sed1330_command( p, CMD_SCROLL, 10, ((char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7}) ); // screen1 and screen2 memory locations + break; + case TYPE_G121C: + sed1330_command( p, CMD_SYSTEM_SET, 8, ((char[8]) {0x30,0x80+CHARWIDTH-1,CHARHEIGHT-1,0x14,0x18,0x7F,0x16,0x00}) ); // Set textmode 21x12 + sed1330_command( p, CMD_SCROLL, 10, ((char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7}) ); // screen1 and screen2 memory locations + break; + case TYPE_G242C: + sed1330_command( p, CMD_SYSTEM_SET, 8, ((char[8]) {0x30,0x80+CHARWIDTH-1,CHARHEIGHT-1,0x27,0x2B,0x7F,0x29,0x00}) ); // Set textmode 40x12 + sed1330_command( p, CMD_SCROLL, 10, ((char[6]) {SCR1_L,SCR1_H,0xC7,SCR2_L,SCR2_H,0xC7}) ); // screen1 and screen2 memory locations + break; + default: + return -1; + } + sed1330_command( p, CMD_CSR_FORM, 2, ((char[2]) {0x04,0x07}) ); // 5x8 cursor + sed1330_command( p, CMD_HDOT_SCR, 1, ((char[1]) {0x00}) ); // horizontal pixel shift=0 + sed1330_command( p, CMD_OVLAY, 1, ((char[1]) {0x01}) ); // XOR mode, screen1 text, screen3 text (screen2 and screen4 are always graph) + sed1330_command( p, CMD_DISP_DIS, 1, ((char[1]) {0x17}) ); // display off, set cursor slow, screen1 on, screen2 on, screen3 off + sed1330_command( p, CMD_CSR_DIR_R, 0, NULL ); // cursor move right + + sed1330_flush( drvthis ); // Clear the contents of the LCD + + sed1330_command( p, CMD_DISP_EN, 0, NULL ); // And display on + + return 0; +} + + +///////////////////////////////////////////////////////////////// +// Send a command and accompanying p +// INTERNAL +// +void +sed1330_command( PrivateData * p, char command, int datacount, char * data ) +{ + int i; + int port = p->port; + + port_out( port+2, (nRESET|nWR|A0) ^ OUTMASK ); // set A0 to indicate command + port_out( port, command ); // set up p + //uPause( 1 ); + port_out( port+2, (nRESET|A0) ^ OUTMASK ); // activate ^WR + uPause( 1 ); + port_out( port+2, (nRESET|nWR|A0) ^ OUTMASK ); // deactivate ^WR again + + + port_out( port+2, (nRESET|nWR) ^ OUTMASK ); // clear A0 to indicate p + + for( i=0; icursor_y-1) * p->bytesperline + (p->cursor_x-1) + 256 * SCR1_H + SCR1_L; + csrloc[0] = cursor_pos % 256; + csrloc[1] = cursor_pos / 256; + + switch( p->cursor_state ) { + case 0: // Off + fc = 0; + csrform[0] = 0x04; + csrform[1] = 0x07; + break; + case 1: // Underlined + fc = 2; + csrform[0] = 0x04; + csrform[1] = 0x07; + break; + case 2: // Block + fc = 2; + break; + csrform[0] = 0x84; + csrform[1] = 0x07; + } + disp_en = 0x14 + fc; + + sed1330_command( p, CMD_CSRW, 2, csrloc ); + sed1330_command( p, CMD_DISP_EN, 1, &disp_en ); // cursor on + sed1330_command( p, CMD_CSR_FORM, 2, csrform ); // 5x8 cursor +} + + +///////////////////////////////////////////////////////////////// +// Close the display +// +MODULE_EXPORT void +sed1330_close( Driver * drvthis ) +{ + PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_close" ); + + free( p ); +} + + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +sed1330_width( Driver * drvthis ) +{ + PrivateData * p = drvthis->private_data; + + return p->width; +} + + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +sed1330_height( Driver * drvthis ) +{ + PrivateData * p = drvthis->private_data; + + return p->height; +} + + +///////////////////////////////////////////////////////////////// +// Clear the framebuffer +// +MODULE_EXPORT void +sed1330_clear( Driver * drvthis ) +{ + PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_clear" ); + + memset( p->framebuf_text, ' ', p->bytesperline * p->height); + memset( p->framebuf_graph, 0, p->bytesperline * p->graph_height ); +} + + +///////////////////////////////////////////////////////////////// +// Place a string in the framebuffer +// +MODULE_EXPORT void +sed1330_string( Driver * drvthis, int x, int y, char *str ) +{ + PrivateData * p = drvthis->private_data; + char * start; + int len; + + debug( RPT_INFO, "sed1330_string x=%d y=%d s=\"%s\"", x, y, str ); + + if( y > p->height ) { + return; // outside framebuf_textfer + } + // Calculate where to start and length to write + start = p->framebuf_text + (y-1)*p->bytesperline + (x-1); + len = strlen(str); + if( p->width < len ) { + len = p->width; + } + + memcpy( start, str, len ); +} + + +///////////////////////////////////////////////////////////////// +// Place a character in the framebuffer +// +MODULE_EXPORT void +sed1330_chr( Driver * drvthis, int x, int y, char c ) +{ + PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_chr x=%d y=%d c='%c'", x, y, c ); + + if( y > p->height || x > p->width ) { + return; // outside framebuf_textfer + } + p->framebuf_text[(y-1)*p->bytesperline + (x-1)] = c; +} + + +///////////////////////////////////////////////////////////////// +// Flush the framebuffer to the display +// +MODULE_EXPORT void +sed1330_flush( Driver * drvthis ) +{ + PrivateData * p = drvthis->private_data; + unsigned int pos, start_pos, nr_equal, fblen, len, cursor_pos; + char csrloc[2]; + + debug( RPT_INFO, "sed1330_flush" ); + + sed1330_command( p, CMD_DISP_EN, 1, ((char[1]) {0x16}) ); // cursor off + + fblen = p->bytesperline * p->height; + for( pos=0; poslcd_contents_text[pos] == p->framebuf_text[pos] ) { + nr_equal ++; + } else { + nr_equal = 0; + } + } + len = pos - start_pos - nr_equal; + if( len > 0 ) { + cursor_pos = start_pos + 256 * SCR1_H + SCR1_L; + csrloc[0] = cursor_pos % 256; + csrloc[1] = cursor_pos / 256; + sed1330_command( p, CMD_CSRW, 2, csrloc ); + sed1330_command( p, CMD_MWRITE, len, p->framebuf_text + start_pos ); + memcpy( p->lcd_contents_text + start_pos, p->framebuf_text + start_pos, len ); + } + } + + fblen = p->bytesperline * p->graph_height; + for( pos=0; poslcd_contents_graph[pos] == p->framebuf_graph[pos] ) { + nr_equal ++; + } else { + nr_equal = 0; + } + } + len = pos - start_pos - nr_equal; + if( len > 0 ) { + cursor_pos = start_pos + 256 * SCR2_H + SCR2_L; + csrloc[0] = cursor_pos % 256; + csrloc[1] = cursor_pos / 256; + sed1330_command( p, CMD_CSRW, 2, csrloc ); + sed1330_command( p, CMD_MWRITE, len, p->framebuf_graph + start_pos ); + memcpy( p->lcd_contents_graph + start_pos, p->framebuf_graph + start_pos, len ); + } + } + + + sed1330_update_cursor( p ); +} + + +///////////////////////////////////////////////////////////////// +// Let the cursor go to a certain location +// +MODULE_EXPORT void +sed1330_cursor( Driver * drvthis, int x, int y, char state ) +{ + PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_cursor x=%d y=%d state='%c'", x, y, state ); + + p->cursor_x = x; + p->cursor_y = y; + p->cursor_state = state; + + sed1330_update_cursor( p ); +} + + +///////////////////////////////////////////////////////////////// +// Sets the backlight on or off +// +MODULE_EXPORT void +sed1330_backlight( Driver * drvthis, int on ) +{ + //PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_backlight on='%c'", on ); + // unimplemented +} + + +///////////////////////////////////////////////////////////////// +// Draws a rectangle +// INTERNAL +// +void +sed1330_rect ( PrivateData * p, int x1, int y1, int x2, int y2, char pattern ) +// pattern: 0=empty 1=filled later more patterns ? +{ + int x, y; + + // Swap coordinates if needed + if( x1>x2 ) { + int swap; + swap=x1; + x1=x2; + x2=swap; + } + if( y1>y2 ) { + int swap; + swap=y1; + y1=y2; + y2=swap; + } + for( x=x1; x<=x2; x++ ) { + for( y=y1; y<=y2; y++ ) { + sed1330_set_pixel( p, x, y ); + } + } +} + + +///////////////////////////////////////////////////////////////// +// Draws a line +// INTERNAL +// +void +sed1330_line ( PrivateData * p, int x1, int y1, int x2, int y2, char pattern ) +// pattern: 0=empty 1=filled later more patterns ? +{ + int x, y; + + // Swap coordinates if needed + if( x1>x2 ) { + int swap; + swap=x1; + x1=x2; + x2=swap; + } + if( y1>y2 ) { + int swap; + swap=y1; + y1=y2; + y2=swap; + } + // Do we have an angle of more or less than 45 degrees ? + if( x2-x1 >= y2-y1 ) { + // Mostly horizontal + for( x=x1; x<=x2; x++ ) { + y = x * (y2-y1) / (x2-x1); + switch( pattern ) { + case 0: + sed1330_clear_pixel( p, x, y ); + break; + case 1: + sed1330_set_pixel( p, x, y ); + break; + } + } + } + else { + // Mostly vertical + for( y=y1; y<=y2; y++ ) { + x = y * (x2-x1) / (y2-y1) ; + switch( pattern ) { + case 0: + sed1330_clear_pixel( p, x, y ); + break; + case 1: + sed1330_set_pixel( p, x, y ); + break; + } + } + } +} + + +///////////////////////////////////////////////////////////////// +// Sets a specified pixel +// INTERNAL +// +inline void +sed1330_set_pixel( PrivateData * p, int x, int y ) +// x, y are graph LCD coordinates, 0-based +{ + unsigned int bytepos; + char bitmask; + + bytepos = y*p->bytesperline + x/PIXELSPERBYTE; + bitmask = 0x80 >> (x % PIXELSPERBYTE); + p->framebuf_graph[bytepos] |= bitmask; +} + + +///////////////////////////////////////////////////////////////// +// clears a specified pixel +// INTERNAL +// +inline void +sed1330_clear_pixel( PrivateData * p, int x, int y ) +// x, y are graph LCD coordinates, 0-based +{ + int bytepos; + char bitmask; + + bytepos = y*p->bytesperline + x/PIXELSPERBYTE; + bitmask = 0x80 >> (x % PIXELSPERBYTE); + p->framebuf_graph[bytepos] &= ~bitmask; +} + + +///////////////////////////////////////////////////////////////// +// Draws a vertical bar at the bottom +// +MODULE_EXPORT void +sed1330_vbar( Driver * drvthis, int x, int y, int len, int promille, int pattern ) +{ + PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_hbar x=%d len=%d", x, len ); + + sed1330_rect ( p, (x-1) * CHARWIDTH, y * CHARHEIGHT - CHARHEIGHT/2, x * CHARWIDTH - 1, y * CHARHEIGHT - CHARHEIGHT/2 + (long) len * CHARHEIGHT * promille / 1000 - 1, 1 ); +} + + +///////////////////////////////////////////////////////////////// +// Draws a horizontal bar to the right (len=pos) +// or to the left (len=neg) +// +MODULE_EXPORT void +sed1330_hbar( Driver * drvthis, int x, int y, int len, int promille, int pattern ) +{ + PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_hbar x=%d y=%d len=%d", x, y, len ); + + sed1330_rect ( p, x * CHARWIDTH, (y-1) * CHARHEIGHT, x * CHARWIDTH - CHARWIDTH/2 + (long) len * CHARWIDTH * promille / 1000 - 1, y * CHARHEIGHT - 1, 1 ); +} + + +///////////////////////////////////////////////////////////////// +// Writes a big number. +// +MODULE_EXPORT void +sed1330_num( Driver * drvthis, int x, int num ) +{ + //PrivateData * p = drvthis->private_data; + + debug( RPT_INFO, "sed1330_bignum x=%d num=%d", x, num ); + +} + + +///////////////////////////////////////////////////////////// +// Does the heartbeat... +// Or in fact a bouncing ball :) +// +MODULE_EXPORT void +sed1330_heartbeat( Driver * drvthis, int type ) +{ + PrivateData * p = drvthis->private_data; + static int timer = 0; + int pos; + //int whichIcon; + int n; + + //char heartdata[2][CHARHEIGHT] = { + // { 0xFF, 0xFF, 0xAF, 0x07, 0x8F, 0xDF, 0xFF, 0xFF, 0x00, 0x00 }, + // { 0xFF, 0xAF, 0x07, 0x07, 0x07, 0x8F, 0xDF, 0xFF, 0x00, 0x00 } + //}; + char bouncing_ball[8][CHARHEIGHT] = { + { 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0x00, 0x00 }, + { 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xFF, 0x87, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xFF, 0x87, 0x87, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0xFF, 0x00, 0x00 }, + { 0xFF, 0xFF, 0xCF, 0x87, 0x87, 0xCF, 0xFF, 0xFF, 0x00, 0x00 }, + }; + + report( RPT_INFO, "sed1330_heartbeat type=%d", type ); + + p->framebuf_text[p->width-1] = ' '; + //whichIcon = (! ((timer + 4) & 5)); + + pos = p->width - 1; + for( n=0; nframebuf_graph[pos] = heartdata[whichIcon][n]; + p->framebuf_graph[pos] = bouncing_ball[timer][n]; + pos += p->bytesperline; + } + + timer++; + timer %= 8; +} diff --git a/server/drivers/sed1330.h b/server/drivers/sed1330.h index e5b913c..899028e 100644 --- a/server/drivers/sed1330.h +++ b/server/drivers/sed1330.h @@ -1,24 +1,28 @@ -/* - * Driver for SED1330 graphical displays - * Header file - */ - -#ifndef SED1330_H -#define SED1330_H - -#include "lcd.h" - -int sed1330_init( lcd_logical_driver * driver, char *args ); -void sed1330_close(); -void sed1330_clear(); -void sed1330_string( int x, int y, char lcd[] ); -void sed1330_chr( int x, int y, char c ); -void sed1330_flush(); -void sed1330_cursor( int x, int y, char state ); -void sed1330_backlight( int on ); -void sed1330_vbar( int x, int len ); -void sed1330_hbar( int x, int y, int len ); -void sed1330_num( int x, int num ); -void sed1330_heartbeat( int type ); - -#endif +/* + * Driver for SED1330 graphical displays + * Header file + */ + +#ifndef SED1330_H +#define SED1330_H + +#include "lcd.h" + + int sed1330_init( Driver * drvthis, char *args ); +MODULE_EXPORT void sed1330_close( Driver * drvthis ); +MODULE_EXPORT int sed1330_width( Driver * drvthis ); +MODULE_EXPORT int sed1330_height( Driver * drvthis ); +MODULE_EXPORT void sed1330_clear( Driver * drvthis ); +MODULE_EXPORT void sed1330_flush( Driver * drvthis ); +MODULE_EXPORT void sed1330_string( Driver * drvthis, int x, int y, char lcd[] ); +MODULE_EXPORT void sed1330_chr( Driver * drvthis, int x, int y, char c ); + +MODULE_EXPORT void sed1330_vbar( Driver * drvthis, int x, int y, int len, int promille, int pattern ); +MODULE_EXPORT void sed1330_hbar( Driver * drvthis, int x, int y, int len, int promille, int pattern ); +MODULE_EXPORT void sed1330_num( Driver * drvthis, int x, int num ); +MODULE_EXPORT void sed1330_heartbeat( Driver * drvthis, int type ); +MODULE_EXPORT void sed1330_cursor( Driver * drvthis, int x, int y, char state ); + +MODULE_EXPORT void sed1330_backlight( Driver * drvthis, int on ); + +#endif diff --git a/server/drivers/sed1520.c b/server/drivers/sed1520.c index e64d7dc..bd573cd 100644 --- a/server/drivers/sed1520.c +++ b/server/drivers/sed1520.c @@ -53,8 +53,18 @@ unsigned int sed1520_lptport = LPTPORT; +char *framebuf = NULL; +int width = LCD_DEFAULT_WIDTH; +int height = LCD_DEFAULT_HEIGHT; +int cellwidth = LCD_DEFAULT_CELLWIDTH; +int cellheight = LCD_DEFAULT_CELLHEIGHT; -lcd_logical_driver *sed1520; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "sed1520_"; ///////////////////////////////////////////////////////////////// // writes command value to one or both sed1520 selected by chip @@ -125,23 +135,21 @@ drawchar2fb (int x, int y, unsigned char z) (((fontmap[(int) z][j] * 2) & (1 << i)) / (1 << i)) * (1 << j); } - sed1520->framebuf[(y * 122) + (x * 6) + (6 - i)] = k; + framebuf[(y * 122) + (x * 6) + (6 - i)] = k; } } ///////////////////////////////////////////////////////////////// -// This initialises the stuff. We support supplying port as +// This initialises the stuff. We support supplying port as // a command line argument. -// +// int -sed1520_init (struct lcd_logical_driver *driver, char *args) +sed1520_init (Driver *drvthis, char *args) { char *argv[64], *str; int argc, i; - sed1520 = driver; - if (args) if ((str = (char *) malloc (strlen (args) + 1))) strcpy (str, args); @@ -195,12 +203,23 @@ sed1520_init (struct lcd_logical_driver *driver, char *args) } } - driver->wid = 20; - driver->hgt = 4; + // driver->wid = 20; + // driver->hgt = 4; if (timing_init() == -1) return -1; + // Allocate our framebuffer + framebuf = malloc (122 * 4); + if (!framebuf) + { + // sed1520_close (); + return -1; + } + + // clear screen + memset (framebuf, 0, 122 * 4); + // Initialize the Port and the sed1520s if(port_access(sed1520_lptport)) return -1; if(port_access(sed1520_lptport+2)) return -1; @@ -212,87 +231,105 @@ sed1520_init (struct lcd_logical_driver *driver, char *args) writecommand (0xC0, CS1 + CS2); selectpage (3); - driver->cellwid = 6; - driver->cellhgt = 8; + cellwidth = 6; + cellheight = 8; - // The Framebuffer LCDproc allocates by default is too small, - // so we free() it (if it exists) and allocate one of adequate size. - if (!driver->framebuf) - free (driver->framebuf); - driver->framebuf = malloc (122 * 4); - if (!driver->framebuf) - { - sed1520_close (); - return -1; - } + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - // clear screen - memset (driver->framebuf, 0, 122 * 4); + // Set the functions the driver supports + drvthis->clear = sed1520_clear; + drvthis->string = sed1520_string; + drvthis->chr = sed1520_chr; + drvthis->old_vbar = sed1520_vbar; + drvthis->old_hbar = sed1520_hbar; + drvthis->num = sed1520_num; + drvthis->init = sed1520_init; + drvthis->close = sed1520_close; + drvthis->flush = sed1520_flush; + drvthis->set_char = sed1520_set_char; - driver->clear = sed1520_clear; - driver->string = sed1520_string; - driver->chr = sed1520_chr; - driver->vbar = sed1520_vbar; - driver->hbar = sed1520_hbar; - driver->num = sed1520_num; - driver->init = sed1520_init; - driver->close = sed1520_close; - driver->flush = sed1520_flush; - driver->flush_box = sed1520_flush_box; - driver->set_char = sed1520_set_char; - - driver->icon = sed1520_icon; - driver->draw_frame = sed1520_draw_frame; + drvthis->old_icon = sed1520_icon; // We dont't need init for vbar,hbar and friends. - //driver->init_hbar = NULL; - //driver->init_vbar = NULL; - //driver->init_num = NULL; + //drvthis->init_hbar = NULL; + //drvthis->init_vbar = NULL; + //drvthis->init_num = NULL; // Neither contrast nor backlight are controllable. - //driver->contrast = NULL; - //driver->backlight = NULL; + //drvthis->contrast = NULL; + //drvthis->backlight = NULL; // There are some unused input lines that may be used for input, // but nothing is programmed so far. - //driver->getkey = NULL; - return 200; // 200 is arbitrary. (must be 1 or more) + //drvthis->getkey = NULL; + return 0; } ///////////////////////////////////////////////////////////////// // Frees the frambuffer and exits the driver. // -void -sed1520_close () +MODULE_EXPORT void +sed1520_close (Driver *drvthis) { - if (sed1520->framebuf != NULL) - free (sed1520->framebuf); - sed1520->framebuf = NULL; + if (framebuf != NULL) + free (framebuf); + framebuf = NULL; +} + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +sed1520_width (Driver *drvthis) +{ + return width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +sed1520_height (Driver *drvthis) +{ + return height; } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -sed1520_clear () +MODULE_EXPORT void +sed1520_clear (Driver *drvthis) { - memset (sed1520->framebuf, 0, 488); + memset (framebuf, 0, 488); } ///////////////////////////////////////////////////////////////// -// +// // Flushes all output to the lcd... // -void -sed1520_flush () +MODULE_EXPORT void +sed1520_flush (Driver *drvthis) { - sed1520->draw_frame (sed1520->framebuf); + int i, j; + for (i = 0; i < 4; i++) + { + selectpage (i); + selectcolumn (0, CS2) ; + for (j = 0; j < 61; j++) + writedata (framebuf[j + (i * 122)], CS2); + selectcolumn (0, CS1) ; + for (j = 61; j < 122; j++) + writedata (framebuf[j + (i * 122)], CS1); + } } ///////////////////////////////////////////////////////////////// // Prints a string on the lc display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -sed1520_string (int x, int y, char string[]) +MODULE_EXPORT void +sed1520_string (Driver *drvthis, int x, int y, char string[]) { int i; x--; // Convert 1-based coords to 0-based... @@ -308,8 +345,8 @@ sed1520_string (int x, int y, char string[]) // Writes char c at position x,y into the framebuffer. // x and y are 1-based textmode coordinates. // -void -sed1520_chr (int x, int y, char c) +MODULE_EXPORT void +sed1520_chr (Driver *drvthis, int x, int y, char c) { y--; x--; @@ -317,14 +354,14 @@ sed1520_chr (int x, int y, char c) } ///////////////////////////////////////////////////////////////// -// This function draws a number num into the last 3 rows of the +// This function draws a number num into the last 3 rows of the // framebuffer at 1-based position x. It should draw a 4-row font, // but methinks this would look a little stretched. When // num=10 a colon is drawn. // FIXME: make big numbers use less memory // -void -sed1520_num (int x, int num) +MODULE_EXPORT void +sed1520_num (Driver *drvthis, int x, int num) { int z, c, i, s; x--; @@ -349,7 +386,7 @@ sed1520_num (int x, int num) if (*(fontbigdp[(z * 8) + i] + c) == '.') s += 128; } - sed1520->framebuf[(z * 122) + 122 + (x * 6) + c] = s; + framebuf[(z * 122) + 122 + (x * 6) + c] = s; } } } @@ -367,7 +404,7 @@ sed1520_num (int x, int num) if (*(fontbignum[num][z * 8 + i] + c) == '.') s += 128; } - sed1520->framebuf[(z * 122) + 122 + (x * 6) + c] = s; + framebuf[(z * 122) + 122 + (x * 6) + c] = s; } } } @@ -381,10 +418,10 @@ sed1520_num (int x, int num) // can be altered. !Important: Characters have to be redraw // by drawchar2fb() to show their new shape. Because we use // a non-standard 6x8 font a *dat not calculated from -// sed1520->width and sed1520->height will fail. +// widthth and sed1520->height will fail. // -void -sed1520_set_char (int n, char *dat) +MODULE_EXPORT void +sed1520_set_char (Driver *drvthis, int n, char *dat) { int row, col, i; @@ -406,11 +443,11 @@ sed1520_set_char (int n, char *dat) ///////////////////////////////////////////////////////////////// -// Draws a vertical from the bottom up to the last 3 rows of the +// Draws a vertical from the bottom up to the last 3 rows of the // framebuffer at 1-based position x. len is given in pixels. // -void -sed1520_vbar (int x, int len) +MODULE_EXPORT void +sed1520_vbar (Driver *drvthis, int x, int len) { int i, j, k; x--; @@ -426,12 +463,12 @@ sed1520_vbar (int x, int len) k += 1 << (7 - i); } - sed1520->framebuf[((3 - j) * 122) + (x * 6)] = 0; - sed1520->framebuf[((3 - j) * 122) + (x * 6) + 1] = 0; - sed1520->framebuf[((3 - j) * 122) + (x * 6) + 2] = k; - sed1520->framebuf[((3 - j) * 122) + (x * 6) + 3] = k; - sed1520->framebuf[((3 - j) * 122) + (x * 6) + 4] = k; - sed1520->framebuf[((3 - j) * 122) + (x * 6) + 5] = 0; + framebuf[((3 - j) * 122) + (x * 6)] = 0; + framebuf[((3 - j) * 122) + (x * 6) + 1] = 0; + framebuf[((3 - j) * 122) + (x * 6) + 2] = k; + framebuf[((3 - j) * 122) + (x * 6) + 3] = k; + framebuf[((3 - j) * 122) + (x * 6) + 4] = k; + framebuf[((3 - j) * 122) + (x * 6) + 5] = 0; len -= 8; } @@ -439,11 +476,11 @@ sed1520_vbar (int x, int len) ///////////////////////////////////////////////////////////////// -// Draws a horizontal bar from left to right at 1-based position +// Draws a horizontal bar from left to right at 1-based position // x,y into the framebuffer. len is given in pixels. // -void -sed1520_hbar (int x, int y, int len) +MODULE_EXPORT void +sed1520_hbar (Driver *drvthis, int x, int y, int len) { int i; x--; @@ -453,15 +490,15 @@ sed1520_hbar (int x, int y, int len) return; for (i = 0; i < len; i++) - sed1520->framebuf[(y * 122) + (x * 6) + i] = 0x3C; + framebuf[(y * 122) + (x * 6) + i] = 0x3C; } ///////////////////////////////////////////////////////////////// -// Reprogrammes character dest to contain an icon given by +// Reprogrammes character dest to contain an icon given by // which. Calls set_char() to do this. // -void -sed1520_icon (int which, char dest) +MODULE_EXPORT void +sed1520_icon (Driver *drvthis, int which, char dest) { char icons[3][6 * 8] = { { @@ -495,42 +532,6 @@ sed1520_icon (int which, char dest) 1, 0, 1, 0, 1, 0,} , }; - sed1520_set_char (dest, &icons[which][0]); + sed1520_set_char (drvthis, dest, &icons[which][0]); } -///////////////////////////////////////////////////////////////// -// Send a rectangular area from lft,top to rgt,bot to the display -// These coordinates are probably one-based, too. It's so fast to -// flush the whole display that it makes no sense to flush less then -// the whole display. Therefore this function redraws the whole -// display. -// FIXME: Check if this function is worth implementing. -// -void -sed1520_flush_box (int lft, int top, int rgt, int bot) -{ - sed1520_flush (); -} - -///////////////////////////////////////////////////////////////// -// Outputs the whole framebuffer *dat to the display. This Display -// contains 2 Controllers, each of them controlling one half of the -// screen. -// -void -sed1520_draw_frame (char *dat) -{ - int i, j; - if (!dat) - return; - for (i = 0; i < 4; i++) - { - selectpage (i); - selectcolumn (0, CS2) ; - for (j = 0; j < 61; j++) - writedata (dat[j + (i * 122)], CS2); - selectcolumn (0, CS1) ; - for (j = 61; j < 122; j++) - writedata (dat[j + (i * 122)], CS1); - } -} diff --git a/server/drivers/sed1520.h b/server/drivers/sed1520.h index 10495a1..ed80302 100644 --- a/server/drivers/sed1520.h +++ b/server/drivers/sed1520.h @@ -1,20 +1,22 @@ #ifndef SED1520_H #define SED1520_H -extern lcd_logical_driver *sed1520; +#include "lcd.h" -int sed1520_init (struct lcd_logical_driver *driver, char *args); -void sed1520_close (); -void sed1520_clear (); -void sed1520_flush (); -void sed1520_string (int x, int y, char string[]); -void sed1520_chr (int x, int y, char c); -void sed1520_vbar (int x, int len); -void sed1520_hbar (int x, int y, int len); -void sed1520_num (int x, int num); -void sed1520_set_char (int n, char *dat); -void sed1520_icon (int which, char dest); -void sed1520_flush_box (int lft, int top, int rgt, int bot); -void sed1520_draw_frame (char *dat); + int sed1520_init (Driver *drvthis, char *args); +MODULE_EXPORT void sed1520_close (Driver *drvthis); +MODULE_EXPORT int sed1520_width (Driver *drvthis); +MODULE_EXPORT int sed1520_height (Driver *drvthis); +MODULE_EXPORT void sed1520_clear (Driver *drvthis); +MODULE_EXPORT void sed1520_flush (Driver *drvthis); +MODULE_EXPORT void sed1520_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void sed1520_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void sed1520_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void sed1520_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void sed1520_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void sed1520_icon (Driver *drvthis, int which, char dest); + +MODULE_EXPORT void sed1520_set_char (Driver *drvthis, int n, char *dat); #endif diff --git a/server/drivers/stv5730.c b/server/drivers/stv5730.c index dea0b39..85d9660 100644 --- a/server/drivers/stv5730.c +++ b/server/drivers/stv5730.c @@ -71,7 +71,7 @@ // Choose Colors: FLINE: First line text color, TEXT: Text color, CBACK: Character Background Color // CBORD: Character Border Color, SBACK: Screen Background color -// 0:Black, 1: Blue, 2:Green, 3: Cyan, 4: Red, 5: Magenta, 6: Yellow, 7: White +// 0:Black, 1: Blue, 2:Green, 3: Cyan, 4: Red, 5: Magenta, 6: Yellow, 7: White #define STV5730_COL_FLINE 4 #define STV5730_COL_TEXT 1 #define STV5730_COL_CBACK 3 @@ -83,6 +83,15 @@ unsigned int stv5730_lptport = LPTPORT; unsigned int stv5730_charattrib = STV5730_ATTRIB; unsigned int stv5730_flags = 0; +char * stv5730_framebuf = NULL; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "stv5730_"; + + // Translation map ascii->stv5730 charset unsigned char stv5730_to_ascii[256] = @@ -121,7 +130,6 @@ unsigned char stv5730_to_ascii[256] = }; -lcd_logical_driver *stv5730; //static void stv5730_upause (int delayCalls); #define stv5730_upause timing_uPause @@ -263,22 +271,20 @@ stv5730_drawchar2fb (int x, int y, unsigned char z) if (x < 0 || x >= STV5730_WID || y < 0 || y >= STV5730_HGT) return; - stv5730->framebuf[(y * STV5730_WID) + x] = stv5730_to_ascii[(unsigned int) z]; + stv5730_framebuf[(y * STV5730_WID) + x] = stv5730_to_ascii[(unsigned int) z]; } ///////////////////////////////////////////////////////////////// -// This initialises the stuff. We support supplying port as +// This initialises the stuff. We support supplying port as // a command line argument. -// +// int -stv5730_init (struct lcd_logical_driver *driver, char *args) +stv5730_init (Driver *drvthis, char *args) { char *argv[64], *str; int argc, i; - stv5730 = driver; - if (args) if ((str = (char *) malloc (strlen (args) + 1))) strcpy (str, args); @@ -333,9 +339,6 @@ stv5730_init (struct lcd_logical_driver *driver, char *args) } } - driver->wid = STV5730_WID; - driver->hgt = STV5730_HGT; - if (timing_init() == -1) return -1; @@ -426,89 +429,150 @@ stv5730_init (struct lcd_logical_driver *driver, char *args) stv5730_write16bit (0x10C0); } - - // The Framebuffer LCDproc allocates by default is too small, - // so we free() it and allocate one of adequate size. - if (!driver->framebuf) - free (driver->framebuf); - - driver->framebuf = malloc (STV5730_WID * STV5730_HGT); - if (!driver->framebuf) + // Alocate our own framebuffer + stv5730_framebuf = malloc (STV5730_WID * STV5730_HGT); + if (!stv5730_framebuf) { - stv5730_close (); - return -1; + stv5730_close (drvthis); + return -4; } // clear screen - memset (driver->framebuf, 0, STV5730_WID * STV5730_HGT); + memset (stv5730_framebuf, 0, STV5730_WID * STV5730_HGT); - driver->cellwid = 4; - driver->cellhgt = 6; + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->clear = stv5730_clear; - driver->string = stv5730_string; - driver->chr = stv5730_chr; - driver->vbar = stv5730_vbar; - driver->hbar = stv5730_hbar; - driver->num = stv5730_num; - driver->init = stv5730_init; - driver->close = stv5730_close; - driver->flush = stv5730_flush; - driver->flush_box = stv5730_flush_box; + // Set the functions the driver supports + drvthis->clear = stv5730_clear; + drvthis->string = stv5730_string; + drvthis->chr = stv5730_chr; + drvthis->old_vbar = stv5730_vbar; + drvthis->old_hbar = stv5730_hbar; + drvthis->num = stv5730_num; + drvthis->init = stv5730_init; + drvthis->close = stv5730_close; + drvthis->width = stv5730_width; + drvthis->height = stv5730_height; + drvthis->cellwidth = stv5730_cellwidth; + drvthis->cellheight = stv5730_cellheight; + drvthis->flush = stv5730_flush; // We dont't have any programmable chars. - //driver->set_char = NULL; + //drvthis->set_char = NULL; - driver->icon = stv5730_icon; - driver->draw_frame = stv5730_draw_frame; + drvthis->old_icon = stv5730_icon; // We dont't need init for vbar,hbar and friends. - //driver->init_hbar = NULL; - //driver->init_vbar = NULL; - //driver->init_num = NULL; + //drvthis->init_hbar = NULL; + //drvthis->init_vbar = NULL; + //drvthis->init_num = NULL; // Neither contrast nor backlight are controllable. - //driver->contrast = NULL; - //driver->backlight = NULL; + //drvthis->contrast = NULL; + //drvthis->backlight = NULL; // There are some unused input lines that may be used for input, // but nothing is programmed so far. - //driver->getkey = NULL; - return 200; // 200 is arbitrary. (must be 1 or more) + //drvthis->getkey = NULL; + return 0; } ///////////////////////////////////////////////////////////////// // Frees the framebuffer and exits the driver. // -void -stv5730_close () +MODULE_EXPORT void +stv5730_close (Driver *drvthis) { - if (stv5730->framebuf != NULL) - free (stv5730->framebuf); - stv5730->framebuf = NULL; + if (stv5730_framebuf != NULL) + free (stv5730_framebuf); + stv5730_framebuf = NULL; } +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +stv5730_width (Driver *drvthis) +{ + return STV5730_WID; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +stv5730_height (Driver *drvthis) +{ + return STV5730_HGT; +} + +///////////////////////////////////////////////////////////////// +// Returns the number of pixels a character is wide +// +MODULE_EXPORT int +stv5730_cellwidth (Driver *drvthis) +{ + return 4; +} + +///////////////////////////////////////////////////////////////// +// Returns the number of pixels a character is high +// +MODULE_EXPORT int +stv5730_cellheight (Driver *drvthis) +{ + return 6; +} +// cellwidth and cellheight are only needed for old_vbar. +// Therefor these values are now hardcoded into these functions. +// When old_vbar is not used anymore, these two functions can be removed. + + ///////////////////////////////////////////////////////////////// // Clears the screen // -void -stv5730_clear () +MODULE_EXPORT void +stv5730_clear (Driver *drvthis) { - memset (stv5730->framebuf, 0x0B, STV5730_WID * STV5730_HGT); + memset (stv5730_framebuf, 0x0B, STV5730_WID * STV5730_HGT); } ///////////////////////////////////////////////////////////////// -// +// // Flushes all output to the lcd... // -void -stv5730_flush () +MODULE_EXPORT void +stv5730_flush (Driver *drvthis) { - stv5730->draw_frame (stv5730->framebuf); + int i, j, atr; + + stv5730_locate (0, 0); + + for (i = 0; i < STV5730_HGT; i++) + { + if (i == 0) + atr = (STV5730_COL_FLINE << 8); + else + atr = (STV5730_COL_TEXT << 8); + stv5730_write16bit (0x1000 + atr + stv5730_framebuf[i * STV5730_WID] + + stv5730_charattrib); + for (j = 1; j < STV5730_WID; j++) + { + if (stv5730_framebuf[j + (i * STV5730_WID) - 1] != + stv5730_framebuf[j + (i * STV5730_WID)]) + stv5730_write8bit (stv5730_framebuf[j + (i * STV5730_WID)]); + else + stv5730_write0bit (); + + }; + } } ///////////////////////////////////////////////////////////////// // Prints a string on the screen, at position (x,y). The // upper-left is (1,1), and the lower right should be (28,11). // -void -stv5730_string (int x, int y, char string[]) +MODULE_EXPORT void +stv5730_string (Driver *drvthis, int x, int y, char string[]) { int i; x--; // Convert 1-based coords to 0-based... @@ -524,8 +588,8 @@ stv5730_string (int x, int y, char string[]) // Writes char c at position x,y into the framebuffer. // x and y are 1-based textmode coordinates. // -void -stv5730_chr (int x, int y, char c) +MODULE_EXPORT void +stv5730_chr (Driver *drvthis, int x, int y, char c) { y--; x--; @@ -536,8 +600,8 @@ stv5730_chr (int x, int y, char c) // This function draws ugly big numbers. We could use the zoom // feature of the stv5730 if we'd know when big numbers start // and stop. -void -stv5730_num (int x, int num) +MODULE_EXPORT void +stv5730_num (Driver *drvthis, int x, int num) { int i, j; @@ -566,11 +630,11 @@ stv5730_num (int x, int num) } ///////////////////////////////////////////////////////////////// -// Draws a vertical bar from the bottom up to the last 7 rows of the +// Draws a vertical bar from the bottom up to the last 7 rows of the // framebuffer at 1-based position x. len is given in pixels. -// -void -stv5730_vbar (int x, int len) +// +MODULE_EXPORT void +stv5730_vbar (Driver *drvthis, int x, int len) { int i; @@ -584,11 +648,11 @@ stv5730_vbar (int x, int len) if (len >= (i + 6)) { - stv5730->framebuf[((10 - (i / 6)) * STV5730_WID) + x] = 0x77; + stv5730_framebuf[((10 - (i / 6)) * STV5730_WID) + x] = 0x77; } else { - stv5730->framebuf[((10 - (i / 6)) * STV5730_WID) + x] = + stv5730_framebuf[((10 - (i / 6)) * STV5730_WID) + x] = 0x72 + (len % 6); } } @@ -597,12 +661,12 @@ stv5730_vbar (int x, int len) ///////////////////////////////////////////////////////////////// -// Draws a horizontal bar from left to right at 1-based position +// Draws a horizontal bar from left to right at 1-based position // x,y into the framebuffer. len is given in pixels. -// It uses the STV5730 'channel-tuning' chars(0x64-0x68) to do +// It uses the STV5730 'channel-tuning' chars(0x64-0x68) to do // this. -void -stv5730_hbar (int x, int y, int len) +MODULE_EXPORT void +stv5730_hbar (Driver *drvthis, int x, int y, int len) { int i; x--; @@ -617,24 +681,24 @@ stv5730_hbar (int x, int y, int len) if (len >= (i + 4)) { - stv5730->framebuf[(y * STV5730_WID) + x + (i / 5)] = 0x64; + stv5730_framebuf[(y * STV5730_WID) + x + (i / 5)] = 0x64; } else { - stv5730->framebuf[(y * STV5730_WID) + x + (i / 5)] = + stv5730_framebuf[(y * STV5730_WID) + x + (i / 5)] = 0x65 + (len % 5); } } } ///////////////////////////////////////////////////////////////// -// Reprogrammes character dest to contain an icon given by -// which. +// Reprogrammes character dest to contain an icon given by +// which. // The STV5730 has no programmable chars. The charset is very // limited, it doesn't even contain a '%' char. But wait... // It contains a heartbeat char ! :-) -void -stv5730_icon (int which, char dest) +MODULE_EXPORT void +stv5730_icon (Driver *drvthis, int which, char dest) { switch (which) { @@ -654,50 +718,3 @@ stv5730_icon (int which, char dest) } } - -///////////////////////////////////////////////////////////////// -// Send a rectangular area from lft,top to rgt,bot to the display -// These coordinates are probably one-based, too. It's so fast to -// flush the whole display that it makes no sense to flush less then -// the whole display. Therefore this function redraws the whole -// display. -// FIXME: Check if this function is worth implementing. -// -void -stv5730_flush_box (int lft, int top, int rgt, int bot) -{ - stv5730_flush (); -} - -///////////////////////////////////////////////////////////////// -// Outputs the whole framebuffer *dat to the display. -// Attributes are set for every row only. -// The first line has special attributes. -void -stv5730_draw_frame (char *dat) -{ - int i, j, atr; - if (!dat) - return; - - stv5730_locate (0, 0); - - for (i = 0; i < STV5730_HGT; i++) - { - if (i == 0) - atr = (STV5730_COL_FLINE << 8); - else - atr = (STV5730_COL_TEXT << 8); - stv5730_write16bit (0x1000 + atr + dat[i * STV5730_WID] + - stv5730_charattrib); - for (j = 1; j < STV5730_WID; j++) - { - if (dat[j + (i * STV5730_WID) - 1] != - dat[j + (i * STV5730_WID)]) - stv5730_write8bit (dat[j + (i * STV5730_WID)]); - else - stv5730_write0bit (); - - }; - } -} diff --git a/server/drivers/stv5730.h b/server/drivers/stv5730.h index 8046d0d..a3bbb2e 100644 --- a/server/drivers/stv5730.h +++ b/server/drivers/stv5730.h @@ -1,19 +1,21 @@ #ifndef STV5730_H #define STV5730_H -extern lcd_logical_driver *stv5730; +#include "lcd.h" -int stv5730_init (struct lcd_logical_driver *driver, char *args); -void stv5730_close (); -void stv5730_clear (); -void stv5730_flush (); -void stv5730_string (int x, int y, char string[]); -void stv5730_chr (int x, int y, char c); -void stv5730_vbar (int x, int len); -void stv5730_hbar (int x, int y, int len); -void stv5730_num (int x, int num); -void stv5730_icon (int which, char dest); -void stv5730_flush_box (int lft, int top, int rgt, int bot); -void stv5730_draw_frame (char *dat); + int stv5730_init (Driver *drvthis, char *args); +MODULE_EXPORT void stv5730_close (Driver *drvthis); +MODULE_EXPORT int stv5730_width (Driver *drvthis); +MODULE_EXPORT int stv5730_height (Driver *drvthis); +MODULE_EXPORT int stv5730_cellwidth (Driver *drvthis); +MODULE_EXPORT int stv5730_cellheight (Driver *drvthis); +MODULE_EXPORT void stv5730_clear (Driver *drvthis); +MODULE_EXPORT void stv5730_flush (Driver *drvthis); +MODULE_EXPORT void stv5730_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void stv5730_chr (Driver *drvthis, int x, int y, char c); +MODULE_EXPORT void stv5730_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void stv5730_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void stv5730_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void stv5730_icon (Driver *drvthis, int which, char dest); #endif diff --git a/server/drivers/t6963.c b/server/drivers/t6963.c index 431ac13..7a4bf9b 100644 --- a/server/drivers/t6963.c +++ b/server/drivers/t6963.c @@ -24,7 +24,6 @@ #include "shared/debug.h" #include "lcd.h" -#include "render.h" #include "port.h" #include "t6963.h" #include "t6963_font.h" @@ -37,7 +36,6 @@ #define DEBUG4 if(debug_level > 3) printf extern int debug_level; -lcd_logical_driver *t6963; static u16 t6963_out_port; static u16 t6963_display_mode; @@ -45,8 +43,20 @@ static u8 *t6963_display_buffer1; static u8 *t6963_display_buffer2; static u8 t6963_graph_line[6]; +static char *t6963_framebuf = NULL; +static int width; +static int height; +static int cellwidth; +static int cellheight; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "t6963_"; + int -t6963_init (struct lcd_logical_driver *driver, char *args) +t6963_init (Driver *drvthis, char *args) { char *argv[64]; int argc; @@ -63,8 +73,6 @@ t6963_init (struct lcd_logical_driver *driver, char *args) t6963_graph_line[4] = 0x3E; t6963_graph_line[5] = 0x3F; - t6963 = driver; - DEBUG3 ("Reading arguments...\n"); argc = get_args (argv, args, 64); @@ -101,47 +109,50 @@ t6963_init (struct lcd_logical_driver *driver, char *args) DEBUG3 (" cool, got 'em!\nSetting width and height\n"); - DEBUG3 ("done\nAllocating memory: %i x %i bytes = %i...\n", driver->wid, driver->hgt, driver->wid * driver->hgt); + DEBUG3 ("done\nAllocating memory: %i x %i bytes = %i...\n", width, height, width * height); // Set display size - t6963->wid = 20; - t6963->hgt = 6; - t6963->cellwid = 6; - t6963->cellhgt = 8; + width = 20; + height = 6; + cellwidth = 6; + cellheight = 8; - // You must use driver->framebuf here, but may use lcd.framebuf later. - if (!driver->framebuf) - driver->framebuf = malloc (driver->wid * driver->hgt); + // Allocate framebuf + t6963_framebuf = malloc (width * height); - if (!driver->framebuf) { - t6963_close (); + if (!t6963_framebuf) { + t6963_close (drvthis); return -1; } // Allocate memory - t6963_display_buffer1 = malloc (driver->wid * 6); - t6963_display_buffer2 = malloc (driver->wid * 6); + t6963_display_buffer1 = malloc (width * 6); + t6963_display_buffer2 = malloc (width * 6); // Clear front and back buffer - if(t6963_display_buffer1) memset(t6963_display_buffer1, ' ', driver->wid * 6); - if(t6963_display_buffer2) memset(t6963_display_buffer1, ' ', driver->wid * 6); + if(t6963_display_buffer1) memset(t6963_display_buffer1, ' ', width * 6); + if(t6963_display_buffer2) memset(t6963_display_buffer1, ' ', width * 6); DEBUG3 ("done\nSetting function pointers...\n"); - driver->clear = t6963_clear; - driver->string = t6963_string; - driver->chr = t6963_chr; - driver->vbar = t6963_vbar; - driver->hbar = t6963_hbar; - driver->num = t6963_num; - driver->init = t6963_init; - driver->close = t6963_close; - driver->flush = t6963_flush; - driver->flush_box = t6963_flush_box; - driver->set_char = t6963_set_char; - driver->icon = t6963_icon; - driver->heartbeat = t6963_heartbeat; - driver->draw_frame = t6963_draw_frame; + // Set variables for server + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->api_version = api_version; + drvthis->supports_multiple = &supports_multiple; - driver->getkey = t6963_getkey; + // Set the functions the driver supports + drvthis->clear = t6963_clear; + drvthis->string = t6963_string; + drvthis->chr = t6963_chr; + drvthis->old_vbar = t6963_vbar; + drvthis->old_hbar = t6963_hbar; + drvthis->num = t6963_num; + drvthis->init = t6963_init; + drvthis->close = t6963_close; + drvthis->flush = t6963_flush; + drvthis->set_char = t6963_set_char; + drvthis->old_icon = t6963_icon; + drvthis->heartbeat = t6963_heartbeat; + + drvthis->getkey = t6963_getkey; DEBUG3 ("done\nSending init to display...\n"); DEBUG4 (" make parallel port an output port\n"); @@ -155,25 +166,25 @@ t6963_init (struct lcd_logical_driver *driver, char *args) DEBUG4(" set graphic/text home adress and area\n"); t6963_low_command_word (SET_GRAPHIC_HOME_ADDRESS, ATTRIB_BASE); - t6963_low_command_word (SET_GRAPHIC_AREA, driver->wid); + t6963_low_command_word (SET_GRAPHIC_AREA, width); t6963_low_command_word (SET_TEXT_HOME_ADDRESS, TEXT_BASE); - t6963_low_command_word (SET_TEXT_AREA, driver->wid); + t6963_low_command_word (SET_TEXT_AREA, width); t6963_low_command (SET_MODE | OR_MODE | EXTERNAL_CG); t6963_low_command_2_bytes (SET_OFFSET_REGISTER, CHARGEN_BASE>>11, 0); t6963_low_command (SET_CURSOR_PATTERN | 7); // cursor is 8 lines high t6963_low_command_2_bytes (SET_CURSOR_POINTER, 0, 0); - t6963_set_nchar (0, fontdata_6x8, 256); + t6963_set_nchar (drvthis, 0, fontdata_6x8, 256); t6963_low_enable_mode (TEXT_ON); t6963_low_disable_mode (GRAPHIC_ON); t6963_low_disable_mode (CURSOR_ON); t6963_low_disable_mode (BLINK_ON); - t6963_clear (); - t6963_graphic_clear (0, 0, driver->wid, driver->cellhgt * 6); - t6963_flush(); + t6963_clear (drvthis); + t6963_graphic_clear (drvthis, 0, 0, width, cellheight * 6); + t6963_flush(drvthis); DEBUG3 ("Initialization done!\n"); return 0; // 200 is arbitrary. (must be 1 or more) @@ -183,19 +194,19 @@ t6963_init (struct lcd_logical_driver *driver, char *args) // lcd.framebuf will be set to the appropriate buffer before calling // your driver. -void -t6963_close () +MODULE_EXPORT void +t6963_close (Driver *drvthis) { DEBUG3 ("Shutting down!\n"); t6963_low_disable_mode (BLINK_ON); ioperm(t6963_out_port, 3, 0); - if (t6963->framebuf != NULL) - free (t6963->framebuf); + if (t6963_framebuf != NULL) + free (t6963_framebuf); if (t6963_display_buffer1 != NULL) free (t6963_display_buffer1); if (t6963_display_buffer2 != NULL) free (t6963_display_buffer2); - t6963->framebuf = NULL; + t6963_framebuf = NULL; t6963_display_buffer1 = NULL; t6963_display_buffer2 = NULL; } @@ -203,20 +214,20 @@ t6963_close () ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -t6963_clear () +MODULE_EXPORT void +t6963_clear (Driver *drvthis) { - DEBUG4 ("Clearing Display of size %i x %i\n", t6963->wid, 6); + DEBUG4 ("Clearing Display of size %i x %i\n", width, 6); - memset (t6963_display_buffer1, ' ', t6963->wid * 6); + memset (t6963_display_buffer1, ' ', width * 6); // for (i=0; i < 6; i++) -// if (t6963_hbar_len[i]==0) t6963_graphic_clear(0, i*t6963->cellhgt, t6963->wid, (i+1)*t6963->cellhgt); +// if (t6963_hbar_len[i]==0) t6963_graphic_clear(0, i*cellheight, width, (i+1)*cellheight); DEBUG4 ("Done\n"); } void -t6963_graphic_clear (int x1, int y1, int x2, int y2) +t6963_graphic_clear (Driver *drvthis, int x1, int y1, int x2, int y2) { int x; @@ -224,7 +235,7 @@ t6963_graphic_clear (int x1, int y1, int x2, int y2) for (;y1 < y2; y1++) { - t6963_low_command_word(SET_ADDRESS_POINTER, ATTRIB_BASE + y1 * t6963->wid + x1); + t6963_low_command_word(SET_ADDRESS_POINTER, ATTRIB_BASE + y1 * width + x1); for (x = x1; x < x2; x++) t6963_low_command_byte(DATA_WRITE_INC, 0); } @@ -233,13 +244,13 @@ t6963_graphic_clear (int x1, int y1, int x2, int y2) ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -void -t6963_flush () +MODULE_EXPORT void +t6963_flush (Driver *drvthis) { int i; - DEBUG4 ("Flushing %i x %i\n", t6963->wid, t6963->hgt); + DEBUG4 ("Flushing %i x %i\n", width, height); - for (i = 0; i < (t6963->wid * 6); i++) + for (i = 0; i < (width * 6); i++) { DEBUG4 ("%i%i|", t6963_display_buffer1[i], t6963_display_buffer2[i]); if (t6963_display_buffer1[i] != t6963_display_buffer2[i]) @@ -250,30 +261,15 @@ t6963_flush () } DEBUG4 ("\n"); t6963_swap_buffers(); - t6963_clear(); -} - -////////////////////////////////////////////////////////////////////// -// Send a rectangular area to the display. -// -// I've just called drv_base_flush() because there's not much point yet -// in flushing less than the entire framebuffer. -// -void -t6963_flush_box (int lft, int top, int rgt, int bot) -{ - DEBUG4 ("flush_box\n"); - t6963_flush(); - //drv_base_flush(); - + t6963_clear(drvthis); } ///////////////////////////////////////////////////////////////// // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,6). // -void -t6963_string (int x, int y, char string[]) +MODULE_EXPORT void +t6963_string (Driver *drvthis, int x, int y, char string[]) { DEBUG4 ("String out\n"); @@ -281,8 +277,8 @@ t6963_string (int x, int y, char string[]) y -= 1; // t6963_low_command_word(SET_ADDRESS_POINTER,TEXT_BASE+POSITION(x,y)); - if(y * t6963->wid + x + strlen(string) <= t6963->wid * 6); - memcpy(&t6963_display_buffer1[y * t6963->wid + x], string, strlen(string)); + if(y * width + x + strlen(string) <= width * 6); + memcpy(&t6963_display_buffer1[y * width + x], string, strlen(string)); } @@ -290,21 +286,21 @@ t6963_string (int x, int y, char string[]) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,6). // -void -t6963_chr (int x, int y, char c) +MODULE_EXPORT void +t6963_chr (Driver *drvthis, int x, int y, char c) { DEBUG4 ("Char out\n"); y--; x--; - if ((y * t6963->wid) + x <= (t6963->wid * 6)) - t6963_display_buffer1[(y * t6963->wid) + x] = c; + if ((y * width) + x <= (width * 6)) + t6963_display_buffer1[(y * width) + x] = c; } ////////////////////////////////////////////////////////////////////// // Draws a big (4-row) number. // -void -t6963_num (int x, int num) +MODULE_EXPORT void +t6963_num (Driver *drvthis, int x, int num) { // printf("BigNum(%i, %i)\n", x, num); } @@ -313,7 +309,7 @@ t6963_num (int x, int num) // Changes the font data of character n. // void -t6963_set_nchar (int n, char *dat, int num) +t6963_set_nchar (Driver *drvthis, int n, char *dat, int num) { int row, col; char letter; @@ -324,36 +320,36 @@ t6963_set_nchar (int n, char *dat, int num) return; t6963_low_command_word(SET_ADDRESS_POINTER, CHARGEN_BASE + n*8); - for (row = 0; row < t6963->cellhgt * num; row++) { + for (row = 0; row < cellheight * num; row++) { letter = 0; - for (col = 0; col < t6963->cellwid; col++) { + for (col = 0; col < cellwidth; col++) { letter <<= 1; - letter |= (dat[(row * t6963->cellwid) + col] > 0); + letter |= (dat[(row * cellwidth) + col] > 0); } t6963_low_command_byte(DATA_WRITE_INC, letter); } } -void -t6963_set_char (int n, char *dat) +MODULE_EXPORT void +t6963_set_char (Driver *drvthis, int n, char *dat) { - t6963_set_nchar (n, dat, 1); + t6963_set_nchar (drvthis, n, dat, 1); } ///////////////////////////////////////////////////////////////// // Draws a vertical bar, from the bottom of the screen up. // -void -t6963_vbar (int x, int len) +MODULE_EXPORT void +t6963_vbar (Driver *drvthis, int x, int len) { int y; DEBUG4 ("Drawing vertical bar..."); - for (y = 0; y < len/t6963->cellhgt; y++) - t6963_chr (x, 6-y, 219); + for (y = 0; y < len/cellheight; y++) + t6963_chr (drvthis, x, 6-y, 219); - if (len % t6963->cellhgt) - t6963_chr (x, 6-y, 211 + (len % t6963->cellhgt)); + if (len % cellheight) + t6963_chr (drvthis, x, 6-y, 211 + (len % cellheight)); DEBUG4 ("Done\n"); } @@ -361,16 +357,16 @@ t6963_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void -t6963_hbar (int x, int y, int len) +MODULE_EXPORT void +t6963_hbar (Driver *drvthis, int x, int y, int len) { - int stop = x + len/t6963->cellwid; + int stop = x + len/cellwidth; DEBUG4 ("Drawing horizontal bar x: %i, y: %i, len:%i, stop: %i...", x, y, len, stop); for (; x < stop; x++) - t6963_chr (x, y, 219); + t6963_chr (drvthis, x, y, 219); - if (len % t6963->cellwid) - t6963_chr (x, y, 225 - (len % t6963->cellwid)); + if (len % cellwidth) + t6963_chr (drvthis, x, y, 225 - (len % cellwidth)); DEBUG4 ("Done\n"); } @@ -378,8 +374,8 @@ t6963_hbar (int x, int y, int len) ///////////////////////////////////////////////////////////////// // Sets character 0 to an icon... // -void -t6963_icon (int which, char dest) +MODULE_EXPORT void +t6963_icon (Driver *drvthis, int which, char dest) { // printf("Char %i set to icon %i\n", dest, which); DEBUG4 ("Icon %i\n", which); @@ -388,8 +384,8 @@ t6963_icon (int which, char dest) ///////////////////////////////////////////////////////////////// // Does the heartbeat // -void -t6963_heartbeat (int type) +MODULE_EXPORT void +t6963_heartbeat (Driver *drvthis, int type) { static int timer; int whichIcon; @@ -402,34 +398,20 @@ t6963_heartbeat (int type) // Set this to pulsate like a real heartbeat... whichIcon = (! ((timer + 4) & 5)); // Put character on screen... - t6963_chr (t6963->wid, 1, 3+whichIcon); + t6963_chr (drvthis, width, 1, 3+whichIcon); } timer++; timer &= 0x0f; } -////////////////////////////////////////////////////////////////////// -// Gets a whole screen buffer as argument... -// - -void -t6963_draw_frame (char *dat) -{ - DEBUG4 ("Drawing frame..."); - - memcpy (t6963_display_buffer1, dat, t6963->wid * t6963->hgt); - - DEBUG4 ("Done"); -} - ////////////////////////////////////////////////////////////////////// // Tries to read a character from an input device... // // Return 0 for "nothing available". // -char -t6963_getkey () +MODULE_EXPORT char +t6963_getkey (Driver *drvthis) { DEBUG4 ("Get key"); return 0; diff --git a/server/drivers/t6963.h b/server/drivers/t6963.h index cc16325..5424d2f 100644 --- a/server/drivers/t6963.h +++ b/server/drivers/t6963.h @@ -12,6 +12,8 @@ #ifndef T6963_H #define T6963_H +#include "lcd.h" + #define SM_UP (1) #define SM_DOWN (2) #define CM_ERASE (2) @@ -105,25 +107,28 @@ typedef unsigned char u8; // * F U N C T I O N S * // **************************************************************************************** -extern lcd_logical_driver *t6963; -int t6963_init (struct lcd_logical_driver *driver, char *args); -void t6963_close (); -void t6963_clear (); -void t6963_graphic_clear (); -void t6963_flush (); -void t6963_string (int x, int y, char string[]); -void t6963_chr (int x, int y, char c); -void t6963_vbar (int x, int len); -void t6963_hbar (int x, int y, int len); -void t6963_num (int x, int num); -void t6963_set_nchar (int n, char *dat, int num); -void t6963_set_char (int n, char *dat); -void t6963_icon (int which, char dest); -void t6963_heartbeat (int type); -void t6963_flush_box (int lft, int top, int rgt, int bot); -void t6963_draw_frame (char *dat); -char t6963_getkey (); + int t6963_init (Driver *drvthis, char *args); +MODULE_EXPORT void t6963_close (Driver *drvthis); +MODULE_EXPORT int t6963_width (Driver *drvthis); +MODULE_EXPORT int t6963_height (Driver *drvthis); +MODULE_EXPORT void t6963_clear (Driver *drvthis); +MODULE_EXPORT void t6963_flush (Driver *drvthis); +MODULE_EXPORT void t6963_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void t6963_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void t6963_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void t6963_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void t6963_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void t6963_icon (Driver *drvthis, int which, char dest); +MODULE_EXPORT void t6963_heartbeat (Driver *drvthis, int type); + +MODULE_EXPORT void t6963_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT char t6963_getkey (Driver *drvthis); + +void t6963_graphic_clear (Driver *drvthis, int x1, int y1, int x2, int y2); +void t6963_set_nchar (Driver *drvthis, int n, char *dat, int num); void t6963_low_data(u8 byte); void t6963_low_command (u8 byte); diff --git a/server/drivers/text.c b/server/drivers/text.c index ca4e721..8fcac45 100644 --- a/server/drivers/text.c +++ b/server/drivers/text.c @@ -6,6 +6,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include #include #include @@ -17,24 +21,7 @@ #include "lcd.h" #include "text.h" -#include "drv_base.h" - -static void text_close (); -static void text_clear (); -static void text_flush (); -static void text_string (int x, int y, char string[]); -static void text_chr (int x, int y, char c); -static int text_contrast (int contrast); -static void text_backlight (int on); -//static void text_init_vbar (); -//static void text_init_hbar (); -//static void text_init_num (); -static void text_vbar (int x, int len); -static void text_hbar (int x, int y, int len); -static void text_num (int x, int num); -//static void text_set_char (int n, char *dat); -//static void text_flush_box (int lft, int top, int rgt, int bot); -static void text_draw_frame (char *dat); +//#include "drv_base.h" /* Ugly code extracted by David GLAUDE from lcdm001.c ;)*/ static char num_icon [10][4][3] = {{{' ','_',' '}, /*0*/ @@ -79,106 +66,160 @@ static char num_icon [10][4][3] = {{{' ','_',' '}, /*0*/ {' ',' ',' '}}}; /* End of ugly code ;) by Rene Wagner */ -lcd_logical_driver *text; +// Variables +int width; +int height; +char * framebuf; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "text_"; ////////////////////////////////////////////////////////////////////////// ////////////////////// For Text-Mode Output ////////////////////////////// ////////////////////////////////////////////////////////////////////////// -#define LCD_DEFAULT_WIDTH 20 -#define LCD_DEFAULT_HEIGHT 4 -// The two value below are fake, we don't support custom char. -#define LCD_DEFAULT_CELL_WIDTH 5 -#define LCD_DEFAULT_CELL_HEIGHT 8 - -// TODO: When using the text driver, ^C fails to interrupt! -// Why? Fix it... -// DONE??? Are you sure, not in my Konsole. David GLAUDE int -text_init (lcd_logical_driver * driver, char *args) +text_init (Driver *drvthis, char *args) { - text = driver; + // Set display sizes + if( drvthis->request_display_width() > 0 + && drvthis->request_display_height() > 0 ) { + // Use size from primary driver + width = drvthis->request_display_width(); + height = drvthis->request_display_height(); + } + else { + // Use default size + width = LCD_DEFAULT_WIDTH; + height = LCD_DEFAULT_HEIGHT; + } - // Make sure the frame buffer is there... - if (!text->framebuf) - text->framebuf = (unsigned char *) - malloc (text->wid * text->hgt); - memset (text->framebuf, ' ', text->wid * text->hgt); + // Allocate the framebuffer + framebuf = (unsigned char *) malloc (width * height); + memset (framebuf, ' ', width * height); + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; // Set the functions the driver supports + drvthis->init = text_init; + drvthis->close = text_close; + drvthis->width = text_width; + drvthis->height = text_height; - text->wid = LCD_DEFAULT_WIDTH; - text->hgt = LCD_DEFAULT_HEIGHT; - text->cellwid = LCD_DEFAULT_CELL_WIDTH; - text->cellhgt = LCD_DEFAULT_CELL_HEIGHT; + drvthis->clear = text_clear; + drvthis->flush = text_flush; + drvthis->string = text_string; + drvthis->chr = text_chr; - text->clear = text_clear; - text->string = text_string; - text->chr = text_chr; - text->vbar = text_vbar; - //text->init_vbar = NULL; - text->hbar = text_hbar; - //text->init_hbar = NULL; - text->num = text_num; - //text->init_num = NULL; + drvthis->old_vbar = text_vbar; + //drvthis->init_vbar = NULL; + drvthis->old_hbar = text_hbar; + //drvthis->init_hbar = NULL; + drvthis->num = text_num; + //drvthis->init_num = NULL; - text->init = text_init; - text->close = text_close; - text->flush = text_flush; - //text->flush_box = NULL; - //text->contrast = NULL; - //text->backlight = NULL; - //text->set_char = NULL; - //text->icon = NULL; - text->draw_frame = text_draw_frame; + drvthis->set_contrast = text_set_contrast; + drvthis->backlight = text_backlight; - //text->getkey = NULL; + //drvthis->set_char = NULL; + //drvthis->icon = NULL; - return 200; // 200 is arbitrary. (must be 1 or more) + //drvthis->getkey = NULL; + + return 0; } -static void -text_close () +///////////////////////////////////////////////////////////////// +// Closes the device +// +MODULE_EXPORT void +text_close (Driver *drvthis) { - if (text->framebuf != NULL) - free (text->framebuf); + if (framebuf != NULL) + free (framebuf); - text->framebuf = NULL; + framebuf = NULL; +} + +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +text_width (Driver *drvthis) +{ + return width; +} + +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +text_height (Driver *drvthis) +{ + return height; } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -static void -text_clear () +MODULE_EXPORT void +text_clear (Driver *drvthis) { - memset (text->framebuf, ' ', text->wid * text->hgt); + memset (framebuf, ' ', width * height); } ////////////////////////////////////////////////////////////////// // Flushes all output to the lcd... // -static void -text_flush () +MODULE_EXPORT void +text_flush (Driver *drvthis) { - text_draw_frame (text->framebuf); + int i, j; + + char out[LCD_MAX_WIDTH]; + + for (i = 0; i < width; i++) { + out[i] = '-'; + } + out[width] = 0; + printf ("+%s+\n", out); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + out[j] = framebuf[j + (i * width)]; + } + out[width] = 0; + printf ("|%s|\n", out); + + } + + for (i = 0; i < width; i++) { + out[i] = '-'; + } + out[width] = 0; + printf ("+%s+\n", out); } ///////////////////////////////////////////////////////////////// // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -static void -text_string (int x, int y, char string[]) +MODULE_EXPORT void +text_string (Driver *drvthis, int x, int y, char string[]) { int i; x--; y--; // Convert 1-based coords to 0-based... for (i = 0; string[i]; i++) { - text->framebuf[(y * text->wid) + x + i] = string[i]; + framebuf[(y * width) + x + i] = string[i]; } } @@ -186,24 +227,33 @@ text_string (int x, int y, char string[]) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -static void -text_chr (int x, int y, char c) +MODULE_EXPORT void +text_chr (Driver *drvthis, int x, int y, char c) { y--; x--; - text->framebuf[(y * text->wid) + x] = c; + framebuf[(y * width) + x] = c; } -static int -text_contrast (int contrast) +///////////////////////////////////////////////////////////////// +// Sets the contrast +// +MODULE_EXPORT void +text_set_contrast (Driver *drvthis, int promille) { -// printf("Contrast: %i\n", contrast); - return 0; + /* + printf("Contrast: %d\n", promille); + */ } -static void -text_backlight (int on) +///////////////////////////////////////////////////////////////// +// Sets the backlight brightness +// +MODULE_EXPORT void +text_backlight (Driver *drvthis, int on) { + //PrivateData * p = (PrivateData*) drvthis->private_data; + /* if(on) { @@ -237,14 +287,16 @@ text_backlight (int on) ///////////////////////////////////////////////////////////////// // Writes a big number. (by Rene Wagner from lcdm001.c) // -static void text_num (int x, int num) +MODULE_EXPORT void text_num (Driver *drvthis, int x, int num) { + //PrivateData * p = (PrivateData*) drvthis->private_data; + int y, dx; // printf("BigNum(%i, %i)\n", x, num); for (y = 1; y < 5; y++) for (dx = 0; dx < 3; dx++) - text_chr (x + dx, y, num_icon[num][y-1][dx]); + text_chr (drvthis, x + dx, y, num_icon[num][y-1][dx]); } //void @@ -256,14 +308,14 @@ static void text_num (int x, int num) ///////////////////////////////////////////////////////////////// // Draws a vertical bar; erases entire column onscreen. // -static void -text_vbar (int x, int len) +MODULE_EXPORT void +text_vbar (Driver *drvthis, int x, int len) { int y; - for (y = text->hgt; y > 0 && len > 0; y--) { - text_chr (x, y, '|'); + for (y = height; y > 0 && len > 0; y--) { + text_chr (drvthis, x, y, '|'); - len -= text->cellhgt; + len -= LCD_DEFAULT_CELLHEIGHT; } } @@ -271,56 +323,14 @@ text_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -static void -text_hbar (int x, int y, int len) +MODULE_EXPORT void +text_hbar (Driver *drvthis, int x, int y, int len) { - for (; x <= text->wid && len > 0; x++) { - text_chr (x, y, '-'); + for (; x <= width && len > 0; x++) { + text_chr (drvthis, x, y, '-'); - len -= text->cellwid; + len -= LCD_DEFAULT_CELLWIDTH; } } -static void -text_flush_box (int lft, int top, int rgt, int bot) -{ - text_flush (); -} - -static void -text_draw_frame (char *dat) -{ - int i, j; - - char out[LCD_MAX_WIDTH]; - - if (!dat) - return; - -// printf("Frame (%ix%i): \n%s\n", lcd.wid, lcd.hgt, dat); - - for (i = 0; i < text->wid; i++) { - out[i] = '-'; - } - out[text->wid] = 0; - printf ("+%s+\n", out); - - for (i = 0; i < text->hgt; i++) { - for (j = 0; j < text->wid; j++) { - out[j] = dat[j + (i * text->wid)]; - } - out[text->wid] = 0; - printf ("|%s|\n", out); - - } - - for (i = 0; i < text->wid; i++) { - out[i] = '-'; - } - out[text->wid] = 0; - printf ("+%s+\n", out); - -} - - diff --git a/server/drivers/text.h b/server/drivers/text.h index 1b29867..fe338e2 100644 --- a/server/drivers/text.h +++ b/server/drivers/text.h @@ -1,8 +1,25 @@ #ifndef LCD_TEXT_H #define LCD_TEXT_H -extern lcd_logical_driver *text; +#include "lcd.h" + + int text_init (Driver * drvthis, char *args); +MODULE_EXPORT void text_close (Driver *drvthis); +MODULE_EXPORT int text_width (Driver *drvthis); +MODULE_EXPORT int text_height (Driver *drvthis); +MODULE_EXPORT void text_clear (Driver *drvthis); +MODULE_EXPORT void text_flush (Driver *drvthis); +MODULE_EXPORT void text_string (Driver *drvthis, int x, int y, char string[]); +MODULE_EXPORT void text_chr (Driver *drvthis, int x, int y, char c); +MODULE_EXPORT void text_set_contrast (Driver *drvthis, int promille); +MODULE_EXPORT void text_backlight (Driver *drvthis, int on); +//MODULE_EXPORT void text_init_vbar (Driver *drvthis); +//MODULE_EXPORT void text_init_hbar (Driver *drvthis); +//MODULE_EXPORT void text_init_num (Driver *drvthis); +MODULE_EXPORT void text_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void text_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void text_num (Driver *drvthis, int x, int num); +//MODULE_EXPORT void text_set_char (Driver *drvthis, int n, char *dat); -int text_init (struct lcd_logical_driver *driver, char *args); #endif diff --git a/server/drivers/wirz-sli.c b/server/drivers/wirz-sli.c index 1cded69..d500e6d 100644 --- a/server/drivers/wirz-sli.c +++ b/server/drivers/wirz-sli.c @@ -1,7 +1,7 @@ /* wirz-sli.c -- Source file for LCDproc Wirz SLI driver Copyright (C) 1999 Horizon Technologies-http://horizon.pair.com/ Written by Bryan Rittmeyer - Released under GPL - + LCD info: http://www.wirz.com/ */ #include @@ -18,7 +18,7 @@ #include "lcd.h" #include "wirz-sli.h" -#include "drv_base.h" +//#include "drv_base.h" #include "shared/debug.h" #include "shared/str.h" @@ -32,15 +32,22 @@ typedef enum { } custom_type; static int fd; -static char lastframe[32]; +static char *framebuf = NULL; +static int width = 0; +static int height = 0; + +// Vars for the server core +MODULE_EXPORT char *api_version = API_VERSION; +MODULE_EXPORT int stay_in_foreground = 0; +MODULE_EXPORT int supports_multiple = 0; +MODULE_EXPORT char *symbol_prefix = "sli_"; -lcd_logical_driver *sli; ///////////////////////////////////////////////////////////////// // Opens com port and sets baud correctly... // int -sli_init (lcd_logical_driver * driver, char *args) +sli_init (Driver *drvthis, char *args) { char *argv[64]; int argc; @@ -52,8 +59,6 @@ sli_init (lcd_logical_driver * driver, char *args) char device[256] = "/dev/lcd"; int speed = B19200; - sli = driver; - //debug("sli_init: Args(all): %s\n", args); argc = get_args (argv, args, 64); @@ -135,7 +140,7 @@ sli_init (lcd_logical_driver * driver, char *args) // Do it... tcsetattr (fd, TCSANOW, &portset); - /* Initialize SLI using autobaud detection, and then turn off cursor + /* Initialize SLI using autobaud detection, and then turn off cursor and clear screen */ usleep (150000); /* 150ms delay to allow SLI to power on */ out[0] = 13; /* CR for SLI autobaud */ @@ -151,92 +156,109 @@ sli_init (lcd_logical_driver * driver, char *args) // Set LCD parameters (I use a 16x2 LCD) -- small but still useful // Its also much cheaper than the higher quality Matrix Orbital modules // Currently, $30 for interface kit and 16x2 non-backlit LCD... - driver->wid = 15; - driver->hgt = 2; + width = 15; + height = 2; - // Set the functions the driver supports... + // Set variables for server + drvthis->api_version = api_version; + drvthis->stay_in_foreground = &stay_in_foreground; + drvthis->supports_multiple = &supports_multiple; - driver->clear = sli_clear; - driver->string = sli_string; - driver->chr = sli_chr; - driver->vbar = sli_vbar; - driver->init_vbar = sli_init_vbar; - driver->hbar = sli_hbar; - driver->init_hbar = sli_init_hbar; - //driver->num = NULL; - //driver->init_num = NULL; + // Set the functions the driver supports + drvthis->clear = sli_clear; + drvthis->string = sli_string; + drvthis->chr = sli_chr; + drvthis->old_vbar = sli_vbar; + drvthis->init_vbar = sli_init_vbar; + drvthis->old_hbar = sli_hbar; + drvthis->init_hbar = sli_init_hbar; + //drvthis->num = NULL; + //drvthis->init_num = NULL; - driver->init = sli_init; - driver->close = sli_close; - driver->flush = sli_flush; - driver->flush_box = sli_flush_box; - //driver->contrast = NULL; - //driver->backlight = NULL; - driver->set_char = sli_set_char; - driver->icon = sli_icon; - driver->draw_frame = sli_draw_frame; + drvthis->init = sli_init; + drvthis->close = sli_close; + drvthis->flush = sli_flush; + //drvthis->contrast = NULL; + //drvthis->backlight = NULL; + drvthis->set_char = sli_set_char; + drvthis->old_icon = sli_icon; - //driver->getkey = NULL; + //drvthis->getkey = NULL; return fd; } -/* Clean-up */ -void -sli_close () +///////////////////////////////////////////////////////////////// +// Clean up +// +MODULE_EXPORT void +sli_close (Driver *drvthis) { close (fd); - if (sli->framebuf) - free (sli->framebuf); + if (framebuf) + free (framebuf); - sli->framebuf = NULL; + framebuf = NULL; } -void -sli_flush () +///////////////////////////////////////////////////////////////// +// Returns the display width +// +MODULE_EXPORT int +sli_width (Driver *drvthis) { - sli_draw_frame (sli->framebuf); + return width; } -/* no bounds checking is done in MtxOrb.c (which I shamelessly ripped) - this is bad imho, so I added it.. may remove later - speed is not a huge issue though, this isnt a - device driver or anything ;) */ -void -sli_flush_box (int lft, int top, int rgt, int bot) +///////////////////////////////////////////////////////////////// +// Returns the display height +// +MODULE_EXPORT int +sli_height (Driver *drvthis) { - int y; - char out[2]; /* Why does the matrix driver allocate so much here? */ + return height; +} - /* simple bounds checking */ - if ((top > sli->hgt) | (bot > sli->hgt)) - return; +///////////////////////////////////////////////////////////////// +// Flush framebuffer to LCD +// +MODULE_EXPORT void +sli_flush (Driver *drvthis) +{ + char out[2]; /* Again, why does the Matrix driver allocate so much here? */ - if ((lft > sli->wid) | (rgt > sli->wid)) - return; + /* + out[0]=0x0FE; + out[1]=0x001; + write(fd, out, 2); + */ -// printf("Flush (%i,%i)-(%i,%i)\n", lft, top, rgt, bot); + /* Don't update if we have no new data + this keeps me from getting a migraine + (just like those copyleft penguin mints... mmmmmm) */ -/* I like having hex, everywhere and all the time */ - for (y = top; y <= bot; y++) { - if (y == 1) - snprintf (out, sizeof(out), "%c%c", 0x0FE, 0x080 + lft); - if (y == 2) - snprintf (out, sizeof(out), "%c%c", 0x0FE, 0x0C0 + lft); - write (fd, out, 0x002); - write (fd, sli->framebuf + (y * sli->wid) + lft, rgt - lft + 1); - } + // if (!strncmp(dat,lastframe,32)) /* Nothing has changed */ + // return; + /* Do the actual refresh */ + out[0] = 0x0FE; + out[1] = 0x080; + write (fd, out, 2); + write (fd, &framebuf[0], 16); + usleep (10); + write (fd, &framebuf[16], 15); + + // strncpy(lastframe,dat,32); // Update lastframe... } ///////////////////////////////////////////////////////////////// // Clears the LCD screen // -void -sli_clear () +MODULE_EXPORT void +sli_clear (Driver *drvthis) { - memset (sli->framebuf, ' ', sli->wid * sli->hgt); + memset (framebuf, ' ', width * height); } @@ -244,8 +266,8 @@ sli_clear () // Prints a string on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -sli_string (int x, int y, char string[]) +MODULE_EXPORT void +sli_string (Driver *drvthis, int x, int y, char string[]) { int i; @@ -254,9 +276,9 @@ sli_string (int x, int y, char string[]) for (i = 0; string[i]; i++) { // Check for buffer overflows... - if ((y * sli->wid) + x + i > (sli->wid * sli->hgt)) + if ((y * width) + x + i > (width * height)) break; - sli->framebuf[(y * sli->wid) + x + i] = string[i]; + framebuf[(y * width) + x + i] = string[i]; } } @@ -264,26 +286,13 @@ sli_string (int x, int y, char string[]) // Prints a character on the lcd display, at position (x,y). The // upper-left is (1,1), and the lower right should be (20,4). // -void -sli_chr (int x, int y, char c) +MODULE_EXPORT void +sli_chr (Driver *drvthis, int x, int y, char c) { y--; x--; - sli->framebuf[(y * sli->wid) + x] = c; -} - -///////////////////////////////////////////////////////////////// -// Prints a character on the lcd display, at position (x,y). The -// upper-left is (1,1), and the lower right should be (20,4). -// -void -sli_chr (int x, int y, char c) -{ - y--; - x--; - - sli->framebuf[(y * sli->wid) + x] = c; + framebuf[(y * width) + x] = c; } ///////////////////////////////////////////////////////////////// @@ -293,14 +302,14 @@ sli_chr (int x, int y, char c) /* Because of the way we do this (custom characters in CGRAM) we can't have both horizontal and vertical bars at once... this also appears to be a limitation of the Matrix Orbital - modules so I will assume that all client coders know about it + modules so I will assume that all client coders know about it I think it would be cool to use triangular stuff for the non-full - characters, so that you can do both bar types at once.. maybe I + characters, so that you can do both bar types at once.. maybe I will release a new version of the SLI driver that attempts this */ -void -sli_init_vbar () +MODULE_EXPORT void +sli_init_vbar (Driver *drvthis) { char a[] = { 0, 0, 0, 0, 0, @@ -374,13 +383,13 @@ sli_init_vbar () }; if (custom != vbar) { - sli_set_char (1, a); - sli_set_char (2, b); - sli_set_char (3, c); - sli_set_char (4, d); - sli_set_char (5, e); - sli_set_char (6, f); - sli_set_char (7, g); + sli_set_char (drvthis, 1, a); + sli_set_char (drvthis, 2, b); + sli_set_char (drvthis, 3, c); + sli_set_char (drvthis, 4, d); + sli_set_char (drvthis, 5, e); + sli_set_char (drvthis, 6, f); + sli_set_char (drvthis, 7, g); custom = vbar; } } @@ -388,8 +397,8 @@ sli_init_vbar () ///////////////////////////////////////////////////////////////// // Inits horizontal bars... // -void -sli_init_hbar () +MODULE_EXPORT void +sli_init_hbar (Driver *drvthis) { char a[] = { @@ -434,10 +443,10 @@ sli_init_hbar () }; if (custom != hbar) { - sli_set_char (1, a); - sli_set_char (2, b); - sli_set_char (3, c); - sli_set_char (4, d); + sli_set_char (drvthis, 1, a); + sli_set_char (drvthis, 2, b); + sli_set_char (drvthis, 3, c); + sli_set_char (drvthis, 4, d); custom = hbar; } } @@ -451,19 +460,19 @@ sli_init_hbar () since we only have 2 lines anyway this is rather pointless for me to add */ -void -sli_vbar (int x, int len) +MODULE_EXPORT void +sli_vbar (Driver *drvthis, int x, int len) { char map[9] = { 32, 1, 2, 3, 4, 5, 6, 7, 255 }; int y; - for (y = sli->hgt; y > 0 && len > 0; y--) { - if (len >= sli->cellhgt) - sli_chr (x, y, 255); + for (y = height; y > 0 && len > 0; y--) { + if (len >= LCD_DEFAULT_CELLHEIGHT) + sli_chr (drvthis, x, y, 255); else - sli_chr (x, y, map[len]); + sli_chr (drvthis, x, y, map[len]); - len -= sli->cellhgt; + len -= LCD_DEFAULT_CELLHEIGHT; } } @@ -471,18 +480,18 @@ sli_vbar (int x, int len) ///////////////////////////////////////////////////////////////// // Draws a horizontal bar to the right. // -void -sli_hbar (int x, int y, int len) +MODULE_EXPORT void +sli_hbar (Driver *drvthis, int x, int y, int len) { char map[6] = { 32, 1, 2, 3, 4, 255 }; - for (; x <= sli->wid && len > 0; x++) { - if (len >= sli->cellwid) - sli_chr (x, y, 255); + for (; x <= width && len > 0; x++) { + if (len >= LCD_DEFAULT_CELLWIDTH) + sli_chr (drvthis, x, y, 255); else - sli_chr (x, y, map[len]); + sli_chr (drvthis, x, y, map[len]); - len -= sli->cellwid; + len -= LCD_DEFAULT_CELLWIDTH; } @@ -495,8 +504,8 @@ sli_hbar (int x, int y, int len) // // The input is just an array of characters... // -void -sli_set_char (int n, char *dat) +MODULE_EXPORT void +sli_set_char (Driver *drvthis, int n, char *dat) { char out[2]; int row, col; @@ -513,11 +522,11 @@ sli_set_char (int n, char *dat) out[1] = 0x040 + 8 * n; write (fd, out, 2); - for (row = 0; row < sli->cellhgt; row++) { + for (row = 0; row < LCD_DEFAULT_CELLHEIGHT; row++) { letter = 0; - for (col = 0; col < sli->cellwid; col++) { + for (col = 0; col < LCD_DEFAULT_CELLWIDTH; col++) { letter <<= 1; - letter |= (dat[(row * sli->cellwid) + col] > 0); + letter |= (dat[(row * LCD_DEFAULT_CELLWIDTH) + col] > 0); } letter |= 0x020; /* SLI can't accept CR, LF, etc in this character! */ write (fd, &letter, 1); @@ -529,8 +538,8 @@ sli_set_char (int n, char *dat) write (fd, out, 2); } -void -sli_icon (int which, char dest) +MODULE_EXPORT void +sli_icon (Driver *drvthis, int which, char dest) { char icons[3][5 * 8] = { { @@ -570,44 +579,6 @@ sli_icon (int which, char dest) if (custom == bign) custom = beat; - sli_set_char (dest, &icons[which][0]); + sli_set_char (drvthis, dest, &icons[which][0]); } -///////////////////////////////////////////////////////////// -// Blasts a single frame onscreen, to the lcd... -// -// Input is a character array, sized sli->wid*sli->hgt -// -void -sli_draw_frame (char *dat) -{ - char out[2]; /* Again, why does the Matrix driver allocate so much here? */ - int y; - - if (!dat) - return; - - /* - out[0]=0x0FE; - out[1]=0x001; - write(fd, out, 2); - */ - - /* Don't update if we have no new data - this keeps me from getting a migraine - (just like those copyleft penguin mints... mmmmmm) */ - - // if (!strncmp(dat,lastframe,32)) /* Nothing has changed */ - // return; - - /* Do the actual refresh */ - out[0] = 0x0FE; - out[1] = 0x080; - write (fd, out, 2); - write (fd, &dat[0], 16); - usleep (10); - write (fd, &dat[16], 15); - - // strncpy(lastframe,dat,32); // Update lastframe... - -} diff --git a/server/drivers/wirz-sli.h b/server/drivers/wirz-sli.h index 5ee1c07..7ed338a 100644 --- a/server/drivers/wirz-sli.h +++ b/server/drivers/wirz-sli.h @@ -1,30 +1,38 @@ /* wirz-sli.h -- Header file for LCDproc Wirz SLI driver Copyright (C) 1999 Horizon Technologies-http://horizon.pair.com/ Written by Bryan Rittmeyer - Released under GPL - + LCD info: http://www.wirz.com/sli/ */ #ifndef SLI_H #define SLI_H -extern lcd_logical_driver *sli; +#include "lcd.h" -int sli_init (lcd_logical_driver * driver, char *device); -void sli_close (); -void sli_flush (); -void sli_flush_box (int lft, int top, int rgt, int bot); -void sli_chr (int x, int y, char c); -int sli_contrast (int contrast); -void sli_backlight (int on); -void sli_init_vbar (); -void sli_init_hbar (); -void sli_vbar (int x, int len); -void sli_hbar (int x, int y, int len); -void sli_init_num (); -void sli_num (int x, int num); -void sli_set_char (int n, char *dat); -void sli_icon (int which, char dest); -void sli_draw_frame (char *dat); -char sli_getkey (); + int sli_init (Driver *drvthis, char *args); +MODULE_EXPORT void sli_close (Driver *drvthis); +MODULE_EXPORT int sli_width (Driver *drvthis); +MODULE_EXPORT int sli_height (Driver *drvthis); +MODULE_EXPORT void sli_clear (Driver *drvthis); +MODULE_EXPORT void sli_flush (Driver *drvthis); +MODULE_EXPORT void sli_string (Driver *drvthis, int x, int y, char *string); +MODULE_EXPORT void sli_chr (Driver *drvthis, int x, int y, char c); + +MODULE_EXPORT void sli_vbar (Driver *drvthis, int x, int len); +MODULE_EXPORT void sli_hbar (Driver *drvthis, int x, int y, int len); +MODULE_EXPORT void sli_num (Driver *drvthis, int x, int num); +MODULE_EXPORT void sli_icon (Driver *drvthis, int which, char dest); + +MODULE_EXPORT void sli_set_char (Driver *drvthis, int n, char *dat); + +MODULE_EXPORT int sli_get_contrast (Driver *drvthis); +MODULE_EXPORT void sli_set_contrast (Driver *drvthis, int contrast); +MODULE_EXPORT void sli_backlight (Driver *drvthis, int on); + +MODULE_EXPORT char sli_getkey (Driver *drvthis); + +MODULE_EXPORT void sli_init_vbar (Driver *drvthis); +MODULE_EXPORT void sli_init_hbar (Driver *drvthis); +MODULE_EXPORT void sli_init_num (Driver *drvthis); #endif diff --git a/server/input.c b/server/input.c index ac6acd3..ecb719f 100644 --- a/server/input.c +++ b/server/input.c @@ -6,7 +6,6 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * * * Handles keypad (and other?) input from the user. @@ -34,44 +33,6 @@ E-Z Ignored */ -// These are the keys for a (likely) properly functioning LK202-25... -// #define KEY_UP 'I' -// #define KEY_DOWN 'J' -// #define KEY_LEFT 'O' -// #define KEY_RIGHT 'E' -// #define KEY_F1 'N' -// #define KEY_F2 'M' -// #define KEY_ENTER 'H' - -// These are the keys for my (possibly) broken LK202-25... -// #define KEY_UP 'I' -// #define KEY_DOWN 'F' -// #define KEY_LEFT 'K' -// #define KEY_RIGHT 'A' -// #define KEY_F1 'N' -// #define KEY_F2 'M' -// #define KEY_ENTER 'H' - -// TODO: Generalize these into each driver... -// -// Really, what this comes down to, is different settings for -// different displays. Unless you want to recompile for all -// the defaults, these key settings must be in the driver. -// -// But then, which driver is active and which screen takes which -// input and... (sigh). -// -// #define PAUSE_KEY KEY_F1 -// #define BACK_KEY KEY_LEFT -// #define FORWARD_KEY KEY_RIGHT -// #define MAIN_MENU_KEY KEY_DOWN - -// This seems somewhat arbitrary, but it IS the original settings: -// -#define PAUSE_KEY 'A' -#define BACK_KEY 'B' -#define FORWARD_KEY 'C' -#define MAIN_MENU_KEY 'D' #include #include @@ -80,7 +41,7 @@ #include "shared/sockets.h" #include "shared/report.h" -#include "drivers/lcd.h" +#include "drivers.h" #include "client_data.h" #include "clients.h" @@ -98,70 +59,75 @@ int server_input (int key); -// FIXME! The server tends to crash when "E" is pressed.. (?!) -// (but only when the joystick driver is the last one on the list...) +/* FIXME! The server tends to crash when "E" is pressed.. (?!) + * (but only when the joystick driver is the last one on the list...) + */ -// Checks for keypad input, and dispatches it +/* Checks for keypad input, and dispatches it */ int handle_input () { char str[15]; int key; screen *s; - //widget *w; + /*widget *w; */ client *c; - if ((key = lcd_ptr->getkey ()) == 0) + report (RPT_INFO, "handle_input()" ); + + if ((key = drivers_getkey ()) == 0) return 0; - //debug (RPT_DEBUG, "handle_input(%c)", (char) key); + debug (RPT_INFO, "handle_input got key: '%c'", key); - // Sequence: - // Does the current screen want the key? - // IfTrue: handle and quit - // IfFalse: - // Let ALL clients handle it if they want - // Let Server handle it, too - // - // This leads to a unique situation: - // First: multiple clients may handle the same key in multiple ways - // Second: the server may handle the key differently yet - // - // Solution: Only the current screen can handle the key press. - // Alternately, only one client can handle the key press. + /* Sequence: + * Does the current screen want the key? + * IfTrue: handle and quit + * IfFalse: + * Let ALL clients handle it if they want + * Let Server handle it, too + * + * This leads to a unique situation: + * First: multiple clients may handle the same key in multiple ways + * Second: the server may handle the key differently yet + * + * Solution: Only the current screen can handle the key press. + * Alternately, only one client can handle the key press. + */ - // TODO: Interpret and translate keys! + /* TODO: Interpret and translate keys! */ - // Give current screen a shot at the key first + /* Give current screen a shot at the key first */ s = CurrentScreen (); if (KeyWanted(s->keys, key)) { - // This screen wants this key. Tell it we got one + /* This screen wants this key. Tell it we got one */ snprintf(str, sizeof(str), "key %c\n", key); sock_send_string(s->parent->sock, str); - // Nobody else gets this key + /* Nobody else gets this key */ } - // if the current screen doesn't want it, - // let the server have it... + /* if the current screen doesn't want it, + * let the server have it... + */ else { - // Give key to clients who want it + /* Give key to clients who want it */ c = FirstClient(clients); while (c) { - // If the client should have this keypress... + /* If the client should have this keypress... */ if(KeyWanted(c->data->client_keys,key)) { - // Send keypress to client + /* Send keypress to client */ snprintf(str, sizeof(str), "key %c\n", key); sock_send_string(c->sock, str); - break; // first come, first serve + break; /* first come, first serve */ }; c = NextClient(clients); - } // while clients + } /* while clients */ - // Give server a shot at all keys + /* Give server a shot at all keys */ server_input (key); } @@ -171,25 +137,24 @@ handle_input () int server_input (int key) { - debug (RPT_INFO, "server_input(%c)", (char) key); - report(RPT_INFO, "key %d pressed on device", key); + report(RPT_INFO, "server_input( key='%c' )", (char) key); switch ((char) key) { - case PAUSE_KEY: + case INPUT_PAUSE_KEY: if (screenlist_action == SCR_HOLD) screenlist_action = 0; else screenlist_action = SCR_HOLD; break; - case BACK_KEY: + case INPUT_BACK_KEY: screenlist_action = SCR_BACK; screenlist_prev (); break; - case FORWARD_KEY: + case INPUT_FORWARD_KEY: screenlist_action = SCR_SKIP; screenlist_next (); break; - case MAIN_MENU_KEY: + case INPUT_MAIN_MENU_KEY: debug (RPT_DEBUG, "got the menu key!"); server_menu (); break; diff --git a/server/input.h b/server/input.h index 30bec7a..d981a52 100644 --- a/server/input.h +++ b/server/input.h @@ -6,14 +6,24 @@ * COPYING file distributed with this package. * * Copyright (c) 1999, William Ferrell, Scott Scriven - * 2001, Joris Robijn * */ #ifndef INPUT_H #define INPUT_H -// Accepts and uses keypad input while displaying screens... +/* Accepts and uses keypad input while displaying screens... */ int handle_input (); +/* These defines should be used by drivers for version 0.4.3 of LCDproc + * as return values for _getkey(). + * You should not change these values, as some drivers still return + * A, B, C; D directly without using these defines! + */ +#define INPUT_PAUSE_KEY 'A' +#define INPUT_BACK_KEY 'B' +#define INPUT_FORWARD_KEY 'C' +#define INPUT_MAIN_MENU_KEY 'D' + + #endif diff --git a/server/main.c b/server/main.c index 109ca08..73d1794 100644 --- a/server/main.c +++ b/server/main.c @@ -53,7 +53,7 @@ extern int optind, optopt, opterr; #define MAX_TIMER 0x10000 -//#define DEFAULT_DEBUG_LEVEL 1 +/*#define DEFAULT_DEBUG_LEVEL 1*/ #define DEFAULT_LCD_PORT LCDPORT #define DEFAULT_BIND_ADDR "127.0.0.1" #define DEFAULT_CONFIGFILE "/etc/LCDd.conf" @@ -85,13 +85,13 @@ char *build_date = __DATE__; /**** Configuration variables ****/ -// All variables are set to 'unset' values +/* All variables are set to 'unset' values*/ #define UNSET_INT -1 #define UNSET_STR "\01" -int debug_level; // for compatibility with MtxOrb, lcdm001 and joy drivers. -// I was about to remove the comment in front of this. -// Now how do we become compatible WITHOUT this debug_level ? +int debug_level; /* for compatibility with MtxOrb and joy drivers. + * I was about to remove the comment in front of this. + * Now how do we become compatible WITHOUT this debug_level ?*/ int lcd_port = UNSET_INT; char bind_addr[64] = UNSET_STR; @@ -105,33 +105,34 @@ static int reportLevel = UNSET_INT; static int reportToSyslog = UNSET_INT; static int serverStarted = 0; -// The drivers and their driver parameters +/* The drivers and their driver parameters*/ char *drivernames[MAX_DRIVERS]; char *driverfilenames[MAX_DRIVERS]; char *driverargs[MAX_DRIVERS]; int num_drivers = 0; -// The parameter structure and args[] should -// be removed when getopt(3) is implemented, -// as there won't be any need for them then. -//typedef struct parameter { -// char *sh, *lg; // short and long versions -//} parameter; - -// This is currently only a list of available arguments, but doesn't -// really *do* anything. It just helps to figure out which parameters -// go to the server, and which ones go to individual drivers... -//static parameter args[] = { -// {"-h", "--help"}, -// {"-d", "--driver"}, -// {"-t", "--type"}, -// {"-f", "--foreground"}, -// {"-b", "--backlight"}, -// {"-i", "--serverinfo"}, -// {"-w", "--waittime"}, -// {NULL, NULL}, -//}; +/* The parameter structure and args[] should + * be removed when getopt(3) is implemented, + * as there won't be any need for them then. + * typedef struct parameter { + * char *sh, *lg; */ /* short and long versions*/ + /*} parameter; + + + * This is currently only a list of available arguments, but doesn't + * really *do* anything. It just helps to figure out which parameters + * go to the server, and which ones go to individual drivers... + *static parameter args[] = { + * {"-h", "--help"}, + * {"-d", "--driver"}, + * {"-t", "--type"}, + * {"-f", "--foreground"}, + * {"-b", "--backlight"}, + * {"-i", "--serverinfo"}, + * {"-w", "--waittime"}, + * {NULL, NULL}, + *}; + */ /**** Local functions ****/ @@ -155,18 +156,20 @@ void lcd_list_drivers(); int main (int argc, char **argv) { - // FIXME: s is getting clobbered - in MANY places!!! - //screen *s = NULL; - //char buf[64]; + /* FIXME: s is getting clobbered - in MANY places!!! + *screen *s = NULL; + *char buf[64]; + */ - signal (SIGINT, exit_program); // Ctrl-C will cause a clean exit... - signal (SIGTERM, exit_program); // and "kill"... - signal (SIGHUP, exit_program); // and "kill -HUP" (hangup)... - signal (SIGKILL, exit_program); // and just in case, "kill -KILL" (which cannot be trapped; but oh well) + signal (SIGINT, exit_program); /* Ctrl-C will cause a clean exit...*/ + signal (SIGTERM, exit_program); /* and "kill"...*/ + signal (SIGHUP, exit_program); /* and "kill -HUP" (hangup)...*/ + signal (SIGKILL, exit_program); /* and just in case, "kill -KILL" (which cannot be trapped; but oh well)*/ - // If no paramaters given, give the help screen. - //if (argc == 1) - // HelpScreen (); + /* If no paramaters given, give the help screen. + *if (argc == 1) + * HelpScreen (); + */ /* * Settings in order of preference: @@ -188,41 +191,42 @@ main (int argc, char **argv) * in the variable declaration... */ - // Set the initial reporting parameters + /* Set the initial reporting parameters*/ report(RPT_NOTICE, "LCDd version %s starting", version ); report(RPT_INFO, "Built on %s, protocol version %s, API version %s", build_date, protocol_version, api_version ); clear_settings(); - // Read command line + /* Read command line*/ ESSENTIAL( process_command_line (argc, argv) ); - // Read config file - // Set configfile to default value first unless changed before + /* Read config file + * Set configfile to default value first unless changed before + */ if (strcmp(configfile, UNSET_STR)==0) strncpy (configfile, DEFAULT_CONFIGFILE, sizeof(configfile)); ESSENTIAL( process_configfile (configfile) ); - // Set default values + /* Set default values*/ set_default_settings(); - // Set reporting values + /* Set reporting values*/ debug_level = reportLevel; ESSENTIAL( set_reporting( reportLevel, (reportToSyslog?RPT_DEST_SYSLOG:RPT_DEST_STDERR) ) ); report( RPT_NOTICE, "Set report level to %d, output to %s", reportLevel, (reportToSyslog?"syslog":"stderr") ); - // Startup the server + /* Startup the server*/ ESSENTIAL( init_sockets() ); ESSENTIAL( init_drivers() ); ESSENTIAL( init_screens() ); ESSENTIAL( drop_privs(user) ); - // Store it for exit_program() + /* Store it for exit_program()*/ serverStarted = 1; #ifndef DEBUG - // Now, go into daemon mode... + /* Now, go into daemon mode...*/ if (daemon_mode) { report(RPT_NOTICE, "Server forking to background"); ESSENTIAL( daemonize() ); @@ -232,7 +236,7 @@ main (int argc, char **argv) #endif do_mainloop(); - // This loop never stops; we'll get out only with a signal... + /* This loop never stops; we'll get out only with a signal...*/ return 0; } @@ -243,7 +247,7 @@ clear_settings () { int i; - //report( RPT_INFO, "clear_settings()" ); + /*report( RPT_INFO, "clear_settings()" );*/ lcd_port = UNSET_INT; strncpy( bind_addr, UNSET_STR, sizeof(bind_addr) ); @@ -275,15 +279,16 @@ process_command_line (int argc, char **argv) { char c; - //report( RPT_INFO, "process_command_line()" ); + /*report( RPT_INFO, "process_command_line()" );*/ - // analyze options here.. + /* analyze options here..*/ while ((c = getopt(argc, argv, "a:p:d:hfib:w:c:u:sr:")) > 0) { - // FIXME: Setting of c in this loop clobbers s! - // s is set equivalent to c. + /* FIXME: Setting of c in this loop clobbers s! + * s is set equivalent to c. + */ switch(c) { case 'd': - // Add to a list of drivers to be initialized later... + /* Add to a list of drivers to be initialized later...*/ if (num_drivers < MAX_DRIVERS) { drivernames[num_drivers] = malloc( strlen(optarg)+1 ); driverfilenames[num_drivers] = malloc( strlen(optarg)+1 ); @@ -371,16 +376,17 @@ process_configfile ( char *configfile ) { int i; char * s; - //char buf[64]; + /*char buf[64];*/ - //report( RPT_INFO, "process_configfile()" ); + /*report( RPT_INFO, "process_configfile()" );*/ - // Read server settings + /* Read server settings*/ config_read_file( configfile ); -// if( debug_level == UNSET_INT ) -// debug_level = config_get_int( "server", "debug", 0, UNSET_INT ); +/* if( debug_level == UNSET_INT ) + * debug_level = config_get_int( "server", "debug", 0, UNSET_INT ); + */ if( lcd_port == UNSET_INT ) lcd_port = config_get_int( "server", "port", 0, UNSET_INT ); @@ -430,7 +436,7 @@ process_configfile ( char *configfile ) } if( reportToSyslog == UNSET_INT ) { - // Is the value set in the config file anyway ? + /* Is the value set in the config file anyway ?*/ if( strcmp( config_get_string( "server", "reportToSyslog", 0, "" ), "" ) != 0 ) { reportToSyslog = config_get_bool( "server", "reportToSyslog", 0, 0 ); } @@ -440,12 +446,13 @@ process_configfile ( char *configfile ) } - // Read drivers + /* Read drivers*/ - // If drivers have been specified on the command line, then do not - // use the driver list from the config file. + /* If drivers have been specified on the command line, then do not + * use the driver list from the config file. + */ if( num_drivers == 0 ) { - // read the drivernames + /* read the drivernames*/ while( 1 ) { s = config_get_string( "server", "driver", num_drivers, "" ); @@ -464,8 +471,9 @@ process_configfile ( char *configfile ) } } - // Now read the driver options that the server needs - // Drivers can read their own options later... + /* Now read the driver options that the server needs + * Drivers can read their own options later... + */ for( i=0; i= 0) { - // Load went OK + /* Load went OK */ switch( res ) { - case 0: // Driver does input only + case 0: /* Driver does input only */ break; - case 1: // Driver does output + case 1: /* Driver does output */ output_loaded = 1; break; - case 2: // Driver does output in foreground (don't daemonize) + case 2: /* Driver does output in foreground (don't daemonize) */ if ( !output_loaded ) { daemon_mode = 0; } @@ -612,7 +618,7 @@ init_drivers() } } - // Do we have a running output driver ? + /* Do we have a running output driver ?*/ if ( output_loaded ) { return 0; } else { @@ -652,7 +658,7 @@ init_screens () report(RPT_ERR, "Error initializing screen list"); return -1; } - // Make sure the server screen shows up every once in a while.. + /* Make sure the server screen shows up every once in a while..*/ if (server_screen_init () < 0) { report(RPT_ERR, "Error initializing server screens"); return -1; @@ -671,49 +677,54 @@ do_mainloop () report( RPT_INFO, "do_mainloop()" ); - //char buf[64]; + /*char buf[64];*/ - // FIXME: s should still be null from initialization.... what's happening here?! + /* FIXME: s should still be null from initialization.... what's happening here?!*/ while (1) { - sock_poll_clients (); // poll clients for input - parse_all_client_messages (); // analyze input from network clients - handle_input (); // handle key input from devices + sock_poll_clients (); /* poll clients for input*/ + parse_all_client_messages (); /* analyze input from network clients*/ + handle_input (); /* handle key input from devices*/ - // TODO: Move this code to screenlist.c... - // ... it should just say "handle_screens();" - // Timer gets reset by screenlist_next() + /* TODO: Move this code to screenlist.c... + * ... it should just say "handle_screens();" + * Timer gets reset by screenlist_next() + */ timer++; - //if (s == NULL) - // s = screenlist_current(); + /*if (s == NULL) + * s = screenlist_current(); - // this is here because s is getting overwritten... - //if (s != screenlist_current()) { - // report(RPT_DEBUG, "internal error! s was found overwritten at main.c:637"); - // s = screenlist_current(); - //} - // - //TODO: THIS MUST BE FIXED..... WHY is s getting overwritten? - // s is a local, it is never passed or assigned to anywhere. - // So SOMETHING is going haywire and clobbering memory.... + * this is here because s is getting overwritten... + *if (s != screenlist_current()) { + * report(RPT_DEBUG, "internal error! s was found overwritten at main.c:637"); + * s = screenlist_current(); + *} + */ + + /*TODO: THIS MUST BE FIXED..... WHY is s getting overwritten? + * s is a local, it is never passed or assigned to anywhere. + * So SOMETHING is going haywire and clobbering memory.... + */ if (s && (timer >= s->duration)) screenlist_next (); - // Just in case it gets out of hand... + /* Just in case it gets out of hand...*/ if (timer >= MAX_TIMER) timer = 0; - // Update server screen with the right number - // of clients and screens... - // - // TODO: Move this call to every client connection - // and every screen add... + /* Update server screen with the right number + * of clients and screens... + */ + + /* TODO: Move this call to every client connection + * and every screen add... + */ update_server_screen (timer); - // draw the current scren + /* draw the current scren*/ if ((s = screenlist_current ()) != NULL) @@ -723,9 +734,10 @@ do_mainloop () usleep (TIME_UNIT); - //Check to see if the screen has a timeout value, if it does - //decrese it and then check to see if it has excpired. - //Remove if expired. + /* Check to see if the screen has a timeout value, if it does + * decrese it and then check to see if it has excpired. + * Remove if expired. + */ if((message = malloc(256)) == NULL) report(RPT_ERR, "Error allocating message string"); else { @@ -756,7 +768,7 @@ do_mainloop () } } - // Quit! + /* Quit! */ exit_program (0); } @@ -767,8 +779,9 @@ exit_program (int val) report( RPT_INFO, "exit_program()" ); - // TODO: These things shouldn't be so interdependent. The order - // things are shut down in shouldn't matter... + /* TODO: These things shouldn't be so interdependent. The order + * things are shut down in shouldn't matter... + */ strncpy(buf, "Server shutting down on ", sizeof (buf) ); switch(val) { @@ -776,26 +789,26 @@ exit_program (int val) case 2: strcat(buf, "SIGINT"); break; case 15: strcat(buf, "SIGTERM"); break; default: snprintf(buf, sizeof(buf), "Server shutting down on signal %d", val); break; - // Other values should not be seen, but just in case.. + /* Other values should not be seen, but just in case.. */ } - report(RPT_NOTICE, buf); // report it + report(RPT_NOTICE, buf); /* report it */ - // Set emergency reporting and flush all messages if not done already. + /* Set emergency reporting and flush all messages if not done already. */ if( reportLevel == UNSET_INT ) reportLevel = DEFAULT_REPORTLEVEL; if( reportToSyslog == UNSET_INT ) reportLevel = DEFAULT_REPORTLEVEL; set_reporting( reportLevel, (reportToSyslog?RPT_DEST_SYSLOG:RPT_DEST_STDERR) ); - // Shutdown things if server start was complete + /* Shutdown things if server start was complete */ if( serverStarted ) { - goodbye_screen (); // display goodbye screen on LCD display - unload_all_drivers (); // release driver memory and file descriptors + goodbye_screen (); /* display goodbye screen on LCD display */ + drivers_unload_all (); /* release driver memory and file descriptors */ - client_shutdown (); // shutdown clients (must come first) - screenlist_shutdown (); // shutdown screens (must come after client_shutdown) - sock_close_all (); // close all open sockets (must come after client_shutdown) + client_shutdown (); /* shutdown clients (must come first) */ + screenlist_shutdown (); /* shutdown screens (must come after client_shutdown) */ + sock_close_all (); /* close all open sockets (must come after client_shutdown) */ } exit (0); @@ -805,39 +818,40 @@ exit_program (int val) void HelpScreen () { - // Help screen is printed to stdout on purpose. No reason to have - // this in syslog... + /* Help screen is printed to stdout on purpose. No reason to have + * this in syslog... + */ report( RPT_INFO, "HelpScreen()" ); - printf ("\nLCDd Server Daemon (part of lcdproc), %s\n", version); - printf ("Copyright (c) 1999 Scott Scriven, William Ferrell, and misc contributors\n"); - printf ("This program is freely redistributable under the terms of the GNU Public License\n\n"); - printf ("Usage: LCDd [ -hfiws ] [ -c ] [ -d ] [ -a ] \\\n\t[ -p ] [ -u ] [ -w