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

library.c

/* library.c
 *
 * Copyright © 2001 Lutz Müller
 *
 * 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.
 *
 * 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.
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <gphoto2-library.h>
#include <gphoto2-port-log.h>

#include "konica.h"

#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (GETTEXT_PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

#define C(r) {int ret=(r);if(ret<0) return(ret);}
#define C_NULL(r) {if (!(r)) return (GP_ERROR_BAD_PARAMETERS);}

#define GP_MODULE "konica"
#define PING_TIMEOUT 60

static struct {
        const char *model;
        int image_id_long;
        int vendor;
        int product;
} konica_cameras[] = {
        {"Konica Q-EZ",        0, 0, 0},
        {"Konica Q-M100",      0, 0, 0},
        {"Konica Q-M100V",     0, 0, 0},
        {"Konica Q-M200",      1, 0, 0},
        {"HP PhotoSmart",      0, 0, 0},
        {"HP PhotoSmart C20",  0, 0, 0},
        {"HP PhotoSmart C30",  0, 0, 0},
        {"HP PhotoSmart C200", 0, 0, 0},
        {NULL,                 0, 0, 0}
};

struct _CameraPrivateLibrary {
      unsigned int speed, timeout;
        int image_id_long;
};


static int localization_file_read (Camera* camera, const char* file_name,
                                   unsigned char** data, long int* data_size,
                           GPContext *context);

static int
timeout_func (Camera *camera, GPContext *context)
{
      C(k_ping (camera->port, context));

      return (GP_OK);
}

static int
get_info (Camera *camera, unsigned int n, CameraFileInfo *info,
        CameraFile *file, GPContext *context)
{
      unsigned long image_id;
      unsigned int buffer_size, exif_size;
      unsigned char *buffer = NULL;
      int protected, r;

      /*
       * Remove the timeout, get the information and restart the
       * timeout afterwards.
       */
      gp_camera_stop_timeout (camera, camera->pl->timeout);
      r = k_get_image_information (camera->port, context,
            camera->pl->image_id_long, n, &image_id, &exif_size,
            &protected, &buffer, &buffer_size);
      camera->pl->timeout = gp_camera_start_timeout (camera, PING_TIMEOUT,
                                           timeout_func);
      C(r);

      info->audio.fields = GP_FILE_INFO_NONE;

      info->preview.fields = GP_FILE_INFO_TYPE;
      strcpy (info->preview.type, GP_MIME_JPEG);

      info->file.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_PERMISSIONS |
                      GP_FILE_INFO_TYPE | GP_FILE_INFO_NAME;
      info->file.size = exif_size * 1000;
      info->file.permissions = GP_FILE_PERM_READ;
      if (!protected)
            info->file.permissions |= GP_FILE_PERM_DELETE;
      strcpy (info->file.type, GP_MIME_JPEG);
      snprintf (info->file.name, sizeof (info->file.name),
              "%06i.jpeg", (int) image_id);

      if (file) {
            gp_file_set_type (file, GP_FILE_TYPE_EXIF);
            gp_file_set_name (file, info->file.name);
            gp_file_set_data_and_size (file, buffer, buffer_size);
      } else
            free (buffer);

      return (GP_OK);
}

static int
file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
                void *data, GPContext *context)
{
      CameraFile *file;
      CameraFileInfo info;
        KStatus status;
        unsigned int i, id;
        Camera *camera = data;
      int result;

        /*
         * We can't get the filename from the camera.
         * But we decide to call the images %6i.jpeg', with the image id as
         * parameter. Therefore, let's get the image ids.
         */
        C(k_get_status (camera->port, context, &status));

      id = gp_context_progress_start (context, status.pictures,
                              _("Getting file list..."));
        for (i = 0; i < status.pictures; i++) {

                /* Get information */
            gp_file_new (&file);
            result = get_info (camera, i + 1, &info, file, context);
            if (result < 0) {
                  gp_file_unref (file);
                  return (result);
            }

                /*
             * Append directly to the filesystem instead of to the list,
             * because we have additional information.
             */
            gp_filesystem_append (camera->fs, folder, info.file.name,
                              context);
            gp_filesystem_set_info_noop (camera->fs, folder, info, context);
            gp_filesystem_set_file_noop (camera->fs, folder, file, context);
            gp_file_unref (file);

            gp_context_idle (context);
            gp_context_progress_update (context, id, i + 1);
            if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
                  return (GP_ERROR_CANCEL);
        }
      gp_context_progress_stop (context, id);

        return (GP_OK);
}

int
camera_id (CameraText* id)
{
        strcpy (id->text, "konica");

        return (GP_OK);
}

