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