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

gphoto2-widget.c

Go to the documentation of this file.
/** \file
 *
 * \author Copyright 2000 Scott Fritzinger
 *
 * \par License
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * \par
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * \par
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include "config.h"
#include <gphoto2/gphoto2-widget.h>

#include <stdlib.h>
#include <string.h>

#include <gphoto2/gphoto2-result.h>
#include <gphoto2/gphoto2-port-log.h>

#define CHECK_NULL(r)        {if (!(r)) return (GP_ERROR_BAD_PARAMETERS);}

/**
 * CameraWidget:
 *
 * The internals of the #CameraWidget are only visible to gphoto2. You can
 * only access them using the functions provided by gphoto2.
 **/
00040 struct _CameraWidget {
      CameraWidgetType type;
      char    label [256];
      char    info [1024];
      char    name [256];

      CameraWidget *parent;

      /* Current value of the widget */
      char   *value_string;
      int     value_int;
      float   value_float;

      /* For Radio and Menu */
      char    **choice;
      int     choice_count;

      /* For Range */
      float   min; 
      float   max; 
      float   increment;

      /* Child info */
      CameraWidget **children;
      int           children_count;

      /* Widget was changed */
      int     changed;

      /* Widget is read only */
      int   readonly;

      /* Reference count */
      int     ref_count;

      /* Unique identifier */
      int     id;

      /* Callback */
      CameraWidgetCallback callback;
};

/**
 * \brief Create a new widget.
 *
 * The function creates a new #CameraWidget of specified type and with
 * given label.
 *
 * @param type the type
 * @param label the label
 * @param widget 
 * @return a gphoto2 error code.
 * 
 **/
int
00095 gp_widget_new (CameraWidgetType type, const char *label, 
               CameraWidget **widget) 
{
      static int i = 0;

      CHECK_NULL (label && widget);

      *widget = (CameraWidget*) malloc (sizeof (CameraWidget));
      memset (*widget, 0, sizeof (CameraWidget));

      (*widget)->type = type;
      strcpy ((*widget)->label, label);
      
      /* set the value to nothing */
      (*widget)->value_int          = 0;
        (*widget)->value_float      = 0.0;
        (*widget)->value_string     = NULL;

        (*widget)->ref_count        = 1;
      (*widget)->choice_count       = 0;
      (*widget)->choice             = NULL;
      (*widget)->readonly           = 0;
      (*widget)->id                 = i++;

        /* Clear all children pointers */
      free ((*widget)->children);
      (*widget)->children = NULL;
      (*widget)->children_count = 0;

      return (GP_OK);
}

/**
 * \brief Frees a CameraWidget
 *
 * @param widget the #CameraWidget to be freed
 * @return a gphoto2 error code.
 * 
 **/
int
00135 gp_widget_free (CameraWidget *widget)
{
      int x;
      CHECK_NULL (widget);

      /* Free children recursively */
      if ((widget->type == GP_WIDGET_WINDOW) ||
          (widget->type == GP_WIDGET_SECTION)) {
            for (x = 0; x < gp_widget_count_children (widget); x++)
                  gp_widget_free (widget->children[x]);
            free (widget->children);
      }
      for (x = 0; x < widget->choice_count; x++)
            free (widget->choice[x]);
      free (widget->choice);

        if (widget->value_string)
            free (widget->value_string);
      free (widget);
      return (GP_OK);
}

/**
 * \brief Increments the reference count for the CameraWidget
 *
 * @param widget a #CameraWidget you want to ref-count
 * @return a gphoto2 error code.
 *
 **/
int
00165 gp_widget_ref (CameraWidget *widget) 
{
      CHECK_NULL (widget);

      widget->ref_count += 1;

      return (GP_OK);
}

/**
 * \brief Decrements the reference count for the CameraWidget
 *
 * @param widget a CameraWidget you want to unref
 * @return a gphoto2 error code.
 *
 **/
int
00182 gp_widget_unref (CameraWidget *widget) 
{
      CHECK_NULL (widget);

      widget->ref_count -= 1;

      if (widget->ref_count == 0)
            gp_widget_free (widget);

      return (GP_OK);
}

/**
 * \brief Retrieves the information about the widget
 *
 * @param widget a #CameraWidget
 * @param info
 * @return a gphoto2 error code.
 *
 **/
