1 /****************************************************************/
2 /* coolshot.c - Gphoto2 library for accessing the Panasonic */
3 /* Coolshot KXL-600A & KXL-601A digital cameras. */
4 /* */
5 /* Copyright 2001 Chris Pinkham */
6 /* */
7 /* Author: Chris Pinkham <cpinkham@infi.net> */
8 /* */
9 /* This library is free software; you can redistribute it */
10 /* and/or modify it under the terms of the GNU Library General */
11 /* Public License as published by the Free Software Foundation; */
12 /* either version 2 of the License, or (at your option) any */
13 /* later version. */
14 /* */
15 /* This library is distributed in the hope that it will be */
16 /* useful, but WITHOUT ANY WARRANTY; without even the implied */
17 /* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
18 /* PURPOSE. See the GNU Library General Public License for */
19 /* more details. */
20 /* */
21 /* You should have received a copy of the GNU Library General */
22 /* Public License along with this library; if not, write to the */
23 /* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,*/
24 /* Boston, MA 02110-1301 USA */
25 /****************************************************************/
26
27 #include "config.h"
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <gphoto2/gphoto2.h>
33
34 #ifdef ENABLE_NLS
35 # include <libintl.h>
36 # undef _
37 # define _(String) dgettext (GETTEXT_PACKAGE, String)
38 # ifdef gettext_noop
39 # define N_(String) gettext_noop (String)
40 # else
41 # define N_(String) (String)
42 # endif
43 #else
44 # define _(String) (String)
45 # define N_(String) (String)
46 #endif
47
48 #include "library.h"
49
50 #define GP_MODULE "coolshot"
51
52 #define TIMEOUT 2000
53 #define DEFAULT_SPEED 9600
54
55 #define COOLSHOT_VERSION "0.4"
56 #define COOLSHOT_LAST_MOD "09/06/2001 02:28 EST"
57
58 /* define what cameras we support */
59 static char *coolshot_cameras[] = {
60 "Panasonic:Coolshot KXL-600A",
61 "Panasonic:Coolshot KXL-601A",
62 ""
63 };
64
65 struct _CameraPrivateLibrary {
66 int speed;
67 };
68
camera_id(CameraText * id)69 int camera_id (CameraText *id)
70 {
71 /* GP_DEBUG ("* camera_id"); */
72
73 strcpy (id->text, "coolshot");
74
75 return (GP_OK);
76 }
77
camera_abilities(CameraAbilitiesList * list)78 int camera_abilities (CameraAbilitiesList *list)
79 {
80 int x = 0;
81 char *ptr;
82 CameraAbilities a;
83
84 /* GP_DEBUG ("* camera_abilities"); */
85
86 ptr = coolshot_cameras[x++];
87 while (*ptr) {
88 memset(&a, 0, sizeof(a));
89 strcpy (a.model, ptr );
90 a.status = GP_DRIVER_STATUS_PRODUCTION;
91 a.port = GP_PORT_SERIAL;
92 a.speed[0] = 9600;
93 a.speed[1] = 19200;
94 a.speed[2] = 38400;
95 a.speed[3] = 57600;
96 a.speed[4] = 115200;
97 a.speed[5] = 0;
98
99 /* fixme, need to set these operations lists to correct values */
100 a.operations = GP_OPERATION_NONE;
101 a.file_operations = GP_FILE_OPERATION_PREVIEW;
102
103 /* fixme, believe supports GP_FOLDER_PUT_FILE */
104 a.folder_operations = GP_FOLDER_OPERATION_NONE;
105
106 gp_abilities_list_append (list, a);
107
108 ptr = coolshot_cameras[x++];
109 }
110
111 return (GP_OK);
112 }
113
camera_start(Camera * camera)114 static int camera_start (Camera *camera)
115 {
116 GP_DEBUG ("* camera_start");
117
118 /* coolshot_sb sets to default speed if speed == 0 */
119 CHECK (coolshot_sb (camera, camera->pl->speed));
120 return( GP_OK );
121 }
122
camera_stop(Camera * camera)123 static int camera_stop (Camera *camera)
124 {
125 GP_DEBUG ("* camera_stop");
126
127 CHECK (coolshot_sb( camera, DEFAULT_SPEED));
128 return (GP_OK);
129 }
130
file_list_func(CameraFilesystem * fs,const char * folder,CameraList * list,void * data,GPContext * context)131 static int file_list_func (CameraFilesystem *fs, const char *folder,
132 CameraList *list, void *data, GPContext *context)
133 {
134 Camera *camera = data;
135 int count;
136
137 GP_DEBUG ("* file_list_func");
138 GP_DEBUG ("*** folder: %s", folder);
139
140 CHECK (camera_start (camera));
141 CHECK (count = coolshot_file_count (camera));
142 CHECK (gp_list_populate (list, "pic_%04i.jpg", count));
143
144 return (camera_stop (camera));
145 }
146
get_info_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileInfo * info,void * data,GPContext * context)147 static int get_info_func (CameraFilesystem *fs, const char *folder,
148 const char *filename, CameraFileInfo *info, void *data,
149 GPContext *context)
150 {
151 Camera *camera = data;
152 int n;
153
154 GP_DEBUG ("* get_info_func");
155 GP_DEBUG ("*** folder: %s", folder);
156 GP_DEBUG ("*** filename: %s",filename);
157
158 CHECK (camera_start (camera));
159
160 /* Get the file number from the CameraFileSystem */
161 CHECK (n = gp_filesystem_number (camera->fs, folder, filename,
162 context));
163
164 /* fixme, get file size also */
165 info->file.fields = GP_FILE_INFO_TYPE;
166 strcpy (info->file.type, GP_MIME_JPEG );
167
168 info->preview.fields = GP_FILE_INFO_TYPE;
169 strcpy (info->preview.type, GP_MIME_JPEG);
170
171 return (camera_stop (camera));
172 }
173
camera_exit(Camera * camera,GPContext * context)174 static int camera_exit (Camera *camera, GPContext *context)
175 {
176 if (camera->pl) {
177 free (camera->pl);
178 camera->pl = NULL;
179 }
180
181 return (GP_OK);
182 }
183
get_file_func(CameraFilesystem * fs,const char * folder,const char * filename,CameraFileType type,CameraFile * file,void * user_data,GPContext * context)184 static int get_file_func (CameraFilesystem *fs, const char *folder,
185 const char *filename, CameraFileType type,
186 CameraFile *file, void *user_data, GPContext *context)
187 {
188 Camera *camera = user_data;
189 char data[128000];
190 int size, n;
191
192 GP_DEBUG ("* camera_file_get");
193 GP_DEBUG ("*** folder: %s", folder);
194 GP_DEBUG ("*** filename: %s",filename);
195 GP_DEBUG ("*** type: %d", type);
196
197 CHECK (camera_start (camera));
198
199 if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) {
200 camera_stop (camera);
201 return (GP_ERROR_CANCEL);
202 }
203
204 /*
205 * Get the file number from the CameraFileSystem (and increment
206 * because we need numbers starting with 1)
207 */
208 CHECK (n = gp_filesystem_number (camera->fs, folder, filename,
209 context));
210 n++;
211
212 switch (type) {
213 case GP_FILE_TYPE_PREVIEW:
214 CHECK (coolshot_request_thumbnail (camera, file, data, &size, n, context));
215 CHECK (coolshot_build_thumbnail (data, &size));
216 CHECK (gp_file_set_mime_type (file, GP_MIME_PPM));
217 break;
218
219 case GP_FILE_TYPE_NORMAL:
220 CHECK (coolshot_request_image (camera, file, data, &size, n, context));
221 CHECK (gp_file_set_mime_type (file, GP_MIME_JPEG));
222 break;
223 default:
224 return (GP_ERROR_NOT_SUPPORTED);
225 }
226
227 CHECK (gp_file_append (file, data, size));
228
229 return (camera_stop (camera));
230 }
231
camera_summary(Camera * camera,CameraText * summary,GPContext * context)232 static int camera_summary (Camera *camera, CameraText *summary,
233 GPContext *context)
234 {
235 int count;
236 char tmp[1024];
237
238 GP_DEBUG ("* camera_summary");
239
240 CHECK (camera_start (camera));
241
242 /* possibly get # pics, mem free, etc. */
243 count = coolshot_file_count (camera);
244
245 sprintf (tmp, "Frames Taken : %4d\n", count);
246 strcat (summary->text, tmp );
247
248 return (camera_stop (camera));
249 }
250
camera_about(Camera * camera,CameraText * about,GPContext * context)251 static int camera_about (Camera *camera, CameraText *about, GPContext *context)
252 {
253 GP_DEBUG ("* camera_about");
254
255 strcpy (about->text,
256 _("coolshot library v" COOLSHOT_VERSION
257 " " COOLSHOT_LAST_MOD "\n"
258 "Chris Pinkham <cpinkham@infi.net>\n"
259 "Support for Panasonic Coolshot digital cameras\n"
260 "based on reverse engineering serial protocol.\n"
261 "\n"));
262
263 return (GP_OK);
264 }
265
266 static CameraFilesystemFuncs fsfuncs = {
267 .file_list_func = file_list_func,
268 .get_file_func = get_file_func,
269 .get_info_func = get_info_func,
270 };
271
camera_init(Camera * camera,GPContext * context)272 int camera_init (Camera *camera, GPContext *context)
273 {
274 int count;
275 GPPortSettings settings;
276
277 /* First, set up all the function pointers */
278 camera->functions->exit = camera_exit;
279 camera->functions->summary = camera_summary;
280 camera->functions->about = camera_about;
281
282 camera->pl = malloc (sizeof (CameraPrivateLibrary));
283 if (!camera->pl)
284 return (GP_ERROR_NO_MEMORY);
285
286 /* Set up the port and remember the requested speed */
287 CHECK (gp_port_get_settings (camera->port, &settings));
288 camera->pl->speed = settings.serial.speed;
289 settings.serial.speed = DEFAULT_SPEED;
290 settings.serial.bits = 8;
291 settings.serial.parity = 0;
292 settings.serial.stopbits = 1;
293 CHECK (gp_port_set_settings (camera->port, settings));
294 CHECK (gp_port_set_timeout (camera->port, TIMEOUT));
295
296 /* check to see if camera is really there */
297 CHECK (coolshot_enq (camera));
298
299 coolshot_sm (camera);
300
301 /* get number of images */
302 CHECK (count = coolshot_file_count (camera));
303
304 CHECK (camera_start (camera));
305 CHECK (gp_filesystem_set_funcs (camera->fs, &fsfuncs, camera));
306
307 /* coolshot_sb sets to default speed if speed == 0 */
308 CHECK (coolshot_sb (camera, camera->pl->speed));
309
310 return (camera_stop (camera));
311 }
312