Remove generated files
[framework/connectivity/libgphoto2.git] / camlibs / gsmart300 / library.c
1 /****************************************************************/
2 /* library.c - Gphoto2 library for the Mustek gSmart 300        */
3 /*                                                              */
4 /* Copyright (C) 2002 Jérôme Lodewyck                           */
5 /*                                                              */
6 /* Author: Jérôme Lodewyck <jerome.lodewyck@ens.fr>             */
7 /*                                                              */
8 /* based on code by: Till Adam <till@adam-lilienthal.de>        */
9 /*                                                              */
10 /* This library is free software; you can redistribute it       */
11 /* and/or modify it under the terms of the GNU Library General  */
12 /* Public License as published by the Free Software Foundation; */
13 /* either version 2 of the License, or (at your option) any     */
14 /* later version.                                               */
15 /*                                                              */
16 /* This library is distributed in the hope that it will be      */
17 /* useful, but WITHOUT ANY WARRANTY; without even the implied   */
18 /* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      */
19 /* PURPOSE.  See the GNU Library General Public License for     */
20 /* more details.                                                */
21 /*                                                              */
22 /* You should have received a copy of the GNU Library General   */
23 /* Public License along with this library; if not, write to the */
24 /* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */
25 /* Boston, MA 02111-1307, USA.                                  */
26 /****************************************************************/
27 #include <config.h>
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32
33 #include <gphoto2/gphoto2.h>
34
35 #ifdef ENABLE_NLS
36 #  include <libintl.h>
37 #  undef _
38 #  define _(String) dgettext (PACKAGE, String)
39 #  ifdef gettext_noop
40 #    define N_(String) gettext_noop (String)
41 #  else
42 #    define N_(String) (String)
43 #  endif
44 #else
45 #  define _(String) (String)
46 #  define N_(String) (String)
47 #endif
48
49 #include "gsmart300.h"
50
51 #define GP_MODULE "gsmart300"
52 #define TIMEOUT       5000
53
54
55 /* forward declarations */
56 static int file_list_func (CameraFilesystem *fs, const char *folder,
57                            CameraList *list, void *data, GPContext *context);
58 static int get_file_func (CameraFilesystem *fs, const char *folder,
59                           const char *filename, CameraFileType type,
60                           CameraFile *file, void *user_data, GPContext *context);
61
62 static int delete_file_func (CameraFilesystem *fs, const char *folder,
63                              const char *filename, void *data, GPContext *context);
64 static int delete_all_func (CameraFilesystem *fs, const char *folder,
65                             void *data, GPContext *context);
66 static int get_info_func (CameraFilesystem *fs, const char *folder,
67                           const char *filename, CameraFileInfo *info,
68                           void *data, GPContext *context);
69
70 /* define what cameras we support */
71 static const struct
72 {
73         char *model;
74         int usb_vendor;
75         int usb_product;
76 }
77 models[] =
78 {
79         {
80         "Mustek:gSmart 300", 0x055f, 0xc200}
81         , {
82         "Casio:LV 10", 0x055f, 0xc200}
83         , {
84
85         NULL, 0, 0}
86 };
87
88 int
89 camera_id (CameraText *id)
90 {
91         strcpy (id->text, "gsmart300");
92         return (GP_OK);
93 }
94
95 int
96 camera_abilities (CameraAbilitiesList *list)
97 {
98         int x = 0;
99         char *ptr;
100         CameraAbilities a;
101
102         ptr = models[x].model;
103         while (ptr) {
104                 memset (&a, 0, sizeof (a));
105                 strcpy (a.model, ptr);
106                 a.status = GP_DRIVER_STATUS_EXPERIMENTAL;
107                 a.port = GP_PORT_USB;
108                 a.speed[0] = 0;
109
110                 a.file_operations = GP_FILE_OPERATION_PREVIEW | GP_FILE_OPERATION_DELETE;
111
112                 a.folder_operations = GP_FOLDER_OPERATION_DELETE_ALL;
113
114                 a.usb_vendor = models[x].usb_vendor;
115                 a.usb_product = models[x].usb_product;
116
117                 gp_abilities_list_append (list, a);
118
119                 ptr = models[++x].model;
120         }
121
122         return (GP_OK);
123 }
124
125
126 static int
127 camera_exit (Camera *camera, GPContext *context)
128 {
129         if (camera->pl) {
130                 if (camera->pl->fats) {
131                         free (camera->pl->fats);
132                         camera->pl->fats = NULL;
133                 }
134                 if (camera->pl->files) {
135                         free (camera->pl->files);
136                         camera->pl->files = NULL;
137                 }
138
139                 free (camera->pl);
140                 camera->pl = NULL;
141         }
142         return (GP_OK);
143 }
144
145 static int
146 camera_summary (Camera *camera, CameraText *summary, GPContext *context)
147 {
148         char tmp[1024];
149
150         if (camera->pl->dirty)
151                 CHECK (gsmart300_get_info (camera->pl));
152
153         snprintf (tmp, sizeof (tmp), "Files: %d\n\n", camera->pl->num_files);
154         strcat (summary->text, tmp);
155
156         return (GP_OK);
157 }
158
159 static int
160 camera_about (Camera *camera, CameraText *about, GPContext *context)
161 {
162         strcpy (about->text,
163                 _("gsmart300 library \n"
164                   "Till Adam <till@adam-lilienthal.de>\n"
165                   "Jerome Lodewyck <jerome.lodewyck@ens.fr>\n"
166                   "Support for Mustek gSmart 300 digital cameras\n"
167                   "based on several other gphoto2 camlib modules and "
168                   "the specifications kindly provided by Mustek.\n" "\n"));
169
170         return (GP_OK);
171 }
172
173 static CameraFilesystemFuncs fsfuncs = {
174         .file_list_func = file_list_func,
175         .get_file_func = get_file_func,
176         .get_info_func = get_info_func,
177         .del_file_func = delete_file_func,
178         .delete_all_func = delete_all_func
179 };
180
181 int
182 camera_init (Camera *camera, GPContext *context)
183 {
184         int ret;
185         GPPortSettings settings;
186
187         /* First, set up all the function pointers */
188         camera->functions->exit = camera_exit;
189         camera->functions->summary = camera_summary;
190         camera->functions->about = camera_about;
191
192         CHECK (gp_port_get_settings (camera->port, &settings));
193         switch (camera->port->type) {
194                 case GP_PORT_USB:
195                         settings.usb.inep = 0x82;
196                         settings.usb.outep = 0x03;
197                         settings.usb.config = 1;
198                         settings.usb.interface = 0;
199                         settings.usb.altsetting = 0;
200
201                         CHECK (gp_port_set_settings (camera->port, settings));
202                         CHECK (gp_port_set_timeout (camera->port, TIMEOUT));
203
204                         break;
205                 default:
206                         gp_context_error (context,
207                                           _("Unsupported port type: %d. "
208                                             "This driver only works with USB "
209                                             "cameras.\n"), camera->port->type);
210                         return (GP_ERROR);
211                         break;
212         }
213
214         camera->pl = malloc (sizeof (CameraPrivateLibrary));
215         if (!camera->pl)
216                 return (GP_ERROR_NO_MEMORY);
217         memset (camera->pl, 0, sizeof (CameraPrivateLibrary));
218         camera->pl->gpdev = camera->port;
219         camera->pl->dirty = 1;
220
221         ret = gsmart300_reset (camera->pl);
222
223         if (ret < 0) {
224                 gp_context_error (context, _("Could not reset camera.\n"));
225                 free (camera->pl);
226                 camera->pl = NULL;
227
228                 return (ret);
229         }
230         /* Set up the CameraFilesystem */
231         return gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
232 }
233
234
235 static int
236 file_list_func (CameraFilesystem *fs, const char *folder,
237                 CameraList *list, void *data, GPContext *context)
238 {
239         Camera *camera = data;
240         int i;
241         char temp_file[14];
242
243         if (camera->pl->dirty)
244                 CHECK (gsmart300_get_info (camera->pl));
245
246         for (i = 0; i < camera->pl->num_files; i++) {
247                 strncpy (temp_file, camera->pl->files[i].name, 12);
248                 temp_file[12] = 0;
249                 gp_list_append (list, temp_file, NULL);
250         }
251
252         return GP_OK;
253 }
254
255 static int
256 get_file_func (CameraFilesystem *fs, const char *folder,
257                const char *filename, CameraFileType type,
258                CameraFile *file, void *user_data, GPContext *context)
259 {
260         Camera *camera = user_data;
261         int number, filetype;
262
263         CHECK (number = gp_filesystem_number (camera->fs, folder, filename, 
264                                               context));
265         switch (type) {
266                 case GP_FILE_TYPE_NORMAL:
267                         CHECK (gsmart300_request_file (camera->pl, file, number));
268                         break;
269                 case GP_FILE_TYPE_PREVIEW:
270                         CHECK (gsmart300_request_thumbnail
271                                (camera->pl, file, number, &filetype));
272                         if (filetype == GSMART_FILE_TYPE_IMAGE) {
273                                 CHECK (gp_file_set_mime_type (file, GP_MIME_BMP));
274                         }
275                         break;
276                 default:
277                         return GP_ERROR_NOT_SUPPORTED;
278         }
279         CHECK (gp_file_set_name (file, filename));
280         return GP_OK;
281 }
282
283 static int
284 get_info_func (CameraFilesystem *fs, const char *folder,
285                const char *filename, CameraFileInfo *info, void *data, 
286                GPContext *context)
287 {
288         Camera *camera = data;
289         int n;
290         struct GsmartFile *file;
291
292         /* Get the file number from the CameraFileSystem */
293         CHECK (n = gp_filesystem_number (camera->fs, folder, filename, 
294                                          context));
295
296         CHECK (gsmart300_get_file_info (camera->pl, n, &file));
297
298         info->file.fields = GP_FILE_INFO_NAME 
299                 | GP_FILE_INFO_TYPE 
300                 | GP_FILE_INFO_WIDTH 
301                 | GP_FILE_INFO_HEIGHT;
302         strncpy (info->file.name, filename, sizeof (info->file.name));
303         if (file->mime_type == GSMART_FILE_TYPE_IMAGE) {
304                 strcpy (info->file.type, GP_MIME_JPEG);
305                 info->preview.width = 80;
306                 info->preview.height = 60;
307         }
308         info->file.width = file->width;
309         info->file.height = file->height;
310
311         info->preview.fields = GP_FILE_INFO_TYPE 
312                 | GP_FILE_INFO_WIDTH 
313                 | GP_FILE_INFO_HEIGHT;
314         strcpy (info->preview.type, GP_MIME_BMP);
315
316         return (GP_OK);
317 }
318
319 static int
320 delete_file_func (CameraFilesystem *fs, const char *folder,
321                   const char *filename, void *data, GPContext *context)
322 {
323         Camera *camera = data;
324         int n, c;
325
326         /* Get the file number from the CameraFileSystem */
327         CHECK (n = gp_filesystem_number (camera->fs, folder, filename, 
328                                          context));
329         CHECK (c = gp_filesystem_count (camera->fs, folder, context));
330         if (n + 1 != c) {
331                 const char *name;
332
333                 gp_filesystem_name (fs, "/", c - 1, &name, context);
334                 gp_context_error (context,
335                                                                                         _("Your camera only supports deleting " 
336                                                                                                 "the last file on the camera. In this "
337                                                                                                 "case, this is file '%s'."), name);
338                 return (GP_ERROR);
339         }
340         CHECK (gsmart300_delete_file (camera->pl, n));
341         return GP_OK;
342 }
343
344 static int
345 delete_all_func (CameraFilesystem *fs, const char *folder, void *data, 
346                  GPContext *context)
347 {
348         Camera *camera = data;
349
350         CHECK (gsmart300_delete_all (camera->pl));
351         return GP_OK;
352 }