1 /*
2 * This program does the equivalent of:
3 * gphoto2 --wait-event-and-download
4 *
5 * compile with: gcc -Wall -o sample-tether sample-tether.c context.c -lgphoto2
6 *
7 */
8
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <gphoto2/gphoto2.h>
17
18 #include "samples.h"
19
errordumper(GPLogLevel level,const char * domain,const char * str,void * data)20 static void errordumper(GPLogLevel level, const char *domain, const char *str,
21 void *data) {
22 fprintf(stdout, "%s\n", str);
23 }
24
25 static void
camera_tether(Camera * camera,GPContext * context)26 camera_tether(Camera *camera, GPContext *context) {
27 int fd, retval;
28 CameraFile *file;
29 CameraEventType evttype;
30 CameraFilePath *path;
31 void *evtdata;
32
33 printf("Tethering...\n");
34
35 while (1) {
36 retval = gp_camera_wait_for_event (camera, 1000, &evttype, &evtdata, context);
37 if (retval != GP_OK)
38 break;
39 switch (evttype) {
40 case GP_EVENT_FILE_ADDED:
41 path = (CameraFilePath*)evtdata;
42 printf("File added on the camera: %s/%s\n", path->folder, path->name);
43
44 fd = open (path->name, O_CREAT | O_WRONLY | O_BINARY, 0644);
45 retval = gp_file_new_from_fd(&file, fd);
46 printf(" Downloading %s...\n", path->name);
47 retval = gp_camera_file_get(camera, path->folder, path->name,
48 GP_FILE_TYPE_NORMAL, file, context);
49
50 printf(" Deleting %s on camera...\n", path->name);
51 retval = gp_camera_file_delete(camera, path->folder, path->name, context);
52 gp_file_free(file);
53 free(evtdata);
54 break;
55 case GP_EVENT_FOLDER_ADDED:
56 path = (CameraFilePath*)evtdata;
57 printf("Folder added on camera: %s / %s\n", path->folder, path->name);
58 free(evtdata);
59 break;
60 case GP_EVENT_FILE_CHANGED:
61 path = (CameraFilePath*)evtdata;
62 printf("File changed on camera: %s / %s\n", path->folder, path->name);
63 free(evtdata);
64 break;
65 case GP_EVENT_CAPTURE_COMPLETE:
66 printf("Capture Complete.\n");
67 break;
68 case GP_EVENT_TIMEOUT:
69 printf("Timeout.\n");
70 break;
71 case GP_EVENT_UNKNOWN:
72 if (evtdata) {
73 printf("Unknown event: %s.\n", (char*)evtdata);
74 } else {
75 printf("Unknown event.\n");
76 }
77 break;
78 default:
79 printf("Type %d?\n", evttype);
80 break;
81 }
82 }
83 }
84
85 int
main(int argc,char ** argv)86 main(int argc, char **argv) {
87 Camera *camera;
88 int retval;
89 GPContext *context = sample_create_context();
90
91 gp_log_add_func(GP_LOG_ERROR, errordumper, NULL);
92 gp_camera_new(&camera);
93
94 /* When I set GP_LOG_DEBUG instead of GP_LOG_ERROR above, I noticed that the
95 * init function seems to traverse the entire filesystem on the camera. This
96 * is partly why it takes so long.
97 * (Marcus: the ptp2 driver does this by default currently.)
98 */
99 printf("Camera init. Takes about 10 seconds.\n");
100 retval = gp_camera_init(camera, context);
101 if (retval != GP_OK) {
102 printf(" Retval: %d\n", retval);
103 exit (1);
104 }
105
106 camera_tether(camera, context);
107
108 gp_camera_exit(camera, context);
109 return 0;
110 }
111