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

dimagev.c

/**********************************************************************;
*       Minolta Dimage V digital camera communication library         *
*               Copyright  2000,2001 Gus Hartmann                  *
*                                                                     *
*    This program is free software; you can redistribute it and/or    *
*    modify it under the terms of the GNU General Public License as   *
*    published by the Free Software Foundation; either version 2 of   *
*    the License, or (at your option) any later version.              *
*                                                                     *
*    This program 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 General Public License for more details.                     *
*                                                                     *
*    You should have received a copy of the GNU General Public        *
*    License along with this program; if not, write to the Free       *
*    Software Foundation, Inc., 59 Temple Place, Suite 330,           *
*    Boston, MA 02111-1307 USA                                        *
*                                                                     *
**********************************************************************/

#include "config.h"

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  ifdef gettext_noop
#    define _(String) dgettext (GETTEXT_PACKAGE, String)
#    define N_(String) gettext_noop (String)
#  else
#    define _(String) (String)
#    define N_(String) (String)
#  endif
#else
#  define _(String) (String)
#  define N_(String) (String)
#endif

#include "dimagev.h"

#define GP_MODULE "dimagev"

int camera_id (CameraText *id) 
{
#if defined HAVE_STRNCPY
      strncpy(id->text, "minolta-dimagev", sizeof(id->text));
#else
      strcpy(id->text, "minolta-dimagev");
#endif

      return GP_OK;
}

int camera_abilities (CameraAbilitiesList *list) 
{
      CameraAbilities a;

      memset(&a, 0, sizeof(a));
#if defined HAVE_STRNCPY
      strncpy(a.model, "Minolta:Dimage V", sizeof(a.model));
#else
      strcpy(a.model, "Minolta:Dimage V");
#endif
      a.status = GP_DRIVER_STATUS_PRODUCTION;
      a.port     = GP_PORT_SERIAL;
      a.speed[0] = 38400;
      a.speed[1] = 0;
      a.operations        =   GP_OPERATION_CAPTURE_IMAGE |
                        GP_OPERATION_CAPTURE_PREVIEW;
      a.file_operations   =   GP_FILE_OPERATION_DELETE | 
                        GP_FILE_OPERATION_PREVIEW;
      a.folder_operations =   GP_FOLDER_OPERATION_PUT_FILE | 
                        GP_FOLDER_OPERATION_DELETE_ALL;

      gp_abilities_list_append(list, a);

      return GP_OK;
}

static int camera_exit (Camera *camera, GPContext *context) 
{
      /* Set the camera back into a normal mode. */
      if (camera->pl) {

            if (camera->pl->data) {
                  camera->pl->data->host_mode = (unsigned char) 0;

                  /* This will also send the host mode of zero. */
                  if ( dimagev_set_date(camera->pl) < GP_OK ) {
                        GP_DEBUG( "camera_init::unable to set camera to system time");
                        return GP_ERROR_IO;
                  }
                  free (camera->pl->data);
                  camera->pl->data = NULL;
            }

            if (camera->pl->status) {
                  free (camera->pl->status);
                  camera->pl->status = NULL;
            }

            if (camera->pl->info) {
                  free (camera->pl->info);
                  camera->pl->info = NULL;
            }

            free (camera->pl);
      }

      return GP_OK;
}

static int file_list_func (CameraFilesystem *fs, const char *folder, 
                     CameraList *list, void *data, GPContext *context) 
{
      Camera *camera = data;
      int ret;

      if ( dimagev_get_camera_status(camera->pl) < GP_OK ) {
            GP_DEBUG( "camera_file_list::unable to get camera status");
            return GP_ERROR_IO;
      }

      if ((ret = gp_list_populate(list, DIMAGEV_FILENAME_FMT, camera->pl->status->number_images)) < GP_OK ) {
            GP_DEBUG( "camera_file_list::unable to populate list");
            return ret;
      }
            
      return GP_OK;
}

