1 // python-gphoto2 - Python interface to libgphoto2
2 // http://github.com/jim-easterbrook/python-gphoto2
3 // Copyright (C) 2014-20  Jim Easterbrook  jim@jim-easterbrook.me.uk
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 %module(package="gphoto2", threads="1") camera
19 %nothread;
20 
21 %include "common/preamble.i"
22 
23 %include "stdint.i"
24 
25 %rename(Camera) _Camera;
26 
27 // Make docstring parameter types more Pythonic
28 %typemap(doc) Camera * "$1_name: gphoto2.$*1_type"
29 %typemap(doc) enum CameraCaptureType "$1_name: $1_type (gphoto2.GP_CAPTURE_IMAGE etc.)"
30 
31 #ifndef SWIGIMPORTED
32 
33 // Allow other Python threads to continue during some function calls
34 %thread gp_camera_wait_for_event;
35 %thread gp_camera_capture;
36 %thread gp_camera_trigger_capture;
37 %thread gp_camera_capture_preview;
38 %thread gp_camera_init;
39 %thread gp_camera_get_config;
40 %thread gp_camera_get_single_config;
41 %thread gp_camera_set_config;
42 %thread gp_camera_set_single_config;
43 %thread gp_camera_folder_list_files;
44 %thread gp_camera_folder_list_folders;
45 %thread gp_camera_folder_delete_all;
46 %thread gp_camera_folder_put_file;
47 %thread gp_camera_file_get;
48 %thread gp_camera_file_get_info;
49 %thread gp_camera_file_read;
50 
51 // Many functions accept NULL context value
52 DEFAULT_CONTEXT
53 
54 // gp_camera_get_abilities() returns a pointer in an output parameter
55 CALLOC_ARGOUT(CameraAbilities *abilities)
56 
57 // gp_camera_new() returns a pointer in an output parameter
58 PLAIN_ARGOUT(Camera **)
59 
60 // gp_camera_get_summary() etc. return a pointer in an output parameter
61 CALLOC_ARGOUT(CameraText *summary)
62 CALLOC_ARGOUT(CameraText *manual)
63 CALLOC_ARGOUT(CameraText *about)
64 
65 // gp_camera_folder_list_files() etc. return a pointer in an output parameter
66 NEW_ARGOUT(CameraList *, gp_list_new, gp_list_unref)
67 
68 // gp_camera_capture_preview() & gp_camera_file_get() return a pointer
69 NEW_ARGOUT(CameraFile *camera_file, gp_file_new, gp_file_unref)
70 // Redefine signature as gp_camera_folder_put_file() also uses *file
71 int gp_camera_capture_preview(Camera *camera, CameraFile *camera_file, GPContext *context);
72 %ignore gp_camera_capture_preview;
73 
74 // gp_camera_capture() returns a pointer in an output parameter
75 CALLOC_ARGOUT(CameraFilePath *path)
76 
77 // gp_camera_file_read() fills a user-supplied buffer
78 %typemap(doc) (char * buf, uint64_t * size) "$1_name: writable buffer (e.g. memoryview)"
79 %typemap(in, numinputs=1) (char * buf, uint64_t * size) (uint64_t temp) {
80   Py_buffer view;
81   if (PyObject_CheckBuffer($input) != 1) {
82     PyErr_SetString(
83       PyExc_TypeError,
84       "in method '$symname', argument $argnum does not support the buffer interface");
85     SWIG_fail;
86   }
87   if (PyObject_GetBuffer($input, &view, PyBUF_SIMPLE | PyBUF_WRITABLE) != 0) {
88     PyErr_SetString(
89       PyExc_TypeError,
90       "in method '$symname', argument $argnum does not export a writable buffer");
91     SWIG_fail;
92   }
93   $1 = view.buf;
94   temp = view.len;
95   $2 = &temp;
96   PyBuffer_Release(&view);
97 }
98 %typemap(argout) (char * buf, uint64_t * size) {
99   $result = SWIG_Python_AppendOutput($result, PyLong_FromUnsignedLongLong(*$2));
100 }
101 
102 // Add default constructor and destructor to _Camera
103 DEFAULT_CTOR(_Camera, gp_camera_new)
104 DEFAULT_DTOR(_Camera, gp_camera_unref)
105 %ignore gp_camera_ref;
106 %ignore gp_camera_unref;
107 
108 // Add member methods to _Camera
109 MEMBER_FUNCTION(_Camera,
110     static void, autodetect, (CameraList *list, GPContext *context),
111     gp_camera_autodetect, (list, context), )
112 MEMBER_FUNCTION(_Camera,
113     void, set_abilities, (CameraAbilities abilities),
114     gp_camera_set_abilities, ($self, abilities), )
115 MEMBER_FUNCTION(_Camera,
116     void, get_abilities, (CameraAbilities *abilities),
117     gp_camera_get_abilities, ($self, abilities), )
118 MEMBER_FUNCTION(_Camera,
119     void, set_port_info, (GPPortInfo info),
120     gp_camera_set_port_info, ($self, info), )
121 MEMBER_FUNCTION(_Camera,
122     void, get_port_info, (GPPortInfo *info),
123     gp_camera_get_port_info, ($self, info), )
124 MEMBER_FUNCTION(_Camera,
125     void, set_port_speed, (int speed),
126     gp_camera_set_port_speed, ($self, speed), )
127 MEMBER_FUNCTION(_Camera,
128     int, get_port_speed, (),
129     gp_camera_get_port_speed, ($self), )
130 MEMBER_FUNCTION(_Camera,
131     void, init, (GPContext *context),
132     gp_camera_init, ($self, context), 1)
133 MEMBER_FUNCTION(_Camera,
134     void, exit, (GPContext *context),
135     gp_camera_exit, ($self, context), )
136 MEMBER_FUNCTION(_Camera,
137     void, get_config, (CameraWidget **window, GPContext *context),
138     gp_camera_get_config, ($self, window, context), 1)
139 MEMBER_FUNCTION(_Camera,
140     void, list_config, (CameraList *list, GPContext *context),
141     gp_camera_list_config, ($self, list, context), )
142 MEMBER_FUNCTION(_Camera,
143     void, get_single_config, (const char *name, CameraWidget **widget, GPContext *context),
144     gp_camera_get_single_config, ($self, name, widget, context), 1)
145 MEMBER_FUNCTION(_Camera,
146     void, set_config, (CameraWidget *window, GPContext *context),
147     gp_camera_set_config, ($self, window, context), 1)
148 MEMBER_FUNCTION(_Camera,
149     void, set_single_config, (const char *name, CameraWidget *widget, GPContext *context),
150     gp_camera_set_single_config, ($self, name, widget, context), 1)
151 MEMBER_FUNCTION(_Camera,
152     void, get_summary, (CameraText *summary, GPContext *context),
153     gp_camera_get_summary, ($self, summary, context), )
154 MEMBER_FUNCTION(_Camera,
155     void, get_manual, (CameraText *manual, GPContext *context),
156     gp_camera_get_manual, ($self, manual, context), )
157 MEMBER_FUNCTION(_Camera,
158     void, get_about, (CameraText *about, GPContext *context),
159     gp_camera_get_about, ($self, about, context), )
160 MEMBER_FUNCTION(_Camera,
161     void, capture, (CameraCaptureType type, CameraFilePath *path, GPContext *context),
162     gp_camera_capture, ($self, type, path, context), 1)
163 MEMBER_FUNCTION(_Camera,
164     void, trigger_capture, (GPContext *context),
165     gp_camera_trigger_capture, ($self, context), 1)
166 MEMBER_FUNCTION(_Camera,
167     void, capture_preview, (CameraFile *camera_file, GPContext *context),
168     gp_camera_capture_preview, ($self, camera_file, context), 1)
169 MEMBER_FUNCTION(_Camera,
170     void, wait_for_event,
171     (int timeout, CameraEventType *eventtype, void **eventdata, GPContext *context),
172     gp_camera_wait_for_event, ($self, timeout, eventtype, eventdata, context), 1)
173 MEMBER_FUNCTION(_Camera,
174     void, get_storageinfo, (CameraStorageInformation **sifs, int *nrofsifs, GPContext *context),
175     gp_camera_get_storageinfo, ($self, sifs, nrofsifs, context), )
176 MEMBER_FUNCTION(_Camera,
177     void, folder_list_files, (const char *folder, CameraList *list, GPContext *context),
178     gp_camera_folder_list_files, ($self, folder, list, context), 1)
179 MEMBER_FUNCTION(_Camera,
180     void, folder_list_folders, (const char *folder, CameraList *list, GPContext *context),
181     gp_camera_folder_list_folders, ($self, folder, list, context), 1)
182 MEMBER_FUNCTION(_Camera,
183     void, folder_delete_all, (const char *folder, GPContext *context),
184     gp_camera_folder_delete_all, ($self, folder, context), 1)
185 MEMBER_FUNCTION(_Camera,
186     void, folder_put_file, (const char *folder, const char *filename, CameraFileType type, CameraFile *file, GPContext *context),
187     gp_camera_folder_put_file, ($self, folder, filename, type, file, context), 1)
188 MEMBER_FUNCTION(_Camera,
189     void, folder_make_dir, (const char *folder, const char *name, GPContext *context),
190     gp_camera_folder_make_dir, ($self, folder, name, context), )
191 MEMBER_FUNCTION(_Camera,
192     void, folder_remove_dir, (const char *folder, const char *name, GPContext *context),
193     gp_camera_folder_remove_dir, ($self, folder, name, context), )
194 MEMBER_FUNCTION(_Camera,
195     void, file_get_info, (const char *folder, const char *file, CameraFileInfo *info, GPContext *context),
196     gp_camera_file_get_info, ($self, folder, file, info, context), 1)
197 MEMBER_FUNCTION(_Camera,
198     void, file_set_info, (const char *folder, const char *file, CameraFileInfo info, GPContext *context),
199     gp_camera_file_set_info, ($self, folder, file, info, context), )
200 MEMBER_FUNCTION(_Camera,
201     void, file_get, (const char *folder, const char *file, CameraFileType type, CameraFile *camera_file, GPContext *context),
202     gp_camera_file_get, ($self, folder, file, type, camera_file, context), 1)
203 MEMBER_FUNCTION(_Camera,
204     void, file_read, (const char *folder, const char *file, CameraFileType type, uint64_t offset, char *buf, uint64_t *size, GPContext *context),
205     gp_camera_file_read, ($self, folder, file, type, offset, buf, size, context), 1)
206 MEMBER_FUNCTION(_Camera,
207     void, file_delete, (const char *folder, const char *file, GPContext *context),
208     gp_camera_file_delete, ($self, folder, file, context), )
209 
210 // gp_camera_get_storageinfo() returns an allocated array in an output parameter
211 %typemap(in, numinputs=0)
212     (CameraStorageInformation **, int *)
213         (CameraStorageInformation* temp_ptr, int temp_cnt),
214     (CameraStorageInformation **sifs, int *nrofsifs)
215         (CameraStorageInformation* temp_ptr, int temp_cnt){
216   temp_ptr = NULL;
217   temp_cnt = 0;
218   $1 = &temp_ptr;
219   $2 = &temp_cnt;
220 }
221 %typemap(argout) (CameraStorageInformation **, int *),
222                  (CameraStorageInformation **sifs, int *nrofsifs) {
223   // copy single array of CameraStorageInformation to individual Python objects
224   PyObject* out_list = PyList_New(*$2);
225   int n;
226   for (n = 0; n < *$2; n++) {
227     CameraStorageInformation* new_sif = malloc(sizeof(CameraStorageInformation));
228     if (new_sif == NULL) {
229       PyErr_SetString(PyExc_MemoryError, "Cannot allocate " "$*1_type");
230       SWIG_fail;
231     }
232     memcpy(new_sif, &(*$1)[n], sizeof(CameraStorageInformation));
233     PyList_SetItem(out_list, n,
234         SWIG_NewPointerObj(new_sif, SWIGTYPE_p__CameraStorageInformation, SWIG_POINTER_OWN));
235   }
236   $result = SWIG_Python_AppendOutput($result, out_list);
237 }
238 %typemap(freearg) (CameraStorageInformation **, int *),
239                   (CameraStorageInformation **sifs, int *nrofsifs) {
240   // deallocate CameraStorageInformation array allocated by gp_camera_get_storageinfo
241   free(*$1);
242 }
243 
244 // Substitute definitions of things added during libgphoto2 development
245 %{
246 #if GPHOTO2_VERSION < 0x02050a
gp_camera_list_config(Camera * camera,CameraList * list,GPContext * context)247 int gp_camera_list_config(Camera *camera, CameraList *list, GPContext *context) {
248     return GP_ERROR_NOT_SUPPORTED;
249 }
gp_camera_get_single_config(Camera * camera,const char * name,CameraWidget ** widget,GPContext * context)250 int gp_camera_get_single_config(Camera *camera, const char *name,
251                                 CameraWidget **widget, GPContext *context) {
252     return GP_ERROR_NOT_SUPPORTED;
253 }
gp_camera_set_single_config(Camera * camera,const char * name,CameraWidget * widget,GPContext * context)254 int gp_camera_set_single_config(Camera *camera, const char *name,
255                                 CameraWidget *widget, GPContext *context) {
256     return GP_ERROR_NOT_SUPPORTED;
257 }
258 #endif
259 #if GPHOTO2_VERSION < 0x020511
260   int GP_EVENT_FILE_CHANGED = GP_EVENT_CAPTURE_COMPLETE + 1;
261 #endif
262 %}
263 
264 // gp_camera_wait_for_event() returns two pointers in output parameters
265 %typemap(in, numinputs=0) (CameraEventType * eventtype, void ** eventdata)
266                           (CameraEventType temp_type, void *temp_data) {
267   temp_type = -1;
268   temp_data = NULL;
269   $1 = &temp_type;
270   $2 = &temp_data;
271 }
272 %typemap(argout) (CameraEventType * eventtype, void ** eventdata) {
273   $result = SWIG_Python_AppendOutput($result, PyInt_FromLong(*$1));
274   if (*$1 == GP_EVENT_FILE_ADDED || *$1 == GP_EVENT_FOLDER_ADDED
275                                  || *$1 == GP_EVENT_FILE_CHANGED) {
276     $result = SWIG_Python_AppendOutput(
277       $result, SWIG_NewPointerObj(*$2, SWIGTYPE_p_CameraFilePath, SWIG_POINTER_OWN));
278   }
279   else if (*$1 == GP_EVENT_UNKNOWN && *$2 != NULL) {
280     $result = SWIG_Python_AppendOutput($result, PyString_FromString(*$2));
281     free(*$2);
282   }
283   else {
284     Py_INCREF(Py_None);
285     $result = SWIG_Python_AppendOutput($result, Py_None);
286     if (*$2 != NULL)
287       free(*$2);
288   }
289 }
290 
291 // Add __str__ method to CameraText
292 #if defined(SWIGPYTHON_BUILTIN)
293 %feature("python:slot", "tp_str", functype="reprfunc") CameraText::__str__;
294 #endif // SWIGPYTHON_BUILTIN
295 %extend CameraText {
__str__()296   char *__str__() {
297     return $self->text;
298   }
299 };
300 
301 // Don't wrap deprecated functions
302 %ignore gp_camera_free;
303 
304 // These structures are private
305 %ignore _CameraFunctions;
306 
307 // Use library functions to access these
308 %ignore _Camera::pl;
309 %ignore _Camera::pc;
310 %ignore _Camera::port;
311 %ignore _Camera::fs;
312 %ignore _Camera::functions;
313 
314 // Other structures are read only
315 %immutable;
316 
317 #endif //ifndef SWIGIMPORTED
318 
319 %include "gphoto2/gphoto2-camera.h"
320