Logo Search packages:      
Sourcecode: vertex version File versions

vpiinternal.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <gtk/gtk.h>

#if defined(__linux__) || defined(__SOLARIS__)
# include <dlfcn.h>
#endif

#include "../include/string.h"
#include "../include/disk.h"

#include "splash.h"
#include "vpi.h"
#include "vpiinternal.h"
#include "vma.h"
#include "vmapixmaps.h"
#include "config.h"


static void *VPILoadOSPlugin(const char *filename, int *error_code);
static void *VPIGetOSPluginFunction(void *handle, const char *name);
static void VPIUnloadOSPlugin(void *handle);
static void VPITouch(vma_plugin_struct *pi); 

const char *VPIGetOSLoadError(void);

int VPIEnable(vma_plugin_struct *pi);
int VPIDisable(vma_plugin_struct *pi);
void *VPIGetFunction(vma_plugin_struct *pi, const char *name);
vma_plugin_struct *VPILoad(
      const char *filename,
      int load_as_disabled,
      int *error_code,
      void *core_ptr
);
void VPIUnload(vma_plugin_struct *pi);

int VPILoadPluginsFromDirectory(
        vma_plugin_struct ***plugin, int *total_plugins,
        const char *path,
        int load_as_disabled,
      int is_global,
      void *core_ptr,
      splash_win_struct *splash_win
);
int VPICListUpdateRow(
        GtkCList *clist, gint row, vma_plugin_struct *plugin_ptr
);
int VPICListAppend(
      GtkCList *clist,
      vma_plugin_struct **plugin, int total_plugins
);

int VPIDoGetInfo(vma_plugin_struct *plugin_ptr);
int VPIDoOpConfigurationChanged(vma_plugin_struct *plugin_ptr);


/* Global plugin load error message, this is updated when
 * VPILoadOSPlugin() is called. If it is not NULL then that implies an
 * error occured.
 */
static const char *plugin_os_load_error_message = NULL;


/*
 *    Operating system specific call to load the plug-in binary
 *    specified by filename. The given filename must be an
 *    absolute path.
 *
 *      If error_code is not NULL, then it will be set to one of
 *      the following values:
 *
 *      0       Success
 *      -1      General error
 *      -2      Cannot find plug-in binary
 *      -3      Cannot find required functions in plug-in binary
 *      -4      Plug-in load failed.
 *    -5    Platform does not support plug-ins.
 */
static void *VPILoadOSPlugin(const char *filename, int *error_code)
{
      /* Reset global error message pointer. */
      plugin_os_load_error_message = NULL;

      /* Reset returns. */
      if(error_code != NULL)
          (*error_code) = -5;

      if(filename == NULL)
          return(NULL);

#if defined(__linux__) || defined(__SOLARIS__)
      {
          void *handle;
          const char *error_strptr = NULL;
          struct stat stat_buf;


          /* Must be absolute path on Linux or Solaris. */
          if((*filename) != '/')
            {
                if(error_code != NULL)
                    (*error_code) = -2;
            return(NULL);
          }

          /* Check if it exists. */
          if(stat(filename, &stat_buf))
          {
            if(error_code != NULL)
                (*error_code) = -2;
            return(NULL);
          }
          /* Is it a directory? */
          if(S_ISDIR(stat_buf.st_mode))
          {
                if(error_code != NULL)
                    (*error_code) = -1;
                return(NULL);
          }

          /* Attempt to open shared object file. */
          handle = dlopen(filename, RTLD_LAZY);
          if(handle == NULL)
            {
                if(error_code != NULL)
                    (*error_code) = -4;
                return(NULL);
            }
          /* Double check for error. */
          plugin_os_load_error_message = error_strptr = dlerror();
          if(error_strptr != NULL)
          {
            /* Be safe and discard handle if dlerror() says otherwise. */
            handle = NULL;

                if(error_code != NULL)
                    (*error_code) = -4;

                return(NULL);
            }


          /* Load success, return the handle. */
            if(error_code != NULL)
                (*error_code) = 0;

          return(handle);
      }
#endif      /* __linux__ or __SOLARIS__ */

      return(NULL);
}

/*
 *    Operating system specific call to find function pointer
 *    that matches the given function name.
 *
 *    Returns NULL on failure.
 */