int
00203 gp_widget_get_info (CameraWidget *widget, const char **info)
{
      CHECK_NULL (widget && info);

      *info = widget->info;
      return (GP_OK);
}


/**
 * \brief Sets the information about the widget
 *
 * @param widget a #CameraWidget
 * @param info Information about above widget
 * @return a gphoto2 error code.
 *
 **/
int
00221 gp_widget_set_info (CameraWidget *widget, const char *info)
{
      CHECK_NULL (widget && info);

      strcpy (widget->info, info);
      return (GP_OK);
}

/**
 * \brief Gets the name of the widget
 *
 * @param widget a #CameraWidget
 * @param name Name of above widget
 * @return a gphoto2 error code.
 *
 **/
int
00238 gp_widget_get_name (CameraWidget *widget, const char **name)
{
      CHECK_NULL (widget && name);

      *name = widget->name;
      return (GP_OK);
}

/**
 * \brief Sets the name of the widget
 *
 * @param widget a #CameraWidget
 * @param name Name of above widget
 * @return a gphoto2 error code.
 *
 **/
int
00255 gp_widget_set_name (CameraWidget *widget, const char *name)
{
      CHECK_NULL (widget && name);

      strcpy (widget->name, name);
      return (GP_OK);
}



/**
 * \brief Retrieves the unique id of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param id 
 * @return a gphoto2 error code.
 *
 **/
int
00274 gp_widget_get_id (CameraWidget *widget, int *id)
{
      CHECK_NULL (widget && id);

      *id = widget->id;
      return (GP_OK);
}

/**
 * \brief Tells that the widget has been changed
 *
 * @param widget a #CameraWidget
 * @param changed a boolean whether we changed or not
 * @return a gphoto2 error code
 *
 * Sets the changed of the CameraWidget depending on 
 * the changed parameter.
 *
 **/
int
00294 gp_widget_set_changed (CameraWidget *widget, int changed)
{
      CHECK_NULL (widget);

      widget->changed = changed;
      return (GP_OK);
}

/**
 * \brief Tells that the widget is readonly
 *
 * @param widget a #CameraWidget
 * @param changed a boolean whether we are readonly or not
 * @return a gphoto2 error code
 *
 * Sets the readonly of the CameraWidget depending on 
 * the changed parameter.
 *
 * Only useful when called from the camera driver.
 **/
int
00315 gp_widget_set_readonly (CameraWidget *widget, int readonly)
{
      CHECK_NULL (widget);

      widget->readonly = readonly;
      return (GP_OK);
}

/**
 * \brief Retrieves the readonly state of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param readonly
 * @return a gphoto2 error code.
 *
 **/
int
00332 gp_widget_get_readonly (CameraWidget *widget, int *readonly) 
{
      CHECK_NULL (widget && readonly);

      *readonly = widget->readonly;
      return (GP_OK);
}

/**
 * \brief Retrieves the type of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param type
 * @return a gphoto2 error code.
 *
 **/
int
00349 gp_widget_get_type (CameraWidget *widget, CameraWidgetType *type) 
{
      CHECK_NULL (widget && type);

      *type = widget->type;
      return (GP_OK);
}

/**
 * \brief Retrieves the label of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param label
 * @return a gphoto2 error code.
 *
 **/
int
00366 gp_widget_get_label (CameraWidget *widget, const char **label) 
{
      CHECK_NULL (widget && label);

      *label = widget->label;
      return (GP_OK);
}

/**
 * \brief Sets the value of the widget
 *
 * @param widget a #CameraWidget
 * @param value 
 * @return a gphoto2 error code.
 *
 * Please pass
 * (char*) for GP_WIDGET_MENU, GP_WIDGET_TEXT, GP_WIDGET_RADIO,
 * (float) for GP_WIDGET_RANGE,
 * (int)   for GP_WIDGET_DATE, GP_WIDGET_TOGGLE, and
 * (CameraWidgetCallback) for GP_WIDGET_BUTTON.
 *
 **/
