* lowlevel.c: Fix bug introduced with last patch. git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@3478 67ed7778-7388-44ab-90cf-0a291f65f57c
1272 lines
43 KiB
C
1272 lines
43 KiB
C
/* library.c
|
|
*
|
|
* Copyright (C) 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 "library.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
#include <gphoto2-library.h>
|
|
#include <gphoto2-debug.h>
|
|
#include <gphoto2-port-log.h>
|
|
|
|
#include "konica.h"
|
|
|
|
#ifdef ENABLE_NLS
|
|
# include <libintl.h>
|
|
# undef _
|
|
# define _(String) dgettext (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 CHECK(c,r) {int ret=(r);if(ret<0){log_error(c,ret);return(ret);}}
|
|
#define CHECK_NULL(r) {if (!(r)) return (GP_ERROR_BAD_PARAMETERS);}
|
|
|
|
#define LOG_ERR(c,r,e) {if ((r)==result) gp_camera_set_error((c),(e));}
|
|
#define GP_MODULE "konica"
|
|
|
|
static void
|
|
log_error (Camera *c, int result)
|
|
{
|
|
LOG_ERR (c, KONICA_ERROR_FOCUSING_ERROR, N_("Focusing error"));
|
|
LOG_ERR (c, KONICA_ERROR_IRIS_ERROR, N_("Iris error"));
|
|
LOG_ERR (c, KONICA_ERROR_STROBE_ERROR, N_("Strobe error"));
|
|
LOG_ERR (c, KONICA_ERROR_EEPROM_CHECKSUM_ERROR, N_("EEPROM checksum error"));
|
|
LOG_ERR (c, KONICA_ERROR_INTERNAL_ERROR1, N_("Internal error (1)"));
|
|
LOG_ERR (c, KONICA_ERROR_INTERNAL_ERROR2, N_("Internal error (2)"));
|
|
LOG_ERR (c, KONICA_ERROR_NO_CARD_PRESENT, N_("No card present"));
|
|
LOG_ERR (c, KONICA_ERROR_CARD_NOT_SUPPORTED, N_("Card not supported"));
|
|
LOG_ERR (c, KONICA_ERROR_CARD_REMOVED_DURING_ACCESS, N_("Card removed during access"));
|
|
LOG_ERR (c, KONICA_ERROR_IMAGE_NUMBER_NOT_VALID, N_("Image number not valid"));
|
|
LOG_ERR (c, KONICA_ERROR_CARD_CAN_NOT_BE_WRITTEN, N_("Card can not be written"));
|
|
LOG_ERR (c, KONICA_ERROR_CARD_IS_WRITE_PROTECTED, N_("Card is write protected"));
|
|
LOG_ERR (c, KONICA_ERROR_NO_SPACE_LEFT_ON_CARD, N_("No space left on card"));
|
|
LOG_ERR (c, KONICA_ERROR_IMAGE_PROTECTED, N_("No image erased as image protected"));
|
|
LOG_ERR (c, KONICA_ERROR_LIGHT_TOO_DARK, N_("Light too dark"));
|
|
LOG_ERR (c, KONICA_ERROR_AUTOFOCUS_ERROR, N_("Autofocus error"));
|
|
LOG_ERR (c, KONICA_ERROR_SYSTEM_ERROR, N_("System error"));
|
|
LOG_ERR (c, KONICA_ERROR_ILLEGAL_PARAMETER, N_("Illegal parameter"));
|
|
LOG_ERR (c, KONICA_ERROR_COMMAND_CANNOT_BE_CANCELLED, N_("Command can not be cancelled"));
|
|
LOG_ERR (c, KONICA_ERROR_LOCALIZATION_DATA_EXCESS, N_("Localization data excess"));
|
|
LOG_ERR (c, KONICA_ERROR_LOCALIZATION_DATA_CORRUPT, N_("Localization data corrupt"));
|
|
LOG_ERR (c, KONICA_ERROR_UNSUPPORTED_COMMAND, N_("Unsupported command"));
|
|
LOG_ERR (c, KONICA_ERROR_OTHER_COMMAND_EXECUTING, N_("Other command executing"));
|
|
LOG_ERR (c, KONICA_ERROR_COMMAND_ORDER_ERROR, N_("Command order error"));
|
|
LOG_ERR (c, KONICA_ERROR_UNKNOWN_ERROR, N_("Unknown error"));
|
|
};
|
|
|
|
static struct {
|
|
const char *model;
|
|
int image_id_long;
|
|
int vendor;
|
|
int product;
|
|
int inep;
|
|
int outep;
|
|
} konica_cameras[] = {
|
|
{"Konica Q-EZ", 0, 0, 0, 0, 0},
|
|
{"Konica Q-M100", 0, 0, 0, 0, 0},
|
|
{"Konica Q-M100V", 0, 0, 0, 0, 0},
|
|
{"Konica Q-M200", 1, 0, 0, 0, 0},
|
|
{"HP PhotoSmart C20", 0, 0, 0, 0, 0},
|
|
{"HP PhotoSmart C30", 0, 0, 0, 0, 0},
|
|
{"HP PhotoSmart C200", 1, 0, 0, 0, 0},
|
|
{NULL, 0, 0, 0, 0, 0}
|
|
};
|
|
|
|
struct _CameraPrivateLibrary {
|
|
unsigned int speed;
|
|
int image_id_long;
|
|
};
|
|
|
|
|
|
static int localization_file_read (Camera* camera, const char* file_name,
|
|
unsigned char** data, long int* data_size);
|
|
|
|
static int
|
|
get_info (Camera *camera, unsigned int n, CameraFileInfo *info,
|
|
CameraFile *file)
|
|
{
|
|
unsigned long image_id;
|
|
unsigned int buffer_size, exif_size;
|
|
unsigned char *buffer = NULL;
|
|
int protected;
|
|
|
|
GP_DEBUG ("*** Getting info for picture %i...", n);
|
|
CHECK (camera, k_get_image_information (camera->port,
|
|
camera->pl->image_id_long, n, &image_id, &exif_size, &protected,
|
|
&buffer, &buffer_size));
|
|
|
|
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);
|
|
|
|
/* Make a JPEG file out of it (for parser) */
|
|
gp_file_append (file, "\xff\xd8", 2);
|
|
gp_file_append (file, buffer, buffer_size);
|
|
gp_file_append (file, "\x01", 1);
|
|
gp_file_append (file, "\xff\xda", 2);
|
|
gp_file_append (file, "\x00\x02", 2);
|
|
}
|
|
free (buffer);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
|
|
void *data)
|
|
{
|
|
CameraFile *file;
|
|
CameraFileInfo info;
|
|
KStatus status;
|
|
unsigned int i;
|
|
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.
|
|
*/
|
|
CHECK (camera, k_get_status (camera->port, &status));
|
|
for (i = 0; i < status.pictures; i++) {
|
|
|
|
/* Get information */
|
|
gp_file_new (&file);
|
|
result = get_info (camera, i + 1, &info, file);
|
|
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);
|
|
gp_filesystem_set_info_noop (camera->fs, folder, info);
|
|
gp_filesystem_set_file_noop (camera->fs, folder, file);
|
|
gp_file_unref (file);
|
|
}
|
|
|
|
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++) {
|
|
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;
|
|
a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL;
|
|
gp_abilities_list_append (list, a);
|
|
}
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
set_speed (Camera *camera, unsigned int speed)
|
|
{
|
|
GPPortSettings settings;
|
|
KBitRate bit_rates;
|
|
KBitFlag bit_flags;
|
|
int i;
|
|
unsigned int speeds[] = {300, 600, 1200, 2400, 4800, 9600, 19200,
|
|
38400, 57600, 115200};
|
|
|
|
CHECK (camera, 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 */
|
|
CHECK (camera, k_get_io_capability (camera->port, &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;
|
|
CHECK (camera, k_set_io_capability (camera->port, bit_rates,
|
|
bit_flags));
|
|
gp_log (GP_LOG_DEBUG, "konica", "Reconnecting at speed %d", speed);
|
|
settings.serial.speed = speed;
|
|
CHECK (camera, gp_port_set_settings (camera->port, settings));
|
|
CHECK (camera, k_init (camera->port));
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
test_speed (Camera *camera)
|
|
{
|
|
int i;
|
|
unsigned int speeds[] = {115200, 9600, 57600, 38400, 19200,
|
|
4800, 2400, 1200, 600, 300};
|
|
GPPortSettings settings;
|
|
|
|
CHECK (camera, gp_port_get_settings (camera->port, &settings));
|
|
for (i = 0; i < 10; i++) {
|
|
gp_log (GP_LOG_DEBUG, "konica", "Testing speed %d",
|
|
speeds[i]);
|
|
settings.serial.speed = speeds[i];
|
|
CHECK (camera, gp_port_set_settings (camera->port, settings));
|
|
if (k_init (camera->port) == GP_OK)
|
|
break;
|
|
}
|
|
if (i == 10)
|
|
return (GP_ERROR_IO);
|
|
|
|
return (speeds[i]);
|
|
}
|
|
|
|
static int
|
|
set_info_func (CameraFilesystem *fs, const char *folder, const char *file,
|
|
CameraFileInfo info, void *data)
|
|
{
|
|
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;
|
|
CHECK (camera, k_set_protect_status (camera->port,
|
|
camera->pl->image_id_long, image_id, protected));
|
|
}
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
get_info_func (CameraFilesystem *fs, const char *folder, const char *filename,
|
|
CameraFileInfo *info, void *data)
|
|
{
|
|
Camera *camera = data;
|
|
CameraFile *file;
|
|
int n, result;
|
|
|
|
/* We need image numbers starting with 1 */
|
|
n = gp_filesystem_number (camera->fs, folder, filename);
|
|
if (n < 0)
|
|
return (n);
|
|
n++;
|
|
|
|
gp_file_new (&file);
|
|
result = get_info (camera, n, info, file);
|
|
if (result < 0) {
|
|
gp_file_unref (file);
|
|
return (result);
|
|
}
|
|
gp_filesystem_set_file_noop (fs, folder, file);
|
|
gp_file_unref (file);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_exit (Camera* camera)
|
|
{
|
|
if (camera->pl) {
|
|
free (camera->pl);
|
|
camera->pl = NULL;
|
|
}
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
delete_all_func (CameraFilesystem *fs, const char* folder, void *data)
|
|
{
|
|
Camera *camera = data;
|
|
unsigned int not_erased = 0;
|
|
|
|
if (strcmp (folder, "/"))
|
|
return (GP_ERROR_DIRECTORY_NOT_FOUND);
|
|
|
|
CHECK (camera, k_erase_all (camera->port, ¬_erased));
|
|
|
|
if (not_erased) {
|
|
gp_camera_set_error (camera, _("%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)
|
|
{
|
|
Camera *camera = data;
|
|
unsigned long image_id;
|
|
char image_id_string[] = {0, 0, 0, 0, 0, 0, 0};
|
|
unsigned char *fdata = NULL;
|
|
long int size;
|
|
|
|
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 the image. */
|
|
switch (type) {
|
|
case GP_FILE_TYPE_PREVIEW:
|
|
CHECK (camera, k_get_image (camera->port,
|
|
camera->pl->image_id_long,
|
|
image_id, K_THUMBNAIL, (unsigned char **) &fdata,
|
|
(unsigned int *) &size));
|
|
break;
|
|
case GP_FILE_TYPE_NORMAL:
|
|
CHECK (camera, k_get_image (camera->port,
|
|
camera->pl->image_id_long,
|
|
image_id, K_IMAGE_EXIF, (unsigned char **) &fdata,
|
|
(unsigned int *) &size));
|
|
break;
|
|
default:
|
|
return (GP_ERROR_NOT_SUPPORTED);
|
|
}
|
|
|
|
CHECK (camera, gp_file_set_data_and_size (file, fdata, size));
|
|
CHECK (camera, 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)
|
|
{
|
|
Camera *camera = data;
|
|
char tmp[] = {0, 0, 0, 0, 0, 0, 0};
|
|
unsigned long image_id;
|
|
|
|
CHECK_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);
|
|
|
|
CHECK (camera, k_erase_image (camera->port, camera->pl->image_id_long,
|
|
image_id));
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_summary (Camera* camera, CameraText* summary)
|
|
{
|
|
char *model = NULL;
|
|
char *serial_number = NULL;
|
|
unsigned char hardware_version_major;
|
|
unsigned char hardware_version_minor;
|
|
unsigned char software_version_major;
|
|
unsigned char software_version_minor;
|
|
unsigned char testing_software_version_major;
|
|
unsigned char testing_software_version_minor;
|
|
char *name = NULL;
|
|
char *manufacturer = NULL;
|
|
|
|
gp_debug_printf (GP_DEBUG_LOW, "konica", "*** ENTER: camera_summary "
|
|
"***");
|
|
CHECK (camera, k_get_information (camera->port, &model, &serial_number,
|
|
&hardware_version_major, &hardware_version_minor,
|
|
&software_version_major, &software_version_minor,
|
|
&testing_software_version_major,
|
|
&testing_software_version_minor, &name, &manufacturer));
|
|
|
|
sprintf (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"),
|
|
model, serial_number, hardware_version_major,
|
|
hardware_version_minor, software_version_major,
|
|
software_version_minor, testing_software_version_major,
|
|
testing_software_version_minor, name, manufacturer);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_capture_preview (Camera* camera, CameraFile* file)
|
|
{
|
|
unsigned char *data = NULL;
|
|
long int size = 0;
|
|
|
|
CHECK (camera, k_get_preview (camera->port, TRUE,
|
|
&data, (unsigned int *) &size));
|
|
CHECK (camera, gp_file_set_data_and_size (file, data, size));
|
|
CHECK (camera, gp_file_set_mime_type (file, GP_MIME_JPEG));
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_capture (Camera* camera, CameraCaptureType type, CameraFilePath* path)
|
|
{
|
|
unsigned long image_id;
|
|
int exif_size;
|
|
unsigned char *buffer = NULL;
|
|
unsigned int buffer_size;
|
|
int protected;
|
|
CameraFile *file = NULL;
|
|
CameraFileInfo info;
|
|
|
|
CHECK_NULL (camera && path);
|
|
|
|
/* We only support capturing of images */
|
|
if (type != GP_CAPTURE_IMAGE)
|
|
return (GP_ERROR_NOT_SUPPORTED);
|
|
|
|
/* Take the picture. */
|
|
CHECK (camera, k_take_picture (camera->port, camera->pl->image_id_long,
|
|
&image_id, &exif_size, &buffer, &buffer_size, &protected));
|
|
sprintf (path->name, "%06i.jpeg", (int) image_id);
|
|
strcpy (path->folder, "/");
|
|
CHECK (camera, gp_filesystem_append (camera->fs, path->folder,
|
|
path->name));
|
|
|
|
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);
|
|
|
|
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_PREVIEW);
|
|
gp_file_set_data_and_size (file, buffer, buffer_size);
|
|
free (buffer);
|
|
gp_filesystem_set_file_noop (camera->fs, path->folder, file);
|
|
gp_file_unref (file);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_about (Camera* camera, CameraText* about)
|
|
{
|
|
CHECK_NULL (camera && about);
|
|
|
|
strcpy (about->text,
|
|
_("Konica library\n"
|
|
"Lutz Müller <urc8@rz.uni-karlsruhe.de>\n"
|
|
"Support for all Konica and several HP cameras."));
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_get_config (Camera* camera, CameraWidget** window)
|
|
{
|
|
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;
|
|
|
|
gp_debug_printf (GP_DEBUG_LOW, "konica", "*** ENTER: "
|
|
"camera_get_config ***");
|
|
|
|
/* Get the current settings. */
|
|
CHECK (camera, k_get_status (camera->port, &status));
|
|
CHECK (camera, k_get_preferences (camera->port, &preferences));
|
|
|
|
/* Create the window. */
|
|
gp_widget_new (GP_WIDGET_WINDOW, _("Konica Configuration"), window);
|
|
|
|
/************************/
|
|
/* Persistent Settings */
|
|
/************************/
|
|
gp_widget_new (GP_WIDGET_SECTION, _("Persistent Settings"), §ion);
|
|
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;
|
|
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"), §ion);
|
|
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"),
|
|
§ion);
|
|
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"), §ion);
|
|
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)
|
|
{
|
|
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_printf (GP_DEBUG_LOW, "konica", "*** ENTER: "
|
|
"camera_set_config ***");
|
|
|
|
/************************/
|
|
/* Persistent Settings */
|
|
/************************/
|
|
gp_widget_get_child_by_label (window, _("Persistent Settings"),
|
|
§ion);
|
|
|
|
/* Date & Time */
|
|
gp_widget_get_child_by_label (section, _("Date and Time"), &widget);
|
|
if (gp_widget_changed (widget)) {
|
|
gp_widget_get_value (widget, &i);
|
|
tm_struct = localtime ((time_t*) &i);
|
|
date.year = tm_struct->tm_year - 100;
|
|
date.month = tm_struct->tm_mon;
|
|
date.day = tm_struct->tm_mday;
|
|
date.hour = tm_struct->tm_hour;
|
|
date.minute = tm_struct->tm_min;
|
|
date.second = tm_struct->tm_sec;
|
|
CHECK (camera, k_set_date_and_time (camera->port, 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;
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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);
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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);
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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);
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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;
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
K_PREFERENCE_RESOLUTION, j));
|
|
}
|
|
|
|
/****************/
|
|
/* Localization */
|
|
/****************/
|
|
gp_widget_get_child_by_label (window, _("Localization"), §ion);
|
|
|
|
/* Localization File */
|
|
CHECK (camera, gp_widget_get_child_by_label (section, _("Language"),
|
|
&widget));
|
|
CHECK (camera, result = gp_widget_changed (widget));
|
|
if (result) {
|
|
CHECK (camera, 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);
|
|
if (result != GP_OK) {
|
|
free (data);
|
|
return (result);
|
|
}
|
|
|
|
/* Go! */
|
|
result = k_localization_data_put (camera->port,
|
|
data, data_size);
|
|
free (data);
|
|
CHECK (camera, 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);
|
|
CHECK (camera, k_localization_tv_output_format_set (
|
|
camera->port, 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);
|
|
CHECK (camera, k_localization_date_format_set (
|
|
camera->port, date_format));
|
|
}
|
|
}
|
|
|
|
/********************************/
|
|
/* Session-persistent Settings */
|
|
/********************************/
|
|
gp_widget_get_child_by_label (window, _("Session-persistent Settings"),
|
|
§ion);
|
|
|
|
/* 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;
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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);
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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"), §ion);
|
|
|
|
/* 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++;
|
|
CHECK (camera, k_set_preference (camera->port,
|
|
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)
|
|
{
|
|
FILE *file;
|
|
unsigned long j;
|
|
char 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_camera_set_error (camera, _("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_printf (GP_DEBUG_LOW, "konica",
|
|
"Error in localization "
|
|
"file: '%c' in line %i is "
|
|
"not allowed.", f,
|
|
(int) line_number);
|
|
fclose (file);
|
|
return (GP_ERROR_CORRUPTED_DATA);
|
|
}
|
|
c[j] = f;
|
|
if (j == 1) {
|
|
if (sscanf (&c[0], "%X", &d) != 1) {
|
|
gp_debug_printf (GP_DEBUG_LOW,
|
|
"konica", "Error in "
|
|
"localization file.");
|
|
return (GP_ERROR_CORRUPTED_DATA);
|
|
}
|
|
(*data)[*data_size] = d;
|
|
(*data_size)++;
|
|
if (*data_size == 65536) {
|
|
gp_camera_message (
|
|
camera,
|
|
_("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)
|
|
{
|
|
/* Set best speed */
|
|
set_speed (camera, 0);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
static int
|
|
camera_post_func (Camera *camera)
|
|
{
|
|
/* Set default speed */
|
|
set_speed (camera, 9600);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|
|
int
|
|
camera_init (Camera* camera)
|
|
{
|
|
int i, speed;
|
|
int inep, outep;
|
|
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);
|
|
inep = konica_cameras [i].inep;
|
|
outep = konica_cameras [i].outep;
|
|
|
|
/* Store some data we constantly need. */
|
|
camera->pl = malloc (sizeof (CameraPrivateLibrary));
|
|
camera->pl->speed = 0;
|
|
camera->pl->image_id_long = konica_cameras [i].image_id_long;
|
|
|
|
/* Initiate the connection */
|
|
CHECK (camera, 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;
|
|
CHECK (camera, gp_port_set_settings (camera->port, settings));
|
|
|
|
/* Initiate the connection */
|
|
speed = test_speed (camera);
|
|
CHECK (camera, speed);
|
|
#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:
|
|
|
|
/* Set up the device */
|
|
settings.usb.inep = inep;
|
|
settings.usb.outep = outep;
|
|
settings.usb.config = 1;
|
|
settings.usb.interface = 0;
|
|
settings.usb.altsetting = 0;
|
|
CHECK (camera, gp_port_set_settings (camera->port, settings));
|
|
|
|
/* Initiate the connection */
|
|
CHECK (camera, k_init (camera->port));
|
|
|
|
break;
|
|
default:
|
|
return (GP_ERROR_UNKNOWN_PORT);
|
|
}
|
|
|
|
/* Set up the filesystem */
|
|
gp_filesystem_set_info_funcs (camera->fs, get_info_func,
|
|
set_info_func, camera);
|
|
gp_filesystem_set_list_funcs (camera->fs, file_list_func,
|
|
NULL, camera);
|
|
gp_filesystem_set_file_funcs (camera->fs, get_file_func,
|
|
delete_file_func, camera);
|
|
gp_filesystem_set_folder_funcs (camera->fs, NULL, delete_all_func,
|
|
NULL, NULL, camera);
|
|
|
|
return (GP_OK);
|
|
}
|
|
|