static void *VPIGetOSPluginFunction(void *handle, const char *name)
{
      if((handle == NULL) || (name == NULL))
          return(NULL);

#if defined(__linux__) || defined(__SOLARIS__)
        {
          void *func_ptr = NULL;
          char *dname;


          /* According to Linux and Solaris man page for dlsym(), we need
           * to make a dynamic copy of the function name before passing
           * to dlsym().
           */
          dname = strdup(name);
          if(dname != NULL)
          {
            const char *error_strptr = NULL;

            func_ptr = dlsym(handle, dname);

            /* Check if there was an error in dlsym(). According
             * to the manual, dlsym() may not return NULL if it
             * actually ment NULL, here's the excerpt:

       dlsym  takes  a  "handle" of a dynamic library returned by
       dlopen and the null terminated symbol name, returning  the
       address where that symbol is loaded.  If the symbol is not
       found, dlsym returns NULL; however,  the  correct  way  to
       test  for  an  error  from  dlsym is to save the result of
       dlerror into a variable, and then check if saved value  is
       not  NULL.   This is because the value of the symbol could
       actually be NULL.   It  is  also  necessary  to  save  the
       results  of  dlerror into a variable because if dlerror is
       called again, it will return NULL.

             */
            error_strptr = dlerror();
            if(error_strptr != NULL)
                func_ptr = NULL;

            free(dname);
            dname = NULL;
          }
          return(func_ptr);
        }
#endif  /* __linux__ or __SOLARIS__ */

      return(NULL);
}

/*
 *    Operating system specific call to unload plug-in.
 */
static void VPIUnloadOSPlugin(void *handle)
{
      if(handle == NULL)
          return;

#if defined(__linux__) || defined(__SOLARIS__)
      {
          const char *error_strptr;


          dlclose(handle);
          handle = NULL;      /* Mark that plug-in was unloaded. */

          error_strptr = dlerror(); /* Just to be formal and sync in case. */
      }
#endif      /* __linux__ or __SOLARIS__ */
}

/*
 *    Updates the plug-in's last used time to the current time.
 */
static void VPITouch(vma_plugin_struct *pi)
{
      if(pi != NULL)
      {
          pi->time_last_used = (time_t)time(NULL);
      }
}


/*
 *    Returns a statically allocated string containing the last error
 *    from a call to VPIEnable() or VPILoad(). Can return NULL if no
 *    error occured.
 */
const char *VPIGetOSLoadError(void)
{
      return(plugin_os_load_error_message);
}

/*
 *    Loads the actual plug-in binary as needed.
 *
 *    The need_call_init will be set to true and need_call_shutdown will
 *    be set to false if a new binary is loaded.
 *
 *    Returns the following:
 *
 *      0       Success or already laoded
 *      -1      General error
 *      -2      Cannot find plug-in binary
 *      -3      Cannot find required functions in plug-in binary
 *      -4      Plug-in load failed.
 *      -5      Platform does not support plug-ins.
 */
int VPIEnable(vma_plugin_struct *pi)
{
      int error_code = 0;

      if(pi == NULL)
          return(-1);

      /* Already loaded? */
      if(pi->handle != NULL)
          return(0);

      /* No filename available? */
      if(pi->filename == NULL)
          return(-1);

      /* Load plugin binary. */
      pi->handle = VPILoadOSPlugin(pi->filename, &error_code);
      if(pi->handle != NULL)
      {
          /* Loaded successfully, update some values and return
           * success.
           */
          pi->processing = 0;
          pi->need_call_init = 1;
          pi->need_call_shutdown = 0;
          pi->manage = VPIGetFunction(pi, VPI_PROTO_NAME_MANAGE);
          VPITouch(pi);
          return(0);
      }
      else
      {
          /* Load failed, return error code from VPILoadOSPlugin(). */
          return(error_code);
      }
}

/*
 *    Unloads the actual plug-in binary if it is loaded.
 *
 *    If pi->need_call_shutdown is true then the shutdown function
 *    will be called before unloading.
 */
