Remove generated files
[framework/connectivity/libgphoto2.git] / camlibs / ricoh / library.c
1 /* library.c
2  *
3  * Copyright © 2002 Lutz Müller <lutz@users.sourceforge.net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, 
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details. 
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <gphoto2/gphoto2-library.h>
28 #include <gphoto2/gphoto2-port-log.h>
29
30 #include "ricoh.h"
31
32 #define GP_MODULE "ricoh"
33
34 #ifdef ENABLE_NLS
35 #  include <libintl.h>
36 #  undef _
37 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
38 #  ifdef gettext_noop
39 #    define N_(String) gettext_noop (String)
40 #  else
41 #    define N_(String) (String)
42 #  endif 
43 #else
44 #  define textdomain(String) (String)
45 #  define gettext(String) (String)
46 #  define dgettext(Domain,Message) (Message)
47 #  define dcgettext(Domain,Message,Type) (Message)
48 #  define bindtextdomain(Domain,Directory) (Domain)
49 #  define _(String) (String)
50 #  define N_(String) (String)
51 #endif
52
53 #define CR(result) {int r=(result); if (r<0) return r;}
54 #define CRW(result,widget) {int r=(result); if (r<0) { gp_widget_free (widget); return r; } }
55
56 static struct {
57         RicohModel id;
58         const char *model;
59 } models[] = {
60         {RICOH_MODEL_1,     "Ricoh:RDC-1"},
61         {RICOH_MODEL_2,     "Ricoh:RDC-2"},
62         {RICOH_MODEL_2E,    "Ricoh:RDC-2E"},
63         {RICOH_MODEL_100G,  "Ricoh:RDC-100G"},
64         {RICOH_MODEL_300,   "Ricoh:RDC-300"},
65         {RICOH_MODEL_300Z,  "Ricoh:RDC-300Z"},
66         {RICOH_MODEL_4200,  "Ricoh:RDC-4200"},
67         {RICOH_MODEL_4300,  "Ricoh:RDC-4300"},
68         {RICOH_MODEL_5000,  "Ricoh:RDC-5000"},
69         {RICOH_MODEL_ESP2,  "Philips:ESP2"},
70         {RICOH_MODEL_ESP50, "Philips:ESP50"},
71         {RICOH_MODEL_ESP60, "Philips:ESP60"},
72         {RICOH_MODEL_ESP70, "Philips:ESP70"},
73         {RICOH_MODEL_ESP80, "Philips:ESP80"},
74         {RICOH_MODEL_ESP80SXG, "Philips:ESP80SXG"},
75         {0, NULL}
76 };
77
78 struct _CameraPrivateLibrary {
79         RicohModel model;
80 };
81
82 int
83 camera_abilities (CameraAbilitiesList *list)
84 {
85         int i;
86         CameraAbilities a;
87
88         memset (&a, 0, sizeof (CameraAbilities));
89         for (i = 0; models[i].model; i++) {
90                 strcpy (a.model, models[i].model);
91                 a.status = GP_DRIVER_STATUS_EXPERIMENTAL;
92                 a.port = GP_PORT_SERIAL;
93                 a.operations = GP_OPERATION_CAPTURE_IMAGE |
94                                GP_OPERATION_CONFIG;
95                 a.file_operations = GP_FILE_OPERATION_DELETE |
96                                     GP_FILE_OPERATION_PREVIEW;
97                 a.folder_operations = GP_FOLDER_OPERATION_PUT_FILE;
98                 CR (gp_abilities_list_append (list, a));
99         }
100
101         return (GP_OK);
102 }
103
104 static int
105 camera_exit (Camera *camera, GPContext *context)
106 {
107         if (camera->pl) {
108                 free (camera->pl);
109                 camera->pl = NULL;
110         }
111
112         ricoh_disconnect (camera, context);
113
114         return GP_OK;
115 }
116
117 static int
118 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
119                 void *data, GPContext *context)
120 {
121         Camera *camera = data;
122         unsigned int n, i;
123         const char *name;
124
125         CR (ricoh_get_num (camera, context, &n));
126         for (i = 0; i < n; i++) {
127                 CR (ricoh_get_pic_name (camera, context, i + 1, &name));
128                 CR (gp_list_append (list, name, NULL));
129         }
130
131         return (GP_OK);
132 }
133
134 static int
135 get_info_func (CameraFilesystem *fs, const char *folder, const char *filename,
136          CameraFileInfo *info, void *data, GPContext *context)
137 {
138         Camera *camera = data;
139         int n;
140         const char *name;
141
142         CR (n = gp_filesystem_number (fs, folder, filename, context));
143         n++;
144         
145         info->audio.fields = GP_FILE_INFO_NONE;         /* no info anbout audio files */
146         
147         info->preview.width = 80;
148         info->preview.height = 60;
149         info->preview.fields = GP_FILE_INFO_WIDTH | GP_FILE_INFO_HEIGHT; 
150         
151         CR (ricoh_get_pic_name (camera, context, n, &name));
152         strcpy (info->file.name, name);
153         CR (ricoh_get_pic_date (camera, context, n, &info->file.mtime));
154         CR (ricoh_get_pic_size (camera, context, n, &info->file.size));
155         strcpy (info->file.type, GP_MIME_EXIF);
156         info->file.fields = GP_FILE_INFO_NAME | GP_FILE_INFO_SIZE | GP_FILE_INFO_MTIME
157                 | GP_FILE_INFO_TYPE;
158         
159         return (GP_OK);
160 }
161                                          
162 static int
163 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
164                CameraFileType type, CameraFile *file, void *user_data,
165                GPContext *context)
166 {
167         Camera *camera = user_data;
168         int n;
169         unsigned int size;
170         unsigned char *data;
171
172         CR (n = gp_filesystem_number (fs, folder, filename, context));
173         n++;
174
175         switch (type) {
176         case GP_FILE_TYPE_NORMAL:
177                 CR (ricoh_get_pic (camera, context, n,
178                                    RICOH_FILE_TYPE_NORMAL, &data, &size));
179                 gp_file_set_mime_type (file, GP_MIME_EXIF);
180                 break;
181         case GP_FILE_TYPE_PREVIEW:
182                 CR (ricoh_get_pic (camera, context, n,
183                                    RICOH_FILE_TYPE_PREVIEW, &data, &size));
184                 gp_file_set_mime_type (file, GP_MIME_TIFF);
185                 break;          
186         default:
187                 return (GP_ERROR_NOT_SUPPORTED);
188         }
189
190         gp_file_set_data_and_size (file, data, size);
191
192         return (GP_OK);
193 }
194
195 static int
196 del_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
197                void *user_data, GPContext *context)
198 {
199         Camera *camera = user_data;
200         int n;
201
202         CR (n = gp_filesystem_number (fs, folder, filename, context));
203         n++;
204
205         CR (ricoh_del_pic (camera, context, n));
206
207         return (GP_OK);
208 }
209
210 static int
211 camera_about (Camera *camera, CameraText *about, GPContext *context)
212 {
213         GP_DEBUG ("camera_about()");
214
215         strcpy (about->text,
216                 _("Ricoh / Philips driver by\n"
217                   "Lutz Mueller <lutz@users.sourceforge.net>,\n"
218                   "Martin Fischer <martin.fischer@inka.de>,\n"
219                   "based on Bob Paauwe's driver\n" )
220                 );
221
222         return GP_OK;
223 }
224
225 int
226 camera_id (CameraText *id)
227 {
228         strcpy (id->text, "Ricoh");
229
230         return (GP_OK);
231 }
232
233 static int
234 camera_summary (Camera *camera, CameraText *about, GPContext *context)
235 {
236         int avail_mem, total_mem;
237         char model[128];
238         unsigned int i;
239
240         CR (ricoh_get_cam_amem (camera, context, &avail_mem));
241         CR (ricoh_get_cam_mem  (camera, context, &total_mem));
242
243         memset (model, 0, sizeof (model));
244         for (i = 0; models[i].model; i++)
245                 if (models[i].id == camera->pl->model)
246                         break;
247         if (models[i].model)
248                 strncpy (model, models[i].model, sizeof (model) - 1);
249         else
250                 snprintf (model, sizeof (model) - 1, _("unknown (0x%02x)"),
251                           camera->pl->model);
252
253         sprintf (about->text, _("Model: %s\n"
254                                 "Memory: %d byte(s) of %d available"),
255                 model, avail_mem, total_mem);
256
257         return (GP_OK);
258 }
259
260 static int
261 camera_capture (Camera *camera, CameraCaptureType type,
262                 CameraFilePath *path, GPContext *context)
263 {
264         unsigned int n;
265
266         if (type != GP_CAPTURE_IMAGE)
267                 return (GP_ERROR_NOT_SUPPORTED);
268
269         CR (ricoh_get_num (camera, context, &n));
270         CR (ricoh_take_pic (camera, context));
271
272         sprintf (path->name, "rdc%04i.jpg", n + 1);
273         strcpy (path->folder, "/");
274         CR (gp_filesystem_append (camera->fs, path->folder,
275                                   path->name, context));
276
277         return (GP_OK);
278 }
279
280 static int
281 put_file_func (CameraFilesystem *fs, const char *folder, CameraFile *file,
282                void *user_data, GPContext *context)
283 {
284         const char *data, *name;
285         unsigned long int size;
286         Camera *camera = user_data;
287
288         CR (gp_file_get_data_and_size (file, &data, &size));
289         CR (gp_file_get_name (file, &name));
290
291         CR (ricoh_put_file (camera, context, name, data, size));
292
293         return (GP_OK);
294 }
295
296 #undef N_ELEMENTS
297 #define N_ELEMENTS(v) (sizeof(v)/sizeof(v[0]))
298
299 static struct {
300         RicohExposure exposure;
301         const char *name;
302 } ricoh_exposures[] = {
303         {RICOH_EXPOSURE_M20,  N_("-2.0")},
304         {RICOH_EXPOSURE_M15,  N_("-1.5")},
305         {RICOH_EXPOSURE_M10,  N_("-1.0")},
306         {RICOH_EXPOSURE_M05,  N_("-0.5")},
307         {RICOH_EXPOSURE_00,   N_("0.0")},
308         {RICOH_EXPOSURE_05,   N_("0.5")},
309         {RICOH_EXPOSURE_10,   N_("1.0")},
310         {RICOH_EXPOSURE_15,   N_("1.5")},
311         {RICOH_EXPOSURE_20,   N_("2.0")},
312         {RICOH_EXPOSURE_AUTO, N_("Auto")}
313 };
314
315 static struct {
316         RicohResolution resolution;
317         const char *name;
318 } ricoh_resolutions[] = {
319         {RICOH_RESOLUTION_640_480,  N_("640 x 480")},
320         {RICOH_RESOLUTION_1280_960, N_("1280 x 960")}
321 };
322
323 static struct {
324         RicohWhiteLevel white_level;
325         const char *name;
326 } ricoh_white_levels[] = {
327         {RICOH_WHITE_LEVEL_AUTO,                N_("Auto")},
328         {RICOH_WHITE_LEVEL_OUTDOOR,             N_("Outdoor")},
329         {RICOH_WHITE_LEVEL_FLUORESCENT,         N_("Fluorescent")},
330         {RICOH_WHITE_LEVEL_INCANDESCENT,        N_("Incandescent")},
331         {RICOH_WHITE_LEVEL_BLACK_WHITE,         N_("Black & White")},
332         {RICOH_WHITE_LEVEL_SEPIA,               N_("Sepia")}
333 };
334
335 static struct {
336         RicohMacro macro;
337         const char *name;
338 } ricoh_macros[] = {
339         {RICOH_MACRO_ON, N_("On")},
340         {RICOH_MACRO_OFF, N_("Off")}
341 };
342
343 static struct {
344         RicohCompression compression;
345         const char *name;
346 } ricoh_compressions[] = {
347         {RICOH_COMPRESSION_NONE, N_("None")},
348         {RICOH_COMPRESSION_MAX,  N_("Maximal")},
349         {RICOH_COMPRESSION_NORM, N_("Normal")},
350         {RICOH_COMPRESSION_MIN,  N_("Minimal")}
351 };
352
353 static struct {
354         RicohRecMode rec_mode;
355         const char *name;
356 } ricoh_rec_modes[] = {
357         {RICOH_REC_MODE_IMAGE,           N_("Image")},
358         {RICOH_REC_MODE_CHARACTER,       N_("Character")},
359         {RICOH_REC_MODE_SOUND,           N_("Sound")},
360         {RICOH_REC_MODE_IMAGE_SOUND,     N_("Image & Sound")},
361         {RICOH_REC_MODE_CHARACTER_SOUND, N_("Character & Sound")}
362 };
363
364 static struct {
365         RicohFlash flash;
366         const char *name;
367 } ricoh_flashs[] = {
368         {RICOH_FLASH_AUTO, N_("Auto")},
369         {RICOH_FLASH_OFF,  N_("Off")},
370         {RICOH_FLASH_ON,   N_("On")}
371 };
372
373 static struct {
374         RicohZoom zoom;
375         const char *name;
376 } ricoh_zooms[] = {
377         {RICOH_ZOOM_OFF, N_("Off")},
378         {RICOH_ZOOM_1,   N_("2x")},
379         {RICOH_ZOOM_2,   N_("3x")},
380         {RICOH_ZOOM_3,   N_("4x")},
381         {RICOH_ZOOM_4,   N_("5x")},
382         {RICOH_ZOOM_5,   N_("6x")},
383         {RICOH_ZOOM_6,   N_("7x")},
384         {RICOH_ZOOM_7,   N_("8x")},
385         {RICOH_ZOOM_8,   N_("9x")}
386 };
387
388 #undef R_ADD_RADIO
389 #define R_ADD_RADIO(ca,co,s,type,n,Name)                                \
390 {                                                                       \
391         CameraWidget *w = NULL;                                         \
392         type v;                                                         \
393         unsigned int i;                                                 \
394                                                                         \
395         CR (gp_widget_new (GP_WIDGET_RADIO, _(Name), &w));              \
396         CR (gp_widget_set_name (w, (Name)));                            \
397         CR (gp_widget_append ((s), w));                                 \
398         CR (ricoh_get_##n ((ca), (co), &v));                            \
399         for (i = 0; i < N_ELEMENTS (ricoh_##n##s); i++) {               \
400                 CR (gp_widget_add_choice (w, _(ricoh_##n##s[i].name))); \
401                 if (v == ricoh_##n##s[i].n)                             \
402                         CR (gp_widget_set_value (w,                     \
403                                 _(ricoh_##n##s[i].name)));              \
404         }                                                               \
405 }
406
407 #undef R_CHECK_RADIO
408 #define R_CHECK_RADIO(c,co,wi,n,Name)                                   \
409 {                                                                       \
410         CameraWidget *w = NULL;                                         \
411         const char *v = NULL;                                           \
412         unsigned int i;                                                 \
413                                                                         \
414         CR (gp_widget_get_child_by_name (wi, Name, &w));                \
415         if (gp_widget_changed (w)) {                                    \
416                 CR (gp_widget_get_value (w, &v));                       \
417                 for (i = 0; i < N_ELEMENTS (ricoh_##n##s); i++)         \
418                         if (!strcmp (v, _(ricoh_##n##s[i].name))) {     \
419                                 CR (ricoh_set_##n (c, co, ricoh_##n##s[i].n));          \
420                                 break;                                  \
421                         }                                               \
422         }                                                               \
423 }
424
425 static int
426 camera_get_config (Camera *c, CameraWidget **window, GPContext *co)
427 {
428         CameraWidget *s, *w;
429         const char *copyright;
430         time_t time;
431
432         CR (gp_widget_new (GP_WIDGET_WINDOW, _("Configuration"), window));
433
434         /* General settings */
435         CR (gp_widget_new (GP_WIDGET_SECTION, _("General"), &s));
436         CR (gp_widget_append (*window, s));
437
438         /* Copyright */
439         CR (gp_widget_new (GP_WIDGET_TEXT, _("Copyright"), &w));
440         CR (gp_widget_set_name (w, "copyright"));
441         CR (gp_widget_set_info (w, _("Copyright (max. 20 characters)")));
442         CR (gp_widget_append (s, w));
443         CR (ricoh_get_copyright (c, co, &copyright));
444         CR (gp_widget_set_value (w, (void *) copyright));
445
446         /* Date */
447         CR (gp_widget_new (GP_WIDGET_DATE, _("Date & Time"), &w));
448         CRW (gp_widget_set_name (w, "date"), w);
449         CRW (gp_widget_set_info (w, _("Date & Time")), w);
450         CRW (gp_widget_append (s, w), w);
451         CR (ricoh_get_date (c, co, &time));
452         CR (gp_widget_set_value (w, &time));
453
454         /* Picture related settings */
455         CR (gp_widget_new (GP_WIDGET_SECTION, _("Pictures"), &s));
456         CRW (gp_widget_append (*window, s), w);
457
458         R_ADD_RADIO (c, co, s, RicohResolution,  resolution,  "Resolution")
459         R_ADD_RADIO (c, co, s, RicohExposure,    exposure,    "Exposure")
460         R_ADD_RADIO (c, co, s, RicohMacro,       macro,       "Macro")
461         R_ADD_RADIO (c, co, s, RicohFlash,       flash,       "Flash")
462         R_ADD_RADIO (c, co, s, RicohZoom,        zoom,        "Zoom")
463         R_ADD_RADIO (c, co, s, RicohCompression, compression, "Compression")
464         R_ADD_RADIO (c, co, s, RicohWhiteLevel,  white_level, "White Level")
465         R_ADD_RADIO (c, co, s, RicohRecMode,     rec_mode,    "Record Mode")
466
467         return (GP_OK);
468 }
469
470 static int
471 camera_set_config (Camera *c, CameraWidget *window, GPContext *co)
472 {
473         CameraWidget *w;
474         const char *v_char;
475         time_t time;
476         RicohMode mode;
477
478         /* We need to be in record mode to set settings. */
479         CR (ricoh_get_mode (c, co, &mode));
480         if (mode != RICOH_MODE_RECORD)
481                 CR (ricoh_set_mode (c, co, RICOH_MODE_RECORD));
482
483         /* Copyright */
484         CR (gp_widget_get_child_by_name (window, "copyright", &w));
485         if (gp_widget_changed (w)) {
486                 CR (gp_widget_get_value (w, &v_char));
487                 CR (ricoh_set_copyright (c, co, v_char));
488         }
489
490         /* Date */
491         CR (gp_widget_get_child_by_name (window, "date", &w));
492         if (gp_widget_changed (w)) {
493                 CR (gp_widget_get_value (w, &time));
494                 CR (ricoh_set_date (c, co, time));
495         }
496
497         R_CHECK_RADIO (c, co, window, resolution,  N_("Resolution"))
498         R_CHECK_RADIO (c, co, window, exposure,    N_("Exposure"))
499         R_CHECK_RADIO (c, co, window, white_level, N_("White level"))
500         R_CHECK_RADIO (c, co, window, macro,       N_("Macro"))
501         R_CHECK_RADIO (c, co, window, zoom,        N_("Zoom"))
502         R_CHECK_RADIO (c, co, window, flash,       N_("Flash"))
503         R_CHECK_RADIO (c, co, window, rec_mode,    N_("Record Mode"))
504         R_CHECK_RADIO (c, co, window, compression, N_("Compression"))
505
506         return (GP_OK);
507 }
508
509 static struct {
510         unsigned int speed;
511         RicohSpeed rspeed;
512 } speeds[] = {
513         {  2400, RICOH_SPEED_2400},
514         {115200, RICOH_SPEED_115200},
515         {  4800, RICOH_SPEED_4800},
516         { 19200, RICOH_SPEED_19200},
517         { 38400, RICOH_SPEED_38400},
518         { 57600, RICOH_SPEED_57600},
519         {     0, 0}
520 };
521
522 static CameraFilesystemFuncs fsfuncs = {
523         .file_list_func = file_list_func,
524         .get_file_func = get_file_func,
525         .del_file_func = del_file_func,
526         .put_file_func = put_file_func,
527         .get_info_func = get_info_func
528 };
529
530 int
531 camera_init (Camera *camera, GPContext *context)
532 {
533         GPPortSettings settings;
534         unsigned int speed, i;
535         int result;
536         RicohModel model = 0;
537
538         /* Try to contact the camera. */
539         CR (gp_port_set_timeout (camera->port, 5000));
540         CR (gp_port_get_settings (camera->port, &settings));
541         speed = (settings.serial.speed ? settings.serial.speed : 115200);
542         for (i = 0; speeds[i].speed; i++) {
543                 GP_DEBUG ("Trying speed %i...", speeds[i].speed);
544                 settings.serial.speed = speeds[i].speed;
545                 CR (gp_port_set_settings (camera->port, settings));
546
547                 /*
548                  * Note that ricoh_connect can only be called to 
549                  * initialize the connection at 2400 bps. At other
550                  * speeds, a different function needs to be used.
551                  */
552                 result = (speeds[i].rspeed == RICOH_SPEED_2400) ? 
553                                 ricoh_connect (camera, NULL, &model) :
554                                 ricoh_get_mode (camera, NULL, NULL);
555                 if (result == GP_OK)
556                         break;
557         }
558
559         /* Contact made? If not, report error. */
560         if (!speeds[i].speed) {
561                 gp_context_error (context, _("Could not contact camera."));
562                 return (GP_ERROR);
563         }
564
565         /* Contact made. Do we need to change the speed? */
566         if (settings.serial.speed != speed) {
567                 for (i = 0; speeds[i].speed; i++)
568                         if (speeds[i].speed == speed)
569                                 break;
570                 if (!speeds[i].speed) {
571                         gp_context_error (context, _("Speed %i is not "
572                                 "supported!"), speed);
573                         return (GP_ERROR);
574                 }
575                 CR (ricoh_set_speed (camera, context, speeds[i].rspeed));
576                 settings.serial.speed = speed;
577                 CR (gp_port_set_settings (camera->port, settings));
578
579                 /* Check if the camera is still there. */
580                 CR (ricoh_get_mode (camera, context, NULL));
581         }
582
583         /* setup the function calls */
584         camera->functions->exit = camera_exit;
585         camera->functions->summary = camera_summary;
586         camera->functions->capture = camera_capture;
587         camera->functions->about = camera_about;
588         camera->functions->get_config = camera_get_config;
589         camera->functions->set_config = camera_set_config;
590         CR (gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera));
591         /*
592          * Remember the model. It could be that there hasn't been the 
593          * need to call ricoh_connect. Then we don't have a model. Should
594          * we disconnect and reconnect in this case?
595          */
596         camera->pl = malloc (sizeof (CameraPrivateLibrary));
597         if (!camera->pl)
598                 return (GP_ERROR_NO_MEMORY);
599         memset (camera->pl, 0, sizeof (CameraPrivateLibrary));
600         camera->pl->model = model;
601
602         return (GP_OK);
603 }
604