Logo Search packages:      
Sourcecode: lcdproc version File versions  Download package

lcd.c

/*
 * Driver master (lcd.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
 *               2002, Rene Wagner
 *
 *
 * This code actually sets up the drivers as requested,
 * initializes drivers, and allocates memory for drivers.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <sys/errno.h>
#include <syslog.h>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "shared/LL.h"
#include "shared/report.h"

#include "lcd.h"

static int lcd_drv_init (lcd_logical_driver * driver, char *args);
static void lcd_drv_close ();
static void lcd_drv_clear ();
static void lcd_drv_flush ();
static void lcd_drv_string (int x, int y, char *string);
static void lcd_drv_chr (int x, int y, char c);
static int lcd_drv_contrast (int contrast);
static void lcd_drv_backlight (int on);
static void lcd_drv_output (int on);
static void lcd_drv_init_vbar ();
static void lcd_drv_init_hbar ();
static void lcd_drv_init_num ();
static void lcd_drv_num (int x, int num);
static void lcd_drv_set_char (int n, char *dat);
static void lcd_drv_vbar (int x, int len);
static void lcd_drv_hbar (int x, int y, int len);
static void lcd_drv_icon (int which, char dest);
static void lcd_drv_flush_box (int lft, int top, int rgt, int bot);
static void lcd_drv_draw_frame ();
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...
 * but WHY?
 *
 */

#ifdef LCDM001_DRV
#include "lcdm001.h"
#endif

#ifdef MTXORB_DRV
#include "MtxOrb.h"
#endif

#ifdef CFONTZ_DRV
#include "CFontz.h"
#endif

#ifdef CWLNX_DRV
#include "CwLnx.h"
#endif

#ifdef LB216_DRV
#include "lb216.h"
#endif

#ifdef TEXT_DRV
#include "text.h"
#endif

#ifdef DEBUG_DRV
#include "debug.h"
#endif

#ifdef CURSES_DRV
#include "curses_drv.h"
#endif

#ifdef HD44780_DRV
#include "hd44780.h"
#endif

#ifdef WIRZSLI_DRV
#include "wirz-sli.h"
#endif

#ifdef SGX120_DRV
#include "SGX120.h"
#endif

#ifdef JOY_DRV
#include "joy.h"
#endif

#ifdef IRMANIN_DRV
#include "irmanin.h"
#endif

#ifdef LIRCIN_DRV
#include "lircin.h"
#endif

#ifdef BAYRAD_DRV
#include "bayrad.h"
#endif

#ifdef SED1330_DRV
#include "sed1330.h"
#endif

#ifdef SED1520_DRV
#include "sed1520.h"
#endif

#ifdef STV5730_DRV
#include "stv5730.h"
#endif

#ifdef GLK_DRV
#include "glk.h"
#endif

#ifdef SVGALIB_DRV
#include "svgalib_drv.h"
#endif

#ifdef T6963_DRV
#include "t6963.h"
#endif

// Make program more readable and understandable;
// hide details...
//#define ResetList(a)        LL_Rewind(a)
//#define GetDriverData(a)    ((lcd_logical_driver *)LL_Get(a))
//#define NextDriver(a)       (LL_Next(a))
//#define MoreDrivers(a)            (LL_Next(a) == 0)
//#define DriverPresent(a)    (a)
//#define FunctionPresent(a)  ((a) != 0)

// TODO: Make a Windows server, and clients...?

lcd_logical_driver lcd, *lcd_root = NULL, *lcd_ptr = NULL;