int VPIDisable(vma_plugin_struct *pi)
{
      void *handle;


      if(pi == NULL)
          return(-1);

      /* Call shutdown function as needed. */
      handle = pi->handle;
        if((handle != NULL) && pi->need_call_shutdown)
        {
            vpi_shutdown_struct v;
            VPI_PROTO_RETURN_SHUTDOWN (*shutdown_func)(VPI_PROTO_INPUT_SHUTDOWN) =
                VPIGetOSPluginFunction(handle, VPI_PROTO_NAME_SHUTDOWN);
            if(shutdown_func != NULL)
            {
                v.flags =       VPI_FLAG_SHUTDOWN_REASON |
                                VPI_FLAG_SHUTDOWN_CLIENT_DATA;
                v.reason = VPI_SHUTDOWN_REASON_NORMAL_REQUEST;
                v.client_data = pi->client_data;

                pi->processing = 1;
                shutdown_func((vpi_id *)pi, &v);
            pi->processing = 0;
            }
            pi->need_call_shutdown = 0;
        }

      /* Unload plug-in. */
      if(pi->handle != NULL)
      {
            VPIUnloadOSPlugin(pi->handle);
            pi->handle = NULL;
          VPITouch(pi);
      }

      /* Reset some other values. */
      pi->processing = 0;
      pi->need_call_init = 0;
      pi->need_call_shutdown = 0;
      pi->manage = NULL;

      pi->null = NULL;
      pi->null_data = NULL;

      pi->import = NULL;
      pi->import_data = NULL;
      pi->import_fcheck = NULL;

      pi->export = NULL;
      pi->export_data = NULL;

      pi->render = NULL;
      pi->render_data = NULL;

        pi->configure = NULL;
        pi->configure_data = NULL;

      pi->configuration_changed = NULL;
      pi->configuration_changed_data = NULL;

      return(0);
}

/*
 *    Returns the pointer to the function specified by name or
 *    NULL on error.
 */
void *VPIGetFunction(vma_plugin_struct *pi, const char *name)
{
      if(pi == NULL)
          return(NULL);

      return(VPIGetOSPluginFunction(pi->handle, name));
}

/*
 *    Loads the plug-in binary specified by filename, returns an
 *    allocated vma_plugin_struct. The return value must be deallocated
 &    by calling VPIUnload().
 *
 *    If error_code is not NULL, then it will be set to one of
 *    the following values:
 *
 *    0     Success
 *    -1    General error
 *    -2    Cannot find plug-in binary
 *    -3    Cannot find required functions in plug-in binary
 *    -4    Plug-in load failed.
 *    -5    Platform does not support plug-ins.
 *
 *    If load_as_disabled is true then a vma_plugin_struct will be
 *    returned but the member handle will be set to NULL. Indicating
 *    that the actual plug-in binary file was not loaded.
 */
vma_plugin_struct *VPILoad(
      const char *filename,
      int load_as_disabled,
      int *error_code,
      void *core_ptr
)
{
      vma_plugin_struct *pi = (vma_plugin_struct *)calloc(
          1, sizeof(vma_plugin_struct)
      );

      if(error_code != NULL)
          (*error_code) = -1;

      if(pi != NULL)
      {
          void *handle;
          struct stat stat_buf;

          if(load_as_disabled)
          {
            handle = NULL;
            if(error_code != NULL)
                (*error_code) = 0;
          }
          else
          {
            /* Attempt to load plug-in, error_code will be updated
             * accordingly.
             */
            handle = VPILoadOSPlugin(filename, error_code);
            if(handle == NULL)
            {
                VPIUnload(pi);
                return(NULL);
            }
            VPITouch(pi);
          }

          /* Set values to loaded plug-in structure. */
          pi->handle = handle;
          pi->core_ptr = core_ptr;
          pi->filename = strdup(filename);

          pi->processing = 0;
          pi->need_call_init = 1;
          pi->need_call_shutdown = 0;
            pi->manage = VPIGetFunction(pi, VPI_PROTO_NAME_MANAGE);

          if(stat(filename, &stat_buf))
                pi->time_installed = 0;
          else
            pi->time_installed = stat_buf.st_mtime;

          pi->title = NULL;
          pi->description = NULL;
          pi->list_icon_data = NULL;
          pi->list_icon_lines = 0;
            pi->icon_pixmap = NULL;
            pi->icon_mask = NULL;


          /* Plug-in loaded successfully. */
          if(error_code != NULL)
            *error_code = 0;
      }
      return(pi);
}

/*
 *    Unloads the given plug-in.
 *
 *    The given structure pi should not be referenced again after
 *    this call.
 *
 *    If the plugin is already loaded and pi->need_call_shutdown is
 *    true, then the shutdown function on the plug-in will be called
 *    just before unloading.
 */