int
camera_abilities (CameraAbilitiesList* list)
{
        int i;
        CameraAbilities a;

        for (i = 0; konica_cameras [i].model; i++) {
            memset(&a, 0, sizeof(a));
            a.status = GP_DRIVER_STATUS_PRODUCTION;
                strcpy (a.model, konica_cameras [i].model);
            a.usb_vendor  = konica_cameras [i].vendor;
            a.usb_product = konica_cameras [i].product;
                if (konica_cameras [i].vendor)
                        a.port = GP_PORT_USB;
                else {
                        a.port = GP_PORT_SERIAL;
                        a.speed[0]     = 300;
                        a.speed[1]     = 600;
                        a.speed[2]     = 1200;
                        a.speed[3]     = 2400;
                        a.speed[4]     = 4800;
                        a.speed[5]     = 9600;
                        a.speed[6]     = 19200;
                        a.speed[7]     = 38400;
                        a.speed[8]     = 57600;
                        a.speed[9]     = 115200;
                        a.speed[10]    = 0;
                }
                a.operations = GP_OPERATION_CONFIG |
                               GP_OPERATION_CAPTURE_IMAGE |
                               GP_OPERATION_CAPTURE_PREVIEW;
                a.file_operations = GP_FILE_OPERATION_DELETE |
                                    GP_FILE_OPERATION_PREVIEW |
                            GP_FILE_OPERATION_EXIF;
                a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL;
                gp_abilities_list_append (list, a);
        }

        return (GP_OK);
}

static int
set_speed (Camera *camera, int speed, GPContext *context)
{
      GPPortSettings settings;
      KBitRate bit_rates;
      KBitFlag bit_flags;
      int i;
      int speeds[] = {300, 600, 1200, 2400, 4800, 9600, 19200,
                         38400, 57600, 115200};

      C(gp_port_get_settings (camera->port, &settings));
      if ((settings.serial.speed == speed) ||
          (settings.serial.speed == 115200))
            return (GP_OK);

      switch (speed) {
      case 0:

            /* Set the highest possible speed */
            C(k_get_io_capability (camera->port, context, &bit_rates,
                                        &bit_flags));
            for (i = 9; i >= 0; i--)
                  if ((1 << i) & bit_rates)
                        break;
            if (i < 0)
                  return (GP_ERROR_IO_SERIAL_SPEED);
            bit_rates = (1 << i);
            speed = speeds[i];
            break;
      case 300:
            bit_rates = 1 << 0;
            break;
      case 600:
            bit_rates = 1 << 1;
            break;
      case 1200:
            bit_rates = 1 << 2;
            break;
      case 2400:
            bit_rates = 1 << 3;
            break;
      case 4800:
              bit_rates = 1 << 4;
              break;
      case 9600:
              bit_rates = 1 << 5;
              break;
      case 19200:
              bit_rates = 1 << 6;
              break;
      case 38400:
              bit_rates = 1 << 7;
              break;
      case 57600:
              bit_rates = 1 << 8;
              break;
      case 115200:
              bit_rates = 1 << 9;
              break;
      default:
              return (GP_ERROR_IO_SERIAL_SPEED);
      }

        /* Request the new speed */
      bit_flags = K_BIT_FLAG_8_BITS;
      C(k_set_io_capability (camera->port, context, bit_rates,
                                  bit_flags));
      gp_log (GP_LOG_DEBUG, "konica", "Reconnecting at speed %d", speed);
      settings.serial.speed = speed;
      C(gp_port_set_settings (camera->port, settings));
      C(k_init (camera->port, context));

      return (GP_OK);
}

static int
test_speed (Camera *camera, GPContext *context)
{
      int i;
      unsigned int speeds[] = {115200, 9600, 57600, 38400, 19200,
                         4800, 2400, 1200, 600, 300};
      unsigned int id;
      GPPortSettings settings;

      C(gp_port_get_settings (camera->port, &settings));

      id = gp_context_progress_start (context, 10,
                              _("Testing different speeds..."));
      for (i = 0; i < 10; i++) {
            gp_log (GP_LOG_DEBUG, "konica", "Testing speed %d",
                  speeds[i]);
            settings.serial.speed = speeds[i];
            C(gp_port_set_settings (camera->port, settings));
            if (k_init (camera->port, context) == GP_OK)
                  break;
            gp_context_idle (context);
            gp_context_progress_update (context, id, i + 1);
            if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
                  return (GP_ERROR_CANCEL);
      }
      gp_context_progress_stop (context, id);
      if (i == 10) {
            gp_context_error (context, _("The camera could not be "
                  "contacted. Please make sure it is connected to the "
                  "computer and turned on."));
            return (GP_ERROR_IO);
      }

      return (speeds[i]);
}

static int
set_info_func (CameraFilesystem *fs, const char *folder, const char *file,
               CameraFileInfo info, void *data, GPContext *context)
{
        Camera *camera = data;
        char tmp[7];
        int protected;
        unsigned long image_id;

        /* Permissions? */
        if (info.file.fields & GP_FILE_INFO_PERMISSIONS) {
                strncpy (tmp, file, 6);
                tmp[6] = '\0';
                image_id = atol (tmp);
                if (info.file.permissions & GP_FILE_PERM_DELETE)
                        protected = FALSE;
                else
                        protected = TRUE;
                C(k_set_protect_status (camera->port, context,
                  camera->pl->image_id_long, image_id, protected));
        }

      /* Name? */
      if (info.file.fields & GP_FILE_INFO_NAME) {
            gp_context_error (context, _("Your camera does not support "
                  "changing filenames."));
            return (GP_ERROR_NOT_SUPPORTED);
      }

        return (GP_OK);
}

