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