Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

drivers.c

00001 /*
00002  *  drivers.c - Loading and managing the driver plugins.
00003  *              This file is part of the FreeLCD package.
00004  *
00005  *  $Id: drivers_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 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <syslog.h>
00030 
00031 #include <common/xmalloc.h>
00032 #include <common/xmlt.h>
00033 #include <drivers/backend.h>
00034 
00035 #include "ltdl.h"
00036 #include "drivers.h"
00037 
00038 #ifndef FLCDD_MODULE_PATH_ENV
00039 #  define FLCDD_MODULE_PATH_ENV "FLCDD_MODULE_PATH"
00040 #endif
00041 
00042 typedef enum { DRIVER = 0, BACKEND = 1 } tag_idx;
00043 typedef enum { NAME = 0 } attr_idx;
00044 
00045 static tag_idx tag_array[] = { DRIVER, BACKEND };
00046 static attr_idx attr_array[] = { NAME };
00047 
00048 static dict_pair tag_translate[] = {
00049     { "backend", &tag_array[BACKEND] },
00050     { "driver", &tag_array[DRIVER] }
00051 };
00052 
00053 static dict_pair attr_translate[] = {
00054     { "name", &attr_array[NAME] }
00055 };
00056 
00057 static dictionary tag_dict = { tag_translate, 2 };
00058 static dictionary attr_dict = { attr_translate, 1 };
00059 
00060 typedef struct
00061 {
00062   void        *drv_handle;
00063   void        *backend_handle;
00064   void        (*destroy_handle)(void *handle);
00065   const char *(*get_info)(const char *field);
00066   void        (*process_canvas)(void *handle, void *canvas);
00067 }
00068 driver_info;
00069 
00070 
00071 static int
00072 _ltdl_error ()
00073 {
00074   syslog (LOG_ERR, "libtool init failed: %s\n", lt_dlerror ());
00075 
00076   return -1;
00077 }
00078 
00079 static void *
00080 _module_error ()
00081 {
00082   syslog (LOG_ERR, "loading plug-in failed: %s\n", lt_dlerror ());
00083 
00084   return 0;
00085 }
00086 
00087 static void *
00088 _create_failed (void *backend)
00089 {
00090   backend_free_handle (backend);
00091   return 0;
00092 }
00093 
00094 int
00095 drivers_init ()
00096 {
00097   static int initialized = 0;
00098   const char *path = 0;
00099 
00100   if (initialized)
00101     return 0;
00102 
00103   /* Tell libtool to use our xmalloc() for allocating memory */
00104   lt_dlmalloc = (lt_ptr(*)(size_t)) xmalloc;
00105 
00106   /* Preload anything, if necessary */
00107   /* LTDL_SET_PRELOADED_SYMBOLS(); */
00108 
00109   if (lt_dlinit () != 0)
00110     return _ltdl_error ();
00111 
00112   path = getenv (FLCDD_MODULE_PATH_ENV);
00113   if (path && lt_dlsetsearchpath (path) != 0)
00114     return _ltdl_error ();
00115 
00116   lt_dladdsearchdir (MODULE_PATH);
00117   initialized = 1;
00118 
00119   return 0;
00120 }
00121 
00122 void *
00123 drivers_create_output (xml_node *config)
00124 {
00125   typedef void*(ch_func)(xml_node *);
00126   typedef void(bb_func)(void *, void *);
00127   typedef void(dh_func)(void *);
00128   typedef const char *(gi_func)(const char *);
00129 
00130   driver_info *info = xmalloc (sizeof (driver_info));
00131   ch_func*   create_handle;
00132   bb_func*   bind_backend;
00133 
00134   void       *backend;
00135   void       *driver;
00136   const char *backend_name;
00137   const char *driver_name;
00138   xml_node   *found;
00139   lt_dlhandle module;
00140 
00141   xmlt_rescan_document (config, &tag_dict, &attr_dict);
00142   
00143   found = xmlt_find (config, 0, BACKEND);
00144   if (!found)
00145     return 0;
00146 
00147   backend_name = xmlt_get_attrib (found, NAME);
00148   backend = backend_create_handle (found, backend_name);
00149   if (!backend)
00150     return 0;
00151 
00152   found = xmlt_find (config, 0, DRIVER);
00153   if (!found)
00154     return _create_failed (backend);
00155 
00156   driver_name = xmlt_get_attrib (found, NAME);
00157   if (!driver_name)
00158     return _create_failed (backend);
00159 
00160   module = lt_dlopenext (driver_name);
00161   if (!module)
00162     return _module_error ();
00163   
00164   create_handle = (ch_func*)lt_dlsym (module, "drv_create_handle");
00165   if (!create_handle)
00166     return _module_error();
00167 
00168   bind_backend   = (bb_func*)lt_dlsym (module, "drv_bind_backend");
00169   if (!bind_backend)
00170     return _module_error();
00171   
00172   driver = create_handle (found);
00173   if (!driver)
00174     return _create_failed (backend);
00175 
00176   info->drv_handle  = driver;
00177   info->backend_handle = backend;
00178   info->destroy_handle = (dh_func*)lt_dlsym (module, "drv_destroy_handle");
00179   info->get_info       = (gi_func*)lt_dlsym (module, "drv_get_info");
00180   info->process_canvas = (bb_func*)lt_dlsym (module, "drv_process_canvas");
00181 
00182   bind_backend (driver, backend);
00183 
00184   return info;  
00185 }
00186 
00187 void
00188 drivers_process_canvas (void *info_, cc_canvas *canvas)
00189 {
00190   driver_info *info = info_;
00191 
00192   info->process_canvas (info->drv_handle, canvas);
00193 }
00194 

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