$search
00001 /********************************************************************* 00002 * 00003 * Software License Agreement (BSD License) 00004 * 00005 * Copyright (c) 2009, Robert Bosch LLC. 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * * Redistributions in binary form must reproduce the above 00015 * copyright notice, this list of conditions and the following 00016 * disclaimer in the documentation and/or other materials provided 00017 * with the distribution. 00018 * * Neither the name of the Robert Bosch nor the names of its 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00028 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00030 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00032 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 * POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 *********************************************************************/ 00036 #include <cstdlib> 00037 #include <cstdio> 00038 #include <cstring> 00039 #include <photo/photo.h> 00040 00041 static void 00042 ctx_error_func (GPContext *context, const char *format, va_list args, void *data) 00043 { 00044 fprintf (stderr, "\n"); 00045 fprintf (stderr, "*** Contexterror *** \n"); 00046 vfprintf (stderr, format, args); 00047 fprintf (stderr, "\n"); 00048 fflush (stderr); 00049 } 00050 00051 static void 00052 ctx_status_func (GPContext *context, const char *format, va_list args, void *data) 00053 { 00054 vfprintf (stderr, format, args); 00055 fprintf (stderr, "\n"); 00056 fflush (stderr); 00057 } 00058 00059 static GPPortInfoList *portinfolist = NULL; 00060 static CameraAbilitiesList *abilities = NULL; 00061 00062 /* 00063 * This detects all currently attached photos and returns 00064 * them in a list. It avoids the generic usb: entry. 00065 * 00066 * This function does not open nor initialize the photos yet. 00067 */ 00068 int camera_autodetect(CameraList *list, GPContext *context) 00069 { 00070 int ret, i; 00071 CameraList *xlist = NULL; 00072 00073 ret = gp_list_new(&xlist); 00074 if (ret<GP_OK) 00075 goto out; 00076 if (!portinfolist) { 00077 /* Load all the port drivers we have... */ 00078 ret = gp_port_info_list_new(&portinfolist); 00079 if (ret<GP_OK) 00080 goto out; 00081 ret = gp_port_info_list_load(portinfolist); 00082 if (ret<0) 00083 goto out; 00084 ret = gp_port_info_list_count(portinfolist); 00085 if (ret<0) 00086 goto out; 00087 } 00088 /* Load all the photo drivers we have... */ 00089 ret = gp_abilities_list_new(&abilities); 00090 if (ret<GP_OK) 00091 goto out; 00092 ret = gp_abilities_list_load(abilities, context); 00093 if (ret<GP_OK) 00094 goto out; 00095 00096 /* ... and autodetect the currently attached photos. */ 00097 ret = gp_abilities_list_detect(abilities, portinfolist, xlist, context); 00098 if (ret<GP_OK) 00099 goto out; 00100 00101 /* Filter out the "usb:" entry */ 00102 ret = gp_list_count(xlist); 00103 if (ret<GP_OK) 00104 goto out; 00105 for(i = 0; i<ret; i++) { 00106 const char *name, *value; 00107 gp_list_get_name(xlist, i, &name); 00108 gp_list_get_value(xlist, i, &value); 00109 if (!strcmp("usb:", value)) 00110 continue; 00111 gp_list_append(list, name, value); 00112 } 00113 out: gp_list_free(xlist); 00114 return gp_list_count(list); 00115 } 00116 00117 /* 00118 * This function opens a camera depending on the specified model and port. 00119 */ 00120 static int camera_open(Camera ** photo, const char *model, const char *port) 00121 { 00122 int ret, m, p; 00123 CameraAbilities a; 00124 GPPortInfo pi; 00125 00126 ret = gp_camera_new(photo); 00127 if (ret<GP_OK) 00128 return ret; 00129 00130 /* First lookup the model / driver */ 00131 m = gp_abilities_list_lookup_model(abilities, model); 00132 if (m<GP_OK) 00133 return ret; 00134 ret = gp_abilities_list_get_abilities(abilities, m, &a); 00135 if (ret<GP_OK) 00136 return ret; 00137 ret = gp_camera_set_abilities(*photo, a); 00138 if (ret<GP_OK) 00139 return ret; 00140 00141 /* Then associate the photo with the specified port */ 00142 p = gp_port_info_list_lookup_path(portinfolist, port); 00143 if (ret<GP_OK) 00144 return ret; 00145 switch (p) { 00146 case GP_ERROR_UNKNOWN_PORT: 00147 fprintf(stderr, "The port you specified " 00148 "('%s') can not be found. Please " 00149 "specify one of the ports found by " 00150 "'gphoto2 --list-ports' and make " 00151 "sure the spelling is correct " 00152 "(i.e. with prefix 'serial:' or 'usb:').", port); 00153 break; 00154 default: 00155 break; 00156 } 00157 if (ret<GP_OK) 00158 return ret; 00159 ret = gp_port_info_list_get_info(portinfolist, p, &pi); 00160 if (ret<GP_OK) 00161 return ret; 00162 ret = gp_camera_set_port_info(*photo, pi); 00163 if (ret<GP_OK) 00164 return ret; 00165 return GP_OK; 00166 } 00167 00168 GPContext* photo_create_context() 00169 { 00170 GPContext *context; 00171 00172 /* This is the mandatory part */ 00173 context = gp_context_new(); 00174 00175 /* All the parts below are optional! */ 00176 gp_context_set_error_func (context, ctx_error_func, NULL); 00177 gp_context_set_status_func (context, ctx_status_func, NULL); 00178 00179 return context; 00180 } 00181 00182 photo_p photo_initialize(void) 00183 { 00184 photo_p photo; 00185 photo = (photo_p)calloc(1, sizeof(photo_t)); 00186 photo->context = NULL; 00187 photo->cam = NULL; 00188 return photo; 00189 } 00190 00191 void photo_free(photo_p photo) 00192 { 00193 if(photo->context) 00194 free(photo->context); 00195 if(photo->cam) 00196 free(photo->cam); 00197 free(photo); 00198 } 00199 00200 int photo_open(photo_p photo, const char *model, const char *port) 00201 { 00202 int ret; 00203 00204 /* create a context */ 00205 photo->context = photo_create_context(); 00206 00207 /* open a specific photo on port */ 00208 ret = camera_open(&photo->cam, model, port); 00209 if (ret != GP_OK) { 00210 fprintf(stderr, "Camera %s on port %s failed to open\n", model, port); 00211 } 00212 00213 return (ret == GP_OK); 00214 } 00215 00216 int photo_autodetect(photo_p photo) 00217 { 00218 CameraList *list; 00219 Camera **cams; 00220 int ret, i, count; 00221 const char *name, *value; 00222 int selected = -1; 00223 00224 /* create a context */ 00225 photo->context = photo_create_context(); 00226 00227 /* Detect all the photos that can be autodetected... */ 00228 ret = gp_list_new(&list); 00229 if (ret<GP_OK) 00230 return 0; 00231 count = camera_autodetect(list, photo->context); 00232 00233 /* Now open all photos we autodected for usage */ 00234 printf("Number of photos: %d\n", count); 00235 cams = (Camera**)calloc(sizeof(Camera*), count); 00236 for(i = 0; i<count; i++) { 00237 gp_list_get_name(list, i, &name); 00238 gp_list_get_value(list, i, &value); 00239 ret = camera_open(&cams[i], name, value); 00240 if (ret==GP_OK) { 00241 selected = i; 00242 photo->cam = cams[i]; 00243 break; 00244 } 00245 else { 00246 fprintf(stderr, "Camera %s on port %s failed to open\n", name, value); 00247 } 00248 } 00249 00250 if(selected<0) { 00251 fprintf(stderr, "Could not find any photo.\n"); 00252 } 00253 00254 return (selected>=0); 00255 } 00256 00257 00258 //int photo_autodetect(photo_p photo) 00259 //{ 00260 // int ret; //, i, count; 00261 // CameraText text; 00262 // 00263 // /* create a context */ 00264 // photo->context = photo_create_context(); 00265 // 00266 // /* create a new camera */ 00267 // gp_camera_new(&photo->cam); 00268 // 00269 // /* this will autodetect the cameras, and take the first one */ 00270 // ret = gp_camera_init(photo->cam,photo->context); 00271 // if (ret < GP_OK) { 00272 // printf("No camera auto detected.\n"); 00273 // gp_camera_free(photo->cam); 00274 // return 0; 00275 // } 00276 // 00277 // /* get camera summary */ 00278 // ret = gp_camera_get_summary(photo->cam,&text,photo->context); 00279 // if (ret < GP_OK) { 00280 // printf("Camera failed retrieving summary.\n"); 00281 // gp_camera_free(photo->cam); 00282 // return 0; 00283 // } 00284 // 00285 // printf("Summary:\n%s\n",text.text); 00286 // return 1; 00287 //} 00288 00289 int photo_close(photo_p photo) 00290 { 00291 int ret; 00292 ret = gp_camera_exit(photo->cam, photo->context); 00293 if (ret != GP_OK) { 00294 fprintf(stderr, "Could not close photo\n"); 00295 } 00296 return (ret == GP_OK); 00297 } 00298 00299 00300 00301