/* * Jenoptik JD11 Camera Driver * Copyright 1999-2001 Marcus Meissner * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include #include "libgphoto2/i18n.h" #include "serial.h" int camera_id (CameraText *id) { strcpy(id->text, "JD11"); return (GP_OK); } int camera_abilities (CameraAbilitiesList *list) { CameraAbilities a; memset(&a,0,sizeof(a)); a.status = GP_DRIVER_STATUS_PRODUCTION; a.port = GP_PORT_SERIAL; a.speed[0] = 115200; a.speed[1] = 0; a.operations = GP_OPERATION_CONFIG; a.file_operations = GP_FILE_OPERATION_PREVIEW; a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL; strcpy(a.model, "Jenoptik:JD11"); gp_abilities_list_append(list, a); /* http://www.digitalkamera.de/Kameras/PrakticaQD500-de.htm (german) */ strcpy(a.model, "Praktica:QD500"); gp_abilities_list_append(list, a); /* Reported to be just a rebranded version by Russ Burdick * */ /* from Gallantcom, http://www.gallantcom.com/prodfaq-probe99.htm */ strcpy(a.model, "Quark:Probe 99"); gp_abilities_list_append(list, a); /* 'Argus DC-100' looks the same, see: * http://www.aaadigitalcameras.com/argus_digital_vga_compact_camera.html * but not reported yet. */ strcpy(a.model, "Argus:DC-100"); gp_abilities_list_append(list, a); /* 'Argus DC-2000' is the same (or uses the same software), check * http://www.arguscamera.com/tech_supp/camoper.htm */ strcpy(a.model, "Argus:DC-2000"); gp_abilities_list_append(list, a); /* http://www.digitaldreamco.com/shop/digital2000.html */ strcpy(a.model, "Digitaldream:DIGITAL 2000"); gp_abilities_list_append(list, a); /* The I/O Magic MagicImage 420 has a black cover, but otherwise * appears to be the same. (Not 100% sure.) * http://www.iomagic.com/support/digitalcameras/magicimage420/magicimage420main.htm */ strcpy(a.model, "IOMagic:MagicImage 420"); gp_abilities_list_append(list, a); return (GP_OK); } static int file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list, void *data, GPContext *context) { Camera *camera = (Camera*)data; if (strcmp(folder,"/")) return GP_ERROR_BAD_PARAMETERS; return jd11_index_reader(camera->port, fs, context); } static int get_file_func (CameraFilesystem *fs, const char *folder, const char *filename, CameraFileType type, CameraFile *file, void *user_data, GPContext *context) { Camera *camera = user_data; int image_no, result; image_no = gp_filesystem_number(fs, folder, filename, context); if(image_no < 0) return image_no; gp_file_set_mime_type (file, GP_MIME_PNM); switch (type) { case GP_FILE_TYPE_RAW: result = jd11_get_image_full(camera,file,image_no,1,context); break; case GP_FILE_TYPE_NORMAL: result = jd11_get_image_full(camera,file,image_no,0,context); break; case GP_FILE_TYPE_PREVIEW: /* We should never get here, we store the thumbs in the fs... */ return (GP_ERROR_NOT_SUPPORTED); default: return (GP_ERROR_NOT_SUPPORTED); } if (result < 0) return result; return (GP_OK); } static int delete_all_func (CameraFilesystem *fs, const char* folder, void *data, GPContext *context) { Camera *camera = data; if (strcmp (folder, "/")) return (GP_ERROR_DIRECTORY_NOT_FOUND); return jd11_erase_all(camera->port); } static int camera_manual (Camera *camera, CameraText *manual, GPContext *context) { strcpy(manual->text, _( "The JD11 camera works rather well with this driver.\n" "An RS232 interface @ 115 kbit is required for image transfer.\n" "The driver allows you to get\n\n" " - thumbnails (64x48 PGM format)\n" " - full images (640x480 PPM format)\n" )); return (GP_OK); } static int camera_about (Camera *camera, CameraText *about, GPContext *context) { strcpy (about->text, _("JD11\n" "Marcus Meissner \n" "Driver for the Jenoptik JD11 camera.\n" "Protocol reverse engineered using WINE and IDA.")); return (GP_OK); } static int camera_config_get (Camera *camera, CameraWidget **window, GPContext *context) { CameraWidget *widget,*section; float value_float,red,green,blue; int ret; gp_widget_new (GP_WIDGET_WINDOW, _("JD11 Configuration"), window); gp_widget_set_name (*window, "config"); gp_widget_new (GP_WIDGET_SECTION, _("Other Settings"), §ion); gp_widget_set_name (section, "othersettings"); gp_widget_append (*window, section); /* Bulb Exposure Time */ gp_widget_new (GP_WIDGET_RANGE, _("Bulb Exposure Time"), &widget); gp_widget_set_name (widget, "exposuretime"); gp_widget_append (section, widget); gp_widget_set_range (widget, 1, 9, 1); /* this is a write only capability */ value_float = 1; gp_widget_set_value (widget, &value_float); gp_widget_new (GP_WIDGET_SECTION, _("Color Settings"), §ion); gp_widget_append (*window, section); gp_widget_set_name (section, "colorsettings"); ret = jd11_get_rgb(camera->port,&red,&green,&blue); if (ret < GP_OK) return ret; gp_widget_new (GP_WIDGET_RANGE, _("Red"), &widget); gp_widget_append (section, widget); gp_widget_set_name (widget, "red"); gp_widget_set_range (widget, 50, 150, 1); red*=100.0; gp_widget_set_value (widget, &red); gp_widget_new (GP_WIDGET_RANGE, _("Green"), &widget); gp_widget_set_name (widget, "green"); gp_widget_append (section, widget); gp_widget_set_range (widget, 50, 150, 1); green*=100.0; gp_widget_set_value (widget, &green); gp_widget_new (GP_WIDGET_RANGE, _("Blue"), &widget); gp_widget_set_name (widget, "blue"); gp_widget_append (section, widget); gp_widget_set_range (widget, 50, 150, 1); blue*=100.0; gp_widget_set_value (widget, &blue); return (GP_OK); } static int camera_config_set (Camera *camera, CameraWidget *window, GPContext *context) { float f,red,green,blue; CameraWidget *widget,*section; int ret,changed = 0; /* * Check if the widgets' values have changed. If yes, tell the camera. */ gp_widget_get_child_by_label (window, _("Other Settings"), §ion); gp_widget_get_child_by_label (section,_("Bulb Exposure Time"), &widget); if (gp_widget_changed (widget)) { gp_widget_get_value (widget, &f); gp_widget_set_changed (widget, 0); ret = jd11_set_bulb_exposure(camera->port,(int)f); if (ret < GP_OK) return ret; } gp_widget_get_child_by_label (window, _("Color Settings"), §ion); gp_widget_get_child_by_label (section,_("Red"), &widget); changed|=gp_widget_changed (widget); gp_widget_set_changed (widget, 0); gp_widget_get_value (widget, &red); red/=100.0; gp_widget_get_child_by_label (section,_("Green"), &widget); changed|=gp_widget_changed (widget); gp_widget_set_changed (widget, 0); gp_widget_get_value (widget, &green); green/=100.0; gp_widget_get_child_by_label (section,_("Blue"), &widget); changed|=gp_widget_changed (widget); gp_widget_set_changed (widget, 0); gp_widget_get_value (widget, &blue); blue/=100.0; ret = GP_OK; if (changed) ret =jd11_set_rgb(camera->port,red,green,blue); return ret; } static CameraFilesystemFuncs fsfuncs = { .file_list_func = file_list_func, .get_file_func = get_file_func, .delete_all_func = delete_all_func, }; int camera_init (Camera *camera, GPContext *context) { gp_port_settings settings; /* First, set up all the function pointers */ camera->functions->manual = camera_manual; camera->functions->about = camera_about; camera->functions->get_config = camera_config_get; camera->functions->set_config = camera_config_set; /* Configure port */ gp_port_set_timeout(camera->port, 1000); gp_port_get_settings(camera->port, &settings); settings.serial.speed = 115200; settings.serial.bits = 8; settings.serial.parity = 0; settings.serial.stopbits= 1; gp_port_set_settings(camera->port, settings); /* Set up the filesystem */ gp_filesystem_set_funcs(camera->fs, &fsfuncs, camera); /* test camera */ return jd11_ping(camera->port); }