void VPIUnload(vma_plugin_struct *pi)
{
      int i;
      void *handle;


      if(pi == NULL)
          return;

      /* Check if plug-in is currently loaded and call shutdown
       * function.
       */
      handle = pi->handle;
      if((handle != NULL) && pi->need_call_shutdown)
      {
          vpi_shutdown_struct v;
          VPI_PROTO_RETURN_SHUTDOWN (*shutdown_func)(VPI_PROTO_INPUT_SHUTDOWN) =
            VPIGetOSPluginFunction(handle, VPI_PROTO_NAME_SHUTDOWN);
          if(shutdown_func != NULL)
          {
            v.flags =   VPI_FLAG_SHUTDOWN_REASON |
                        VPI_FLAG_SHUTDOWN_CLIENT_DATA;
            v.reason = VPI_SHUTDOWN_REASON_NORMAL_REQUEST;
            v.client_data = pi->client_data;

                pi->processing = 1;
            shutdown_func((vpi_id *)pi, &v);
                pi->processing = 0;
          }
          pi->need_call_shutdown = 0;
      }

      /* Unload plug-in. */
      if(pi->handle != NULL)
      {
          VPIUnloadOSPlugin(pi->handle);
          pi->handle = NULL;
          VPITouch(pi);
      }


      /* Begin deallocating resources. */

      /* File name. */
        free(pi->filename); 
        pi->filename = NULL;

      /* Appearance resources. */
      /* Title. */
      free(pi->title);
      pi->title = NULL;
      /* Description. */
      free(pi->description);
      pi->description = NULL;
      /* Standard list XPM icon data. */
      for(i = 0; i < pi->list_icon_lines; i++)
          free(pi->list_icon_data[i]);
      free(pi->list_icon_data);
      pi->list_icon_data = NULL;
      pi->list_icon_lines = 0;
      /* Standard list icon pixmap and mask. */
      if(pi->icon_pixmap != NULL)
      {
          gdk_pixmap_unref(pi->icon_pixmap);
          pi->icon_pixmap = NULL;
      }
      if(pi->icon_mask != NULL)
      {
          gdk_bitmap_unref(pi->icon_mask);
          pi->icon_mask = NULL;
      }


      /* Begin deallocating operation callback resources. */

      /* Import file types. */
      for(i = 0; i < pi->total_import_ftypes; i++)
      {
          free(pi->import_ftype_ext[i]);
          free(pi->import_ftype_name[i]);
      }
      free(pi->import_ftype_ext);
      pi->import_ftype_ext = NULL;
      free(pi->import_ftype_name);
      pi->import_ftype_name = NULL;
      pi->total_import_ftypes = 0;

      /* Export file types. */
      for(i = 0; i < pi->total_export_ftypes; i++)
      {
          free(pi->export_ftype_ext[i]);
          free(pi->export_ftype_name[i]);
      }
      free(pi->export_ftype_ext);
      pi->export_ftype_ext = NULL;
      free(pi->export_ftype_name);
      pi->export_ftype_name = NULL;
      pi->total_export_ftypes = 0;

      /* Render. */
      free(pi->render_label);
      pi->render_label = NULL;

      /* Deallocate the structure itself. */
      free(pi);
}



/*
 *    Loads a list of plug-ins from the specified directory path.
 *
 *    The new plug-ins will be appended to the given list.
 *
 *    Returns non-zero on error.
 */