static int
get_info_func (CameraFilesystem *fs, const char *folder, const char *filename,
               CameraFileInfo *info, void *data, GPContext *context)
{
        Camera *camera = data;
      CameraFile *file;
        int n, result;

      /* We need image numbers starting with 1 */
      n = gp_filesystem_number (camera->fs, folder, filename, context);
      if (n < 0)
            return (n);
      n++;

      gp_file_new (&file);
      result = get_info (camera, n, info, file, context);
      if (result < 0) {
            gp_file_unref (file);
            return (result);
      }
      gp_filesystem_set_file_noop (fs, folder, file, context);
      gp_file_unref (file);

        return (GP_OK);
}

static int
camera_exit (Camera* camera, GPContext *context)
{
        if (camera->pl) {
            gp_camera_stop_timeout (camera, camera->pl->timeout);
                free (camera->pl);
                camera->pl = NULL;
        }

        return (GP_OK);
}

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

        if (strcmp (folder, "/"))
                return (GP_ERROR_DIRECTORY_NOT_FOUND);

        C(k_erase_all (camera->port, context, &not_erased));

        if (not_erased) {
            gp_context_error (context, _("%i pictures could not be "
                  "deleted because they are protected"), not_erased);
            gp_filesystem_reset (camera->fs);
            return (GP_ERROR);
        }

        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;
        unsigned long image_id;
      char image_id_string[] = {0, 0, 0, 0, 0, 0, 0};
        unsigned char *fdata = NULL;
        unsigned int size;
      CameraFileInfo info;
      int r;

        if (strlen (filename) != 11)
                return (GP_ERROR_FILE_NOT_FOUND);
        if (strcmp (folder, "/"))
                return (GP_ERROR_DIRECTORY_NOT_FOUND);

      /* Check if we can get the image id from the filename. */
      strncpy (image_id_string, filename, 6);
      image_id = atol (image_id_string);

      /* Get information about the image */
      C(gp_filesystem_get_info (camera->fs, folder,
                              filename, &info, context));

      /*
       * Remove the timeout, get the image and start the timeout
       * afterwards.
       */
      gp_camera_stop_timeout (camera, camera->pl->timeout);
        switch (type) {
        case GP_FILE_TYPE_PREVIEW:
            size = 2048;
            r = k_get_image (camera->port, context,
                  camera->pl->image_id_long,
                  image_id, K_THUMBNAIL, (unsigned char **) &fdata,
                  &size);
                break;
        case GP_FILE_TYPE_NORMAL:
            size = info.file.size;
            r = k_get_image (camera->port, context,
                  camera->pl->image_id_long,
                  image_id, K_IMAGE_EXIF, (unsigned char **) &fdata,
                  &size);
                break;
        default:
            r = GP_ERROR_NOT_SUPPORTED;
        }
      camera->pl->timeout = gp_camera_start_timeout (camera, PING_TIMEOUT,
                                           timeout_func);
      C(r);

        C(gp_file_set_data_and_size (file, fdata, size));
        C(gp_file_set_mime_type (file, GP_MIME_JPEG));

        return (GP_OK);
}

static int
delete_file_func (CameraFilesystem *fs, const char *folder,
              const char *filename, void *data, GPContext *context)
{
      Camera *camera = data;
        char tmp[] = {0, 0, 0, 0, 0, 0, 0};
        unsigned long image_id;

      C_NULL (camera && folder && filename);

      /* We don't support folders */
        if (strcmp (folder, "/")) return (GP_ERROR_DIRECTORY_NOT_FOUND);

      /* Extract the image id from the filename */
      strncpy (tmp, filename, 6);
        image_id = atol (tmp);

        C(k_erase_image (camera->port, context, camera->pl->image_id_long,
                        image_id));

        return (GP_OK);
}

static int
camera_summary (Camera* camera, CameraText* summary, GPContext *context)
{
      KInformation info;

        GP_DEBUG ("*** ENTER: camera_summary "
                         "***");
        C(k_get_information (camera->port, context, &info));

      snprintf (summary->text, sizeof (summary->text),
                _("Model: %s\n"
                "Serial Number: %s,\n"
                "Hardware Version: %i.%i\n"
                "Software Version: %i.%i\n"
                "Testing Software Version: %i.%i\n"
                "Name: %s,\n"
                "Manufacturer: %s\n"),
            info.model, info.serial_number,
            info.hardware.major, info.hardware.minor,
            info.software.major, info.software.minor,
            info.testing.major, info.testing.minor,
                info.name, info.manufacturer);

        return (GP_OK);
}

