Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

backend.c

00001 /*
00002  *  backend.c - Different backends that can be used by the drivers.
00003  *              This file is part of the FreeLCD package.
00004  *
00005  *  $Id: backend_8c-source.html,v 1.1 2003/02/16 22:50:41 unicorn Exp $
00006  *
00007  *  This program is free software; you can redistribute it and/or modify it
00008  *  under the terms of the GNU General Public License as published by the
00009  *  Free Software Foundation; either version 2 of the License, or (at your
00010  *  option) any later version.
00011  * 
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00020  *  MA  02111-1307  USA
00021  *
00022  *  Copyright (c) 2002, 2003, Jeroen van den Berg <unicorn@hippie.nu>
00023  */
00024 
00025 #include <string.h>
00026 #include <termios.h>
00027 #include <unistd.h>
00028 #include <curses.h>
00029 #include <fcntl.h>
00030 
00031 #include "backend.h"
00032 
00033 #ifndef HAVE_CFMAKERAW
00034 # define HAVE_CFMAKERAW 0
00035 #endif
00036 
00037 
00038 typedef enum
00039 {
00040   NAME = 0, WIDTH, HEIGHT, DEVICE, BAUDRATE
00041 }
00042 tag_e;
00043 
00044 tag_e tag[] =
00045 {
00046   NAME, WIDTH, HEIGHT, DEVICE, BAUDRATE
00047 }; 
00048 
00049 dict_pair tag_dict[] =
00050 {
00051     { "baudrate", &tag[BAUDRATE] },
00052     { "device", &tag[DEVICE] },
00053     { "height", &tag[HEIGHT] },
00054     { "name", &tag[NAME] },
00055     { "width", &tag[WIDTH] }
00056 };
00057 
00058 dictionary tags = 
00059 {
00060   tag_dict, 5
00061 };
00062 
00063 
00064 
00065 typedef struct
00066 {
00067   int opened;
00068   void *dev_handle;
00069   int (*send_func) (void *, const char *, size_t);
00070   void (*close_func) (void *);
00071 }
00072 bck_handle;
00073 
00074 typedef struct
00075 {
00076   WINDOW *cont;
00077   WINDOW *border;
00078 }
00079 cursd;
00080 
00081 
00082 /* ===================
00083  *  SERIAL
00084  * =================== 
00085  */
00086 
00087 /*-------------------------------------------------------- _send_serial --*/
00088 static int
00089 _send_serial (void *h, const char *data, size_t len)
00090 {
00091   size_t result;
00092 
00093   while (len > 0)
00094     {
00095       result = write (*(int *) h, data, len);
00096       if (result < 0)
00097         return 0;
00098 
00099       len -= result;
00100     }
00101   return 1;
00102 }
00103 
00104 /*------------------------------------------------------- _close_serial --*/
00105 static void
00106 _close_serial (void *h) 
00107 { 
00108   close (*(int *) h);
00109 }
00110 
00111 /*-------------------------------------------------------- _open_serial --*/
00112 static void
00113 _open_serial (bck_handle * h, xml_node *config)
00114 {
00115   struct termios portset;
00116   const char* baud = 0;
00117   const char* device = "/dev/ttyS0";
00118   xml_node *node;
00119   int _baudrate;
00120   int fd;
00121   
00122   node = xmlt_find (config, 0, DEVICE);
00123   if (node)
00124     device = xmlt_get_first_cdata (node);
00125   
00126   node = xmlt_find (config, 0, BAUDRATE);
00127   if (node)
00128     baud = xmlt_get_first_cdata (node);
00129   
00130   fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY);
00131   if (fd < 0)
00132     return;
00133 
00134   if (baud == 0)
00135     _baudrate = B9600; /* No baudrate specified, 9600 is a nice default. */
00136   else
00137     {
00138       switch (atoi (baud))
00139         {
00140         case 600:
00141           _baudrate = B600;
00142           break;
00143         case 1200:
00144           _baudrate = B1200;
00145           break;
00146         case 1800:
00147           _baudrate = B1800;
00148           break;
00149         case 2400:
00150           _baudrate = B2400;
00151           break;
00152         case 4800:
00153           _baudrate = B4800;
00154           break;
00155         case 9600:
00156           _baudrate = B9600;
00157           break;
00158         case 19200:
00159           _baudrate = B19200;
00160           break;
00161         case 38400:
00162           _baudrate = B38400;
00163           break;
00164         case 57600:
00165           _baudrate = B57600;
00166           break;
00167         case 115200:
00168           _baudrate = B115200;
00169           break;
00170         case 230400:
00171           _baudrate = B230400;
00172           break;
00173         default:
00174           _baudrate = B9600;
00175           break;
00176         }
00177     }
00178 
00179   /* Set the serial port to raw mode */
00180   tcgetattr (fd, &portset);
00181 
00182 #if HAVE_CFMAKERAW
00183   cfmakeraw (&portset);
00184 #else
00185   portset.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
00186                        | INLCR | IGNCR | ICRNL | IXON);
00187   portset.c_oflag &= ~OPOST;
00188   portset.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
00189   portset.c_cflag &= ~(CSIZE | PARENB);
00190   portset.c_cflag |= CS8 | CREAD | CLOCAL;
00191 #endif
00192 
00193   /* Set baudrate */
00194   cfsetospeed (&portset, _baudrate);
00195   cfsetispeed (&portset, B0);
00196   tcsetattr (fd, TCSANOW, &portset);
00197 
00198   h->dev_handle = 0;
00199   h->send_func = _send_serial;
00200   h->close_func = _close_serial;
00201   h->dev_handle = malloc (sizeof (int));
00202   if (h->dev_handle == 0)
00203     exit (EXIT_FAILURE);
00204 
00205   *((int *) h->dev_handle) = fd;
00206   h->opened = 1;
00207 }
00208 
00209 
00210 
00211 /* ===================
00212  *  CURSES
00213  * =================== 
00214  */
00215 
00216 /*-------------------------------------------------------- _send_curses --*/
00217 static int
00218 _send_curses (void *h, const char *data, size_t len)
00219 {
00220   cursd *x = h;
00221 
00222   waddnstr (x->cont, data, len);
00223   touchwin (x->cont);
00224   wrefresh (x->cont);
00225 
00226   return 1;
00227 }
00228 
00229 /*------------------------------------------------------- _close_curses --*/
00230 static void
00231 _close_curses (void *h)
00232 {
00233   cursd *x = h;
00234 
00235   delwin (x->border);
00236   delwin (x->cont);
00237   endwin ();
00238   curs_set (1);
00239 }
00240 
00241 /*-------------------------------------------------------- _open_curses --*/
00242 static void
00243 _open_curses (bck_handle *h, xml_node *config)
00244 {
00245   cursd *x;
00246   int width = 20;
00247   int height = 4;
00248   int wx;
00249   int wy;
00250   const char *num; 
00251   xml_node *node;
00252 
00253   num = 0;
00254   node = xmlt_find (config, 0, WIDTH);
00255   if (node)
00256     num = xmlt_get_first_cdata (node);
00257   
00258   if (num)
00259     width = atoi (num);
00260 
00261   num = 0;
00262   node = xmlt_find (config, 0, HEIGHT);
00263   if (node)
00264     num = xmlt_get_first_cdata (node);
00265   
00266   if (num)
00267     height = atoi (num);
00268   
00269   x = malloc (sizeof (cursd));
00270   if (x == 0)
00271     exit (EXIT_FAILURE);
00272 
00273   if (initscr () == 0)
00274       return;
00275 
00276   wy = 12 - (height / 2);
00277   wx = 40 - (width / 2);
00278   x->cont = newwin (height, width, wy, wx);
00279   x->border = newwin (height + 2, width + 4, wy - 1, wx - 2);
00280   
00281   if (   x->cont == 0 
00282       || x->border == 0
00283       || nonl() == ERR
00284       || noecho() == ERR
00285       || curs_set (0) == ERR)
00286     {
00287       free (x);
00288       endwin ();
00289       return;
00290     }
00291 
00292   box (x->border, 0, 0);
00293   scrollok (x->cont, 0);
00294   touchwin (x->border);
00295   wrefresh (x->border);
00296 
00297   h->dev_handle = x;
00298   h->send_func = _send_curses;
00299   h->close_func = _close_curses;
00300   h->opened = 1;
00301 }
00302 
00303 
00304 /*---------------------------------------------- backend_create_handle --*/
00305 void *
00306 backend_create_handle (xml_node *config, const char* type)
00307 {
00308   bck_handle *h = malloc (sizeof (bck_handle));
00309 
00310   if (h == 0)
00311     exit (EXIT_FAILURE);
00312 
00313   if (type == 0)
00314     return 0;
00315 
00316   h->opened = 0;
00317   h->dev_handle = 0;
00318 
00319   xmlt_rescan_document (config, &tags, 0);
00320   
00321   if (!strcmp ("serial", type))
00322     _open_serial (h, config);
00323 
00324   else if (!strcmp ("curses", type))
00325     _open_curses (h, config);
00326   
00327   return (void *) h;
00328 }
00329 
00330 /*-------------------------------------------------------- backend_send --*/
00331 int
00332 backend_send (void *handle, const char *data, size_t len)
00333 {
00334   bck_handle *h = (bck_handle *) handle;
00335 
00336   if (!h->opened)
00337     return -1;
00338 
00339   return h->send_func (h->dev_handle, data, len);
00340 }
00341 
00342 /*----------------------------------------------- backend_free_handle --*/
00343 void
00344 backend_free_handle (void *handle)
00345 {
00346   bck_handle *h = (bck_handle *) handle;
00347 
00348   if (h->opened)
00349     h->close_func (h->dev_handle);
00350 
00351   free (h->dev_handle);
00352   free (h);
00353 }

Generated on Sun Feb 16 23:39:49 2003 for FreeLCD by doxygen1.2.18