1 /* Sony DSC-F55 & MSAC-SR1 - gPhoto2 camera library
2  * Copyright 2001, 2002, 2004 Raymond Penners <raymond@dotsphinx.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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 
20 #include "config.h"
21 
22 #include <string.h>
23 #include <stdlib.h>
24 
25 #include <gphoto2/gphoto2.h>
26 #include <sys/types.h>
27 
28 #include "sony.h"
29 #include "nls.h"
30 #include <gphoto2/gphoto2-camera.h>
31 
32 #define GP_MODULE "sonydscf55"
33 
34 struct ModelInfo {
35 	SonyModel model_id;
36 	const char *model_str;
37 };
38 
39 static const struct ModelInfo models[] = {
40 	{ SONY_MODEL_MSAC_SR1, "Sony:MSAC-SR1" },
41 	{ SONY_MODEL_DCR_PC100, "Sony:DCR-PC100" },
42 	{ SONY_MODEL_TRV_20E,   "Sony:TRV-20E" },
43 	{ SONY_MODEL_DSC_F55, "Sony:DSC-F55" }
44 };
45 
46 int
camera_id(CameraText * id)47 camera_id(CameraText * id)
48 {
49 	strcpy(id->text, SONY_CAMERA_ID);
50 	return (GP_OK);
51 }
52 
53 int
camera_abilities(CameraAbilitiesList * list)54 camera_abilities(CameraAbilitiesList * list)
55 {
56 	unsigned int i;
57 	CameraAbilities a;
58 
59 	for (i = 0; i < sizeof(models) / sizeof(models[i]); i++) {
60 		memset(&a, 0, sizeof(a));
61 		strcpy(a.model, models[i].model_str);
62 		a.status = GP_DRIVER_STATUS_PRODUCTION;
63 		a.port = GP_PORT_SERIAL;
64 		a.speed[0] = 0;
65 		a.operations = GP_OPERATION_NONE;
66 		a.file_operations = GP_FILE_OPERATION_PREVIEW | GP_FILE_OPERATION_EXIF;
67 		a.folder_operations = GP_FOLDER_OPERATION_NONE;
68 		gp_abilities_list_append(list, a);
69 	}
70 
71 	return (GP_OK);
72 }
73 
74 /**
75  * De-initialises camera
76  */
77 static int
camera_exit(Camera * camera,GPContext * context)78 camera_exit(Camera * camera, GPContext *context)
79 {
80 	int rc;
81 
82 	GP_DEBUG(
83 			"camera_exit()");
84 
85 	if (camera->pl) {
86 		rc = sony_exit (camera);
87 		if (rc < 0)
88 			return (rc);
89 		free (camera->pl);
90 		camera->pl = NULL;
91 	}
92 
93 	return (GP_OK);
94 }
95 
96 
97 
98 static int
camera_about(Camera * camera,CameraText * about,GPContext * context)99 camera_about(Camera * camera, CameraText * about, GPContext *context)
100 {
101 	strcpy(about->text,
102 	       _("Sony DSC-F55/505 gPhoto library\n"
103 		 "Supports Sony MSAC-SR1 and Memory Stick used by DCR-PC100\n"
104 		 "Originally written by Mark Davies <mdavies@dial.pipex.com>\n"
105 		 "gPhoto2 port by Raymond Penners <raymond@dotsphinx.com>"));
106 
107 	return (GP_OK);
108 }
109 
110 static int
file_list_func(CameraFilesystem * fs,const char * folder,CameraList * list,void * data,GPContext * context)111 file_list_func (CameraFilesystem *fs, const char *folder, CameraList *list,
112 		void *data, GPContext *context)
113 {
114 	Camera *camera = data;
115 	int mpeg, rc = GP_OK;
116 
117 	GP_DEBUG("camera_folder_list_files()");
118 
119 	for (mpeg = 0; mpeg <= 1 && rc == GP_OK; mpeg++) {
120 		int i, count;
121 		SonyFileType file_type;
122 
123 		file_type = mpeg ? SONY_FILE_MPEG : SONY_FILE_IMAGE;
124 
125 		rc = sony_file_count(camera, file_type, &count);
126 		if (rc != GP_OK) {
127 			break;
128 		}
129 
130 		for (i = 1; i <= count; i++) {
131 			char buf[13];
132 			rc = sony_file_name_get(camera, i, file_type, buf);
133 			if (rc != GP_OK) {
134 				break;
135 			}
136 			gp_list_append(list, buf, NULL);
137 
138 			if (gp_context_cancel(context)
139 			    == GP_CONTEXT_FEEDBACK_CANCEL) {
140 				rc = GP_ERROR_CANCEL;
141 			}
142 		}
143 	}
144 	return rc;
145 }
146 
147 
148 static int
get_sony_file_id(Camera * camera,const char * folder,const char * filename,GPContext * context,int * sony_id,SonyFileType * sony_type)149 get_sony_file_id(Camera *camera, const char *folder,
150 		 const char *filename, GPContext *context,
151 		 int *sony_id, SonyFileType *sony_type)
152 {
153 	int num = gp_filesystem_number(camera->fs, folder, filename, context);
154 	if (num < 0)
155 		return (num);
156 
157 	num++;
158 
159 	if (sony_is_mpeg_file_name(filename)) {
160 		const char *name_found;
161 		int mpeg_num = 0;
162 		do {
163 			mpeg_num++;
164 			gp_filesystem_name(camera->fs, folder, num-mpeg_num, &name_found, context);
165 		}
166 		while (sony_is_mpeg_file_name(name_found)
167 		       && (mpeg_num<=num));
168 		mpeg_num--;
169 
170 		*sony_type = SONY_FILE_MPEG;
171 		*sony_id = mpeg_num;
172 	}
173 	else {
174 		*sony_type = SONY_FILE_IMAGE;
175 		*sony_id = num;
176 	}
177 	return GP_OK;
178 }
179 
180 
181 static int
get_file_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileType type,CameraFile * file,void * data,GPContext * context)182 get_file_func (CameraFilesystem *fs, const char *folder, const char *filename,
183 	       CameraFileType type, CameraFile * file, void *data,
184 	       GPContext *context)
185 {
186 	Camera *camera = data;
187 	int num;
188 	SonyFileType file_type;
189 	int rc = GP_ERROR;
190 
191 	GP_DEBUG("camera_file_get(\"%s/%s\")", folder, filename);
192 
193 	rc = get_sony_file_id(camera, folder, filename, context,
194 			      &num, &file_type);
195 	if (rc != GP_OK)
196 		return rc;
197 
198 	switch (type) {
199 	case GP_FILE_TYPE_NORMAL:
200 		if (file_type == SONY_FILE_MPEG) {
201 			rc = sony_mpeg_get(camera, num, file, context);
202                 }
203 		else {
204 			rc = sony_image_get(camera, num, file, context);
205 		}
206 		break;
207 	case GP_FILE_TYPE_PREVIEW:
208 		if (file_type == SONY_FILE_MPEG) {
209 			rc = GP_OK;
210 		}
211 		else {
212 			rc = sony_thumbnail_get(camera, num, file, context);
213 		}
214 		break;
215 	case GP_FILE_TYPE_EXIF:
216 		if (file_type == SONY_FILE_MPEG) {
217 			rc = GP_OK;
218 		}
219 		else {
220 			rc = sony_exif_get(camera, num, file, context);
221 		}
222 		break;
223 	default:
224 		rc = GP_ERROR_NOT_SUPPORTED;
225 	}
226 	return rc;
227 }
228 
229 
230 
231 static int
get_info_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileInfo * info,void * data,GPContext * context)232 get_info_func (CameraFilesystem *fs, const char *folder,
233 	       const char *filename, CameraFileInfo *info, void *data,
234 	       GPContext *context)
235 {
236 	Camera *camera = data;
237 	int num, rc;
238 	SonyFileType file_type;
239 
240 	rc = get_sony_file_id(camera, folder, filename, context,
241 			      &num, &file_type);
242 	if (rc != GP_OK)
243 		return rc;
244 
245 	rc = sony_image_info(camera, num, file_type, info, context);
246 	return rc;
247 }
248 
249 
250 static int
model_compare(const char * a,const char * b)251 model_compare(const char *a, const char *b)
252 {
253 	const char *amod;
254 	const char *bmod;
255 	int alen, blen;
256 
257 	alen = strlen(a);
258 	blen = strlen(b);
259 	if (alen != blen)
260 		return 0;
261 	amod = strchr(a, ':');
262 	bmod = strchr(b, ':');
263 	if ((amod == NULL && bmod == NULL)
264 	    || (amod != NULL && bmod != NULL)) {
265 		return !strcasecmp(a, b);
266 	}
267 	if (amod != NULL) {
268 		int aidx = amod - a;
269 		return (!strncasecmp(a, b, aidx))
270 			&& (!strcasecmp(a+aidx+1, b+aidx+1));
271 	}
272 	if (bmod != NULL) {
273 		int bidx = bmod - b;
274 		return (!strncasecmp(a, b, bidx))
275 			&& (!strcasecmp(a+bidx+1, b+bidx+1));
276 	}
277 	/* can't really get here */
278 	return 42;
279 }
280 
281 static int
get_camera_model(Camera * camera,SonyModel * model)282 get_camera_model(Camera *camera, SonyModel *model)
283 {
284 	CameraAbilities a;
285 	int rc;
286 
287 	rc = gp_camera_get_abilities (camera, &a);
288 	if (rc == GP_OK) {
289 		unsigned int i;
290 		rc = GP_ERROR;
291 		for (i = 0; i < sizeof(models) / sizeof(models[i]); i++) {
292 			if (model_compare(models[i].model_str,
293 						 a.model)) {
294 				rc = GP_OK;
295 				*model = models[i].model_id;
296 				break;
297 			}
298 		}
299 	}
300 	return rc;
301 }
302 
303 
304 static CameraFilesystemFuncs fsfuncs = {
305 	.file_list_func = file_list_func,
306 	.get_file_func = get_file_func,
307 	.get_info_func = get_info_func
308 };
309 
310 /**
311  * Initialises camera
312  */
313 int
camera_init(Camera * camera,GPContext * context)314 camera_init(Camera * camera, GPContext *context)
315 {
316 	int rc;
317 	SonyModel model;
318 
319 	rc = get_camera_model(camera, &model);
320 	if (rc != GP_OK)
321 		return rc;
322 
323 	camera->functions->exit = camera_exit;
324 	camera->functions->about = camera_about;
325 	gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera);
326 
327 	camera->pl = malloc (sizeof (CameraPrivateLibrary));
328 	if (!camera->pl)
329 		return (GP_ERROR_NO_MEMORY);
330 
331 	rc = sony_init (camera, model);
332 	if (rc < 0) {
333 		free (camera->pl);
334 		camera->pl = NULL;
335 		return (rc);
336 	}
337 	return (GP_OK);
338 }
339 
340 /*
341  * Local Variables:
342  * c-file-style:"linux"
343  * indent-tabs-mode:t
344  * End:
345  */
346