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