// TODO: Add multiple names for the same driver?
//
// Would allow the use of "MatrixOrbital" (for example) or
// "Joystick" or "CrystalFontz" or similar more memorable
// names, as well as older ones...
//
lcd_physical_driver drivers[] = {

#ifdef LCDM001_DRV
      {"lcdm001", lcdm001_init,},
      {"LCDM001", lcdm001_init,},
#endif
#ifdef MTXORB_DRV
      {"MtxOrb", MtxOrb_init,},
      {"MatrixOrbital", MtxOrb_init,},
#endif
#ifdef CFONTZ_DRV
      {"CFontz", CFontz_init,},
      {"CrystalFontz", CFontz_init,},
#endif
#ifdef CWLNX_DRV
      {"CwLnx", CwLnx_init,},
      {"Cwlinux", CwLnx_init,},
#endif
#ifdef HD44780_DRV
      {"HD44780", HD44780_init,},
      {"Hitachi", HD44780_init,},
#endif
#ifdef WIRZSLI_DRV
      {"sli", sli_init,},
      {"Wirz", sli_init,},
      {"Wirz-sli", sli_init,},
      {"wirz-sli", sli_init,},
#endif
#ifdef LB216_DRV
      {"LB216", LB216_init,},
#endif
#ifdef TEXT_DRV
      {"text", text_init,},
#endif
#ifdef DEBUG_DRV
      {"debug", debug_init,},
#endif
#ifdef CURSES_DRV
      {"curses", curses_drv_init,},
      {"ncurses", curses_drv_init,},
#endif
#ifdef JOY_DRV
      {"joy", joy_init,},
      {"joystick", joy_init,},
#endif
#ifdef IRMANIN_DRV
      {"irmanin", irmanin_init,},
#endif
#ifdef LIRCIN_DRV
      {"lircin", lircin_init,},
#endif
#ifdef BAYRAD_DRV
      {"BayRAD", bayrad_init,},
#endif
#ifdef GLK_DRV
      {"glk", glk_init,},
      {"glc", glk_init,},
#endif
#ifdef SED1330_DRV
      {"sed1330", sed1330_init,},
#endif
#ifdef SED1520_DRV
      {"sed1520", sed1520_init,},
#endif
#ifdef STV5730_DRV
      {"stv5730", stv5730_init,},
#endif
#ifdef SGX120_DRV
      {"sgx120", SGX120_init,},
      {"SGX120", SGX120_init,},
#endif
#ifdef SVGALIB_DRV
      {"svgalib", svgalib_drv_init,},
      {"vga", svgalib_drv_init,},
      {"svga", svgalib_drv_init,},
#endif
#ifdef T6963_DRV
      {"t6963", t6963_init,},
      {"Toshiba", t6963_init,},
#endif

      {NULL, NULL,},

};

LinkedList *list;

#define CurrentDriver (drivers[i].name)
#define NextDriver (drivers[i+1].name)

void
lcd_list_drivers (void) {
      int i = 0;

      printf("\t");
      while (CurrentDriver != NULL) {
            printf("%s", CurrentDriver);

            if (NextDriver != NULL)
                  printf(", ");

            i++;
            if ((i % 8) == 0)
                  printf("\n\t");
      }

      printf("\n");
}

////////////////////////////////////////////////////////////
// This function initializes a few basics as well as the
// "base" array.  To initialize a specific driver, use the
// lcd_add_driver() function.
//
// 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)
{
      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 up these wrapper functions...
      driver->clear = lcd_drv_clear;
      driver->string = lcd_drv_string;
      driver->chr = lcd_drv_chr;
      driver->vbar = lcd_drv_vbar;
      driver->hbar = lcd_drv_hbar;
      driver->init_num = lcd_drv_init_num;
      driver->num = lcd_drv_num;

      driver->init = lcd_drv_init;
      driver->close = lcd_drv_close;
      driver->flush = lcd_drv_flush;
      driver->flush_box = lcd_drv_flush_box;
      driver->contrast = lcd_drv_contrast;
      driver->backlight = lcd_drv_backlight;
      driver->output = lcd_drv_output;
      driver->set_char = lcd_drv_set_char;
      driver->icon = lcd_drv_icon;
      driver->init_vbar = lcd_drv_init_vbar;
      driver->init_hbar = lcd_drv_init_hbar;
      driver->draw_frame = lcd_drv_draw_frame;

      driver->getkey = lcd_drv_getkey;
      driver->getinfo = lcd_drv_getinfo;
      driver->heartbeat = lcd_drv_heartbeat;

      return 1;                                   // 1 is arbitrary.  (must be 1 or more)
}

#define ChkNull(a,b,c) if ((driver->a) == 0) { syslog(LOG_INFO, "warning: %s: null entries deprecated!", (c)); driver->a = (b); }
#define ChkBaseDrv(a,b,c) if ((driver->a) == (void *) -1) { syslog(LOG_ERR, "warning: %s: base driver has been REMOVED!", (c)); driver->a = (b); }