int
00389 gp_widget_set_value (CameraWidget *widget, const void *value) 
{
      CHECK_NULL (widget && value);

        switch (widget->type) {
      case GP_WIDGET_BUTTON:
            widget->callback = (CameraWidgetCallback) value;
            return (GP_OK);
      case GP_WIDGET_MENU:
      case GP_WIDGET_RADIO:
        case GP_WIDGET_TEXT:
            gp_log (GP_LOG_DEBUG, "gphoto2-widget", "Setting value to "
                  "'%s'...", (char*) value);
              if (widget->value_string) {
                  if (strcmp (widget->value_string, (char*) value))
                              widget->changed = 1;
                  free (widget->value_string);
            } else
                  widget->changed = 1;
            widget->value_string = strdup ((char*)value);
            return (GP_OK);
        case GP_WIDGET_RANGE:
                  if (widget->value_float != *((float*)value)) {
                  widget->value_float  = *((float*)value);
                  widget->changed = 1;
                  }
                  return (GP_OK);
      case GP_WIDGET_DATE:
        case GP_WIDGET_TOGGLE:
            if (widget->value_int != *((int*)value)) {
                  widget->value_int  = *((int*)value);
                  widget->changed = 1;
            }
              return (GP_OK);
      case GP_WIDGET_WINDOW:
      case GP_WIDGET_SECTION:
        default:
            return (GP_ERROR_BAD_PARAMETERS);
        }
}

/**
 * \brief Retrieves the value of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param value
 * @return a gphoto2 error code.
 *
 **/
int
00439 gp_widget_get_value (CameraWidget *widget, void *value) 
{
      CHECK_NULL (widget && value);

        switch (widget->type) {
      case GP_WIDGET_BUTTON:
            *(CameraWidgetCallback*)value = widget->callback;
            return (GP_OK);
      case GP_WIDGET_MENU:
      case GP_WIDGET_RADIO:
        case GP_WIDGET_TEXT:
            *((char**)value) = widget->value_string;
            return (GP_OK);
        case GP_WIDGET_RANGE:
            *((float*)value) = widget->value_float;
            return (GP_OK);
        case GP_WIDGET_TOGGLE:
      case GP_WIDGET_DATE:
                  *((int*)value) = widget->value_int;
            return (GP_OK);
      case GP_WIDGET_SECTION:
      case GP_WIDGET_WINDOW:
        default:
            return (GP_ERROR_BAD_PARAMETERS);
        }
}

/**
 * \brief Appends a #CameraWidget to a #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param child the #CameraWidget you would like to append to above
 * @return a gphoto2 error code.
 *
 **/
int
00475 gp_widget_append (CameraWidget *widget, CameraWidget *child) 
{
      CameraWidget **newlist;
      CHECK_NULL (widget && child);

      /* Return if they can't have any children */
        if ((widget->type != GP_WIDGET_WINDOW) && 
          (widget->type != GP_WIDGET_SECTION))
            return (GP_ERROR_BAD_PARAMETERS);

      if (widget->children_count)
            newlist = realloc(widget->children,sizeof(CameraWidget*)*(widget->children_count+1));
      else
            newlist = malloc(sizeof(CameraWidget*));
      if (!newlist) return (GP_ERROR_NO_MEMORY);
      widget->children = newlist;
      widget->children[widget->children_count] = child;
      widget->children_count += 1;
      child->parent = widget;
      child->changed = 0;

      return (GP_OK);
}

/**
 * \brief Prepends a #CameraWidget to a #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param child the #CameraWidget you would like to prepend to above
 * @return a gphoto2 error code.
 *
 **/
int
00508 gp_widget_prepend (CameraWidget *widget, CameraWidget *child) 
{
      int x;
      CameraWidget**    newlist;

      CHECK_NULL (widget && child);

      /* Return if they can't have any children */
      if ((widget->type != GP_WIDGET_WINDOW) && 
          (widget->type != GP_WIDGET_SECTION))
            return (GP_ERROR_BAD_PARAMETERS);

      if (widget->children_count)
            newlist = realloc(widget->children,sizeof(CameraWidget*)*(widget->children_count+1));
      else
            newlist = malloc(sizeof(CameraWidget*));
      if (!newlist) return (GP_ERROR_NO_MEMORY);
      widget->children = newlist;

      /* Shift down 1 */
      for (x = widget->children_count; x > 0; x--)
            widget->children[x] = widget->children[x - 1];

      /* Prepend the child */
      widget->children[0] = child;
      widget->children_count += 1;
      child->parent = widget;
      child->changed = 0;

      return (GP_OK);
}

