Source code upload
[framework/connectivity/libgphoto2.git] / camlibs / kodak / dc240 / dc240.c
1 /*
2   Kodak DC 240/280/3400/5000 driver.
3   Maintainer:
4        Hubert Figuiere <hfiguiere@teaser.fr>
5  */
6
7 #include "config.h"
8
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12
13 #include <gphoto2/gphoto2.h>
14 #include <gphoto2/gphoto2-port.h>
15
16 #ifdef ENABLE_NLS
17 #  include <libintl.h>
18 #  undef _
19 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
20 #  ifdef gettext_noop
21 #    define N_(String) gettext_noop (String)
22 #  else
23 #    define N_(String) (String)
24 #  endif
25 #else
26 #  define textdomain(String) (String)
27 #  define gettext(String) (String)
28 #  define dgettext(Domain,Message) (Message)
29 #  define dcgettext(Domain,Message,Type) (Message)
30 #  define bindtextdomain(Domain,Directory) (Domain)
31 #  define _(String) (String)
32 #  define N_(String) (String)
33 #endif
34
35 #include "dc240.h"
36 #include "library.h"
37
38 int
39 camera_id (CameraText *id) 
40 {
41         strcpy(id->text, "kodak-dc240");
42
43         return (GP_OK);
44 }
45
46 static const struct camera_to_usb {
47         char *name;
48         unsigned short idVendor;
49         unsigned short idProduct;
50 } camera_to_usb[] = {
51         { "Kodak:DC240", 0x040A, 0x0120 },
52         { "Kodak:DC280", 0x040A, 0x0130 },
53         { "Kodak:DC3400", 0x040A, 0x0132 },
54         { "Kodak:DC5000", 0x040A, 0x0131 },
55         { NULL, 0, 0 }
56 };
57
58 /*
59   Abilities are based upon what we can do with a DC240.
60   Later cameras have a superset of the DC240 feature and are not
61   currently supported.
62  */
63 int
64 camera_abilities (CameraAbilitiesList *list) 
65 {
66         CameraAbilities a;
67         int i;
68
69         for (i = 0; camera_to_usb[i].name; i++)
70         {
71             memset (&a, 0, sizeof (a));
72             strcpy(a.model, camera_to_usb[i].name);
73             a.status = GP_DRIVER_STATUS_PRODUCTION;
74             a.port     = GP_PORT_SERIAL | GP_PORT_USB;
75             a.speed[0] = 9600;
76             a.speed[1] = 19200;
77             a.speed[2] = 38400;
78             a.speed[3] = 57600;
79             a.speed[4] = 115200;
80             a.speed[5] = 0;
81             a.usb_vendor  = camera_to_usb[i].idVendor;
82             a.usb_product = camera_to_usb[i].idProduct;
83             a.operations        =       GP_OPERATION_CAPTURE_IMAGE;
84             a.file_operations   =       GP_FILE_OPERATION_DELETE | 
85                                         GP_FILE_OPERATION_PREVIEW;
86             a.folder_operations =       GP_FOLDER_OPERATION_NONE;
87             
88             gp_abilities_list_append(list, a);
89         }
90         return (GP_OK);
91 }
92
93 static int
94 camera_exit (Camera *camera, GPContext *context) 
95 {
96         dc240_close (camera, context);
97         
98         return (GP_OK);
99 }
100
101 static int
102 folder_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
103                   void *data, GPContext *context) 
104 {
105         Camera *camera = data;
106
107         return dc240_get_directory_list(camera, list, folder, 0x10, context);
108 }
109
110 static int
111 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
112                 void *data, GPContext *context) 
113 {
114         Camera *camera = data;
115
116         return dc240_get_directory_list(camera, list, folder, 0x00, context);
117 }
118
119 static int
120 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
121                CameraFileType type, CameraFile *file, void *data,
122                GPContext *context) 
123 {
124         Camera *camera = data;
125
126         switch (type) {
127         case GP_FILE_TYPE_NORMAL:
128         case GP_FILE_TYPE_RAW:
129                 return dc240_file_action (camera, DC240_ACTION_IMAGE, file,
130                                            folder, filename, context);
131         case GP_FILE_TYPE_PREVIEW:
132                 return dc240_file_action (camera, DC240_ACTION_PREVIEW, file,
133                                            folder, (char*) filename, context);
134         default:
135                 return GP_ERROR_NOT_SUPPORTED;
136         }
137 }
138
139 static int
140 delete_file_func (CameraFilesystem *fs, const char *folder,
141                   const char *filename, void *data, GPContext *context)
142 {
143         Camera *camera = data;
144
145         return (dc240_file_action (camera, DC240_ACTION_DELETE, NULL, folder, 
146                                    filename, context));
147 }
148
149 static int
150 camera_capture (Camera *camera, CameraCaptureType type,
151                 CameraFilePath *path, GPContext *context) 
152 {
153         int result;
154
155         if (type != GP_CAPTURE_IMAGE)
156                 return (GP_ERROR_NOT_SUPPORTED);
157
158         /* Capture the image */
159         result = dc240_capture (camera, path, context);
160         if (result < 0)
161                 return (result);
162
163         /* Tell the filesystem about it */
164         result = gp_filesystem_append (camera->fs, path->folder, path->name, context);
165         if (result < 0)
166                 return (result);
167
168         return (GP_OK);
169 }
170
171 static int
172 camera_summary (Camera *camera, CameraText *summary, GPContext *context) 
173 {
174     char buf [32 * 1024];
175     char temp [1024];
176     int retval;
177     DC240StatusTable table;
178     
179     retval = dc240_get_status (camera, &table, context);
180     if (retval == GP_OK) {
181         sprintf (buf, _("Model: Kodak %s\n"), dc240_convert_type_to_camera(table.cameraType));
182         sprintf (temp, _("Firmware version: %d.%02d\n"), table.fwVersInt, table.fwVersDec);
183         strcat (buf, temp);
184         sprintf (temp, _("Battery status: %s, AC Adapter: %s\n"), 
185                  dc240_get_battery_status_str(table.battStatus), 
186                  dc240_get_ac_status_str(table.acAdapter));
187         strcat (buf, temp);
188         sprintf (temp, _("Number of pictures: %d\n"), table.numPict);
189         strcat (buf, temp);
190         sprintf (temp, _("Space remaining: High: %d, Medium: %d, Low: %d\n"), 
191                  table.remPictHigh, table.remPictMed, table.remPictLow);
192         strcat (buf, temp);
193         
194         sprintf (temp, _("Memory card status (%d): %s\n"), table.memCardStatus,
195                  dc240_get_memcard_status_str(table.memCardStatus));
196         strcat (buf, temp);
197
198         sprintf (temp, _("Total pictures captured: %d, Flashes fired: %d\n"), 
199                  table.totalPictTaken, table.totalStrobeFired); 
200         strcat (buf, temp);
201         
202         
203         strcpy(summary->text, buf);
204     }
205     return retval;
206 }
207
208 static int
209 camera_about (Camera *camera, CameraText *about, GPContext *context) 
210 {
211         strcpy (about->text, 
212                 _("Kodak DC240 Camera Library\n"
213                 "Scott Fritzinger <scottf@gphoto.net> and Hubert Figuiere <hfiguiere@teaser.fr>\n"
214                 "Camera Library for the Kodak DC240, DC280, DC3400 and DC5000 cameras.\n"
215                 "Rewritten and updated for gPhoto2."));
216
217         return (GP_OK);
218 }
219
220 static CameraFilesystemFuncs fsfuncs = {
221         .file_list_func = file_list_func,
222         .folder_list_func = folder_list_func,
223         .get_file_func = get_file_func,
224         .del_file_func = delete_file_func
225 };
226
227 int
228 camera_init (Camera *camera, GPContext *context) 
229 {
230         int ret, selected_speed = 0;
231         GPPortSettings settings;
232         
233         /* First, set up all the function pointers */
234         camera->functions->exit             = camera_exit;
235         camera->functions->capture          = camera_capture;
236         camera->functions->summary          = camera_summary;
237         camera->functions->about            = camera_about;
238
239         /* Set up the CameraFilesystem */
240         gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
241
242         ret = gp_port_get_settings (camera->port, &settings);
243         if (ret < 0)
244                 return (ret);
245         switch (camera->port->type) {
246         case GP_PORT_SERIAL:
247
248                 /* Remember the selected speed */
249                 selected_speed = settings.serial.speed;
250
251                 settings.serial.speed    = 9600;
252                 settings.serial.bits     = 8;
253                 settings.serial.parity   = 0;
254                 settings.serial.stopbits = 1;
255                 break;
256         case GP_PORT_USB:
257                 settings.usb.inep       = 0x82;
258                 settings.usb.outep      = 0x01;
259                 settings.usb.config     = 1;
260                 settings.usb.interface  = 0;
261                 settings.usb.altsetting = 0;
262                 break;
263         default:
264                 return (GP_ERROR_UNKNOWN_PORT);
265         }
266         
267         ret = gp_port_set_settings (camera->port, settings);
268         if (ret < 0)
269                 return (ret);
270
271         ret = gp_port_set_timeout (camera->port, TIMEOUT);
272         if (ret < 0)
273                 return (ret);
274
275         if (camera->port->type == GP_PORT_SERIAL) {
276                 char buf[8];    
277                 /* Reset the camera to 9600 */
278                 gp_port_send_break(camera->port, 1);
279
280                 /* Used to have a 1500 msec pause here to give
281                  * the camera time to reset - but, since
282                  * the serial port sometimes returns a garbage
283                  * character or two after the break, we do 
284                  * a couple of TIMEOUT (750 msec) pauses here
285                  * force the delay as well as flush the port 
286                  */
287                 gp_port_read(camera->port, buf, 8);
288                 gp_port_read(camera->port, buf, 8);
289
290                 ret = dc240_set_speed (camera, selected_speed);
291                 if (ret < 0)
292                         return (ret);
293         }
294
295         /* Open the CF card */
296         ret = dc240_open (camera);
297         if (ret < 0)
298                 return (ret);
299         
300         ret = dc240_packet_set_size (camera, HPBS+2);
301         if (ret < 0)
302                 return (ret);
303
304         return (GP_OK);
305 }