1 /* library.c *
2 * Copyright 2002 Dominik Kuhlen <dkuhlen@fhm.edu>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
18 */
19 #include "config.h"
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include <gphoto2/gphoto2-library.h>
26 #include <gphoto2/gphoto2-port-log.h>
27
28 #include "sx330z.h"
29
30
31 #ifdef ENABLE_NLS
32 # include <libintl.h>
33 # undef _
34 # define _(String) dgettext (GETTEXT_PACKAGE, String)
35 # ifdef gettext_noop
36 # define N_(String) gettext_noop (String)
37 # else
38 # define N_(String) (String)
39 # endif
40 #else
41 # define textdomain(String) (String)
42 # define gettext(String) (String)
43 # define dgettext(Domain,Message) (Message)
44 # define dcgettext(Domain,Message,Type) (Message)
45 # define bindtextdomain(Domain,Directory) (Domain)
46 # define _(String) (String)
47 # define N_(String) (String)
48 #endif
49
50
51
52 #define GP_MODULE "sx330z"
53
54
55 #define TIMEOUT 2000
56
57 #define SX330Z_VERSION "0.1"
58 #define SX330Z_LAST_MOD "02.07.2002"
59
60
61 #define CR(res) { int r=(res);if (r<0) return (r);}
62
63 /*
64 * supported cameras :
65 * - Traveler SX330z (Aldi cam)
66 * - Other SX330z / SX3300z Models ?
67 * please report if you have others that are working
68 */
69
70 static const struct
71 {
72 char *model;
73 int usb_vendor;
74 int usb_product;
75 } models[]= {
76 {"Traveler:SX330z",USB_VENDOR_TRAVELER,USB_PRODUCT_SX330Z},
77 {"Maginon:SX330z",USB_VENDOR_TRAVELER,USB_PRODUCT_SX330Z},
78 {"Skanhex:SX-330z",USB_VENDOR_TRAVELER,USB_PRODUCT_SX330Z},
79 {"Medion:MD 9700",USB_VENDOR_TRAVELER,USB_PRODUCT_MD9700},
80 {"Jenoptik:JD-3300z3",USB_VENDOR_TRAVELER,USB_PRODUCT_SX330Z},
81
82 {"Traveler:SX410z",USB_VENDOR_TRAVELER,USB_PRODUCT_SX410Z},
83 {"Concord:EyeQ 4330",USB_VENDOR_TRAVELER,USB_PRODUCT_SX410Z},
84 {"Jenoptik:JD-4100z3",USB_VENDOR_TRAVELER,USB_PRODUCT_SX410Z},
85 {"Medion:MD 6000",USB_VENDOR_TRAVELER,USB_PRODUCT_SX410Z},
86 {"Maginon SX-410z",USB_VENDOR_TRAVELER,USB_PRODUCT_SX410Z},
87 {"Lifetec:LT 5995",USB_VENDOR_TRAVELER,USB_PRODUCT_SX410Z},
88 {NULL,0,0}
89 };
90
91
92 /*
93 * camera abilities
94 */
95 int
camera_abilities(CameraAbilitiesList * list)96 camera_abilities (CameraAbilitiesList *list)
97 {
98 int i;
99 CameraAbilities a;
100 for(i=0;models[i].model;i++)
101 {
102 memset(&a,0,sizeof(CameraAbilities));
103 strcpy(a.model,models[i].model);
104 a.usb_vendor = models[i].usb_vendor;
105 a.usb_product = models[i].usb_product;
106 a.status = GP_DRIVER_STATUS_EXPERIMENTAL;
107 a.port = GP_PORT_USB;
108 a.speed[0] = 0;
109 a.operations = GP_OPERATION_NONE;
110 a.file_operations = GP_FILE_OPERATION_PREVIEW|
111 GP_FILE_OPERATION_DELETE|
112 GP_FILE_OPERATION_EXIF;
113 a.folder_operations = GP_FOLDER_OPERATION_NONE;
114 CR(gp_abilities_list_append(list,a));
115 } /* all models... */
116 return(GP_OK);
117 } /* camera_abilities */
118
119
120
121
122 /*
123 * file list function
124 */
125 static int
file_list_func(CameraFilesystem * fs,const char * folder,CameraList * list,void * data,GPContext * context)126 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
127 void *data, GPContext *context)
128 {
129 Camera *camera = data;
130 CameraFileInfo info;
131 int32_t tpages=0;
132 int pcnt,ecnt; /* pagecounter, entrycounter*/
133 struct traveler_toc_page toc;
134 int id;
135
136 /* get number of TOC pages */
137 CR (sx330z_get_toc_num_pages (camera, context, &tpages));
138 /* Read the TOC pages */
139 id = gp_context_progress_start (context, tpages, _("Getting "
140 "information on %i files..."), tpages);
141 for (pcnt = 0; pcnt < tpages; pcnt++) {
142 CR (sx330z_get_toc_page (camera, context, &toc, pcnt));
143 for (ecnt = 0; ecnt < toc.numEntries; ecnt++) {
144 char fn[20];
145
146 info.audio.fields = GP_FILE_INFO_NONE;
147 info.preview.fields = GP_FILE_INFO_TYPE;
148 strcpy (info.preview.type, GP_MIME_EXIF);
149 info.file.fields = GP_FILE_INFO_SIZE |
150 GP_FILE_INFO_TYPE |
151 GP_FILE_INFO_PERMISSIONS;
152 info.file.size = toc.entries[ecnt].size;
153 info.file.permissions = GP_FILE_PERM_READ |
154 GP_FILE_PERM_DELETE;
155 strcpy (info.file.type,GP_MIME_JPEG);
156 sprintf (fn, "%.12s", toc.entries[ecnt].name);
157
158 /*
159 * Append directly to the filesystem instead of to
160 * the list, because we have additional information.
161 */
162 gp_filesystem_append (camera->fs, folder, fn, context);
163 gp_filesystem_set_info_noop (camera->fs, folder, fn,
164 info, context);
165 }
166 gp_context_progress_update (context, id, pcnt);
167 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL)
168 return (GP_ERROR_CANCEL);
169 }
170
171 gp_context_progress_stop (context, id);
172
173 return (GP_OK);
174 }
175
176
177 static int
get_file_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileType type,CameraFile * file,void * user_data,GPContext * context)178 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
179 CameraFileType type, CameraFile *file, void *user_data,
180 GPContext *context)
181 {
182 Camera *camera = user_data;
183 char *data = NULL;
184 unsigned long int size = 0;
185
186 switch (type) {
187 case GP_FILE_TYPE_EXIF:
188 gp_file_set_mime_type (file, GP_MIME_RAW);
189 CR (sx330z_get_data (camera, context, filename, &data,
190 &size, SX_THUMBNAIL));
191 break;
192 case GP_FILE_TYPE_RAW:
193 case GP_FILE_TYPE_NORMAL:
194 gp_file_set_mime_type (file, GP_MIME_JPEG);
195 CR (sx330z_get_data (camera, context, filename, &data,
196 &size, SX_IMAGE));
197 break;
198 case GP_FILE_TYPE_PREVIEW:
199 default:
200 return (GP_ERROR_NOT_SUPPORTED);
201 }
202 gp_file_set_data_and_size (file, data, size);
203
204 return (GP_OK);
205 }
206
207
208 /*
209 * Delete file function (working ..)
210 */
211 static int
del_file_func(CameraFilesystem * fs,const char * folder,const char * filename,void * user_data,GPContext * context)212 del_file_func(CameraFilesystem *fs,const char *folder,const char *filename,
213 void *user_data,GPContext *context)
214 {
215 Camera *camera=user_data;
216 /*int id;*/
217 if (strcmp(folder,"/")) return(GP_ERROR_DIRECTORY_NOT_FOUND);
218 GP_DEBUG("Deleting : %s",filename);
219 return(sx330z_delete_file(camera,context,filename));
220 } /* delete file func */
221
222
223 /*
224 * Camera ID
225 */
226 int
camera_id(CameraText * id)227 camera_id(CameraText *id)
228 {
229 strcpy(id->text,"Traveler SX330z");
230 return (GP_OK);
231 } /* camera id */
232
233
234
235
236 /*
237 * Camera about
238 */
239 static int
camera_about(Camera * camera,CameraText * about,GPContext * context)240 camera_about(Camera *camera,CameraText *about,GPContext *context)
241 {
242 strcpy(about->text,_("(Traveler) SX330z Library (And other Aldi-cams).\n"
243 "Even other Vendors like Jenoptik, Skanhex, Maginon should work.\n"
244 "Please send bugreports and comments.\n"
245 "Dominik Kuhlen <kinimod@users.sourceforge.net>\n"));
246 return(GP_OK);
247 } /* camera about */
248
249
250 /*
251 * camera_exit
252 * release allocated memory
253 */
254 int
camera_exit(Camera * camera,GPContext * context)255 camera_exit(Camera *camera, GPContext *context)
256 {
257 if (camera->pl)
258 free(camera->pl);
259 return(GP_OK);
260 }
261
262
263 static CameraFilesystemFuncs fsfuncs = {
264 .file_list_func = file_list_func,
265 .get_file_func = get_file_func,
266 .del_file_func = del_file_func
267 };
268
269 /*
270 * OK, lets get serious !
271 */
272 int
camera_init(Camera * camera,GPContext * context)273 camera_init(Camera *camera,GPContext *context)
274 {
275 GPPortSettings settings;
276 CameraAbilities abilities;
277 /* try to contact the camera ...*/
278 /*CR(gp_port_get_settings(camera->port,&settings));*/
279
280 camera->functions->about=camera_about;
281 camera->functions->exit=camera_exit;
282 gp_port_get_settings(camera->port,&settings);
283 if (camera->port->type!=GP_PORT_USB)
284 {
285 gp_context_error(context,_("sx330z is USB only"));
286 return(GP_ERROR_UNKNOWN_PORT);
287 }
288 /* GP_DEBUG("camera_init : in = %x",camera->port->settings.usb.inep);*/
289 CR(gp_port_set_settings(camera->port,settings));
290 CR(gp_port_set_timeout(camera->port,TIMEOUT));
291
292 CR(gp_filesystem_set_funcs(camera->fs, &fsfuncs, camera));
293
294 camera->pl=malloc(sizeof(CameraPrivateLibrary));
295 if (!camera->pl)
296 return(GP_ERROR_NO_MEMORY);
297
298 CR(gp_camera_get_abilities(camera, &abilities));
299 camera->pl->usb_product=abilities.usb_product; /* some models differ in Thumbnail size */
300 /* GP_DEBUG("sx330z Camera_init : sx init %04x",camera->pl->usb_product); */
301 return(sx330z_init(camera,context));
302
303 } /* camera init */
304
305