int VPILoadPluginsFromDirectory(
        vma_plugin_struct ***plugin, int *total_plugins,
      const char *path,
      int load_as_disabled,
      int is_global,
      void *core_ptr,
        splash_win_struct *splash_win
)
{
      gchar **strv;
      gint i, n, strc;
      const gchar *cstrptr;
      gchar tmp_path[PATH_MAX + NAME_MAX];


      if((path == NULL) || (plugin == NULL) || (total_plugins == NULL))
          return(-1);

      if((*total_plugins) < 0)
          (*total_plugins) = 0;

      /* Get directory listing. */
      strv = GetDirEntNames(path);
      if(strv != NULL)
      {
          /* Count number of directory entries. */
          for(strc = 0; strv[strc] != NULL; strc++);
      }
      else
      {
          strc = 0;
      }

      /* Sort listing. */
      StringQSort(strv, strc);

      /* Itterate through directory entries. */
      for(i = 0; i < strc; i++)
      {
          /* Get directory entry. */
          cstrptr = (const char *)strv[i];
          if(cstrptr == NULL)
            continue;

          /* Check for special directory notations. */
          /* Current or previous directory? */
          if(!strcmp(cstrptr, ".") ||
               !strcmp(cstrptr, "..")
          )
          {
            /* Skip. */
          }
          /* Regular directory entry. */
          else
          {
            const gchar *cstrptr2 = PrefixPaths(path, cstrptr);
            if(cstrptr2 != NULL)
            {
                gint error_code;
                vma_plugin_struct *plugin_ptr;

                strncpy(tmp_path, cstrptr2, PATH_MAX + NAME_MAX);
                tmp_path[PATH_MAX + NAME_MAX - 1] = '\0';

                /* Attempt to load plug-in, skip errors (ie if
                 * it was a directory.
                 */
                plugin_ptr = VPILoad(
                  tmp_path, load_as_disabled, &error_code,
                  core_ptr
                );
                if(plugin_ptr != NULL)
                {
                  /* Loaded successfully, allocate more pointers
                   * in the plug-ins list.
                   */
                  n = (*total_plugins);
                  (*total_plugins) = n + 1;
                        (*plugin) = (vma_plugin_struct **)realloc(
                      *plugin,
                      (*total_plugins) * sizeof(vma_plugin_struct *)
                  );
                  if((*plugin) == NULL)
                  {
                      (*total_plugins) = 0;
                  }
                  else
                  {
                      (*plugin)[n] = plugin_ptr;

                      /* Global global mark if is_global is true. */
                      plugin_ptr->global = ((is_global) ? 1 : 0);
                  }
                }
            }
          }

          /* Update splash window? */
          if(splash_win != NULL)
          {
            gint len = strlen(cstrptr) + 80;
            gchar *buf;


            buf = (gchar *)g_malloc(len);
            if(buf != NULL)
                sprintf(
                  buf,
                  "Loading Plug-In `%s'...",
                  cstrptr
                );

            SplashUpdate(
                splash_win,
                    0, (gdouble)(i + 1) / (gdouble)strc,
                    buf,
                    TRUE
                );

            g_free(buf);
          }

          /* Deallocate directory entry. */
          free(strv[i]);
          strv[i] = NULL;
          cstrptr = NULL;
      }

      /* Deallocate pointer array for directory entries. */
      if(strv != NULL)
      {
          free(strv);
          strv = NULL;
          strc = 0;
      }

      return(0);
}


/*
 *    Updates a row on the given clist with respect to the specified
 *    plug-in.
 */
int VPICListUpdateRow(
      GtkCList *clist, gint row, vma_plugin_struct *plugin_ptr
)
{
      gint columns;


      if((clist == NULL) || (plugin_ptr == NULL))
          return(-1);

      if((row < 0) || (row >= clist->rows))
          return(-1);

      columns = clist->columns;

      gtk_clist_set_row_data(clist, row, plugin_ptr);

      /* File name column exists? */
      if(columns > 0)
      {
          const gchar *cstrptr, *cstrptr2;
          gchar *strptr;

          /* Get file name (without parent path). */
          cstrptr = (const gchar *)((plugin_ptr->filename == NULL) ?
            "(null)" : plugin_ptr->filename
          );
          cstrptr2 = (const gchar *)strrchr(
            cstrptr, DIR_DELIMINATOR
          );
          if(cstrptr2 != NULL)
            cstrptr2++;
          else
            cstrptr2 = cstrptr;

          /* Make a copy. */
          strptr = g_strdup(cstrptr2);

          /* List icon available? */
            if(plugin_ptr->icon_pixmap != NULL)
                gtk_clist_set_pixtext(
                    clist,
                    row, 0,
                    strptr,
                    VMA_LIST_PIXMAP_TEXT_SPACING,
                    plugin_ptr->icon_pixmap,
                    plugin_ptr->icon_mask
                );
          else
                gtk_clist_set_text(
                    clist, 
                    row, 0,
                    strptr
                );

          /* Deallocate coppied file name. */
          g_free(strptr);
      }

      /* Title column exists? */
      if(columns > 1)
      {
          gchar *strptr = g_strdup((plugin_ptr->title == NULL) ?
            "Untitled" : plugin_ptr->title
            );
          gtk_clist_set_text(
            clist, row, 1, strptr
          );
          g_free(strptr);
      }

      /* Enabled/disabled state column exists? */
        if(columns > 2)
        {
          GdkPixmap *pixmap;
          GdkBitmap *mask;
          gint icon_num;


          icon_num = ((plugin_ptr->handle == NULL) ?
            VMA_PIXMAP_PLUGIN_DISABLED_20x20 :
            VMA_PIXMAP_PLUGIN_ENABLED_20x20
          );

          VMAPixmapsListGetValues(
            &vma_pixmaps_list, icon_num,
            &pixmap, &mask, NULL
          );
          if(pixmap != NULL)
                gtk_clist_set_pixmap(
                    clist,
                    row, 2,
                    pixmap, mask
                );
      }

        /* Local/global column exists? */
        if(columns > 3)
        {
            gchar *strptr = g_strdup((plugin_ptr->global) ?
                "G" : "L"
            );   
            gtk_clist_set_text(
                clist, row, 3, strptr
            );
            g_free(strptr);
        }
 
      return(0);
}