/**
 * \brief Counts the children of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @return a gphoto2 error code or number of children
 *
 **/
int
00548 gp_widget_count_children (CameraWidget *widget) 
{
      CHECK_NULL (widget);

      return (widget->children_count);
}

/**
 * \brief Retrieves the child number \c child_number of the parent
 *
 * @param widget a #CameraWidget
 * @param child_number the number of the child
 * @param child
 * @return a gphoto2 error code.
 *
 **/
int
00565 gp_widget_get_child (CameraWidget *widget, int child_number, 
                 CameraWidget **child) 
{
      CHECK_NULL (widget && child);

      if (child_number >= widget->children_count)
            return (GP_ERROR_BAD_PARAMETERS);

      *child = widget->children[child_number];
      return (GP_OK);
}

/**
 * \brief Retrieves the child with label \c label of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param label the label of the child
 * @param child
 * @return a gphoto2 error code.
 *
 **/
int
00587 gp_widget_get_child_by_label (CameraWidget *widget, const char *label, 
                        CameraWidget **child)
{
      int x;

      CHECK_NULL (widget && label && child);

      if (strcmp (widget->label, label) == 0) {
            *child = widget;
            return (GP_OK);
      }

      for (x = 0; x < widget->children_count; x++) {
            int result;
            CameraWidget *child_rec;
            
            result = gp_widget_get_child_by_label (widget->children[x], 
                                           label, &child_rec);
            if (result == GP_OK) {
                  *child = child_rec;
                  return (GP_OK);
            }
      }

      return (GP_ERROR_BAD_PARAMETERS);
}

/**
 * \brief Retrieves the child with id \c id of the widget
 *
 * @param widget a #CameraWidget
 * @param id the id of the child
 * @param child
 * @return a gphoto2 error code.
 *
 **/
int
00624 gp_widget_get_child_by_id (CameraWidget *widget, int id, CameraWidget **child) 
{
      int x;

      CHECK_NULL (widget && child);

      if (widget->id == id) {
            *child = widget;
            return (GP_OK);
      }
      
      for (x = 0; x < widget->children_count; x++) {
            int result;
            CameraWidget *child_rec;
            
            result = gp_widget_get_child_by_id (widget->children[x], id, 
                                        &child_rec);
            if (result == GP_OK) {
                  *child = child_rec;
                  return (GP_OK);
            }
      }

      return (GP_ERROR_BAD_PARAMETERS);
}

/**
 * \brief Retrieves the child with name \c name of the widget
 *
 * @param widget a #CameraWidget
 * @param name the name of the child
 * @return a gphoto2 error code.
 *
 **/
int
00659 gp_widget_get_child_by_name (CameraWidget *widget, const char *name,
                       CameraWidget **child)
{
      int x;

      CHECK_NULL (widget && child);

      if (!strcmp (widget->name, name)) {
            *child = widget;
            return (GP_OK);
      }
      
      for (x = 0; x < widget->children_count; x++) {
            int result;
            CameraWidget *child_rec;
            
            result = gp_widget_get_child_by_name (widget->children[x], name,
                                          &child_rec);
            if (result == GP_OK) {
                  *child = child_rec;
                  return (GP_OK);
            }
      }

      return (GP_ERROR_BAD_PARAMETERS);
}

/**
 * \brief Retrieves the parent of a CameraWidget
 *
 * @param widget a #CameraWidget
 * @param parent the pointer to the parent to return
 * @return a gphoto2 error code.
 *
 **/
int
00695 gp_widget_get_parent (CameraWidget *widget, CameraWidget **parent)
{
      CHECK_NULL (widget && parent);

      *parent = widget->parent;

      return (GP_OK);
}

/**
 * \brief Retrieves the root of the #CameraWidget
 *
 * @param widget a #CameraWidget
 * @param root
 * @return a gphoto2 error code.
 *
 **/
int
00713 gp_widget_get_root (CameraWidget *widget, CameraWidget **root) 
{
      CHECK_NULL (widget && root);

      if (widget->parent) 
            return (gp_widget_get_root (widget->parent, root));
      else {
            *root = widget;
            return (GP_OK);
      }
}