static int
camera_capture_preview (Camera* camera, CameraFile* file, GPContext *context)
{
        unsigned char *data = NULL;
        unsigned int size = 0;

        C(k_get_preview (camera->port, context, TRUE, &data, &size));
        C(gp_file_set_data_and_size (file, data, size));
        C(gp_file_set_mime_type (file, GP_MIME_JPEG));

        return (GP_OK);
}

static int
camera_capture (Camera* camera, CameraCaptureType type, CameraFilePath* path,
            GPContext *context)
{
        unsigned long image_id;
      int exif_size;
      unsigned char *buffer = NULL;
      unsigned int buffer_size;
      int protected, r;
      CameraFile *file = NULL;
      CameraFileInfo info;

      C_NULL (camera && path);

      /* We only support capturing of images */
      if (type != GP_CAPTURE_IMAGE)
            return (GP_ERROR_NOT_SUPPORTED);

      /* Stop the timeout, take the picture, and restart the timeout. */
      gp_camera_stop_timeout (camera, camera->pl->timeout);
      r = k_take_picture (camera->port, context, camera->pl->image_id_long,
            &image_id, &exif_size, &buffer, &buffer_size, &protected);
      camera->pl->timeout = gp_camera_start_timeout (camera, PING_TIMEOUT,
                                           timeout_func);
      C(r);

      sprintf (path->name, "%06i.jpeg", (int) image_id);
      strcpy (path->folder, "/");
      C(gp_filesystem_append (camera->fs, path->folder,
                                   path->name, context));

      info.preview.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_TYPE;
      info.preview.size = buffer_size;
      strcpy (info.preview.type, GP_MIME_JPEG);

      info.file.fields = GP_FILE_INFO_SIZE | GP_FILE_INFO_PERMISSIONS |
                      GP_FILE_INFO_TYPE | GP_FILE_INFO_NAME;
      info.file.size = exif_size;
      info.file.permissions = GP_FILE_PERM_READ;
      if (!protected)
            info.file.permissions |= GP_FILE_PERM_DELETE;
      strcpy (info.file.type, GP_MIME_JPEG);
      snprintf (info.file.name, sizeof (info.file.name),
              "%06i.jpeg", (int) image_id);
      gp_filesystem_set_info_noop (camera->fs, path->folder, info, context);

      gp_file_new (&file);
      gp_file_set_name (file, info.file.name);
      gp_file_set_mime_type (file, GP_MIME_JPEG);
      gp_file_set_type (file, GP_FILE_TYPE_EXIF);
      gp_file_set_data_and_size (file, buffer, buffer_size);
      gp_filesystem_set_file_noop (camera->fs, path->folder, file, context);
      gp_file_unref (file);

        return (GP_OK);
}

static int
camera_about (Camera* camera, CameraText* about, GPContext *context)
{
      C_NULL (camera && about);

      /* Translators: please write 'M"uller' (that is, with u-umlaut)
         if your charset allows it.  If not, use "Mueller". */
        strcpy (about->text, _("Konica library\n"
                "Lutz Mueller <lutz@users.sourceforge.net>\n"
                "Support for all Konica and several HP cameras."));

        return (GP_OK);
}