static int get_file_func (CameraFilesystem *fs, const char *folder,
                    const char *filename, CameraFileType type,
                    CameraFile *file, void *data, GPContext *context) 
{
      Camera *camera = data;
      int file_number=0, result;
      char buffer[128];

      file_number = gp_filesystem_number(fs, folder, filename, context);
      if (file_number < 0)
            return (file_number);

      switch (type) {
      case GP_FILE_TYPE_NORMAL:
            gp_file_set_mime_type (file, GP_MIME_JPEG);
            gp_file_set_name (file, filename);
            result = dimagev_get_picture (camera->pl, file_number + 1, file);
            break;
      case GP_FILE_TYPE_PREVIEW:
            gp_file_set_mime_type (file, GP_MIME_PPM);
#if defined HAVE_SNPRINTF
            snprintf(buffer, sizeof(buffer), DIMAGEV_THUMBNAIL_FMT, ( file_number + 1) );
#else
            sprintf(buffer, DIMAGEV_THUMBNAIL_FMT, ( file_number + 1) );
#endif 
            gp_file_set_name (file, buffer);
            result = dimagev_get_thumbnail (camera->pl, file_number + 1, file);
            break;
      default:
            return (GP_ERROR_NOT_SUPPORTED);
      }

      if (result < 0) {
            GP_DEBUG( "camera_file_get::unable to retrieve image file");
            return result;
      }

      sleep(2);
      return GP_OK;
}

static int delete_file_func (CameraFilesystem *fs, const char *folder, 
                       const char *filename, void *data,
                       GPContext *context) 
{
      Camera *camera = data;
      int file_number=0;

      file_number = gp_filesystem_number(camera->fs, folder, filename, context);
      if (file_number < 0)
            return (file_number);

      return dimagev_delete_picture(camera->pl, (file_number + 1 ));
}

static int camera_capture (Camera *camera, CameraCaptureType type, CameraFilePath *path, GPContext *context) 
{
      if (type != GP_CAPTURE_IMAGE)
            return (GP_ERROR_NOT_SUPPORTED);

      if ( dimagev_shutter(camera->pl) < GP_OK ) {
            GP_DEBUG( "camera_capture::unable to open shutter");
            return GP_ERROR_IO;
      }

      /* Now check how many pictures are taken, and return the last one. */
      if ( dimagev_get_camera_status(camera->pl) != 0 ) {
            GP_DEBUG( "camera_capture::unable to get camera status");
            return GP_ERROR_IO;
      }

#if defined HAVE_SNPRINTF
      snprintf(path->folder, sizeof(path->folder), "/");
      snprintf(path->name, sizeof(path->name), DIMAGEV_FILENAME_FMT, camera->pl->status->number_images);
#else
      sprintf(path->folder, "/");
      sprintf(path->name, DIMAGEV_FILENAME_FMT, camera->pl->status->number_images);
#endif

      /* Tell the CameraFilesystem about this picture */
      gp_filesystem_append (camera->fs, path->folder, path->name, context);

      return GP_OK;
}

static int put_file_func (CameraFilesystem *fs, const char *folder, 
                    CameraFile *file, void *data, GPContext *context) 
{
      Camera *camera = data;

      return dimagev_put_file(camera->pl, file);
}

static int delete_all_func (CameraFilesystem *fs, const char *folder,
                      void *data, GPContext *context) 
{
      Camera *camera = data;

      return dimagev_delete_all(camera->pl);
}