/*
 *    Appends a list of new rows to the clist given by the list of
 *    plugins.
 */
int VPICListAppend(
        GtkCList *clist,
        vma_plugin_struct **plugin, int total_plugins
)
{
      gint i, n, row, columns;
      gchar **val;
      vma_plugin_struct *plugin_ptr;


      if((clist == NULL) || (plugin == NULL) || (total_plugins <= 0))
          return(-1);

      /* Allocate clist row value array for each column. */
      columns = clist->columns;
      if(columns <= 0)
          return(-1);

      /* Allocate row string values. */
      val = (gchar **)g_malloc(columns * sizeof(gchar *));
      if(val == NULL)
          return(-1);
      /* Allocate blank strings for each new value. */
      for(n = 0; n < columns; n++)
          val[n] = g_strdup("");


      /* Itterate through each plug-in. */
      for(i = 0; i < total_plugins; i++)
      {
          plugin_ptr = plugin[i];
          if(plugin_ptr == NULL)
            continue;

          /* Append a row to the clist. */
          row = gtk_clist_append(clist, val);
          VPICListUpdateRow(clist, row, plugin_ptr);
      }

      /* Deallocate clist row value array. */
      for(n = 0; n < columns; n++)
          g_free(val[n]);
      g_free(val);

      return(0);
}


/*
 *    Procedure to call the plug-in's info function and handle
 *    the recieved information (if any).
 *
 *    Returns the status from the plug-in's info function or
 *    VPI_FALSE on error.
 */
int VPIDoGetInfo(vma_plugin_struct *plugin_ptr)
{
      int status = VPI_FALSE;
      vpi_info_struct v;
      VPI_PROTO_RETURN_INFO (*info_func)(VPI_PROTO_INPUT_INFO);


      if(plugin_ptr == NULL)
          return(status);

      /* Plug-in not enabled? */
      if(plugin_ptr->handle == NULL)
          return(status);

      /* Set up info values structure that will be passed to the
       * plug-in's info function.
       */
      v.flags = (VPI_FLAG_INFO_VERSION_MAJOR |
          VPI_FLAG_INFO_VERSION_MINOR |
          VPI_FLAG_INFO_VERSION_RELEASE
      );
      v.version_major = PROG_VERSION_MAJOR;
      v.version_minor = PROG_VERSION_MINOR;
      v.version_release = PROG_VERSION_RELEASE;

      /* Get pointer to plug-in's info function. */
      info_func = VPIGetFunction(
          plugin_ptr, VPI_PROTO_NAME_INFO
      );
      if(info_func != NULL)
      {
          /* Mark as processing while calling the plug-in's info
           * function.
           */
          plugin_ptr->processing = 1;
          status = info_func((vpi_id *)plugin_ptr, &v);
          plugin_ptr->processing = 0;
      }

      return(status);
}

/*
 *      Procedure to call the plug-in's configuration changed operation
 *    function.
 *
 *      Returns the status from the plug-in's info function or
 *      VPI_FALSE on error.
 */
int VPIDoOpConfigurationChanged(vma_plugin_struct *plugin_ptr)
{
        int status = VPI_FALSE;
        vpi_op_configuration_changed_struct v;
      int (*configuration_changed)(
          vpi_id *, vpi_op_configuration_changed_struct *, void *
      );


        if(plugin_ptr == NULL)
            return(status);

        /* Plug-in not enabled? */
        if(plugin_ptr->handle == NULL)
            return(status);


        /* Get pointer to plug-in's info function. */
      configuration_changed = plugin_ptr->configuration_changed;
      if(configuration_changed != NULL)
      {
            /* Set up configuration changed values structure that will
           * be passed to the plug-in's configuration changed operation
           * function.
             */
          v.flags = 0;

            plugin_ptr->processing = 1;
            status = configuration_changed(
            (vpi_id *)plugin_ptr, &v,
            plugin_ptr->configuration_changed_data
          );
            plugin_ptr->processing = 0;
        }

      return(status);
}

Generated by  Doxygen 1.6.0   Back to index