static int
lcd_drv_patch_init (struct lcd_logical_driver *driver)
{
      // These are to patch drivers that use "NULL" as a valid value...
      ChkNull(clear, lcd_drv_clear, "clear");
      ChkNull(string, lcd_drv_string, "string");
      ChkNull(chr, lcd_drv_chr, "chr");
      ChkNull(vbar, lcd_drv_vbar, "vbar");
      ChkNull(hbar, lcd_drv_hbar, "hbar");
      ChkNull(init_num, lcd_drv_init_num, "init_num");
      ChkNull(num, lcd_drv_num, "num");

      ChkNull(init, lcd_drv_init, "init");
      ChkNull(close, lcd_drv_close, "close");
      ChkNull(flush, lcd_drv_flush, "flush");
      ChkNull(flush_box, lcd_drv_flush_box, "flush_box");
      ChkNull(contrast, lcd_drv_contrast, "contrast");
      ChkNull(backlight, lcd_drv_backlight, "backlight");
      ChkNull(output, lcd_drv_output, "output");
      ChkNull(set_char, lcd_drv_set_char, "set_char");
      ChkNull(icon, lcd_drv_icon, "icon");
      ChkNull(init_vbar, lcd_drv_init_vbar, "init_vbar");
      ChkNull(init_hbar, lcd_drv_init_hbar, "init_hbar");
      ChkNull(draw_frame, lcd_drv_draw_frame, "draw_frame");

      ChkNull(getkey, lcd_drv_getkey, "getkey");
      ChkNull(getinfo, lcd_drv_getinfo, "getinfo");
      ChkNull(heartbeat, lcd_drv_heartbeat, "heartbeat");

      // Now check for base driver entries...;
      ChkBaseDrv(clear, lcd_drv_clear, "clear");
      ChkBaseDrv(string, lcd_drv_string, "string");
      ChkBaseDrv(chr, lcd_drv_chr, "chr");
      ChkBaseDrv(vbar, lcd_drv_vbar, "vbar");
      ChkBaseDrv(hbar, lcd_drv_hbar, "hbar");
      ChkBaseDrv(init_num, lcd_drv_init_num, "init_num");
      ChkBaseDrv(num, lcd_drv_num, "num");

      ChkBaseDrv(init, lcd_drv_init, "init");
      ChkBaseDrv(close, lcd_drv_close, "close");
      ChkBaseDrv(flush, lcd_drv_flush, "flush");
      ChkBaseDrv(flush_box, lcd_drv_flush_box, "flush_box");
      ChkBaseDrv(contrast, lcd_drv_contrast, "contrast");
      ChkBaseDrv(backlight, lcd_drv_backlight, "backlight");
      ChkBaseDrv(output, lcd_drv_output, "output");
      ChkBaseDrv(set_char, lcd_drv_set_char, "set_char");
      ChkBaseDrv(icon, lcd_drv_icon, "icon");
      ChkBaseDrv(init_vbar, lcd_drv_init_vbar, "init_vbar");
      ChkBaseDrv(init_hbar, lcd_drv_init_hbar, "init_hbar");
      ChkBaseDrv(draw_frame, lcd_drv_draw_frame, "draw_frame");

      ChkBaseDrv(getkey, lcd_drv_getkey, "getkey");
      ChkBaseDrv(getinfo, lcd_drv_getinfo, "getinfo");
      ChkBaseDrv(heartbeat, lcd_drv_heartbeat, "heartbeat");

      return 0;
}

/*
 * This function can be replaced later with something
 * that utilizes the results of dynamic library loading
 *
 */

int *
lcd_find_init (char *driver) {
      int i;

      if (!driver)
            return NULL;

      for (i = 0; drivers[i].name; i++) {
            if (strcasecmp(driver, drivers[i].name) == 0) {
                  return ((int *)*drivers[i].init);
            }
      }
      return NULL;
}

// TODO:  lcd_remove_driver()

struct lcd_logical_driver *
lcd_allocate_driver () {
      struct lcd_logical_driver *driver;
      //int driver_size;

      // This bit of fakery allows us to use lcd as the first
      // allocated buffer, which is what everything currently uses for
      // output in the main server code.

#define FirstTime (lcd_ptr->framebuf == NULL)

      if ((driver = malloc(sizeof(lcd_logical_driver))) == NULL) {
            syslog(LOG_ERR, "error allocating driver space!");
            return NULL;
      }

      if (lcd_root == NULL)
            lcd_root = driver;

      if (lcd_ptr == NULL)
            lcd_ptr = driver;

      return driver;
}

// This initializes the specified driver and sends parameters to
// it.  This is the function which calls, for example,
// MtxOrb_init.  The specifics come from the drivers[] array.

static char (*main_getkey) () = NULL;