static int camera_summary (Camera *camera, CameraText *summary, GPContext *context) 
{
      int i = 0, count = 0;

      if ( dimagev_get_camera_status(camera->pl) < GP_OK ) {
            GP_DEBUG( "camera_summary::unable to get camera status");
            return GP_ERROR_IO;
      }

      if ( dimagev_get_camera_data(camera->pl) < GP_OK ) {
            GP_DEBUG( "camera_summary::unable to get camera data");
            return GP_ERROR_IO;
      }

      if ( dimagev_get_camera_info(camera->pl) < GP_OK ) {
            GP_DEBUG( "camera_summary::unable to get camera info");
            return GP_ERROR_IO;
      }

      dimagev_dump_camera_status(camera->pl->status);
      dimagev_dump_camera_data(camera->pl->data);
      dimagev_dump_camera_info(camera->pl->info);

      /* Now put all of the information into a reasonably formatted string. */
      /* i keeps track of the length. */
      i = 0;
      /* First the stuff from the dimagev_info_t */
#if defined HAVE_SNPRINTF
      i = snprintf(summary->text, sizeof(summary->text),
#else
      i = sprintf(summary->text,
#endif
            _("Model:\t\t\tMinolta Dimage V (%s)\n"
            "Hardware Revision:\t%s\nFirmware Revision:\t%s\n"),
            camera->pl->info->model, camera->pl->info->hardware_rev,
            camera->pl->info->firmware_rev);

      if ( i > 0 ) {
            count += i;
      }

      /* Now the stuff from dimagev_data_t */
#if defined HAVE_SNPRINTF
      i = snprintf(&(summary->text[count]), sizeof(summary->text) - count,
#else
      i = sprintf(&(summary->text[count]),
#endif
            _("Host Mode:\t\t%s\n"
            "Exposure Correction:\t%s\n"
            "Exposure Data:\t\t%d\n"
            "Date Valid:\t\t%s\n"
            "Date:\t\t\t%d/%02d/%02d %02d:%02d:%02d\n"
            "Self Timer Set:\t\t%s\n"
            "Quality Setting:\t%s\n"
            "Play/Record Mode:\t%s\n"
            "Card ID Valid:\t\t%s\n"
            "Card ID:\t\t%d\n"
            "Flash Mode:\t\t"),

            ( camera->pl->data->host_mode != (unsigned char) 0 ? _("Remote") : _("Local") ),
            ( camera->pl->data->exposure_valid != (unsigned char) 0 ? _("Yes") : _("No") ),
            (signed char)camera->pl->data->exposure_correction,
            ( camera->pl->data->date_valid != (unsigned char) 0 ? _("Yes") : _("No") ),
            ( camera->pl->data->year < (unsigned char) 70 ? 2000 + (int) camera->pl->data->year : 1900 + (int) camera->pl->data->year ),
            camera->pl->data->month, camera->pl->data->day, camera->pl->data->hour,
            camera->pl->data->minute, camera->pl->data->second,
            ( camera->pl->data->self_timer_mode != (unsigned char) 0 ? _("Yes") : _("No")),
            ( camera->pl->data->quality_setting != (unsigned char) 0 ? _("Fine") : _("Standard") ),
            ( camera->pl->data->play_rec_mode != (unsigned char) 0 ? _("Record") : _("Play") ),
            ( camera->pl->data->valid != (unsigned char) 0 ? _("Yes") : _("No")), camera->pl->data->id_number );

      if ( i > 0 ) {
            count += i;
      }

      /* Flash is a special case, a switch is needed. */
      switch ( camera->pl->data->flash_mode ) {
            case 0:
#if defined HAVE_SNPRINTF
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count,
#else
                  i = sprintf(&(summary->text[count]),
#endif
                        _("Automatic\n"));
                  break;
            case 1:
#if defined HAVE_SNPRINTF
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count,
#else
                  i = sprintf(&(summary->text[count]),
#endif
                        _("Force Flash\n"));
                  break;
            case 2:
#if defined HAVE_SNPRINTF
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count,
#else
                  i = sprintf(&(summary->text[count]),
#endif
                        _("Prohibit Flash\n"));
                  break;
            default:
#if defined HAVE_SNPRINTF
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count,
#else
                  i = sprintf(&(summary->text[count]),
#endif
                        _("Invalid Value ( %d )\n"), camera->pl->data->flash_mode);
                  break;
      }

      if ( i > 0 ) {
            count += i;
      }

      /* Now for the information in dimagev_status_t */
#if defined HAVE_SNPRINTF
      i = snprintf(&(summary->text[count]), sizeof(summary->text) - count,
#else
      i = sprintf(&(summary->text[count]),
#endif
            _("Battery Level:\t\t%s\n"
            "Number of Images:\t%d\n"
            "Minimum Capacity Left:\t%d\n"
            "Busy:\t\t\t%s\n"
            "Flash Charging:\t\t%s\n"
            "Lens Status:\t\t"),
            ( camera->pl->status->battery_level ? _("Not Full") : _("Full") ),
            camera->pl->status->number_images,
            camera->pl->status->minimum_images_can_take,
            ( camera->pl->status->busy ? _("Busy") : _("Idle") ),
            ( camera->pl->status->flash_charging ? _("Charging") : _("Ready") )

      );

      if ( i > 0 ) {
            count += i;
      }

      /* Lens status is another switch. */
      switch ( camera->pl->status->lens_status ) {
            case 0:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Normal\n"));
                  break;
            case 1: case 2:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Lens direction does not match flash light\n"));
                  break;
            case 3:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Lens is not connected\n"));
                  break;
            default:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Bad value for lens status %d\n"), camera->pl->status->lens_status);
                  break;
      }

      if ( i > 0 ) {
            count += i;
      }

      /* Card status is another switch. */
      i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Card Status:\t\t"));
      if ( i > 0 ) {
            count += i;
      }

      switch ( camera->pl->status->card_status ) {
            case 0:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Normal"));
                  break;
            case 1:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Full"));
                  break;
            case 2:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Write-protected"));
                  break;
            case 3:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Unsuitable card"));
                  break;
            default:
                  i = snprintf(&(summary->text[count]), sizeof(summary->text) - count, _("Bad value for card status %d"), camera->pl->status->card_status);
                  break;
      }
      
      if ( i > 0 ) {
            count += i;
      }


      return GP_OK;
}

static int camera_about (Camera *camera, CameraText *about, GPContext *context) 
{
#if defined HAVE_SNPRINTF
      snprintf(about->text, sizeof(about->text),
#else
      sprintf(about->text,
#endif
_("Minolta Dimage V Camera Library\n%s\nGus Hartmann <gphoto@gus-the-cat.org>\nSpecial thanks to Minolta for the spec."), DIMAGEV_VERSION);

      return GP_OK;
}

static CameraFilesystemFuncs fsfuncs = {
      .file_list_func = file_list_func,
      .get_file_func = get_file_func,
      .del_file_func = delete_file_func,
      .put_file_func = put_file_func,
      .delete_all_func = delete_all_func,
};

int camera_init (Camera *camera, GPContext *context) 
{
      GPPortSettings settings;

        /* First, set up all the function pointers */
        camera->functions->exit                 = camera_exit;
        camera->functions->capture              = camera_capture;
        camera->functions->summary              = camera_summary;
        camera->functions->about                = camera_about;

        GP_DEBUG( "initializing the camera");

      camera->pl = malloc (sizeof (CameraPrivateLibrary));
      if (!camera->pl)
            return (GP_ERROR_NO_MEMORY);
      memset (camera->pl, 0, sizeof (CameraPrivateLibrary));
      camera->pl->dev = camera->port;

      /* Configure the port */
        gp_port_set_timeout(camera->port, 5000);
      gp_port_get_settings(camera->port, &settings);
        settings.serial.speed = 38400;
        settings.serial.bits = 8;
        settings.serial.parity = 0;
        settings.serial.stopbits = 1;
        gp_port_set_settings(camera->port, settings);

        if  ( dimagev_get_camera_data(camera->pl) < GP_OK ) {
                GP_DEBUG( "camera_init::unable to get current camera data");
            free (camera->pl);
            camera->pl = NULL;
                return GP_ERROR_IO;
        }

        if  ( dimagev_get_camera_status(camera->pl) < GP_OK ) {
                GP_DEBUG( "camera_init::unable to get current camera status");
            free (camera->pl);
            camera->pl = NULL;
                return GP_ERROR_IO;
        }

      /* Apparently, trying to set the clock now leaves the camera in an
         unstable state. Skiping it for now. */
        /* if ( dimagev_set_date(camera->pl) < GP_OK ) {
                GP_DEBUG( "camera_init::unable to set camera to system time");
        } */

      /* Set up the filesystem */
      gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
        return GP_OK;
}

Generated by  Doxygen 1.6.0   Back to index