static int
camera_get_config (Camera* camera, CameraWidget** window, GPContext *context)
{
        CameraWidget *widget;
        CameraWidget *section;
        KStatus status;
        KPreferences preferences;
        int     year_4_digits;
        struct tm       tm_struct;
        time_t          t;
        float value_float;
        const char *name;
        GP_SYSTEM_DIR d;
        GP_SYSTEM_DIRENT de;
      unsigned int id;

        /* Get the current settings. */
      id = gp_context_progress_start (context, 2,
                              _("Getting configuration..."));
        C(k_get_status (camera->port, context, &status));
      gp_context_progress_update (context, id, 1);
        C(k_get_preferences (camera->port, context, &preferences));
      gp_context_progress_stop (context, id);

        /* Create the window. */
        gp_widget_new (GP_WIDGET_WINDOW, _("Konica Configuration"), window);

        /************************/
        /* Persistent Settings  */
        /************************/
        gp_widget_new (GP_WIDGET_SECTION, _("Persistent Settings"), &section);
        gp_widget_append (*window, section);

        /* Date */
        gp_widget_new (GP_WIDGET_DATE, _("Date and Time"), &widget);
        gp_widget_append (section, widget);
        if (status.date.year > 80) year_4_digits = status.date.year + 1900;
        else year_4_digits = status.date.year + 2000;
        tm_struct.tm_year = year_4_digits - 1900;
        tm_struct.tm_mon = status.date.month - 1;
        tm_struct.tm_mday = status.date.day;
        tm_struct.tm_hour = status.date.hour;
        tm_struct.tm_min = status.date.minute;
        tm_struct.tm_sec = status.date.second;
        t = mktime (&tm_struct);
        gp_widget_set_value (widget, &t);

        /* Beep */
        gp_widget_new (GP_WIDGET_RADIO, _("Beep"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("On"));
        gp_widget_add_choice (widget, _("Off"));
        switch (preferences.beep) {
        case 0:
                gp_widget_set_value (widget, _("Off"));
                break;
        default:
                gp_widget_set_value (widget, _("On"));
                break;
        }
        gp_widget_set_info (widget, _("Shall the camera beep when taking a "
                            "picture?"));

        /* Self Timer Time */
        gp_widget_new (GP_WIDGET_RANGE, _("Self Timer Time"), &widget);
        gp_widget_append (section, widget);
        gp_widget_set_range (widget, 3, 40, 1);
        value_float = preferences.self_timer_time;
        gp_widget_set_value (widget, &value_float);

        /* Auto Off Time */
        gp_widget_new (GP_WIDGET_RANGE, _("Auto Off Time"), &widget);
        gp_widget_append (section, widget);
        gp_widget_set_range (widget, 1, 255, 1);
        value_float = preferences.shutoff_time;
        gp_widget_set_value (widget, &value_float);

        /* Slide Show Interval */
        gp_widget_new (GP_WIDGET_RANGE, _("Slide Show Interval"), &widget);
        gp_widget_append (section, widget);
        gp_widget_set_range (widget, 1, 30, 1);
        value_float = preferences.slide_show_interval;
        gp_widget_set_value (widget, &value_float);

        /* Resolution */
        gp_widget_new (GP_WIDGET_RADIO, _("Resolution"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("Low (576 x 436)"));
        gp_widget_add_choice (widget, _("Medium (1152 x 872)"));
        gp_widget_add_choice (widget, _("High (1152 x 872)"));
        switch (status.resolution) {
        case 1:
                gp_widget_set_value (widget, _("High (1152 x 872)"));
                break;
        case 3:
                gp_widget_set_value (widget, _("Low (576 x 436)"));
                break;
        default:
                gp_widget_set_value (widget, _("Medium (1152 x 872)"));
                break;
        }

        /****************/
        /* Localization */
        /****************/
        gp_widget_new (GP_WIDGET_SECTION, _("Localization"), &section);
        gp_widget_append (*window, section);

        /* Language */
        d = GP_SYSTEM_OPENDIR (LOCALIZATION);
        if (d) {
                gp_widget_new (GP_WIDGET_MENU, _("Language"), &widget);
                gp_widget_append (section, widget);
                while ((de = GP_SYSTEM_READDIR (d))) {
                        name = GP_SYSTEM_FILENAME (de);
                        if (name && (*name != '.'))
                                gp_widget_add_choice (widget, name);
                }
                gp_widget_set_value (widget, _("None selected"));
        }

        /* TV output format */
        gp_widget_new (GP_WIDGET_MENU, _("TV Output Format"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("NTSC"));
        gp_widget_add_choice (widget, _("PAL"));
        gp_widget_add_choice (widget, _("Do not display TV menu"));
        gp_widget_set_value (widget, _("None selected"));

        /* Date format */
        gp_widget_new (GP_WIDGET_MENU, _("Date Format"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("Month/Day/Year"));
        gp_widget_add_choice (widget, _("Day/Month/Year"));
        gp_widget_add_choice (widget, _("Year/Month/Day"));
        gp_widget_set_value (widget, _("None selected"));

        /********************************/
        /* Session-persistent Settings  */
        /********************************/
        gp_widget_new (GP_WIDGET_SECTION, _("Session-persistent Settings"),
                       &section);
        gp_widget_append (*window, section);

        /* Flash */
        gp_widget_new (GP_WIDGET_RADIO, _("Flash"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("Off"));
        gp_widget_add_choice (widget, _("On"));
        gp_widget_add_choice (widget, _("On, red-eye reduction"));
        gp_widget_add_choice (widget, _("Auto"));
        gp_widget_add_choice (widget, _("Auto, red-eye reduction"));
        switch (status.flash) {
        case 0:
                gp_widget_set_value (widget, _("Off"));
                break;
        case 1:
                gp_widget_set_value (widget, _("On"));
                break;
        case 5:
                gp_widget_set_value (widget, _("On, red-eye reduction"));
                break;
        case 6:
                gp_widget_set_value (widget, _("Auto, red-eye reduction"));
                break;
        default:
                gp_widget_set_value (widget, _("Auto"));
                break;
        }

        /* Exposure */
        gp_widget_new (GP_WIDGET_RANGE, _("Exposure"), &widget);
        gp_widget_append (section, widget);
        gp_widget_set_range (widget, 0, 255, 1);
        value_float = status.exposure;
        gp_widget_set_value (widget, &value_float);

        /* Focus */
        gp_widget_new (GP_WIDGET_RADIO, _("Focus"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("Fixed"));
        gp_widget_add_choice (widget, _("Auto"));
        switch ((unsigned int) (status.focus / 2)) {
        case 1:
                gp_widget_set_value (widget, _("Auto"));
                break;
        default:
                gp_widget_set_value (widget, _("Fixed"));
                break;
        }

        /************************/
        /* Volatile Settings    */
        /************************/
        gp_widget_new (GP_WIDGET_SECTION, _("Volatile Settings"), &section);
        gp_widget_append (*window, section);

        /* Self Timer */
        gp_widget_new (GP_WIDGET_RADIO, _("Self Timer"), &widget);
        gp_widget_append (section, widget);
        gp_widget_add_choice (widget, _("Self Timer (only next picture)"));
        gp_widget_add_choice (widget, _("Normal"));
        switch (status.focus % 2) {
        case 1:
                gp_widget_set_value (widget, _("Self Timer ("
                                     "next picture only)"));
                break;
        default:
                gp_widget_set_value (widget, _("Normal"));
                break;
        }

        /* That's it. */
        return (GP_OK);
}

static int
camera_set_config (Camera *camera, CameraWidget *window, GPContext *context)
{
        CameraWidget *section;
        CameraWidget *widget_focus;
        CameraWidget *widget_self_timer;
        CameraWidget *widget;
        KDate date;
        KDateFormat date_format = K_DATE_FORMAT_YEAR_MONTH_DAY;
        KTVOutputFormat tv_output_format = K_TV_OUTPUT_FORMAT_HIDE;
        unsigned int beep = 0;
      int i, j = 0;
        unsigned char *data;
        long int data_size;
        unsigned char focus_self_timer = 0;
      float f;
        char *c;
        struct tm *tm_struct;
        int result;

        GP_DEBUG ("*** ENTER: camera_set_config ***");

        /************************/
        /* Persistent Settings  */
        /************************/
        gp_widget_get_child_by_label (window, _("Persistent Settings"),
                                      &section);

        /* Date & Time */
        gp_widget_get_child_by_label (section, _("Date and Time"), &widget);
        if (gp_widget_changed (widget)) {
                time_t xtime;

                gp_widget_get_value (widget, &i);
                xtime = i;
                tm_struct = localtime (&xtime);
                date.year   = tm_struct->tm_year - 100;
                date.month  = tm_struct->tm_mon + 1;
                date.day    = tm_struct->tm_mday;
                date.hour   = tm_struct->tm_hour;
                date.minute = tm_struct->tm_min;
                date.second = tm_struct->tm_sec;
                C(k_set_date_and_time (camera->port, context, date));
        }

        /* Beep */
        gp_widget_get_child_by_label (section, _("Beep"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &c);
                if (strcmp (c, _("Off")) == 0)
                        beep = 0;
                else
                        beep = 1;
                C(k_set_preference (camera->port, context,
                                     K_PREFERENCE_BEEP, beep));
        }

        /* Self Timer Time */
        gp_widget_get_child_by_label (section, _("Self Timer Time"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &f);
                C(k_set_preference (camera->port, context,
                        K_PREFERENCE_SELF_TIMER_TIME, (int) f));
        }

        /* Auto Off Time */
        gp_widget_get_child_by_label (section, _("Auto Off Time"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &f);
                C(k_set_preference (camera->port, context,
                                        K_PREFERENCE_AUTO_OFF_TIME, (int) f));
        }

        /* Slide Show Interval */
        gp_widget_get_child_by_label (section, _("Slide Show Interval"),
                                      &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &f);
                C(k_set_preference (camera->port, context,
                                K_PREFERENCE_SLIDE_SHOW_INTERVAL, (int) f));
        }

        /* Resolution */
        gp_widget_get_child_by_label (section, _("Resolution"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &c);
                if (!strcmp (c, _("High (1152 x 872)")))
                        j = 1;
                else if (!strcmp (c, _("Low (576 x 436)")))
                        j = 3;
                else
                        j = 0;
                C(k_set_preference (camera->port, context,
                                        K_PREFERENCE_RESOLUTION, j));
        }

        /****************/
        /* Localization */
        /****************/
        gp_widget_get_child_by_label (window, _("Localization"), &section);

        /* Localization File */
        C(gp_widget_get_child_by_label (section, _("Language"), &widget));
      C(result = gp_widget_changed (widget));
      if (result) {
            C(gp_widget_get_value (widget, &c));
                if (strcmp (c, _("None selected"))) {
                        data = NULL;
                        data_size = 0;

                        /* Read localization file */
                        result = localization_file_read (camera, c,
                                                         &data, &data_size,
                                           context);
                        if (result != GP_OK) {
                                free (data);
                                return (result);
                        }

                        /* Go! */
                        result = k_localization_data_put (camera->port, context,
                                                          data, data_size);
                        free (data);
                        C(result);
                }
        }

        /* TV Output Format */
        gp_widget_get_child_by_label (section, _("TV Output Format"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &c);
                if (strcmp (c, _("None selected"))) {
                        if (!strcmp (c, _("NTSC")))
                                tv_output_format = K_TV_OUTPUT_FORMAT_NTSC;
                        else if (!strcmp (c, _("PAL")))
                                tv_output_format = K_TV_OUTPUT_FORMAT_PAL;
                        else if (!strcmp (c, _("Do not display TV menu")))
                                tv_output_format = K_TV_OUTPUT_FORMAT_HIDE;
                        else
                        return (GP_ERROR);
                        C(k_localization_tv_output_format_set (
                                        camera->port, context, tv_output_format));
                }
        }

        /* Date Format */
        gp_widget_get_child_by_label (section, _("Date Format"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &c);
                if (strcmp (c, _("None selected"))) {
                        if (!strcmp (c, _("Month/Day/Year")))
                                date_format = K_DATE_FORMAT_MONTH_DAY_YEAR;
                        else if (!strcmp (c, _("Day/Month/Year")))
                                date_format = K_DATE_FORMAT_DAY_MONTH_YEAR;
                        else if (!strcmp (c, _("Year/Month/Day")))
                                date_format = K_DATE_FORMAT_YEAR_MONTH_DAY;
                        else
                        return (GP_ERROR);
                        C(k_localization_date_format_set (
                                    camera->port, context, date_format));
                }
        }

        /********************************/
        /* Session-persistent Settings  */
        /********************************/
        gp_widget_get_child_by_label (window, _("Session-persistent Settings"),
                                      &section);

        /* Flash */
        gp_widget_get_child_by_label (section, _("Flash"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &c);
                if (!strcmp (c, _("Off")))
                        j = 0;
                else if (!strcmp (c, _("On")))
                        j = 1;
                else if (!strcmp (c, _("On, red-eye reduction")))
                        j = 5;
                else if (!strcmp (c, _("Auto")))
                        j = 2;
                else
                        j = 6;
                C(k_set_preference (camera->port, context,
                                     K_PREFERENCE_FLASH, j));
        }

        /* Exposure */
        gp_widget_get_child_by_label (section, _("Exposure"), &widget);
        if (gp_widget_changed (widget)) {
                gp_widget_get_value (widget, &f);
                C(k_set_preference (camera->port, context,
                                        K_PREFERENCE_EXPOSURE, (int) f));
        }

        /* Focus will be set together with self timer. */
        gp_widget_get_child_by_label (section, _("Focus"), &widget_focus);

        /************************/
        /* Volatile Settings    */
        /************************/
        gp_widget_get_child_by_label (window, _("Volatile Settings"), &section);

        /* Self Timer (and Focus) */
        gp_widget_get_child_by_label (section, _("Self Timer"),
                                      &widget_self_timer);
        if (gp_widget_changed (widget_focus) &&
            gp_widget_changed (widget_self_timer)) {
                gp_widget_get_value (widget_focus, &c);
                if (!strcmp (c, _("Auto")))
                        focus_self_timer = 2;
                else
                        focus_self_timer = 0;
                gp_widget_get_value (widget_self_timer, &c);
                if (!strcmp (c, _("Self Timer (only next picture)")))
                        focus_self_timer++;
                C(k_set_preference (camera->port, context,
                        K_PREFERENCE_FOCUS_SELF_TIMER, focus_self_timer));
        }

        /* We are done. */
        return (GP_OK);
}

int
localization_file_read (Camera *camera, const char *file_name,
                        unsigned char **data, long int *data_size,
                  GPContext *context)
{
        FILE *file;
        unsigned int j;
        int f;
        unsigned char c[] = "\0\0";
        unsigned long line_number;
        unsigned char checksum;
        unsigned long fcs;
        unsigned int d;
        char path[1024];

        strcpy (path, LOCALIZATION);
        strcat (path, "/");
        strcat (path, file_name);
      gp_log (GP_LOG_DEBUG, "konica", "Uploading '%s'...", path);
        file = fopen (path, "r");
        if (!file) {
            gp_context_error (context, _("Could not find localization "
                  "data at '%s'"), path);
                return (GP_ERROR_FILE_NOT_FOUND);
      }

        /* Allocate the memory */
        *data_size = 0;
        *data = malloc (sizeof (char) * 65536);
        if (!*data)
                return (GP_ERROR_NO_MEMORY);

        j = 0;
        line_number = 1;
        do {
                f = fgetc (file);
                switch (f) {
                case '\n':
                        line_number++;
                        continue;
                case EOF:
                        break;
                case '#':
                        /************************/
                        /* Comment: Discard.    */
                        /************************/
                        do {
                                f = fgetc (file);
                        } while ((f != '\n') && (f != EOF));
                        if (f == '\n') line_number++;
                        continue;
                case '\t':
                        continue;
                case ' ':
                        continue;
                default:
                        /****************************************/
                        /* j == 0: We have to read the second   */
                        /* half of the byte to send.            */
                        /* j == 1: We'll compose our byte.      */
                        /****************************************/
                        if ((f != '0') && (f != '1') && (f != '2') &&
                            (f != '3') && (f != '4') && (f != '5') &&
                            (f != '6') && (f != '7') && (f != '8') &&
                            (f != '9') && (f != 'A') && (f != 'B') &&
                            (f != 'C') && (f != 'D') && (f != 'E') &&
                            (f != 'F')) {
                                GP_DEBUG ("Error in localization "
                                "file: '%c' in line %i is "
                                "not allowed.", f,
                                (int) line_number);
                                fclose (file);
                                return (GP_ERROR_CORRUPTED_DATA);
                        }
                        c[j] = (char) f;
                        if (j == 1) {
                                if (sscanf (&c[0], "%X", &d) != 1) {
                              GP_DEBUG ("Error in localization "
                                      "file.");
                                        return (GP_ERROR_CORRUPTED_DATA);
                                }
                                (*data)[*data_size] = d;
                                (*data_size)++;
                                if (*data_size == 65536) {
                                        gp_context_error (context,
                                    _("Localization file too long!"));
                                        fclose (file);
                                        return (FALSE);
                                }
                        }
                        j = 1 - j;
                        continue;
                }
        } while (f != EOF);
        fclose (file);

        /* Calculate and check checksum. */
        checksum = 0;
      gp_log (GP_LOG_DEBUG, "konica", "Checksum not implemented!");
        /*FIXME: There's a checksum at (*data)[100]. I could not
          figure out how it is calculated. */

        /* Calculate and check frame check sequence. */
        fcs = 0;

      gp_log (GP_LOG_DEBUG, "konica", "Frame check sequence "
            "not implemented!");
        /* FIXME: There's a frame check sequence at (*data)[108]
           and (*data)[109]. I could not figure out how it is
           calculated. */
        gp_log (GP_LOG_DEBUG, "konica", "-> %i bytes read.\n",
            (int) *data_size);
        return (GP_OK);
}

static int
camera_pre_func (Camera *camera, GPContext *context)
{
      /* Set best speed */
      set_speed (camera, 0, context);

      return (GP_OK);
}

static int
camera_post_func (Camera *camera, GPContext *context)
{
      /* Set default speed */
      set_speed (camera, 9600, context);

      return (GP_OK);
}

int
camera_init (Camera* camera, GPContext *context)
{
        int i, speed;
        GPPortSettings settings;
      CameraAbilities a;

        /* First, set up all the function pointers. */
      camera->functions->pre_func         = camera_pre_func;
      camera->functions->post_func        = camera_post_func;
        camera->functions->exit                 = camera_exit;
        camera->functions->get_config           = camera_get_config;
        camera->functions->set_config           = camera_set_config;
        camera->functions->capture              = camera_capture;
        camera->functions->capture_preview      = camera_capture_preview;
        camera->functions->summary              = camera_summary;
        camera->functions->about                = camera_about;

        /* Lookup model information */
      gp_camera_get_abilities (camera, &a);
        for (i = 0; konica_cameras [i].model; i++)
                if (!strcmp (konica_cameras [i].model, a.model))
                        break;
        if (!konica_cameras [i].model)
                return (GP_ERROR_MODEL_NOT_FOUND);

      /* Store some data we constantly need. */
      camera->pl = malloc (sizeof (CameraPrivateLibrary));
      memset (camera->pl, 0, sizeof (CameraPrivateLibrary));
      camera->pl->image_id_long = konica_cameras [i].image_id_long;

        /* Initiate the connection */
      C(gp_port_get_settings (camera->port, &settings));
        switch (camera->port->type) {
        case GP_PORT_SERIAL:

                /* Set up the device */
                settings.serial.bits = 8;
                settings.serial.parity = 0;
                settings.serial.stopbits = 1;
                C(gp_port_set_settings (camera->port, settings));

                /* Initiate the connection */
            C(speed = test_speed (camera, context));
#if 0
/* Ideally, we need to reset the speed to the speed that we encountered
   after each operation (multiple programs accessing the camera). However,
   that takes quite a bit of time for HP cameras... */
            camera->pl->speed = speed;
#endif

                break;
        case GP_PORT_USB:

            /* Use the defaults the core parsed */
                C(gp_port_set_settings (camera->port, settings));

                /* Initiate the connection */
                C(k_init (camera->port, context));

                break;
        default:
                return (GP_ERROR_UNKNOWN_PORT);
        }

        /* Set up the filesystem */
      C(gp_filesystem_set_info_funcs (camera->fs, get_info_func,
                              set_info_func, camera));
      C(gp_filesystem_set_list_funcs (camera->fs, file_list_func,
                              NULL, camera));
      C(gp_filesystem_set_file_funcs (camera->fs, get_file_func,
                              delete_file_func, camera));
      C(gp_filesystem_set_folder_funcs (camera->fs, NULL, delete_all_func,
                              NULL, NULL, camera));

      /* Ping the camera every minute to prevent shut-down. */
      camera->pl->timeout = gp_camera_start_timeout (camera, PING_TIMEOUT,
                                           timeout_func);

        return (GP_OK);
}


Generated by  Doxygen 1.6.0   Back to index