/**
 * \brief Sets some range parameters of the #CameraWidget
 *
 * @param range a #CameraWidget of type GP_WIDGET_RANGE
 * @param min
 * @param max
 * @param increment
 * @return a gphoto2 error code.
 *
 **/
int
00736 gp_widget_set_range (CameraWidget *range, float min, float max, float increment)
{
      CHECK_NULL (range);
      
      if (range->type != GP_WIDGET_RANGE)
            return (GP_ERROR_BAD_PARAMETERS);

      range->min = min;
      range->max = max;
      range->increment = increment;

      return (GP_OK);
}

/**
 * \brief Retrieves some range parameters of the #CameraWidget
 *
 * @param range a #CameraWidget of type GP_WIDGET_RANGE
 * @param min
 * @param max
 * @param increment
 * @return a gphoto2 error code.
 *
 **/
int
00761 gp_widget_get_range (CameraWidget *range, float *min, float *max, 
                 float *increment) 
{
      CHECK_NULL (range && min && max && increment);
      if (range->type != GP_WIDGET_RANGE)
            return (GP_ERROR_BAD_PARAMETERS);

      *min = range->min;
      *max = range->max;
      *increment = range->increment;

      return (GP_OK);
}

/**
 * \brief Adds a choice to the #CameraWidget
 *
 * @param widget a #CameraWidget of type GP_WIDGET_RADIO or GP_WIDGET_MENU
 * @param choice
 * @return a gphoto2 error code.
 *
 **/
int
00784 gp_widget_add_choice (CameraWidget *widget, const char *choice) 
{
      char **choices;
      CHECK_NULL (widget && choice);
      if ((widget->type != GP_WIDGET_RADIO) &&
          (widget->type != GP_WIDGET_MENU))
            return (GP_ERROR_BAD_PARAMETERS);

      if (widget->choice_count) {
            choices = realloc (widget->choice, sizeof(char*)*(widget->choice_count+1));
      } else {
            choices = malloc (sizeof(char*));
      }
      if (!choices) return (GP_ERROR_NO_MEMORY);

      widget->choice = choices;
      widget->choice[widget->choice_count] = strdup(choice);
      widget->choice_count += 1;
      return (GP_OK);
}

/**
 * \brief Counts the choices of the #CameraWidget
 *
 * @param widget a #CameraWidget of type GP_WIDGET_RADIO or GP_WIDGET_MENU
 * @return a gphoto2 error code or number of choices.
 * 
 **/
int
00813 gp_widget_count_choices (CameraWidget *widget) 
{
      CHECK_NULL (widget);
      if ((widget->type != GP_WIDGET_RADIO) &&
          (widget->type != GP_WIDGET_MENU))
            return (GP_ERROR_BAD_PARAMETERS);

      return (widget->choice_count);
}

/**
 * \brief Retrieves the choice number \c choice_number
 *
 * @param widget a #CameraWidget of type GP_WIDGET_RADIO or GP_WIDGET_MENU
 * @param choice_number
 * @param choice
 * @return a gphoto2 error code
 *
 **/
int
00833 gp_widget_get_choice (CameraWidget *widget, int choice_number, 
                  const char **choice) 
{
      CHECK_NULL (widget && choice);
      if ((widget->type != GP_WIDGET_RADIO) &&
          (widget->type != GP_WIDGET_MENU))
            return (GP_ERROR_BAD_PARAMETERS);

      if (choice_number >= widget->choice_count)
            return (GP_ERROR_BAD_PARAMETERS);

      *choice = widget->choice[choice_number];
      return (GP_OK);
}

/**
 * \brief Tells if the widget has been changed
 *
 * @param widget a #CameraWidget
 * @return a gphoto2 error code or changed flag.
 *
 * Returns 1 if the state of the #CameraWidget has been changed or 0 if not.
 * In addition, it resets the changed flag to 0.
 *
 **/
int
00859 gp_widget_changed (CameraWidget *widget) 
{
        int val;

      CHECK_NULL (widget);

        val = widget->changed;
        widget->changed = 0;

        return (val);
}

Generated by  Doxygen 1.6.0   Back to index