int
lcd_add_driver (char *driver, char *args)
{
      int i;
      char buf[80];
      int (*init_driver) ();

      lcd_logical_driver *ptr = NULL;
      lcd_logical_driver *add = NULL;

      if (!driver)
            return -1;

      if ((init_driver = (void *) lcd_find_init(driver)) != NULL) {

            snprintf(buf, sizeof(buf), "adding %s driver", driver);
            syslog(LOG_INFO, buf);

            // This creates an instance of the lcd structure specific to the
            // driver... it is passed to the driver's init routine...

            if ((add = lcd_allocate_driver()) == NULL)
                  return -1;

            memset (add, 0, sizeof (lcd_logical_driver));

            // Default settings for the driver...
            lcd_drv_init(add, NULL);

            i = init_driver (add, args);

            if (!add->framebuf) {
                  if ((add->framebuf = malloc (add->wid * add->hgt)) == NULL) {
                        snprintf (buf, sizeof(buf), "couldn't allocate framebuffer of %d chars for driver \"%s\"",
                              (add->wid * add->hgt), driver);
                        syslog (LOG_ERR, buf);
                        // free (add);
                        return -1;
                  }
            }
            memset (add->framebuf, ' ', (add->wid * add->hgt));

            // Now patch up the returned driver structure
            // before returning
            lcd_drv_patch_init (add);     // patches drivers that think NULL is okay...

            if (main_getkey == NULL) {

                  // Patch the getkey with the getkey loop...
                  main_getkey = add->getkey;
                  add->getkey = lcd_drv_getkey_loop;
                  add->nextkey = NULL;

            } else {

                  // Tack additional drivers onto the getkey list...
                  ptr = lcd_root;
                  while (ptr->nextkey)
                        ptr = ptr->nextkey;

                  // ptr now points to a driver which contains
                  // a nextkey which is NULL... add the new
                  // driver in.
                  ptr->nextkey = add;
            }

            return i;
      } else {
            snprintf(buf, sizeof(buf), "invalid driver: %s", driver);
            syslog(LOG_ERR, buf);
      }
      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...
//
// The way it works is this:
//   It loops through the list of drivers, calling each one to keep
//      them all synchronized.  During this loop...
//   - First, set the framebuffer to point to the drivers' framebuffer.
//       (this ensures that whatever driver gets called will operate on
//        the correct buffer)
//   - Then, it checks to see what sort of call to make.
//       driver->func() > 0 means it should call the driver function.
//       driver->func() == NULL means it should not make a call.
//       driver->func() == -1 means it should call the generic driver.
//////////////////////////////////////////////////////////////////////

/*
 * The functions below are null functions which are used
 * when a particular driver does not set them.
 *
 */

// lcd_drv_close ()
// lcd_drv_clear ()
// lcd_drv_flush ()
// lcd_drv_string (int x, int y, char string[])
// lcd_drv_chr (int x, int y, char c)
// lcd_drv_contrast (int contrast)
// lcd_drv_backlight (int on)
// lcd_drv_output (int on)
// lcd_drv_init_vbar ()
// lcd_drv_init_hbar ()
// lcd_drv_init_num ()
// lcd_drv_num (int x, int num)
// lcd_drv_set_char (int n, char *dat)
// lcd_drv_vbar (int x, int len)
// lcd_drv_hbar (int x, int y, int len)
// lcd_drv_icon (int which, char dest)
// lcd_drv_flush_box (int lft, int top, int rgt, int bot)
// lcd_drv_draw_frame (char *dat)
// lcd_drv_getkey ()
// lcd_drv_getinfo ()

static void
lcd_drv_close ()
{
      ;
}

static void
lcd_drv_clear ()
{
      ;
}

static void
lcd_drv_flush ()
{
      ;
}

static void
lcd_drv_string (int x, int y, char *string)
{
      ;
}

static void
lcd_drv_chr (int x, int y, char c)
{
      ;
}

static int
lcd_drv_contrast (int contrast)
{
      return -1;
}

static void
lcd_drv_backlight (int on)
{
      ;
}

static void
lcd_drv_output (int on)
{
      ;
}

static void
lcd_drv_init_vbar ()
{
      ;
}

static void
lcd_drv_init_hbar ()
{
      ;
}

static void
lcd_drv_init_num ()
{
      ;
}

static void
lcd_drv_num (int x, int num)
{
      ;
}

static void
lcd_drv_set_char (int n, char *dat)
{
      ;
}

static void
lcd_drv_vbar (int x, int len)
{
      ;
}

static void
lcd_drv_hbar (int x, int y, int len)
{
      ;
}

static void
lcd_drv_icon (int which, char dest)
{
      ;
}

static void
lcd_drv_flush_box (int lft, int top, int rgt, int bot)
{
      ;
}

static void
lcd_drv_draw_frame (char *dat)
{
      ;
}

static char *
lcd_drv_getinfo ()
{
      return NULL;
}

static char
lcd_drv_getkey ()
{
      return 0;
}

// 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;
      char c;

      if ((c = main_getkey()) != 0)
            return c;

      driver = lcd_root;
      while ((driver = driver->nextkey) != NULL)
            if ((c = driver->getkey()) > 0)
                  return c;

      return 0;
}

static void
lcd_drv_heartbeat (int type)
{
      ;
}


Generated by  Doxygen 1.6.0   Back to index