1 /* config.c
2  *
3  * Copyright (C) 2003-2020 Marcus Meissner <marcus@jet.franken.de>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA  02110-1301  USA
19  */
20 #define _DEFAULT_SOURCE
21 #include "config.h"
22 
23 #include <math.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <time.h>
28 #ifdef WIN32
29 # include <winsock.h>
30 #else
31 # include <sys/socket.h>
32 # include <netinet/in.h>
33 # include <arpa/inet.h>
34 #endif
35 #include <sys/types.h>
36 
37 #include <gphoto2/gphoto2-library.h>
38 #include <gphoto2/gphoto2-port-log.h>
39 #include <gphoto2/gphoto2-setting.h>
40 
41 #ifdef ENABLE_NLS
42 #  include <libintl.h>
43 #  undef _
44 #  define _(String) dgettext (GETTEXT_PACKAGE, String)
45 #  ifdef gettext_noop
46 #    define N_(String) gettext_noop (String)
47 #  else
48 #    define N_(String) (String)
49 #  endif
50 #else
51 #  define textdomain(String) (String)
52 #  define gettext(String) (String)
53 #  define dgettext(Domain,Message) (Message)
54 #  define dcgettext(Domain,Message,Type) (Message)
55 #  define bindtextdomain(Domain,Directory) (Domain)
56 #  define _(String) (String)
57 #  define N_(String) (String)
58 #endif
59 
60 #include "ptp.h"
61 #include "ptp-bugs.h"
62 #include "ptp-private.h"
63 #include "ptp-pack.c"
64 
65 #ifdef __GNUC__
66 # define __unused__ __attribute__((unused))
67 #else
68 # define __unused__
69 #endif
70 
71 #define SET_CONTEXT(camera, ctx) ((PTPData *) camera->pl->params.data)->context = ctx
72 
73 int
have_prop(Camera * camera,uint16_t vendor,uint16_t prop)74 have_prop(Camera *camera, uint16_t vendor, uint16_t prop) {
75 	unsigned int i;
76 
77 	/* prop 0 matches */
78 	if (!prop && (camera->pl->params.deviceinfo.VendorExtensionID==vendor))
79 		return 1;
80 
81 	if (	((prop & 0x7000) == 0x5000) ||
82 		(NIKON_1(&camera->pl->params) && ((prop & 0xf000) == 0xf000))
83 	) { /* properties */
84 		for (i=0; i<camera->pl->params.deviceinfo.DevicePropertiesSupported_len; i++) {
85 			if (prop != camera->pl->params.deviceinfo.DevicePropertiesSupported[i])
86 				continue;
87 			if ((prop & 0xf000) == 0x5000) { /* generic property */
88 				if (!vendor || (camera->pl->params.deviceinfo.VendorExtensionID==vendor))
89 					return 1;
90 			}
91 			if (camera->pl->params.deviceinfo.VendorExtensionID==vendor)
92 				return 1;
93 		}
94 	}
95 	if ((prop & 0x7000) == 0x1000) { /* commands */
96 		for (i=0; i<camera->pl->params.deviceinfo.OperationsSupported_len; i++) {
97 
98 			if (prop != camera->pl->params.deviceinfo.OperationsSupported[i])
99 				continue;
100 			if ((prop & 0xf000) == 0x1000) /* generic property */
101 				return 1;
102 			if (camera->pl->params.deviceinfo.VendorExtensionID==vendor)
103 				return 1;
104 		}
105 	}
106 	return 0;
107 }
108 
109 static int
camera_prepare_chdk_capture(Camera * camera,GPContext * context)110 camera_prepare_chdk_capture(Camera *camera, GPContext *context) {
111 	PTPParams		*params = &camera->pl->params;
112 	int 			scriptid = 0, major = 0,minor = 0;
113 	unsigned int		status;
114 	int			luastatus;
115 	ptp_chdk_script_msg	*msg = NULL;
116 	char *lua		=
117 PTP_CHDK_LUA_SERIALIZE
118 "if not get_mode() then\n\
119         switch_mode_usb(1)\n\
120         local i=0\n\
121         while not get_mode() and i < 300 do\n\
122                 sleep(10)\n\
123                 i=i+1\n\
124         end\n\
125         if not get_mode() then\n\
126                 return false, 'switch failed'\n\
127         end\n\
128         return true\n\
129 end\n\
130 return false,'already in rec'\n\
131 ";
132 	C_PTP (ptp_chdk_get_version (params, &major, &minor));
133 	GP_LOG_D ("CHDK %d.%d", major, minor);
134 
135 	GP_LOG_D ("calling lua script %s", lua);
136 	C_PTP (ptp_chdk_exec_lua(params, lua, 0, &scriptid, &luastatus));
137 	GP_LOG_D ("called script. script id %d, status %d", scriptid, luastatus);
138 
139 	while (1) {
140 		C_PTP (ptp_chdk_get_script_status(params, &status));
141 		GP_LOG_D ("script status %x", status);
142 
143 		if (status & PTP_CHDK_SCRIPT_STATUS_MSG) {
144 			C_PTP (ptp_chdk_read_script_msg(params, &msg));
145 			GP_LOG_D ("message script id %d, type %d, subtype %d", msg->script_id, msg->type, msg->subtype);
146 			GP_LOG_D ("message script %s", msg->data);
147 			free (msg);
148 		}
149 
150 		if (!(status & PTP_CHDK_SCRIPT_STATUS_RUN))
151 			break;
152 		usleep(100000);
153 	}
154 	return GP_OK;
155 }
156 
157 static int
camera_unprepare_chdk_capture(Camera * camera,GPContext * context)158 camera_unprepare_chdk_capture(Camera *camera, GPContext *context) {
159 	PTPParams		*params = &camera->pl->params;
160 	int 			scriptid = 0, status = 0;
161 	ptp_chdk_script_msg	*msg = NULL;
162 	char *lua		=
163 PTP_CHDK_LUA_SERIALIZE
164 "if get_mode() then\n\
165         switch_mode_usb(0)\n\
166         local i=0\n\
167         while get_mode() and i < 300 do\n\
168                 sleep(10)\n\
169                 i=i+1\n\
170         end\n\
171         if get_mode() then\n\
172                 return false, 'switch failed'\n\
173         end\n\
174         return true\n\
175 end\n\
176 return false,'already in play'\n\
177 ";
178 	GP_LOG_D ("calling lua script %s", lua);
179 	C_PTP (ptp_chdk_exec_lua(params, lua, 0, &scriptid, &status));
180 	C_PTP (ptp_chdk_read_script_msg(params, &msg));
181 
182 	GP_LOG_D ("called script. script id %d, status %d", scriptid, status);
183 	GP_LOG_D ("message script id %d, type %d, subtype %d", msg->script_id, msg->type, msg->subtype);
184 	GP_LOG_D ("message script %s", msg->data);
185 	free (msg);
186 	if (!status) {
187 		gp_context_error(context,_("CHDK did not leave recording mode."));
188 		return GP_ERROR;
189 	}
190 	return GP_OK;
191 }
192 
193 static int
camera_prepare_canon_powershot_capture(Camera * camera,GPContext * context)194 camera_prepare_canon_powershot_capture(Camera *camera, GPContext *context) {
195 	uint16_t		ret;
196 	PTPContainer		event;
197 	PTPPropertyValue	propval;
198 	PTPParams		*params = &camera->pl->params;
199 	int 			found, oldtimeout;
200 
201         if (ptp_property_issupported(params, PTP_DPC_CANON_FlashMode)) {
202 		GP_LOG_D ("Canon capture mode is already set up.");
203 		C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_EventEmulateMode, &propval, PTP_DTC_UINT16));
204 		GP_LOG_D ("Event emulate mode 0x%04x", propval.u16);
205 		params->canon_event_mode = propval.u16;
206 		return GP_OK;
207 	}
208 
209 	propval.u16 = 0;
210 	C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_EventEmulateMode, &propval, PTP_DTC_UINT16));
211 	GP_LOG_D ("prop 0xd045 value is 0x%04x",propval.u16);
212 
213 	propval.u16=1;
214 	C_PTP (ptp_setdevicepropvalue(params, PTP_DPC_CANON_EventEmulateMode, &propval, PTP_DTC_UINT16));
215 	params->canon_event_mode = propval.u16;
216 	C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_SizeOfOutputDataFromCamera, &propval, PTP_DTC_UINT32));
217 	GP_LOG_D ("prop PTP_DPC_CANON_SizeOfOutputDataFromCamera value is %d",propval.u32);
218 	C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_SizeOfInputDataToCamera, &propval, PTP_DTC_UINT32));
219 	GP_LOG_D ("prop PTP_DPC_CANON_SizeOfInputDataToCamera value is %d",propval.u32);
220 
221 	C_PTP (ptp_getdeviceinfo (params, &params->deviceinfo));
222 	C_PTP (ptp_getdeviceinfo (params, &params->deviceinfo));
223 	CR (fixup_cached_deviceinfo (camera, &params->deviceinfo));
224 
225 	C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_SizeOfOutputDataFromCamera, &propval, PTP_DTC_UINT32));
226 	GP_LOG_D ("prop PTP_DPC_CANON_SizeOfOutputDataFromCamera value is %d",propval.u32);
227 	C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_SizeOfInputDataToCamera, &propval, PTP_DTC_UINT32));
228 	GP_LOG_D ("prop PTP_DPC_CANON_SizeOfInputDataToCamera value is %d",propval.u32);
229 	C_PTP (ptp_getdeviceinfo (params, &params->deviceinfo));
230 	CR (fixup_cached_deviceinfo (camera, &params->deviceinfo));
231 	C_PTP (ptp_getdevicepropvalue(params, PTP_DPC_CANON_EventEmulateMode, &propval, PTP_DTC_UINT16));
232 	params->canon_event_mode = propval.u16;
233 	GP_LOG_D ("prop 0xd045 value is 0x%04x",propval.u16);
234 
235 	GP_LOG_D ("Magic code ends.");
236 
237 	GP_LOG_D ("Setting prop. EventEmulateMode to 7.");
238 /* interrupt  9013 get event
239  1     Yes      No
240  2     Yes      No
241  3     Yes      Yes
242  4     Yes      Yes
243  5     Yes      Yes
244  6     No       No
245  7     No       Yes
246  */
247 	propval.u16 = 7;
248 	C_PTP (ptp_setdevicepropvalue(params, PTP_DPC_CANON_EventEmulateMode, &propval, PTP_DTC_UINT16));
249 	params->canon_event_mode = propval.u16;
250 
251 	ret = ptp_canon_startshootingmode (params);
252 	if (ret == PTP_RC_CANON_A009) {
253 		/* I think this means ... already in capture mode */
254 		return GP_OK;
255 	}
256 	if (ret != PTP_RC_OK) {
257 		GP_LOG_E ("'ptp_canon_startshootingmode (params)' failed: 0x%04x", ret);
258 		C_PTP_REP (ret);
259 	}
260 	gp_port_get_timeout (camera->port, &oldtimeout);
261 	gp_port_set_timeout (camera->port, 1000);
262 
263 	/* Catch the event telling us the mode was switched ... */
264 	/* If we were prepared already, it will be 5*50*1000 wait, so 1/4 second ... hmm */
265 	found = 0;
266 	while (found++<10) {
267 		ret = ptp_check_event (params);
268 		if (ret != PTP_RC_OK)
269 			break;
270 
271 		while (ptp_get_one_event (params, &event)) {
272 			GP_LOG_D ("Event: 0x%x", event.Code);
273 			if ((event.Code==0xc00c) ||
274 			    (event.Code==PTP_EC_StorageInfoChanged)) {
275 				GP_LOG_D ("Event: Entered shooting mode.");
276 				found = 1;
277 				break;
278 			}
279 		}
280 		usleep(50*1000);
281 	}
282 
283 #if 0
284 	gp_port_set_timeout (camera->port, oldtimeout);
285 	if (ptp_operation_issupported(params, PTP_OC_CANON_ViewfinderOn)) {
286 		ret = ptp_canon_viewfinderon (params);
287 		if (ret != PTP_RC_OK)
288 			GP_LOG_E ("Canon enable viewfinder failed: %d", ret);
289 		/* ignore errors here */
290 	}
291 	gp_port_set_timeout (camera->port, 1000);
292 #endif
293 
294 	/* Reget device info, they change on the Canons. */
295 	C_PTP (ptp_getdeviceinfo(&camera->pl->params, &camera->pl->params.deviceinfo));
296 	CR (fixup_cached_deviceinfo (camera, &camera->pl->params.deviceinfo));
297 	gp_port_set_timeout (camera->port, oldtimeout);
298 	return GP_OK;
299 }
300 
301 int
camera_canon_eos_update_capture_target(Camera * camera,GPContext * context,int value)302 camera_canon_eos_update_capture_target(Camera *camera, GPContext *context, int value) {
303 	PTPParams		*params = &camera->pl->params;
304 	char			buf[200];
305 	PTPPropertyValue	ct_val;
306 	PTPDevicePropDesc	dpd;
307 	int			cardval = -1;
308 
309 	memset(&dpd,0,sizeof(dpd));
310 	if (!have_eos_prop(params, PTP_VENDOR_CANON, PTP_DPC_CANON_EOS_CaptureDestination) ) {
311 		GP_LOG_D ("No CaptureDestination property?");
312 		return GP_OK;
313 	}
314 	C_PTP (ptp_canon_eos_getdevicepropdesc (params,PTP_DPC_CANON_EOS_CaptureDestination, &dpd));
315 
316 	/* Look for the correct value of the card mode */
317 	if (value != PTP_CANON_EOS_CAPTUREDEST_HD) {
318 		if (dpd.FormFlag == PTP_DPFF_Enumeration) {
319 			unsigned int	i;
320 			for (i=0;i<dpd.FORM.Enum.NumberOfValues;i++) {
321 				if (dpd.FORM.Enum.SupportedValue[i].u32 != PTP_CANON_EOS_CAPTUREDEST_HD) {
322 					cardval = dpd.FORM.Enum.SupportedValue[i].u32;
323 					break;
324 				}
325 			}
326 			GP_LOG_D ("Card value is %d",cardval);
327 		}
328 		if (cardval == -1) {
329 			GP_LOG_D ("NO Card found - falling back to SDRAM!");
330 			cardval = PTP_CANON_EOS_CAPTUREDEST_HD;
331 		}
332 	}
333 
334 	if (value == 1)
335 		value = cardval;
336 
337 	/* -1 == use setting from config-file, 1 == card, 4 == ram*/
338 	ct_val.u32 = (value == -1)
339 		     ? (GP_OK == gp_setting_get("ptp2","capturetarget",buf)) && strcmp(buf,"sdram") ? cardval : PTP_CANON_EOS_CAPTUREDEST_HD
340 		     : value;
341 
342 	/* otherwise we get DeviceBusy for some reason */
343 	if (ct_val.u32 != dpd.CurrentValue.u32) {
344 		C_PTP_MSG (ptp_canon_eos_setdevicepropvalue (params, PTP_DPC_CANON_EOS_CaptureDestination, &ct_val, PTP_DTC_UINT32),
345 			   "setdevicepropvalue of capturetarget to 0x%x failed", ct_val.u32);
346 		if (ct_val.u32 == PTP_CANON_EOS_CAPTUREDEST_HD) {
347 			uint16_t	ret;
348 
349 			/* if we want to download the image from the device, we need to tell the camera
350 			 * that we have enough space left. */
351 			/* this might be a trigger value for "no space" -Marcus
352 			ret = ptp_canon_eos_pchddcapacity(params, 0x7fffffff, 0x00001000, 0x00000001);
353 			 */
354 
355 			LOG_ON_PTP_E (ptp_canon_eos_setuilock (params));
356 			ret = ptp_canon_eos_pchddcapacity(params, 0x0fffffff, 0x00001000, 0x00000001);
357 			LOG_ON_PTP_E (ptp_canon_eos_resetuilock (params));
358 			/* not so bad if its just busy, would also fail later. */
359 			if (ret == PTP_RC_DeviceBusy) ret = PTP_RC_OK;
360 			C_PTP (ret);
361 			/* Tricky ... eos1200d seems to take a while to register this change and the first capture
362 			 * when it is still switching might be going down the drain. */
363 			while (1) {
364 				C_PTP (ptp_check_eos_events (params));
365 				C_PTP (ptp_canon_eos_getdevicepropdesc (params,PTP_DPC_CANON_EOS_AvailableShots, &dpd));
366 				if (dpd.CurrentValue.u32 > 0)
367 					break;
368 			}
369 		}
370 	} else {
371 		GP_LOG_D ("optimized ... setdevicepropvalue of capturetarget to 0x%x not done as it was set already.", ct_val.u32 );
372 	}
373 	ptp_free_devicepropdesc (&dpd);
374 	return GP_OK;
375 }
376 
377 static int
camera_prepare_canon_eos_capture(Camera * camera,GPContext * context)378 camera_prepare_canon_eos_capture(Camera *camera, GPContext *context) {
379 	PTPParams	*params = &camera->pl->params;
380 	PTPStorageIDs	sids;
381 	int		tries;
382 
383 	GP_LOG_D ("preparing EOS capture...");
384 
385 	if (is_canon_eos_m(params)) {
386 		int mode = 0x15;	/* default for EOS M and newer Powershot SX */
387 
388 		if (!strcmp(params->deviceinfo.Model,"Canon PowerShot SX540 HS")) mode = 0x11;	/* testing for https://github.com/gphoto/libgphoto2/issues/360 */
389 		if (!strcmp(params->deviceinfo.Model,"Canon PowerShot SX600 HS")) goto skip;
390 
391 		if (!strcmp(params->deviceinfo.Model,"Canon PowerShot G5 X")) mode = 0x11;
392 		if (!strcmp(params->deviceinfo.Model,"Canon EOS M6 Mark II")) mode = 0x1;
393 		C_PTP (ptp_canon_eos_setremotemode(params, mode));
394 	} else {
395 		C_PTP (ptp_canon_eos_setremotemode(params, 1));
396 	}
397 skip:
398 	C_PTP (ptp_canon_eos_seteventmode(params, 1));
399 	params->eos_camerastatus = -1;	/* aka unknown */
400 
401 	if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_SetRequestOLCInfoGroup))
402 		C_PTP (ptp_canon_eos_setrequestolcinfogroup(params, 0x00001fff));
403 
404 	/* Get the initial bulk set of event data */
405 	C_PTP (ptp_check_eos_events (params));
406 
407 	if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_RequestDevicePropValue)) {
408 		/* request additional properties */
409 		/* if one of this is not present GeneralError will be returned, so only check
410 		 * and log, but do not error return */
411 		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_Owner));
412 		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_Artist));
413 		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_Copyright));
414 		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_SerialNumber));
415 
416 /*		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_DPOFVersion)); */
417 /*		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_MyMenuList)); */
418 /*		LOG_ON_PTP_E (ptp_canon_eos_requestdevicepropvalue (params, PTP_DPC_CANON_EOS_LensAdjustParams)); */
419 	}
420 	if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_GetDeviceInfoEx)) {
421 		PTPCanonEOSDeviceInfo x;
422 		unsigned int i;
423 
424 		C_PTP (ptp_canon_eos_getdeviceinfo (params, &x));
425 		for (i=0;i<x.EventsSupported_len;i++)
426 			GP_LOG_D ("event: %04x", x.EventsSupported[i]);
427 		for (i=0;i<x.DevicePropertiesSupported_len;i++)
428 			GP_LOG_D ("deviceprop: %04x", x.DevicePropertiesSupported[i]);
429 		for (i=0;i<x.unk_len;i++)
430 			GP_LOG_D ("unk: %04x", x.unk[i]);
431 		ptp_free_EOS_DI (&x);
432 	}
433 
434 	/* The new EOS occasionally returned an empty event set ... likely because we are too fast. try again some times. */
435 	C_PTP (ptp_check_eos_events (params));
436 	tries = 10;
437 	while (--tries && !have_eos_prop(params,PTP_VENDOR_CANON,PTP_DPC_CANON_EOS_EVFOutputDevice)) {
438 		GP_LOG_D("evfoutput device not found, retrying");
439 		usleep(50*1000);
440 		C_PTP (ptp_check_eos_events (params));
441 	}
442 
443 	CR (camera_canon_eos_update_capture_target( camera, context, -1 ));
444 
445 	ptp_free_DI (&params->deviceinfo);
446 	C_PTP (ptp_getdeviceinfo(params, &params->deviceinfo));
447 	CR (fixup_cached_deviceinfo (camera, &params->deviceinfo));
448 	C_PTP (ptp_canon_eos_getstorageids(params, &sids));
449 	if (sids.n >= 1) {
450 		unsigned char *sdata;
451 		unsigned int slen;
452 		C_PTP (ptp_canon_eos_getstorageinfo(params, sids.Storage[0], &sdata, &slen ));
453 		free (sdata);
454 	}
455 	free (sids.Storage);
456 
457 	/* FIXME: 9114 call missing here! */
458 
459 	/* Get the second bulk set of 0x9116 property data */
460 	C_PTP (ptp_check_eos_events (params));
461 	params->eos_captureenabled = 1;
462 
463 	/* run this only on EOS M, not on PowerShot SX */
464 	/* I lost track where it is needed.
465 	 * Need it:
466 	 * + EOS M10
467 	 * + PowerShot SX 720HS
468 	 * + PowerShot G9x mark II
469 	 */
470 	if (is_canon_eos_m (params)) {
471 		/* This code is needed on EOS m3 at least. might not be needed on others ... mess :/ */
472 		PTPPropertyValue    ct_val;
473 
474 		GP_LOG_D ("EOS M detected");
475 
476 		C_PTP (ptp_canon_eos_seteventmode(params, 2));
477 		ct_val.u16 = 0x0008;
478 		C_PTP (ptp_canon_eos_setdevicepropvalue (params, PTP_DPC_CANON_EOS_EVFOutputDevice, &ct_val, PTP_DTC_UINT16));
479 
480 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
481 		usleep(1000*1000); /* 1 second */
482 #endif
483 
484 		C_PTP (ptp_check_eos_events (params));
485 	}
486 	return GP_OK;
487 }
488 
489 int
camera_prepare_capture(Camera * camera,GPContext * context)490 camera_prepare_capture (Camera *camera, GPContext *context)
491 {
492 	PTPParams		*params = &camera->pl->params;
493 
494 	GP_LOG_D ("prepare_capture");
495 	switch (params->deviceinfo.VendorExtensionID) {
496 	case PTP_VENDOR_FUJI:
497 		{
498 			PTPPropertyValue propval;
499 
500 			/* without the firmware update ... not an error... */
501 			if (!have_prop (camera, PTP_VENDOR_FUJI, 0xd207))
502 				return GP_OK;
503 
504 			/* timelapse does:
505 			 * d38c -> 1	(PC Mode)
506 			 * d207 -> 2	(USB control)
507 			 */
508 
509 			propval.u16 = 0x0001;
510 			LOG_ON_PTP_E (ptp_setdevicepropvalue (params, 0xd38c, &propval, PTP_DTC_UINT16));
511 			propval.u16 = 0x0002;
512 			LOG_ON_PTP_E (ptp_setdevicepropvalue (params, 0xd207, &propval, PTP_DTC_UINT16));
513 			return GP_OK;
514 		}
515 		break;
516 	case PTP_VENDOR_CANON:
517 		if (ptp_operation_issupported(params, PTP_OC_CANON_InitiateReleaseControl))
518 			return camera_prepare_canon_powershot_capture(camera,context);
519 
520 		if (ptp_operation_issupported(params, PTP_OC_CHDK))
521 			return camera_prepare_chdk_capture(camera,context);
522 
523 		if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteRelease) ||
524 		    ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn)
525 		)
526 			return camera_prepare_canon_eos_capture(camera,context);
527 		gp_context_error(context, _("Sorry, your Canon camera does not support Canon capture"));
528 		return GP_ERROR_NOT_SUPPORTED;
529 	case PTP_VENDOR_PANASONIC: {
530 		char buf[1024];
531 		if ((GP_OK != gp_setting_get("ptp2","capturetarget",buf)) || !strcmp(buf,"sdram"))
532 			C_PTP (ptp_panasonic_setcapturetarget(params, 1));
533 		else
534 			C_PTP (ptp_panasonic_setcapturetarget(params, 0));
535 		break;
536 	}
537 	default:
538 		/* generic capture does not need preparation */
539 		return GP_OK;
540 	}
541 	return GP_OK;
542 }
543 
544 static int
camera_unprepare_canon_powershot_capture(Camera * camera,GPContext * context)545 camera_unprepare_canon_powershot_capture(Camera *camera, GPContext *context) {
546 	PTPParams		*params = &camera->pl->params;
547 
548 	C_PTP (ptp_canon_endshootingmode (params));
549 
550 	if (ptp_operation_issupported(params, PTP_OC_CANON_ViewfinderOff)) {
551 		if (params->canon_viewfinder_on) {
552 			params->canon_viewfinder_on = 0;
553 			LOG_ON_PTP_E (ptp_canon_viewfinderoff (params));
554 			/* ignore errors here */
555 		}
556 	}
557 	/* Reget device info, they change on the Canons. */
558 	C_PTP (ptp_getdeviceinfo(params, &params->deviceinfo));
559 	CR (fixup_cached_deviceinfo (camera, &params->deviceinfo));
560 	return GP_OK;
561 }
562 
563 static int
camera_unprepare_canon_eos_capture(Camera * camera,GPContext * context)564 camera_unprepare_canon_eos_capture(Camera *camera, GPContext *context) {
565 	PTPParams		*params = &camera->pl->params;
566 
567 	/* just in case we had autofocus running */
568 	if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_AfCancel))
569 		CR (ptp_canon_eos_afcancel(params));
570 
571 	if (is_canon_eos_m (params)) {
572 		PTPPropertyValue    ct_val;
573 
574 		ct_val.u16 = 0x0000;
575 		C_PTP (ptp_canon_eos_setdevicepropvalue (params, PTP_DPC_CANON_EOS_EVFOutputDevice, &ct_val, PTP_DTC_UINT16));
576 	}
577 
578 	/* then emits 911b and 911c ... not done yet ... */
579 	CR (camera_canon_eos_update_capture_target(camera, context, 1));
580 
581 	if (ptp_operation_issupported(&camera->pl->params, PTP_OC_CANON_EOS_ResetUILock))
582 		LOG_ON_PTP_E (ptp_canon_eos_resetuilock (params));
583 
584 	/* Drain the rest set of the event data */
585 	C_PTP (ptp_check_eos_events (params));
586 	C_PTP (ptp_canon_eos_setremotemode(params, 0));
587 	C_PTP (ptp_canon_eos_seteventmode(params, 0));
588 	params->eos_captureenabled = 0;
589 	return GP_OK;
590 }
591 
592 int
camera_unprepare_capture(Camera * camera,GPContext * context)593 camera_unprepare_capture (Camera *camera, GPContext *context)
594 {
595 	GP_LOG_D ("Unprepare_capture");
596 	switch (camera->pl->params.deviceinfo.VendorExtensionID) {
597 	case PTP_VENDOR_CANON:
598 		if (ptp_operation_issupported(&camera->pl->params, PTP_OC_CANON_TerminateReleaseControl))
599 			return camera_unprepare_canon_powershot_capture (camera, context);
600 
601 		if (ptp_operation_issupported(&camera->pl->params, PTP_OC_CHDK))
602 			return camera_unprepare_chdk_capture(camera,context);
603 
604 		if (ptp_operation_issupported(&camera->pl->params, PTP_OC_CANON_EOS_RemoteRelease) ||
605 		    ptp_operation_issupported(&camera->pl->params, PTP_OC_CANON_EOS_RemoteReleaseOn)
606 		)
607 			return camera_unprepare_canon_eos_capture (camera, context);
608 
609 		gp_context_error(context,
610 		_("Sorry, your Canon camera does not support Canon capture"));
611 		return GP_ERROR_NOT_SUPPORTED;
612 	case PTP_VENDOR_FUJI:
613 		{
614 			PTPPropertyValue propval;
615 			PTPParams *params = &camera->pl->params;
616 
617 			if (params->inliveview) {
618 				C_PTP_REP (ptp_terminateopencapture (params, params->opencapture_transid));
619 				params->inliveview = 0;
620 			}
621 
622 			propval.u16 = 0x0001;
623 			C_PTP (ptp_setdevicepropvalue (params, 0xd207, &propval, PTP_DTC_UINT16));
624 			return GP_OK;
625 		}
626 		break;
627 	default:
628 		/* generic capture does not need unpreparation */
629 		return GP_OK;
630 	}
631 	return GP_OK;
632 }
633 
634 static uint16_t
nikon_wait_busy(PTPParams * params,int waitms,int timeout)635 nikon_wait_busy(PTPParams *params, int waitms, int timeout) {
636 	uint16_t	res;
637 	int		tries;
638 
639 	/* wait either 1 second, or 50 tries */
640 	if (waitms)
641 		tries=timeout/waitms;
642 	else
643 		tries=50;
644 	do {
645 		res = ptp_nikon_device_ready(params);
646 		if (res != PTP_RC_DeviceBusy)
647 			return res;
648 		if (waitms) usleep(waitms*1000)/*wait a bit*/;
649 	} while (tries--);
650 	return res;
651 }
652 
653 struct submenu;
654 #define CONFIG_GET_ARGS Camera *camera, CameraWidget **widget, struct submenu* menu, PTPDevicePropDesc *dpd
655 #define CONFIG_GET_NAMES camera, widget, menu, dpd
656 typedef int (*get_func)(CONFIG_GET_ARGS);
657 #define CONFIG_PUT_ARGS Camera *camera, CameraWidget *widget, PTPPropertyValue *propval, PTPDevicePropDesc *dpd
658 #define CONFIG_PUT_NAMES camera, widget, propval, dpd
659 typedef int (*put_func)(CONFIG_PUT_ARGS);
660 
661 struct menu;
662 #define CONFIG_MENU_GET_ARGS Camera *camera, CameraWidget **widget, struct menu* menu
663 typedef int (*get_menu_func)(CONFIG_MENU_GET_ARGS);
664 #define CONFIG_MENU_PUT_ARGS Camera *camera, CameraWidget *widget
665 typedef int (*put_menu_func)(CONFIG_MENU_PUT_ARGS);
666 
667 struct submenu {
668 	char 		*label;
669 	char		*name;
670 	uint16_t	propid;
671 	uint16_t	vendorid;
672 	uint32_t	type;	/* for 32bit alignment */
673 	get_func	getfunc;
674 	put_func	putfunc;
675 };
676 
677 struct menu {
678 	char		*label;
679 	char		*name;
680 
681 	uint16_t	usb_vendorid;
682 	uint16_t	usb_productid;
683 
684 	/* Either: Standard menu */
685 	struct	submenu	*submenus;
686 	/* Or: Non-standard menu with custom behaviour */
687 	get_menu_func	getfunc;
688 	put_menu_func	putfunc;
689 };
690 
691 /* Generic helper function for:
692  *
693  * ENUM xINTxx propertiess, with potential vendor specific variables. \
694  */
695 #define GENERIC_TABLE(bits,type,dpc) \
696 struct deviceproptable##bits {		\
697 	char		*label;		\
698 	type		value;		\
699 	uint16_t	vendor_id;	\
700 };\
701 \
702 static int \
703 _get_Generic##bits##Table(CONFIG_GET_ARGS, struct deviceproptable##bits * tbl, int tblsize) { \
704 	int i, j; \
705 	int isset = FALSE, isset2 = FALSE; \
706  \
707 	if (!(dpd->FormFlag & (PTP_DPFF_Enumeration|PTP_DPFF_Range))) { \
708 		GP_LOG_D ("no enumeration/range in %sbit table code... going on", #bits); \
709 	} \
710 	if (dpd->DataType != dpc) { \
711 		GP_LOG_D ("no %s prop in %sbit table code", #bits, #bits); \
712 		return GP_ERROR; \
713 	} \
714  \
715 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget); \
716 	gp_widget_set_name (*widget, menu->name); \
717 	if (dpd->FormFlag & PTP_DPFF_Enumeration) { \
718 		if (!dpd->FORM.Enum.NumberOfValues) { \
719 			/* fill in with all values we have in the table. */ \
720 			for (j=0;j<tblsize;j++) { \
721 				if ((tbl[j].vendor_id == 0) || \
722 				    (tbl[j].vendor_id == camera->pl->params.deviceinfo.VendorExtensionID) \
723 				) { \
724 					gp_widget_add_choice (*widget, _(tbl[j].label)); \
725 					if (tbl[j].value == dpd->CurrentValue.bits) { \
726 						gp_widget_set_value (*widget, _(tbl[j].label)); \
727 						isset2 = TRUE; \
728 					} \
729 				} \
730 			} \
731 			/* fallthrough in case we do not have currentvalue in the table. isset2 = FALSE */ \
732 		} \
733 		for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) { \
734 			isset = FALSE; \
735 			for (j=0;j<tblsize;j++) { \
736 				if ((tbl[j].value == dpd->FORM.Enum.SupportedValue[i].bits) && \
737 				    ((tbl[j].vendor_id == 0) || \
738 				     (tbl[j].vendor_id == camera->pl->params.deviceinfo.VendorExtensionID)) \
739 				) { \
740 					gp_widget_add_choice (*widget, _(tbl[j].label)); \
741 					if (tbl[j].value == dpd->CurrentValue.bits) { \
742 						isset2 = TRUE; \
743 						gp_widget_set_value (*widget, _(tbl[j].label)); \
744 					} \
745 					isset = TRUE; \
746 					break; \
747 				} \
748 			} \
749 			if (!isset) { \
750 				char buf[200]; \
751 				sprintf(buf, _("Unknown value %04x"), dpd->FORM.Enum.SupportedValue[i].bits); \
752 				gp_widget_add_choice (*widget, buf); \
753 				if (dpd->FORM.Enum.SupportedValue[i].bits == dpd->CurrentValue.bits) { \
754 					isset2 = TRUE; \
755 					gp_widget_set_value (*widget, buf); \
756 				} \
757 			} \
758 		} \
759 	} \
760 	if (dpd->FormFlag & PTP_DPFF_Range) { \
761 		type r;	\
762 		for (	r = dpd->FORM.Range.MinimumValue.bits; \
763 			r<=dpd->FORM.Range.MaximumValue.bits; \
764 			r+= dpd->FORM.Range.StepSize.bits \
765 		) { \
766 			isset = FALSE; \
767 			for (j=0;j<tblsize;j++) { \
768 				if ((tbl[j].value == r) && \
769 				    ((tbl[j].vendor_id == 0) || \
770 				     (tbl[j].vendor_id == camera->pl->params.deviceinfo.VendorExtensionID)) \
771 				) { \
772 					gp_widget_add_choice (*widget, _(tbl[j].label)); \
773 					if (r == dpd->CurrentValue.bits) { \
774 						isset2 = TRUE; \
775 						gp_widget_set_value (*widget, _(tbl[j].label)); \
776 					} \
777 					isset = TRUE; \
778 					break; \
779 				} \
780 			} \
781 			if (!isset) { \
782 				char buf[200]; \
783 				sprintf(buf, _("Unknown value %04x"), r); \
784 				gp_widget_add_choice (*widget, buf); \
785 				if (r == dpd->CurrentValue.bits) { \
786 					isset2 = TRUE; \
787 					gp_widget_set_value (*widget, buf); \
788 				} \
789 			} \
790  \
791 			/* device might report stepsize 0. but we do at least 1 round */ \
792 			if (dpd->FORM.Range.StepSize.bits == 0) \
793 				break; \
794 		} \
795 	} \
796 	if (!isset2) { \
797 		for (j=0;j<tblsize;j++) { \
798 			if (((tbl[j].vendor_id == 0) || \
799 			     (tbl[j].vendor_id == camera->pl->params.deviceinfo.VendorExtensionID)) && \
800 			     (tbl[j].value == dpd->CurrentValue.bits) \
801 			) { \
802 				gp_widget_add_choice (*widget, _(tbl[j].label)); \
803 				isset2 = TRUE; \
804 				gp_widget_set_value (*widget, _(tbl[j].label)); \
805 			} \
806 		} \
807 		if (!isset2) { \
808 			char buf[200]; \
809 			sprintf(buf, _("Unknown value %04x"), dpd->CurrentValue.bits); \
810 			gp_widget_add_choice (*widget, buf); \
811 			gp_widget_set_value (*widget, buf); \
812 		} \
813 	} \
814 	return (GP_OK); \
815 } \
816 \
817 \
818 static int \
819 _put_Generic##bits##Table(CONFIG_PUT_ARGS, struct deviceproptable##bits * tbl, int tblsize) { \
820 	char *value; \
821 	int i, intval, j; \
822 	int foundvalue = 0; \
823 	type bits##val = 0; \
824  \
825 	CR (gp_widget_get_value (widget, &value)); \
826 	for (i=0;i<tblsize;i++) { \
827 		if ((!strcmp(_(tbl[i].label),value) || !strcmp(tbl[i].label,value)) && \
828 		    ((tbl[i].vendor_id == 0) || (tbl[i].vendor_id == camera->pl->params.deviceinfo.VendorExtensionID)) \
829 		) { \
830 			bits##val = tbl[i].value; \
831 			foundvalue = 1; \
832 		 \
833 			if (dpd->FormFlag & PTP_DPFF_Enumeration) { \
834 				for (j = 0; j<dpd->FORM.Enum.NumberOfValues; j++) { \
835 					if (bits##val == dpd->FORM.Enum.SupportedValue[j].bits) { \
836 						GP_LOG_D ("FOUND right value for %s in the enumeration at val %d", value, bits##val); \
837 						propval->bits = bits##val; \
838 						return GP_OK; \
839 					} \
840 				} \
841 				GP_LOG_D ("did not find the right value for %s in the enumeration at val %d... continuing", value, bits##val); \
842 				/* continue looking, but with this value as fallback */ \
843 			} else { \
844 				GP_LOG_D ("not an enumeration ... return %s as %d", value, bits##val); \
845 				propval->bits = bits##val; \
846 				return GP_OK; \
847 			} \
848 		} \
849 	} \
850 	if (foundvalue) { \
851 		GP_LOG_D ("Using fallback, not found in enum... return %s as %d", value, bits##val); \
852 		propval->bits = bits##val; \
853 		return GP_OK; \
854 	} \
855 	if (!sscanf(value, _("Unknown value %04x"), &intval)) { \
856 		GP_LOG_E ("failed to find value %s in list", value); \
857 		return GP_ERROR; \
858 	} \
859 	GP_LOG_D ("Using fallback, not found in enum... return %s as %d", value, bits##val); \
860 	propval->bits = intval; \
861 	return GP_OK; \
862 }
863 
GENERIC_TABLE(u32,uint32_t,PTP_DTC_UINT32)864 GENERIC_TABLE(u32,uint32_t,PTP_DTC_UINT32)
865 GENERIC_TABLE(u16,uint16_t,PTP_DTC_UINT16)
866 GENERIC_TABLE(i16,int16_t, PTP_DTC_INT16)
867 GENERIC_TABLE(u8, uint8_t, PTP_DTC_UINT8)
868 GENERIC_TABLE(i8, int8_t,  PTP_DTC_INT8)
869 
870 #define GENERIC16TABLE(name,tbl) 			\
871 static int						\
872 _get_##name(CONFIG_GET_ARGS) {				\
873 	return _get_Genericu16Table(CONFIG_GET_NAMES,	\
874 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
875 	);						\
876 }							\
877 							\
878 static int __unused__					\
879 _put_##name(CONFIG_PUT_ARGS) {				\
880 	return _put_Genericu16Table(CONFIG_PUT_NAMES,	\
881 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
882 	);						\
883 }
884 
885 #define GENERIC32TABLE(name,tbl) 			\
886 static int						\
887 _get_##name(CONFIG_GET_ARGS) {				\
888 	return _get_Genericu32Table(CONFIG_GET_NAMES,	\
889 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
890 	);						\
891 }							\
892 							\
893 static int __unused__					\
894 _put_##name(CONFIG_PUT_ARGS) {				\
895 	return _put_Genericu32Table(CONFIG_PUT_NAMES,	\
896 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
897 	);						\
898 }
899 
900 #define GENERICI16TABLE(name,tbl) 			\
901 static int						\
902 _get_##name(CONFIG_GET_ARGS) {				\
903 	return _get_Generici16Table(CONFIG_GET_NAMES,	\
904 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
905 	);						\
906 }							\
907 							\
908 static int __unused__					\
909 _put_##name(CONFIG_PUT_ARGS) {				\
910 	return _put_Generici16Table(CONFIG_PUT_NAMES,	\
911 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
912 	);						\
913 }
914 
915 #define GENERIC8TABLE(name,tbl) 			\
916 static int						\
917 _get_##name(CONFIG_GET_ARGS) {				\
918 	return _get_Genericu8Table(CONFIG_GET_NAMES,	\
919 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
920 	);						\
921 }							\
922 							\
923 static int __unused__					\
924 _put_##name(CONFIG_PUT_ARGS) {				\
925 	return _put_Genericu8Table(CONFIG_PUT_NAMES,	\
926 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
927 	);						\
928 }
929 
930 #define GENERICI8TABLE(name,tbl) 			\
931 static int						\
932 _get_##name(CONFIG_GET_ARGS) {				\
933 	return _get_Generici8Table(CONFIG_GET_NAMES,	\
934 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
935 	);						\
936 }							\
937 							\
938 static int __unused__					\
939 _put_##name(CONFIG_PUT_ARGS) {				\
940 	return _put_Generici8Table(CONFIG_PUT_NAMES,	\
941 		tbl,sizeof(tbl)/sizeof(tbl[0])		\
942 	);						\
943 }
944 
945 static int
946 _get_AUINT8_as_CHAR_ARRAY(CONFIG_GET_ARGS) {
947 	unsigned int	j;
948 	char 		value[128];
949 
950 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
951 	gp_widget_set_name (*widget, menu->name);
952 	if (dpd->DataType != PTP_DTC_AUINT8) {
953 		sprintf (value,_("unexpected datatype %i"),dpd->DataType);
954 	} else {
955 		memset(value,0,sizeof(value));
956 		for (j=0;j<dpd->CurrentValue.a.count;j++)
957 			value[j] = dpd->CurrentValue.a.v[j].u8;
958 	}
959 	gp_widget_set_value (*widget,value);
960 	return (GP_OK);
961 }
962 
963 static int
_get_STR(CONFIG_GET_ARGS)964 _get_STR(CONFIG_GET_ARGS) {
965 	char value[64];
966 
967 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
968 	gp_widget_set_name (*widget, menu->name);
969 	if (dpd->DataType != PTP_DTC_STR) {
970 		sprintf (value,_("unexpected datatype %i"),dpd->DataType);
971 		gp_widget_set_value (*widget,value);
972 	} else {
973 		gp_widget_set_value (*widget,dpd->CurrentValue.str);
974 	}
975 	return (GP_OK);
976 }
977 
978 static int
_get_STR_ENUMList(CONFIG_GET_ARGS)979 _get_STR_ENUMList (CONFIG_GET_ARGS) {
980 	int j;
981 
982 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
983 		return GP_ERROR;
984 	if (dpd->DataType != PTP_DTC_STR)
985 		return GP_ERROR;
986 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
987 	gp_widget_set_name (*widget, menu->name);
988 	for (j=0;j<dpd->FORM.Enum.NumberOfValues; j++)
989 		gp_widget_add_choice (*widget,dpd->FORM.Enum.SupportedValue[j].str);
990 	gp_widget_set_value (*widget,dpd->CurrentValue.str);
991 	return GP_OK;
992 }
993 
994 static int
_put_STR(CONFIG_PUT_ARGS)995 _put_STR(CONFIG_PUT_ARGS) {
996 	const char *string;
997 
998 	CR (gp_widget_get_value(widget, &string));
999 	C_MEM (propval->str = strdup (string));
1000 	return (GP_OK);
1001 }
1002 
1003 static int
_put_AUINT8_as_CHAR_ARRAY(CONFIG_PUT_ARGS)1004 _put_AUINT8_as_CHAR_ARRAY(CONFIG_PUT_ARGS) {
1005 	char	*value;
1006 	unsigned int i;
1007 
1008 	CR (gp_widget_get_value(widget, &value));
1009 	memset(propval,0,sizeof(PTPPropertyValue));
1010 	/* add \0 ? */
1011 	C_MEM (propval->a.v = malloc((strlen(value)+1)*sizeof(PTPPropertyValue)));
1012 	propval->a.count = strlen(value)+1;
1013 	for (i=0;i<strlen(value)+1;i++)
1014 		propval->a.v[i].u8 = value[i];
1015 	return (GP_OK);
1016 }
1017 
1018 static int
_get_Range_INT8(CONFIG_GET_ARGS)1019 _get_Range_INT8(CONFIG_GET_ARGS) {
1020 	float CurrentValue;
1021 
1022 	if (dpd->FormFlag != PTP_DPFF_Range)
1023 		return (GP_ERROR_NOT_SUPPORTED);
1024 	if (dpd->DataType != PTP_DTC_INT8)
1025 		return (GP_ERROR_NOT_SUPPORTED);
1026 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1027 	gp_widget_set_name ( *widget, menu->name);
1028 	CurrentValue = (float) dpd->CurrentValue.i8;
1029 	gp_widget_set_range ( *widget, (float) dpd->FORM.Range.MinimumValue.i8, (float) dpd->FORM.Range.MaximumValue.i8, (float) dpd->FORM.Range.StepSize.i8);
1030 	gp_widget_set_value ( *widget, &CurrentValue);
1031 	return (GP_OK);
1032 }
1033 
1034 
1035 static int
_put_Range_INT8(CONFIG_PUT_ARGS)1036 _put_Range_INT8(CONFIG_PUT_ARGS) {
1037 	float f;
1038 
1039 	CR (gp_widget_get_value(widget, &f));
1040 	propval->i8 = (int) f;
1041 	return (GP_OK);
1042 }
1043 
1044 static int
_get_Range_UINT8(CONFIG_GET_ARGS)1045 _get_Range_UINT8(CONFIG_GET_ARGS) {
1046 	float CurrentValue;
1047 
1048 	if (dpd->FormFlag != PTP_DPFF_Range)
1049 		return (GP_ERROR_NOT_SUPPORTED);
1050 	if (dpd->DataType != PTP_DTC_UINT8)
1051 		return (GP_ERROR_NOT_SUPPORTED);
1052 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1053 	gp_widget_set_name ( *widget, menu->name);
1054 	CurrentValue = (float) dpd->CurrentValue.u8;
1055 	gp_widget_set_range ( *widget, (float) dpd->FORM.Range.MinimumValue.u8, (float) dpd->FORM.Range.MaximumValue.u8, (float) dpd->FORM.Range.StepSize.u8);
1056 	gp_widget_set_value ( *widget, &CurrentValue);
1057 	return (GP_OK);
1058 }
1059 
1060 
1061 static int
_put_Range_UINT8(CONFIG_PUT_ARGS)1062 _put_Range_UINT8(CONFIG_PUT_ARGS) {
1063 	float f;
1064 
1065 	CR (gp_widget_get_value(widget, &f));
1066 	propval->u8 = (int) f;
1067 	return (GP_OK);
1068 }
1069 
1070 static int
_get_Fuji_Totalcount(CONFIG_GET_ARGS)1071 _get_Fuji_Totalcount(CONFIG_GET_ARGS) {
1072 	char buf[20];
1073 
1074 	sprintf(buf,"%d",dpd->CurrentValue.u32 >> 16);
1075 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
1076 	gp_widget_set_name (*widget, menu->name);
1077 	gp_widget_set_value (*widget, buf);
1078 	return	GP_OK;
1079 }
1080 
1081 /* generic int getter */
1082 static int
_get_INT(CONFIG_GET_ARGS)1083 _get_INT(CONFIG_GET_ARGS) {
1084 	char value[64];
1085 	float	rvalue = 0;
1086 
1087 	switch (dpd->DataType) {
1088 	case PTP_DTC_UINT32:
1089 		sprintf (value, "%u", dpd->CurrentValue.u32 ); rvalue = dpd->CurrentValue.u32;
1090 		break;
1091 	case PTP_DTC_INT32:
1092 		sprintf (value, "%d", dpd->CurrentValue.i32 ); rvalue = dpd->CurrentValue.i32;
1093 		break;
1094 	case PTP_DTC_UINT16:
1095 		sprintf (value, "%u", dpd->CurrentValue.u16 ); rvalue = dpd->CurrentValue.u16;
1096 		break;
1097 	case PTP_DTC_INT16:
1098 		sprintf (value, "%d", dpd->CurrentValue.i16 ); rvalue = dpd->CurrentValue.i16;
1099 		break;
1100 	case PTP_DTC_UINT8:
1101 		sprintf (value, "%u", dpd->CurrentValue.u8 ); rvalue = dpd->CurrentValue.u8;
1102 		break;
1103 	case PTP_DTC_INT8:
1104 		sprintf (value, "%d", dpd->CurrentValue.i8 ); rvalue = dpd->CurrentValue.i8;
1105 		break;
1106 	default:
1107 		sprintf (value,_("unexpected datatype %i"),dpd->DataType);
1108 		return GP_ERROR;
1109 	}
1110 	if (dpd->FormFlag == PTP_DPFF_Enumeration) {
1111 		gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1112 		gp_widget_set_name (*widget, menu->name);
1113 		gp_widget_set_value (*widget, value); /* text */
1114 	} else {
1115 		if (dpd->FormFlag == PTP_DPFF_Range) {
1116 			gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1117 			gp_widget_set_name (*widget, menu->name);
1118 			gp_widget_set_value (*widget, &rvalue); /* float */
1119 		} else {
1120 			gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
1121 			gp_widget_set_name (*widget, menu->name);
1122 			gp_widget_set_value (*widget, value); /* text */
1123 		}
1124 	}
1125 
1126 	if (dpd->FormFlag == PTP_DPFF_Enumeration) {
1127 		int i;
1128 
1129 		for (i=0;i<dpd->FORM.Enum.NumberOfValues;i++) {
1130 			switch (dpd->DataType) {
1131 			case PTP_DTC_UINT32:	sprintf (value, "%u", dpd->FORM.Enum.SupportedValue[i].u32 ); break;
1132 			case PTP_DTC_INT32:	sprintf (value, "%d", dpd->FORM.Enum.SupportedValue[i].i32 ); break;
1133 			case PTP_DTC_UINT16:	sprintf (value, "%u", dpd->FORM.Enum.SupportedValue[i].u16 ); break;
1134 			case PTP_DTC_INT16:	sprintf (value, "%d", dpd->FORM.Enum.SupportedValue[i].i16 ); break;
1135 			case PTP_DTC_UINT8:	sprintf (value, "%u", dpd->FORM.Enum.SupportedValue[i].u8  ); break;
1136 			case PTP_DTC_INT8:	sprintf (value, "%d", dpd->FORM.Enum.SupportedValue[i].i8  ); break;
1137 			default: sprintf (value,_("unexpected datatype %i"),dpd->DataType); return GP_ERROR;
1138 			}
1139 			gp_widget_add_choice (*widget,value);
1140 		}
1141 	}
1142 	if (dpd->FormFlag == PTP_DPFF_Range) {
1143 		float b = 0, t = 0, s = 0;
1144 
1145 #define X(type,u) case type: b = (float)dpd->FORM.Range.MinimumValue.u; t = (float)dpd->FORM.Range.MaximumValue.u; s = (float)dpd->FORM.Range.StepSize.u; break;
1146 		switch (dpd->DataType) {
1147 		X(PTP_DTC_UINT32,u32)
1148 		X(PTP_DTC_INT32,i32)
1149 		X(PTP_DTC_UINT16,u16)
1150 		X(PTP_DTC_INT16,i16)
1151 		X(PTP_DTC_UINT8,u8)
1152 		X(PTP_DTC_INT8,i8)
1153 		}
1154 #undef X
1155 		gp_widget_set_range (*widget, b, t, s);
1156 	}
1157 	return GP_OK;
1158 }
1159 
1160 static int
_put_INT(CONFIG_PUT_ARGS)1161 _put_INT(CONFIG_PUT_ARGS) {
1162 	if (dpd->FormFlag == PTP_DPFF_Range) {
1163 		float f;
1164 
1165 		CR (gp_widget_get_value(widget, &f));
1166 		switch (dpd->DataType) {
1167 		case PTP_DTC_UINT32:	propval->u32 = f; break;
1168 		case PTP_DTC_INT32:	propval->i32 = f; break;
1169 		case PTP_DTC_UINT16:	propval->u16 = f; break;
1170 		case PTP_DTC_INT16:	propval->i16 = f; break;
1171 		case PTP_DTC_UINT8:	propval->u8 = f; break;
1172 		case PTP_DTC_INT8:	propval->i8 = f; break;
1173 		}
1174 		return GP_OK;
1175 	} else {
1176 		char *value;
1177 		unsigned int u;
1178 		int i;
1179 
1180 		CR (gp_widget_get_value(widget, &value));
1181 
1182 		switch (dpd->DataType) {
1183 		case PTP_DTC_UINT32:
1184 		case PTP_DTC_UINT16:
1185 		case PTP_DTC_UINT8:
1186 			C_PARAMS (1 == sscanf (value, "%u", &u ));
1187 			break;
1188 		case PTP_DTC_INT32:
1189 		case PTP_DTC_INT16:
1190 		case PTP_DTC_INT8:
1191 			C_PARAMS (1 == sscanf (value, "%d", &i ));
1192 			break;
1193 		default:
1194 			return GP_ERROR;
1195 		}
1196 		switch (dpd->DataType) {
1197 		case PTP_DTC_UINT32:
1198 			propval->u32 = u;
1199 			break;
1200 		case PTP_DTC_INT32:
1201 			propval->i32 = i;
1202 			break;
1203 		case PTP_DTC_UINT16:
1204 			propval->u16 = u;
1205 			break;
1206 		case PTP_DTC_INT16:
1207 			propval->i16 = i;
1208 			break;
1209 		case PTP_DTC_UINT8:
1210 			propval->u8 = u;
1211 			break;
1212 		case PTP_DTC_INT8:
1213 			propval->i8 = i;
1214 			break;
1215 		}
1216 	}
1217 	return GP_OK;
1218 }
1219 
1220 
1221 static int
_get_Nikon_OnOff_UINT8(CONFIG_GET_ARGS)1222 _get_Nikon_OnOff_UINT8(CONFIG_GET_ARGS) {
1223 	if (dpd->FormFlag != PTP_DPFF_Range)
1224 		return (GP_ERROR_NOT_SUPPORTED);
1225 	if (dpd->DataType != PTP_DTC_UINT8)
1226 		return (GP_ERROR_NOT_SUPPORTED);
1227 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1228 	gp_widget_set_name ( *widget, menu->name);
1229 	gp_widget_add_choice (*widget,_("On"));
1230 	gp_widget_add_choice (*widget,_("Off"));
1231 	gp_widget_set_value ( *widget, (dpd->CurrentValue.u8?_("On"):_("Off")));
1232 	return (GP_OK);
1233 }
1234 
1235 static int
_put_Nikon_OnOff_UINT8(CONFIG_PUT_ARGS)1236 _put_Nikon_OnOff_UINT8(CONFIG_PUT_ARGS) {
1237 	char *value;
1238 
1239 	CR (gp_widget_get_value(widget, &value));
1240 	if(!strcmp(value,_("On"))) {
1241 		propval->u8 = 1;
1242 		return (GP_OK);
1243 	}
1244 	if(!strcmp(value,_("Off"))) {
1245 		propval->u8 = 0;
1246 		return (GP_OK);
1247 	}
1248 	return (GP_ERROR);
1249 }
1250 
1251 static int
_get_Nikon_OffOn_UINT8(CONFIG_GET_ARGS)1252 _get_Nikon_OffOn_UINT8(CONFIG_GET_ARGS) {
1253 	if (dpd->FormFlag != PTP_DPFF_Range)
1254 		return (GP_ERROR_NOT_SUPPORTED);
1255 	if (dpd->DataType != PTP_DTC_UINT8)
1256 		return (GP_ERROR_NOT_SUPPORTED);
1257 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1258 	gp_widget_set_name ( *widget, menu->name);
1259 	gp_widget_add_choice (*widget,_("On"));
1260 	gp_widget_add_choice (*widget,_("Off"));
1261 	gp_widget_set_value ( *widget, (!dpd->CurrentValue.u8?_("On"):_("Off")));
1262 	return (GP_OK);
1263 }
1264 
1265 static int
_put_Nikon_OffOn_UINT8(CONFIG_PUT_ARGS)1266 _put_Nikon_OffOn_UINT8(CONFIG_PUT_ARGS) {
1267 	char *value;
1268 
1269 	CR (gp_widget_get_value(widget, &value));
1270 	if(!strcmp(value,_("On"))) {
1271 		propval->u8 = 0;
1272 		return (GP_OK);
1273 	}
1274 	if(!strcmp(value,_("Off"))) {
1275 		propval->u8 = 1;
1276 		return (GP_OK);
1277 	}
1278 	return (GP_ERROR);
1279 }
1280 
1281 #define PUT_SONY_VALUE_(bits,inttype) 								\
1282 static int										\
1283 _put_sony_value_##bits (PTPParams*params, uint16_t prop, inttype value,int useenumorder) {	\
1284 	GPContext 		*context = ((PTPData *) params->data)->context;		\
1285 	PTPDevicePropDesc	dpd;							\
1286 	PTPPropertyValue	propval;						\
1287 	inttype			origval;						\
1288 	time_t			start,end;						\
1289 	int			tries = 100;	/* 100 steps allowed towards the new value */	\
1290 											\
1291 	GP_LOG_D("setting 0x%04x to 0x%08x", prop, value);				\
1292 											\
1293 	C_PTP_REP (ptp_sony_getalldevicepropdesc (params));				\
1294 	C_PTP_REP (ptp_generic_getdevicepropdesc (params, prop, &dpd));			\
1295 	if (value == dpd.CurrentValue.bits) {						\
1296 		GP_LOG_D("value is already 0x%08x", value);				\
1297 		return GP_OK;								\
1298 	}										\
1299 fallback:										\
1300 	do {										\
1301 		origval = dpd.CurrentValue.bits;					\
1302 		/* if it is a ENUM, the camera will walk through the ENUM */		\
1303 		if (useenumorder && (dpd.FormFlag & PTP_DPFF_Enumeration) && dpd.FORM.Enum.NumberOfValues) {		\
1304 			int i, posorig = -1, posnew = -1;				\
1305 											\
1306 			for (i=0;i<dpd.FORM.Enum.NumberOfValues;i++) {			\
1307 				if (origval == dpd.FORM.Enum.SupportedValue[i].bits)	\
1308 					posorig = i;					\
1309 				if (value == dpd.FORM.Enum.SupportedValue[i].bits)	\
1310 					posnew = i;					\
1311 				if ((posnew != -1) && (posorig != -1))			\
1312 					break;						\
1313 			}								\
1314 			if (posnew == -1) {						\
1315 				gp_context_error (context, _("Target value is not in enumeration."));\
1316 				return GP_ERROR_BAD_PARAMETERS;				\
1317 			}								\
1318 			GP_LOG_D("posnew %d, posorig %d, value %d", posnew, posorig, value);	\
1319 			if (posnew == posorig)						\
1320 				break;							\
1321 			if (posnew > posorig)						\
1322 				propval.u8 = posnew-posorig;				\
1323 			else								\
1324 				propval.u8 = 0x100-(posorig-posnew);			\
1325 		} else {								\
1326 			if (value == origval)						\
1327 				break;							\
1328 			if (value > origval)						\
1329 				propval.u8 = 0x01;					\
1330 			else								\
1331 				propval.u8 = 0xff;					\
1332 		}									\
1333 		C_PTP_REP (ptp_sony_setdevicecontrolvalueb (params, prop, &propval, PTP_DTC_UINT8 ));\
1334 											\
1335 		GP_LOG_D ("value is (0x%x vs target 0x%x)", origval, value);		\
1336 											\
1337 		/* we tell the camera to do it, but it takes around 0.7 seconds for the SLT-A58 */	\
1338 		time(&start);								\
1339 		do {									\
1340 			C_PTP_REP (ptp_sony_getalldevicepropdesc (params));		\
1341 			C_PTP_REP (ptp_generic_getdevicepropdesc (params, prop, &dpd));	\
1342 											\
1343 			if (dpd.CurrentValue.bits == value) {				\
1344 				GP_LOG_D ("Value matched!");				\
1345 				break;							\
1346 			}								\
1347 			if (dpd.CurrentValue.bits != origval) {				\
1348 				GP_LOG_D ("value changed (0x%x vs 0x%x vs target 0x%x), next step....", dpd.CurrentValue.bits, origval, value);\
1349 				break;							\
1350 			}								\
1351 											\
1352 			usleep(200*1000);						\
1353 											\
1354 			time(&end);							\
1355 		} while (end-start <= 3);						\
1356 											\
1357 		if (propval.u8 == 0x01 && dpd.CurrentValue.bits > value) {		\
1358 			GP_LOG_D ("We overshooted value, maybe not exact match possible. Break!");	\
1359 			break;								\
1360 		}									\
1361 		if (propval.u8 == 0xff && dpd.CurrentValue.bits < value) {		\
1362 			GP_LOG_D ("We overshooted value, maybe not exact match possible. Break!");	\
1363 			break;								\
1364 		}									\
1365 											\
1366 		if (dpd.CurrentValue.bits == value) {					\
1367 			GP_LOG_D ("Value matched!");					\
1368 			break;								\
1369 		}									\
1370 		if (dpd.CurrentValue.bits == origval) {					\
1371 			GP_LOG_D ("value did not change (0x%x vs 0x%x vs target 0x%x), not good ...", dpd.CurrentValue.bits, origval, value);\
1372 			break;								\
1373 		}									\
1374 		/* We did not get there. Did we hit 0? */				\
1375 		if (useenumorder && (dpd.FormFlag & PTP_DPFF_Enumeration)) {		\
1376 			int i, posnow = -1;						\
1377 											\
1378 			for (i=0;i<dpd.FORM.Enum.NumberOfValues;i++) {			\
1379 				if (dpd.CurrentValue.bits == dpd.FORM.Enum.SupportedValue[i].bits) {	\
1380 					posnow = i;					\
1381 					break;						\
1382 				}							\
1383 			}								\
1384 			if (posnow == -1) {						\
1385 				GP_LOG_D ("Now value is not in enumeration, falling back to ordered tries.");\
1386 				useenumorder = 0;					\
1387 				goto fallback;						\
1388 			}								\
1389 			GP_LOG_D("posnow %d, value %d", posnow, dpd.CurrentValue.bits);	\
1390 			if ((posnow == 0) && (propval.u8 == 0xff)) {			\
1391 				gp_context_error (context, _("Sony was not able to set the new value, is it valid?"));	\
1392 				GP_LOG_D ("hit bottom of enumeration, not good.");	\
1393 				return GP_ERROR;					\
1394 			}								\
1395 			if ((posnow == dpd.FORM.Enum.NumberOfValues-1) && (propval.u8 == 0x01)) {			\
1396 				GP_LOG_D ("hit top of enumeration, not good.");		\
1397 				gp_context_error (context, _("Sony was not able to set the new value, is it valid?"));	\
1398 				return GP_ERROR;					\
1399 			}								\
1400 		} 									\
1401 	} while (tries--);/* occasionally we fail, make an escape path */		\
1402 	return GP_OK;									\
1403 }
1404 
PUT_SONY_VALUE_(u16,uint16_t)1405 PUT_SONY_VALUE_(u16,uint16_t) /* _put_sony_value_u16 */
1406 PUT_SONY_VALUE_(i16,int16_t) /* _put_sony_value_i16 */
1407 PUT_SONY_VALUE_(u32,uint32_t) /* _put_sony_value_u32 */
1408 
1409 static int
1410 _get_CANON_FirmwareVersion(CONFIG_GET_ARGS) {
1411 	char value[64];
1412 
1413 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
1414 	gp_widget_set_name (*widget, menu->name);
1415 	if (dpd->DataType != PTP_DTC_UINT32) {
1416 		sprintf (value,_("unexpected datatype %i"),dpd->DataType);
1417 	} else {
1418 		uint32_t x = dpd->CurrentValue.u32;
1419 		sprintf (value,"%d.%d.%d.%d",((x&0xff000000)>>24),((x&0xff0000)>>16),((x&0xff00)>>8),x&0xff);
1420 	}
1421 	gp_widget_set_value (*widget,value);
1422 	return (GP_OK);
1423 }
1424 
1425 static struct deviceproptableu16 whitebalance[] = {
1426 	{ N_("Manual"),			0x0001, 0 },
1427 	{ N_("Automatic"),		0x0002, 0 },
1428 	{ N_("One-push Automatic"),	0x0003, 0 },
1429 	{ N_("Daylight"),		0x0004, 0 },
1430 	{ N_("Fluorescent"),		0x0005, 0 },
1431 	{ N_("Tungsten"),		0x0006, 0 },
1432 	{ N_("Flash"),			0x0007, 0 },
1433 	{ N_("Cloudy"),			0x8010, PTP_VENDOR_NIKON },
1434 	{ N_("Shade"),			0x8011, PTP_VENDOR_NIKON },
1435 	{ N_("Color Temperature"),	0x8012, PTP_VENDOR_NIKON },
1436 	{ N_("Preset"),			0x8013, PTP_VENDOR_NIKON },
1437 	{ N_("Off"),			0x8014, PTP_VENDOR_NIKON },
1438 	{ N_("Natural light auto"),	0x8016, PTP_VENDOR_NIKON },
1439 
1440 	{ N_("Fluorescent Lamp 1"),	0x8001, PTP_VENDOR_FUJI },
1441 	{ N_("Fluorescent Lamp 2"),	0x8002, PTP_VENDOR_FUJI },
1442 	{ N_("Fluorescent Lamp 3"),	0x8003, PTP_VENDOR_FUJI },
1443 	{ N_("Fluorescent Lamp 4"),	0x8004, PTP_VENDOR_FUJI },
1444 	{ N_("Fluorescent Lamp 5"),	0x8005, PTP_VENDOR_FUJI },
1445 	{ N_("Shade"),			0x8006, PTP_VENDOR_FUJI },
1446 	{ N_("Choose Color Temperature"),0x8007, PTP_VENDOR_FUJI },
1447 	{ N_("Preset Custom 1"),	0x8008, PTP_VENDOR_FUJI },
1448 	{ N_("Preset Custom 2"),	0x8009, PTP_VENDOR_FUJI },
1449 	{ N_("Preset Custom 3"),	0x800a, PTP_VENDOR_FUJI },
1450 	{ N_("Preset Custom 4"),	0x800b, PTP_VENDOR_FUJI },
1451 	{ N_("Preset Custom 5"),	0x800c, PTP_VENDOR_FUJI },
1452 
1453 	{ N_("Shade"),			0x8011, PTP_VENDOR_SONY },
1454 	{ N_("Cloudy"),			0x8010, PTP_VENDOR_SONY },
1455 	{ N_("Fluorescent: Warm White"),0x8001, PTP_VENDOR_SONY },
1456 	{ N_("Fluorescent: Cold White"),0x8002, PTP_VENDOR_SONY },
1457 	{ N_("Fluorescent: Day White"),	0x8003, PTP_VENDOR_SONY },
1458 	{ N_("Fluorescent: Daylight"),	0x8004, PTP_VENDOR_SONY },
1459 	{ N_("Choose Color Temperature"),0x8012, PTP_VENDOR_SONY },
1460 	{ N_("Preset 1"),		0x8020, PTP_VENDOR_SONY },
1461 	{ N_("Preset 2"),		0x8021, PTP_VENDOR_SONY },
1462 	{ N_("Preset 3"),		0x8022, PTP_VENDOR_SONY },
1463 	{ N_("Preset"),			0x8023, PTP_VENDOR_SONY },
1464 	{ N_("Underwater: Auto"),	0x8030, PTP_VENDOR_SONY },
1465 
1466 	{ N_("Shade"),			0x8001, PTP_VENDOR_PENTAX },
1467 	{ N_("Cloudy"),			0x8002, PTP_VENDOR_PENTAX },
1468 	{ N_("Tungsten 2"),		0x8020, PTP_VENDOR_PENTAX },
1469 	{ N_("Fluorescent: Daylight"),	0x8003, PTP_VENDOR_PENTAX },
1470 	{ N_("Fluorescent: Day White"),	0x8004, PTP_VENDOR_PENTAX },
1471 	{ N_("Fluorescent: White"),	0x8005, PTP_VENDOR_PENTAX },
1472 	{ N_("Fluorescent: Tungsten"),	0x8006, PTP_VENDOR_PENTAX },
1473 };
1474 GENERIC16TABLE(WhiteBalance,whitebalance)
1475 
1476 static struct deviceproptableu16 olympus_whitebalance[] = {
1477 	{ N_("Automatic"),		0x0001, 0 },
1478 	{ N_("Daylight"),		0x0002, 0 },
1479 	{ N_("Shade"),			0x0003, 0 },
1480 	{ N_("Cloudy"),			0x0004, 0 },
1481 	{ N_("Tungsten"),		0x0005, 0 },
1482 	{ N_("Fluorescent"),		0x0006, 0 },
1483 	{ N_("Underwater"),		0x0007, 0 },
1484 	{ N_("Flash"),			0x0008, 0 },
1485 	{ N_("Preset 1"),		0x0009, 0 },
1486 	{ N_("Preset 2"),		0x000a, 0 },
1487 	{ N_("Preset 3"),		0x000b, 0 },
1488 	{ N_("Preset 4"),		0x000c, 0 },
1489 	{ N_("Custom"),			0x000d, 0 },
1490 };
1491 GENERIC16TABLE(Olympus_WhiteBalance,olympus_whitebalance)
1492 
1493 static struct deviceproptableu16 fuji_imageformat[] = {
1494 	{ N_("RAW"),			1,	PTP_VENDOR_FUJI },
1495 	{ N_("JPEG Fine"),		2,	PTP_VENDOR_FUJI },
1496 	{ N_("JPEG Normal"),		3,	PTP_VENDOR_FUJI },
1497 	{ N_("RAW + JPEG Fine"),	4,	PTP_VENDOR_FUJI },
1498 	{ N_("RAW + JPEG Normal"),	5,	PTP_VENDOR_FUJI },
1499 };
1500 GENERIC16TABLE(Fuji_ImageFormat,fuji_imageformat)
1501 
1502 static struct deviceproptableu16 olympus_imageformat[] = {
1503 	{ N_("RAW"),			0x020,	PTP_VENDOR_GP_OLYMPUS_OMD },
1504 	{ N_("Large Fine JPEG"),	0x101,	PTP_VENDOR_GP_OLYMPUS_OMD },
1505 	{ N_("Large Normal JPEG"),	0x102,	PTP_VENDOR_GP_OLYMPUS_OMD },
1506 	{ N_("Medium Normal JPEG"),	0x103,	PTP_VENDOR_GP_OLYMPUS_OMD },
1507 	{ N_("Small Normal JPEG"),	0x104,	PTP_VENDOR_GP_OLYMPUS_OMD },
1508 	{ N_("Large Fine JPEG+RAW"),	0x121,	PTP_VENDOR_GP_OLYMPUS_OMD },
1509 	{ N_("Large Normal JPEG+RAW"),	0x122,	PTP_VENDOR_GP_OLYMPUS_OMD },
1510 	{ N_("Medium Normal JPEG+RAW"),	0x123,	PTP_VENDOR_GP_OLYMPUS_OMD },
1511 	{ N_("Small Normal JPEG+RAW"),	0x124,	PTP_VENDOR_GP_OLYMPUS_OMD },
1512 };
1513 GENERIC16TABLE(Olympus_Imageformat,olympus_imageformat)
1514 
1515 static struct deviceproptableu16 fuji_releasemode[] = {
1516 	{ N_("Single frame"),		1,	PTP_VENDOR_FUJI },
1517 	{ N_("Continuous low speed"),	2,	PTP_VENDOR_FUJI },
1518 	{ N_("Continuous high speed"),	3,	PTP_VENDOR_FUJI },
1519 	{ N_("Self-timer"),		4,	PTP_VENDOR_FUJI },
1520 	{ N_("Mup Mirror up"),		5,	PTP_VENDOR_FUJI },
1521 };
1522 GENERIC16TABLE(Fuji_ReleaseMode,fuji_releasemode)
1523 
1524 static struct deviceproptableu16 fuji_filmsimulation[] = {
1525 	{ N_("PROVIA/Standard"),            1,	PTP_VENDOR_FUJI },
1526 	{ N_("Velvia/Vivid"),               2,	PTP_VENDOR_FUJI },
1527 	{ N_("ASTIA/Soft"),                 3,	PTP_VENDOR_FUJI },
1528 	{ N_("PRO Neg.Hi"),                 4,	PTP_VENDOR_FUJI },
1529 	{ N_("PRO Neg.Std"),                5,	PTP_VENDOR_FUJI },
1530 	{ N_("Black & White"),              6,	PTP_VENDOR_FUJI },
1531 	{ N_("Black & White+Ye Filter"),    7,	PTP_VENDOR_FUJI },
1532 	{ N_("Black & White+R Filter"),     8,	PTP_VENDOR_FUJI },
1533 	{ N_("Black & White+G Filter"),     9,	PTP_VENDOR_FUJI },
1534 	{ N_("Sepia"),                      10,	PTP_VENDOR_FUJI },
1535 	{ N_("Classic Chrome"),             11,	PTP_VENDOR_FUJI },
1536 	{ N_("ACROS"),                      12,	PTP_VENDOR_FUJI },
1537 	{ N_("ACROS+Ye Filter"),            13,	PTP_VENDOR_FUJI },
1538 	{ N_("ACROS+R Filter,"),            14,	PTP_VENDOR_FUJI },
1539 	{ N_("ACROS+G Filter"),             15,	PTP_VENDOR_FUJI },
1540 	{ N_("ETERNA/Cinema"),              16,	PTP_VENDOR_FUJI },
1541 	{ N_("Classic Neg"),                17,	PTP_VENDOR_FUJI },
1542 	{ N_("ETERNA BLEACH BYPASS"),       18,	PTP_VENDOR_FUJI },
1543 };
GENERIC16TABLE(Fuji_FilmSimulation,fuji_filmsimulation)1544 GENERIC16TABLE(Fuji_FilmSimulation,fuji_filmsimulation)
1545 
1546 static int
1547 _get_ExpCompensation(CONFIG_GET_ARGS) {
1548 	int j;
1549 	char buf[13];
1550 
1551 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
1552 		return GP_ERROR;
1553 	if (dpd->DataType != PTP_DTC_INT16)
1554 		return GP_ERROR;
1555 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1556 	gp_widget_set_name (*widget, menu->name);
1557 	for (j=0;j<dpd->FORM.Enum.NumberOfValues; j++) {
1558 		sprintf(buf, "%g", dpd->FORM.Enum.SupportedValue[j].i16/1000.0);
1559 		gp_widget_add_choice (*widget,buf);
1560 	}
1561 	sprintf(buf, "%g", dpd->CurrentValue.i16/1000.0);
1562 	gp_widget_set_value (*widget,buf);
1563 	return GP_OK;
1564 }
1565 
1566 static int
_put_ExpCompensation(CONFIG_PUT_ARGS)1567 _put_ExpCompensation(CONFIG_PUT_ARGS) {
1568 	char	*value;
1569 	float	x;
1570 	int16_t	val, targetval = 0;
1571 	int	mindist = 65535, j;
1572 
1573 	CR (gp_widget_get_value(widget, &value));
1574 	if (1 != sscanf(value,"%g", &x))
1575 		return GP_ERROR;
1576 
1577 	/* float processing is not always hitting the right values, but close */
1578 	val = x*1000.0;
1579 	for (j=0;j<dpd->FORM.Enum.NumberOfValues; j++) {
1580 		if (abs(dpd->FORM.Enum.SupportedValue[j].i16 - val) < mindist) {
1581 			mindist = abs(dpd->FORM.Enum.SupportedValue[j].i16 - val);
1582 			targetval = dpd->FORM.Enum.SupportedValue[j].i16;
1583 		}
1584 	}
1585 	propval->i16 = targetval;
1586 	return GP_OK ;
1587 }
1588 
1589 /* old method, uses stepping */
1590 static int
_put_Sony_ExpCompensation(CONFIG_PUT_ARGS)1591 _put_Sony_ExpCompensation(CONFIG_PUT_ARGS) {
1592 	int ret;
1593 
1594 	ret = _put_ExpCompensation(CONFIG_PUT_NAMES);
1595 	if (ret != GP_OK) return ret;
1596 	return _put_sony_value_i16 (&camera->pl->params, dpd->DevicePropertyCode, propval->i16, 0);
1597 }
1598 
1599 /* new method, can set directly */
1600 static int
_put_Sony_ExpCompensation2(CONFIG_PUT_ARGS)1601 _put_Sony_ExpCompensation2(CONFIG_PUT_ARGS) {
1602 	int ret;
1603 
1604 	ret = _put_ExpCompensation(CONFIG_PUT_NAMES);
1605 	if (ret != GP_OK) return ret;
1606 	return translate_ptp_result (ptp_sony_setdevicecontrolvaluea (&camera->pl->params, dpd->DevicePropertyCode, propval, PTP_DTC_INT16));
1607 }
1608 
1609 static int
_get_Olympus_ExpCompensation(CONFIG_GET_ARGS)1610 _get_Olympus_ExpCompensation(CONFIG_GET_ARGS) {
1611 	int j;
1612 	char buf[13];
1613 
1614 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
1615 		return GP_ERROR;
1616 	if (dpd->DataType != PTP_DTC_UINT16)
1617 		return GP_ERROR;
1618 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1619 	gp_widget_set_name (*widget, menu->name);
1620 	for (j=0;j<dpd->FORM.Enum.NumberOfValues; j++) {
1621 		sprintf(buf, "%g", dpd->FORM.Enum.SupportedValue[j].i16/1000.0);
1622 		gp_widget_add_choice (*widget,buf);
1623 	}
1624 	sprintf(buf, "%g", dpd->CurrentValue.i16/1000.0);
1625 	gp_widget_set_value (*widget,buf);
1626 	return GP_OK;
1627 }
1628 
1629 static int
_put_Olympus_ExpCompensation(CONFIG_PUT_ARGS)1630 _put_Olympus_ExpCompensation(CONFIG_PUT_ARGS) {
1631 	char	*value;
1632 	float	x;
1633 	int16_t	val, targetval = 0;
1634 	int	mindist = 65535, j;
1635 
1636 	CR (gp_widget_get_value(widget, &value));
1637 	if (1 != sscanf(value,"%g", &x))
1638 		return GP_ERROR;
1639 
1640 	/* float processing is not always hitting the right values, but close */
1641 	val = x*1000.0;
1642 	for (j=0;j<dpd->FORM.Enum.NumberOfValues; j++) {
1643 		if (abs(dpd->FORM.Enum.SupportedValue[j].i16 - val) < mindist) {
1644 			mindist = abs(dpd->FORM.Enum.SupportedValue[j].i16 - val);
1645 			targetval = dpd->FORM.Enum.SupportedValue[j].i16;
1646 		}
1647 	}
1648 	propval->i16 = targetval;
1649 	return GP_OK ;
1650 }
1651 
1652 
1653 static struct deviceproptableu16 canon_assistlight[] = {
1654 	{ N_("On"),	0x0000, PTP_VENDOR_CANON },
1655 	{ N_("Off"),	0x0001, PTP_VENDOR_CANON },
1656 };
1657 GENERIC16TABLE(Canon_AssistLight,canon_assistlight)
1658 
1659 static struct deviceproptableu16 canon_autorotation[] = {
1660 	{ N_("On"),	0x0000, PTP_VENDOR_CANON },
1661 	{ N_("Off"),	0x0001, PTP_VENDOR_CANON },
1662 };
1663 GENERIC16TABLE(Canon_AutoRotation,canon_autorotation)
1664 
1665 static struct deviceproptableu16 canon_beepmode[] = {
1666 	{ N_("Off"),	0x00, PTP_VENDOR_CANON },
1667 	{ N_("On"),	0x01, PTP_VENDOR_CANON },
1668 };
GENERIC16TABLE(Canon_BeepMode,canon_beepmode)1669 GENERIC16TABLE(Canon_BeepMode,canon_beepmode)
1670 
1671 static int
1672 _get_Canon_ZoomRange(CONFIG_GET_ARGS) {
1673 	float	f, t, b, s;
1674 
1675 	if (!(dpd->FormFlag & PTP_DPFF_Range))
1676 		return (GP_ERROR);
1677 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1678 	gp_widget_set_name (*widget,menu->name);
1679 	f = (float)dpd->CurrentValue.u16;
1680 	b = (float)dpd->FORM.Range.MinimumValue.u16;
1681 	t = (float)dpd->FORM.Range.MaximumValue.u16;
1682 	s = (float)dpd->FORM.Range.StepSize.u16;
1683 	gp_widget_set_range (*widget, b, t, s);
1684 	gp_widget_set_value (*widget, &f);
1685 	return (GP_OK);
1686 }
1687 
1688 static int
_put_Canon_ZoomRange(CONFIG_PUT_ARGS)1689 _put_Canon_ZoomRange(CONFIG_PUT_ARGS)
1690 {
1691 	float	f;
1692 
1693 	CR (gp_widget_get_value(widget, &f));
1694 	propval->u16 = (unsigned short)f;
1695 	return (GP_OK);
1696 }
1697 
1698 /* This seems perhaps focal length * 1.000.000 */
1699 static int
_get_Sony_Zoom(CONFIG_GET_ARGS)1700 _get_Sony_Zoom(CONFIG_GET_ARGS) {
1701 	float	f, t, b, s;
1702 
1703 	if (dpd->DataType != PTP_DTC_UINT32)
1704 		return GP_ERROR;
1705 	if (!(dpd->FormFlag & PTP_DPFF_Range))
1706 		return GP_ERROR;
1707 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1708 	gp_widget_set_name (*widget,menu->name);
1709 	f = (float)dpd->CurrentValue.u32 / 1000000;
1710 	b = (float)dpd->FORM.Range.MinimumValue.u32 / 1000000;
1711 	t = (float)dpd->FORM.Range.MaximumValue.u32 / 1000000;
1712 	s = 1;
1713 	gp_widget_set_range (*widget, b, t, s);
1714 	gp_widget_set_value (*widget, &f);
1715 	return GP_OK;
1716 }
1717 
1718 static int
_put_Sony_Zoom(CONFIG_PUT_ARGS)1719 _put_Sony_Zoom(CONFIG_PUT_ARGS)
1720 {
1721 	float	f;
1722 	PTPParams *params = &camera->pl->params;
1723 
1724 	CR (gp_widget_get_value(widget, &f));
1725 	propval->u32 = (uint32_t)f*1000000;
1726 	return _put_sony_value_u32(params, PTP_DPC_SONY_Zoom, propval->u32, 0);
1727 }
1728 
1729 static int
_get_Nikon_WBBias(CONFIG_GET_ARGS)1730 _get_Nikon_WBBias(CONFIG_GET_ARGS) {
1731 	float	f, t, b, s;
1732 
1733 	if (dpd->DataType != PTP_DTC_INT8)
1734 		return GP_ERROR;
1735 	if (!(dpd->FormFlag & PTP_DPFF_Range))
1736 		return GP_ERROR;
1737 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1738 	gp_widget_set_name (*widget,menu->name);
1739 	f = (float)dpd->CurrentValue.i8;
1740 	b = (float)dpd->FORM.Range.MinimumValue.i8;
1741 	t = (float)dpd->FORM.Range.MaximumValue.i8;
1742 	s = (float)dpd->FORM.Range.StepSize.i8;
1743 	gp_widget_set_range (*widget, b, t, s);
1744 	gp_widget_set_value (*widget, &f);
1745 	return (GP_OK);
1746 }
1747 
1748 static int
_put_Nikon_WBBias(CONFIG_PUT_ARGS)1749 _put_Nikon_WBBias(CONFIG_PUT_ARGS)
1750 {
1751 	float	f;
1752 
1753 	CR (gp_widget_get_value(widget, &f));
1754 	propval->i8 = (signed char)f;
1755 	return (GP_OK);
1756 }
1757 
1758 /* This can get type 1 (INT8) , 2 (UINT8) and 4 (UINT16) */
1759 static int
_get_Nikon_UWBBias(CONFIG_GET_ARGS)1760 _get_Nikon_UWBBias(CONFIG_GET_ARGS) {
1761 	float	f, t, b, s;
1762 
1763 	if (!(dpd->FormFlag & PTP_DPFF_Range))
1764 		return GP_ERROR;
1765 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1766 	gp_widget_set_name (*widget,menu->name);
1767 	switch (dpd->DataType) {
1768 	case PTP_DTC_UINT16:
1769 		f = (float)dpd->CurrentValue.u16;
1770 		b = (float)dpd->FORM.Range.MinimumValue.u16;
1771 		t = (float)dpd->FORM.Range.MaximumValue.u16;
1772 		s = (float)dpd->FORM.Range.StepSize.u16;
1773 		break;
1774 	case PTP_DTC_UINT8:
1775 		f = (float)dpd->CurrentValue.u8;
1776 		b = (float)dpd->FORM.Range.MinimumValue.u8;
1777 		t = (float)dpd->FORM.Range.MaximumValue.u8;
1778 		s = (float)dpd->FORM.Range.StepSize.u8;
1779 		break;
1780 	case PTP_DTC_INT8:
1781 		f = (float)dpd->CurrentValue.i8;
1782 		b = (float)dpd->FORM.Range.MinimumValue.i8;
1783 		t = (float)dpd->FORM.Range.MaximumValue.i8;
1784 		s = (float)dpd->FORM.Range.StepSize.i8;
1785 		break;
1786 	default:
1787 		return GP_ERROR;
1788 	}
1789 	gp_widget_set_range (*widget, b, t, s);
1790 	gp_widget_set_value (*widget, &f);
1791 	return GP_OK;
1792 }
1793 
1794 static int
_put_Nikon_UWBBias(CONFIG_PUT_ARGS)1795 _put_Nikon_UWBBias(CONFIG_PUT_ARGS)
1796 {
1797 	float	f;
1798 
1799 	CR (gp_widget_get_value(widget, &f));
1800 	switch (dpd->DataType) {
1801 	case PTP_DTC_UINT16:
1802 		propval->u16 = (unsigned short)f;
1803 		break;
1804 	case PTP_DTC_UINT8:
1805 		propval->u8 = (unsigned char)f;
1806 		break;
1807 	case PTP_DTC_INT8:
1808 		propval->i8 = (char)f;
1809 		break;
1810 	default:
1811 		return GP_ERROR;
1812 	}
1813 	return GP_OK;
1814 }
1815 
1816 static int
_get_Nikon_WBBiasPresetVal(CONFIG_GET_ARGS)1817 _get_Nikon_WBBiasPresetVal(CONFIG_GET_ARGS) {
1818 	char buf[20];
1819 
1820 	if (dpd->DataType != PTP_DTC_UINT32)
1821 		return (GP_ERROR);
1822 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
1823 	gp_widget_set_name (*widget,menu->name);
1824 	sprintf (buf, "%d", dpd->CurrentValue.u32);
1825 	gp_widget_set_value (*widget, buf);
1826 	return (GP_OK);
1827 }
1828 static int
_get_Nikon_WBBiasPreset(CONFIG_GET_ARGS)1829 _get_Nikon_WBBiasPreset(CONFIG_GET_ARGS) {
1830 	char buf[20];
1831 	int i;
1832 
1833 	if (dpd->DataType != PTP_DTC_UINT8)
1834 		return (GP_ERROR);
1835 	if (!(dpd->FormFlag & PTP_DPFF_Range))
1836 		return (GP_ERROR);
1837 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1838 	gp_widget_set_name (*widget,menu->name);
1839 	for (i = dpd->FORM.Range.MinimumValue.u8; i < dpd->FORM.Range.MaximumValue.u8; i++) {
1840 		sprintf (buf, "%d", i);
1841 		gp_widget_add_choice (*widget, buf);
1842 		if (i == dpd->CurrentValue.u8)
1843 			gp_widget_set_value (*widget, buf);
1844 	}
1845 	return (GP_OK);
1846 }
1847 
1848 static int
_put_Nikon_WBBiasPreset(CONFIG_PUT_ARGS)1849 _put_Nikon_WBBiasPreset(CONFIG_PUT_ARGS) {
1850 	int	ret;
1851 	char	*val;
1852 
1853 	CR (gp_widget_get_value(widget, &val));
1854 	sscanf (val, "%u", &ret);
1855 	propval->u8 = ret;
1856 	return (GP_OK);
1857 }
1858 
1859 static int
_get_Nikon_HueAdjustment(CONFIG_GET_ARGS)1860 _get_Nikon_HueAdjustment(CONFIG_GET_ARGS) {
1861 	float	f, t, b, s;
1862 
1863 	if (dpd->DataType != PTP_DTC_INT8)
1864 		return (GP_ERROR);
1865 	if (dpd->FormFlag & PTP_DPFF_Range) {
1866 		gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
1867 		gp_widget_set_name (*widget,menu->name);
1868 		f = (float)dpd->CurrentValue.i8;
1869 		b = (float)dpd->FORM.Range.MinimumValue.i8;
1870 		t = (float)dpd->FORM.Range.MaximumValue.i8;
1871 		s = (float)dpd->FORM.Range.StepSize.i8;
1872 		gp_widget_set_range (*widget, b, t, s);
1873 		gp_widget_set_value (*widget, &f);
1874 		return (GP_OK);
1875 	}
1876 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
1877 		char buf[20];
1878 		int i, isset = FALSE;
1879 
1880 		gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1881 		gp_widget_set_name (*widget,menu->name);
1882 		for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
1883 
1884 			sprintf (buf, "%d", dpd->FORM.Enum.SupportedValue[i].i8);
1885 			gp_widget_add_choice (*widget, buf);
1886 			if (dpd->FORM.Enum.SupportedValue[i].i8 == dpd->CurrentValue.i8) {
1887 				gp_widget_set_value (*widget, buf);
1888 				isset = TRUE;
1889 			}
1890 		}
1891 		if (!isset && (dpd->FORM.Enum.NumberOfValues > 0)) {
1892 			sprintf (buf, "%d", dpd->FORM.Enum.SupportedValue[0].i8);
1893 			gp_widget_set_value (*widget, buf);
1894 		}
1895 		return (GP_OK);
1896 	}
1897 	return (GP_ERROR);
1898 }
1899 
1900 static int
_put_Nikon_HueAdjustment(CONFIG_PUT_ARGS)1901 _put_Nikon_HueAdjustment(CONFIG_PUT_ARGS)
1902 {
1903 	if (dpd->FormFlag & PTP_DPFF_Range) {
1904 		float	f = 0.0;
1905 		CR (gp_widget_get_value(widget, &f));
1906 		propval->i8 = (signed char)f;
1907 		return (GP_OK);
1908 	}
1909 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
1910 		char *val;
1911 		int ival;
1912 
1913 		CR (gp_widget_get_value(widget, &val));
1914 		sscanf (val, "%d", &ival);
1915 		propval->i8 = ival;
1916 		return (GP_OK);
1917 	}
1918 	return (GP_ERROR);
1919 }
1920 
1921 static int
_get_Nikon_MovieLoopLength(CONFIG_GET_ARGS)1922 _get_Nikon_MovieLoopLength(CONFIG_GET_ARGS) {
1923 
1924 	if (dpd->DataType != PTP_DTC_UINT32)
1925 		return GP_ERROR;
1926 
1927 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
1928 		char buf[20];
1929 		int i, isset = FALSE;
1930 
1931 		gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
1932 		gp_widget_set_name (*widget,menu->name);
1933 		for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
1934 
1935 			sprintf (buf, "%d", dpd->FORM.Enum.SupportedValue[i].u32/10);
1936 			gp_widget_add_choice (*widget, buf);
1937 			if (dpd->FORM.Enum.SupportedValue[i].u32 == dpd->CurrentValue.u32) {
1938 				gp_widget_set_value (*widget, buf);
1939 				isset = TRUE;
1940 			}
1941 		}
1942 		if (!isset && (dpd->FORM.Enum.NumberOfValues > 0)) {
1943 			sprintf (buf, "%d", dpd->FORM.Enum.SupportedValue[0].u32/10);
1944 			gp_widget_set_value (*widget, buf);
1945 		}
1946 		return GP_OK;
1947 	}
1948 	return GP_ERROR;
1949 }
1950 
1951 static int
_put_Nikon_MovieLoopLength(CONFIG_PUT_ARGS)1952 _put_Nikon_MovieLoopLength(CONFIG_PUT_ARGS)
1953 {
1954 	char *val;
1955 	int ival;
1956 
1957 	CR (gp_widget_get_value(widget, &val));
1958 	sscanf (val, "%d", &ival);
1959 	propval->u32 = ival*10;
1960 	return GP_OK;
1961 }
1962 
1963 
1964 static struct deviceproptableu8 canon_quality[] = {
1965 	{ N_("undefined"),	0x00, 0 },
1966 	{ N_("economy"),	0x01, 0 },
1967 	{ N_("normal"),		0x02, 0 },
1968 	{ N_("fine"),		0x03, 0 },
1969 	{ N_("lossless"),	0x04, 0 },
1970 	{ N_("superfine"),	0x05, 0 },
1971 };
1972 GENERIC8TABLE(Canon_Quality,canon_quality)
1973 
1974 static struct deviceproptableu8 canon_fullview_fileformat[] = {
1975 	{ N_("Undefined"),	0x00, 0 },
1976 	{ N_("JPEG"),		0x01, 0 },
1977 	{ N_("CRW"),		0x02, 0 },
1978 };
1979 GENERIC8TABLE(Canon_Capture_Format,canon_fullview_fileformat)
1980 
1981 static struct deviceproptableu8 canon_shootmode[] = {
1982 	{ N_("Auto"),		0x01, 0 },
1983 	{ N_("TV"),		0x02, 0 },
1984 	{ N_("AV"),		0x03, 0 },
1985 	{ N_("Manual"),		0x04, 0 },
1986 	{ N_("A_DEP"),		0x05, 0 },
1987 	{ N_("M_DEP"),		0x06, 0 },
1988 	{ N_("Bulb"),		0x07, 0 },
1989 	/* Marcus: The SDK has more listed, but I have never seen them
1990 	 * enumerated by the cameras. Lets leave them out for now. */
1991 };
1992 GENERIC8TABLE(Canon_ShootMode,canon_shootmode)
1993 
1994 static struct deviceproptableu16 canon_eos_autoexposuremode[] = {
1995 	{ N_("P"),		0x0000, 0 },
1996 	{ N_("TV"),		0x0001, 0 },
1997 	{ N_("AV"),		0x0002, 0 },
1998 	{ N_("Manual"),		0x0003, 0 },
1999 	{ N_("Bulb"),		0x0004, 0 },
2000 	{ N_("A_DEP"),		0x0005, 0 },
2001 	{ N_("DEP"),		0x0006, 0 },
2002 	{ N_("Custom"),		0x0007, 0 },
2003 	{ N_("Lock"),		0x0008, 0 },
2004 	{ N_("Green"),		0x0009, 0 },
2005 	{ N_("Night Portrait"),	0x000a, 0 },
2006 	{ N_("Sports"),		0x000b, 0 },
2007 	{ N_("Portrait"),	0x000c, 0 },
2008 	{ N_("Landscape"),	0x000d, 0 },
2009 	{ N_("Closeup"),	0x000e, 0 },
2010 	{ N_("Flash Off"),	0x000f, 0 },
2011 };
2012 GENERIC16TABLE(Canon_EOS_AutoExposureMode,canon_eos_autoexposuremode)
2013 
2014 static struct deviceproptableu32 canon_eos_alomode[] = {
2015 	{ N_("Standard"),				0x10000, 0 },
2016 	{ N_("Standard (disabled in manual exposure)"),	0x00000, 0 },
2017 	{ N_("Low"),					0x10101, 0 },
2018 	{ N_("Low (disabled in manual exposure)"),	0x00101, 0 },
2019 	{ N_("Off"),					0x10303, 0 },
2020 	{ N_("Off (disabled in manual exposure)"),	0x00303, 0 },
2021 	{ N_("High"),					0x10202, 0 },
2022 	{ N_("High (disabled in manual exposure)"),	0x00202, 0 },
2023 	{ N_("x1"),	0x1, 0 },
2024 	{ N_("x2"),	0x2, 0 },
2025 	{ N_("x3"),	0x3, 0 },
2026 };
2027 GENERIC32TABLE(Canon_EOS_AloMode,canon_eos_alomode)
2028 
2029 static struct deviceproptableu8 canon_flash[] = {
2030 	{ N_("off"),				0, 0 },
2031 	{ N_("auto"),				1, 0 },
2032 	{ N_("on"),				2, 0 },
2033 	{ N_("red eye suppression"),		3, 0 },
2034 	{ N_("fill in"), 			4, 0 },
2035 	{ N_("auto + red eye suppression"),	5, 0 },
2036 	{ N_("on + red eye suppression"),	6, 0 },
2037 };
2038 GENERIC8TABLE(Canon_FlashMode,canon_flash)
2039 
2040 static struct deviceproptableu8 nikon_internalflashmode[] = {
2041 	{ N_("iTTL"),		0, 0 },
2042 	{ N_("Manual"),		1, 0 },
2043 	{ N_("Commander"),	2, 0 },
2044 	{ N_("Repeating"),	3, 0 }, /* stroboskop */
2045 };
2046 GENERIC8TABLE(Nikon_InternalFlashMode,nikon_internalflashmode)
2047 
2048 static struct deviceproptableu8 nikon_flashcommandermode[] = {
2049 	{ N_("TTL"),		0, 0 },
2050 	{ N_("Auto Aperture"),	1, 0 },
2051 	{ N_("Full Manual"),	2, 0 },
2052 };
2053 GENERIC8TABLE(Nikon_FlashCommanderMode,nikon_flashcommandermode)
2054 
2055 static struct deviceproptableu8 nikon_liveviewsize[] = {
2056 	{ N_("QVGA"),		1, 0 },
2057 	{ N_("VGA"),		2, 0 },
2058 	{ N_("XGA"),		3, 0 },
2059 };
2060 GENERIC8TABLE(Nikon_LiveViewSize,nikon_liveviewsize)
2061 
2062 static struct deviceproptableu16 fuji_liveviewsize[] = {
2063 	{ N_("XGA"),		1, 0 },
2064 	{ N_("VGA"),		2, 0 },
2065 	{ N_("QVGA"),		3, 0 },
2066 };
2067 GENERIC16TABLE(Fuji_LiveViewSize,fuji_liveviewsize)
2068 
2069 static struct deviceproptableu8 sony_qx_liveviewsize[] = {
2070 	{ "640x480",		1, 0 },
2071 	{ "1024x768",		2, 0 },
2072 	{ "1920x1280",		3, 0 },
2073 };
2074 GENERIC8TABLE(Sony_QX_LiveViewSize,sony_qx_liveviewsize)
2075 
2076 static struct deviceproptableu8 nikon_flashcommanderpower[] = {
2077 	{ N_("Full"),		0, 0 },
2078 	{ "1/2",		1, 0 },
2079 	{ "1/4",		2, 0 },
2080 	{ "1/8",		3, 0 },
2081 	{ "1/16",		4, 0 },
2082 	{ "1/32",		5, 0 },
2083 	{ "1/64",		6, 0 },
2084 	{ "1/128",		7, 0 },
2085 };
2086 GENERIC8TABLE(Nikon_FlashCommanderPower,nikon_flashcommanderpower)
2087 
2088 /* 0xd1d3 */
2089 static struct deviceproptableu8 nikon_flashcommandchannel[] = {
2090 	{ "1",		0, 0 },
2091 	{ "2",		1, 0 },
2092 	{ "3",		2, 0 },
2093 	{ "4",		3, 0 },
2094 };
2095 GENERIC8TABLE(Nikon_FlashCommandChannel,nikon_flashcommandchannel)
2096 
2097 /* 0xd1d4 */
2098 static struct deviceproptableu8 nikon_flashcommandselfmode[] = {
2099 	{ N_("TTL"),		0, 0 },
2100 	{ N_("Manual"),		1, 0 },
2101 	{ N_("Off"),		2, 0 },
2102 };
2103 GENERIC8TABLE(Nikon_FlashCommandSelfMode,nikon_flashcommandselfmode)
2104 
2105 /* 0xd1d5, 0xd1d8, 0xd1da */
2106 static struct deviceproptableu8 nikon_flashcommandXcompensation[] = {
2107 	{ "-3.0",		0, 0 },
2108 	{ "-2.7",		1, 0 },
2109 	{ "-2.3",		2, 0 },
2110 	{ "-2.0",		3, 0 },
2111 	{ "-1.7",		4, 0 },
2112 	{ "-1.3",		5, 0 },
2113 	{ "-1.0",		6, 0 },
2114 	{ "-0.7",		7, 0 },
2115 	{ "-0.3",		8, 0 },
2116 	{ "0.0",		9, 0 },
2117 	{ "0.3",		10, 0 },
2118 	{ "0.7",		11, 0 },
2119 	{ "1.0",		12, 0 },
2120 	{ "1.3",		13, 0 },
2121 	{ "1.7",		14, 0 },
2122 	{ "2.0",		15, 0 },
2123 	{ "2.3",		16, 0 },
2124 	{ "2.7",		17, 0 },
2125 	{ "3.0",		18, 0 },
2126 };
2127 GENERIC8TABLE(Nikon_FlashCommandXCompensation,nikon_flashcommandXcompensation)
2128 
2129 /* 0xd1d5, 0xd1d9, 0xd1dc */
2130 static struct deviceproptableu8 nikon_flashcommandXvalue[] = {
2131 	{ N_("Full"),		0, 0 },
2132 	{ "1/1.3",		1, 0 },
2133 	{ "1/1.7",		2, 0 },
2134 	{ "1/2",		3, 0 },
2135 	{ "1/2.5",		4, 0 },
2136 	{ "1/3.2",		5, 0 },
2137 	{ "1/4",		6, 0 },
2138 	{ "1/5",		7, 0 },
2139 	{ "1/6.4",		8, 0 },
2140 	{ "1/8",		9, 0 },
2141 	{ "1/10",		10, 0 },
2142 	{ "1/13",		11, 0 },
2143 	{ "1/16",		12, 0 },
2144 	{ "1/20",		13, 0 },
2145 	{ "1/25",		14, 0 },
2146 	{ "1/32",		15, 0 },
2147 	{ "1/40",		16, 0 },
2148 	{ "1/50",		17, 0 },
2149 	{ "1/64",		18, 0 },
2150 	{ "1/80",		19, 0 },
2151 	{ "1/100",		20, 0 },
2152 	{ "1/128",		21, 0 },
2153 };
2154 GENERIC8TABLE(Nikon_FlashCommandXValue,nikon_flashcommandXvalue)
2155 
2156 
2157 /* 0xd1d7, 0xd1da */
2158 static struct deviceproptableu8 nikon_flashcommandXmode[] = {
2159 	{ N_("TTL"),		0, 0 },
2160 	{ N_("Auto Aperture"),	1, 0 },
2161 	{ N_("Manual"),		2, 0 },
2162 	{ N_("Off"),		3, 0 },
2163 };
2164 GENERIC8TABLE(Nikon_FlashCommandXMode,nikon_flashcommandXmode)
2165 
2166 
2167 static struct deviceproptableu8 nikon_afmode[] = {
2168 	{ N_("AF-S"),		0, 0 },
2169 	{ N_("AF-C"),		1, 0 },
2170 	{ N_("AF-A"),		2, 0 },
2171 	{ N_("MF (fixed)"),	3, 0 },
2172 	{ N_("MF (selection)"),	4, 0 },
2173 	/* more for newer */
2174 };
2175 GENERIC8TABLE(Nikon_AFMode,nikon_afmode)
2176 
2177 static struct deviceproptableu8 nikon_videomode[] = {
2178 	{ N_("NTSC"),		0, 0 },
2179 	{ N_("PAL"),		1, 0 },
2180 };
2181 GENERIC8TABLE(Nikon_VideoMode,nikon_videomode)
2182 
2183 static struct deviceproptableu8 flash_modemanualpower[] = {
2184 	{ N_("Full"),	0x00, 0 },
2185 	{ "1/2",	0x01, 0 },
2186 	{ "1/4",	0x02, 0 },
2187 	{ "1/8",	0x03, 0 },
2188 	{ "1/16",	0x04, 0 },
2189 	{ "1/32",	0x05, 0 },
2190 };
2191 GENERIC8TABLE(Nikon_FlashModeManualPower,flash_modemanualpower)
2192 
2193 static struct deviceproptableu8 canon_meteringmode[] = {
2194 	{ N_("Center-weighted"),		0, 0 },
2195 	{ N_("Spot"),				1, 0 },
2196 	{ N_("Average"),			2, 0 },
2197 	{ N_("Evaluative"),			3, 0 },
2198 	{ N_("Partial"),			4, 0 },
2199 	{ N_("Center-weighted average"),	5, 0 },
2200 	{ N_("Spot metering interlocked with AF frame"),	6, 0 },
2201 	{ N_("Multi spot"),			7, 0 },
2202 };
2203 GENERIC8TABLE(Canon_MeteringMode,canon_meteringmode)
2204 
2205 static struct deviceproptableu8 canon_eos_picturestyle[] = {
2206 	{ N_("Standard"),	0x81, 0 },
2207 	{ N_("Portrait"),	0x82, 0 },
2208 	{ N_("Landscape"),	0x83, 0 },
2209 	{ N_("Neutral"),	0x84, 0 },
2210 	{ N_("Faithful"),	0x85, 0 },
2211 	{ N_("Monochrome"),	0x86, 0 },
2212 	{ N_("Auto"),		0x87, 0 }, /*Canon EOS 5D Mark III*/
2213 	{ N_("Fine detail"),	0x88, 0 },
2214 	{ N_("User defined 1"),	0x21, 0 },
2215 	{ N_("User defined 2"),	0x22, 0 },
2216 	{ N_("User defined 3"),	0x23, 0 },
2217 };
2218 GENERIC8TABLE(Canon_EOS_PictureStyle,canon_eos_picturestyle)
2219 
2220 static struct deviceproptableu16 canon_shutterspeed[] = {
2221 	{ "auto",	0x0000,0 },
2222 	{ "bulb",	0x0004,0 },
2223 	{ "bulb",	0x000c,0 },
2224 	{ "30",		0x0010,0 },
2225 	{ "25",		0x0013,0 },
2226 	{ "20.3",	0x0014,0 }, /* + 1/3 */
2227 	{ "20",		0x0015,0 },
2228 	{ "15",		0x0018,0 },
2229 	{ "13",		0x001b,0 },
2230 	{ "10",		0x001c,0 },
2231 	{ "10.3",	0x001d,0 }, /* 10.4 */
2232 	{ "8",		0x0020,0 },
2233 	{ "6.3",	0x0023,0 }, /* + 1/3 */
2234 	{ "6",		0x0024,0 },
2235 	{ "5",		0x0025,0 },
2236 	{ "4",		0x0028,0 },
2237 	{ "3.2",	0x002b,0 },
2238 	{ "3",		0x002c,0 },
2239 	{ "2.5",	0x002d,0 },
2240 	{ "2",		0x0030,0 },
2241 	{ "1.6",	0x0033,0 },
2242 	{ "1.5",	0x0034,0 },
2243 	{ "1.3",	0x0035,0 },
2244 	{ "1",		0x0038,0 },
2245 	{ "0.8",	0x003b,0 },
2246 	{ "0.7",	0x003c,0 },
2247 	{ "0.6",	0x003d,0 },
2248 	{ "0.5",	0x0040,0 },
2249 	{ "0.4",	0x0043,0 },
2250 	{ "0.3",	0x0044,0 },
2251 	{ "0.3",	0x0045,0 }, /* 1/3 */
2252 	{ "1/4",	0x0048,0 },
2253 	{ "1/5",	0x004b,0 },
2254 	{ "1/6",	0x004c,0 },
2255 	{ "1/6",	0x004d,0 }, /* 1/3? */
2256 	{ "1/8",	0x0050,0 },
2257 	{ "1/10",	0x0053,0 }, /* 1/3? */
2258 	{ "1/10",	0x0054,0 },
2259 	{ "1/13",	0x0055,0 },
2260 	{ "1/15",	0x0058,0 },
2261 	{ "1/20",	0x005b,0 }, /* 1/3? */
2262 	{ "1/20",	0x005c,0 },
2263 	{ "1/25",	0x005d,0 },
2264 	{ "1/30",	0x0060,0 },
2265 	{ "1/40",	0x0063,0 },
2266 	{ "1/45",	0x0064,0 },
2267 	{ "1/50",	0x0065,0 },
2268 	{ "1/60",	0x0068,0 },
2269 	{ "1/80",	0x006b,0 },
2270 	{ "1/90",	0x006c,0 },
2271 	{ "1/100",	0x006d,0 },
2272 	{ "1/125",	0x0070,0 },
2273 	{ "1/160",	0x0073,0 },
2274 	{ "1/180",	0x0074,0 },
2275 	{ "1/200",	0x0075,0 },
2276 	{ "1/250",	0x0078,0 },
2277 	{ "1/320",	0x007b,0 },
2278 	{ "1/350",	0x007c,0 },
2279 	{ "1/400",	0x007d,0 },
2280 	{ "1/500",	0x0080,0 },
2281 	{ "1/640",	0x0083,0 },
2282 	{ "1/750",	0x0084,0 },
2283 	{ "1/800",	0x0085,0 },
2284 	{ "1/1000",	0x0088,0 },
2285 	{ "1/1250",	0x008b,0 },
2286 	{ "1/1500",	0x008c,0 },
2287 	{ "1/1600",	0x008d,0 },
2288 	{ "1/2000",	0x0090,0 },
2289 	{ "1/2500",	0x0093,0 },
2290 	{ "1/3000",	0x0094,0 },
2291 	{ "1/3200",	0x0095,0 },
2292 	{ "1/4000",	0x0098,0 },
2293 	{ "1/5000",	0x009b,0 },
2294 	{ "1/6000",	0x009c,0 },
2295 	{ "1/6400",	0x009d,0 },
2296 	{ "1/8000",	0x00a0,0 },
2297 };
2298 GENERIC16TABLE(Canon_ShutterSpeed,canon_shutterspeed)
2299 
2300 
2301 static struct deviceproptableu16 canon_focuspoints[] = {
2302 	{ N_("Focusing Point on Center Only, Manual"),	0x1000, 0 },
2303 	{ N_("Focusing Point on Center Only, Auto"),	0x1001, 0 },
2304 	{ N_("Multiple Focusing Points (No Specification), Manual"),	0x3000, 0 },
2305 	{ N_("Multiple Focusing Points, Auto"),		0x3001, 0 },
2306 	{ N_("Multiple Focusing Points (Right)"),	0x3002, 0 },
2307 	{ N_("Multiple Focusing Points (Center)"),	0x3003, 0 },
2308 	{ N_("Multiple Focusing Points (Left)"),	0x3004, 0 },
2309 };
2310 GENERIC16TABLE(Canon_FocusingPoint,canon_focuspoints)
2311 
2312 static struct deviceproptableu8 canon_size[] = {
2313 	{ N_("Large"),		0x00, 0 },
2314 	{ N_("Medium 1"),	0x01, 0 },
2315 	{ N_("Medium 2"),	0x03, 0 },
2316 	{ N_("Medium 3"),	0x07, 0 },
2317 	{ N_("Small"),		0x02, 0 },
2318 };
2319 GENERIC8TABLE(Canon_Size,canon_size)
2320 
2321 static struct deviceproptableu8 sony_size[] = {
2322 	{ N_("Large"),		0x01, 0 },
2323 	{ N_("Medium"),		0x02, 0 },
2324 	{ N_("Small"),		0x03, 0 },
2325 };
2326 GENERIC8TABLE(Sony_ImageSize,sony_size)
2327 
2328 static struct deviceproptableu8 nikon1_size[] = {
2329 	{ N_("Small"),		0x00, 0 },
2330 	{ N_("Medium"),		0x01, 0 },
2331 	{ N_("Large"),		0x02, 0 },
2332 };
2333 GENERIC8TABLE(Nikon1_ImageSize,nikon1_size)
2334 
2335 static struct deviceproptableu8 sony_aspectratio[] = {
2336 	{ N_("3:2"),		0x01, 0 },
2337 	{ N_("16:9"),		0x02, 0 },
2338 };
2339 GENERIC8TABLE(Sony_AspectRatio,sony_aspectratio)
2340 
2341 /* values are from 6D */
2342 static struct deviceproptableu16 canon_eos_aspectratio[] = {
2343 	{ "3:2",	0x0000, 0},
2344 	{ "1:1",	0x0001, 0},
2345 	{ "4:3",	0x0002, 0},
2346 	{ "16:9",	0x0007, 0},
2347 };
2348 GENERIC16TABLE(Canon_EOS_AspectRatio,canon_eos_aspectratio)
2349 
2350 /* actually in 1/10s of a second, but only 3 values in use */
2351 static struct deviceproptableu16 canon_selftimer[] = {
2352 	{ N_("Not used"),	0,	0 },
2353 	{ N_("10 seconds"),	100,	0 },
2354 	{ N_("2 seconds"), 	20,	0 },
2355 };
2356 GENERIC16TABLE(Canon_SelfTimer,canon_selftimer)
2357 
2358 /* actually it is a flag value, 1 = TFT, 2 = PC, 4 = MOBILE, 8 = MOBILE2 */
2359 static struct deviceproptableu16 canon_eos_cameraoutput[] = {
2360 	{ N_("Off"),		0, 0 }, /*On 5DM3, LCD/TFT is off, mirror down and optical view finder enabled */
2361 	{ N_("TFT"),		1, 0 },
2362 	{ N_("PC"), 		2, 0 },
2363 	{ N_("TFT + PC"), 	3, 0 },
2364 	{ N_("MOBILE"),		4, 0 },
2365 	{ N_("TFT + MOBILE"),	5, 0 },
2366 	{ N_("PC + MOBILE"),	6, 0 },
2367 	{ N_("TFT + PC + MOBILE"), 7, 0 },
2368 	{ N_("MOBILE2"),	8, 0 },
2369 	{ N_("TFT + MOBILE2"),	9, 0 },
2370 	{ N_("PC + MOBILE2"),	10, 0 },
2371 	{ N_("TFT + PC + MOBILE2"), 11, 0 },
2372 };
2373 GENERIC16TABLE(Canon_EOS_CameraOutput,canon_eos_cameraoutput)
2374 
2375 static struct deviceproptableu16 canon_eos_evfrecordtarget[] = {
2376 	{ N_("None"),		0, 0 },
2377 	{ N_("SDRAM"),		3, 0 },
2378 	{ N_("Card"),		4, 0 },
2379 };
2380 GENERIC16TABLE(Canon_EOS_EVFRecordTarget,canon_eos_evfrecordtarget)
2381 
2382 /* values currently unknown */
2383 static struct deviceproptableu16 canon_eos_evfmode[] = {
2384 	{ "0",	0, 0 },
2385 	{ "1",	1, 0 },
2386 };
GENERIC16TABLE(Canon_EOS_EVFMode,canon_eos_evfmode)2387 GENERIC16TABLE(Canon_EOS_EVFMode,canon_eos_evfmode)
2388 
2389 #if 0 /* reimplement with viewfinder on/off below */
2390 static struct deviceproptableu8 canon_cameraoutput[] = {
2391 	{ N_("Undefined"),	0, 0 },
2392 	{ N_("LCD"),		1, 0 },
2393 	{ N_("Video OUT"), 	2, 0 },
2394 	{ N_("Off"), 		3, 0 },
2395 };
2396 GENERIC8TABLE(Canon_CameraOutput,canon_cameraoutput)
2397 #endif
2398 
2399 static int
2400 _get_Canon_CameraOutput(CONFIG_GET_ARGS) {
2401 	int i,isset=0;
2402 	char buf[30];
2403 
2404 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
2405 		return (GP_ERROR);
2406 	if (dpd->DataType != PTP_DTC_UINT8)
2407 		return (GP_ERROR);
2408 
2409 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
2410 	gp_widget_set_name (*widget, menu->name);
2411 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
2412 		char *x;
2413 
2414 		switch (dpd->FORM.Enum.SupportedValue[i].u8) {
2415 		default:sprintf(buf,_("Unknown %d"),dpd->FORM.Enum.SupportedValue[i].u8);
2416 			x=buf;
2417 			break;
2418 		case 1: x=_("LCD");break;
2419 		case 2: x=_("Video OUT");break;
2420 		case 3: x=_("Off");break;
2421 		}
2422 		gp_widget_add_choice (*widget,x);
2423 		if (dpd->FORM.Enum.SupportedValue[i].u8 == dpd->CurrentValue.u8) {
2424 			gp_widget_set_value (*widget,x);
2425 			isset = 1;
2426 		}
2427 	}
2428 	if (!isset) {
2429 		sprintf(buf,_("Unknown %d"),dpd->CurrentValue.u8);
2430 		gp_widget_set_value (*widget,buf);
2431 	}
2432 	return GP_OK;
2433 }
2434 
2435 static int
_put_Canon_CameraOutput(CONFIG_PUT_ARGS)2436 _put_Canon_CameraOutput(CONFIG_PUT_ARGS) {
2437 	int	u, i;
2438 	char	*value;
2439 	PTPParams *params = &camera->pl->params;
2440 
2441 	CR (gp_widget_get_value(widget, &value));
2442 
2443 	u = -1;
2444 	if (!strcmp(value,_("LCD"))) { u = 1; }
2445 	if (!strcmp(value,_("Video OUT"))) { u = 2; }
2446 	if (!strcmp(value,_("Off"))) { u = 3; }
2447 	if (sscanf(value,_("Unknown %d"),&i)) { u = i; }
2448 	C_PARAMS (u != -1);
2449 
2450 	if ((u==1) || (u==2)) {
2451 		if (ptp_operation_issupported(params, PTP_OC_CANON_ViewfinderOn)) {
2452 			if (!params->canon_viewfinder_on)  {
2453 				if (LOG_ON_PTP_E (ptp_canon_viewfinderon (params)) == PTP_RC_OK)
2454 					params->canon_viewfinder_on=1;
2455 			}
2456 		}
2457 	}
2458 	if (u==3) {
2459 		if (ptp_operation_issupported(params, PTP_OC_CANON_ViewfinderOff)) {
2460 			if (params->canon_viewfinder_on)  {
2461 				if (LOG_ON_PTP_E (ptp_canon_viewfinderoff (params)) == PTP_RC_OK)
2462 					params->canon_viewfinder_on=0;
2463 			}
2464 		}
2465 	}
2466 	propval->u8 = u;
2467 	return GP_OK;
2468 }
2469 
2470 static struct deviceproptableu16 canon_isospeed[] = {
2471 	{ N_("Factory Default"),0xffff, 0 },
2472 	{ "6",			0x0028, 0 },
2473 	{ "12",			0x0030, 0 },
2474 	{ "25",			0x0038, 0 },
2475 	{ "50",			0x0040, 0 },
2476 	{ "64",			0x0043, 0 },
2477 	{ "80",			0x0045, 0 },
2478 	{ "100",		0x0048, 0 },
2479 	{ "125",		0x004b, 0 },
2480 	{ "160",		0x004d, 0 },
2481 	{ "200",		0x0050, 0 },
2482 	{ "250",		0x0053, 0 },
2483 	{ "320",		0x0055, 0 },
2484 	{ "400",		0x0058, 0 },
2485 	{ "500",		0x005b, 0 },
2486 	{ "640",		0x005d, 0 },
2487 	{ "800",		0x0060, 0 },
2488 	{ "1000",		0x0063, 0 },
2489 	{ "1250",		0x0065, 0 },
2490 	{ "1600",		0x0068, 0 },
2491 	{ "2000",		0x006b, 0 },
2492 	{ "2500",		0x006d, 0 },
2493 	{ "3200",		0x0070, 0 },
2494 	{ "4000",		0x0073, 0 },
2495 	{ "5000",		0x0075, 0 },
2496 	{ "6400",		0x0078, 0 },
2497 	{ "8000",		0x007b, 0 },
2498 	{ "10000",		0x007d, 0 },
2499 	{ "12800",		0x0080, 0 },
2500 	{ "16000",		0x0083, 0 },
2501 	{ "20000",		0x0085, 0 },
2502 	{ "25600",		0x0088, 0 },
2503 	{ "32000",		0x008b, 0 },
2504 	{ "40000",		0x008d, 0 },
2505 	{ "51200",		0x0090, 0 },
2506 	{ "102400",		0x0098, 0 },
2507 	{ "204800",		0x00a0, 0 },
2508 	{ "409600",		0x00a8, 0 },
2509 	{ "819200",		0x00b0, 0 },
2510 	{ N_("Auto"),		0x0000, 0 },
2511 };
2512 GENERIC16TABLE(Canon_ISO,canon_isospeed)
2513 
2514 /* see ptp-pack.c:ptp_unpack_EOS_ImageFormat */
2515 static struct deviceproptableu16 canon_eos_image_format[] = {
2516 	{ N_("RAW"),				0x0c00, 0 },
2517 	{ N_("mRAW"),				0x1c00, 0 },
2518 	{ N_("sRAW"),				0x2c00, 0 },
2519 	{ N_("cRAW"),				0x0b00, 0 },
2520 	{ N_("Large Fine JPEG"),		0x0300, 0 },
2521 	{ N_("Large Normal JPEG"),		0x0200, 0 },
2522 	{ N_("Medium Fine JPEG"),		0x1300, 0 },
2523 	{ N_("Medium Normal JPEG"),		0x1200, 0 },
2524 	{ N_("Small Fine JPEG"),		0x2300, 0 },
2525 	{ N_("Small Normal JPEG"),		0x2200, 0 },
2526 	{ N_("Small Fine JPEG"),		0xd300, 0 },
2527 	{ N_("Small Normal JPEG"),		0xd200, 0 },
2528 	{ N_("Smaller JPEG"),			0xe300, 0 },
2529 	{ N_("Tiny JPEG"),			0xf300, 0 },
2530 	{ N_("RAW + Large Fine JPEG"),		0x0c03, 0 },
2531 	{ N_("mRAW + Large Fine JPEG"),		0x1c03, 0 },
2532 	{ N_("sRAW + Large Fine JPEG"),		0x2c03, 0 },
2533 	{ N_("cRAW + Large Fine JPEG"),		0x0b03, 0 },
2534 	{ N_("RAW + Medium Fine JPEG"),		0x0c13, 0 },
2535 	{ N_("mRAW + Medium Fine JPEG"),	0x1c13, 0 },
2536 	{ N_("sRAW + Medium Fine JPEG"),	0x2c13, 0 },
2537 	{ N_("cRAW + Medium Fine JPEG"),	0x0b13, 0 },
2538 	{ N_("RAW + Small Fine JPEG"),		0x0c23, 0 },
2539 	{ N_("RAW + Small Fine JPEG"),		0x0cd3, 0 }, /*Canon EOS 5D Mark III*/
2540 	{ N_("mRAW + Small Fine JPEG"),		0x1c23, 0 },
2541 	{ N_("mRAW + Small Fine JPEG"),		0x1cd3, 0 }, /*Canon EOS 5D Mark III*/
2542 	{ N_("sRAW + Small Fine JPEG"),		0x2c23, 0 },
2543 	{ N_("sRAW + Small Fine JPEG"),		0x2cd3, 0 }, /*Canon EOS 5D Mark III*/
2544 	{ N_("cRAW + Small Fine JPEG"),		0x0bd3, 0 },
2545 	{ N_("RAW + Large Normal JPEG"),	0x0c02, 0 },
2546 	{ N_("mRAW + Large Normal JPEG"),	0x1c02, 0 },
2547 	{ N_("sRAW + Large Normal JPEG"),	0x2c02, 0 },
2548 	{ N_("cRAW + Large Normal JPEG"),	0x0b02, 0 },
2549 	{ N_("RAW + Medium Normal JPEG"),	0x0c12, 0 },
2550 	{ N_("mRAW + Medium Normal JPEG"),	0x1c12, 0 },
2551 	{ N_("sRAW + Medium Normal JPEG"),	0x2c12, 0 },
2552 	{ N_("cRAW + Medium Normal JPEG"),	0x0b12, 0 },
2553 	{ N_("RAW + Small Normal JPEG"),	0x0c22, 0 },
2554 	{ N_("RAW + Small Normal JPEG"),	0x0cd2, 0 }, /*Canon EOS 5D Mark III*/
2555 	{ N_("mRAW + Small Normal JPEG"),	0x1c22, 0 },
2556 	{ N_("mRAW + Small Normal JPEG"),	0x1cd2, 0 }, /*Canon EOS 5D Mark III*/
2557 	{ N_("sRAW + Small Normal JPEG"),	0x2c22, 0 },
2558 	{ N_("sRAW + Small Normal JPEG"),	0x2cd2, 0 }, /*Canon EOS 5D Mark III*/
2559 	{ N_("cRAW + Small Normal JPEG"),	0x0bd2, 0 },
2560 	{ N_("RAW + Smaller JPEG"),		0x0ce3, 0 }, /*Canon EOS 5D Mark III*/
2561 	{ N_("mRAW + Smaller JPEG"),		0x1ce3, 0 }, /*Canon EOS 5D Mark III*/
2562 	{ N_("sRAW + Smaller JPEG"),		0x2ce3, 0 }, /*Canon EOS 5D Mark III*/
2563 	{ N_("cRAW + Smaller JPEG"),		0x0be3, 0 }, /*Canon EOS M50*/
2564 	{ N_("RAW + Tiny JPEG"),		0x0cf3, 0 }, /*Canon EOS 5D Mark III*/
2565 	{ N_("mRAW + Tiny JPEG"),		0x1cf3, 0 }, /*Canon EOS 5D Mark III*/
2566 	{ N_("sRAW + Tiny JPEG"),		0x2cf3, 0 }, /*Canon EOS 5D Mark III*/
2567 	/* There are more RAW + 'smallish' JPEG combinations for at least the 5DM3 possible.
2568 	   Axel was simply to lazy to exercise the combinatorial explosion. :-/ */
2569 };
2570 GENERIC16TABLE(Canon_EOS_ImageFormat,canon_eos_image_format)
2571 
2572 static struct deviceproptableu16 canon_eos_aeb[] = {
2573 	{ N_("off"),		0x0000, 0 },
2574 	{ "+/- 1/3",		0x0003, 0 },
2575 	{ "+/- 1/2",		0x0004, 0 },
2576 	{ "+/- 2/3",		0x0005, 0 },
2577 	{ "+/- 1",		0x0008, 0 },
2578 	{ "+/- 1 1/3",		0x000b, 0 },
2579 	{ "+/- 1 1/2",		0x000c, 0 },
2580 	{ "+/- 1 2/3",		0x000d, 0 },
2581 	{ "+/- 2",		0x0010, 0 },
2582 	{ "+/- 2 1/3",		0x0013, 0 },
2583 	{ "+/- 2 1/2",		0x0014, 0 },
2584 	{ "+/- 2 2/3",		0x0015, 0 },
2585 	{ "+/- 3",		0x0018, 0 },
2586 };
2587 GENERIC16TABLE(Canon_EOS_AEB,canon_eos_aeb)
2588 
2589 static struct deviceproptableu16 canon_eos_drive_mode[] = {
2590 	{ N_("Single"),			0x0000, 0 },
2591 	{ N_("Continuous"),		0x0001, 0 },
2592 	{ N_("Video"),			0x0002, 0 },
2593 	{ N_("Continuous high speed"),	0x0004, 0 },
2594 	{ N_("Continuous low speed"),	0x0005, 0 },
2595 	{ N_("Single: Silent shooting"),0x0006, 0 },
2596 	{ N_("Continuous timer"),	0x0007, 0 },
2597 	{ N_("Timer 10 sec"),		0x0010, 0 },
2598 	{ N_("Timer 2 sec"),		0x0011, 0 },
2599 	{ N_("Super high speed continuous shooting"),		0x0012, 0 },
2600 	{ N_("Single silent"),		0x0013, 0 },
2601 	{ N_("Continuous silent"),	0x0014, 0 },
2602 	{ N_("Silent HS continuous"),	0x0015, 0 },
2603 	{ N_("Silent LS continuous"),	0x0016, 0 },
2604 };
GENERIC16TABLE(Canon_EOS_DriveMode,canon_eos_drive_mode)2605 GENERIC16TABLE(Canon_EOS_DriveMode,canon_eos_drive_mode)
2606 
2607 static int
2608 _get_Olympus_ISO(CONFIG_GET_ARGS) {
2609 	int i;
2610 
2611 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
2612 		return GP_ERROR;
2613 	if (dpd->DataType != PTP_DTC_UINT16)
2614 		return GP_ERROR;
2615 
2616 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
2617 	gp_widget_set_name (*widget, menu->name);
2618 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
2619 		char	buf[20];
2620 
2621 		sprintf(buf,"%d",dpd->FORM.Enum.SupportedValue[i].u16);
2622 		if (dpd->FORM.Enum.SupportedValue[i].u16 == 0xffff) { strcpy(buf,_("Auto")); }
2623 		if (dpd->FORM.Enum.SupportedValue[i].u16 == 0xfffd) { strcpy(buf,_("Low")); }
2624 		gp_widget_add_choice (*widget,buf);
2625 		if (dpd->FORM.Enum.SupportedValue[i].u16 == dpd->CurrentValue.u16)
2626 			gp_widget_set_value (*widget,buf);
2627 	}
2628 	return GP_OK;
2629 }
2630 
2631 static int
_put_Olympus_ISO(CONFIG_PUT_ARGS)2632 _put_Olympus_ISO(CONFIG_PUT_ARGS)
2633 {
2634 	char *value;
2635 	unsigned int	u;
2636 
2637 	CR (gp_widget_get_value(widget, &value));
2638 	if (!strcmp(value,_("Auto"))) {
2639 		propval->u16 = 0xffff;
2640 		return GP_OK;
2641 	}
2642 	if (!strcmp(value,_("Low"))) {
2643 		propval->u16 = 0xfffd;
2644 		return GP_OK;
2645 	}
2646 
2647 	if (sscanf(value, "%ud", &u)) {
2648 		propval->u16 = u;
2649 		return GP_OK;
2650 	}
2651 	return GP_ERROR;
2652 }
2653 
2654 static int
_get_Olympus_OMD_Bulb(CONFIG_GET_ARGS)2655 _get_Olympus_OMD_Bulb(CONFIG_GET_ARGS) {
2656 	int val;
2657 
2658 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
2659 	gp_widget_set_name (*widget,menu->name);
2660 	val = 2; /* always changed */
2661 	gp_widget_set_value  (*widget, &val);
2662 	return (GP_OK);
2663 }
2664 
2665 static int
_put_Olympus_OMD_Bulb(CONFIG_PUT_ARGS)2666 _put_Olympus_OMD_Bulb(CONFIG_PUT_ARGS)
2667 {
2668 	PTPParams *params = &(camera->pl->params);
2669 	int val;
2670 	GPContext *context = ((PTPData *) params->data)->context;
2671 
2672 	CR (gp_widget_get_value(widget, &val));
2673 	if (val) {
2674 		int ret = ptp_olympus_omd_bulbstart (params);
2675 		if (ret == PTP_RC_GeneralError) {
2676 			gp_context_error (((PTPData *) camera->pl->params.data)->context,
2677 			_("For bulb capture to work, make sure the mode dial is switched to 'M' and set 'shutterspeed' to 'bulb'."));
2678 			return translate_ptp_result (ret);
2679 		}
2680 		C_PTP_REP (ret);
2681 	} else {
2682 		C_PTP_REP (ptp_olympus_omd_bulbend (params));
2683 	}
2684 	return GP_OK;
2685 }
2686 
2687 static struct deviceproptableu16 fuji_action[] = {
2688 	{ N_("Shoot"),			0x0304, 0 },
2689 	{ N_("Bulb On"),		0x0500, 0 },
2690 	{ N_("Bulb Off"),		0x000c, 0 },
2691 	{ N_("AF"),			0x0200, 0 },
2692 	{ N_("Cancel AF"),		0x0004, 0 },
2693 /* D208 is some kind of control, likely bitmasked. reported like an enum.
2694  * 0x200 seems to mean focusing?
2695  * 0x208 capture?
2696  * camera starts with 0x304
2697  *
2698  * After setting usually it does "initiatecapture" to trigger this mode operation.
2699  *
2700  * xt2:    0x104,0x200,0x4,0x304,0x500,0xc,0xa000,6,0x9000,2,0x9100,1,0x9300,5
2701  * xt3:    0x104,0x200,0x4,0x304,0x500,0xc,0xa000,6,0x9000,2,0x9100,1,0x9200,0x40,0x9300,5,0x804,0x80
2702  * xt30:   0x104,0x200,0x4,0x304,0x500,0xc,0xa000,6,0x9000,2,0x9100,1,0x9200,0x40,0x9300,5
2703  * xt4:    0x104,0x200,0x4,0x304,0x500,0xc,0x8000,0xa000,6,0x9000,2,0x9100,1,0x9300,5,0xe,0x9200,0x40,0x804,0x80
2704  * xh1:    0x104,0x200,0x4,0x304,0x500,0xc,0xa000,6,0x9000,2,0x9100,1,0x9300,5
2705  * gfx100: 0x104,0x200,0x4,0x304,0x500,0xc,0x8000,0xa000,6,0x9000,2,0x9100,1,0x9300,5,0xe,0x9200
2706  * gfx50r: 0x104,0x200,0x4,0x304,0x500,0xc,0xa000,6,0x9000,2,0x9100,1,0x9300,5,0xe
2707  * xpro2:  0x104,0x200,0x4,0x304,0x500,0xc,0xa000,6,0x9000,2,0x9100,1
2708  *
2709  * 0x304 is for regular capture         SDK_ShootS2toS0 (default) (SDK_Shoot)
2710  * 0x200 seems for autofocus (s1?)      SDK_ShootS1
2711  * 0x500 start bulb? 0xc end bulb?      SDK_StartBulb
2712  * 0xc                                  SDK_EndBulb
2713  * 0x600                                SDK_1PushAF
2714  * 0x4                                  SDK_CancelS1
2715  * 0x300                                SDK_ShootS2
2716  * 0x8000 migh be autowhitebalance
2717  * working bulb transition (with autofocus):
2718  * 	0x200 -> wait for d209 turn from 1 to 2 -> 0x500 -> wait BULBTIME seconds -> 0xc
2719  * seen in fuji webcam traces:
2720  * 	0x9300 -> wait for d209 turn from 1 to 2 -> 0x0005
2721  * 	0x9000 -> ? not sure, was polling with d212 ?  -> 0x0002
2722  */
2723 };
GENERIC16TABLE(Fuji_Action,fuji_action)2724 GENERIC16TABLE(Fuji_Action,fuji_action)
2725 
2726 static int
2727 _get_Fuji_AFDrive(CONFIG_GET_ARGS) {
2728 	int val;
2729 
2730 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
2731 	gp_widget_set_name (*widget,menu->name);
2732 	val = 2; /* always changed */
2733 	gp_widget_set_value  (*widget, &val);
2734 	return GP_OK;
2735 }
2736 
2737 static int
_put_Fuji_AFDrive(CONFIG_PUT_ARGS)2738 _put_Fuji_AFDrive(CONFIG_PUT_ARGS)
2739 {
2740 	PTPParams		*params = &(camera->pl->params);
2741 	GPContext		*context = ((PTPData *) params->data)->context;
2742 	PTPPropertyValue	pval;
2743 
2744 	/* Focusing first ... */
2745 	pval.u16 = 0x9300;
2746 	C_PTP_REP (ptp_setdevicepropvalue (params, 0xd208, &pval, PTP_DTC_UINT16));
2747 	C_PTP_REP (ptp_initiatecapture(params, 0x00000000, 0x00000000));
2748 
2749 	/* poll camera until it is ready */
2750 	pval.u16 = 0x0001;
2751 	while (pval.u16 == 0x0001) {
2752 		C_PTP (ptp_getdevicepropvalue (params, PTP_DPC_FUJI_AFStatus, &pval, PTP_DTC_UINT16));
2753 		GP_LOG_D ("XXX Ready to shoot? %X", pval.u16);
2754 	}
2755 
2756 	/* 2 - means OK apparently, 3 - means failed and initiatecapture will get busy. */
2757 	if (pval.u16 == 3) { /* reported on out of focus */
2758 		gp_context_error (context, _("Fuji Capture failed: Perhaps no auto-focus?"));
2759 		return GP_ERROR;
2760 	}
2761 
2762 	/* release focus lock */
2763 
2764 	pval.u16 = 0x0005;
2765 	C_PTP_REP (ptp_setdevicepropvalue (params, 0xd208, &pval, PTP_DTC_UINT16));
2766 	C_PTP_REP (ptp_initiatecapture(params, 0x00000000, 0x00000000));
2767 	return GP_OK;
2768 }
2769 
2770 static int
_get_Fuji_Bulb(CONFIG_GET_ARGS)2771 _get_Fuji_Bulb(CONFIG_GET_ARGS) {
2772 	int val;
2773 
2774 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
2775 	gp_widget_set_name (*widget,menu->name);
2776 	val = 2; /* always changed */
2777 	gp_widget_set_value  (*widget, &val);
2778 	return GP_OK;
2779 }
2780 
2781 static int
_put_Fuji_Bulb(CONFIG_PUT_ARGS)2782 _put_Fuji_Bulb(CONFIG_PUT_ARGS)
2783 {
2784 	PTPParams		*params = &(camera->pl->params);
2785 	int			val;
2786 	GPContext		*context = ((PTPData *) params->data)->context;
2787 	PTPPropertyValue	pval;
2788 
2789 	CR (gp_widget_get_value(widget, &val));
2790 	if (val) {
2791 		/* Focusing first ... */
2792 		pval.u16 = 0x0200;
2793 		C_PTP_REP (ptp_setdevicepropvalue (params, 0xd208, &pval, PTP_DTC_UINT16));
2794 		C_PTP_REP (ptp_initiatecapture(params, 0x00000000, 0x00000000));
2795 
2796 		/* poll camera until it is ready */
2797 		pval.u16 = 0x0001;
2798 		while (pval.u16 == 0x0001) {
2799 			C_PTP (ptp_getdevicepropvalue (params, PTP_DPC_FUJI_AFStatus, &pval, PTP_DTC_UINT16));
2800 			GP_LOG_D ("XXX Ready to shoot? %X", pval.u16);
2801 		}
2802 
2803 		/* 2 - means OK apparently, 3 - means failed and initiatecapture will get busy. */
2804 		if (pval.u16 == 3) { /* reported on out of focus */
2805 			gp_context_error (context, _("Fuji Capture failed: Perhaps no auto-focus?"));
2806 			return GP_ERROR;
2807 		}
2808 
2809 		/* now start bulb capture */
2810 		pval.u16 = 0x0500;
2811 		C_PTP_REP (ptp_setdevicepropvalue (params, 0xd208, &pval, PTP_DTC_UINT16));
2812 
2813 		C_PTP_REP (ptp_initiatecapture(params, 0x00000000, 0x00000000));
2814 	} else {
2815 		pval.u16 = 0x000c;
2816 		C_PTP_REP (ptp_setdevicepropvalue (params, 0xd208, &pval, PTP_DTC_UINT16));
2817 
2818 		C_PTP_REP (ptp_initiatecapture(params, 0x00000000, 0x00000000));
2819 	}
2820 	return GP_OK;
2821 }
2822 
2823 static int
_get_Sony_ISO(CONFIG_GET_ARGS)2824 _get_Sony_ISO(CONFIG_GET_ARGS) {
2825 	int	i,isset=0;
2826 	char	buf[50];
2827 
2828 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
2829 		return GP_ERROR;
2830 	if (dpd->DataType != PTP_DTC_UINT32)
2831 		return GP_ERROR;
2832 
2833 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
2834 	gp_widget_set_name (*widget, menu->name);
2835 
2836 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
2837 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0x00ffffffU) {
2838 			sprintf(buf,_("Auto ISO"));
2839 		} else if (dpd->FORM.Enum.SupportedValue[i].u32 == 0x01ffffffU) {
2840 			sprintf(buf,_("Auto ISO Multi Frame Noise Reduction"));
2841 		} else {
2842 			if (dpd->FORM.Enum.SupportedValue[i].u32 & 0xff000000) {
2843 				sprintf(buf,_("%d Multi Frame Noise Reduction"),dpd->FORM.Enum.SupportedValue[i].u32 & 0xffff);
2844 			} else {
2845 				sprintf(buf,"%d",dpd->FORM.Enum.SupportedValue[i].u32);
2846 			}
2847 		}
2848 		gp_widget_add_choice (*widget,buf);
2849 		if (dpd->FORM.Enum.SupportedValue[i].u32 == dpd->CurrentValue.u32) {
2850 			isset=1;
2851 			gp_widget_set_value (*widget,buf);
2852 		}
2853 	}
2854 	if (!isset) {
2855 		if (dpd->CurrentValue.u32 == 0x00ffffffU)
2856 			sprintf(buf,_("Auto ISO"));
2857 		else if (dpd->CurrentValue.u32 == 0x01ffffffU)
2858 			sprintf(buf,_("Auto ISO Multi Frame Noise Reduction"));
2859 		else {
2860 			if (dpd->CurrentValue.u32 & 0xff000000) {
2861 				sprintf(buf,_("%d Multi Frame Noise Reduction"),dpd->CurrentValue.u32 & 0xffff);
2862 			} else {
2863 				sprintf(buf,"%d",dpd->CurrentValue.u32);
2864 			}
2865 		}
2866 		gp_widget_set_value (*widget,buf);
2867 	}
2868 	return GP_OK;
2869 }
2870 
2871 /* old method, using stepping */
2872 static int
_put_Sony_ISO(CONFIG_PUT_ARGS)2873 _put_Sony_ISO(CONFIG_PUT_ARGS)
2874 {
2875 	char 		*value;
2876 	uint32_t	u;
2877 	PTPParams	*params = &(camera->pl->params);
2878 
2879 	CR (gp_widget_get_value(widget, &value));
2880 	if (!strcmp(value,_("Auto ISO"))) {
2881 		u = 0x00ffffff;
2882 		goto setiso;
2883 	}
2884 	if (!strcmp(value,_("Auto ISO Multi Frame Noise Reduction"))) {
2885 		u = 0x01ffffff;
2886 		goto setiso;
2887 	}
2888 
2889 	if (!sscanf(value, "%ud", &u))
2890 		return GP_ERROR;
2891 
2892 	if (strstr(value,_("Multi Frame Noise Reduction")))
2893 		u |= 0x1000000;
2894 
2895 setiso:
2896 	propval->u32 = u;
2897 
2898 	return _put_sony_value_u32(params, dpd->DevicePropertyCode, u, 1);
2899 }
2900 
2901 /* new method, can just set the value via setcontroldevicea */
2902 static int
_put_Sony_ISO2(CONFIG_PUT_ARGS)2903 _put_Sony_ISO2(CONFIG_PUT_ARGS)
2904 {
2905 	char 		*value;
2906 	uint32_t	u;
2907 	PTPParams	*params = &(camera->pl->params);
2908 
2909 	CR (gp_widget_get_value(widget, &value));
2910 	if (!strcmp(value,_("Auto ISO"))) {
2911 		u = 0x00ffffff;
2912 		goto setiso;
2913 	}
2914 	if (!strcmp(value,_("Auto ISO Multi Frame Noise Reduction"))) {
2915 		u = 0x01ffffff;
2916 		goto setiso;
2917 	}
2918 
2919 	if (!sscanf(value, "%ud", &u))
2920 		return GP_ERROR;
2921 
2922 	if (strstr(value,_("Multi Frame Noise Reduction")))
2923 		u |= 0x1000000;
2924 
2925 setiso:
2926 	propval->u32 = u;
2927 
2928 	return translate_ptp_result (ptp_sony_setdevicecontrolvaluea(params, dpd->DevicePropertyCode, propval, PTP_DTC_UINT32));
2929 }
2930 
2931 static int
_put_Sony_QX_ISO(CONFIG_PUT_ARGS)2932 _put_Sony_QX_ISO(CONFIG_PUT_ARGS)
2933 {
2934 	char 		*value;
2935 	uint32_t	u;
2936 
2937 	CR (gp_widget_get_value(widget, &value));
2938 	if (!strcmp(value,_("Auto ISO"))) {
2939 		u = 0x00ffffff;
2940 		goto setiso;
2941 	}
2942 	if (!strcmp(value,_("Auto ISO Multi Frame Noise Reduction"))) {
2943 		u = 0x01ffffff;
2944 		goto setiso;
2945 	}
2946 
2947 	if (!sscanf(value, "%ud", &u))
2948 		return GP_ERROR;
2949 
2950 	if (strstr(value,_("Multi Frame Noise Reduction")))
2951 		u |= 0x1000000;
2952 
2953 setiso:
2954 	propval->u32 = u;
2955 
2956 	/*return translate_ptp_result (ptp_sony_qx_setdevicecontrolvaluea(params, dpd->DevicePropertyCode, propval, PTP_DTC_UINT32));*/
2957 
2958 	return GP_OK; /* will be set by generic code */
2959 }
2960 
2961 
2962 static int
_get_Olympus_AspectRatio(CONFIG_GET_ARGS)2963 _get_Olympus_AspectRatio(CONFIG_GET_ARGS) {
2964 	int i;
2965 
2966 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
2967 		return GP_ERROR;
2968 	if (dpd->DataType != PTP_DTC_UINT32)
2969 		return GP_ERROR;
2970 
2971 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
2972 	gp_widget_set_name (*widget, menu->name);
2973 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
2974 		char	buf[20];
2975 
2976 		sprintf(buf,"%d:%d",(dpd->FORM.Enum.SupportedValue[i].u32 >> 16), dpd->FORM.Enum.SupportedValue[i].u32 & 0xffff);
2977 		gp_widget_add_choice (*widget,buf);
2978 		if (dpd->FORM.Enum.SupportedValue[i].u32 == dpd->CurrentValue.u32)
2979 			gp_widget_set_value (*widget,buf);
2980 	}
2981 	return GP_OK;
2982 }
2983 
2984 static int
_put_Olympus_AspectRatio(CONFIG_PUT_ARGS)2985 _put_Olympus_AspectRatio(CONFIG_PUT_ARGS)
2986 {
2987 	char		*value;
2988 	unsigned int	x,y;
2989 
2990 	CR (gp_widget_get_value(widget, &value));
2991 
2992 	if (2 == sscanf(value, "%d:%d", &x, &y)) {
2993 		propval->u32 = (x<<16) | y;
2994 		return GP_OK;
2995 	}
2996 	return GP_ERROR;
2997 }
2998 
2999 
3000 static int
_get_Milliseconds(CONFIG_GET_ARGS)3001 _get_Milliseconds(CONFIG_GET_ARGS) {
3002 	unsigned int i, min, max;
3003 
3004 	if (!(dpd->FormFlag & (PTP_DPFF_Range|PTP_DPFF_Enumeration)))
3005 		return (GP_ERROR);
3006 	if ((dpd->DataType != PTP_DTC_UINT32) && (dpd->DataType != PTP_DTC_UINT16))
3007 		return (GP_ERROR);
3008 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
3009 	gp_widget_set_name (*widget, menu->name);
3010 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
3011 		unsigned int t;
3012 
3013 		if (dpd->DataType == PTP_DTC_UINT32)
3014 			t = dpd->CurrentValue.u32;
3015 		else
3016 			t = dpd->CurrentValue.u16;
3017 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3018 			char	buf[20];
3019 			unsigned int x;
3020 
3021 			if (dpd->DataType == PTP_DTC_UINT32)
3022 				x = dpd->FORM.Enum.SupportedValue[i].u32;
3023 			else
3024 				x = dpd->FORM.Enum.SupportedValue[i].u16;
3025 
3026 			sprintf(buf,"%0.3fs",x/1000.0);
3027 			gp_widget_add_choice (*widget,buf);
3028 			if (x == t)
3029 				gp_widget_set_value (*widget,buf);
3030 		}
3031 	}
3032 	if (dpd->FormFlag & PTP_DPFF_Range) {
3033 		unsigned int s;
3034 
3035 		if (dpd->DataType == PTP_DTC_UINT32) {
3036 			min = dpd->FORM.Range.MinimumValue.u32;
3037 			max = dpd->FORM.Range.MaximumValue.u32;
3038 			s = dpd->FORM.Range.StepSize.u32;
3039 		} else {
3040 			min = dpd->FORM.Range.MinimumValue.u16;
3041 			max = dpd->FORM.Range.MaximumValue.u16;
3042 			s = dpd->FORM.Range.StepSize.u16;
3043 		}
3044 		for (i=min; i<=max; i+=s) {
3045 			char buf[20];
3046 
3047 			sprintf (buf, "%0.3fs", i/1000.0);
3048 			CR (gp_widget_add_choice (*widget, buf));
3049 			if (	((dpd->DataType == PTP_DTC_UINT32) && (dpd->CurrentValue.u32 == i)) ||
3050 				((dpd->DataType == PTP_DTC_UINT16) && (dpd->CurrentValue.u16 == i))
3051 			   )
3052 				CR (gp_widget_set_value (*widget, buf));
3053 
3054 			/* device might report stepsize 0. but we do at least 1 round */
3055 			if (s == 0)
3056 				break;
3057 		}
3058 
3059 	}
3060 	return GP_OK;
3061 }
3062 
3063 static int
_put_Milliseconds(CONFIG_PUT_ARGS)3064 _put_Milliseconds(CONFIG_PUT_ARGS)
3065 {
3066 	char *value;
3067 	float	f;
3068 
3069 	CR (gp_widget_get_value(widget, &value));
3070 
3071 	if (sscanf(value, "%f", &f)) {
3072 		if (dpd->DataType == PTP_DTC_UINT32)
3073 			propval->u32 = f*1000;
3074 		else
3075 			propval->u16 = f*1000;
3076 		return GP_OK;
3077 	}
3078 	return GP_ERROR;
3079 }
3080 
3081 static int
_get_FNumber(CONFIG_GET_ARGS)3082 _get_FNumber(CONFIG_GET_ARGS) {
3083 	int i;
3084 
3085 	GP_LOG_D ("get_FNumber");
3086 	if (!(dpd->FormFlag & (PTP_DPFF_Enumeration|PTP_DPFF_Range)))
3087 		return (GP_ERROR);
3088 	if (dpd->DataType != PTP_DTC_UINT16)
3089 		return (GP_ERROR);
3090 
3091 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
3092 		gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
3093 		gp_widget_set_name (*widget, menu->name);
3094 
3095 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3096 			char	buf[20];
3097 
3098 			sprintf(buf,"f/%g",(dpd->FORM.Enum.SupportedValue[i].u16*1.0)/100.0);
3099 			gp_widget_add_choice (*widget,buf);
3100 			if (dpd->FORM.Enum.SupportedValue[i].u16 == dpd->CurrentValue.u16)
3101 				gp_widget_set_value (*widget,buf);
3102 		}
3103 		GP_LOG_D ("get_FNumber via enum");
3104 	} else { /* Range */
3105 		float value_float;
3106 
3107 		gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
3108 		gp_widget_set_name (*widget, menu->name);
3109 		gp_widget_set_range (*widget,
3110 				dpd->FORM.Range.MinimumValue.u16/100.0,
3111 				dpd->FORM.Range.MaximumValue.u16/100.0,
3112 				dpd->FORM.Range.StepSize.u16/100.0
3113 				);
3114 		value_float = dpd->CurrentValue.u16/100.0;
3115 		gp_widget_set_value (*widget, &value_float);
3116 		GP_LOG_D ("get_FNumber via float");
3117 	}
3118 	return GP_OK;
3119 }
3120 
3121 static int
_put_FNumber(CONFIG_PUT_ARGS)3122 _put_FNumber(CONFIG_PUT_ARGS)
3123 {
3124 	int i;
3125 
3126 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
3127 		char	*value;
3128 		float	f;
3129 
3130 		CR (gp_widget_get_value(widget, &value));
3131 		if (strstr (value, "f/") == value)
3132 			value += strlen("f/");
3133 
3134 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3135 			char	buf[20];
3136 
3137 			sprintf(buf,"%g",(dpd->FORM.Enum.SupportedValue[i].u16*1.0)/100.0);
3138 			if (!strcmp (buf, value)) {
3139 				propval->u16 = dpd->FORM.Enum.SupportedValue[i].u16;
3140 				return GP_OK;
3141 			}
3142 		}
3143 		if (sscanf(value, "%g", &f)) {
3144 			propval->u16 = f*100;
3145 			return GP_OK;
3146 		}
3147 	} else { /* RANGE uses float */
3148 		float fvalue;
3149 
3150 		CR (gp_widget_get_value (widget, &fvalue));
3151 		propval->u16 = fvalue*100;
3152 		return GP_OK;
3153 	}
3154 	return GP_ERROR;
3155 }
3156 
3157 static int
_put_Sony_FNumber(CONFIG_PUT_ARGS)3158 _put_Sony_FNumber(CONFIG_PUT_ARGS)
3159 {
3160 	float			fvalue;
3161 	PTPParams		*params = &(camera->pl->params);
3162 
3163 	CR (gp_widget_get_value (widget, &fvalue));
3164 
3165 	propval->u16 = fvalue*100; /* probably not used */
3166 	return _put_sony_value_u16 (params, PTP_DPC_FNumber, fvalue*100, 0);
3167 }
3168 
3169 static int
_put_Sony_QX_FNumber(CONFIG_PUT_ARGS)3170 _put_Sony_QX_FNumber(CONFIG_PUT_ARGS)
3171 {
3172 	float			fvalue;
3173 
3174 	CR (gp_widget_get_value (widget, &fvalue));
3175 
3176 	propval->u16 = fvalue*100;
3177 	/*return translate_ptp_result (ptp_sony_qx_setdevicecontrolvaluea (&camera->pl->params, dpd->DevicePropertyCode, propval, PTP_DTC_UINT16)); */
3178 	return GP_OK; /* will be handled by generic setter going to QX stter */
3179 }
3180 
3181 static int
_get_ExpTime(CONFIG_GET_ARGS)3182 _get_ExpTime(CONFIG_GET_ARGS) {
3183 	int		i;
3184 	PTPParams	*params = &(camera->pl->params);
3185 
3186 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
3187 		return (GP_ERROR);
3188 	if (dpd->DataType != PTP_DTC_UINT32)
3189 		return (GP_ERROR);
3190 
3191 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
3192 	gp_widget_set_name (*widget, menu->name);
3193 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3194 		char	buf[20];
3195 
3196 		if (params->deviceinfo.VendorExtensionID == PTP_VENDOR_NIKON) {
3197 			if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xffffffff) {
3198 				sprintf(buf,_("Bulb"));
3199 				goto choicefound;
3200 			}
3201 			if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xfffffffd) {
3202 				sprintf(buf,_("Time"));
3203 				goto choicefound;
3204 			}
3205 		}
3206 		sprintf (buf,_("%0.4fs"), (1.0*dpd->FORM.Enum.SupportedValue[i].u32)/10000.0);
3207 choicefound:
3208 		gp_widget_add_choice (*widget,buf);
3209 		if (dpd->FORM.Enum.SupportedValue[i].u32 == dpd->CurrentValue.u32)
3210 			gp_widget_set_value (*widget,buf);
3211 	}
3212 	return (GP_OK);
3213 }
3214 
3215 static int
_put_ExpTime(CONFIG_PUT_ARGS)3216 _put_ExpTime(CONFIG_PUT_ARGS)
3217 {
3218 	unsigned int	i, delta, xval, ival1, ival2, ival3;
3219 	float		val;
3220 	char		*value;
3221 	PTPParams	*params = &(camera->pl->params);
3222 
3223 	CR (gp_widget_get_value (widget, &value));
3224 
3225 	if (params->deviceinfo.VendorExtensionID == PTP_VENDOR_NIKON) {
3226 		if (!strcmp(value,_("Bulb"))) {
3227 			propval->u32 = 0xffffffff;
3228 			return GP_OK;
3229 		}
3230 		if (!strcmp(value,_("Time"))) {
3231 			propval->u32 = 0xfffffffd;
3232 			return GP_OK;
3233 		}
3234 	}
3235 
3236 	if (sscanf(value,_("%d %d/%d"),&ival1,&ival2,&ival3) == 3) {
3237 		GP_LOG_D ("%d %d/%d case", ival1, ival2, ival3);
3238 		val = ((float)ival1) + ((float)ival2/(float)ival3);
3239 	} else if (sscanf(value,_("%d/%d"),&ival1,&ival2) == 2) {
3240 		GP_LOG_D ("%d/%d case", ival1, ival2);
3241 		val = (float)ival1/(float)ival2;
3242 	} else if (!sscanf(value,_("%f"),&val)) {
3243 		GP_LOG_E ("failed to parse: %s", value);
3244 		return (GP_ERROR);
3245 	} else
3246 		GP_LOG_D ("%fs case", val);
3247 	val = val*10000.0;
3248 	delta = 1000000;
3249 	xval = val;
3250 	/* match the closest value */
3251 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3252 		/*GP_LOG_D ("delta is currently %d, val is %f, supval is %u, abs is %u",delta,val,dpd->FORM.Enum.SupportedValue[i].u32,abs(val - dpd->FORM.Enum.SupportedValue[i].u32));*/
3253 		if (abs((int)(val - dpd->FORM.Enum.SupportedValue[i].u32))<delta) {
3254 			xval = dpd->FORM.Enum.SupportedValue[i].u32;
3255 			delta = abs((int)(val - dpd->FORM.Enum.SupportedValue[i].u32));
3256 		}
3257 	}
3258 	GP_LOG_D ("value %s is %f, closest match was %d",value,val,xval);
3259 	propval->u32 = xval;
3260 	return GP_OK;
3261 }
3262 
3263 static int
_get_Video_Framerate(CONFIG_GET_ARGS)3264 _get_Video_Framerate(CONFIG_GET_ARGS) {
3265 	char		buf[20];
3266 
3267 	if (dpd->DataType != PTP_DTC_UINT32)
3268 		return GP_ERROR;
3269 
3270 	if (dpd->FormFlag == PTP_DPFF_Enumeration) {
3271 		gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
3272 		/* value will be set below */
3273 	} else {
3274 		if (dpd->FormFlag == PTP_DPFF_Range) {
3275 			gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
3276 			float val = dpd->CurrentValue.u32 / 1000000.0;
3277 			gp_widget_set_value (*widget, &val);
3278 		} else {
3279 			gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
3280 			sprintf (buf, "%0.4f", (1.0*dpd->CurrentValue.u32) / 1000000.0);
3281 			gp_widget_set_value (*widget, buf);
3282 		}
3283 	}
3284 
3285 	gp_widget_set_name (*widget, menu->name);
3286 
3287 	if (dpd->FormFlag == PTP_DPFF_Enumeration) {
3288 		int		i;
3289 
3290 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3291 			sprintf (buf,"%0.4f", (1.0*dpd->FORM.Enum.SupportedValue[i].u32)/1000000.0);
3292 			gp_widget_add_choice (*widget,buf);
3293 			if (dpd->FORM.Enum.SupportedValue[i].u32 == dpd->CurrentValue.u32)
3294 				gp_widget_set_value (*widget,buf);
3295 		}
3296 	}
3297 	if (dpd->FormFlag == PTP_DPFF_Range) {
3298 		float b, t, s;
3299 
3300 		b = (1.0*dpd->FORM.Range.MinimumValue.u32) / 1000000.0;
3301 		t = (1.0*dpd->FORM.Range.MaximumValue.u32) / 1000000.0;
3302 		s = (1.0*dpd->FORM.Range.StepSize.u32) / 1000000.0;
3303 		gp_widget_set_range (*widget, b, t, s);
3304 	}
3305 	return GP_OK;
3306 }
3307 
3308 static int
_put_Video_Framerate(CONFIG_PUT_ARGS)3309 _put_Video_Framerate(CONFIG_PUT_ARGS)
3310 {
3311 	float		val;
3312 	char		*value;
3313 
3314 	if (dpd->FormFlag == PTP_DPFF_Range) {
3315 		CR (gp_widget_get_value (widget, &val));
3316 	} else {
3317 		CR (gp_widget_get_value (widget, &value));
3318 
3319 		if (!sscanf(value,_("%f"),&val)) {
3320 			GP_LOG_E ("failed to parse: %s", value);
3321 			return GP_ERROR;
3322 		}
3323 	}
3324 	propval->u32 = val * 1000000;
3325 	return GP_OK;
3326 }
3327 
3328 static int
_get_Sharpness(CONFIG_GET_ARGS)3329 _get_Sharpness(CONFIG_GET_ARGS) {
3330 	int i, min, max, t;
3331 
3332 	if (!(dpd->FormFlag & (PTP_DPFF_Enumeration|PTP_DPFF_Range)))
3333 		return (GP_ERROR);
3334 	if ((dpd->DataType != PTP_DTC_UINT8) && (dpd->DataType != PTP_DTC_INT8))
3335 		return (GP_ERROR);
3336 
3337 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
3338 	gp_widget_set_name (*widget, menu->name);
3339 
3340 	if (dpd->FormFlag & PTP_DPFF_Range) {
3341 		int s;
3342 
3343 		if (dpd->DataType == PTP_DTC_UINT8) {
3344 			min = dpd->FORM.Range.MinimumValue.u8;
3345 			max = dpd->FORM.Range.MaximumValue.u8;
3346 			s = dpd->FORM.Range.StepSize.u8;
3347 		} else {
3348 			min = dpd->FORM.Range.MinimumValue.i8;
3349 			max = dpd->FORM.Range.MaximumValue.i8;
3350 			s = dpd->FORM.Range.StepSize.i8;
3351 		}
3352 		if (!s) {
3353 			gp_widget_set_value (*widget, "invalid range, stepping 0");
3354 			return GP_OK;
3355 		}
3356 		for (i=min; i<=max; i+=s) {
3357 			char buf[20];
3358 
3359 			if (max != min)
3360 				sprintf (buf, "%d%%", (i-min)*100/(max-min));
3361 			else
3362 				strcpy (buf, "range max=min?");
3363 			gp_widget_add_choice (*widget, buf);
3364 			if (	((dpd->DataType == PTP_DTC_UINT8) && (dpd->CurrentValue.u8 == i)) ||
3365 				((dpd->DataType == PTP_DTC_INT8)  && (dpd->CurrentValue.i8 == i))
3366 			)
3367 				gp_widget_set_value (*widget, buf);
3368 		}
3369 	}
3370 
3371 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
3372 		min = 256;
3373 		max = -256;
3374 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3375 			if (dpd->DataType == PTP_DTC_UINT8) {
3376 				if (dpd->FORM.Enum.SupportedValue[i].u8 < min)
3377 					min = dpd->FORM.Enum.SupportedValue[i].u8;
3378 				if (dpd->FORM.Enum.SupportedValue[i].u8 > max)
3379 					max = dpd->FORM.Enum.SupportedValue[i].u8;
3380 			} else {
3381 				if (dpd->FORM.Enum.SupportedValue[i].i8 < min)
3382 					min = dpd->FORM.Enum.SupportedValue[i].i8;
3383 				if (dpd->FORM.Enum.SupportedValue[i].i8 > max)
3384 					max = dpd->FORM.Enum.SupportedValue[i].i8;
3385 			}
3386 		}
3387 		if (dpd->DataType == PTP_DTC_UINT8)
3388 			t = dpd->CurrentValue.u8;
3389 		else
3390 			t = dpd->CurrentValue.i8;
3391 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3392 			char buf[20];
3393 			int x;
3394 
3395 			if (dpd->DataType == PTP_DTC_UINT8)
3396 				x = dpd->FORM.Enum.SupportedValue[i].u8;
3397 			else
3398 				x = dpd->FORM.Enum.SupportedValue[i].i8;
3399 
3400 			if (max != min)
3401 				sprintf (buf, "%d%%", (x-min)*100/(max-min));
3402 			else
3403 				strcpy (buf, "range max=min?");
3404 			gp_widget_add_choice (*widget, buf);
3405 			if (t == x)
3406 				gp_widget_set_value (*widget, buf);
3407 		}
3408 	}
3409 	return (GP_OK);
3410 }
3411 
3412 static int
_put_Sharpness(CONFIG_PUT_ARGS)3413 _put_Sharpness(CONFIG_PUT_ARGS) {
3414 	const char *val;
3415 	int i, min, max, x;
3416 
3417 	gp_widget_get_value (widget, &val);
3418 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
3419 		min = 256;
3420 		max = -256;
3421 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3422 			if (dpd->DataType == PTP_DTC_UINT8) {
3423 				if (dpd->FORM.Enum.SupportedValue[i].u8 < min)
3424 					min = dpd->FORM.Enum.SupportedValue[i].u8;
3425 				if (dpd->FORM.Enum.SupportedValue[i].u8 > max)
3426 					max = dpd->FORM.Enum.SupportedValue[i].u8;
3427 			} else {
3428 				if (dpd->FORM.Enum.SupportedValue[i].i8 < min)
3429 					min = dpd->FORM.Enum.SupportedValue[i].i8;
3430 				if (dpd->FORM.Enum.SupportedValue[i].i8 > max)
3431 					max = dpd->FORM.Enum.SupportedValue[i].i8;
3432 			}
3433 		}
3434 		for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
3435 			char buf[20];
3436 
3437 			if (dpd->DataType == PTP_DTC_UINT8)
3438 				x = dpd->FORM.Enum.SupportedValue[i].u8;
3439 			else
3440 				x = dpd->FORM.Enum.SupportedValue[i].i8;
3441 
3442 			sprintf (buf, "%d%%", (x-min)*100/(max-min));
3443 			if (!strcmp(buf, val)) {
3444 				if (dpd->DataType == PTP_DTC_UINT8)
3445 					propval->u8 = x;
3446 				else
3447 					propval->i8 = x;
3448 				return GP_OK;
3449 			}
3450 		}
3451 	}
3452 	if (dpd->FormFlag & PTP_DPFF_Range) {
3453 		int s;
3454 
3455 		if (dpd->DataType == PTP_DTC_UINT8) {
3456 			min = dpd->FORM.Range.MinimumValue.u8;
3457 			max = dpd->FORM.Range.MaximumValue.u8;
3458 			s = dpd->FORM.Range.StepSize.u8;
3459 		} else {
3460 			min = dpd->FORM.Range.MinimumValue.i8;
3461 			max = dpd->FORM.Range.MaximumValue.i8;
3462 			s = dpd->FORM.Range.StepSize.i8;
3463 		}
3464 		for (i=min; i<=max; i+=s) {
3465 			char buf[20];
3466 
3467 			sprintf (buf, "%d%%", (i-min)*100/(max-min));
3468 			if (strcmp (buf, val)) {
3469 				if (s == 0)
3470 					break;
3471 				continue;
3472 			}
3473 			if (dpd->DataType == PTP_DTC_UINT8)
3474 				propval->u8 = i;
3475 			else
3476 				propval->i8 = i;
3477 			return GP_OK;
3478 		}
3479 	}
3480 	return GP_ERROR;
3481 }
3482 
3483 
3484 static struct deviceproptableu16 exposure_program_modes[] = {
3485 	{ "M",			0x0001, 0 },
3486 	{ "P",			0x0002, 0 },
3487 	{ "A",			0x0003, 0 },
3488 	{ "S",			0x0004, 0 },
3489 	{ N_("Creative"),	0x0005, 0 },
3490 	{ N_("Action"),		0x0006, 0 },
3491 	{ N_("Portrait"),	0x0007, 0 },
3492 	{ N_("Auto"),		0x8010, PTP_VENDOR_NIKON},
3493 	{ N_("Portrait"),	0x8011, PTP_VENDOR_NIKON},
3494 	{ N_("Landscape"),	0x8012, PTP_VENDOR_NIKON},
3495 	{ N_("Macro"),		0x8013, PTP_VENDOR_NIKON},
3496 	{ N_("Sports"),		0x8014, PTP_VENDOR_NIKON},
3497 	{ N_("Night Portrait"),	0x8015, PTP_VENDOR_NIKON},
3498 	{ N_("Night Landscape"),0x8016, PTP_VENDOR_NIKON},
3499 	{ N_("Children"),	0x8017, PTP_VENDOR_NIKON},
3500 	{ N_("Automatic (No Flash)"),	0x8018, PTP_VENDOR_NIKON},
3501 
3502 	{ N_("Intelligent Auto"),		0x8000, PTP_VENDOR_SONY},
3503 	{ N_("Superior Auto"),			0x8001, PTP_VENDOR_SONY},
3504 	{ N_("Movie"),				0x8050, PTP_VENDOR_SONY},
3505 	{ N_("Tele-zoom Cont. Priority AE"),	0x8031, PTP_VENDOR_SONY},
3506 	{ N_("Sweep Panorama"),			0x8041, PTP_VENDOR_SONY},
3507 	{ N_("Intelligent Auto Flash Off"),	0x8060, PTP_VENDOR_SONY},
3508 	{ N_("Sports Action"),			0x8011, PTP_VENDOR_SONY},
3509 	{ N_("Macro"),				0x8015, PTP_VENDOR_SONY},
3510 	{ N_("Landscape"),			0x8014, PTP_VENDOR_SONY},
3511 	{ N_("Sunset"),				0x8012, PTP_VENDOR_SONY},
3512 	{ N_("Night Scene"),			0x8013, PTP_VENDOR_SONY},
3513 	{ N_("Hand-held Twilight"),		0x8016, PTP_VENDOR_SONY},
3514 	{ N_("Night Portrait"),			0x8017, PTP_VENDOR_SONY},
3515 	{ N_("Picture Effect"),			0x8070, PTP_VENDOR_SONY},
3516 	{ N_("S&Q"),				0x8084, PTP_VENDOR_SONY}, /* on A7III */
3517 };
3518 GENERIC16TABLE(ExposureProgram,exposure_program_modes)
3519 
3520 static struct deviceproptableu8 nikon_scenemode[] = {
3521 	{ N_("Night landscape"),	0, 0 },
3522 	{ N_("Party/Indoor"),		1, 0 },
3523 	{ N_("Beach/Snow"),		2, 0 },
3524 	{ N_("Sunset"),			3, 0 },
3525 	{ N_("Dusk/Dawn"),		4, 0 },
3526 	{ N_("Pet Portrait"),		5, 0 },
3527 	{ N_("Candlelight"),		6, 0 },
3528 	{ N_("Blossom"),		7, 0 },
3529 	{ N_("Autumn colors"),		8, 0 },
3530 	{ N_("Food"),			9, 0 },
3531 	/* ? */
3532 	{ N_("Portrait"),		13, 0 },
3533 	{ N_("Landscape"),		14, 0 },
3534 	{ N_("Child"),			15, 0 },
3535 	{ N_("Sports"),			16, 0 },
3536 	{ N_("Close up"),		17, 0 },
3537 	{ N_("Night Portrait"),		18, 0 },
3538 
3539 };
3540 GENERIC8TABLE(NIKON_SceneMode,nikon_scenemode);
3541 
3542 /* Nikon 1 S1 specials in here */
3543 static struct deviceproptableu8 nikon_1_j3_iso[] = {
3544 	/* values from a J3 */
3545 	{ N_("A6400 (160-6400)"),	0x01, 0 },
3546 	{ N_("A3200 (160-3200)"),	0x02, 0 },
3547 	{ N_("A800 (160-800)"),		0x03, 0 },
3548 
3549 	/* these same same for all 1 */
3550 	{ "100",	0x0a, 0 },
3551 	{ "110",	0x0b, 0 },
3552 	{ "125",	0x0c, 0 },
3553 	{ "140",	0x0d, 0 },
3554 	{ "160",	0x0e, 0 },
3555 	{ "180",	0x0f, 0 },
3556 	{ "200",	0x10, 0 },
3557 	{ "220",	0x11, 0 },
3558 	{ "250",	0x12, 0 },
3559 	{ "280",	0x13, 0 },
3560 	{ "320",	0x14, 0 },
3561 	{ "360",	0x15, 0 },
3562 	{ "400",	0x16, 0 },
3563 	{ "400",	0x16, 0 },
3564 	{ "450",	0x17, 0 },
3565 	{ "500",	0x18, 0 },
3566 	{ "560",	0x19, 0 },
3567 	{ "640",	0x1a, 0 },
3568 	{ "720",	0x1b, 0 },
3569 	{ "800",	0x1c, 0 },
3570 	{ "900",	0x1d, 0 },
3571 	{ "1000",	0x1e, 0 },
3572 	{ "1100",	0x1f, 0 },
3573 	{ "1250",	0x20, 0 },
3574 	{ "1400",	0x21, 0 },
3575 	{ "1600",	0x22, 0 },
3576 	{ "1800",	0x23, 0 },
3577 	{ "2000",	0x24, 0 },
3578 	{ "2200",	0x25, 0 },
3579 	{ "2500",	0x26, 0 },
3580 	{ "2800",	0x27, 0 },
3581 	{ "3200",	0x28, 0 },
3582 	{ "6400",	0x2e, 0 },
3583 	/* more unknown values */
3584 };
3585 GENERIC8TABLE(Nikon_1_J3_ISO,nikon_1_j3_iso);
3586 
3587 /* Nikon 1 S1 specials in here */
3588 static struct deviceproptableu8 nikon_1_s1_iso[] = {
3589 	{ "100",	0x0a, 0 },
3590 	{ "110",	0x0b, 0 },
3591 	{ "125",	0x0c, 0 },
3592 	{ "140",	0x0d, 0 },
3593 	{ "160",	0x0e, 0 },
3594 	{ "180",	0x0f, 0 },
3595 	{ "200",	0x10, 0 },
3596 	{ "220",	0x11, 0 },
3597 	{ "250",	0x12, 0 },
3598 	{ "280",	0x13, 0 },
3599 	{ "320",	0x14, 0 },
3600 	{ "360",	0x15, 0 },
3601 	{ "400",	0x16, 0 },
3602 	{ "450",	0x17, 0 },
3603 	{ "500",	0x18, 0 },
3604 	{ "560",	0x19, 0 },
3605 	{ "640",	0x1a, 0 },
3606 	{ "720",	0x1b, 0 },
3607 	{ "800",	0x1c, 0 },
3608 	{ "900",	0x1d, 0 },
3609 	{ "1000",	0x1e, 0 },
3610 	{ "1100",	0x1f, 0 },
3611 	{ "1250",	0x20, 0 },
3612 	{ "1400",	0x21, 0 },
3613 	{ "1600",	0x22, 0 },
3614 	{ "1800",	0x23, 0 },
3615 	{ "2000",	0x24, 0 },
3616 	{ "2200",	0x25, 0 },
3617 	{ "2500",	0x26, 0 },
3618 	{ "2800",	0x27, 0 },
3619 	{ "3200",	0x28, 0 },
3620 	{ "6400",	0x2e, 0 },
3621 };
3622 GENERIC8TABLE(Nikon_1_S1_ISO,nikon_1_s1_iso);
3623 
3624 /* Generic Nikon 1 ISO */
3625 static struct deviceproptableu8 nikon_1_iso[] = {
3626 	{ "ISO Auto 6400",	0x01, 0 },
3627 	{ "ISO Auto 3200",	0x02, 0 },
3628 	{ "ISO Auto 800",	0x03, 0 },
3629 	{ "110",	0x0b, 0 },
3630 	{ "125",	0x0c, 0 },
3631 	{ "140",	0x0d, 0 },
3632 	{ "160",	0x0e, 0 },
3633 	{ "180",	0x0f, 0 },
3634 	{ "200",	0x10, 0 },
3635 	{ "220",	0x11, 0 },
3636 	{ "250",	0x12, 0 },
3637 	{ "280",	0x13, 0 },
3638 	{ "320",	0x14, 0 },
3639 	{ "360",	0x15, 0 },
3640 	{ "400",	0x16, 0 },
3641 	{ "450",	0x17, 0 },
3642 	{ "500",	0x18, 0 },
3643 	{ "560",	0x19, 0 },
3644 	{ "640",	0x1a, 0 },
3645 	{ "720",	0x1b, 0 },
3646 	{ "800",	0x1c, 0 },
3647 	{ "900",	0x1d, 0 },
3648 	{ "1000",	0x1e, 0 },
3649 	{ "1100",	0x1f, 0 },
3650 	{ "1250",	0x20, 0 },
3651 	{ "1400",	0x21, 0 },
3652 	{ "1600",	0x22, 0 },
3653 	{ "1800",	0x23, 0 },
3654 	{ "2000",	0x24, 0 },
3655 	{ "2200",	0x25, 0 },
3656 	{ "2500",	0x26, 0 },
3657 	{ "2800",	0x27, 0 },
3658 	{ "3200",	0x28, 0 },
3659 	{ "6400",	0x2e, 0 },
3660 };
3661 GENERIC8TABLE(Nikon_1_ISO,nikon_1_iso);
3662 
3663 static struct deviceproptableu8 nikon_1_whitebalance[] = {
3664 	/* values from a J3 */
3665 	{ N_("Auto"),			0x00, 0 },
3666 	{ N_("Tungsten"),		0x01, 0 },
3667 	{ N_("Fluorescent"),		0x02, 0 },
3668 	{ N_("Daylight"),		0x03, 0 },
3669 	{ N_("Flash"),			0x04, 0 },
3670 	{ N_("Cloudy"),			0x05, 0 },
3671 	{ N_("Shade"),			0x06, 0 },
3672 
3673 	/* these are not in the enum range on the j3 ... but reported? */
3674 	{ N_("Water"),			0x0a, 0 },
3675 	{ N_("Preset"),			0x08, 0 },
3676 };
3677 GENERIC8TABLE(Nikon_1_WhiteBalance,nikon_1_whitebalance);
3678 
3679 static struct deviceproptableu8 nikon_hdrhighdynamic[] = {
3680 	{ N_("Auto"),	0, 0 },
3681 	{ N_("1 EV"),	1, 0 },
3682 	{ N_("2 EV"),	2, 0 },
3683 	{ N_("3 EV"),	3, 0 },
3684 };
3685 GENERIC8TABLE(Nikon_HDRHighDynamic,nikon_hdrhighdynamic);
3686 
3687 static struct deviceproptableu8 nikon_aebracketstep[] = {
3688 	{ N_("1/3 EV"),	0, 0 },
3689 	{ N_("1/2 EV"),	1, 0 },
3690 	{ N_("2/3 EV"),	2, 0 },
3691 	{ N_("1 EV"),	3, 0 },
3692 	{ N_("2 EV"),	4, 0 },
3693 	{ N_("3 EV"),	5, 0 },
3694 };
3695 GENERIC8TABLE(Nikon_AEBracketStep,nikon_aebracketstep);
3696 
3697 static struct deviceproptableu8 nikon_wbbracketstep[] = {
3698 	{ N_("1 EV"),	0, 0 },
3699 	{ N_("2 EV"),	1, 0 },
3700 	{ N_("3 EV"),	2, 0 },
3701 };
3702 GENERIC8TABLE(Nikon_WBBracketStep,nikon_wbbracketstep);
3703 
3704 static struct deviceproptableu8 nikon_adlbracketstep[] = {
3705 	{ N_("Auto"),		0, 0 },
3706 	{ N_("Low"),		1, 0 },
3707 	{ N_("Normal"),		2, 0 },
3708 	{ N_("High"),		3, 0 },
3709 	{ N_("Extra high"),	4, 0 },
3710 };
3711 GENERIC8TABLE(Nikon_ADLBracketStep,nikon_adlbracketstep);
3712 
3713 static struct deviceproptableu8 nikon_bracketpattern[] = {
3714 	{ N_("2 images (normal and under)"),			0, 0 },
3715 	{ N_("2 images (normal and over)"),			1, 0 },
3716 	{ N_("3 images (normal and 2 unders)"),			2, 0 },
3717 	{ N_("3 images (normal and 2 overs)"),			3, 0 },
3718 	{ N_("3 images (normal, under and over)"),		4, 0 },
3719 	{ N_("5 images (normal, 2 unders and 2 overs)"),	5, 0 },
3720 	{ N_("7 images (normal, 3 unders and 3 overs)"),	6, 0 },
3721 	{ N_("9 images (normal, 4 unders and 4 overs)"),	7, 0 },
3722 	{ N_("0 image"),					8, 0 },
3723 };
3724 GENERIC8TABLE(Nikon_BracketPattern,nikon_bracketpattern);
3725 
3726 static struct deviceproptableu8 nikon_adlbracketpattern[] = {
3727 	{ N_("2 shots (Off -> User setting)"),				0, 0 },
3728 	{ N_("3 shots (Off -> Low -> User setting)"),			1, 0 },
3729 	{ N_("4 shots (Off -> Low -> Normal -> High)"),			2, 0 },
3730 	{ N_("5 shots (Off -> Low -> Normal -> High -> Extra High)"),	3, 0 },
3731 	{ N_("0 image"),						4, 0 },
3732 };
3733 GENERIC8TABLE(Nikon_ADLBracketPattern,nikon_adlbracketpattern);
3734 
3735 static struct deviceproptableu8 nikon_hdrsmoothing[] = {
3736 	{ N_("Auto"),		3, 0 },
3737 	{ N_("Low"),		2, 0 },
3738 	{ N_("Normal"),		1, 0 },
3739 	{ N_("High"),		0, 0 },
3740 	{ N_("Extra high"),	4, 0 },
3741 };
3742 GENERIC8TABLE(Nikon_HDRSmoothing,nikon_hdrsmoothing);
3743 
3744 static struct deviceproptableu16 nikon_d7100_exposure_program_modes[] = {
3745 	{ "M",			0x0001, 0 },
3746 	{ "P",			0x0002, 0 },
3747 	{ "A",			0x0003, 0 },
3748 	{ "S",			0x0004, 0 },
3749 	{ N_("Auto"),		0x8010, PTP_VENDOR_NIKON},
3750 	{ N_("Portrait"),	0x8011, PTP_VENDOR_NIKON},
3751 	{ N_("Landscape"),	0x8012, PTP_VENDOR_NIKON},
3752 	{ N_("Macro"),		0x8013, PTP_VENDOR_NIKON},
3753 	{ N_("Sports"),		0x8014, PTP_VENDOR_NIKON},
3754 	{ N_("No Flash"),	0x8016, PTP_VENDOR_NIKON},
3755 	{ N_("Children"),	0x8017, PTP_VENDOR_NIKON},
3756 	{ N_("Scene"),		0x8018, PTP_VENDOR_NIKON},
3757 	{ N_("Effects"),	0x8019, PTP_VENDOR_NIKON},
3758 	{ N_("U1"),		0x8050, PTP_VENDOR_NIKON},
3759 	{ N_("U2"),		0x8051, PTP_VENDOR_NIKON},
3760 };
3761 GENERIC16TABLE(NIKON_D7100_ExposureProgram,nikon_d7100_exposure_program_modes)
3762 
3763 static struct deviceproptableu16 nikon_d5100_exposure_program_modes[] = {
3764 	{ "M",			0x0001, 0 },
3765 	{ "P",			0x0002, 0 },
3766 	{ "A",			0x0003, 0 },
3767 	{ "S",			0x0004, 0 },
3768 	{ N_("Auto"),		0x8010, PTP_VENDOR_NIKON},
3769 	{ N_("Portrait"),	0x8011, PTP_VENDOR_NIKON},
3770 	{ N_("Landscape"),	0x8012, PTP_VENDOR_NIKON},
3771 	{ N_("Macro"),		0x8013, PTP_VENDOR_NIKON},
3772 	{ N_("Sports"),		0x8014, PTP_VENDOR_NIKON},
3773 	{ N_("No Flash"),	0x8016, PTP_VENDOR_NIKON},
3774 	{ N_("Children"),	0x8017, PTP_VENDOR_NIKON},
3775 	{ N_("Scene"),		0x8018, PTP_VENDOR_NIKON},
3776 	{ N_("Effects"),	0x8019, PTP_VENDOR_NIKON},
3777 };
3778 GENERIC16TABLE(NIKON_D5100_ExposureProgram,nikon_d5100_exposure_program_modes)
3779 
3780 static struct deviceproptableu8 nikon_1_exposure_program_modes[] = {
3781 	{ "P",			0x00, 0 },
3782 	{ "S",			0x01, 0 },
3783 	{ "A",			0x02, 0 },
3784 	{ "M",			0x03, 0 },
3785 	{ N_("Night Landscape"),0x04, 0 },
3786 	{ N_("Night Portrait"),	0x05, 0 },
3787 	{ N_("Back Light"),	0x06, 0 },
3788 	{ N_("Panorama"),	0x07, 0 },
3789 	{ N_("Smoothing"),	0x08, 0 },
3790 	{ N_("Tilt-Shift"),	0x09, 0 },
3791 	{ N_("Select Color"),	0x0a, 0 },
3792 };
3793 GENERIC8TABLE(NIKON_1_ExposureProgram,nikon_1_exposure_program_modes)
3794 
3795 static struct deviceproptableu16 capture_mode[] = {
3796 	{ N_("Single Shot"),		0x0001, 0 },
3797 	{ N_("Burst"),			0x0002, 0 },
3798 	{ N_("Timelapse"),		0x0003, 0 },
3799 	{ N_("Continuous Low Speed"),	0x8010, PTP_VENDOR_NIKON},
3800 	{ N_("Timer"),			0x8011, PTP_VENDOR_NIKON},
3801 	{ N_("Mirror Up"),		0x8012, PTP_VENDOR_NIKON},
3802 	{ N_("Remote"),			0x8013, PTP_VENDOR_NIKON},
3803 	{ N_("Quick Response Remote"),	0x8014, PTP_VENDOR_NIKON}, /* others nikons */
3804 	{ N_("Delayed Remote"),		0x8015, PTP_VENDOR_NIKON}, /* d90 */
3805 	{ N_("Quiet Release"),		0x8016, PTP_VENDOR_NIKON}, /* d5000 */
3806 	{ N_("Continuous Quiet Release"),	0x8018, PTP_VENDOR_NIKON}, /* d850 */
3807 
3808 	{ N_("Continuous Low Speed"),	0x8012, PTP_VENDOR_SONY},
3809 	{ N_("Selftimer 2s"),		0x8005, PTP_VENDOR_SONY},
3810 	{ N_("Selftimer 5s"),		0x8003, PTP_VENDOR_SONY},
3811 	{ N_("Selftimer 10s"),		0x8004, PTP_VENDOR_SONY},
3812 	{ N_("Selftimer 10s 3 Pictures"),0x8008, PTP_VENDOR_SONY},
3813 	{ N_("Selftimer 10s 5 Pictures"),0x8009, PTP_VENDOR_SONY},
3814 	{ N_("Selftimer 5s 3 Pictures"),0x800c, PTP_VENDOR_SONY},
3815 	{ N_("Selftimer 5s 5 Pictures"),0x800d, PTP_VENDOR_SONY},
3816 	{ N_("Selftimer 2s 3 Pictures"),0x800e, PTP_VENDOR_SONY},
3817 	{ N_("Selftimer 2s 5 Pictures"),0x800f, PTP_VENDOR_SONY},
3818 	{ N_("Continuous Hi+ Speed"),   0x8010, PTP_VENDOR_SONY}, /* A7III */
3819 	{ N_("Continuous Med Speed"),   0x8015, PTP_VENDOR_SONY}, /* A7III */
3820 
3821 	{ N_("Bracketing C 0.3 Steps 3 Pictures"),	0x8337, PTP_VENDOR_SONY},
3822 	{ N_("Bracketing C 0.3 Steps 5 Pictures"),	0x8537, PTP_VENDOR_SONY},
3823 	{ N_("Bracketing C 0.3 Steps 9 Pictures"),	0x8937, PTP_VENDOR_SONY},
3824 
3825 	{ N_("Bracketing C 0.5 Steps 3 Pictures"),	0x8357, PTP_VENDOR_SONY},
3826 	{ N_("Bracketing C 0.5 Steps 5 Pictures"),	0x8557, PTP_VENDOR_SONY},
3827 	{ N_("Bracketing C 0.5 Steps 9 Pictures"),	0x8957, PTP_VENDOR_SONY},
3828 
3829 	{ N_("Bracketing C 0.7 Steps 3 Pictures"),	0x8377, PTP_VENDOR_SONY},
3830 	{ N_("Bracketing C 0.7 Steps 5 Pictures"),	0x8577, PTP_VENDOR_SONY},
3831 	{ N_("Bracketing C 0.7 Steps 9 Pictures"),	0x8977, PTP_VENDOR_SONY},
3832 
3833 	{ N_("Bracketing C 1.0 Steps 3 Pictures"),	0x8311, PTP_VENDOR_SONY},
3834 	{ N_("Bracketing C 1.0 Steps 5 Pictures"),	0x8511, PTP_VENDOR_SONY},
3835 	{ N_("Bracketing C 1.0 Steps 9 Pictures"),	0x8911, PTP_VENDOR_SONY},
3836 
3837 	{ N_("Bracketing C 2.0 Steps 3 Pictures"),	0x8321, PTP_VENDOR_SONY},
3838 	{ N_("Bracketing C 2.0 Steps 5 Pictures"),	0x8521, PTP_VENDOR_SONY},
3839 
3840 	{ N_("Bracketing C 3.0 Steps 3 Pictures"),	0x8331, PTP_VENDOR_SONY},
3841 	{ N_("Bracketing C 3.0 Steps 5 Pictures"),	0x8531, PTP_VENDOR_SONY},
3842 
3843 	{ N_("Bracketing S 0.3 Steps 3 Pictures"),	0x8336, PTP_VENDOR_SONY},
3844 	{ N_("Bracketing S 0.3 Steps 5 Pictures"),	0x8536, PTP_VENDOR_SONY},
3845 	{ N_("Bracketing S 0.3 Steps 9 Pictures"),	0x8936, PTP_VENDOR_SONY},
3846 
3847 	{ N_("Bracketing S 0.5 Steps 3 Pictures"),	0x8356, PTP_VENDOR_SONY},
3848 	{ N_("Bracketing S 0.5 Steps 5 Pictures"),	0x8556, PTP_VENDOR_SONY},
3849 	{ N_("Bracketing S 0.5 Steps 9 Pictures"),	0x8956, PTP_VENDOR_SONY},
3850 
3851 	{ N_("Bracketing S 0.7 Steps 3 Pictures"),	0x8376, PTP_VENDOR_SONY},
3852 	{ N_("Bracketing S 0.7 Steps 5 Pictures"),	0x8576, PTP_VENDOR_SONY},
3853 	{ N_("Bracketing S 0.7 Steps 9 Pictures"),	0x8976, PTP_VENDOR_SONY},
3854 
3855 	{ N_("Bracketing S 1.0 Steps 3 Pictures"),	0x8310, PTP_VENDOR_SONY},
3856 	{ N_("Bracketing S 1.0 Steps 5 Pictures"),	0x8510, PTP_VENDOR_SONY},
3857 	{ N_("Bracketing S 1.0 Steps 9 Pictures"),	0x8910, PTP_VENDOR_SONY},
3858 
3859 	{ N_("Bracketing S 2.0 Steps 3 Pictures"),	0x8320, PTP_VENDOR_SONY},
3860 	{ N_("Bracketing S 2.0 Steps 5 Pictures"),	0x8520, PTP_VENDOR_SONY},
3861 	{ N_("Bracketing S 3.0 Steps 3 Pictures"),	0x8330, PTP_VENDOR_SONY},
3862 	{ N_("Bracketing S 3.0 Steps 5 Pictures"),	0x8530, PTP_VENDOR_SONY},
3863 	{ N_("Bracketing WB Lo"),	0x8018, PTP_VENDOR_SONY},
3864 	{ N_("Bracketing DRO Lo"),	0x8019, PTP_VENDOR_SONY},
3865 	{ N_("Bracketing WB Hi"),	0x8028, PTP_VENDOR_SONY},
3866 	{ N_("Bracketing DRO Hi"),	0x8029, PTP_VENDOR_SONY},
3867 /*
3868 	{ N_("Continuous"),		0x8001, PTP_VENDOR_CASIO},
3869 	{ N_("Prerecord"),		0x8002, PTP_VENDOR_CASIO},
3870 */
3871 };
3872 GENERIC16TABLE(CaptureMode,capture_mode)
3873 
3874 static struct deviceproptableu16 focus_metering[] = {
3875 	{ N_("Centre-spot"),	0x0001, 0 },
3876 	{ N_("Multi-spot"),	0x0002, 0 },
3877 	{ N_("Single Area"),	0x8010, PTP_VENDOR_NIKON},
3878 	{ N_("Closest Subject"),0x8011, PTP_VENDOR_NIKON},
3879 	{ N_("Group Dynamic"),  0x8012, PTP_VENDOR_NIKON},
3880 	{ N_("Single-area AF"),	0x8001, PTP_VENDOR_FUJI},
3881 	{ N_("Dynamic-area AF"),0x8002, PTP_VENDOR_FUJI},
3882 	{ N_("Group-dynamic AF"),0x8003, PTP_VENDOR_FUJI},
3883 	{ N_("Dynamic-area AF with closest subject priority"),0x8004, PTP_VENDOR_FUJI},
3884 };
3885 GENERIC16TABLE(FocusMetering,focus_metering)
3886 
3887 static struct deviceproptableu16 nikon_d7100_focus_metering[] = {
3888 	{ N_("Auto"),0x8011, PTP_VENDOR_NIKON},
3889 	{ N_("Single Area"),	0x8010, PTP_VENDOR_NIKON},
3890 	{ N_("Dynamic Area (9)"),	0x0002, 0 },
3891 	{ N_("Dynamic Area (21)"),  0x8013, PTP_VENDOR_NIKON},
3892 	{ N_("Dynamic Area (51)"),  0x8014, PTP_VENDOR_NIKON},
3893 	{ N_("3D Tracking"),  0x8012, PTP_VENDOR_NIKON},
3894 };
3895 GENERIC16TABLE(Nikon_D7100_FocusMetering,nikon_d7100_focus_metering)
3896 
3897 static struct deviceproptableu16 nikon_d850_focus_metering[] = {
3898 	{ N_("Dynamic-area AF (25 points)"),0x0002, PTP_VENDOR_NIKON},
3899 	{ N_("Single-point AF"),0x8010, PTP_VENDOR_NIKON},
3900 	{ N_("Auto-area AF"),	0x8011, PTP_VENDOR_NIKON},
3901 	{ N_("3D-tracking"),	0x8012, PTP_VENDOR_NIKON},
3902 	{ N_("Dynamic-area AF (72 points)"),0x8013, PTP_VENDOR_NIKON},
3903 	{ N_("Dynamic-area AF (153 points)"),	0x8014, PTP_VENDOR_NIKON},
3904 	{ N_("Group-area AF"),	0x8015, PTP_VENDOR_NIKON},
3905 	{ N_("Dynamic-area AF (9 points)"),	0x8016, PTP_VENDOR_NIKON},
3906 
3907 	{ N_("Pinpoint AF"),		0x8017, PTP_VENDOR_NIKON}, /* on Z */
3908 	{ N_("Wide-area AF (S)"),	0x8018, PTP_VENDOR_NIKON}, /* on Z */
3909 	{ N_("Wide-area AF (L)"),	0x8019, PTP_VENDOR_NIKON}, /* on Z */
3910 };
3911 GENERIC16TABLE(Nikon_D850_FocusMetering,nikon_d850_focus_metering)
3912 
3913 static struct deviceproptableu8 nikon_colormodel[] = {
3914 	{ N_("sRGB (portrait)"),0x00, 0 },
3915 	{ N_("AdobeRGB"),	0x01, 0 },
3916 	{ N_("sRGB (nature)"),	0x02, 0 },
3917 };
3918 GENERIC8TABLE(Nikon_ColorModel,nikon_colormodel)
3919 
3920 static struct deviceproptableu8 nikon_colorspace[] = {
3921 	{ N_("sRGB"),		0x00, 0 },
3922 	{ N_("AdobeRGB"),	0x01, 0 },
3923 };
3924 GENERIC8TABLE(Nikon_ColorSpace,nikon_colorspace)
3925 
3926 static struct deviceproptableu16 canon_eos_colorspace[] = {
3927 	{ N_("sRGB"), 		0x01, 0 },
3928 	{ N_("AdobeRGB"),	0x02, 0 },
3929 };
3930 GENERIC16TABLE(Canon_EOS_ColorSpace,canon_eos_colorspace)
3931 
3932 static struct deviceproptableu8 nikon_evstep[] = {
3933 	{ "1/3",	0, 0 },
3934 	{ "1/2",	1, 0 },
3935 };
3936 GENERIC8TABLE(Nikon_EVStep,nikon_evstep)
3937 
3938 static struct deviceproptableu8 nikon_orientation[] = {
3939 	{ "0'",		0, 0 },
3940 	{ "270'",	1, 0 },
3941 	{ "90'",	2, 0 },
3942 	{ "180'",	3, 0 },
3943 };
3944 GENERIC8TABLE(Nikon_CameraOrientation,nikon_orientation)
3945 
3946 static struct deviceproptableu16 canon_orientation[] = {
3947 	{ "0'",		0, 0 },
3948 	{ "90'",	1, 0 },
3949 	{ "180'",	2, 0 },
3950 	{ "270'",	3, 0 },
3951 };
3952 
3953 static int
_get_Canon_CameraOrientation(CONFIG_GET_ARGS)3954 _get_Canon_CameraOrientation(CONFIG_GET_ARGS) {
3955 	char	orient[50]; /* needs also to fit the translated string */
3956 	unsigned int	i;
3957 
3958 	if (dpd->DataType != PTP_DTC_UINT16)
3959 		return (GP_ERROR);
3960 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
3961 	gp_widget_set_name (*widget, menu->name);
3962 	for (i=0;i<sizeof(canon_orientation)/sizeof(canon_orientation[0]);i++) {
3963 		if (canon_orientation[i].value != dpd->CurrentValue.u16)
3964 			continue;
3965 		gp_widget_set_value (*widget, canon_orientation[i].label);
3966 		return GP_OK;
3967 	}
3968 	sprintf (orient, _("Unknown value 0x%04x"), dpd->CurrentValue.u16);
3969 	gp_widget_set_value (*widget, orient);
3970 	return GP_OK;
3971 }
3972 
3973 static int
_get_Nikon_AngleLevel(CONFIG_GET_ARGS)3974 _get_Nikon_AngleLevel(CONFIG_GET_ARGS) {
3975 	char	orient[20];
3976 
3977 	if (dpd->DataType != PTP_DTC_INT32)
3978 		return (GP_ERROR);
3979 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
3980 	gp_widget_set_name (*widget, menu->name);
3981 	sprintf (orient, "%.f'", dpd->CurrentValue.i32/65536.0);
3982 	gp_widget_set_value (*widget, orient);
3983 	return GP_OK;
3984 }
3985 
3986 
3987 static struct deviceproptableu8 nikon_afsensor[] = {
3988 	{ N_("Centre"),	0x00, 0 },
3989 	{ N_("Top"),	0x01, 0 },
3990 	{ N_("Bottom"),	0x02, 0 },
3991 	{ N_("Left"),	0x03, 0 },
3992 	{ N_("Right"),	0x04, 0 },
3993 };
3994 GENERIC8TABLE(Nikon_AutofocusArea,nikon_afsensor)
3995 
3996 
3997 static struct deviceproptableu16 exposure_metering[] = {
3998 	{ N_("Average"),	0x0001, 0 },
3999 	{ N_("Center Weighted"),0x0002, 0 },
4000 	{ N_("Multi Spot"),	0x0003, 0 },
4001 	{ N_("Center Spot"),	0x0004, 0 },
4002 	{ N_("Spot"),		0x8001, PTP_VENDOR_FUJI },
4003 	{ N_("ESP"),		0x8001, PTP_VENDOR_GP_OLYMPUS_OMD },
4004 	{ N_("Spot+Highlights"),0x8011, PTP_VENDOR_GP_OLYMPUS_OMD },
4005 	{ N_("Spot+Shadows"),	0x8012, PTP_VENDOR_GP_OLYMPUS_OMD },
4006 	/* next ones taken from A7III */
4007 	{ N_("Multi"),			0x8001, PTP_VENDOR_SONY },
4008 	{ N_("Center"),			0x8002, PTP_VENDOR_SONY },
4009 	{ N_("Entire Screen Avg."),	0x8003, PTP_VENDOR_SONY },
4010 	{ N_("Spot Standard"),		0x8004, PTP_VENDOR_SONY },
4011 	{ N_("Spot Large"),		0x8005, PTP_VENDOR_SONY },
4012 	{ N_("Highlight"),		0x8006, PTP_VENDOR_SONY },
4013 };
4014 GENERIC16TABLE(ExposureMetering,exposure_metering)
4015 
4016 static struct deviceproptableu16 flash_mode[] = {
4017 	{ N_("Automatic Flash"),		0x0001, 0 },
4018 	{ N_("Flash off"),			0x0002, 0 },
4019 	{ N_("Fill flash"),			0x0003, 0 },
4020 	{ N_("Red-eye automatic"),		0x0004, 0 },
4021 	{ N_("Red-eye fill"),			0x0005, 0 },
4022 	{ N_("External sync"),			0x0006, 0 },
4023 	{ N_("Auto"),				0x8010, PTP_VENDOR_NIKON},
4024 	{ N_("Auto Slow Sync"),			0x8011, PTP_VENDOR_NIKON},
4025 	{ N_("Rear Curtain Sync + Slow Sync"),	0x8012, PTP_VENDOR_NIKON},
4026 	{ N_("Red-eye Reduction + Slow Sync"),	0x8013, PTP_VENDOR_NIKON},
4027 	{ N_("Front-curtain sync"),			0x8001, PTP_VENDOR_FUJI},
4028 	{ N_("Red-eye reduction"),			0x8002, PTP_VENDOR_FUJI},
4029 	{ N_("Red-eye reduction with slow sync"),	0x8003, PTP_VENDOR_FUJI},
4030 	{ N_("Slow sync"),				0x8004, PTP_VENDOR_FUJI},
4031 	{ N_("Rear-curtain with slow sync"),		0x8005, PTP_VENDOR_FUJI},
4032 	{ N_("Rear-curtain sync"),			0x8006, PTP_VENDOR_FUJI},
4033 
4034 	{ N_("Rear Curtain Sync"),			0x8003, PTP_VENDOR_SONY},
4035 	{ N_("Wireless Sync"),				0x8004, PTP_VENDOR_SONY},
4036 	{ N_("Slow Sync"),				0x8032, PTP_VENDOR_SONY},
4037 };
4038 GENERIC16TABLE(FlashMode,flash_mode)
4039 
4040 static struct deviceproptableu16 effect_modes[] = {
4041 	{ N_("Standard"),	0x0001, 0 },
4042 	{ N_("Black & White"),	0x0002, 0 },
4043 	{ N_("Sepia"),		0x0003, 0 },
4044 };
4045 GENERIC16TABLE(EffectMode,effect_modes)
4046 
4047 static struct deviceproptableu8 nikon_effect_modes[] = {
4048 	{ N_("Night Vision"),		0x00, 0 },
4049 	{ N_("Color sketch"),		0x01, 0 },
4050 	{ N_("Miniature effect"),	0x02, 0 },
4051 	{ N_("Selective color"),	0x03, 0 },
4052 	{ N_("Silhouette"),		0x04, 0 },
4053 	{ N_("High key"),		0x05, 0 },
4054 	{ N_("Low key"),		0x06, 0 },
4055 };
GENERIC8TABLE(NIKON_EffectMode,nikon_effect_modes)4056 GENERIC8TABLE(NIKON_EffectMode,nikon_effect_modes)
4057 
4058 
4059 static int
4060 _get_FocalLength(CONFIG_GET_ARGS) {
4061 	float value_float , start=0.0, end=0.0, step=0.0;
4062 	int i;
4063 
4064 	if (!(dpd->FormFlag & (PTP_DPFF_Range|PTP_DPFF_Enumeration)))
4065 		return (GP_ERROR);
4066 	if (dpd->DataType != PTP_DTC_UINT32)
4067 		return (GP_ERROR);
4068 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
4069 	gp_widget_set_name (*widget, menu->name);
4070 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
4071 		/* Find the range we need. */
4072 		start = 10000.0;
4073 		end = 0.0;
4074 		for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4075 			float cur = dpd->FORM.Enum.SupportedValue[i].u32 / 100.0;
4076 
4077 			if (cur < start) start = cur;
4078 			if (cur > end)   end = cur;
4079 		}
4080 		step = 1.0;
4081 	}
4082 	if (dpd->FormFlag & PTP_DPFF_Range) {
4083 		start = dpd->FORM.Range.MinimumValue.u32/100.0;
4084 		end = dpd->FORM.Range.MaximumValue.u32/100.0;
4085 		step = dpd->FORM.Range.StepSize.u32/100.0;
4086 	}
4087 	gp_widget_set_range (*widget, start, end, step);
4088 	value_float = dpd->CurrentValue.u32/100.0;
4089 	gp_widget_set_value (*widget, &value_float);
4090 	return (GP_OK);
4091 }
4092 
4093 static int
_put_FocalLength(CONFIG_PUT_ARGS)4094 _put_FocalLength(CONFIG_PUT_ARGS) {
4095 	unsigned int i;
4096 	float value_float;
4097 	uint32_t curdiff, newval;
4098 
4099 	CR (gp_widget_get_value (widget, &value_float));
4100 	propval->u32 = 100*value_float;
4101 	if (dpd->FormFlag & PTP_DPFF_Range)
4102 		return GP_OK;
4103 	/* If FocalLength is enumerated, we need to hit the
4104 	 * values exactly, otherwise nothing will happen.
4105 	 * (problem encountered on my Nikon P2)
4106 	 */
4107 	curdiff = 10000;
4108 	newval = propval->u32;
4109 	for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4110 		uint32_t diff = abs((int)(dpd->FORM.Enum.SupportedValue[i].u32  - propval->u32));
4111 
4112 		if (diff < curdiff) {
4113 			newval = dpd->FORM.Enum.SupportedValue[i].u32;
4114 			curdiff = diff;
4115 		}
4116 	}
4117 	propval->u32 = newval;
4118 	return GP_OK;
4119 }
4120 
4121 static int
_get_VideoFormat(CONFIG_GET_ARGS)4122 _get_VideoFormat(CONFIG_GET_ARGS) {
4123 	int i, valset = 0;
4124 	char buf[200];
4125 
4126 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
4127 		return GP_ERROR;
4128 
4129 	if (dpd->DataType != PTP_DTC_UINT32)
4130 		return GP_ERROR;
4131 
4132 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4133 	gp_widget_set_name (*widget, menu->name);
4134 
4135 	/* We use FOURCC values, which should be 4 characters always */
4136 
4137 	for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4138 		sprintf (buf, "%c%c%c%c",
4139 			(dpd->FORM.Enum.SupportedValue[i].u32     )  & 0xff,
4140 			(dpd->FORM.Enum.SupportedValue[i].u32 >> 8)  & 0xff,
4141 			(dpd->FORM.Enum.SupportedValue[i].u32 >> 16) & 0xff,
4142 			(dpd->FORM.Enum.SupportedValue[i].u32 >> 24) & 0xff
4143 		);
4144 		gp_widget_add_choice (*widget,buf);
4145 		if (dpd->CurrentValue.u32 == dpd->FORM.Enum.SupportedValue[i].u32) {
4146 			gp_widget_set_value (*widget, buf);
4147 			valset = 1;
4148 		}
4149 	}
4150 	if (!valset) {
4151 		sprintf (buf, "%c%c%c%c",
4152 			(dpd->CurrentValue.u32     )  & 0xff,
4153 			(dpd->CurrentValue.u32 >> 8)  & 0xff,
4154 			(dpd->CurrentValue.u32 >> 16) & 0xff,
4155 			(dpd->CurrentValue.u32 >> 24) & 0xff
4156 		);
4157 		sprintf (buf, _("%d mm"), dpd->CurrentValue.u16);
4158 		gp_widget_set_value (*widget, buf);
4159 	}
4160 	return GP_OK;
4161 }
4162 
4163 static int
_put_VideoFormat(CONFIG_PUT_ARGS)4164 _put_VideoFormat(CONFIG_PUT_ARGS) {
4165 	const unsigned char *value_str;
4166 
4167 	CR (gp_widget_get_value (widget, &value_str));
4168 	if (strlen((char*)value_str) < 4)
4169 		return GP_ERROR_BAD_PARAMETERS;
4170 	/* we could check if we have it in the ENUM */
4171 	propval->u32 = value_str[0] | (value_str[1] << 8) | (value_str[2] << 16) | (value_str[3] << 24);
4172 	return GP_OK;
4173 }
4174 
4175 static int
_get_FocusDistance(CONFIG_GET_ARGS)4176 _get_FocusDistance(CONFIG_GET_ARGS) {
4177 	if (!(dpd->FormFlag & (PTP_DPFF_Range|PTP_DPFF_Enumeration)))
4178 		return (GP_ERROR);
4179 
4180 	if (dpd->DataType != PTP_DTC_UINT16)
4181 		return (GP_ERROR);
4182 
4183 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
4184 		int i, valset = 0;
4185 		char buf[200];
4186 
4187 		gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4188 		gp_widget_set_name (*widget, menu->name);
4189 
4190 		for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4191 
4192 			if (dpd->FORM.Enum.SupportedValue[i].u16 == 0xFFFF)
4193 				strcpy (buf, _("infinite"));
4194 			else
4195 				sprintf (buf, _("%d mm"), dpd->FORM.Enum.SupportedValue[i].u16);
4196 			gp_widget_add_choice (*widget,buf);
4197 			if (dpd->CurrentValue.u16 == dpd->FORM.Enum.SupportedValue[i].u16) {
4198 				gp_widget_set_value (*widget, buf);
4199 				valset = 1;
4200 			}
4201 		}
4202 		if (!valset) {
4203 			sprintf (buf, _("%d mm"), dpd->CurrentValue.u16);
4204 			gp_widget_set_value (*widget, buf);
4205 		}
4206 	}
4207 	if (dpd->FormFlag & PTP_DPFF_Range) {
4208 		float value_float , start=0.0, end=0.0, step=0.0;
4209 
4210 		gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
4211 		gp_widget_set_name (*widget, menu->name);
4212 
4213 		start = dpd->FORM.Range.MinimumValue.u16/100.0;
4214 		end = dpd->FORM.Range.MaximumValue.u16/100.0;
4215 		step = dpd->FORM.Range.StepSize.u16/100.0;
4216 		gp_widget_set_range (*widget, start, end, step);
4217 		value_float = dpd->CurrentValue.u16/100.0;
4218 		gp_widget_set_value (*widget, &value_float);
4219 	}
4220 	return GP_OK;
4221 }
4222 
4223 static int
_put_FocusDistance(CONFIG_PUT_ARGS)4224 _put_FocusDistance(CONFIG_PUT_ARGS) {
4225 	int val;
4226 	const char *value_str;
4227 
4228 	if (dpd->FormFlag & PTP_DPFF_Range) {
4229 		float value_float;
4230 
4231 		CR (gp_widget_get_value (widget, &value_float));
4232 		propval->u16 = value_float;
4233 		return GP_OK;
4234 	}
4235 	/* else ENUMeration */
4236 	CR (gp_widget_get_value (widget, &value_str));
4237 	if (!strcmp (value_str, _("infinite"))) {
4238 		propval->u16 = 0xFFFF;
4239 		return GP_OK;
4240 	}
4241 	C_PARAMS (sscanf(value_str, _("%d mm"), &val));
4242 	propval->u16 = val;
4243 	return GP_OK;
4244 }
4245 
4246 static int
_get_Nikon_ShutterSpeed(CONFIG_GET_ARGS)4247 _get_Nikon_ShutterSpeed(CONFIG_GET_ARGS) {
4248 	int i, valset = 0;
4249 	char buf[200];
4250 	int x,y;
4251 
4252 	if (dpd->DataType != PTP_DTC_UINT32)
4253 		return (GP_ERROR);
4254 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
4255 		return (GP_ERROR);
4256 
4257 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4258 	gp_widget_set_name (*widget, menu->name);
4259 
4260 	for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4261 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xffffffff) {
4262 			sprintf(buf,_("Bulb"));
4263 			goto choicefound;
4264 		}
4265 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xfffffffe) {
4266 			sprintf(buf,_("x 200"));
4267 			goto choicefound;
4268 		}
4269 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xfffffffd) {
4270 			sprintf(buf,_("Time"));
4271 			goto choicefound;
4272 		}
4273 		x = dpd->FORM.Enum.SupportedValue[i].u32>>16;
4274 		y = dpd->FORM.Enum.SupportedValue[i].u32&0xffff;
4275 		if (y == 1) { /* x/1 */
4276 			sprintf (buf, "%d", x);
4277 		} else {
4278 			sprintf (buf, "%d/%d",x,y);
4279 		}
4280 choicefound:
4281 		gp_widget_add_choice (*widget,buf);
4282 		if (dpd->CurrentValue.u32 == dpd->FORM.Enum.SupportedValue[i].u32) {
4283 			gp_widget_set_value (*widget, buf);
4284 			valset = 1;
4285 		}
4286 	}
4287 	if (!valset) {
4288 		x = dpd->CurrentValue.u32>>16;
4289 		y = dpd->CurrentValue.u32&0xffff;
4290 		if (y == 1) {
4291 			sprintf (buf, "%d",x);
4292 		} else {
4293 			sprintf (buf, "%d/%d",x,y);
4294 		}
4295 		gp_widget_set_value (*widget, buf);
4296 	}
4297 	return GP_OK;
4298 }
4299 
4300 static int
_put_Nikon_ShutterSpeed(CONFIG_PUT_ARGS)4301 _put_Nikon_ShutterSpeed(CONFIG_PUT_ARGS) {
4302 	int x,y;
4303 	const char *value_str;
4304 
4305 	gp_widget_get_value (widget, &value_str);
4306 
4307 	if (!strcmp(value_str,_("Bulb"))) {
4308 		propval->u32 = 0xffffffff;
4309 		return GP_OK;
4310 	}
4311 	if (!strcmp(value_str,_("x 200"))) {
4312 		propval->u32 = 0xfffffffe;
4313 		return GP_OK;
4314 	}
4315 	if (!strcmp(value_str,_("Time"))) {
4316 		propval->u32 = 0xfffffffd;
4317 		return GP_OK;
4318 	}
4319 
4320 	if (strchr(value_str, '/')) {
4321 		if (2 != sscanf (value_str, "%d/%d", &x, &y))
4322 			return GP_ERROR;
4323 	} else {
4324 		if (!sscanf (value_str, "%d", &x))
4325 			return GP_ERROR;
4326 		y = 1;
4327 	}
4328 	propval->u32 = (x<<16) | y;
4329 	return GP_OK;
4330 }
4331 
4332 static int
_get_Olympus_ShutterSpeed(CONFIG_GET_ARGS)4333 _get_Olympus_ShutterSpeed(CONFIG_GET_ARGS) {
4334 	int i, valset = 0;
4335 	char buf[200];
4336 	int x,y;
4337 
4338 	if (dpd->DataType != PTP_DTC_UINT32)
4339 		return (GP_ERROR);
4340 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
4341 		return (GP_ERROR);
4342 
4343 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4344 	gp_widget_set_name (*widget, menu->name);
4345 
4346 	for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4347 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xfffffffc) {
4348 			sprintf(buf,_("Bulb"));
4349 			goto choicefound;
4350 		}
4351 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xfffffffa) {
4352 		 	sprintf(buf,_("Composite"));
4353 		 	goto choicefound;
4354 		 }
4355 		if (dpd->FORM.Enum.SupportedValue[i].u32 == 0xfffffffb) {
4356 			sprintf(buf,_("Time"));
4357 			goto choicefound;
4358 		}
4359 
4360 		x = dpd->FORM.Enum.SupportedValue[i].u32>>16;
4361 		y = dpd->FORM.Enum.SupportedValue[i].u32&0xffff;
4362 
4363 		if (((y % 10) == 0) && ((x % 10) == 0)) {
4364 			y /= 10;
4365 			x /= 10;
4366 		}
4367 		if (y == 1) { /* x/1 */
4368 			sprintf (buf, "%d", x);
4369 		} else {
4370 			sprintf (buf, "%d/%d",x,y);
4371 		}
4372 
4373 choicefound:
4374 
4375 		gp_widget_add_choice (*widget,buf);
4376 		if (dpd->CurrentValue.u32 == dpd->FORM.Enum.SupportedValue[i].u32) {
4377 			gp_widget_set_value (*widget, buf);
4378 			valset = 1;
4379 		}
4380 	}
4381 	if (!valset) {
4382 		x = dpd->CurrentValue.u32>>16;
4383 		y = dpd->CurrentValue.u32&0xffff;
4384 		if (y == 1) {
4385 			sprintf (buf, "%d",x);
4386 		} else {
4387 			sprintf (buf, "%d/%d",x,y);
4388 		}
4389 		gp_widget_set_value (*widget, buf);
4390 	}
4391 	return GP_OK;
4392 }
4393 
4394 static int
_put_Olympus_ShutterSpeed(CONFIG_PUT_ARGS)4395 _put_Olympus_ShutterSpeed(CONFIG_PUT_ARGS) {
4396 	int x,y;
4397 	const char *value_str;
4398 
4399 	gp_widget_get_value (widget, &value_str);
4400 
4401 	if (!strcmp(value_str,_("Bulb"))) {
4402 		propval->u32 = 0xfffffffc;
4403 		return GP_OK;
4404 	}
4405 	if (!strcmp(value_str,_("Composite"))) {
4406 	 	propval->u32 = 0xfffffffa;
4407 	 	return GP_OK;
4408 	 }
4409 	if (!strcmp(value_str,_("Time"))) {
4410 		propval->u32 = 0xfffffffb;
4411 		return GP_OK;
4412 	}
4413 
4414 	if (strchr(value_str, '/')) {
4415 		if (2 != sscanf (value_str, "%d/%d", &x, &y))
4416 			return GP_ERROR;
4417 	} else {
4418 		if (!sscanf (value_str, "%d", &x))
4419 			return GP_ERROR;
4420 		y = 10;
4421 		x *=10;
4422 	}
4423 
4424 	propval->u32 = (x<<16) | y;
4425 	return GP_OK;
4426 }
4427 
4428 
4429 static int
_get_Ricoh_ShutterSpeed(CONFIG_GET_ARGS)4430 _get_Ricoh_ShutterSpeed(CONFIG_GET_ARGS) {
4431 	int i, valset = 0;
4432 	char buf[200];
4433 	int x,y;
4434 
4435 	if (dpd->DataType != PTP_DTC_UINT64)
4436 		return GP_ERROR;
4437 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
4438 		return GP_ERROR;
4439 
4440 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4441 	gp_widget_set_name (*widget, menu->name);
4442 
4443 	for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4444 		if (dpd->FORM.Enum.SupportedValue[i].u64 == 0) {
4445 			sprintf(buf,_("Auto"));
4446 			goto choicefound;
4447 		}
4448 		x = dpd->FORM.Enum.SupportedValue[i].u64>>32;
4449 		y = dpd->FORM.Enum.SupportedValue[i].u64&0xffffffff;
4450 		if (y == 1) {
4451 			sprintf (buf, "1/%d", x);
4452 		} else {
4453 			sprintf (buf, "%d/%d",y,x);
4454 		}
4455 choicefound:
4456 		gp_widget_add_choice (*widget,buf);
4457 		if (dpd->CurrentValue.u64 == dpd->FORM.Enum.SupportedValue[i].u64) {
4458 			gp_widget_set_value (*widget, buf);
4459 			valset = 1;
4460 		}
4461 	}
4462 	if (!valset) {
4463 		x = dpd->CurrentValue.u64>>32;
4464 		y = dpd->CurrentValue.u64&0xffffffff;
4465 		if (y == 1) {
4466 			sprintf (buf, "1/%d",x);
4467 		} else {
4468 			sprintf (buf, "%d/%d",y,x);
4469 		}
4470 		gp_widget_set_value (*widget, buf);
4471 	}
4472 	return GP_OK;
4473 }
4474 
4475 static int
_put_Ricoh_ShutterSpeed(CONFIG_PUT_ARGS)4476 _put_Ricoh_ShutterSpeed(CONFIG_PUT_ARGS) {
4477 	int x,y;
4478 	const char *value_str;
4479 
4480 	gp_widget_get_value (widget, &value_str);
4481 
4482 	if (!strcmp(value_str,_("Auto"))) {
4483 		propval->u64 = 0;
4484 		return GP_OK;
4485 	}
4486 
4487 	if (strchr(value_str, '/')) {
4488 		if (2 != sscanf (value_str, "%d/%d", &y, &x))
4489 			return GP_ERROR;
4490 	} else {
4491 		if (!sscanf (value_str, "%d", &x))
4492 			return GP_ERROR;
4493 		y = 1;
4494 	}
4495 	propval->u64 = ((uint64_t)x<<32) | y;
4496 	return GP_OK;
4497 }
4498 
4499 /* This list is taken from Sony A58... fill in more if your Sony has more */
4500 static struct sonyshutter {
4501 	int dividend, divisor;
4502 } sony_shuttertable[] = {
4503 	{30,1},
4504 	{25,1},
4505 	{20,1},
4506 	{15,1},
4507 	{13,1},
4508 	{10,1},
4509 	{8,1},
4510 	{6,1},
4511 	{5,1},
4512 	{4,1},
4513 	{32,10},
4514 	{25,10},
4515 	{2,1},
4516 	{16,10},
4517 	{13,10},
4518 	{1,1},
4519 	{8,10},
4520 	{6,10},
4521 	{5,10},
4522 	{4,10},
4523 	{1,3},
4524 	{1,4},
4525 	{1,5},
4526 	{1,6},
4527 	{1,8},
4528 	{1,10},
4529 	{1,13},
4530 	{1,15},
4531 	{1,20},
4532 	{1,25},
4533 	{1,30},
4534 	{1,40},
4535 	{1,50},
4536 	{1,60},
4537 	{1,80},
4538 	{1,100},
4539 	{1,125},
4540 	{1,160},
4541 	{1,200},
4542 	{1,250},
4543 	{1,320},
4544 	{1,400},
4545 	{1,500},
4546 	{1,640},
4547 	{1,800},
4548 	{1,1000},
4549 	{1,1250},
4550 	{1,1600},
4551 	{1,2000},
4552 	{1,2500},
4553 	{1,3200},
4554 	{1,4000},
4555 	/* A7 series */
4556 	{1,5000},
4557 	{1,6400},
4558 	{1,8000},
4559 	/* A9, some RX series cameras */
4560 	{1,10000},
4561 	{1,12500},
4562 	{1,16000},
4563 	{1,20000},
4564 	{1,25000},
4565 	{1,32000},
4566 };
4567 
4568 static int
_get_Sony_ShutterSpeed(CONFIG_GET_ARGS)4569 _get_Sony_ShutterSpeed(CONFIG_GET_ARGS) {
4570 	int			x,y;
4571 	char			buf[20];
4572 	PTPParams		*params = &(camera->pl->params);
4573 	GPContext 		*context = ((PTPData *) params->data)->context;
4574 
4575 	if (dpd->DataType != PTP_DTC_UINT32)
4576 		return GP_ERROR;
4577 
4578 	if (have_prop (camera, PTP_VENDOR_SONY, PTP_DPC_SONY_ShutterSpeed2))
4579 		C_PTP_REP (ptp_generic_getdevicepropdesc (params, PTP_DPC_SONY_ShutterSpeed2, dpd));
4580 
4581 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4582 	gp_widget_set_name (*widget, menu->name);
4583 
4584 	/* new style has an ENUM again */
4585 	if (dpd->FormFlag & PTP_DPFF_Enumeration) {
4586 		unsigned int i;
4587 
4588 		for (i=0;i<dpd->FORM.Enum.NumberOfValues;i++) {
4589 			x = dpd->FORM.Enum.SupportedValue[i].u32 >> 16;
4590 			y = dpd->FORM.Enum.SupportedValue[i].u32 & 0xffff;
4591 
4592 			if (y == 1)
4593 				sprintf (buf, "%d",x);
4594 			else
4595 				sprintf (buf, "%d/%d",x,y);
4596 			gp_widget_add_choice (*widget, buf);
4597 		}
4598 		gp_widget_add_choice (*widget, _("Bulb"));
4599 	} else {
4600 		unsigned int i;
4601 		/* use our static table */
4602 		for (i=0;i<sizeof(sony_shuttertable)/sizeof(sony_shuttertable[0]);i++) {
4603 			x = sony_shuttertable[i].dividend;
4604 			y = sony_shuttertable[i].divisor;
4605 			if (y == 1)
4606 				sprintf (buf, "%d",x);
4607 			else
4608 				sprintf (buf, "%d/%d",x,y);
4609 			gp_widget_add_choice (*widget, buf);
4610 		}
4611 		gp_widget_add_choice (*widget, _("Bulb"));
4612 	}
4613 
4614 	if (dpd->CurrentValue.u32 == 0) {
4615 		strcpy(buf,_("Bulb"));
4616 	} else {
4617 		x = dpd->CurrentValue.u32>>16;
4618 		y = dpd->CurrentValue.u32&0xffff;
4619 		if (y == 1)
4620 			sprintf (buf, "%d",x);
4621 		else
4622 			sprintf (buf, "%d/%d",x,y);
4623 	}
4624 	gp_widget_set_value (*widget, buf);
4625 	return GP_OK;
4626 }
4627 
4628 static int
_put_Sony_ShutterSpeed(CONFIG_PUT_ARGS)4629 _put_Sony_ShutterSpeed(CONFIG_PUT_ARGS) {
4630 	int			x,y,a,b,direction,position_current,position_new;
4631 	const char		*val;
4632 	float 			old,new,current;
4633 	PTPPropertyValue	value;
4634 	uint32_t		new32, origval;
4635 	PTPParams		*params = &(camera->pl->params);
4636 	GPContext 		*context = ((PTPData *) params->data)->context;
4637 	time_t			start,end;
4638 	unsigned int		i;
4639 
4640 	CR (gp_widget_get_value (widget, &val));
4641 
4642 	if (dpd->CurrentValue.u32 == 0) {
4643 		x = 65536; y = 1;
4644 	} else {
4645 		x = dpd->CurrentValue.u32>>16;
4646 		y = dpd->CurrentValue.u32&0xffff;
4647 	}
4648 	old = ((float)x)/(float)y;
4649 	current = old;
4650 
4651 	if (!strcmp(val,_("Bulb"))) {
4652 		new32 = 0;
4653 		x = 65536; y = 1;
4654 	} else {
4655 		if (2!=sscanf(val, "%d/%d", &x, &y)) {
4656 			if (1==sscanf(val,"%d", &x)) {
4657 				y = 1;
4658 			} else {
4659 				return GP_ERROR_BAD_PARAMETERS;
4660 			}
4661 		}
4662 		new32 = (x<<16)|y;
4663 	}
4664 	/* new style */
4665 	if (have_prop (camera, PTP_VENDOR_SONY, PTP_DPC_SONY_ShutterSpeed2)) {
4666 		propval->u32 = new32;
4667 		return translate_ptp_result (ptp_sony_setdevicecontrolvaluea(params, PTP_DPC_SONY_ShutterSpeed2, propval, PTP_DTC_UINT32));
4668 	}
4669 	/* old style uses stepping */
4670 
4671 	new = ((float)x)/(float)y;
4672 
4673 	if (old > new) {
4674 		value.u8 = 0x01;
4675 		direction = 1;
4676 	}
4677 	else {
4678 		value.u8 = 0xff;
4679 		direction = -1;
4680 	}
4681 
4682 	if (direction == 1) {
4683 		for (i=0;i<sizeof(sony_shuttertable)/sizeof(sony_shuttertable[0]);i++) {
4684 			a = sony_shuttertable[i].dividend;
4685 			b = sony_shuttertable[i].divisor;
4686 			position_new = i;
4687 			if (new >= ((float)a)/(float)b)
4688 				break;
4689 		}
4690 	} else {
4691 		for (i=sizeof(sony_shuttertable)/sizeof(sony_shuttertable[0])-1;i--;) {
4692 			a = sony_shuttertable[i].dividend;
4693 			b = sony_shuttertable[i].divisor;
4694 			position_new = i;
4695 			if (new <= ((float)a)/(float)b)
4696 				break;
4697 		}
4698 	}
4699 
4700 	do {
4701 		origval = dpd->CurrentValue.u32;
4702 		if (old == new)
4703 			break;
4704 
4705 		for (i=0;i<sizeof(sony_shuttertable)/sizeof(sony_shuttertable[0]);i++) {
4706 			a = sony_shuttertable[i].dividend;
4707 			b = sony_shuttertable[i].divisor;
4708 			position_current = i;
4709 			if (current >= ((float)a)/(float)b)
4710 				break;
4711 		}
4712 
4713 		// Calculating jump width
4714 		if (direction > 0)
4715 			value.u8 = 0x00 + position_new - position_current;
4716 		else
4717 			value.u8 = 0x100 + position_new - position_current;
4718 
4719 		a = dpd->CurrentValue.u32>>16;
4720 		b = dpd->CurrentValue.u32&0xffff;
4721 		C_PTP_REP (ptp_sony_setdevicecontrolvalueb (params, dpd->DevicePropertyCode, &value, PTP_DTC_UINT8 ));
4722 
4723 		GP_LOG_D ("shutterspeed value is (0x%x vs target 0x%x)", origval, new32);
4724 
4725 		/* we tell the camera to do it, but it takes around 0.7 seconds for the SLT-A58 */
4726 		time(&start);
4727 		do {
4728 			C_PTP_REP (ptp_sony_getalldevicepropdesc (params));
4729 			C_PTP_REP (ptp_generic_getdevicepropdesc (params, dpd->DevicePropertyCode, dpd));
4730 
4731 			if (dpd->CurrentValue.u32 == new32) {
4732 				GP_LOG_D ("Value matched!");
4733 				break;
4734 			}
4735 			a = dpd->CurrentValue.u32>>16;
4736 			b = dpd->CurrentValue.u32&0xffff;
4737 			current = ((float)a)/((float)b);
4738 
4739 			if ((a*y != 0) && (a*y == b*x)) {
4740 				GP_LOG_D ("Value matched via math(tm) %d/%d == %d/%d!",x,y,a,b);
4741 				break;
4742 			}
4743 
4744 			if (dpd->CurrentValue.u32 != origval) {
4745 				GP_LOG_D ("value changed (0x%x vs 0x%x vs target 0x%x), next step....", dpd->CurrentValue.u32, origval, new32);
4746 				break;
4747 			}
4748 
4749 			usleep(200*1000);
4750 
4751 			time(&end);
4752 		} while (end-start <= 3);
4753 
4754 		if (direction > 0 && current <= new) {
4755 			GP_LOG_D ("Overshooted value, maybe choice not available!");
4756 			break;
4757 		}
4758 		if (direction < 0 && current >= new) {
4759 			GP_LOG_D ("Overshooted value, maybe choice not available!");
4760 			break;
4761 		}
4762 
4763 		if (dpd->CurrentValue.u32 == new32) {
4764 			GP_LOG_D ("Value matched!");
4765 			break;
4766 		}
4767 		if ((a*y != 0) && (a*y == b*x)) {
4768 			GP_LOG_D ("Value matched via math(tm) %d/%d == %d/%d!",x,y,a,b);
4769 			break;
4770 		}
4771 		if (dpd->CurrentValue.u32 == origval) {
4772 			GP_LOG_D ("value did not change (0x%x vs 0x%x vs target 0x%x), not good ...", dpd->CurrentValue.u32, origval, new32);
4773 			break;
4774 		}
4775 	} while (1);
4776 	propval->u32 = new;
4777 	return GP_OK;
4778 }
4779 
4780 static int
_get_Nikon_FocalLength(CONFIG_GET_ARGS)4781 _get_Nikon_FocalLength(CONFIG_GET_ARGS) {
4782 	char	len[20];
4783 
4784 	if (dpd->DataType != PTP_DTC_UINT32)
4785 		return (GP_ERROR);
4786 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
4787 	gp_widget_set_name (*widget, menu->name);
4788 	sprintf (len, "%.0f mm", dpd->CurrentValue.u32 * 0.01);
4789 	gp_widget_set_value (*widget, len);
4790 	return (GP_OK);
4791 }
4792 
4793 static int
_get_Nikon_ApertureAtFocalLength(CONFIG_GET_ARGS)4794 _get_Nikon_ApertureAtFocalLength(CONFIG_GET_ARGS) {
4795 	char	len[20];
4796 
4797 	if (dpd->DataType != PTP_DTC_UINT16)
4798 		return (GP_ERROR);
4799 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
4800 	gp_widget_set_name (*widget, menu->name);
4801 	sprintf (len, "%.0f", dpd->CurrentValue.u16 * 0.01);
4802 	gp_widget_set_value (*widget, len);
4803 	return (GP_OK);
4804 }
4805 
4806 static int
_get_Olympus_Aperture(CONFIG_GET_ARGS)4807 _get_Olympus_Aperture(CONFIG_GET_ARGS) {
4808 	char	len[20];
4809 	int	i;
4810 
4811 	if (dpd->DataType != PTP_DTC_UINT16)
4812 		return GP_ERROR;
4813 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
4814 		return GP_ERROR;
4815 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4816 	gp_widget_set_name (*widget, menu->name);
4817 	for (i=0;i<dpd->FORM.Enum.NumberOfValues; i++) {
4818 		sprintf (len, "%.1f", dpd->FORM.Enum.SupportedValue[i].u16 * 0.1);
4819 		gp_widget_add_choice (*widget, len);
4820 	}
4821 	sprintf (len, "%.1f", dpd->CurrentValue.u16 * 0.1);
4822 	gp_widget_set_value (*widget, len);
4823 	return GP_OK;
4824 }
4825 
4826 static int
_put_Olympus_Aperture(CONFIG_PUT_ARGS)4827 _put_Olympus_Aperture(CONFIG_PUT_ARGS) {
4828 	char	*val;
4829 	float	f;
4830 
4831 	gp_widget_get_value (widget, &val);
4832 	sscanf (val, "%f", &f);
4833 	propval->u16 = 10*f;
4834 	return GP_OK;
4835 }
4836 
4837 static int
_get_Nikon_LightMeter(CONFIG_GET_ARGS)4838 _get_Nikon_LightMeter(CONFIG_GET_ARGS) {
4839 	char	meter[20];
4840 
4841 	if (dpd->DataType != PTP_DTC_INT8)
4842 		return (GP_ERROR);
4843 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
4844 	gp_widget_set_name (*widget, menu->name);
4845 	sprintf (meter, "%.1f", dpd->CurrentValue.i8 * 0.08333);
4846 	gp_widget_set_value (*widget, meter);
4847 	return (GP_OK);
4848 }
4849 
4850 
4851 static int
_get_Nikon_FlashExposureCompensation(CONFIG_GET_ARGS)4852 _get_Nikon_FlashExposureCompensation(CONFIG_GET_ARGS) {
4853 	float value_float;
4854 
4855 	if (!(dpd->FormFlag & PTP_DPFF_Range))
4856 		return GP_ERROR;
4857 	if (dpd->DataType != PTP_DTC_INT8)
4858 		return GP_ERROR;
4859 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
4860 	gp_widget_set_name (*widget, menu->name);
4861 	gp_widget_set_range (*widget,
4862 		dpd->FORM.Range.MinimumValue.i8/6.0,
4863 		dpd->FORM.Range.MaximumValue.i8/6.0,
4864 		dpd->FORM.Range.StepSize.i8/6.0
4865 	);
4866 	value_float = dpd->CurrentValue.i8/6.0;
4867 	gp_widget_set_value (*widget, &value_float);
4868 	return GP_OK;
4869 }
4870 
4871 static int
_put_Nikon_FlashExposureCompensation(CONFIG_PUT_ARGS)4872 _put_Nikon_FlashExposureCompensation(CONFIG_PUT_ARGS) {
4873 	float val;
4874 
4875 	CR (gp_widget_get_value(widget, &val));
4876 	propval->i8 = 6.0*val;
4877 	return GP_OK;
4878 }
4879 
4880 static int
_get_Nikon_LowLight(CONFIG_GET_ARGS)4881 _get_Nikon_LowLight(CONFIG_GET_ARGS) {
4882 	float value_float;
4883 
4884 	if (!(dpd->FormFlag & PTP_DPFF_Range))
4885 		return (GP_ERROR);
4886 	if (dpd->DataType != PTP_DTC_UINT8)
4887 		return (GP_ERROR);
4888 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
4889 	gp_widget_set_name (*widget, menu->name);
4890 	gp_widget_set_range (*widget,
4891 		dpd->FORM.Range.MinimumValue.u8,
4892 		dpd->FORM.Range.MaximumValue.u8,
4893 		dpd->FORM.Range.StepSize.u8
4894 	);
4895 	value_float = dpd->CurrentValue.u8;
4896 	gp_widget_set_value (*widget, &value_float);
4897 	return (GP_OK);
4898 }
4899 
4900 static int
_get_Canon_EOS_WBAdjust(CONFIG_GET_ARGS)4901 _get_Canon_EOS_WBAdjust(CONFIG_GET_ARGS) {
4902 	int i, valset = 0;
4903 	char buf[200];
4904 
4905 	if (dpd->DataType != PTP_DTC_INT32)
4906 		return (GP_ERROR);
4907 	if (!(dpd->FormFlag & PTP_DPFF_Enumeration))
4908 		return (GP_ERROR);
4909 
4910 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
4911 	gp_widget_set_name (*widget, menu->name);
4912 
4913 	for (i = 0; i<dpd->FORM.Enum.NumberOfValues; i++) {
4914 		sprintf (buf, "%d", dpd->FORM.Enum.SupportedValue[i].i32);
4915 		gp_widget_add_choice (*widget,buf);
4916 		if (dpd->CurrentValue.i32 == dpd->FORM.Enum.SupportedValue[i].i32) {
4917 			gp_widget_set_value (*widget, buf);
4918 			valset = 1;
4919 		}
4920 	}
4921 	if (!valset) {
4922 		sprintf (buf, "%d",dpd->CurrentValue.i32);
4923 		gp_widget_set_value (*widget, buf);
4924 	}
4925 	return GP_OK;
4926 }
4927 
4928 static int
_put_Canon_EOS_WBAdjust(CONFIG_PUT_ARGS)4929 _put_Canon_EOS_WBAdjust(CONFIG_PUT_ARGS) {
4930 	int x;
4931 	const char *value_str;
4932 
4933 	gp_widget_get_value (widget, &value_str);
4934 	if (!sscanf (value_str, "%d", &x))
4935 		return GP_ERROR;
4936 	propval->i32 = x;
4937 	return GP_OK;
4938 }
4939 
4940 static struct deviceproptableu8 nikon_liveviewaf[] = {
4941 	{ N_("Face-priority AF"),	0, 0 },
4942 	{ N_("Wide-area AF"),		1, 0 },
4943 	{ N_("Normal-area AF"),		2, 0 },
4944 	{ N_("Subject-tracking AF"),	3, 0 },
4945 	{ N_("Spot-area AF"),		4, 0 },
4946 };
4947 GENERIC8TABLE(Nikon_LiveViewAFU,nikon_liveviewaf)
4948 
4949 static struct deviceproptableu8 nikon_liveviewimagezoomratio[] = {
4950 	{ N_("Entire Display"),	0, 0 },
4951 	{ N_("25%"),		2, 0 },
4952 	{ N_("50%"),		4, 0 },
4953 	{ N_("100%"),		6, 0 },
4954 	{ N_("200%"),		7, 0 },
4955 };
4956 GENERIC8TABLE(Nikon_LiveViewImageZoomRatio,nikon_liveviewimagezoomratio)
4957 
4958 static struct deviceproptablei8 nikon_liveviewafi[] = {
4959 	{ N_("Face-priority AF"),	0, 0 },
4960 	{ N_("Wide-area AF"),		1, 0 },
4961 	{ N_("Normal-area AF"),		2, 0 },
4962 	{ N_("Subject-tracking AF"),	3, 0 },
4963 	{ N_("Spot-area AF"),		4, 0 },
4964 };
4965 GENERICI8TABLE(Nikon_LiveViewAFI,nikon_liveviewafi)
4966 
4967 static struct deviceproptableu8 nikon_liveviewaffocus[] = {
4968 	{ N_("Single-servo AF"),		0, 0 },
4969 	{ N_("Continuous-servo AF"),		1, 0 },
4970 	{ N_("Full-time-servo AF"),		2, 0 },
4971 	{ N_("Manual Focus (fixed)"),		3, 0 },
4972 	{ N_("Manual Focus (selection)"),	4, 0 },
4973 };
4974 GENERIC8TABLE(Nikon_LiveViewAFFocus,nikon_liveviewaffocus)
4975 
4976 static struct deviceproptableu8 nikon_afareaillum[] = {
4977 	{ N_("Auto"),		0, 0 },
4978 	{ N_("Off"),		1, 0 },
4979 	{ N_("On"),		2, 0 },
4980 };
4981 GENERIC8TABLE(Nikon_AFAreaIllum,nikon_afareaillum)
4982 
4983 
4984 static struct deviceproptableu8 nikon_aelaflmode[] = {
4985 	{ N_("AE/AF Lock"),	0x00, 0 },
4986 	{ N_("AE Lock only"),	0x01, 0 },
4987 	{ N_("AF Lock Only"),	0x02, 0 },
4988 	{ N_("AF Lock Hold"),	0x03, 0 },
4989 	{ N_("AF On"),		0x04, 0 },
4990 	{ N_("Flash Level Lock"),0x05, 0 },
4991 };
4992 GENERIC8TABLE(Nikon_AELAFLMode,nikon_aelaflmode)
4993 
4994 static struct deviceproptableu8 nikon_lcdofftime[] = {
4995 	{ N_("10 seconds"),	0x00, 0 },
4996 	{ N_("20 seconds"),	0x01, 0 },
4997 	{ N_("1 minute"),	0x02, 0 },
4998 	{ N_("5 minutes"),	0x03, 0 },
4999 	{ N_("10 minutes"),	0x04, 0 },
5000 	{ N_("5 seconds"),	0x05, 0 },	/* d80 observed */
5001 };
5002 GENERIC8TABLE(Nikon_LCDOffTime,nikon_lcdofftime)
5003 
5004 static struct deviceproptableu8 nikon_recordingmedia[] = {
5005 	{ N_("Card"),		0x00, 0 },
5006 	{ N_("SDRAM"),		0x01, 0 },
5007 };
5008 GENERIC8TABLE(Nikon_RecordingMedia,nikon_recordingmedia)
5009 
5010 static struct deviceproptableu8 nikon_selftimerdelay[] = {
5011 	{ N_("2 seconds"),	0x00, 0 },
5012 	{ N_("5 seconds"),	0x01, 0 },
5013 	{ N_("10 seconds"),	0x02, 0 },
5014 	{ N_("20 seconds"),	0x03, 0 },
5015 };
5016 GENERIC8TABLE(Nikon_SelfTimerDelay,nikon_selftimerdelay)
5017 
5018 static struct deviceproptableu8 nikon_centerweight[] = {
5019 	{ N_("6 mm"),	0x00, 0 },
5020 	{ N_("8 mm"),	0x01, 0 },
5021 	{ N_("10 mm"),	0x02, 0 },
5022 	{ N_("12 mm"),	0x03, 0 },
5023 	{ N_("Average"),0x04, 0 },	/* ? */
5024 };
5025 GENERIC8TABLE(Nikon_CenterWeight,nikon_centerweight)
5026 
5027 static struct deviceproptableu8 nikon_d850_centerweight[] = {
5028 	{ N_("8 mm"),	0x00, 0 },
5029 	{ N_("12 mm"),	0x01, 0 },
5030 	{ N_("15 mm"),	0x02, 0 },
5031 	{ N_("20 mm"),	0x03, 0 },
5032 	{ N_("Average"),0x04, 0 },
5033 };
5034 GENERIC8TABLE(Nikon_D850_CenterWeight,nikon_d850_centerweight)
5035 
5036 static struct deviceproptableu8 nikon_flashshutterspeed[] = {
5037 	{ N_("1/60"),	0x00, 0 },
5038 	{ N_("1/30"),	0x01, 0 },
5039 	{ N_("1/15"),	0x02, 0 },
5040 	{ N_("1/8"),	0x03, 0 },
5041 	{ N_("1/4"),	0x04, 0 },
5042 	{ N_("1/2"),	0x05, 0 },
5043 	{ N_("1"),	0x06, 0 },
5044 	{ N_("2"),	0x07, 0 },
5045 	{ N_("4"),	0x08, 0 },
5046 	{ N_("8"),	0x09, 0 },
5047 	{ N_("15"),	0x0a, 0 },
5048 	{ N_("30"),	0x0b, 0 },
5049 };
5050 GENERIC8TABLE(Nikon_FlashShutterSpeed,nikon_flashshutterspeed)
5051 
5052 static struct deviceproptablei16 fuji_shutterspeed[] = {
5053 	{ N_("bulb"),	-31, 0 },
5054 	{ N_("30s"),	-30, 0 },
5055 	{ N_("25s"),	-28, 0 },
5056 	{ N_("20s"),	-26, 0 },
5057 	{ N_("15s"),	-24, 0 },
5058 	{ N_("13s"),	-22, 0 },
5059 	{ N_("10s"),	-20, 0 },
5060 	{ N_("8s"),	-18, 0 },
5061 	{ N_("6s"),	-16, 0 },
5062 	{ N_("5s"),	-14, 0 },
5063 	{ N_("4s"),	-12, 0 },
5064 	{ N_("3s"),	-10, 0 },
5065 	{ N_("2.5s"),	-8, 0 },
5066 	{ N_("2s"),	-6, 0 },
5067 	{ N_("1.6s"),	-4, 0 },
5068 	{ N_("1.3s"),	-2, 0 },
5069 	{ N_("1s"),	0, 0 },
5070 	{ N_("1/1.3s"),	2, 0 },
5071 	{ N_("1/1.6s"),	4, 0 },
5072 	{ N_("1/2s"),	6, 0 },
5073 	{ N_("1/2.5s"),	8, 0 },
5074 	{ N_("1/3s"),	10, 0 },
5075 	{ N_("1/4s"),	12, 0 },
5076 	{ N_("1/5s"),	14, 0 },
5077 	{ N_("1/6s"),	16, 0 },
5078 	{ N_("1/8s"),	18, 0 },
5079 	{ N_("1/10s"),	20, 0 },
5080 	{ N_("1/13s"),	22, 0 },
5081 	{ N_("1/15s"),	24, 0 },
5082 	{ N_("1/20s"),	26, 0 },
5083 	{ N_("1/25s"),	28, 0 },
5084 	{ N_("1/30s"),	30, 0 },
5085 	{ N_("1/40s"),	32, 0 },
5086 	{ N_("1/50s"),	34, 0 },
5087 	{ N_("1/60s"),	36, 0 },
5088 	{ N_("1/80s"),	38, 0 },
5089 	{ N_("1/100s"),	40, 0 },
5090 	{ N_("1/125s"),	42, 0 },
5091 	{ N_("1/160s"),	44, 0 },
5092 	{ N_("1/200s"),	46, 0 },
5093 	{ N_("1/250s"),	48, 0 },
5094 	{ N_("1/320s"),	50, 0 },
5095 	{ N_("1/400s"),	52, 0 },
5096 	{ N_("1/500s"),	54, 0 },
5097 	{ N_("1/640s"),	56, 0 },
5098 	{ N_("1/800s"),	58, 0 },
5099 	{ N_("1/1000s"),60, 0 },
5100 	{ N_("1/1250s"),62, 0 },
5101 	{ N_("1/1250s"),62, 0 },
5102 	{ N_("1/1600s"),64, 0 },
5103 	{ N_("1/2000s"),66, 0 },
5104 	{ N_("1/2500s"),68, 0 },
5105 	{ N_("1/3200s"),70, 0 },
5106 	{ N_("1/4000s"),72, 0 },
5107 	{ N_("1/5000s"),74, 0 },
5108 	{ N_("1/6400s"),76, 0 },
5109 	{ N_("1/8000s"),78, 0 },
5110 };
5111 GENERICI16TABLE(Fuji_ShutterSpeed,fuji_shutterspeed)
5112 
5113 static struct deviceproptableu32 fuji_new_shutterspeed[] = {
5114 	{ N_("bulb"),	0xffffffff, 0 },
5115 	{ "60m",	64000180, 0 },
5116 	{ "30m",	64000150, 0 },
5117 	{ "15m",	64000120, 0 },
5118 	{ "8m",		64000090, 0 },
5119 	{ "4m",		64000060, 0 },
5120 	{ "2m",		64000030, 0 },
5121 	{ "60s",	64000000, 0 },
5122 	{ "50s",	50796833, 0 },
5123 	{ "40s",	40317473, 0 },
5124 	{ "30s",	32000000, 0 },
5125 	{ "25s",	25398416, 0 },
5126 	{ "20s",	20158736, 0 },
5127 	{ "15s",	16000000, 0 },
5128 	{ "13s",	12699208, 0 },
5129 	{ "10s",	10079368, 0 },
5130 	{ "8s",		8000000, 0 },
5131 	{ "6s",		6349604, 0 },
5132 	{ "5s",		5039684, 0 },
5133 	{ "4s",		4000000, 0 },
5134 	{ "3s",		3174802, 0 },
5135 	{ "2.5s",	2519842, 0 },
5136 	{ "2s",		2000000, 0 },
5137 	{ "1.6s",	1587401, 0 },
5138 	{ "1.3s",	1259921, 0 },
5139 	{ "1s",		1000000, 0 },
5140 	{ "0.8s",	793700, 0 },
5141 	{ "0.6s",	629960, 0 },
5142 	{ "1/2",	500000, 0 },
5143 	{ "0.4s",	396850, 0 },
5144 	{ "1/3",	314980, 0 },
5145 	{ "1/4",	250000, 0 },
5146 	{ "1/5",	198425, 0 },
5147 	{ "1/6",	157490, 0 },
5148 	{ "1/8",	125000, 0 },
5149 	{ "1/10",	99212, 0 },
5150 	{ "1/13",	78745, 0 },
5151 	{ "1/15",	62500, 0 },
5152 	{ "1/20",	49606, 0 },
5153 	{ "1/25",	39372, 0 },
5154 	{ "1/30",	31250, 0 },
5155 	{ "1/40",	24803, 0 },
5156 	{ "1/50",	19686, 0 },
5157 	{ "1/60",	15625, 0 },
5158 	{ "1/80",	12401, 0 },
5159 	{ "1/100",	9843, 0 },
5160 	{ "1/125",	7812, 0 },
5161 	{ "1/160",	6200, 0 },
5162 	{ "1/200",	4921, 0 },
5163 	{ "1/250",	3906, 0 },
5164 	{ "1/320",	3100, 0 },
5165 	{ "1/400",	2460, 0 },
5166 	{ "1/500",	1953, 0 },
5167 	{ "1/640",	1550, 0 },
5168 	{ "1/800",	1230, 0 },
5169 	{ "1/1000",	976, 0 },
5170 	{ "1/1250",	775, 0 },
5171 	{ "1/1600",	615, 0 },
5172 	{ "1/2000",	488, 0 },
5173 	{ "1/2500",	387, 0 },
5174 	{ "1/3200",	307, 0 },
5175 	{ "1/4000",	244, 0 },
5176 	{ "1/5000",	193, 0 },
5177 	{ "1/6400",	153, 0 },
5178 	{ "1/8000",	122, 0 },
5179 	{ "1/10000",	96, 0 },
5180 	{ "1/13000",	76, 0 },
5181 	{ "1/16000",	61, 0 },
5182 	{ "1/20000",	48, 0 },
5183 	{ "1/25000",	38, 0 },
5184 	{ "1/32000",	30, 0 },
5185 };
5186 GENERIC32TABLE(Fuji_New_ShutterSpeed,fuji_new_shutterspeed)
5187 
5188 static struct deviceproptableu8 nikon_remotetimeout[] = {
5189 	{ N_("1 minute"),	0x00,	0 },
5190 	{ N_("5 minutes"),	0x01,	0 },
5191 	{ N_("10 minutes"),	0x02,	0 },
5192 	{ N_("15 minutes"),	0x03,	0 },
5193 };
5194 GENERIC8TABLE(Nikon_RemoteTimeout,nikon_remotetimeout)
5195 
5196 static struct deviceproptableu8 nikon_optimizeimage[] = {
5197 	{ N_("Normal"),		0x00,	0 },
5198 	{ N_("Vivid"),		0x01,	0 },
5199 	{ N_("Sharper"),	0x02, 0 },
5200 	{ N_("Softer"),		0x03, 0 },
5201 	{ N_("Direct Print"),	0x04, 0 },
5202 	{ N_("Portrait"),	0x05, 0 },
5203 	{ N_("Landscape"),	0x06, 0 },
5204 	{ N_("Custom"),		0x07, 0 },
5205 };
5206 GENERIC8TABLE(Nikon_OptimizeImage,nikon_optimizeimage)
5207 
5208 static struct deviceproptableu8 nikon_sharpening[] = {
5209 	{ N_("Auto"),		0x00, 0 },
5210 	{ N_("Normal"),		0x01, 0 },
5211 	{ N_("Low"),		0x02, 0 },
5212 	{ N_("Medium Low"),	0x03, 0 },
5213 	{ N_("Medium high"),	0x04, 0 },
5214 	{ N_("High"),		0x05, 0 },
5215 	{ N_("None"),		0x06, 0 },
5216 };
5217 GENERIC8TABLE(Nikon_Sharpening,nikon_sharpening)
5218 
5219 static struct deviceproptableu8 nikon_tonecompensation[] = {
5220 	{ N_("Auto"),		0x00, 0 },
5221 	{ N_("Normal"),		0x01, 0 },
5222 	{ N_("Low contrast"),	0x02, 0 },
5223 	{ N_("Medium Low"),	0x03, 0 },
5224 	{ N_("Medium High"),	0x04, 0 },
5225 	{ N_("High control"),	0x05, 0 },
5226 	{ N_("Custom"),		0x06, 0 },
5227 };
5228 GENERIC8TABLE(Nikon_ToneCompensation,nikon_tonecompensation)
5229 
5230 static struct deviceproptableu8 canon_afdistance[] = {
5231 	{ N_("Manual"),			0x00, 0 },
5232 	{ N_("Auto"),			0x01, 0 },
5233 	{ N_("Unknown"),		0x02, 0 },
5234 	{ N_("Zone Focus (Close-up)"),	0x03, 0 },
5235 	{ N_("Zone Focus (Very Close)"),0x04, 0 },
5236 	{ N_("Zone Focus (Close)"),	0x05, 0 },
5237 	{ N_("Zone Focus (Medium)"),	0x06, 0 },
5238 	{ N_("Zone Focus (Far)"),	0x07, 0 },
5239 	{ N_("Zone Focus (Reserved 1)"),0x08, 0 },
5240 	{ N_("Zone Focus (Reserved 2)"),0x09, 0 },
5241 	{ N_("Zone Focus (Reserved 3)"),0x0a, 0 },
5242 	{ N_("Zone Focus (Reserved 4)"),0x0b, 0 },
5243 };
5244 GENERIC8TABLE(Canon_AFDistance,canon_afdistance)
5245 
5246 
5247 /* Focus Modes as per PTP standard. |0x8000 means vendor specific. */
5248 static struct deviceproptableu16 focusmodes[] = {
5249 	{ N_("Undefined"),	0x0000, 0 },
5250 	{ N_("Manual"),		0x0001, 0 },
5251 	{ N_("Automatic"),	0x0002, 0 },
5252 	{ N_("Automatic Macro"),0x0003, 0 },
5253 	{ N_("AF-S"),		0x8010, PTP_VENDOR_NIKON },
5254 	{ N_("AF-C"),		0x8011, PTP_VENDOR_NIKON },
5255 	{ N_("AF-A"),		0x8012, PTP_VENDOR_NIKON },
5256 	{ N_("Single-Servo AF"),0x8001, PTP_VENDOR_FUJI },
5257 	{ N_("Continuous-Servo AF"),0x8002, PTP_VENDOR_FUJI },
5258 
5259 	{ N_("C-AF"),		0x8002, PTP_VENDOR_GP_OLYMPUS_OMD },
5260 	{ N_("S-AF+MF"),	0x8001, PTP_VENDOR_GP_OLYMPUS_OMD },
5261 
5262 	{ N_("AF-A"),		0x8005, PTP_VENDOR_SONY },
5263 	{ N_("AF-C"),		0x8004, PTP_VENDOR_SONY },
5264 	{ N_("DMF"),		0x8006, PTP_VENDOR_SONY },
5265 
5266 };
GENERIC16TABLE(FocusMode,focusmodes)5267 GENERIC16TABLE(FocusMode,focusmodes)
5268 
5269 /* Sony specific, we need to wait for it settle (around 1 second), otherwise we get trouble later on */
5270 static int
5271 _put_Sony_FocusMode(CONFIG_PUT_ARGS) {
5272 	PTPParams		*params = &(camera->pl->params);
5273 	GPContext 		*context = ((PTPData *) params->data)->context;
5274 	int 			ret;
5275 	PTPDevicePropDesc	dpd2;
5276 	time_t			start,end;
5277 
5278 	ret = _put_FocusMode(CONFIG_PUT_NAMES);
5279 	if (ret != GP_OK) return ret;
5280 	start = time(NULL);
5281 	C_PTP_REP (ptp_generic_setdevicepropvalue (params, PTP_DPC_FocusMode, propval, PTP_DTC_UINT16));
5282 	while (1) {
5283 		C_PTP_REP (ptp_sony_getalldevicepropdesc (params));
5284 		C_PTP_REP (ptp_generic_getdevicepropdesc (params, PTP_DPC_FocusMode, &dpd2));
5285 		if (dpd2.CurrentValue.u16 == propval->u16)
5286 			break;
5287 		end = time(NULL);
5288 		if (end-start >= 3) {
5289 			GP_LOG_E("failed to change variable to %d (current %d)\n", propval->u16, dpd2.CurrentValue.u16);
5290 			break;
5291 		}
5292 	}
5293 	return GP_OK;
5294 }
5295 
5296 
5297 static struct deviceproptableu16 eos_focusmodes[] = {
5298 	{ N_("One Shot"),	0x0000, 0 },
5299 	{ N_("AI Servo"),	0x0001, 0 },
5300 	{ N_("AI Focus"),	0x0002, 0 },
5301 	{ N_("Manual"),		0x0003, 0 },
5302 };
5303 GENERIC16TABLE(Canon_EOS_FocusMode,eos_focusmodes)
5304 
5305 static struct deviceproptableu16 eos_quickreviewtime[] = {
5306 	{ N_("None"),		0x0000, 0 },
5307 	{ N_("2 seconds"),	0x0002, 0 },
5308 	{ N_("4 seconds"),	0x0004, 0 },
5309 	{ N_("8 seconds"),	0x0008, 0 },
5310 	{ N_("Hold"),		0x00ff, 0 },
5311 };
5312 GENERIC16TABLE(Canon_EOS_QuickReviewTime,eos_quickreviewtime)
5313 
5314 
5315 static struct deviceproptableu8 canon_whitebalance[] = {
5316 	{ N_("Auto"),			0, 0 },
5317 	{ N_("Daylight"),		1, 0 },
5318 	{ N_("Cloudy"),			2, 0 },
5319 	{ N_("Tungsten"),		3, 0 },
5320 	{ N_("Fluorescent"),		4, 0 },
5321 	{ N_("Custom"),			6, 0 },
5322 	{ N_("Fluorescent H"),		7, 0 },
5323 	{ N_("Color Temperature"),	9, 0 },
5324 	{ N_("Custom Whitebalance PC-1"),	10, 0 },
5325 	{ N_("Custom Whitebalance PC-2"),	11, 0 },
5326 	{ N_("Custom Whitebalance PC-3"),	12, 0 },
5327 	{ N_("Missing Number"),		13, 0 },
5328 	/*{ N_("Fluorescent H"),		14, 0 }, ... dup? */
5329 };
5330 GENERIC8TABLE(Canon_WhiteBalance,canon_whitebalance)
5331 
5332 /* check against SDK */
5333 static struct deviceproptableu8 canon_eos_whitebalance[] = {
5334 	{ N_("Auto"),		0, 0 },
5335 	{ N_("Daylight"),	1, 0 },
5336 	{ N_("Cloudy"),		2, 0 },
5337 	{ N_("Tungsten"),	3, 0 },
5338 	{ N_("Fluorescent"),	4, 0 },
5339 	{ N_("Flash"),		5, 0 },
5340 	{ N_("Manual"),		6, 0 },
5341 	{"Unknown 7",		7, 0 },
5342 	{ N_("Shadow"),		8, 0 },
5343 	{ N_("Color Temperature"),9, 0 },
5344 	{ N_("Custom Whitebalance: PC-1"),		10, 0 },
5345 	{ N_("Custom Whitebalance: PC-2"),		11, 0 },
5346 	{ N_("Custom Whitebalance: PC-3"),		12, 0 },
5347 	{ N_("Manual 2"),	15, 0 },
5348 	{ N_("Manual 3"),	16, 0 },
5349 	{ N_("Manual 4"),	18, 0 },
5350 	{ N_("Manual 5"),	19, 0 },
5351 	{ N_("Custom Whitebalance: PC-4"),		20, 0 },
5352 	{ N_("Custom Whitebalance: PC-5"),		21, 0 },
5353 	{ N_("AWB White"),	23, 0 },
5354 };
5355 GENERIC8TABLE(Canon_EOS_WhiteBalance,canon_eos_whitebalance)
5356 
5357 
5358 static struct deviceproptableu8 canon_expcompensation[] = {
5359 	{ N_("Factory Default"),0xff, 0 },
5360 	{ "+3",			0x00, 0 },
5361 	{ "+2 2/3",		0x03, 0 },
5362 	{ "+2 1/2",		0x04, 0 },
5363 	{ "+2 1/3",		0x05, 0 },
5364 	{ "+2",			0x08, 0 },
5365 	{ "+1 2/3",		0x0b, 0 },
5366 	{ "+1 1/2",		0x0c, 0 },
5367 	{ "+1 1/3",		0x0d, 0 },
5368 	{ "+1",			0x10, 0 },
5369 	{ "+2/3",		0x13, 0 },
5370 	{ "+1/2",		0x14, 0 },
5371 	{ "+1/3",		0x15, 0 },
5372 	{ "0",			0x18, 0 },
5373 	{ "-1/3",		0x1b, 0 },
5374 	{ "-1/2",		0x1c, 0 },
5375 	{ "-2/3",		0x1d, 0 },
5376 	{ "-1",			0x20, 0 },
5377 	{ "-1 1/3",		0x23, 0 },
5378 	{ "-1 1/2",		0x24, 0 },
5379 	{ "-1 2/3",		0x25, 0 },
5380 	{ "-2",			0x28, 0 },
5381 	{ "-2 1/3",		0x2b, 0 },
5382 	{ "-2 1/2",		0x2c, 0 },
5383 	{ "-2 2/3",		0x2d, 0 },
5384 	{ "-3",			0x30, 0 },
5385 };
5386 GENERIC8TABLE(Canon_ExpCompensation,canon_expcompensation)
5387 
5388 static struct deviceproptableu8 canon_expcompensation2[] = {
5389 	{ "5",		0x28, 0 },
5390 	{ "4.6",	0x25, 0 },
5391 	{ "4.5",	0x24, 0 },
5392 	{ "4.3",	0x23, 0 },
5393 	{ "4",		0x20, 0 },
5394 	{ "3.6",	0x1d, 0 },
5395 	{ "3.5",	0x1c, 0 },
5396 	{ "3.3",	0x1b, 0 },
5397 	{ "3",		0x18, 0 },
5398 	{ "2.6",	0x15, 0 },
5399 	{ "2.5",	0x14, 0 },
5400 	{ "2.3",	0x13, 0 },
5401 	{ "2",		0x10, 0 },
5402 	{ "1.6",	0x0d, 0 },
5403 	{ "1.5",	0x0c, 0 },
5404 	{ "1.3",	0x0b, 0 },
5405 	{ "1",		0x08, 0 },
5406 	{ "1.0",	0x08, 0 },
5407 	{ "0.6",	0x05, 0 },
5408 	{ "0.5",	0x04, 0 },
5409 	{ "0.3",	0x03, 0 },
5410 	{ "0",		0x00, 0 },
5411 	{ "-0.3",	0xfd, 0 },
5412 	{ "-0.5",	0xfc, 0 },
5413 	{ "-0.6",	0xfb, 0 },
5414 	{ "-1",		0xf8, 0 },
5415 	{ "-1.0",	0xf8, 0 },
5416 	{ "-1.3",	0xf5, 0 },
5417 	{ "-1.5",	0xf4, 0 },
5418 	{ "-1.6",	0xf3, 0 },
5419 	{ "-2",		0xf0, 0 },
5420 	{ "-2.3",	0xed, 0 },
5421 	{ "-2.5",	0xec, 0 },
5422 	{ "-2.6",	0xeb, 0 },
5423 	{ "-3",		0xe8, 0 },
5424 	{ "-3.3",	0xe5, 0 },
5425 	{ "-3.5",	0xe4, 0 },
5426 	{ "-3.6",	0xe3, 0 },
5427 	{ "-4",		0xe0, 0 },
5428 	{ "-4.3",	0xdd, 0 }, /*Canon EOS 5D Mark III*/
5429 	{ "-4.5",	0xdc, 0 },
5430 	{ "-4.6",	0xdb, 0 },
5431 	{ "-5",		0xd8, 0 },
5432 };
5433 GENERIC8TABLE(Canon_ExpCompensation2,canon_expcompensation2)
5434 
5435 
5436 static struct deviceproptableu16 canon_photoeffect[] = {
5437 	{ N_("Off"),		0, 0 },
5438 	{ N_("Vivid"),		1, 0 },
5439 	{ N_("Neutral"),	2, 0 },
5440 	{ N_("Low sharpening"),	3, 0 },
5441 	{ N_("Sepia"),		4, 0 },
5442 	{ N_("Black & white"),	5, 0 },
5443 };
5444 GENERIC16TABLE(Canon_PhotoEffect,canon_photoeffect)
5445 
5446 
5447 /* FIXME: actually uint32 in SDK doc? also non-standard type in debuglogs */
5448 static struct deviceproptableu16 canon_bracketmode[] = {
5449 	{ N_("AE bracket"),	1, 0 },
5450 	{ N_("ISO bracket"),	2, 0 },
5451 	{ N_("WB bracket"),	4, 0 },
5452 	{ N_("FE bracket"),	8, 0 },
5453 	{ N_("Bracket off"),	0xffff, 0 },
5454 };
5455 GENERIC16TABLE(Canon_BracketMode,canon_bracketmode)
5456 
5457 static struct deviceproptableu16 canon_aperture[] = {
5458 	{ N_("implicit auto"),	0x0, 0 },
5459 	{ N_("auto"),	0xffff, 0 },
5460 	{ "1",		0x0008, 0 },
5461 	{ "1.1",	0x000b, 0 },
5462 	{ "1.2",	0x000c, 0 },
5463 	{ "1.2",	0x000d, 0 }, /* (1/3)? */
5464 	{ "1.4",	0x0010, 0 },
5465 	{ "1.6",	0x0013, 0 },
5466 	{ "1.8",	0x0014, 0 },
5467 	{ "1.8",	0x0015, 0 }, /* (1/3)? */
5468 	{ "2",		0x0018, 0 },
5469 	{ "2.2",	0x001b, 0 },
5470 	{ "2.5",	0x001c, 0 },
5471 	{ "2.5",	0x001d, 0 }, /* (1/3)? */
5472 	{ "2.8",	0x0020, 0 },
5473 	{ "3.2",	0x0023, 0 },
5474 	{ "3.5",	0x0024, 0 },
5475 	{ "3.5",	0x0025, 0 }, /* (1/3)? */
5476 	{ "4",		0x0028, 0 },
5477 	{ "4.5",	0x002c, 0 },
5478 	{ "4.5",	0x002b, 0 }, /* (1/3)? */
5479 	{ "5",		0x002d, 0 }, /* 5.6 (1/3)??? */
5480 	{ "5.6",	0x0030, 0 },
5481 	{ "6.3",	0x0033, 0 },
5482 	{ "6.7",	0x0034, 0 },
5483 	{ "7.1",	0x0035, 0 },
5484 	{ "8",		0x0038, 0 },
5485 	{ "9",		0x003b, 0 },
5486 	{ "9.5",	0x003c, 0 },
5487 	{ "10",		0x003d, 0 },
5488 	{ "11",		0x0040, 0 },
5489 	{ "13",		0x0043, 0 }, /* (1/3)? */
5490 	{ "13",		0x0044, 0 },
5491 	{ "14",		0x0045, 0 },
5492 	{ "16",		0x0048, 0 },
5493 	{ "18",		0x004b, 0 },
5494 	{ "19",		0x004c, 0 },
5495 	{ "20",		0x004d, 0 },
5496 	{ "22",		0x0050, 0 },
5497 	{ "25",		0x0053, 0 },
5498 	{ "27",		0x0054, 0 },
5499 	{ "29",		0x0055, 0 },
5500 	{ "32",		0x0058, 0 },
5501 	{ "36",		0x005b, 0 },
5502 	{ "38",		0x005c, 0 },
5503 	{ "40",		0x005d, 0 },
5504 	{ "45",		0x0060, 0 },
5505 	{ "51",		0x0063, 0 },
5506 	{ "54",		0x0064, 0 },
5507 	{ "57",		0x0065, 0 },
5508 	{ "64",		0x0068, 0 },
5509 	{ "72",		0x006b, 0 },
5510 	{ "76",		0x006c, 0 },
5511 	{ "81",		0x006d, 0 },
5512 	{ "91",		0x0070, 0 },
5513 };
5514 GENERIC16TABLE(Canon_Aperture,canon_aperture)
5515 
5516 static struct deviceproptableu16 fuji_aperture[] = {
5517 	{ "1.8",	10, 0 },
5518 	{ "2",		12, 0 },
5519 	{ "2.2",	14, 0 },
5520 	{ "2.5",	16, 0 },
5521 	{ "2.8",	18, 0 },
5522 	{ "3.2",	20, 0 },
5523 	{ "3.5",	22, 0 },
5524 	{ "4",		24, 0 },
5525 	{ "4.5",	26, 0 },
5526 	{ "5",		28, 0 },
5527 	{ "5.6",	30, 0 },
5528 	{ "6.3",	32, 0 },
5529 	{ "7.1",	34, 0 },
5530 	{ "8",		36, 0 },
5531 	{ "9",		38, 0 },
5532 	{ "10",		40, 0 },
5533 	{ "11",		42, 0 },
5534 	{ "13",		44, 0 },
5535 	{ "14",		46, 0 },
5536 	{ "16",		48, 0 },
5537 	{ "18",		50, 0 },
5538 	{ "20",		52, 0 },
5539 	{ "22",		54, 0 },
5540 	{ "25",		56, 0 },
5541 	{ "29",		58, 0 },
5542 	{ "32",		60, 0 },
5543 	{ "36",		62, 0 },
5544 };
5545 GENERIC16TABLE(Fuji_Aperture,fuji_aperture)
5546 
5547 /* The j5 only reports some of those, there is no clear pattern... fill in with more 1 series */
5548 static struct deviceproptableu8 nikon_1_aperture[] = {
5549 	/* 1 */
5550 	/* 1.1 */
5551 	/* 1.2 */
5552 	/* 1.3 */
5553 	/* 1.4 */
5554 	/* 1.5 */
5555 	/* 1.6 */
5556 	/* 1.7 */
5557 	{ "1.8",	10, 0 },
5558 	/* 1.9 */
5559 	{ "2",		12, 0 },
5560 	{ "2.2",	14, 0 },
5561 	/* 2.4 */
5562 	{ "2.5",	16, 0 },
5563 	/* 2.7 */
5564 	{ "2.8",	18, 0 },
5565 	/* 3 */
5566 	{ "3.2",	20, 0 },
5567 	{ "3.5",	22, 0 },
5568 	/* 3.8 */
5569 	{ "4",		24, 0 },
5570 	/* 4.2 */
5571 	{ "4.5",	26, 0 },
5572 	/* 4.8 */
5573 	{ "5",		28, 0 },
5574 	/* 5.3 */
5575 	{ "5.6",	30, 0 },
5576 	/* 6 */
5577 	{ "6.3",	32, 0 },
5578 	/* 6.7 */
5579 	{ "7.1",	34, 0 },
5580 	/* 7.6 */
5581 	{ "8",		36, 0 },
5582 	/* 8.5 */
5583 	{ "9", 		38, 0 },
5584 	/* 9.5 */
5585 	{ "10", 	40, 0 },
5586 	{ "11", 	42, 0 },
5587 	/* 12 */
5588 	{ "13",		44, 0 },
5589 	{ "14", 	46, 0 },
5590 	/* 15 */
5591 	{ "16",		48, 0 },
5592 	/* 17 */
5593 	/* 18 */
5594 	/* 19 */
5595 	/* 20 */
5596 	/* 21 */
5597 	/* 22 */
5598 	/* 24 */
5599 	/* 25 */
5600 	/* 27.6 */
5601 	/* 29 */
5602 	/* 30 */
5603 	/* 32 */
5604 	/* 0 */
5605 };
5606 GENERIC8TABLE(Nikon_1_Aperture,nikon_1_aperture)
5607 
5608 /* The j5 only reports some of those, there is no clear pattern... fill in with more 1 series */
5609 static struct deviceproptablei8 nikon_1_shutterspeedi[] = {
5610 	{ "Bulb",	-31, 0 },
5611 	{ "30",		-30, 0 },
5612 	{ "25",		-28, 0 },
5613 	{ "20",		-26, 0 },
5614 	{ "15",		-24, 0 },
5615 	{ "13",		-22, 0 },
5616 	{ "10",		-20, 0 },
5617 	{ "8",		-18, 0 },
5618 	{ "6",		-16, 0 },
5619 	{ "5",		-14, 0 },
5620 	{ "4",		-12, 0 },
5621 	{ "3",		-10, 0 },
5622 	{ "25/10",	-8, 0 },
5623 	{ "2",		-6, 0 },
5624 	{ "16/10",	-4, 0 },
5625 	/* { "15/10",	xx, 0 }, not in j5 */
5626 	{ "13/10",	-2, 0 },
5627 	{ "1",		 0, 0 },
5628 	{ "10/13",	 2, 0 }, /* 1 1/3 */
5629 	/* { "10/15", 	xx, 0 }, not in j5 */
5630 	{ "10/16",	 4, 0 },
5631 	{ "1/2",	 6, 0 },
5632 	{ "10/25",	 8, 0 },
5633 	{ "1/3",	10, 0 },
5634 	{ "1/4",	12, 0 },
5635 	{ "1/5",	14, 0 },
5636 	{ "1/6",	16, 0 },
5637 	{ "1/8",	18, 0 },
5638 	{ "1/10",	20, 0 },
5639 	{ "1/13",	22, 0 },
5640 	{ "1/15",	24, 0 },
5641 	{ "1/20",	26, 0 },
5642 	{ "1/25",	28, 0 },
5643 	{ "1/30",	30, 0 },
5644 	{ "1/40",	32, 0 },
5645 	/* { "1/45", xx, 0 }, not in j5 */
5646 	{ "1/50",	34, 0 },
5647 	{ "1/60",	36, 0 },
5648 	{ "1/80",	38, 0 },
5649 	/* { "1/90", xx, 0 } not in j5 */
5650 	{ "1/100",	40, 0 },
5651 	{ "1/125",	42, 0 },
5652 	{ "1/160",	44, 0 },
5653 	/* { "1/180", xx, 0 }, not in j5 */
5654 	{ "1/200",	46, 0 },
5655 	{ "1/250",	48, 0 },
5656 	{ "1/320",	50, 0 },
5657 	/* { "1/350", xx, 0 }, not in j5 */
5658 	{ "1/400",	52, 0 },
5659 	{ "1/500",	54, 0 },
5660 	{ "1/640",	56, 0 },
5661 	/* { "1/750",	xx, 0 }, not in j5 */
5662 	{ "1/800", 	58, 0 },
5663 	{ "1/1000",	60, 0 },
5664 	{ "1/1250",	62, 0 },
5665 	/* { "1/1500", xx, 0}, not in j5 */
5666 	{ "1/1600",	64, 0 },
5667 	{ "1/2000",	66, 0 },
5668 	{ "1/2500",	68, 0 },
5669 	/* { "1/3000",	xx, 0 }, not in j5 */
5670 	{ "1/3200",	70, 0 },
5671 	{ "1/4000",	72, 0 },
5672 	{ "1/5000",	74, 0 },
5673 	/*{ "1/6000",	xx, 0 }, not in j5 */
5674 	{ "1/6400",	76, 0 },
5675 	{ "1/8000",	78, 0 },
5676 	/* { "1/9000", xx , 0}, not in j5 */
5677 	{ "1/10000",	80, 0 },
5678 	/* { "1/12500", xx, 0 }, not in j5 */
5679 	{ "1/13000",	82, 0 },
5680 	/* { "1/15000", xx, 0 }, not in j5 */
5681 	{ "1/16000",	84, 0 },
5682 };
GENERICI8TABLE(Nikon_1_ShutterSpeedI,nikon_1_shutterspeedi)5683 GENERICI8TABLE(Nikon_1_ShutterSpeedI,nikon_1_shutterspeedi)
5684 
5685 static int
5686 _get_Nikon_1_ShutterSpeedU(CONFIG_GET_ARGS) {
5687 	dpd->DataType = PTP_DTC_INT8;
5688 	return _get_Nikon_1_ShutterSpeedI(CONFIG_GET_NAMES);
5689 }
5690 
5691 static int
_put_Nikon_1_ShutterSpeedU(CONFIG_PUT_ARGS)5692 _put_Nikon_1_ShutterSpeedU(CONFIG_PUT_ARGS) {
5693 	dpd->DataType = PTP_DTC_INT8;
5694 	return _put_Nikon_1_ShutterSpeedI(CONFIG_PUT_NAMES);
5695 }
5696 
5697 static struct deviceproptableu8 nikon_bracketset[] = {
5698 	{ N_("AE & Flash"),	0, 0 },
5699 	{ N_("AE only"),	1, 0 },
5700 	{ N_("Flash only"),	2, 0 },
5701 	{ N_("WB bracketing"),	3, 0 },
5702 	{ N_("ADL bracketing"),	4, 0 },
5703 };
5704 GENERIC8TABLE(Nikon_BracketSet,nikon_bracketset)
5705 
5706 static struct deviceproptableu8 nikon_cleansensor[] = {
5707 	{ N_("Off"),			0, 0 },
5708 	{ N_("Startup"),		1, 0 },
5709 	{ N_("Shutdown"),		2, 0 },
5710 	{ N_("Startup and Shutdown"),	3, 0 },
5711 };
5712 GENERIC8TABLE(Nikon_CleanSensor,nikon_cleansensor)
5713 
5714 static struct deviceproptableu8 nikon_flickerreduction[] = {
5715 	{ N_("50 Hz"),			0, 0 },
5716 	{ N_("60 Hz"),			1, 0 },
5717 	{ N_("Auto"),			2, 0 },
5718 };
5719 GENERIC8TABLE(Nikon_FlickerReduction,nikon_flickerreduction)
5720 
5721 static struct deviceproptableu8 nikon_remotemode[] = {
5722 	{ N_("Delayed Remote"),			0, 0 },
5723 	{ N_("Quick Response"),			1, 0 },
5724 	{ N_("Remote Mirror Up"),		2, 0 },
5725 };
5726 GENERIC8TABLE(Nikon_RemoteMode,nikon_remotemode)
5727 
5728 static struct deviceproptableu8 nikon_applicationmode[] = {
5729 	{ N_("Application Mode 0"),			0, 0 },
5730 	{ N_("Application Mode 1"),			1, 0 },
5731 };
5732 GENERIC8TABLE(Nikon_ApplicationMode,nikon_applicationmode)
5733 
5734 static struct deviceproptableu8 nikon_saturation[] = {
5735 	{ N_("Normal"),		0, 0 },
5736 	{ N_("Moderate"),	1, 0 },
5737 	{ N_("Enhanced"),	2, 0 },
5738 };
5739 GENERIC8TABLE(Nikon_Saturation,nikon_saturation)
5740 
5741 
5742 static struct deviceproptableu8 nikon_bracketorder[] = {
5743 	{ N_("MTR > Under"),	0, 0 },
5744 	{ N_("Under > MTR"),	1, 0 },
5745 };
5746 GENERIC8TABLE(Nikon_BracketOrder,nikon_bracketorder)
5747 
5748 /* There is a table for it in the internet */
5749 static struct deviceproptableu8 nikon_lensid[] = {
5750 	{N_("Unknown"),	0, 0},
5751 	{"Sigma 70-300mm 1:4-5.6 D APO Macro",		38, 0},
5752 	{"AF Nikkor 80-200mm 1:2.8 D ED",		83, 0},
5753 	{"AF Nikkor 50mm 1:1.8 D",			118, 0},
5754 	{"AF-S Nikkor 18-70mm 1:3.5-4.5G ED DX",	127, 0},
5755 	{"AF-S Nikkor 18-200mm 1:3.5-5.6 GED DX VR",	139, 0},
5756 	{"AF-S Nikkor 24-70mm 1:2.8G ED DX",		147, 0},
5757 	{"AF-S Nikkor 18-55mm 1:3.5-F5.6G DX VR",	154, 0},
5758 	{"AF-S Nikkor 35mm 1:1.8G DX", 			159, 0},
5759 	{"Sigma EX 30mm 1:1.4 DC HSM",			248, 0}, /* from mge */
5760 };
5761 GENERIC8TABLE(Nikon_LensID,nikon_lensid) /* FIXME: seen UINT8 and UINT16 types now */
5762 
5763 static struct deviceproptableu8 nikon_microphone[] = {
5764 	{N_("Auto sensitivity"),	0, 0},
5765 	{N_("High sensitivity"),	1, 0},
5766 	{N_("Medium sensitivity"),	2, 0},
5767 	{N_("Low sensitivity"),		3, 0},
5768 	{N_("Microphone off"),		4, 0},
5769 };
5770 GENERIC8TABLE(Nikon_Microphone, nikon_microphone);
5771 
5772 static struct deviceproptableu8 nikon_moviequality[] = {
5773 	{"320x216",	0, 0},
5774 	{"640x424",	1, 0},
5775 	{"1280x720",	2, 0},
5776 };
5777 GENERIC8TABLE(Nikon_MovieQuality, nikon_moviequality);
5778 
5779 static struct deviceproptableu8 nikon_d850_moviequality[] = {
5780  	{"3840x2160; 30p",	0, 0},
5781 	{"3840x2160; 25p",	1, 0},
5782 	{"3840x2160; 24p",	2, 0},
5783 
5784  	{"1920x1080; 60p",	3, 0},
5785 	{"1920x1080; 50p",	4, 0},
5786 	{"1920x1080; 30p",	5, 0},
5787 	{"1920x1080; 25p",	6, 0},
5788 	{"1920x1080; 24p",	7, 0},
5789 
5790 	{"1280x720; 60p",	8, 0},
5791 	{"1280x720; 50p",	9, 0},
5792 
5793 	{"1920x1080; 30p x4 (slow-mo)", 10, 0},
5794 	{"1920x1080; 25p x4 (slow-mo)",	11, 0},
5795 	{"1920x1080; 24p x5 (slow-mo)",	12, 0},
5796 };
5797 GENERIC8TABLE(Nikon_D850_MovieQuality, nikon_d850_moviequality);
5798 
5799 static struct deviceproptableu8 nikon_d5100_moviequality[] = {
5800 	{"640x424; 25fps; normal",		0, 0},
5801 	{"640x424; 25fps; high quality",	1, 0},
5802  	{"1280x720; 24fps; normal",		2, 0},
5803 	{"1280x720; 24fps; high quality",	3, 0},
5804 	{"1280x720; 25fps; normal",		4, 0},
5805 	{"1280x720; 25fps; high quality",	5, 0},
5806 	{"1920x1080; 24fps; normal",		6, 0},
5807 	{"1920x1080; 24fps; high quality",	7, 0},
5808 	{"1920x1080; 25fps; normal",		8, 0},
5809 	{"1920x1080; 25fps; high quality",	9, 0},
5810 };
5811 GENERIC8TABLE(Nikon_D5100_MovieQuality, nikon_d5100_moviequality);
5812 
5813 static struct deviceproptableu8 nikon_d7100_moviequality[] = {
5814 	{"1920x1080; 60i",	0, 0},
5815 	{"1920x1080; 50i",	1, 0},
5816  	{"1920x1080; 30p",	2, 0},
5817 	{"1920x1080; 25p",	3, 0},
5818 	{"1920x1080; 24p",	4, 0},
5819 	{"1280x720; 60p",	5, 0},
5820 	{"1280x720; 50p",	6, 0},
5821 };
5822 GENERIC8TABLE(Nikon_D7100_MovieQuality, nikon_d7100_moviequality);
5823 
5824 static struct deviceproptableu8 nikon_d7100_moviequality2[] = {
5825 	{"Norm",	0, 0},
5826 	{"High",	1, 0},
5827 };
5828 GENERIC8TABLE(Nikon_D7100_MovieQuality2, nikon_d7100_moviequality2);
5829 
5830 static struct deviceproptableu8 nikon_1_moviequality[] = {
5831 	{"1080/60i",	0, 0},
5832  	{"1080/30p",	1, 0},
5833 	{"720/60p",	3, 0},
5834 	{"720/30p",	4, 0},
5835 };
5836 GENERIC8TABLE(Nikon_1_MovieQuality, nikon_1_moviequality);
5837 
5838 static struct deviceproptableu8 nikon_d90_isoautohilimit[] = {
5839 	{"400",		0, 0},
5840 	{"800",		1, 0},
5841 	{"1600",	2, 0},
5842 	{"3200",	3, 0},
5843 	{N_("Hi 1"),	4, 0},
5844 	{N_("Hi 2"),	5, 0},
5845 };
5846 GENERIC8TABLE(Nikon_D90_ISOAutoHiLimit, nikon_d90_isoautohilimit);
5847 
5848 static struct deviceproptableu8 nikon_d7100_isoautohilimit[] = {
5849 	{ "200",    0,  0 },
5850 	{ "250",    1,  0 },
5851 	{ "280",    2,  0 },
5852 	{ "320",    3,  0 },
5853 	{ "400",    4,  0 },
5854 	{ "500",    5,  0 },
5855 	{ "560",    6,  0 },
5856 	{ "640",    7,  0 },
5857 	{ "800",    8,  0 },
5858 	{ "1000",   9,  0 },
5859 	{ "1100",   10, 0 },
5860 	{ "1250",   11, 0 },
5861 	{ "1600",   12, 0 },
5862 	{ "2000",   13, 0 },
5863 	{ "2200",   14, 0 },
5864 	{ "2500",   15, 0 },
5865 	{ "3200",   16, 0 },
5866 	{ "4000",   17, 0 },
5867 	{ "4500",   18, 0 },
5868 	{ "5000",   19, 0 },
5869 	{ "6400",   20, 0 },
5870 	{ "Hi 0.3", 21, 0 },
5871 	{ "Hi 0.5", 22, 0 },
5872 	{ "Hi 0.7", 23, 0 },
5873 	{ "Hi 1",   24, 0 },
5874 	{ "Hi 2",   25, 0 },
5875 };
5876 GENERIC8TABLE(Nikon_D7100_ISOAutoHiLimit, nikon_d7100_isoautohilimit);
5877 
5878 static struct deviceproptableu8 nikon_manualbracketmode[] = {
5879 	{N_("Flash/speed"),	0, 0},
5880 	{N_("Flash/speed/aperture"),	1, 0},
5881 	{N_("Flash/aperture"),	2, 0},
5882 	{N_("Flash only"),	3, 0},
5883 };
5884 GENERIC8TABLE(Nikon_ManualBracketMode, nikon_manualbracketmode);
5885 
5886 static struct deviceproptableu8 nikon_d3s_isoautohilimit[] = {
5887 	{"400",	   0, 0},
5888 	{"500",	   1, 0},
5889 	{"640",	   3, 0},
5890 	{"800",    4, 0},
5891 	{"1000",   5, 0},
5892 	{"1250",   7, 0},
5893 	{"1600",   8, 0},
5894 	{"2000",   9, 0},
5895 	{"2500",  11, 0},
5896 	{"3200",  12, 0},
5897 	{"4000",  13, 0},
5898 	{"5000",  15, 0},
5899 	{"6400",  16, 0},
5900 	{"8000",  17, 0},
5901 	{"10000", 19, 0},
5902 	{"12800", 20, 0},
5903 	{"14400", 21, 0},
5904 	{"20000", 23, 0},
5905 	{"25600", 24, 0},
5906 	{"51200", 25, 0},
5907 	{"102400",26, 0},
5908 };
5909 GENERIC8TABLE(Nikon_D3s_ISOAutoHiLimit, nikon_d3s_isoautohilimit);
5910 
5911 #if 0
5912 static struct deviceproptableu8 nikon_d70s_padvpvalue[] = {
5913 	{ "1/125",	0x00, 0 },
5914 	{ "1/60",	0x01, 0 },
5915 	{ "1/30",	0x02, 0 },
5916 	{ "1/15",	0x03, 0 },
5917 	{ "1/8",	0x04, 0 },
5918 	{ "1/4",	0x05, 0 },
5919 	{ "1/2",	0x06, 0 },
5920 	{ "1",		0x07, 0 },
5921 	{ "2",		0x08, 0 },
5922 	{ "4",		0x09, 0 },
5923 	{ "8",		0x0a, 0 },
5924 	{ "15",		0x0b, 0 },
5925 	{ "30",		0x0c, 0 },
5926 };
5927 GENERIC8TABLE(Nikon_D70s_PADVPValue,nikon_d70s_padvpvalue)
5928 #endif
5929 
5930 static struct deviceproptableu8 nikon_d90_padvpvalue[] = {
5931 	{ "1/2000",	0x00, 0 },
5932 	{ "1/1600",	0x01, 0 },
5933 	{ "1/1250",	0x02, 0 },
5934 	{ "1/1000",	0x03, 0 },
5935 	{ "1/800",	0x04, 0 },
5936 	{ "1/640",	0x05, 0 },
5937 	{ "1/500",	0x06, 0 },
5938 	{ "1/400",	0x07, 0 },
5939 	{ "1/320",	0x08, 0 },
5940 	{ "1/250",	0x09, 0 },
5941 	{ "1/200",	0x0a, 0 },
5942 	{ "1/160",	0x0b, 0 },
5943 	{ "1/125",	0x0c, 0 },
5944 	{ "1/100",	0x0d, 0 },
5945 	{ "1/80",	0x0e, 0 },
5946 	{ "1/60",	0x0f, 0 },
5947 	{ "1/50",	0x10, 0 },
5948 	{ "1/40",	0x11, 0 },
5949 	{ "1/30",	0x12, 0 },
5950 	{ "1/15",	0x13, 0 },
5951 	{ "1/8",	0x14, 0 },
5952 	{ "1/4",	0x15, 0 },
5953 	{ "1/2",	0x16, 0 },
5954 	{ "1",		0x17, 0 },
5955 };
5956 GENERIC8TABLE(Nikon_D90_PADVPValue,nikon_d90_padvpvalue)
5957 
5958 static struct deviceproptableu8 nikon_d7100_padvpvalue[] = {
5959 	{ "1/4000",	0x00, 0 },
5960 	{ "1/3200",	0x01, 0 },
5961 	{ "1/2500",	0x02, 0 },
5962 	{ "1/2000",	0x03, 0 },
5963 	{ "1/1600",	0x04, 0 },
5964 	{ "1/1250",	0x05, 0 },
5965 	{ "1/1000",	0x06, 0 },
5966 	{ "1/800",	0x07, 0 },
5967 	{ "1/640",	0x08, 0 },
5968 	{ "1/500",	0x09, 0 },
5969 	{ "1/400",	0x0a, 0 },
5970 	{ "1/320",	0x0b, 0 },
5971 	{ "1/250",	0x0c, 0 },
5972 	{ "1/200",	0x0d, 0 },
5973 	{ "1/160",	0x0e, 0 },
5974 	{ "1/125",	0x0f, 0 },
5975 	{ "1/100",	0x10, 0 },
5976 	{ "1/80",	0x11, 0 },
5977 	{ "1/60",	0x12, 0 },
5978 	{ "1/50",	0x13, 0 },
5979 	{ "1/40",	0x14, 0 },
5980 	{ "1/30",	0x15, 0 },
5981 	{ "1/15",	0x16, 0 },
5982 	{ "1/8",	0x17, 0 },
5983         { "1/4",	0x18, 0 },
5984         { "1/2",	0x19, 0 },
5985         { "1",		0x1a, 0 },
5986         { "Auto",	0x1b, 0 },
5987 };
5988 GENERIC8TABLE(Nikon_D7100_PADVPValue,nikon_d7100_padvpvalue)
5989 
5990 static struct deviceproptableu8 nikon_d3s_padvpvalue[] = {
5991 	{ "1/4000",	0x00, 0 },
5992 	{ "1/3200",	0x01, 0 },
5993 	{ "1/2500",	0x02, 0 },
5994 	{ "1/2000",	0x03, 0 },
5995 	{ "1/1600",	0x04, 0 },
5996 	{ "1/1250",	0x05, 0 },
5997 	{ "1/1000",	0x06, 0 },
5998 	{ "1/800",	0x07, 0 },
5999 	{ "1/640",	0x08, 0 },
6000 	{ "1/500",	0x09, 0 },
6001 	{ "1/400",	0x0a, 0 },
6002 	{ "1/320",	0x0b, 0 },
6003 	{ "1/250",	0x0c, 0 },
6004 	{ "1/200",	0x0d, 0 },
6005 	{ "1/160",	0x0e, 0 },
6006 	{ "1/125",	0x0f, 0 },
6007 	{ "1/100",	0x10, 0 },
6008 	{ "1/80",	0x11, 0 },
6009 	{ "1/60",	0x12, 0 },
6010 	{ "1/50",	0x13, 0 },
6011 	{ "1/40",	0x14, 0 },
6012 	{ "1/30",	0x15, 0 },
6013 	{ "1/15",	0x16, 0 },
6014 	{ "1/8",	0x17, 0 },
6015 	{ "1/4",	0x18, 0 },
6016 	{ "1/2",	0x19, 0 },
6017 	{ "1",		0x1a, 0 },
6018 };
6019 GENERIC8TABLE(Nikon_D3s_PADVPValue,nikon_d3s_padvpvalue)
6020 
6021 static struct deviceproptableu8 nikon_z6_padvpvalue[] = {
6022 	{ "1/4000",	0x00, 0 },
6023 	{ "1/3200",	0x01, 0 },
6024 	{ "1/2500",	0x02, 0 },
6025 	{ "1/2000",	0x03, 0 },
6026 	{ "1/1600",	0x04, 0 },
6027 	{ "1/1250",	0x05, 0 },
6028 	{ "1/1000",	0x06, 0 },
6029 	{ "1/800",	0x07, 0 },
6030 	{ "1/640",	0x08, 0 },
6031 	{ "1/500",	0x09, 0 },
6032 	{ "1/400",	0x0a, 0 },
6033 	{ "1/320",	0x0b, 0 },
6034 	{ "1/250",	0x0c, 0 },
6035 	{ "1/200",	0x0d, 0 },
6036 	{ "1/160",	0x0e, 0 },
6037 	{ "1/125",	0x0f, 0 },
6038 	{ "1/100",	0x10, 0 },
6039 	{ "1/80",	0x11, 0 },
6040 	{ "1/60",	0x12, 0 },
6041 	{ "1/50",	0x13, 0 },
6042 	{ "1/40",	0x14, 0 },
6043 	{ "1/30",	0x15, 0 },
6044 	{ "1/25",	0x16, 0 },
6045 	{ "1/20",	0x17, 0 },
6046 	{ "1/15",	0x18, 0 },
6047 	{ "1/13",	0x19, 0 },
6048 	{ "1/10",	0x1a, 0 },
6049 	{ "1/8",	0x1b, 0 },
6050 	{ "1/6",	0x1c, 0 },
6051 	{ "1/5",	0x1d, 0 },
6052 	{ "1/4",	0x1e, 0 },
6053 	{ "1/3",	0x1f, 0 },
6054 	{ "1/2.5",	0x20, 0 },
6055 	{ "1/2",	0x21, 0 },
6056 	{ "1/1.6",	0x22, 0 },
6057 	{ "1/1.3",	0x23, 0 },
6058 	{ "1",		0x24, 0 },
6059 	{ "1.3",	0x25, 0 },
6060 	{ "1.6",	0x26, 0 },
6061 	{ "2",		0x27, 0 },
6062 	{ "2.5",	0x28, 0 },
6063 	{ "3",		0x29, 0 },
6064 	{ "4",		0x2a, 0 },
6065 	{ "5",		0x2b, 0 },
6066 	{ "6",		0x2c, 0 },
6067 	{ "8",		0x2d, 0 },
6068 	{ "10",		0x2e, 0 },
6069 	{ "13",		0x2f, 0 },
6070 	{ "15",		0x30, 0 },
6071 	{ "20",		0x31, 0 },
6072 	{ "25",		0x32, 0 },
6073 	{ "30",		0x33, 0 },
6074 	{ N_("auto"),	0x34, 0 },
6075 };
6076 GENERIC8TABLE(Nikon_Z6_PADVPValue,nikon_z6_padvpvalue)
6077 
6078 static struct deviceproptableu8 nikon_d90_activedlighting[] = {
6079 	{ N_("Extra high"), 0x00,   0 },
6080 	{ N_("High"),       0x01,   0 },
6081 	{ N_("Normal"),     0x02,   0 },
6082 	{ N_("Low"),        0x03,   0 },
6083 	{ N_("Off"),        0x04,   0 },
6084 	{ N_("Auto"),       0x05,   0 },
6085 };
6086 GENERIC8TABLE(Nikon_D90_ActiveDLighting,nikon_d90_activedlighting)
6087 
6088 static struct deviceproptablei8 nikon_d850_activedlighting[] = {
6089 	{ N_("Auto"),		0x00,   0 },
6090 	{ N_("Off"),		0x01,   0 },
6091 	{ N_("Low"),		0x02,   0 },
6092 	{ N_("Normal"),		0x03,   0 },
6093 	{ N_("High"),		0x04,   0 },
6094 	{ N_("Extra high"),	0x05,   0 },
6095 };
6096 GENERICI8TABLE(Nikon_D850_ActiveDLighting,nikon_d850_activedlighting)
6097 
6098 static struct deviceproptableu8 nikon_1_compression[] = {
6099 	{ N_("JPEG Normal"),	0x00, PTP_VENDOR_NIKON },
6100 	{ N_("JPEG Fine"),	0x01, PTP_VENDOR_NIKON },
6101 	{ N_("JPEG Basic"),	0x02, PTP_VENDOR_NIKON },
6102 	{ N_("NEF+Fine"),	0x03, PTP_VENDOR_NIKON },
6103 	{ N_("NEF (Raw)"),	0x04, PTP_VENDOR_NIKON }, /* for j5 */
6104 	{ N_("NEF (Raw)"),	0x06, PTP_VENDOR_NIKON }, /* for j3 */
6105 };
6106 GENERIC8TABLE(Nikon_1_Compression,nikon_1_compression)
6107 
6108 static struct deviceproptableu8 nikon_d90_compression[] = {
6109 	{ N_("JPEG Basic"),	0x00, PTP_VENDOR_NIKON },
6110 	{ N_("JPEG Normal"),	0x01, PTP_VENDOR_NIKON },
6111 	{ N_("JPEG Fine"),	0x02, PTP_VENDOR_NIKON },
6112 	{ N_("NEF (Raw)"),	0x04, PTP_VENDOR_NIKON },
6113 	{ N_("NEF+Basic"),	0x05, PTP_VENDOR_NIKON },
6114 	{ N_("NEF+Normal"),	0x06, PTP_VENDOR_NIKON },
6115 	{ N_("NEF+Fine"),	0x07, PTP_VENDOR_NIKON },
6116 };
6117 GENERIC8TABLE(Nikon_D90_Compression,nikon_d90_compression)
6118 
6119 static struct deviceproptableu8 nikon_d3s_compression[] = {
6120 	{ N_("JPEG Basic"),	0x00, PTP_VENDOR_NIKON },
6121 	{ N_("JPEG Normal"),	0x01, PTP_VENDOR_NIKON },
6122 	{ N_("JPEG Fine"),	0x02, PTP_VENDOR_NIKON },
6123 	{ N_("TIFF (RGB)"),	0x03, PTP_VENDOR_NIKON },
6124 	{ N_("NEF (Raw)"),	0x04, PTP_VENDOR_NIKON },
6125 	{ N_("NEF+Basic"),	0x05, PTP_VENDOR_NIKON },
6126 	{ N_("NEF+Normal"),	0x06, PTP_VENDOR_NIKON },
6127 	{ N_("NEF+Fine"),	0x07, PTP_VENDOR_NIKON },
6128 };
6129 GENERIC8TABLE(Nikon_D3s_Compression,nikon_d3s_compression)
6130 
6131 static struct deviceproptableu8 nikon_d40_compression[] = {
6132 	{ N_("JPEG Basic"),  0x00, PTP_VENDOR_NIKON },
6133 	{ N_("JPEG Normal"), 0x01, PTP_VENDOR_NIKON },
6134 	{ N_("JPEG Fine"),   0x02, PTP_VENDOR_NIKON },
6135 	{ N_("NEF (Raw)"),   0x03, PTP_VENDOR_NIKON },
6136 	{ N_("NEF+Basic"),   0x04, PTP_VENDOR_NIKON },
6137 };
6138 GENERIC8TABLE(Nikon_D40_Compression,nikon_d40_compression)
6139 
6140 static struct deviceproptableu8 nikon_d850_compression[] = {
6141 	{ N_("JPEG Basic"),  0x00, PTP_VENDOR_NIKON },
6142 	{ N_("JPEG Basic*"), 0x01, PTP_VENDOR_NIKON },
6143 	{ N_("JPEG Normal"), 0x02, PTP_VENDOR_NIKON },
6144 	{ N_("JPEG Normal*"),   0x03, PTP_VENDOR_NIKON },
6145 	{ N_("JPEG Fine"),   0x04, PTP_VENDOR_NIKON },
6146 	{ N_("JPEG Fine*"),   0x05, PTP_VENDOR_NIKON },
6147 	{ N_("TIFF"),   0x06, PTP_VENDOR_NIKON },
6148 	{ N_("NEF (Raw)"),   0x07, PTP_VENDOR_NIKON },
6149 	{ N_("NEF+Basic"),   0x08, PTP_VENDOR_NIKON },
6150 	{ N_("NEF+Basic*"),   0x09, PTP_VENDOR_NIKON },
6151 	{ N_("NEF+Normal"),   0x0A, PTP_VENDOR_NIKON },
6152 	{ N_("NEF+Normal*"),   0x0B, PTP_VENDOR_NIKON },
6153 	{ N_("NEF+Fine"),   0x0C, PTP_VENDOR_NIKON },
6154 	{ N_("NEF+Fine*"),   0x0D, PTP_VENDOR_NIKON },
6155 };
6156 GENERIC8TABLE(Nikon_D850_Compression,nikon_d850_compression)
6157 
6158 static struct deviceproptableu8 nikon_d7500_compression[] = {
6159 	{ N_("JPEG Basic"),  0x00, PTP_VENDOR_NIKON },
6160 	{ N_("JPEG Basic*"), 0x01, PTP_VENDOR_NIKON },
6161 	{ N_("JPEG Normal"), 0x02, PTP_VENDOR_NIKON },
6162 	{ N_("JPEG Normal*"),   0x03, PTP_VENDOR_NIKON },
6163 	{ N_("JPEG Fine"),   0x04, PTP_VENDOR_NIKON },
6164 	{ N_("JPEG Fine*"),   0x05, PTP_VENDOR_NIKON },
6165 	{ N_("NEF (Raw)"),   0x07, PTP_VENDOR_NIKON },
6166 	{ N_("NEF+Basic"),   0x08, PTP_VENDOR_NIKON },
6167 	{ N_("NEF+Basic*"),   0x09, PTP_VENDOR_NIKON },
6168 	{ N_("NEF+Normal"),   0x0A, PTP_VENDOR_NIKON },
6169 	{ N_("NEF+Normal*"),   0x0B, PTP_VENDOR_NIKON },
6170 	{ N_("NEF+Fine"),   0x0C, PTP_VENDOR_NIKON },
6171 	{ N_("NEF+Fine*"),   0x0D, PTP_VENDOR_NIKON },
6172 };
6173 GENERIC8TABLE(Nikon_D7500_Compression,nikon_d7500_compression)
6174 
6175 static struct deviceproptableu8 compressionsetting[] = {
6176 	{ N_("JPEG Basic"),	0x00, PTP_VENDOR_NIKON },
6177 	{ N_("JPEG Normal"),	0x01, PTP_VENDOR_NIKON },
6178 	{ N_("JPEG Fine"),	0x02, PTP_VENDOR_NIKON },
6179 	{ N_("NEF (Raw)"),	0x04, PTP_VENDOR_NIKON },
6180 	{ N_("NEF+Basic"),	0x05, PTP_VENDOR_NIKON },
6181 	{ N_("NEF+Normal"),	0x06, PTP_VENDOR_NIKON },
6182 	{ N_("NEF+Fine"),	0x07, PTP_VENDOR_NIKON },
6183 
6184 	{ N_("Standard"),		0x02, PTP_VENDOR_SONY },
6185 	{ N_("Fine"),			0x03, PTP_VENDOR_SONY },
6186 	{ N_("Extra Fine"),		0x04, PTP_VENDOR_SONY },
6187 	{ N_("RAW"),			0x10, PTP_VENDOR_SONY },
6188 	{ N_("RAW+JPEG (Std)"),		0x12, PTP_VENDOR_SONY },
6189 	{ N_("RAW+JPEG (Fine)"),	0x13, PTP_VENDOR_SONY },
6190 	{ N_("RAW+JPEG (X.Fine)"),	0x14, PTP_VENDOR_SONY },
6191 };
6192 GENERIC8TABLE(CompressionSetting,compressionsetting)
6193 
6194 static struct deviceproptableu8 sony_qx_compression[] = {
6195 	{ N_("Standard"),	0x02, 0 },
6196 	{ N_("Fine"),		0x03, 0 },
6197 	{ N_("Extra Fine"),	0x04, 0 },
6198 	{ N_("RAW"),		0x10, 0 },
6199 	{ N_("RAW+JPEG"),	0x13, 0 },
6200 };
6201 GENERIC8TABLE(Sony_QX_Compression,sony_qx_compression)
6202 
6203 static struct deviceproptableu8 sony_sensorcrop[] = {
6204 	{ N_("Off"),	0x01, 0 },
6205 	{ N_("On"),	0x02, 0 },
6206 };
GENERIC8TABLE(Sony_SensorCrop,sony_sensorcrop)6207 GENERIC8TABLE(Sony_SensorCrop,sony_sensorcrop)
6208 
6209 /* Sony specific, we need to wait for it settle (around 1 second), otherwise we get trouble later on */
6210 static int
6211 _put_Sony_CompressionSetting(CONFIG_PUT_ARGS) {
6212 	PTPParams		*params = &(camera->pl->params);
6213 	GPContext 		*context = ((PTPData *) params->data)->context;
6214 	int 			ret;
6215 	PTPDevicePropDesc	dpd2;
6216 	time_t			start,end;
6217 
6218 	ret = _put_CompressionSetting(CONFIG_PUT_NAMES);
6219 	if (ret != GP_OK) return ret;
6220 	start = time(NULL);
6221 	C_PTP_REP (ptp_generic_setdevicepropvalue (params, PTP_DPC_CompressionSetting, propval, PTP_DTC_UINT8));
6222 	while (1) {
6223 		C_PTP_REP (ptp_sony_getalldevicepropdesc (params));
6224 		C_PTP_REP (ptp_generic_getdevicepropdesc (params, PTP_DPC_CompressionSetting, &dpd2));
6225 		if (dpd2.CurrentValue.u8 == propval->u8)
6226 			break;
6227 		end = time(NULL);
6228 		if (end-start >= 2) {
6229 			GP_LOG_E("failed to change variable to %d (current %d)\n", propval->u8, dpd2.CurrentValue.u8);
6230 			break;
6231 		}
6232 	}
6233 	return GP_OK;
6234 }
6235 
6236 static struct deviceproptableu16 canon_eos_highisonr[] = {
6237 	/* 6d values */
6238 	{ N_("Off"),		0, 0 },
6239 	{ N_("Low"),		1, 0 },
6240 	{ N_("Normal"),		2, 0 },
6241 	{ N_("High"),		3, 0 },
6242 	{ N_("Multi-Shot"),	4, 0 },
6243 };
6244 
6245 GENERIC16TABLE(Canon_EOS_HighIsoNr,canon_eos_highisonr)
6246 
6247 static struct deviceproptableu8 nikon_d90_highisonr[] = {
6248 	{ N_("Off"),	0, 0 },
6249 	{ N_("Low"),	1, 0 },
6250 	{ N_("Normal"),	2, 0 },
6251 	{ N_("High"),	3, 0 },
6252 };
6253 GENERIC8TABLE(Nikon_D90_HighISONR,nikon_d90_highisonr)
6254 
6255 static struct deviceproptableu8 nikon_1_highisonr[] = {
6256 	{ N_("On"),	0, 0 },
6257 	{ N_("Off"),	3, 0 },
6258 };
6259 GENERIC8TABLE(Nikon_1_HighISONR,nikon_1_highisonr)
6260 
6261 static struct deviceproptableu8 nikon_d90_meterofftime[] = {
6262 	{ N_("4 seconds"),	0x00, 0 },
6263 	{ N_("6 seconds"),	0x01, 0 },
6264 	{ N_("8 seconds"),	0x02, 0 },
6265 	{ N_("16 seconds"),	0x03, 0 },
6266 	{ N_("30 seconds"),	0x04, 0 },
6267 	{ N_("1 minute"),	0x05, 0 },
6268 	{ N_("5 minutes"),	0x06, 0 },
6269 	{ N_("10 minutes"),	0x07, 0 },
6270 	{ N_("30 minutes"),	0x08, 0 },
6271 };
6272 GENERIC8TABLE(Nikon_D90_MeterOffTime,nikon_d90_meterofftime)
6273 
6274 
6275 static struct deviceproptableu8 nikon_rawcompression[] = {
6276 	{ N_("Lossless"),	0x00, 0 },
6277 	{ N_("Lossy"),		0x01, 0 },
6278 };
6279 GENERIC8TABLE(Nikon_RawCompression,nikon_rawcompression)
6280 
6281 static struct deviceproptableu8 nikon_d3s_jpegcompressionpolicy[] = {
6282 	{ N_("Size Priority"),	0x00, 0 },
6283 	{ N_("Optimal quality"),0x01, 0 },
6284 };
6285 GENERIC8TABLE(Nikon_D3s_JPEGCompressionPolicy,nikon_d3s_jpegcompressionpolicy)
6286 
6287 static struct deviceproptableu8 nikon_d3s_flashsyncspeed[] = {
6288 	{ N_("1/250s (Auto FP)"),	0x00, 0 },
6289 	{ N_("1/250s"),			0x01, 0 },
6290 	{ N_("1/200s"),			0x02, 0 },
6291 	{ N_("1/160s"),			0x03, 0 },
6292 	{ N_("1/125s"),			0x04, 0 },
6293 	{ N_("1/100s"),			0x05, 0 },
6294 	{ N_("1/80s"),			0x06, 0 },
6295 	{ N_("1/60s"),			0x07, 0 },
6296 };
6297 GENERIC8TABLE(Nikon_D3s_FlashSyncSpeed,nikon_d3s_flashsyncspeed)
6298 
6299 static struct deviceproptableu8 nikon_d7100_flashsyncspeed[] = {
6300 	{ N_("1/320s (Auto FP)"),	0x00, 0 },
6301 	{ N_("1/250s (Auto FP)"),	0x01, 0 },
6302 	{ N_("1/250s"),			0x02, 0 },
6303 	{ N_("1/200s"),			0x03, 0 },
6304 	{ N_("1/160s"),			0x04, 0 },
6305 	{ N_("1/125s"),			0x05, 0 },
6306 	{ N_("1/100s"),			0x06, 0 },
6307 	{ N_("1/80s"),			0x07, 0 },
6308 	{ N_("1/60s"),			0x08, 0 },
6309 };
6310 GENERIC8TABLE(Nikon_D7100_FlashSyncSpeed,nikon_d7100_flashsyncspeed)
6311 
6312 static struct deviceproptableu8 nikon_d3s_afcmodepriority[] = {
6313 	{ N_("Release"),	0x00, 0 },
6314 	{ N_("Release + Focus"),0x01, 0 },
6315 	{ N_("Focus"),		0x02, 0 },
6316 };
6317 GENERIC8TABLE(Nikon_D3s_AFCModePriority,nikon_d3s_afcmodepriority)
6318 
6319 static struct deviceproptableu8 nikon_d3s_afsmodepriority[] = {
6320 	{ N_("Release"),	0x00, 0 },
6321 	{ N_("Focus"),		0x01, 0 },
6322 };
6323 GENERIC8TABLE(Nikon_D3s_AFSModePriority,nikon_d3s_afsmodepriority)
6324 
6325 static struct deviceproptableu8 nikon_d3s_dynamicafarea[] = {
6326 	{ N_("9 points"),	0x00, 0 },
6327 	{ N_("21 points"),	0x01, 0 },
6328 	{ N_("51 points"),	0x02, 0 },
6329 	{ N_("51 points (3D)"),	0x03, 0 },
6330 };
6331 GENERIC8TABLE(Nikon_D3s_DynamicAFArea,nikon_d3s_dynamicafarea)
6332 
6333 static struct deviceproptableu8 nikon_d3s_aflockon[] = {
6334 	{ N_("5 (Long)"),	0x00, 0 },
6335 	{ N_("4"),		0x01, 0 },
6336 	{ N_("3 (Normal)"),	0x02, 0 },
6337 	{ N_("2"),		0x03, 0 },
6338 	{ N_("1 (Short)"),	0x04, 0 },
6339 	{ N_("Off"),		0x05, 0 },
6340 };
6341 GENERIC8TABLE(Nikon_D3s_AFLockOn,nikon_d3s_aflockon)
6342 
6343 static struct deviceproptableu8 nikon_d3s_afactivation[] = {
6344 	{ N_("Shutter/AF-ON"),	0x00, 0 },
6345 	{ N_("AF-ON"),		0x01, 0 },
6346 };
6347 GENERIC8TABLE(Nikon_D3s_AFActivation,nikon_d3s_afactivation)
6348 
6349 static struct deviceproptableu8 nikon_d3s_afareapoint[] = {
6350 	{ N_("AF51"),	0x00, 0 },
6351 	{ N_("AF11"),	0x01, 0 },
6352 };
6353 GENERIC8TABLE(Nikon_D3s_AFAreaPoint,nikon_d3s_afareapoint)
6354 
6355 static struct deviceproptableu8 nikon_d3s_normalafon[] = {
6356 	{ N_("AF-ON"),		0x00, 0 },
6357 	{ N_("AE/AF lock"),	0x01, 0 },
6358 	{ N_("AE lock only"),	0x02, 0 },
6359 	{ N_("AE lock (Reset on release)"),	0x03, 0 },
6360 	{ N_("AE lock (Hold)"),	0x04, 0 },
6361 	{ N_("AF lock only"),	0x05, 0 },
6362 };
6363 GENERIC8TABLE(Nikon_D3s_NormalAFOn,nikon_d3s_normalafon)
6364 
6365 static struct deviceproptableu8 nikon_d3s_flashshutterspeed[] = {
6366 	{ N_("1/60s"),  0x00,   0 },
6367 	{ N_("1/30s"),  0x01,   0 },
6368 	{ N_("1/15s"),  0x02,   0 },
6369 	{ N_("1/8s"),   0x03,   0 },
6370 	{ N_("1/4s"),   0x04,   0 },
6371 	{ N_("1/2s"),   0x05,   0 },
6372 	{ N_("1s"),     0x06,   0 },
6373 	{ N_("2s"),     0x07,   0 },
6374 	{ N_("4s"),     0x08,   0 },
6375 	{ N_("8s"),     0x09,   0 },
6376 	{ N_("15s"),    0x0a,   0 },
6377 	{ N_("30s"),    0x0b,   0 },
6378 };
6379 GENERIC8TABLE(Nikon_D3s_FlashShutterSpeed,nikon_d3s_flashshutterspeed)
6380 
6381 static struct deviceproptableu8 nikon_d90_shootingspeed[] = {
6382 	{ N_("4 fps"),	0x00, 0 },
6383 	{ N_("3 fps"),	0x01, 0 },
6384 	{ N_("2 fps"),	0x02, 0 },
6385 	{ N_("1 fps"),	0x03, 0 },
6386 };
6387 GENERIC8TABLE(Nikon_D90_ShootingSpeed,nikon_d90_shootingspeed)
6388 
6389 static struct deviceproptableu8 nikon_d7100_shootingspeed[] = {
6390 	{ N_("6 fps"),	0x00, 0 },
6391 	{ N_("5 fps"),	0x01, 0 },
6392 	{ N_("4 fps"),	0x02, 0 },
6393 	{ N_("3 fps"),	0x03, 0 },
6394 	{ N_("2 fps"),	0x04, 0 },
6395 	{ N_("1 fps"),	0x05, 0 },
6396 };
6397 GENERIC8TABLE(Nikon_D7100_ShootingSpeed,nikon_d7100_shootingspeed)
6398 
6399 static struct deviceproptableu8 nikon_d3s_shootingspeed[] = {
6400 	{ N_("9 fps"),	0x00, 0 },
6401 	{ N_("8 fps"),	0x01, 0 },
6402 	{ N_("7 fps"),	0x02, 0 },
6403 	{ N_("6 fps"),	0x03, 0 },
6404 	{ N_("5 fps"),	0x04, 0 },
6405 	{ N_("4 fps"),	0x05, 0 },
6406 	{ N_("3 fps"),	0x06, 0 },
6407 	{ N_("2 fps"),	0x07, 0 },
6408 	{ N_("1 fps"),	0x08, 0 },
6409 };
6410 GENERIC8TABLE(Nikon_D3s_ShootingSpeed,nikon_d3s_shootingspeed)
6411 
6412 static struct deviceproptableu8 nikon_d850_shootingspeed[] = {
6413 	{ N_("8 fps"),	0x01, 0 },
6414 	{ N_("7 fps"),	0x02, 0 },
6415 	{ N_("6 fps"),	0x03, 0 },
6416 	{ N_("5 fps"),	0x04, 0 },
6417 	{ N_("4 fps"),	0x05, 0 },
6418 	{ N_("3 fps"),	0x06, 0 },
6419 	{ N_("2 fps"),	0x07, 0 },
6420 	{ N_("1 fps"),	0x08, 0 },
6421 };
6422 GENERIC8TABLE(Nikon_D850_ShootingSpeed,nikon_d850_shootingspeed)
6423 
6424 static struct deviceproptableu8 nikon_d3s_shootingspeedhigh[] = {
6425 	{ N_("11 fps"),	0x00, 0 },
6426 	{ N_("10 fps"),	0x01, 0 },
6427 	{ N_("9 fps"),	0x02, 0 },
6428 };
6429 GENERIC8TABLE(Nikon_D3s_ShootingSpeedHigh,nikon_d3s_shootingspeedhigh)
6430 
6431 static struct deviceproptableu8 nikon_d7000_funcbutton[] = {
6432 	{ N_("Unassigned"),			0x00, 0 },/* unselectable */
6433 	{ N_("Preview"),			0x01, 0 },
6434 	{ N_("FV lock"),			0x02, 0 },
6435 	{ N_("AE/AF lock"),			0x03, 0 },
6436 	{ N_("AE lock only"),			0x04, 0 },
6437 	{ N_("Invalid"),			0x05, 0 },/* unselectable */
6438 	{ N_("AE lock (hold)"),			0x06, 0 },
6439 	{ N_("AF lock only"),			0x07, 0 },
6440 	{ N_("Flash off"),			0x08, 0 },
6441 	{ N_("Bracketing burst"),		0x09, 0 },
6442 	{ N_("Matrix metering"),		0x0a, 0 },
6443 	{ N_("Center-weighted metering"),	0x0b, 0 },
6444 	{ N_("Spot metering"),			0x0c, 0 },
6445 	{ N_("Playback"),			0x0d, 0 },
6446 	{ N_("Access top item in MY MENU"),	0x0e, 0 },
6447 	{ N_("+NEF (RAW)"),			0x0f, 0 },
6448 	{ N_("Framing grid"),			0x10, 0 },
6449 	{ N_("Active D-Lighting"),		0x11, 0 },
6450 	{ N_("1 step spd/aperture"),		0x12, 0 },
6451 	{ N_("Choose non-CPU lens number"),	0x13, 0 },
6452 	{ N_("Viewfinder virtual horizont"),	0x14, 0 },
6453 	{ N_("Start movie recording"),		0x15, 0 },
6454 };
6455 GENERIC8TABLE(Nikon_D7000_FuncButton,nikon_d7000_funcbutton)
6456 
6457 static struct deviceproptableu8 nikon_menus_and_playback[] = {
6458 	{ N_("Off"),				0x0, 0 },
6459 	{ N_("On"),				0x1, 0 },
6460 	{ N_("On (image review excluded)"),	0x2, 0 },
6461 };
6462 GENERIC8TABLE(Nikon_MenusAndPlayback,nikon_menus_and_playback)
6463 
6464 static struct deviceproptableu8 nikon_vignettecorrection[] = {
6465 	{ N_("High"),		0x0, 0 },
6466 	{ N_("Normal"),		0x1, 0 },
6467 	{ N_("Moderate"),	0x2, 0 },
6468 	{ N_("Off"),		0x3, 0 },
6469 };
6470 GENERIC8TABLE(Nikon_VignetteCorrection,nikon_vignettecorrection)
6471 
6472 static struct deviceproptableu8 nikon_hdmidatadepth[] = {
6473 	{ "8",		0x0, 0 },
6474 	{ "10",		0x1, 0 },
6475 };
6476 GENERIC8TABLE(Nikon_HDMIDataDepth,nikon_hdmidatadepth)
6477 
6478 static struct deviceproptableu8 nikon_facedetection[] = {
6479 	{ N_("Off"),				0x0, 0 },
6480 	{ N_("Face detection"),			0x1, 0 },
6481 	{ N_("Face and pupil detection"),	0x2, 0 },
6482 	{ N_("Animal detection"),		0x3, 0 },
6483 };
GENERIC8TABLE(Nikon_FaceDetection,nikon_facedetection)6484 GENERIC8TABLE(Nikon_FaceDetection,nikon_facedetection)
6485 
6486 static int
6487 _get_BatteryLevel(CONFIG_GET_ARGS) {
6488 	unsigned char value_float , start, end;
6489 	char	buffer[20];
6490 
6491 	if (dpd->DataType != PTP_DTC_UINT8)
6492 		return GP_ERROR;
6493 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
6494 
6495 	if (dpd->FormFlag == PTP_DPFF_Range) {
6496 		gp_widget_set_name (*widget, menu->name);
6497 		start = dpd->FORM.Range.MinimumValue.u8;
6498 		end = dpd->FORM.Range.MaximumValue.u8;
6499 		value_float = dpd->CurrentValue.u8;
6500 		if (0 == end - start + 1) {
6501 			/* avoid division by 0 */
6502 			sprintf (buffer, "broken");
6503 		} else {
6504 			sprintf (buffer, "%d%%", (int)((value_float-start+1)*100/(end-start+1)));
6505 		}
6506 		return gp_widget_set_value(*widget, buffer);
6507 	}
6508 	/* Enumeration is also valid on EOS, but this will be just be the % value */
6509 	sprintf (buffer, "%d%%", dpd->CurrentValue.u8);
6510 	return gp_widget_set_value(*widget, buffer);
6511 }
6512 
6513 static int
_get_SONY_BatteryLevel(CONFIG_GET_ARGS)6514 _get_SONY_BatteryLevel(CONFIG_GET_ARGS) {
6515 	unsigned char value_float , start, end;
6516 	char	buffer[20];
6517 
6518 	if (dpd->DataType != PTP_DTC_INT8)
6519 		return GP_ERROR;
6520 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
6521 
6522 	if (dpd->FormFlag == PTP_DPFF_Range) {
6523 		gp_widget_set_name (*widget, menu->name);
6524 		start = dpd->FORM.Range.MinimumValue.i8;
6525 		if (dpd->FORM.Range.MinimumValue.i8 == -1)
6526 			start = 0; /* -1 might be special for unknown? */
6527 		else
6528 			start = dpd->FORM.Range.MinimumValue.i8;
6529 		end = dpd->FORM.Range.MaximumValue.i8;
6530 		value_float = dpd->CurrentValue.i8;
6531 		if (0 == end - start + 1) {
6532 			/* avoid division by 0 */
6533 			sprintf (buffer, "broken");
6534 		} else {
6535 			sprintf (buffer, "%d%%", (int)((value_float-start+1)*100/(end-start+1)));
6536 		}
6537 		return gp_widget_set_value(*widget, buffer);
6538 	}
6539 	/* Enumeration is also valid on EOS, but this will be just be the % value */
6540 	if (dpd->CurrentValue.i8 == -1)
6541 		sprintf (buffer, _("Unknown"));
6542 	else
6543 		sprintf (buffer, "%d%%", dpd->CurrentValue.i8);
6544 	return gp_widget_set_value(*widget, buffer);
6545 }
6546 
6547 static int
_get_Canon_EOS_BatteryLevel(CONFIG_GET_ARGS)6548 _get_Canon_EOS_BatteryLevel(CONFIG_GET_ARGS) {
6549 	if (dpd->DataType != PTP_DTC_UINT16)
6550 		return (GP_ERROR);
6551 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
6552 	gp_widget_set_name (*widget, menu->name);
6553 	switch (dpd->CurrentValue.u16) {
6554 	case 0: gp_widget_set_value(*widget, _("Low")); break;
6555 	case 1: gp_widget_set_value(*widget, _("50%")); break;
6556 	case 2: gp_widget_set_value(*widget, _("100%")); break;
6557 	case 4: gp_widget_set_value(*widget, _("75%")); break;
6558 	case 5: gp_widget_set_value(*widget, _("25%")); break;
6559 	default: gp_widget_set_value(*widget, _("Unknown value")); break;
6560 	}
6561 	return (GP_OK);
6562 }
6563 
6564 static int
_get_Canon_EOS_StorageID(CONFIG_GET_ARGS)6565 _get_Canon_EOS_StorageID(CONFIG_GET_ARGS) {
6566 	char buf[16];
6567 
6568 	if (dpd->DataType != PTP_DTC_UINT32)
6569 		return GP_ERROR;
6570 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
6571 	gp_widget_set_name (*widget, menu->name);
6572 	sprintf(buf,"%08x",dpd->CurrentValue.u32);
6573 	gp_widget_set_value(*widget, buf);
6574 	return GP_OK;
6575 }
6576 
6577 static int
_put_Canon_EOS_StorageID(CONFIG_PUT_ARGS)6578 _put_Canon_EOS_StorageID(CONFIG_PUT_ARGS) {
6579 	char		*val = NULL;
6580 	unsigned int	x = 0;
6581 
6582 	CR (gp_widget_get_value(widget, &val));
6583 	if (!sscanf(val,"%x",&x))
6584 		return GP_ERROR_BAD_PARAMETERS;
6585 	propval->u32 = x;
6586 	return GP_OK;
6587 }
6588 
6589 
6590 static int
_get_UINT32_as_time(CONFIG_GET_ARGS)6591 _get_UINT32_as_time(CONFIG_GET_ARGS) {
6592 	time_t	camtime;
6593 
6594 	gp_widget_new (GP_WIDGET_DATE, _(menu->label), widget);
6595 	gp_widget_set_name (*widget,menu->name);
6596 	camtime = dpd->CurrentValue.u32;
6597 	gp_widget_set_value (*widget,&camtime);
6598 	return (GP_OK);
6599 }
6600 
6601 static int
_put_UINT32_as_time(CONFIG_PUT_ARGS)6602 _put_UINT32_as_time(CONFIG_PUT_ARGS) {
6603 	time_t	camtime;
6604 
6605 	camtime = 0;
6606 	CR (gp_widget_get_value (widget,&camtime));
6607 	propval->u32 = camtime;
6608 	return (GP_OK);
6609 }
6610 
6611 static int
_get_UINT32_as_localtime(CONFIG_GET_ARGS)6612 _get_UINT32_as_localtime(CONFIG_GET_ARGS) {
6613 	time_t	camtime;
6614 	struct	tm *ptm;
6615 
6616 	gp_widget_new (GP_WIDGET_DATE, _(menu->label), widget);
6617 	gp_widget_set_name (*widget,menu->name);
6618 	camtime = dpd->CurrentValue.u32;
6619 	/* hack to convert from local time on camera to utc */
6620 	ptm = gmtime(&camtime);
6621 	ptm->tm_isdst = -1;
6622 	camtime = mktime (ptm);
6623 	gp_widget_set_value (*widget,&camtime);
6624 	return (GP_OK);
6625 }
6626 
6627 static int
_put_UINT32_as_localtime(CONFIG_PUT_ARGS)6628 _put_UINT32_as_localtime(CONFIG_PUT_ARGS) {
6629 	time_t	camtime,newcamtime;
6630 	struct	tm *ptm;
6631 #if HAVE_SETENV
6632 	char	*tz;
6633 #endif
6634 
6635 	camtime = 0;
6636 	CR (gp_widget_get_value (widget, &camtime));
6637 	ptm = localtime(&camtime);
6638 
6639 #if HAVE_SETENV
6640 	tz = getenv("TZ");
6641 	if (tz)
6642 		C_MEM (tz = strdup(tz));
6643 	setenv("TZ", "", 1);
6644 	tzset();
6645 #endif
6646 	newcamtime = mktime(ptm);
6647 #if HAVE_SETENV
6648 	if (tz) {
6649 		setenv("TZ", tz, 1);
6650 		free(tz);
6651 	} else
6652 		unsetenv("TZ");
6653 	tzset();
6654 #endif
6655 
6656 	propval->u32 = newcamtime;
6657 	return (GP_OK);
6658 }
6659 
6660 static int
_get_Canon_SyncTime(CONFIG_GET_ARGS)6661 _get_Canon_SyncTime(CONFIG_GET_ARGS) {
6662 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
6663 	gp_widget_set_name (*widget,menu->name);
6664 	return (GP_OK);
6665 }
6666 
6667 static int
_put_Canon_SyncTime(CONFIG_PUT_ARGS)6668 _put_Canon_SyncTime(CONFIG_PUT_ARGS) {
6669 	/* Just set the time if the entry changes. */
6670 	propval->u32 = time(NULL);
6671 	return (GP_OK);
6672 }
6673 
6674 static int
_get_Nikon_AFDrive(CONFIG_GET_ARGS)6675 _get_Nikon_AFDrive(CONFIG_GET_ARGS) {
6676 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
6677 	gp_widget_set_name (*widget,menu->name);
6678 	return (GP_OK);
6679 }
6680 
6681 static int
_put_Nikon_AFDrive(CONFIG_PUT_ARGS)6682 _put_Nikon_AFDrive(CONFIG_PUT_ARGS) {
6683 	PTPParams	*params = &(camera->pl->params);
6684 	GPContext 	*context = ((PTPData *) params->data)->context;
6685 
6686 	if (!ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_AfDrive))
6687 		return (GP_ERROR_NOT_SUPPORTED);
6688 
6689 	C_PTP (ptp_nikon_afdrive (&camera->pl->params));
6690 	/* wait at most 5 seconds for focusing currently */
6691 	C_PTP_REP (nikon_wait_busy (params, 10, 5000));
6692 	/* this can return PTP_RC_OK or PTP_RC_NIKON_OutOfFocus */
6693 	return GP_OK;
6694 }
6695 
6696 static int
_get_Nikon_ChangeAfArea(CONFIG_GET_ARGS)6697 _get_Nikon_ChangeAfArea(CONFIG_GET_ARGS) {
6698 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
6699 	gp_widget_set_name (*widget,menu->name);
6700 
6701 	gp_widget_set_value (*widget,"0x0");
6702 	return (GP_OK);
6703 }
6704 
6705 static int
_put_Nikon_ChangeAfArea(CONFIG_PUT_ARGS)6706 _put_Nikon_ChangeAfArea(CONFIG_PUT_ARGS) {
6707 	uint16_t	ret;
6708 	char		*val;
6709 	int		x,y;
6710 	PTPParams	*params = &(camera->pl->params);
6711 	GPContext 	*context = ((PTPData *) params->data)->context;
6712 
6713 	CR (gp_widget_get_value(widget, &val));
6714 
6715 	C_PARAMS (2 == sscanf(val, "%dx%d", &x, &y));
6716 
6717 	ret = ptp_nikon_changeafarea (&camera->pl->params, x, y);
6718 	if (ret == PTP_RC_NIKON_NotLiveView) {
6719 		gp_context_error (context, _("Nikon changeafarea works only in LiveView mode."));
6720 		return GP_ERROR;
6721 	}
6722 
6723 	C_PTP_MSG (ret, "Nikon changeafarea failed");
6724 #if 0
6725 	int		tries = 0;
6726 	/* wait at most 5 seconds for focusing currently */
6727 	while (PTP_RC_DeviceBusy == (ret = ptp_nikon_device_ready(&camera->pl->params))) {
6728 		tries++;
6729 		if (tries == 500)
6730 			return GP_ERROR_CAMERA_BUSY;
6731 		usleep(10*1000);
6732 	}
6733 	/* this can return PTP_RC_OK or PTP_RC_NIKON_OutOfFocus */
6734 	if (ret == PTP_RC_NIKON_OutOfFocus)
6735 		gp_context_error (context, _("Nikon autofocus drive did not focus."));
6736 #endif
6737 	return translate_ptp_result (ret);
6738 }
6739 
6740 static int
_get_Canon_EOS_AFDrive(CONFIG_GET_ARGS)6741 _get_Canon_EOS_AFDrive(CONFIG_GET_ARGS) {
6742 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
6743 	gp_widget_set_name (*widget,menu->name);
6744 	return (GP_OK);
6745 }
6746 
6747 static int
_put_Canon_EOS_AFDrive(CONFIG_PUT_ARGS)6748 _put_Canon_EOS_AFDrive(CONFIG_PUT_ARGS) {
6749 	int		val;
6750 	PTPParams	*params = &(camera->pl->params);
6751 
6752 	if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_DoAf))
6753 		return (GP_ERROR_NOT_SUPPORTED);
6754 
6755 	CR (gp_widget_get_value(widget, &val));
6756 	if (val)
6757 		C_PTP (ptp_canon_eos_afdrive (params));
6758 	else
6759 		C_PTP (ptp_canon_eos_afcancel (params));
6760 	/* Get the next set of event data */
6761 	C_PTP (ptp_check_eos_events (params));
6762 	return GP_OK;
6763 }
6764 
6765 static int
_get_Canon_EOS_AFCancel(CONFIG_GET_ARGS)6766 _get_Canon_EOS_AFCancel(CONFIG_GET_ARGS) {
6767 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
6768 	gp_widget_set_name (*widget,menu->name);
6769 	return (GP_OK);
6770 }
6771 
6772 static int
_put_Canon_EOS_AFCancel(CONFIG_PUT_ARGS)6773 _put_Canon_EOS_AFCancel(CONFIG_PUT_ARGS) {
6774 	PTPParams *params = &(camera->pl->params);
6775 
6776 	if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_AfCancel))
6777 		return (GP_ERROR_NOT_SUPPORTED);
6778 
6779 	C_PTP (ptp_canon_eos_afcancel (params));
6780 	/* Get the next set of event data */
6781 	C_PTP (ptp_check_eos_events (params));
6782 	return GP_OK;
6783 }
6784 
6785 static int
_get_Nikon_MFDrive(CONFIG_GET_ARGS)6786 _get_Nikon_MFDrive(CONFIG_GET_ARGS) {
6787 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
6788 	gp_widget_set_name (*widget,menu->name);
6789 
6790 	gp_widget_set_range(*widget, -32767.0, 32767.0, 1.0);
6791 	return (GP_OK);
6792 }
6793 
6794 static int
_put_Nikon_MFDrive(CONFIG_PUT_ARGS)6795 _put_Nikon_MFDrive(CONFIG_PUT_ARGS) {
6796 	uint16_t	ret;
6797 	float		val;
6798 	unsigned int	xval, flag;
6799 	PTPParams	*params = &(camera->pl->params);
6800 	GPContext 	*context = ((PTPData *) params->data)->context;
6801 
6802 	if (!ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_MfDrive))
6803 		return (GP_ERROR_NOT_SUPPORTED);
6804 	gp_widget_get_value(widget, &val);
6805 
6806 	if (val<0) {
6807 		xval = -val;
6808 		flag = 0x1;
6809 	} else {
6810 		xval = val;
6811 		flag = 0x2;
6812 	}
6813 	if (!xval) xval = 1;
6814 	ret = LOG_ON_PTP_E (ptp_nikon_mfdrive (&camera->pl->params, flag, xval));
6815 	if (ret == PTP_RC_NIKON_NotLiveView) {
6816 		gp_context_error (context, _("Nikon manual focus works only in LiveView mode."));
6817 		return GP_ERROR;
6818 	}
6819 	if (ret != PTP_RC_OK)
6820 		return translate_ptp_result(ret);
6821 
6822 	/* The mf drive operation has started ... wait for it to
6823 	 * finish. */
6824 	ret = LOG_ON_PTP_E (nikon_wait_busy (&camera->pl->params, 20, 1000));
6825 	if (ret == PTP_RC_NIKON_MfDriveStepEnd) {
6826 		gp_context_error (context, _("Nikon manual focus at limit."));
6827 		return GP_ERROR_CAMERA_ERROR;
6828 	}
6829 	if (ret == PTP_RC_NIKON_MfDriveStepInsufficiency) {
6830 		gp_context_error (context, _("Nikon manual focus stepping too small."));
6831 		return GP_ERROR_CAMERA_ERROR;
6832 	}
6833 	return translate_ptp_result(ret);
6834 }
6835 
6836 static int
_get_Nikon_ControlMode(CONFIG_GET_ARGS)6837 _get_Nikon_ControlMode(CONFIG_GET_ARGS) {
6838 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
6839 	gp_widget_set_name (*widget,menu->name);
6840 	gp_widget_set_value(*widget, "0");
6841 	return (GP_OK);
6842 }
6843 
6844 static int
_put_Nikon_ControlMode(CONFIG_PUT_ARGS)6845 _put_Nikon_ControlMode(CONFIG_PUT_ARGS) {
6846 	PTPParams *params = &(camera->pl->params);
6847 	char*		val;
6848 	unsigned int	xval = 0;
6849 
6850 	if (!ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_ChangeCameraMode))
6851 		return GP_ERROR_NOT_SUPPORTED;
6852 	gp_widget_get_value(widget, &val);
6853 
6854 	if (!sscanf(val,"%d",&xval))
6855 		return GP_ERROR;
6856 
6857 	C_PTP (ptp_nikon_changecameramode (&camera->pl->params, xval));
6858 	return GP_OK;
6859 }
6860 
6861 static int
_get_Canon_EOS_RemoteRelease(CONFIG_GET_ARGS)6862 _get_Canon_EOS_RemoteRelease(CONFIG_GET_ARGS) {
6863 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
6864 	gp_widget_set_name (*widget,menu->name);
6865 
6866 	/* FIXME: remember state of release */
6867 	gp_widget_add_choice (*widget, _("None"));
6868 	gp_widget_add_choice (*widget, _("Press Half"));
6869 	gp_widget_add_choice (*widget, _("Press Full"));
6870 	gp_widget_add_choice (*widget, _("Release Half"));
6871 	gp_widget_add_choice (*widget, _("Release Full"));
6872 	gp_widget_add_choice (*widget, _("Immediate"));
6873 	/* debugging */
6874 	gp_widget_add_choice (*widget, _("Press 1"));
6875 	gp_widget_add_choice (*widget, _("Press 2"));
6876 	gp_widget_add_choice (*widget, _("Press 3"));
6877 	gp_widget_add_choice (*widget, _("Release 1"));
6878 	gp_widget_add_choice (*widget, _("Release 2"));
6879 	gp_widget_add_choice (*widget, _("Release 3"));
6880 	gp_widget_set_value (*widget, _("None"));
6881 	return (GP_OK);
6882 }
6883 
6884 /* On EOS 7D:
6885  * 9128 1 0  (half?)
6886  * 9128 2 0  (full?)
6887  * parameters: press mode, ? afmode ? SDK seems to suggest 1==NonAF, 0 == AF
6888  */
6889 
6890 static int
_put_Canon_EOS_RemoteRelease(CONFIG_PUT_ARGS)6891 _put_Canon_EOS_RemoteRelease(CONFIG_PUT_ARGS) {
6892 	const char*	val;
6893 	PTPParams	*params = &(camera->pl->params);
6894 	GPContext 	*context = ((PTPData *) params->data)->context;
6895 
6896 	if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn))
6897 		return (GP_ERROR_NOT_SUPPORTED);
6898 
6899 	/* If someone has set the capture target between */
6900 	CR (camera_canon_eos_update_capture_target( camera, context, -1 ));
6901 
6902 	gp_widget_get_value(widget, &val);
6903 
6904 	if (!strcmp (val, _("None"))) {
6905 		return GP_OK;
6906 	} else if (!strcmp (val, _("Press Half"))) {
6907 		C_PTP (ptp_canon_eos_remotereleaseon (params, 1, 1));
6908 	} else if (!strcmp (val, _("Press Full"))) {
6909 		C_PTP (ptp_canon_eos_remotereleaseon (params, 3, 1));
6910 	} else if (!strcmp (val, _("Immediate"))) {
6911 		/* HACK by Flori Radlherr: "fire and forget" half release before release:
6912 		   Avoids autofocus drive while focus-switch on the lens is in AF state */
6913 		C_PTP (ptp_canon_eos_remotereleaseon (params, 1, 1));
6914 		C_PTP (ptp_canon_eos_remotereleaseon (params, 3, 1));
6915 	/* try out others with 0 */
6916 	} else if (!strcmp (val, _("Press 1"))) {
6917 		C_PTP (ptp_canon_eos_remotereleaseon (params, 1, 0));
6918 	} else if (!strcmp (val, _("Press 2"))) {
6919 		C_PTP (ptp_canon_eos_remotereleaseon (params, 2, 0));
6920 	} else if (!strcmp (val, _("Press 3"))) {
6921 		C_PTP (ptp_canon_eos_remotereleaseon (params, 3, 0));
6922 	} else if (!strcmp (val, _("Release 1"))) {
6923 		C_PTP (ptp_canon_eos_remotereleaseoff (params, 1));
6924 	} else if (!strcmp (val, _("Release 2"))) {
6925 		C_PTP (ptp_canon_eos_remotereleaseoff (params, 2));
6926 	} else if (!strcmp (val, _("Release 3"))) {
6927 		C_PTP (ptp_canon_eos_remotereleaseoff (params, 3));
6928 	} else if (!strcmp (val, _("Release Half"))) {
6929 		C_PTP (ptp_canon_eos_remotereleaseoff (params, 1));
6930 	} else if (!strcmp (val, _("Release Full"))) {
6931 		C_PTP (ptp_canon_eos_remotereleaseoff (params, 3));
6932 	} else {
6933 		GP_LOG_D ("Unknown value %s", val);
6934 		return GP_ERROR_NOT_SUPPORTED;
6935 	}
6936 
6937 	/* Get the next set of event data */
6938 	C_PTP (ptp_check_eos_events (params));
6939 	return GP_OK;
6940 }
6941 
6942 static int
_get_Canon_EOS_ContinousAF(CONFIG_GET_ARGS)6943 _get_Canon_EOS_ContinousAF(CONFIG_GET_ARGS) {
6944 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
6945 	gp_widget_set_name (*widget,menu->name);
6946 
6947 	gp_widget_add_choice (*widget, _("Off"));
6948 	gp_widget_add_choice (*widget, _("On"));
6949 	switch (dpd->CurrentValue.u32) {
6950 	case 0: gp_widget_set_value (*widget, _("Off")); break;
6951 	case 1: gp_widget_set_value (*widget, _("On")); break;
6952 	default: {
6953 		char buf[200];
6954 		sprintf(buf,"Unknown value 0x%08x", dpd->CurrentValue.u32);
6955 		gp_widget_set_value (*widget, buf);
6956 		break;
6957 	}
6958 	}
6959 	return GP_OK;
6960 }
6961 
6962 static int
_put_Canon_EOS_ContinousAF(CONFIG_PUT_ARGS)6963 _put_Canon_EOS_ContinousAF(CONFIG_PUT_ARGS) {
6964 	char *val;
6965 	unsigned int ival;
6966 
6967 	CR(gp_widget_get_value (widget, &val));
6968 	if (!strcmp(val,_("Off"))) { propval->u32 = 0; return GP_OK; }
6969 	if (!strcmp(val,_("On"))) { propval->u32 = 1; return GP_OK; }
6970 	if (!sscanf(val,"Unknown value 0x%08x",&ival))
6971 		return GP_ERROR_BAD_PARAMETERS;
6972 	propval->u32 = ival;
6973 	return GP_OK;
6974 }
6975 
6976 static int
_get_Canon_EOS_MFDrive(CONFIG_GET_ARGS)6977 _get_Canon_EOS_MFDrive(CONFIG_GET_ARGS) {
6978 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
6979 	gp_widget_set_name (*widget,menu->name);
6980 
6981 	gp_widget_add_choice (*widget, _("Near 1"));
6982 	gp_widget_add_choice (*widget, _("Near 2"));
6983 	gp_widget_add_choice (*widget, _("Near 3"));
6984 	gp_widget_add_choice (*widget, _("None"));
6985 	gp_widget_add_choice (*widget, _("Far 1"));
6986 	gp_widget_add_choice (*widget, _("Far 2"));
6987 	gp_widget_add_choice (*widget, _("Far 3"));
6988 
6989 	gp_widget_set_value (*widget, _("None"));
6990 	return (GP_OK);
6991 }
6992 
6993 static int
_put_Canon_EOS_MFDrive(CONFIG_PUT_ARGS)6994 _put_Canon_EOS_MFDrive(CONFIG_PUT_ARGS) {
6995 	const char*	val;
6996 	unsigned int	xval;
6997 	PTPParams *params = &(camera->pl->params);
6998 
6999 	if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_DriveLens))
7000 		return (GP_ERROR_NOT_SUPPORTED);
7001 	gp_widget_get_value(widget, &val);
7002 
7003 	if (!strcmp (val, _("None"))) return GP_OK;
7004 
7005 	if (!sscanf (val, _("Near %d"), &xval)) {
7006 		if (!sscanf (val, _("Far %d"), &xval)) {
7007 			GP_LOG_D ("Could not parse %s", val);
7008 			return GP_ERROR;
7009 		} else {
7010 			xval |= 0x8000;
7011 		}
7012 	}
7013 	C_PTP_MSG (ptp_canon_eos_drivelens (params, xval),
7014 		   "Canon manual focus drive 0x%x failed", xval);
7015 	/* Get the next set of event data */
7016 	C_PTP (ptp_check_eos_events (params));
7017 	return GP_OK;
7018 }
7019 
7020 static int
_get_Panasonic_MFDrive(CONFIG_GET_ARGS)7021 _get_Panasonic_MFDrive(CONFIG_GET_ARGS) {
7022 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
7023 	gp_widget_set_name (*widget,menu->name);
7024 
7025 	gp_widget_add_choice (*widget, _("Near 1"));
7026 	gp_widget_add_choice (*widget, _("Near 2"));
7027 	gp_widget_add_choice (*widget, _("None"));
7028 	gp_widget_add_choice (*widget, _("Far 1"));
7029 	gp_widget_add_choice (*widget, _("Far 2"));
7030 
7031 	gp_widget_set_value (*widget, _("None"));
7032 	return GP_OK;
7033 }
7034 
7035 static int
_put_Panasonic_MFDrive(CONFIG_PUT_ARGS)7036 _put_Panasonic_MFDrive(CONFIG_PUT_ARGS) {
7037 	const char*     val;
7038 	unsigned int    xval;
7039 	uint16_t	direction = 0; // 0=near
7040 	uint16_t	mode = 0x02;
7041 	PTPParams	*params = &(camera->pl->params);
7042 
7043 	gp_widget_get_value(widget, &val);
7044 
7045 	if (!strcmp (val, _("None"))) return GP_OK;
7046 
7047 	if (!sscanf (val, _("Near %d"), &xval)) {
7048 		if (!sscanf (val, _("Far %d"), &xval)) {
7049 			GP_LOG_D ("Could not parse %s", val);
7050 			return GP_ERROR;
7051 		} else {
7052 			direction = 1; // far
7053 		}
7054 	}
7055 	if(direction) { // far
7056 		if(xval == 1) mode = 0x03;
7057 		if(xval == 2) mode = 0x04;
7058 	} else { // near
7059 		if(xval == 1) mode = 0x02;
7060 		if(xval == 2) mode = 0x01;
7061 	}
7062 	gp_widget_set_value (widget, _("None")); /* Marcus: not right here */
7063 	C_PTP_MSG (ptp_panasonic_manualfocusdrive (params, mode), "Panasonic manual focus drive 0x%x failed", xval);
7064 	return GP_OK;
7065 }
7066 
7067 
7068 static int
_get_Olympus_OMD_MFDrive(CONFIG_GET_ARGS)7069 _get_Olympus_OMD_MFDrive(CONFIG_GET_ARGS) {
7070 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
7071 	gp_widget_set_name (*widget,menu->name);
7072 
7073 	gp_widget_add_choice (*widget, _("Near 1"));
7074 	gp_widget_add_choice (*widget, _("Near 2"));
7075 	gp_widget_add_choice (*widget, _("Near 3"));
7076 	gp_widget_add_choice (*widget, _("None"));
7077 	gp_widget_add_choice (*widget, _("Far 1"));
7078 	gp_widget_add_choice (*widget, _("Far 2"));
7079 	gp_widget_add_choice (*widget, _("Far 3"));
7080 
7081 	gp_widget_set_value (*widget, _("None"));
7082 	return (GP_OK);
7083 }
7084 
7085 static int
_put_Olympus_OMD_MFDrive(CONFIG_PUT_ARGS)7086 _put_Olympus_OMD_MFDrive(CONFIG_PUT_ARGS) {
7087 	const char*	val;
7088 	unsigned int	xval;
7089 	uint32_t direction = 0x01;
7090 	uint32_t step_size = 0x0e;
7091 	PTPParams *params = &(camera->pl->params);
7092 
7093 	if (!ptp_operation_issupported(params, PTP_OC_OLYMPUS_OMD_MFDrive))
7094 		return (GP_ERROR_NOT_SUPPORTED);
7095 	gp_widget_get_value(widget, &val);
7096 
7097 	if (!strcmp (val, _("None"))) return GP_OK;
7098 
7099 	if (!sscanf (val, _("Near %d"), &xval)) {
7100 		if (!sscanf (val, _("Far %d"), &xval)) {
7101 			GP_LOG_D ("Could not parse %s", val);
7102 			return GP_ERROR;
7103 		} else {
7104 			direction = 0x02;
7105 		}
7106 	}
7107 	if(xval == 1) step_size = 0x03;
7108 	if(xval == 2) step_size = 0x0e;
7109 	if(xval == 3) step_size = 0x3c;
7110 
7111 	C_PTP_MSG (ptp_olympus_omd_move_focus (params, direction, step_size),
7112 		   "Olympus manual focus drive 0x%x failed", xval);
7113 	return GP_OK;
7114 }
7115 
7116 
7117 static int
_get_Canon_EOS_Zoom(CONFIG_GET_ARGS)7118 _get_Canon_EOS_Zoom(CONFIG_GET_ARGS) {
7119 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
7120 	gp_widget_set_name (*widget, menu->name);
7121 
7122 	gp_widget_set_value (*widget, "0");
7123 	return (GP_OK);
7124 }
7125 
7126 /* Only 1 and 5 seem to work on the EOS 1000D */
7127 static int
_put_Canon_EOS_Zoom(CONFIG_PUT_ARGS)7128 _put_Canon_EOS_Zoom(CONFIG_PUT_ARGS) {
7129 	const char*	val;
7130 	unsigned int	xval;
7131 	PTPParams *params = &(camera->pl->params);
7132 
7133 	if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_Zoom))
7134 		return (GP_ERROR_NOT_SUPPORTED);
7135 
7136 	gp_widget_get_value(widget, &val);
7137 	if (!sscanf (val, "%d", &xval)) {
7138 		GP_LOG_D ("Could not parse %s", val);
7139 		return GP_ERROR;
7140 	}
7141 	C_PTP_MSG (ptp_canon_eos_zoom (params, xval),
7142 		   "Canon zoom 0x%x failed", xval);
7143 
7144 	/* Get the next set of event data */
7145 	C_PTP (ptp_check_eos_events (params));
7146 	return GP_OK;
7147 }
7148 
7149 /* EOS Zoom. Works in approx 64 pixel steps on the EOS 1000D, but just accept
7150  * all kind of pairs */
7151 static int
_get_Canon_EOS_ZoomPosition(CONFIG_GET_ARGS)7152 _get_Canon_EOS_ZoomPosition(CONFIG_GET_ARGS) {
7153 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
7154 	gp_widget_set_name (*widget, menu->name);
7155 
7156 	gp_widget_set_value (*widget, "0,0");
7157 	return (GP_OK);
7158 }
7159 
7160 static int
_put_Canon_EOS_ZoomPosition(CONFIG_PUT_ARGS)7161 _put_Canon_EOS_ZoomPosition(CONFIG_PUT_ARGS) {
7162 	const char*	val;
7163 	unsigned int	x,y;
7164 	PTPParams *params = &(camera->pl->params);
7165 
7166 	if (!ptp_operation_issupported(params, PTP_OC_CANON_EOS_ZoomPosition))
7167 		return (GP_ERROR_NOT_SUPPORTED);
7168 
7169 	gp_widget_get_value(widget, &val);
7170 	if (2!=sscanf (val, "%d,%d", &x,&y)) {
7171 		GP_LOG_D ("Could not parse %s (expected 'x,y')", val);
7172 		return GP_ERROR;
7173 	}
7174 	C_PTP_MSG (ptp_canon_eos_zoomposition (params, x,y),
7175 		   "Canon zoom position %d,%d failed", x, y);
7176 	/* Get the next set of event data */
7177 	C_PTP (ptp_check_eos_events (params));
7178 	return GP_OK;
7179 }
7180 
7181 static int
_get_Canon_CHDK_Script(CONFIG_GET_ARGS)7182 _get_Canon_CHDK_Script(CONFIG_GET_ARGS) {
7183 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
7184 	gp_widget_set_name (*widget, menu->name);
7185 
7186 	gp_widget_add_choice  (*widget, "cls();exit_alt();");
7187 	gp_widget_add_choice  (*widget, "shoot();cls();exit_alt();");
7188 	gp_widget_set_value  (*widget, "cls();exit_alt();");
7189 	return (GP_OK);
7190 }
7191 
7192 static int
_put_Canon_CHDK_Script(CONFIG_PUT_ARGS)7193 _put_Canon_CHDK_Script(CONFIG_PUT_ARGS) {
7194 	char		*script;
7195 	PTPParams	*params = &(camera->pl->params);
7196 	int		script_id;
7197 	unsigned int	status;
7198 	int		luastatus;
7199 
7200 	CR (gp_widget_get_value(widget, &script));
7201 
7202 //  Nafraf: Working on this!!!
7203 //
7204 //  gphoto: config.c
7205 //  ret = ptp_chdk_exec_lua (params, val, &output);
7206 //
7207 //  chdkptp: chdkptp.c
7208 //    ret = ptp_chdk_exec_lua (params,
7209 //                (char *)luaL_optstring(L,2,""),
7210 //                luaL_optnumber(L,3,0),
7211 //                &ptp_cs->script_id,
7212 //                &status)
7213 //
7214 // Unfinished, I'm not sure of last 3 parameters
7215 	GP_LOG_D ("calling script: %s", script);
7216 	C_PTP (ptp_chdk_exec_lua (params, script, 0, &script_id, &luastatus));
7217 	GP_LOG_D ("called script, id %d, status %d", script_id, luastatus);
7218 
7219 	while (1) {
7220 		C_PTP (ptp_chdk_get_script_status(params, &status));
7221 		GP_LOG_D ("script status %x", status);
7222 
7223 		if (status & PTP_CHDK_SCRIPT_STATUS_MSG) {
7224 			ptp_chdk_script_msg	*msg = NULL;
7225 
7226 			C_PTP (ptp_chdk_read_script_msg(params, &msg));
7227 			GP_LOG_D ("message script id %d, type %d, subtype %d", msg->script_id, msg->type, msg->subtype);
7228 			GP_LOG_D ("message script %s", msg->data);
7229 			free (msg);
7230 		}
7231 
7232 		if (!(status & PTP_CHDK_SCRIPT_STATUS_RUN))
7233 			break;
7234 		usleep(100000);
7235 	}
7236 
7237 	return GP_OK;
7238 }
7239 
7240 
7241 static int
_get_STR_as_time(CONFIG_GET_ARGS)7242 _get_STR_as_time(CONFIG_GET_ARGS) {
7243 	time_t		camtime;
7244 	struct tm	tm;
7245 	char		capture_date[64],tmp[5];
7246 
7247 	/* strptime() is not widely accepted enough to use yet */
7248 	memset(&tm,0,sizeof(tm));
7249 	if (!dpd->CurrentValue.str)
7250 		return (GP_ERROR);
7251 	gp_widget_new (GP_WIDGET_DATE, _(menu->label), widget);
7252 	gp_widget_set_name (*widget, menu->name);
7253 	strncpy(capture_date,dpd->CurrentValue.str,sizeof(capture_date));
7254 	strncpy (tmp, capture_date, 4);
7255 	tmp[4] = 0;
7256 	tm.tm_year=atoi (tmp) - 1900;
7257 	strncpy (tmp, capture_date + 4, 2);
7258 	tmp[2] = 0;
7259 	tm.tm_mon = atoi (tmp) - 1;
7260 	strncpy (tmp, capture_date + 6, 2);
7261 	tmp[2] = 0;
7262 	tm.tm_mday = atoi (tmp);
7263 	strncpy (tmp, capture_date + 9, 2);
7264 	tmp[2] = 0;
7265 	tm.tm_hour = atoi (tmp);
7266 	strncpy (tmp, capture_date + 11, 2);
7267 	tmp[2] = 0;
7268 	tm.tm_min = atoi (tmp);
7269 	strncpy (tmp, capture_date + 13, 2);
7270 	tmp[2] = 0;
7271 	tm.tm_sec = atoi (tmp);
7272 	tm.tm_isdst = -1; /* autodetect */
7273 	camtime = mktime(&tm);
7274 	gp_widget_set_value (*widget,&camtime);
7275 	return (GP_OK);
7276 }
7277 
7278 static int
_put_STR_as_time(CONFIG_PUT_ARGS)7279 _put_STR_as_time(CONFIG_PUT_ARGS) {
7280 	time_t		camtime;
7281 #ifdef HAVE_GMTIME_R
7282 	struct tm	xtm;
7283 #endif
7284 	struct tm	*pxtm;
7285 	char		asctime[64];
7286 
7287 	camtime = 0;
7288 	CR (gp_widget_get_value (widget,&camtime));
7289 #ifdef HAVE_GMTIME_R
7290 	memset(&xtm,0,sizeof(xtm));
7291 	pxtm = localtime_r (&camtime, &xtm);
7292 #else
7293 	pxtm = localtime (&camtime);
7294 #endif
7295 	/* 20020101T123400.0 is returned by the HP Photosmart */
7296 	sprintf(asctime,"%04d%02d%02dT%02d%02d%02d",pxtm->tm_year+1900,pxtm->tm_mon+1,pxtm->tm_mday,pxtm->tm_hour,pxtm->tm_min,pxtm->tm_sec);
7297 
7298 	/* if the camera reported fractional seconds, also add it */
7299 	if (strchr(dpd->CurrentValue.str,'.'))
7300 		strcat(asctime,".0");
7301 
7302 	C_MEM (propval->str = strdup(asctime));
7303 	return (GP_OK);
7304 }
7305 
7306 static int
_put_None(CONFIG_PUT_ARGS)7307 _put_None(CONFIG_PUT_ARGS) {
7308 	return (GP_ERROR_NOT_SUPPORTED);
7309 }
7310 
7311 static int
_get_Canon_CaptureMode(CONFIG_GET_ARGS)7312 _get_Canon_CaptureMode(CONFIG_GET_ARGS) {
7313 	int val;
7314 
7315 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7316 	gp_widget_set_name (*widget, menu->name);
7317 	/* we use presence of FlashMode as indication of capture enablement or not */
7318 	val = have_prop (camera, PTP_VENDOR_CANON, PTP_DPC_CANON_FlashMode);
7319 	return gp_widget_set_value  (*widget, &val);
7320 }
7321 
7322 static int
_put_Canon_CaptureMode(CONFIG_PUT_ARGS)7323 _put_Canon_CaptureMode(CONFIG_PUT_ARGS) {
7324 	int val;
7325 
7326 	CR (gp_widget_get_value(widget, &val));
7327 	if (val)
7328 		return camera_prepare_capture (camera, NULL);
7329 	else
7330 		return camera_unprepare_capture (camera, NULL);
7331 }
7332 
7333 static int
_get_Canon_RemoteMode(CONFIG_GET_ARGS)7334 _get_Canon_RemoteMode(CONFIG_GET_ARGS) {
7335 	char		buf[200];
7336 	PTPParams	*params = &(camera->pl->params);
7337 	uint32_t	mode;
7338 
7339 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
7340 	gp_widget_set_name (*widget, menu->name);
7341 	if (ptp_operation_issupported (params, PTP_OC_CANON_EOS_GetRemoteMode)) {
7342 		C_PTP (ptp_canon_eos_getremotemode (params, &mode));
7343 		sprintf (buf, "%d", mode);
7344 	} else {
7345 		strcpy (buf, "0");
7346 	}
7347 	return gp_widget_set_value  (*widget, buf);
7348 }
7349 
7350 static int
_put_Canon_RemoteMode(CONFIG_PUT_ARGS)7351 _put_Canon_RemoteMode(CONFIG_PUT_ARGS) {
7352 	uint32_t	mode;
7353 	char		*val;
7354 	PTPParams	*params = &(camera->pl->params);
7355 
7356 	CR (gp_widget_get_value(widget, &val));
7357 	if (!sscanf (val, "%d", &mode))
7358 		return GP_ERROR;
7359 	C_PTP (ptp_canon_eos_setremotemode (params, mode));
7360 	return GP_OK;
7361 }
7362 
7363 
7364 static int
_get_Canon_EOS_ViewFinder(CONFIG_GET_ARGS)7365 _get_Canon_EOS_ViewFinder(CONFIG_GET_ARGS) {
7366 	int val;
7367 	PTPParams		*params = &(camera->pl->params);
7368 
7369 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7370 	gp_widget_set_name (*widget, menu->name);
7371 	val = params->inliveview;	/* try returning live view mode */
7372 	gp_widget_set_value  (*widget, &val);
7373 	return GP_OK;
7374 }
7375 
7376 static int
_put_Canon_EOS_ViewFinder(CONFIG_PUT_ARGS)7377 _put_Canon_EOS_ViewFinder(CONFIG_PUT_ARGS) {
7378 	int			val;
7379 	uint16_t		res;
7380 	PTPParams		*params = &(camera->pl->params);
7381 	PTPPropertyValue	xval;
7382 
7383 	CR (gp_widget_get_value(widget, &val));
7384 	if (val) {
7385 		if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_InitiateViewfinder)) {
7386 			res = ptp_canon_eos_start_viewfinder (params);
7387 			params->inliveview = 1;
7388 			return translate_ptp_result (res);
7389 		}
7390 	} else {
7391 		if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_TerminateViewfinder)) {
7392 			res = ptp_canon_eos_end_viewfinder (params);
7393 			params->inliveview = 0;
7394 			return translate_ptp_result (res);
7395 		}
7396 	}
7397 	if (val)
7398 		xval.u16 = 2;
7399 	else
7400 		xval.u16 = 0;
7401 	C_PTP_MSG (ptp_canon_eos_setdevicepropvalue (params, PTP_DPC_CANON_EOS_EVFOutputDevice, &xval, PTP_DTC_UINT16),
7402 		   "ptp2_eos_viewfinder enable: failed to set evf outputmode to %d", xval.u16);
7403         return GP_OK;
7404 }
7405 
7406 static int
_get_Panasonic_ViewFinder(CONFIG_GET_ARGS)7407 _get_Panasonic_ViewFinder(CONFIG_GET_ARGS) {
7408 	int val;
7409 
7410 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7411 	gp_widget_set_name (*widget, menu->name);
7412 	val = 2;	/* always changed, unless we can find out the state ... */
7413 	gp_widget_set_value  (*widget, &val);
7414 	return (GP_OK);
7415 }
7416 
7417 static int
_put_Panasonic_ViewFinder(CONFIG_PUT_ARGS)7418 _put_Panasonic_ViewFinder(CONFIG_PUT_ARGS) {
7419 	int			val;
7420 	uint16_t		res;
7421 	PTPParams		*params = &(camera->pl->params);
7422 
7423 	CR (gp_widget_get_value(widget, &val));
7424 	if (val) {
7425 		res = ptp_panasonic_liveview (params, 1);
7426 		params->inliveview = 1;
7427 	} else {
7428 		res = ptp_panasonic_liveview (params, 0);
7429 		params->inliveview = 0;
7430 	}
7431 	return translate_ptp_result (res);
7432 }
7433 
7434 static int
_get_Nikon_ViewFinder(CONFIG_GET_ARGS)7435 _get_Nikon_ViewFinder(CONFIG_GET_ARGS) {
7436 	int			val;
7437 	PTPPropertyValue	value;
7438 	PTPParams		*params = &(camera->pl->params);
7439 
7440 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7441 	gp_widget_set_name (*widget, menu->name);
7442 	if (LOG_ON_PTP_E (ptp_getdevicepropvalue (params, PTP_DPC_NIKON_LiveViewStatus, &value, PTP_DTC_UINT8)) != PTP_RC_OK )
7443 		value.u8 = 0;
7444 	val = value.u8 ? 1 : 0;
7445 	gp_widget_set_value  (*widget, &val);
7446 	return (GP_OK);
7447 }
7448 
7449 static int
_put_Nikon_ViewFinder(CONFIG_PUT_ARGS)7450 _put_Nikon_ViewFinder(CONFIG_PUT_ARGS) {
7451 	int			val;
7452 	PTPParams		*params = &(camera->pl->params);
7453 	GPContext 		*context = ((PTPData *) params->data)->context;
7454 
7455 	if (!ptp_operation_issupported(params, PTP_OC_NIKON_StartLiveView))
7456 		return GP_ERROR_NOT_SUPPORTED;
7457 
7458 	CR (gp_widget_get_value (widget, &val));
7459 	if (val) {
7460 		PTPPropertyValue	value;
7461 
7462 		if (LOG_ON_PTP_E (ptp_getdevicepropvalue (params, PTP_DPC_NIKON_LiveViewStatus, &value, PTP_DTC_UINT8)) != PTP_RC_OK)
7463 			value.u8 = 0;
7464 
7465 		if (have_prop(camera, params->deviceinfo.VendorExtensionID, PTP_DPC_NIKON_LiveViewProhibitCondition)) {
7466 			C_PTP (ptp_getdevicepropvalue (params, PTP_DPC_NIKON_LiveViewProhibitCondition, &value, PTP_DTC_UINT32));
7467 
7468 			if (value.u32) {
7469 				/* we could have multiple reasons, but just report the first one. by decreasing order of possibility */
7470 				if (value.u32 & (1<<8)) { gp_context_error (context, _("Liveview cannot start: Battery exhausted")); return GP_ERROR; }
7471 				if (value.u32 & (1<<17)){ gp_context_error (context, _("Liveview cannot start: Temperature too high")); return GP_ERROR; }
7472 				if (value.u32 & (1<<9)) { gp_context_error (context, _("Liveview cannot start: TTL error")); return GP_ERROR; }
7473 				if (value.u32 & (1<<22)){ gp_context_error (context, _("Liveview cannot start: In Mirror-up operation")); return GP_ERROR; }
7474 				if (value.u32 & (1<<24)){ gp_context_error (context, _("Liveview cannot start: Lens is retracting")); return GP_ERROR; }
7475 				if (value.u32 & (1<<5)) { gp_context_error (context, _("Liveview cannot start: Minimum aperture warning")); return GP_ERROR; }
7476 				if (value.u32 & (1<<15)){ gp_context_error (context, _("Liveview cannot start: Processing of shooting operation")); return GP_ERROR; }
7477 				if (value.u32 & (1<<2)) { gp_context_error (context, _("Liveview cannot start: Sequence error")); return GP_ERROR; }
7478 				if (value.u32 & (1<<31)){ gp_context_error (context, _("Liveview cannot start: Exposure Program Mode is not P/A/S/M")); return GP_ERROR; }
7479 				if (value.u32 & (1<<21)){ gp_context_error (context, _("Liveview cannot start: Bulb warning")); return GP_ERROR; }
7480 				if (value.u32 & (1<<20)){ gp_context_error (context, _("Liveview cannot start: Card unformatted")); return GP_ERROR; }
7481 				if (value.u32 & (1<<19)){ gp_context_error (context, _("Liveview cannot start: Card error")); return GP_ERROR; }
7482 				if (value.u32 & (1<<18)){ gp_context_error (context, _("Liveview cannot start: Card protected")); return GP_ERROR; }
7483 				if (value.u32 & (1<<14)){ gp_context_error (context, _("Liveview cannot start: Recording destination card, but no card or card protected")); return GP_ERROR; }
7484 				if (value.u32 & (1<<12)){ gp_context_error (context, _("Liveview cannot start: Pending unretrieved SDRAM image")); return GP_ERROR; }
7485 				if (value.u32 & (1<<12)){ gp_context_error (context, _("Liveview cannot start: Pending unretrieved SDRAM image")); return GP_ERROR; }
7486 				if (value.u32 & (1<<4)) { gp_context_error (context, _("Liveview cannot start: Fully pressed button")); return GP_ERROR; }
7487 
7488 				gp_context_error (context, _("Liveview cannot start: code 0x%08x"), value.u32);
7489 				return GP_ERROR;
7490 			}
7491 		}
7492 
7493                 if (!value.u8) {
7494 			value.u8 = 1;
7495 			LOG_ON_PTP_E (ptp_setdevicepropvalue (params, PTP_DPC_NIKON_RecordingMedia, &value, PTP_DTC_UINT8));
7496 			C_PTP_REP_MSG (ptp_nikon_start_liveview (params),
7497 				       _("Nikon enable liveview failed"));
7498 			/* Has to put the mirror up, so takes a bit. */
7499 			C_PTP (nikon_wait_busy(params, 50, 1000));
7500 			params->inliveview = 1;
7501 		}
7502 	} else {
7503 		if (ptp_operation_issupported(params, PTP_OC_NIKON_EndLiveView))
7504 			C_PTP (ptp_nikon_end_liveview (params));
7505 		params->inliveview = 0;
7506 	}
7507 	return GP_OK;
7508 }
7509 
7510 static int
_get_Canon_FocusLock(CONFIG_GET_ARGS)7511 _get_Canon_FocusLock(CONFIG_GET_ARGS) {
7512 	int val;
7513 
7514 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7515 	gp_widget_set_name (*widget,menu->name);
7516 	val = 2; /* always changed */
7517 	gp_widget_set_value  (*widget, &val);
7518 	return (GP_OK);
7519 }
7520 
7521 static int
_put_Canon_FocusLock(CONFIG_PUT_ARGS)7522 _put_Canon_FocusLock(CONFIG_PUT_ARGS)
7523 {
7524 	PTPParams *params = &(camera->pl->params);
7525 	int val;
7526 
7527 	CR (gp_widget_get_value(widget, &val));
7528 	if (val)
7529 		C_PTP (ptp_canon_focuslock (params));
7530 	else
7531 		C_PTP (ptp_canon_focusunlock (params));
7532 	return GP_OK;
7533 }
7534 
7535 static int
_get_PowerDown(CONFIG_GET_ARGS)7536 _get_PowerDown(CONFIG_GET_ARGS) {
7537 	int val;
7538 
7539 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7540 	gp_widget_set_name (*widget,menu->name);
7541 	val = 2; /* always changed */
7542 	gp_widget_set_value  (*widget, &val);
7543 	return (GP_OK);
7544 }
7545 
7546 static int
_put_PowerDown(CONFIG_PUT_ARGS)7547 _put_PowerDown(CONFIG_PUT_ARGS)
7548 {
7549 	PTPParams *params = &(camera->pl->params);
7550 	int val;
7551 
7552 	CR (gp_widget_get_value(widget, &val));
7553 	if (val)
7554 		C_PTP (ptp_powerdown (params));
7555 	return GP_OK;
7556 }
7557 
7558 static int
_get_Generic_OPCode(CONFIG_GET_ARGS)7559 _get_Generic_OPCode(CONFIG_GET_ARGS) {
7560 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
7561 	gp_widget_set_name (*widget,menu->name);
7562 	gp_widget_set_value  (*widget, "0x1001,0xparam1,0xparam2");
7563 	return GP_OK;
7564 }
7565 
7566 static int
_put_Generic_OPCode(CONFIG_PUT_ARGS)7567 _put_Generic_OPCode(CONFIG_PUT_ARGS)
7568 {
7569 	PTPParams		*params = &(camera->pl->params);
7570 	char			*val, *x;
7571 	int			opcode;
7572 	int			nparams;
7573 	uint32_t		xparams[5];
7574 	uint16_t		ret;
7575 	PTPContainer		ptp;
7576 	unsigned char		*data = NULL;
7577 	unsigned int		size = 0;
7578 
7579 	CR (gp_widget_get_value(widget, &val));
7580 
7581 	if (!sscanf(val,"0x%x", &opcode))
7582 		return GP_ERROR_BAD_PARAMETERS;
7583 	GP_LOG_D ("opcode 0x%x", opcode);
7584 	nparams = 0; x = val;
7585 	while ((x = strchr(x,',')) && (nparams<5)) {
7586 		x++;
7587 		if (!sscanf(x,"0x%x", &xparams[nparams]))
7588 			return GP_ERROR_BAD_PARAMETERS;
7589 		GP_LOG_D ("param %d 0x%x", nparams, xparams[nparams]);
7590 		nparams++;
7591 	}
7592 	ptp.Code = opcode;
7593 	ptp.Nparam = nparams;
7594 	ptp.Param1 = xparams[0];
7595 	ptp.Param2 = xparams[1];
7596 	ptp.Param3 = xparams[2];
7597 	ptp.Param4 = xparams[3];
7598 	ptp.Param5 = xparams[4];
7599 
7600 	/* FIXME: handle in data */
7601 
7602 	ret = ptp_transaction (params, &ptp, PTP_DP_GETDATA, 0, &data, &size);
7603 
7604 	/* FIXME: handle out data (store locally?) */
7605 
7606 	return translate_ptp_result (ret);
7607 }
7608 
7609 static int
_get_Sony_Movie(CONFIG_GET_ARGS)7610 _get_Sony_Movie(CONFIG_GET_ARGS) {
7611 	int val;
7612 
7613 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7614 	gp_widget_set_name (*widget,menu->name);
7615 	val = 2; /* always changed */
7616 	gp_widget_set_value  (*widget, &val);
7617 	return (GP_OK);
7618 }
7619 
7620 static int
_put_Sony_Movie(CONFIG_PUT_ARGS)7621 _put_Sony_Movie(CONFIG_PUT_ARGS)
7622 {
7623 	PTPParams *params = &(camera->pl->params);
7624 	int val;
7625 	PTPPropertyValue	value;
7626 	GPContext *context = ((PTPData *) params->data)->context;
7627 
7628 	CR (gp_widget_get_value(widget, &val));
7629 	if (val)
7630 		value.u16 = 2;
7631 	else
7632 		value.u16 = 1;
7633         C_PTP_REP (ptp_sony_setdevicecontrolvalueb (params, 0xD2C8, &value, PTP_DTC_UINT16 ));
7634 	return GP_OK;
7635 }
7636 
7637 static int
_get_Sony_QX_Movie(CONFIG_GET_ARGS)7638 _get_Sony_QX_Movie(CONFIG_GET_ARGS) {
7639 	int val;
7640 
7641 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7642 	gp_widget_set_name (*widget,menu->name);
7643 	val = 2; /* always changed */
7644 	gp_widget_set_value  (*widget, &val);
7645 	return GP_OK;
7646 }
7647 
7648 static int
_put_Sony_QX_Movie(CONFIG_PUT_ARGS)7649 _put_Sony_QX_Movie(CONFIG_PUT_ARGS)
7650 {
7651 	PTPParams *params = &(camera->pl->params);
7652 	int val;
7653 	PTPPropertyValue	value;
7654 	GPContext *context = ((PTPData *) params->data)->context;
7655 
7656 	CR (gp_widget_get_value(widget, &val));
7657 	if (val)
7658 		value.u16 = 2;
7659 	else
7660 		value.u16 = 1;
7661         C_PTP_REP (ptp_sony_qx_setdevicecontrolvalueb (params, PTP_DPC_SONY_QX_Movie_Rec, &value, PTP_DTC_UINT16 ));
7662 	return GP_OK;
7663 }
7664 
7665 static int
_get_Nikon_Movie(CONFIG_GET_ARGS)7666 _get_Nikon_Movie(CONFIG_GET_ARGS) {
7667 	int val;
7668 
7669 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7670 	gp_widget_set_name (*widget,menu->name);
7671 	val = 2; /* always changed */
7672 	gp_widget_set_value  (*widget, &val);
7673 	return (GP_OK);
7674 }
7675 
7676 static int
_put_Nikon_Movie(CONFIG_PUT_ARGS)7677 _put_Nikon_Movie(CONFIG_PUT_ARGS)
7678 {
7679 	PTPParams *params = &(camera->pl->params);
7680 	int val, ret;
7681 	GPContext *context = ((PTPData *) params->data)->context;
7682 	PTPPropertyValue	value;
7683 
7684 	CR (gp_widget_get_value(widget, &val));
7685 	if (val) {
7686 		if (have_prop(camera,PTP_VENDOR_NIKON,PTP_DPC_NIKON_ApplicationMode)) {
7687 			value.u8 = 0;
7688 			C_PTP (ptp_getdevicepropvalue (params, PTP_DPC_NIKON_ApplicationMode, &value, PTP_DTC_UINT8));
7689 			if (value.u8 != 1) {
7690 				value.u8 = 1;
7691 				C_PTP (ptp_setdevicepropvalue (params, PTP_DPC_NIKON_ApplicationMode, &value, PTP_DTC_UINT8));
7692 			}
7693 		}
7694 
7695                 ret = ptp_getdevicepropvalue (params, PTP_DPC_NIKON_LiveViewStatus, &value, PTP_DTC_UINT8);
7696                 if (ret != PTP_RC_OK)
7697                         value.u8 = 0;
7698 
7699                 if (!value.u8) {
7700                         value.u8 = 1;
7701                         LOG_ON_PTP_E (ptp_setdevicepropvalue (params, PTP_DPC_NIKON_RecordingMedia, &value, PTP_DTC_UINT8));
7702                         C_PTP_REP_MSG (ptp_nikon_start_liveview (params),
7703                                        _("Nikon enable liveview failed"));
7704 			C_PTP_REP_MSG (nikon_wait_busy(params, 50, 1000),
7705 				       _("Nikon enable liveview failed"));
7706 		}
7707 
7708 		if (have_prop(camera,PTP_VENDOR_NIKON,PTP_DPC_NIKON_MovRecProhibitCondition)) {
7709 			value.u32 = 0;
7710 			LOG_ON_PTP_E (ptp_getdevicepropvalue (params, PTP_DPC_NIKON_MovRecProhibitCondition, &value, PTP_DTC_UINT32));
7711 			if (value.u32) {
7712 				if (value.u32 & (1<<14)) { gp_context_error (context, _("Movie recording cannot start: Camera is not in application mode.")); return GP_ERROR; }
7713 				if (value.u32 & (1<<13)) { gp_context_error (context, _("Movie recording cannot start: Set liveview selector is enabled.")); return GP_ERROR; }
7714 				if (value.u32 & (1<<12)) { gp_context_error (context, _("Movie recording cannot start: In enlarged liveview.")); return GP_ERROR; }
7715 				if (value.u32 & (1<<11)) { gp_context_error (context, _("Movie recording cannot start: Card protected.")); return GP_ERROR; }
7716 				if (value.u32 & (1<<10)) { gp_context_error (context, _("Movie recording cannot start: Already in movie recording.")); return GP_ERROR; }
7717 				if (value.u32 & (1<< 9)) { gp_context_error (context, _("Movie recording cannot start: Images / movies not yet record in buffer.")); return GP_ERROR; }
7718 				if (value.u32 & (1<< 3)) { gp_context_error (context, _("Movie recording cannot start: Card full.")); return GP_ERROR; }
7719 				if (value.u32 & (1<< 2)) { gp_context_error (context, _("Movie recording cannot start: Card not formatted.")); return GP_ERROR; }
7720 				if (value.u32 & (1<< 1)) { gp_context_error (context, _("Movie recording cannot start: Card error.")); return GP_ERROR; }
7721 				if (value.u32 & (1<< 0)) { gp_context_error (context, _("Movie recording cannot start: No card.")); return GP_ERROR; }
7722 				gp_context_error (context, _("Movie recording cannot start: code 0x%08x"), value.u32);
7723 				return GP_ERROR;
7724 			}
7725 		}
7726 
7727 		C_PTP_REP (ptp_nikon_startmovie (params));
7728 	} else {
7729 		C_PTP_REP (ptp_nikon_stopmovie (params));
7730 		/* switch Application Mode off again, otherwise we cannot get to the filesystem */
7731 		if (have_prop(camera,PTP_VENDOR_NIKON,PTP_DPC_NIKON_ApplicationMode)) {
7732 			value.u8 = 1;
7733 			C_PTP (ptp_getdevicepropvalue (params, PTP_DPC_NIKON_ApplicationMode, &value, PTP_DTC_UINT8));
7734 			if (value.u8 != 0) {
7735 				value.u8 = 0;
7736 				C_PTP (ptp_setdevicepropvalue (params, PTP_DPC_NIKON_ApplicationMode, &value, PTP_DTC_UINT8));
7737 			}
7738 		}
7739 	}
7740 	return GP_OK;
7741 }
7742 
7743 static int
_get_Nikon_Bulb(CONFIG_GET_ARGS)7744 _get_Nikon_Bulb(CONFIG_GET_ARGS) {
7745 	int val;
7746 
7747 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7748 	gp_widget_set_name (*widget,menu->name);
7749 	val = 2; /* always changed */
7750 	gp_widget_set_value  (*widget, &val);
7751 	return (GP_OK);
7752 }
7753 
7754 static int
_put_Nikon_Bulb(CONFIG_PUT_ARGS)7755 _put_Nikon_Bulb(CONFIG_PUT_ARGS)
7756 {
7757 	PTPParams *params = &(camera->pl->params);
7758 	int val;
7759 
7760 	CR (gp_widget_get_value(widget, &val));
7761 	if (val) {
7762 		PTPPropertyValue propval2;
7763 		char buf[20];
7764 
7765 		C_PTP (ptp_nikon_changecameramode (params, 1));
7766 		propval2.u16 = 1; /* Exposure Mode to Full Manual */
7767 		C_PTP (ptp_setdevicepropvalue (params, PTP_DPC_ExposureProgramMode, &propval2, PTP_DTC_UINT16));
7768 		propval2.u32 = 0xffffffff; /* Exposure Time to bulb */
7769 		C_PTP_MSG (ptp_setdevicepropvalue (params, PTP_DPC_ExposureTime, &propval2, PTP_DTC_UINT32),
7770 			   "failed to set exposuretime to bulb");
7771 		/* If there is no capturetarget set yet, the default is "sdram" */
7772 		if (GP_OK != gp_setting_get("ptp2","capturetarget",buf))
7773 			strcpy (buf, "sdram");
7774 
7775 		C_PTP_MSG (ptp_nikon_capture2 (params, 0/*No AF*/, !strcmp(buf,"sdram")),
7776 			   "failed to initiate bulb capture");
7777 		return GP_OK;
7778 	} else {
7779 		C_PTP (ptp_nikon_terminatecapture (params, 0, 0));
7780 		C_PTP (nikon_wait_busy(params, 100, 5000));
7781 		return GP_OK;
7782 	}
7783 }
7784 
7785 
7786 static int
_get_OpenCapture(CONFIG_GET_ARGS)7787 _get_OpenCapture(CONFIG_GET_ARGS) {
7788 	int val;
7789 
7790 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7791 	gp_widget_set_name (*widget,menu->name);
7792 	val = 2; /* always changed */
7793 	gp_widget_set_value  (*widget, &val);
7794 	return GP_OK;
7795 }
7796 
7797 static int
_put_OpenCapture(CONFIG_PUT_ARGS)7798 _put_OpenCapture(CONFIG_PUT_ARGS)
7799 {
7800 	PTPParams *params = &(camera->pl->params);
7801 	int val;
7802 	GPContext *context = ((PTPData *) params->data)->context;
7803 
7804 	CR (gp_widget_get_value(widget, &val));
7805 	if (val) {
7806 		C_PTP_REP (ptp_initiateopencapture (params, 0x0, 0x0)); /* so far use only defaults for storage and ofc */
7807 		params->opencapture_transid = params->transaction_id-1; /* transid will be incremented already */
7808 	} else {
7809 		C_PTP_REP (ptp_terminateopencapture (params, params->opencapture_transid));
7810 	}
7811 	return GP_OK;
7812 }
7813 
7814 static int
_get_Sony_Autofocus(CONFIG_GET_ARGS)7815 _get_Sony_Autofocus(CONFIG_GET_ARGS) {
7816 	int val;
7817 
7818 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7819 	gp_widget_set_name (*widget,menu->name);
7820 	val = 2; /* always changed */
7821 	gp_widget_set_value  (*widget, &val);
7822 	return (GP_OK);
7823 }
7824 
7825 static int
_put_Sony_Autofocus(CONFIG_PUT_ARGS)7826 _put_Sony_Autofocus(CONFIG_PUT_ARGS)
7827 {
7828 	PTPParams *params = &(camera->pl->params);
7829 	int val;
7830 	PTPPropertyValue xpropval;
7831 
7832 	CR (gp_widget_get_value(widget, &val));
7833 	xpropval.u16 = val ? 2 : 1;
7834 
7835 	C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_AutoFocus, &xpropval, PTP_DTC_UINT16));
7836 
7837 	return GP_OK;
7838 }
7839 
7840 static int
_get_Sony_ManualFocus(CONFIG_GET_ARGS)7841 _get_Sony_ManualFocus(CONFIG_GET_ARGS) {
7842 	int val;
7843 
7844 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
7845 	gp_widget_set_range(*widget, -7.0, 7.0, 1.0);
7846 	gp_widget_set_name (*widget,menu->name);
7847 	val = 0.0; /* always changed */
7848 	gp_widget_set_value  (*widget, &val);
7849 	return (GP_OK);
7850 }
7851 
7852 static int
_put_Sony_ManualFocus(CONFIG_PUT_ARGS)7853 _put_Sony_ManualFocus(CONFIG_PUT_ARGS)
7854 {
7855 	PTPParams *params = &(camera->pl->params);
7856 	float val;
7857 	PTPPropertyValue xpropval;
7858 
7859 	CR (gp_widget_get_value(widget, &val));
7860 
7861 	if(val != 0.0) {
7862 		/* value 2 seems to set it to autofocusmode. see issue https://github.com/gphoto/libgphoto2/issues/434
7863 		xpropval.u16 = 2;
7864 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, 0xd2d2, &xpropval, PTP_DTC_UINT16));
7865 		*/
7866 		if(val <= -7) xpropval.u16 = 0xFFFF - 6;
7867 		else if(val <= -6.0) xpropval.u16 = 0xFFFF - 5;
7868 		else if(val <= -5.0) xpropval.u16 = 0xFFFF - 4;
7869 		else if(val <= -4.0) xpropval.u16 = 0xFFFF - 3;
7870 		else if(val <= -3.0) xpropval.u16 = 0xFFFF - 2;
7871 		else if(val <= -2.0) xpropval.u16 = 0xFFFF - 1;
7872 		else if(val <= -1.0) xpropval.u16 = 0xFFFF;
7873 		else if(val <= 1.0) xpropval.u16 = 1;
7874 		else if(val <= 2.0) xpropval.u16 = 2;
7875 		else if(val <= 3.0) xpropval.u16 = 3;
7876 		else if(val <= 4.0) xpropval.u16 = 4;
7877 		else if(val <= 5.0) xpropval.u16 = 5;
7878 		else if(val <= 6.0) xpropval.u16 = 6;
7879 		else if(val <= 7.0) xpropval.u16 = 7;
7880 		else xpropval.u16 = 0;
7881 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_NearFar, &xpropval, PTP_DTC_UINT16));
7882 	} else {
7883 		xpropval.u16 = 1;
7884 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, 0xd2d2, &xpropval, PTP_DTC_UINT16));
7885 	}
7886 
7887 	return GP_OK;
7888 }
7889 
7890 static int
_get_Sony_Capture(CONFIG_GET_ARGS)7891 _get_Sony_Capture(CONFIG_GET_ARGS) {
7892 	int val;
7893 
7894 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7895 	gp_widget_set_name (*widget,menu->name);
7896 	val = 2; /* always changed */
7897 	gp_widget_set_value  (*widget, &val);
7898 	return GP_OK;
7899 }
7900 
7901 static int
_put_Sony_Capture(CONFIG_PUT_ARGS)7902 _put_Sony_Capture(CONFIG_PUT_ARGS)
7903 {
7904 	PTPParams *params = &(camera->pl->params);
7905 	int val;
7906 	PTPPropertyValue xpropval;
7907 
7908 	CR (gp_widget_get_value(widget, &val));
7909 	xpropval.u16 = val ? 2 : 1;
7910 
7911 	C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_Capture, &xpropval, PTP_DTC_UINT16));
7912 
7913 	return GP_OK;
7914 }
7915 
7916 static int
_get_Sony_Bulb(CONFIG_GET_ARGS)7917 _get_Sony_Bulb(CONFIG_GET_ARGS) {
7918 	int val;
7919 
7920 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
7921 	gp_widget_set_name (*widget,menu->name);
7922 	val = 2; /* always changed */
7923 	gp_widget_set_value  (*widget, &val);
7924 	return (GP_OK);
7925 }
7926 
7927 static int
_put_Sony_Bulb(CONFIG_PUT_ARGS)7928 _put_Sony_Bulb(CONFIG_PUT_ARGS)
7929 {
7930 	PTPParams *params = &(camera->pl->params);
7931 	int val;
7932 	PTPPropertyValue xpropval;
7933 
7934 	CR (gp_widget_get_value(widget, &val));
7935 	if (val) {
7936 		xpropval.u16 = 1;
7937 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_AutoFocus, &xpropval, PTP_DTC_UINT16));
7938 
7939 		xpropval.u16 = 2;
7940 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_StillImage, &xpropval, PTP_DTC_UINT16));
7941 	} else {
7942 		xpropval.u16 = 1;
7943 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_Capture, &xpropval, PTP_DTC_UINT16));
7944 
7945 		xpropval.u16 = 1;
7946 		C_PTP (ptp_sony_setdevicecontrolvalueb (params, PTP_DPC_SONY_AutoFocus, &xpropval, PTP_DTC_UINT16));
7947 	}
7948 	return GP_OK;
7949 }
7950 
7951 static int
_put_Panasonic_Shutter(CONFIG_PUT_ARGS)7952 _put_Panasonic_Shutter(CONFIG_PUT_ARGS)
7953 {
7954 	PTPParams *params = &(camera->pl->params);
7955 	char *xval;
7956 	uint32_t val;
7957 	float f;
7958 
7959 	CR (gp_widget_get_value(widget, &xval));
7960 	if(xval[0] == 'b' || xval[0] == 'B') {
7961 		val = 0xFFFFFFFF;
7962 	} else if(xval[1] == '/') {
7963 		sscanf (xval, "1/%f", &f);
7964 		f *= 1000;
7965 		val = (uint32_t) f;
7966 	} else {
7967 		sscanf (xval, "%f", &f);
7968 		f *= 1000;
7969 		val = (uint32_t) f;
7970 		val |= 0x80000000;
7971 	}
7972 
7973 	//printf("setting shutterspeed to %lu (%s)\n", val, xval);
7974 
7975 	return translate_ptp_result (ptp_panasonic_setdeviceproperty(params, 0x2000031, (unsigned char*)&val, 4));
7976 }
7977 
7978 static int
_get_Panasonic_Shutter(CONFIG_GET_ARGS)7979 _get_Panasonic_Shutter(CONFIG_GET_ARGS) {
7980 	uint32_t currentVal;
7981 	uint32_t listCount;
7982 	uint32_t *list;
7983 	PTPParams *params = &(camera->pl->params);
7984 	GPContext *context = ((PTPData *) params->data)->context;
7985 
7986 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, 0x2000030, 4, &currentVal, &list, &listCount));
7987 
7988 	//printf("retrieved %lu property values\n", listCount);
7989 
7990 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
7991 	gp_widget_set_name (*widget, menu->name);
7992 
7993 	uint32_t i;
7994 	float f;
7995 	char buf[16];
7996 	for (i = 0; i < listCount; i++) {
7997 		if(currentVal == 0xFFFFFFFF) {
7998 			sprintf (buf, "bulb");
7999 		} else if(list[i] & 0x80000000) {
8000 			list[i] &= ~0x80000000;
8001 			f = (float) list[i];
8002 			f /= 1000;
8003 			if(list[i] % 1000 == 0) {
8004 				sprintf (buf, "%.0f", f);
8005 			} else {
8006 				sprintf (buf, "%.1f", f);
8007 			}
8008 		} else {
8009 			f = (float) list[i];
8010 			f /= 1000;
8011 			if(list[i] % 1000 == 0) {
8012 				sprintf (buf, "1/%.0f", f);
8013 			} else {
8014 				sprintf (buf, "1/%.1f", f);
8015 			}
8016 		}
8017 		gp_widget_add_choice (*widget, buf);
8018 	}
8019 
8020 	if(currentVal == 0) {
8021 		uint16_t valuesize;
8022 		ptp_panasonic_getdeviceproperty(params, 0x2000030, &valuesize, &currentVal);
8023 	}
8024 
8025 	if(currentVal == 0xFFFFFFFF) {
8026 		sprintf (buf, "bulb");
8027 	} else if(currentVal & 0x80000000) {
8028 		currentVal &= ~0x80000000;
8029 		f = (float) currentVal;
8030 		f /= 1000;
8031 		if(currentVal % 1000 == 0) {
8032 			sprintf (buf, "%.0f", f);
8033 		} else {
8034 			sprintf (buf, "%.1f", f);
8035 		}
8036 	} else {
8037 		f = (float) currentVal;
8038 		f /= 1000;
8039 		if(currentVal % 1000 == 0) {
8040 			sprintf (buf, "1/%.0f", f);
8041 		} else {
8042 			sprintf (buf, "1/%.1f", f);
8043 		}
8044 	}
8045 
8046 	gp_widget_set_value (*widget, &buf);
8047 
8048 	free(list);
8049 
8050 	return GP_OK;
8051 }
8052 
8053 static int
_put_Panasonic_ISO(CONFIG_PUT_ARGS)8054 _put_Panasonic_ISO(CONFIG_PUT_ARGS)
8055 {
8056 	PTPParams *params = &(camera->pl->params);
8057 	char *xval;
8058 	unsigned int ival;
8059 	uint32_t val;
8060 
8061 	CR (gp_widget_get_value(widget, &xval));
8062 	sscanf (xval, "%d", &ival);
8063 	val = ival;
8064 
8065 	//printf("setting ISO to %lu (%s)\n", val, xval);
8066 
8067 	return translate_ptp_result (ptp_panasonic_setdeviceproperty(params, 0x2000021, (unsigned char*)&val, 4));
8068 }
8069 
8070 static int
_get_Panasonic_ISO(CONFIG_GET_ARGS)8071 _get_Panasonic_ISO(CONFIG_GET_ARGS) {
8072 	uint32_t currentVal;
8073 	uint32_t listCount;
8074 	uint32_t *list;
8075 	uint16_t valsize;
8076 	PTPParams *params = &(camera->pl->params);
8077 	GPContext *context = ((PTPData *) params->data)->context;
8078 
8079 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, 0x2000020, 4, &currentVal, &list, &listCount));
8080 
8081 	//printf("retrieved %lu property values\n", listCount);
8082 
8083 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8084 	gp_widget_set_name (*widget, menu->name);
8085 
8086 	uint32_t i;
8087 	char buf[16];
8088 	for (i = 0; i < listCount; i++) {
8089 		sprintf (buf, "%d", (unsigned int)list[i]);
8090 		gp_widget_add_choice (*widget, buf);
8091 	}
8092 	ptp_panasonic_getdeviceproperty(params, 0x2000021, &valsize, &currentVal);
8093 
8094 	sprintf (buf, "%d", (unsigned int)currentVal);
8095 	gp_widget_set_value (*widget, buf);
8096 
8097 	free(list);
8098 
8099 	return GP_OK;
8100 }
8101 
8102 static
8103 struct {
8104 	char*	str;
8105 	uint16_t val;
8106 } panasonic_wbtable[] = {
8107 	{ N_("Automatic"),	0x0002	},
8108 	{ N_("Daylight"),	0x0004	},
8109 	{ N_("Cloudy"),		32776	},
8110 	{ N_("Tungsten"),	0x0006	},
8111 	{ N_("Flash"),		0x0007	},
8112 	{ N_("Preset 1"),	32779	},
8113 	{ N_("Preset 2"),	32780	},
8114 	{ N_("Preset 3"),	32781	},
8115 	{ N_("Preset 4"),	32782	},
8116 	{ N_("Shadow"),		32783	},
8117 	{ N_("Temperature 1"),	32784	},
8118 	{ N_("Temperature 2"),	32785	},
8119 	{ N_("Temperature 3"),	32786	},
8120 	{ N_("Temperature 4"),	32787	},
8121 	{ N_("Automatic C"), 	32788	},
8122 };
8123 
8124 static int
_put_Panasonic_Whitebalance(CONFIG_PUT_ARGS)8125 _put_Panasonic_Whitebalance(CONFIG_PUT_ARGS)
8126 {
8127 	PTPParams *params = &(camera->pl->params);
8128 	GPContext *context = ((PTPData *) params->data)->context;
8129 	char *xval;
8130 	uint32_t val = 0;
8131 	uint32_t currentVal;
8132 	uint32_t listCount;
8133 	uint32_t *list;
8134 	int ival;
8135 	unsigned int i;
8136 
8137 	CR (gp_widget_get_value(widget, &xval));
8138 
8139 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, PTP_DPC_PANASONIC_WhiteBalance, 2, &currentVal, &list, &listCount));
8140 
8141 	if (sscanf(xval,_("Unknown 0x%04x"), &ival))
8142 		val = ival;
8143 
8144 	for (i = 0; i < listCount; i++) {
8145 		unsigned int j;
8146 
8147 		for (j=0;j<sizeof(panasonic_wbtable)/sizeof(panasonic_wbtable[0]);j++) {
8148 			if (!strcmp(xval,_(panasonic_wbtable[j].str))) {
8149 				val = panasonic_wbtable[j].val;
8150 				break;
8151 			}
8152 		}
8153 	}
8154 	free(list);
8155 	GP_LOG_D("setting whitebalance to 0x%04x", val);
8156 	return translate_ptp_result (ptp_panasonic_setdeviceproperty(params, PTP_DPC_PANASONIC_WhiteBalance, (unsigned char*)&val, 2));
8157 }
8158 
8159 static int
_get_Panasonic_Whitebalance(CONFIG_GET_ARGS)8160 _get_Panasonic_Whitebalance(CONFIG_GET_ARGS) {
8161 	uint32_t currentVal;
8162 	uint32_t listCount;
8163 	uint32_t *list;
8164 	uint32_t i,j;
8165 	int	valset = 0;
8166 	char	buf[32];
8167 	PTPParams *params = &(camera->pl->params);
8168 	GPContext *context = ((PTPData *) params->data)->context;
8169 
8170 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, PTP_DPC_PANASONIC_WhiteBalance, 2, &currentVal, &list, &listCount));
8171 
8172 	//printf("retrieved %lu property values\n", listCount);
8173 
8174 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8175 	gp_widget_set_name (*widget, menu->name);
8176 
8177 	for (i = 0; i < listCount; i++) {
8178 		sprintf(buf,_("Unknown 0x%04x"), list[i]);
8179 		for (j=0;j<sizeof(panasonic_wbtable)/sizeof(panasonic_wbtable[0]);j++) {
8180 			if (panasonic_wbtable[j].val == list[i]) {
8181 				strcpy(buf,_(panasonic_wbtable[j].str));
8182 				break;
8183 			}
8184 		}
8185 		if (list[i] == currentVal) {
8186 			gp_widget_set_value (*widget, buf);
8187 			valset = 1;
8188 		}
8189 
8190 		gp_widget_add_choice (*widget, buf);
8191 	}
8192 	free(list);
8193 	if (!valset) {
8194 		sprintf(buf,_("Unknown 0x%04x"), currentVal);
8195 		gp_widget_set_value (*widget, buf);
8196 	}
8197 	return GP_OK;
8198 }
8199 static int
_put_Panasonic_Exposure(CONFIG_PUT_ARGS)8200 _put_Panasonic_Exposure(CONFIG_PUT_ARGS)
8201 {
8202 	PTPParams *params = &(camera->pl->params);
8203 	char *xval;
8204 	uint32_t val;
8205 	float f;
8206 
8207 	CR (gp_widget_get_value(widget, &xval));
8208 
8209 	sscanf (xval, "%f", &f);
8210 
8211 	if (f < 0)
8212 		val = (uint32_t)(0x8000 | (int)(((-f)*3)));
8213 	else
8214 		val = (uint32_t) (f*3);
8215 	return translate_ptp_result (ptp_panasonic_setdeviceproperty(params, PTP_DPC_PANASONIC_Exposure, (unsigned char*)&val, 2));
8216 }
8217 
8218 static int
_get_Panasonic_Exposure(CONFIG_GET_ARGS)8219 _get_Panasonic_Exposure(CONFIG_GET_ARGS) {
8220 	uint32_t currentVal;
8221 	uint32_t listCount;
8222 	uint32_t *list;
8223 	uint32_t i;
8224 	char	buf[16];
8225 	PTPParams *params = &(camera->pl->params);
8226 	GPContext *context = ((PTPData *) params->data)->context;
8227 
8228 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, PTP_DPC_PANASONIC_Exposure, 2, &currentVal, &list, &listCount));
8229 
8230 	//printf("retrieved %lu property values\n", listCount);
8231 
8232 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8233 	gp_widget_set_name (*widget, menu->name);
8234 
8235 	for (i = 0; i < listCount; i++) {
8236 		int val = (int)list[i];
8237 
8238 		if (val & 0x8000)
8239 			val = -(val & 0x7fff);
8240 		sprintf (buf, "%f", val/3.0);
8241 		gp_widget_add_choice (*widget, buf);
8242 	}
8243 	free(list);
8244 
8245 	sprintf (buf, "%f", (float)currentVal);
8246 	gp_widget_set_value (*widget, &buf);
8247 	return GP_OK;
8248 }
8249 
8250 static int
_put_Panasonic_FNumber(CONFIG_PUT_ARGS)8251 _put_Panasonic_FNumber(CONFIG_PUT_ARGS)
8252 {
8253 	PTPParams *params = &(camera->pl->params);
8254 	char *xval;
8255 	uint32_t val;
8256 
8257 	CR (gp_widget_get_value(widget, &xval));
8258 	float f;
8259 	sscanf (xval, "%f", &f);
8260 	val = (uint32_t) (f*10);
8261 
8262 	//printf("setting ISO to %lu (%s)\n", val, xval);
8263 
8264 	return translate_ptp_result (ptp_panasonic_setdeviceproperty(params, 0x2000041, (unsigned char*)&val, 2));
8265 }
8266 
8267 static int
_get_Panasonic_FNumber(CONFIG_GET_ARGS)8268 _get_Panasonic_FNumber(CONFIG_GET_ARGS) {
8269 	uint32_t currentVal;
8270 	uint32_t listCount;
8271 	uint16_t valsize;
8272 	uint32_t *list;
8273 	PTPParams *params = &(camera->pl->params);
8274 	GPContext *context = ((PTPData *) params->data)->context;
8275 
8276 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, 0x2000040, 2, &currentVal, &list, &listCount));
8277 
8278 	//printf("retrieved %lu property values\n", listCount);
8279 
8280 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8281 	gp_widget_set_name (*widget, menu->name);
8282 
8283 	uint32_t i;
8284 	float f;
8285 	char buf[16];
8286 	for (i = 0; i < listCount; i++) {
8287 		f = (float) list[i];
8288 		f /= 10.0;
8289 		if(list[i] % 10 == 0) {
8290 			sprintf (buf, "%.0f", f);
8291 		} else {
8292 			sprintf (buf, "%.1f", f);
8293 		}
8294 		gp_widget_add_choice (*widget, buf);
8295 	}
8296 	ptp_panasonic_getdeviceproperty(params, 0x2000041, &valsize, &currentVal);
8297 
8298 	f = (float) currentVal;
8299 	f /= 10.0;
8300 	if(currentVal % 10 == 0) {
8301 		sprintf (buf, "%.0f", f);
8302 	} else {
8303 		sprintf (buf, "%.1f", f);
8304 	}
8305 
8306 	gp_widget_set_value (*widget, &buf);
8307 
8308 	free(list);
8309 
8310 	return GP_OK;
8311 }
8312 
8313 static int
_put_Panasonic_ImageFormat(CONFIG_PUT_ARGS)8314 _put_Panasonic_ImageFormat(CONFIG_PUT_ARGS)
8315 {
8316 	PTPParams *params = &(camera->pl->params);
8317 	char *xval;
8318 	uint32_t val;
8319 	unsigned int uval;
8320 
8321 	CR (gp_widget_get_value(widget, &xval));
8322 
8323 	sscanf (xval, "%u", &uval);
8324 	val = uval;
8325 	//printf("setting ImageFormat to %lu (%s)\n", val, xval);
8326 
8327 	return translate_ptp_result (ptp_panasonic_setdeviceproperty(params, 0x20000A2, (unsigned char*)&val, 2));
8328 }
8329 
8330 static int
_get_Panasonic_ImageFormat(CONFIG_GET_ARGS)8331 _get_Panasonic_ImageFormat(CONFIG_GET_ARGS) {
8332 	uint32_t currentVal;
8333 	uint32_t listCount;
8334 	uint32_t *list;
8335 	PTPParams *params = &(camera->pl->params);
8336 	GPContext *context = ((PTPData *) params->data)->context;
8337 
8338 	C_PTP_REP (ptp_panasonic_getdevicepropertydesc(params, 0x20000A2, 2, &currentVal, &list, &listCount));
8339 
8340 	//printf("retrieved %lu property values\n", listCount);
8341 
8342 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8343 	gp_widget_set_name (*widget, menu->name);
8344 
8345 	uint32_t i;
8346 	char buf[16];
8347 	for (i = 0; i < listCount; i++) {
8348 		sprintf (buf, "%u", (unsigned int)list[i]);
8349 		gp_widget_add_choice (*widget, buf);
8350 	}
8351 
8352 	sprintf (buf, "%u", (unsigned int)currentVal);
8353 	gp_widget_set_value (*widget, buf);
8354 
8355 	free(list);
8356 
8357 	return GP_OK;
8358 }
8359 
8360 static int
_get_Canon_EOS_Bulb(CONFIG_GET_ARGS)8361 _get_Canon_EOS_Bulb(CONFIG_GET_ARGS) {
8362 	int val;
8363 
8364 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
8365 	gp_widget_set_name (*widget,menu->name);
8366 	val = 2; /* always changed */
8367 	gp_widget_set_value  (*widget, &val);
8368 	return (GP_OK);
8369 }
8370 
8371 static int
_put_Canon_EOS_Bulb(CONFIG_PUT_ARGS)8372 _put_Canon_EOS_Bulb(CONFIG_PUT_ARGS)
8373 {
8374 	PTPParams *params = &(camera->pl->params);
8375 	int val;
8376 	GPContext *context = ((PTPData *) params->data)->context;
8377 
8378 	CR (gp_widget_get_value(widget, &val));
8379 	if (val) {
8380 		int ret = ptp_canon_eos_bulbstart (params);
8381 		if (ret == PTP_RC_GeneralError) {
8382 			gp_context_error (((PTPData *) camera->pl->params.data)->context,
8383 			_("For bulb capture to work, make sure the mode dial is switched to 'M' and set 'shutterspeed' to 'bulb'."));
8384 			return translate_ptp_result (ret);
8385 		}
8386 		C_PTP_REP (ret);
8387 	} else {
8388 		C_PTP_REP (ptp_canon_eos_bulbend (params));
8389 	}
8390 	return GP_OK;
8391 }
8392 
8393 static int
_get_Canon_EOS_UILock(CONFIG_GET_ARGS)8394 _get_Canon_EOS_UILock(CONFIG_GET_ARGS) {
8395 	int val;
8396 
8397 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
8398 	gp_widget_set_name (*widget,menu->name);
8399 	val = 2; /* always changed */
8400 	gp_widget_set_value  (*widget, &val);
8401 	return (GP_OK);
8402 }
8403 
8404 static int
_put_Canon_EOS_UILock(CONFIG_PUT_ARGS)8405 _put_Canon_EOS_UILock(CONFIG_PUT_ARGS)
8406 {
8407 	PTPParams *params = &(camera->pl->params);
8408 	int val;
8409 	GPContext *context = ((PTPData *) params->data)->context;
8410 
8411 	CR (gp_widget_get_value(widget, &val));
8412 	if (val)
8413 		C_PTP_REP (ptp_canon_eos_setuilock (params));
8414 	else
8415 		C_PTP_REP (ptp_canon_eos_resetuilock (params));
8416 	return GP_OK;
8417 }
8418 
8419 static int
_get_Canon_EOS_PopupFlash(CONFIG_GET_ARGS)8420 _get_Canon_EOS_PopupFlash(CONFIG_GET_ARGS) {
8421 	int val;
8422 
8423 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
8424 	gp_widget_set_name (*widget,menu->name);
8425 	val = 2; /* always changed */
8426 	gp_widget_set_value  (*widget, &val);
8427 	return GP_OK;
8428 }
8429 
8430 static int
_put_Canon_EOS_PopupFlash(CONFIG_PUT_ARGS)8431 _put_Canon_EOS_PopupFlash(CONFIG_PUT_ARGS)
8432 {
8433 	PTPParams *params = &(camera->pl->params);
8434 	GPContext *context = ((PTPData *) params->data)->context;
8435 
8436 	C_PTP_REP (ptp_canon_eos_popupflash (params));
8437 	return GP_OK;
8438 }
8439 
8440 static int
_get_Nikon_FastFS(CONFIG_GET_ARGS)8441 _get_Nikon_FastFS(CONFIG_GET_ARGS) {
8442 	int val;
8443 	char buf[1024];
8444 
8445 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
8446 	gp_widget_set_name (*widget, menu->name);
8447 	val = 1; /* default is fast fs */
8448 	if (GP_OK == gp_setting_get("ptp2","nikon.fastfilesystem", buf))
8449 		val = atoi(buf);
8450 	gp_widget_set_value  (*widget, &val);
8451 	return (GP_OK);
8452 }
8453 
8454 static int
_put_Nikon_FastFS(CONFIG_PUT_ARGS)8455 _put_Nikon_FastFS(CONFIG_PUT_ARGS) {
8456 	int val;
8457 	char buf[20];
8458 
8459 	CR (gp_widget_get_value(widget, &val));
8460 	sprintf(buf,"%d",val);
8461 	gp_setting_set("ptp2","nikon.fastfilesystem",buf);
8462 	return GP_OK;
8463 }
8464 
8465 static int
_get_Nikon_Thumbsize(CONFIG_GET_ARGS)8466 _get_Nikon_Thumbsize(CONFIG_GET_ARGS) {
8467 	char buf[1024];
8468 
8469 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8470 	gp_widget_add_choice (*widget, _("normal"));
8471 	gp_widget_add_choice (*widget, _("large"));
8472 	gp_widget_set_name (*widget, menu->name);
8473 	strcpy(buf,"normal");
8474 	gp_setting_get("ptp2","thumbsize", buf);
8475 	gp_widget_set_value  (*widget, N_(buf));
8476 	return GP_OK;
8477 }
8478 
8479 static int
_put_Nikon_Thumbsize(CONFIG_PUT_ARGS)8480 _put_Nikon_Thumbsize(CONFIG_PUT_ARGS) {
8481 	char *buf;
8482 	PTPParams	*params = &(camera->pl->params);
8483 	GPContext	*context = ((PTPData *) params->data)->context;
8484 
8485 	CR (gp_widget_get_value  (widget, &buf));
8486 	if (!strcmp(buf,_("normal"))) {
8487 		gp_setting_set("ptp2","thumbsize","normal");
8488 		return GP_OK;
8489 	}
8490 	if (!strcmp(buf,_("large"))) {
8491 		gp_setting_set("ptp2","thumbsize","large");
8492 		return GP_OK;
8493 	}
8494 	gp_context_error (context, _("Unknown thumb size value '%s'."), buf);
8495 	return GP_ERROR;
8496 }
8497 
8498 static struct {
8499 	char	*name;
8500 	char	*label;
8501 } capturetargets[] = {
8502 	{"sdram", N_("Internal RAM") },
8503 	{"card", N_("Memory card") },
8504 };
8505 
8506 static int
_get_CaptureTarget(CONFIG_GET_ARGS)8507 _get_CaptureTarget(CONFIG_GET_ARGS) {
8508 	unsigned int i;
8509 	char buf[1024];
8510 
8511 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8512 	gp_widget_set_name (*widget, menu->name);
8513 	if (GP_OK != gp_setting_get("ptp2","capturetarget", buf))
8514 		strcpy(buf,"sdram");
8515 
8516 	for (i=0;i<sizeof (capturetargets)/sizeof (capturetargets[i]);i++) {
8517 		gp_widget_add_choice (*widget, _(capturetargets[i].label));
8518 		if (!strcmp (buf,capturetargets[i].name))
8519 			gp_widget_set_value (*widget, _(capturetargets[i].label));
8520 	}
8521 	return GP_OK;
8522 }
8523 
8524 static int
_put_CaptureTarget(CONFIG_PUT_ARGS)8525 _put_CaptureTarget(CONFIG_PUT_ARGS) {
8526 	unsigned int	i;
8527 	char		*val;
8528 	PTPParams	*params = &(camera->pl->params);
8529 	GPContext	*context = ((PTPData *) params->data)->context;
8530 	char		buf[1024];
8531 
8532 	CR (gp_widget_get_value(widget, &val));
8533 	for (i=0;i<sizeof(capturetargets)/sizeof(capturetargets[i]);i++) {
8534 		if (!strcmp( val, _(capturetargets[i].label))) {
8535 			gp_setting_set("ptp2","capturetarget",capturetargets[i].name);
8536 			break;
8537 		}
8538 	}
8539 	/* Also update it in the live Canon EOS camera. (Nikon and Canon Powershot just use different opcodes.) */
8540 	if (	(params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
8541 		(ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteRelease) ||
8542 		 ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn)
8543 		)
8544 	)
8545 		CR (camera_canon_eos_update_capture_target( camera, context, -1 ));
8546 
8547 	if (params->deviceinfo.VendorExtensionID == PTP_VENDOR_PANASONIC) {
8548 		if ((GP_OK != gp_setting_get("ptp2","capturetarget",buf)) || !strcmp(buf,"sdram"))
8549 			C_PTP (ptp_panasonic_setcapturetarget(params, 1));
8550 		else
8551 			C_PTP (ptp_panasonic_setcapturetarget(params, 0));
8552 	}
8553 	return GP_OK;
8554 }
8555 
8556 static struct deviceproptableu16 sony_capturetarget[] = {
8557 	{ "sdram",		0x0001, 0 },
8558 	{ "card",		0x0010, 0 },
8559 	{ "card+sdram",		0x0011, 0 },
8560 };
8561 GENERIC16TABLE(Sony_CaptureTarget,sony_capturetarget)
8562 
8563 static struct deviceproptableu32 audio_format[] = {
8564 	{ "PCM",		0x0001, 0 },
8565 	{ "ADPCM",		0x0002, 0 },
8566 	{ "IEEE float",		0x0003, 0 },
8567 	{ "VSELP",		0x0004, 0 },
8568 	{ "IBM CVSD",		0x0005, 0 },
8569 	{ "a-Law",		0x0006, 0 },
8570 	{ "u-Law",		0x0007, 0 },
8571 	{ "DTS",		0x0008, 0 },
8572 	{ "DRM",		0x0009, 0 },
8573 	{ "OKI-ADPCM",		0x0010, 0 },
8574 	{ "IMA-ADPCM",		0x0011, 0 },
8575 	{ "Mediaspace ADPCM",	0x0012, 0 },
8576 	{ "Sierra ADPCM",	0x0013, 0 },
8577 	{ "G723 ADPCM",		0x0014, 0 },
8578 	{ "DIGISTD",		0x0015, 0 },
8579 	{ "DIGIFIX",		0x0016, 0 },
8580 	{ "Dolby AC2",		0x0030, 0 },
8581 	{ "GSM 610",		0x0031, 0 },
8582 	{ "Rockwell ADPCM",	0x003b, 0 },
8583 	{ "Rockwell DIGITALK",	0x003c, 0 },
8584 	{ "G721 ADPCM",		0x0040, 0 },
8585 	{ "G728 CELP",		0x0041, 0 },
8586 	{ "MPEG",		0x0050, 0 },
8587 	{ "RT24",		0x0052, 0 },
8588 	{ "PAC",		0x0053, 0 },
8589 	{ "MP3",		0x0055, 0 },
8590 	{ "G726 ADPCM",		0x0064, 0 },
8591 	{ "G722 ADPCM",		0x0065, 0 },
8592 	{ "IBM u-Law",		0x0101, 0 },
8593 	{ "IBM a-Law",		0x0102, 0 },
8594 	{ "IBM ADPCM",		0x0103, 0 },
8595 	{ "Ogg Vorbis 1",	0x674f, 0 },
8596 	{ "Ogg Vorbis 1 PLUS",	0x676f, 0 },
8597 	{ "Ogg Vorbis 2",	0x6750, 0 },
8598 	{ "Ogg Vorbis 2 PLUS",	0x6770, 0 },
8599 	{ "Ogg Vorbis 3",	0x6751, 0 },
8600 	{ "Ogg Vorbis 3 PLUS",	0x6771, 0 },
8601 	{ "Ogg Vorbis 3 PLUS",	0x6771, 0 },
8602 	/* Development 0xffff */
8603 	/* Reserved 0xffff...  */
8604 };
8605 GENERIC32TABLE(Audio_Format,audio_format)
8606 
8607 static struct {
8608 	char	*name;
8609 	char	*label;
8610 } chdkonoff[] = {
8611 	{"on", N_("On") },
8612 	{"off", N_("Off") },
8613 };
8614 
8615 static int
_get_CHDK(CONFIG_GET_ARGS)8616 _get_CHDK(CONFIG_GET_ARGS) {
8617 	unsigned int i;
8618 	char buf[1024];
8619 
8620 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8621 	gp_widget_set_name (*widget, menu->name);
8622 	if (GP_OK != gp_setting_get("ptp2","chdk", buf))
8623 		strcpy(buf,"off");
8624 	for (i=0;i<sizeof (chdkonoff)/sizeof (chdkonoff[i]);i++) {
8625 		gp_widget_add_choice (*widget, _(chdkonoff[i].label));
8626 		if (!strcmp (buf,chdkonoff[i].name))
8627 			gp_widget_set_value (*widget, _(chdkonoff[i].label));
8628 	}
8629 	return GP_OK;
8630 }
8631 
8632 static int
_put_CHDK(CONFIG_PUT_ARGS)8633 _put_CHDK(CONFIG_PUT_ARGS) {
8634 	unsigned int i;
8635 	char *val;
8636 
8637 	CR (gp_widget_get_value(widget, &val));
8638 	for (i=0;i<sizeof(chdkonoff)/sizeof(chdkonoff[i]);i++) {
8639 		if (!strcmp( val, _(chdkonoff[i].label))) {
8640 			gp_setting_set("ptp2","chdk",chdkonoff[i].name);
8641 			break;
8642 		}
8643 	}
8644 	return GP_OK;
8645 }
8646 
8647 static struct {
8648 	char	*name;
8649 	char	*label;
8650 } afonoff[] = {
8651 	{"on", N_("On") },
8652 	{"off", N_("Off") },
8653 };
8654 
8655 static int
_get_Autofocus(CONFIG_GET_ARGS)8656 _get_Autofocus(CONFIG_GET_ARGS) {
8657 	unsigned int i;
8658 	char buf[1024];
8659 
8660 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8661 	gp_widget_set_name (*widget, menu->name);
8662 	if (GP_OK != gp_setting_get("ptp2","autofocus", buf))
8663 		strcpy(buf,"on");
8664 	for (i=0;i<sizeof (afonoff)/sizeof (afonoff[i]);i++) {
8665 		gp_widget_add_choice (*widget, _(afonoff[i].label));
8666 		if (!strcmp (buf,afonoff[i].name))
8667 			gp_widget_set_value (*widget, _(afonoff[i].label));
8668 	}
8669 	return GP_OK;
8670 }
8671 
8672 static int
_put_Autofocus(CONFIG_PUT_ARGS)8673 _put_Autofocus(CONFIG_PUT_ARGS) {
8674 	unsigned int i;
8675 	char *val;
8676 
8677 	CR (gp_widget_get_value(widget, &val));
8678 	for (i=0;i<sizeof(afonoff)/sizeof(afonoff[i]);i++) {
8679 		if (!strcmp( val, _(afonoff[i].label))) {
8680 			gp_setting_set("ptp2","autofocus",afonoff[i].name);
8681 			break;
8682 		}
8683 	}
8684 	return GP_OK;
8685 }
8686 
8687 /* Wifi profiles functions */
8688 
8689 static int
_put_nikon_list_wifi_profiles(CONFIG_PUT_ARGS)8690 _put_nikon_list_wifi_profiles (CONFIG_PUT_ARGS)
8691 {
8692 	int i;
8693 	CameraWidget *child, *child2;
8694 	const char *name;
8695 	int value;
8696 	char* endptr;
8697 	long val;
8698 	PTPParams *params = &(camera->pl->params);
8699 
8700 	if (camera->pl->params.deviceinfo.VendorExtensionID != PTP_VENDOR_NIKON)
8701 		return (GP_ERROR_NOT_SUPPORTED);
8702 
8703 	for (i = 0; i < gp_widget_count_children(widget); i++) {
8704 		gp_widget_get_child(widget, i, &child);
8705 		gp_widget_get_child_by_name(child, "delete", &child2);
8706 
8707 		gp_widget_get_value(child2, &value);
8708 		if (value) {
8709 			gp_widget_get_name(child, &name);
8710 			/* FIXME: far from elegant way to get ID back... */
8711 			val = strtol(name, &endptr, 0);
8712 			if (!*endptr) {
8713 				C_PTP (ptp_nikon_deletewifiprofile(&(camera->pl->params), val));
8714 				gp_widget_set_value(child2, 0);
8715 			}
8716 		}
8717 	}
8718 
8719 	/* FIXME: deleted entry still exists, rebuild tree if deleted = 1 ? */
8720 
8721 	return GP_OK;
8722 }
8723 
8724 static int
_get_nikon_list_wifi_profiles(CONFIG_GET_ARGS)8725 _get_nikon_list_wifi_profiles (CONFIG_GET_ARGS)
8726 {
8727 	CameraWidget *child;
8728 	int ret;
8729 	char buffer[4096];
8730 	int i;
8731 	PTPParams *params = &(camera->pl->params);
8732 
8733 	if (params->deviceinfo.VendorExtensionID != PTP_VENDOR_NIKON)
8734 		return (GP_ERROR_NOT_SUPPORTED);
8735 
8736 	/* check for more codes, on non-wireless nikons getwifiprofilelist might hang */
8737 	if (!ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_GetProfileAllData)	||
8738 	    !ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_SendProfileData)	||
8739 	    !ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_DeleteProfile)		||
8740 	    !ptp_operation_issupported(&camera->pl->params, PTP_OC_NIKON_SetProfileData))
8741 		return (GP_ERROR_NOT_SUPPORTED);
8742 
8743 	ret = ptp_nikon_getwifiprofilelist(params);
8744 	if (ret != PTP_RC_OK)
8745 		return (GP_ERROR_NOT_SUPPORTED);
8746 
8747 	gp_widget_new (GP_WIDGET_SECTION, _(menu->label), widget);
8748 	gp_widget_set_name (*widget, menu->name);
8749 	gp_widget_new (GP_WIDGET_TEXT, "Version", &child);
8750 	snprintf(buffer, 4096, "%d", params->wifi_profiles_version);
8751 	gp_widget_set_value(child, buffer);
8752 	gp_widget_append(*widget, child);
8753 
8754 	for (i = 0; i < params->wifi_profiles_number; i++) {
8755 		CameraWidget *child2;
8756 		if (params->wifi_profiles[i].valid) {
8757 			gp_widget_new (GP_WIDGET_SECTION, params->wifi_profiles[i].profile_name, &child);
8758 			snprintf(buffer, 4096, "%d", params->wifi_profiles[i].id);
8759 			gp_widget_set_name(child, buffer);
8760 			gp_widget_append(*widget, child);
8761 
8762 			gp_widget_new (GP_WIDGET_TEXT, _("ID"), &child2);
8763 			snprintf (buffer, 4096, "%d", params->wifi_profiles[i].id);
8764 			gp_widget_set_value(child2, buffer);
8765 			gp_widget_append(child, child2);
8766 
8767 			gp_widget_new (GP_WIDGET_TEXT, _("ESSID"), &child2);
8768 			snprintf (buffer, 4096, "%s", params->wifi_profiles[i].essid);
8769 			gp_widget_set_value(child2, buffer);
8770 			gp_widget_append(child, child2);
8771 
8772 			gp_widget_new (GP_WIDGET_TEXT, _("Display"), &child2);
8773 			snprintf (buffer, 4096, "Order: %d, Icon: %d, Device type: %d",
8774 			          params->wifi_profiles[i].display_order,
8775 			          params->wifi_profiles[i].icon_type,
8776 			          params->wifi_profiles[i].device_type);
8777 			gp_widget_set_value(child2, buffer);
8778 			gp_widget_append(child, child2);
8779 
8780 			gp_widget_new (GP_WIDGET_TEXT, "Dates", &child2);
8781 			snprintf (buffer, 4096,
8782 				_("Creation date: %s, Last usage date: %s"),
8783 				params->wifi_profiles[i].creation_date,
8784 				params->wifi_profiles[i].lastusage_date);
8785 			gp_widget_set_value(child2, buffer);
8786 			gp_widget_append(child, child2);
8787 
8788 			gp_widget_new (GP_WIDGET_TOGGLE, _("Delete"), &child2);
8789 			gp_widget_set_value(child2, 0);
8790 			gp_widget_set_name(child2, "delete");
8791 			gp_widget_append(child, child2);
8792 		}
8793 	}
8794 
8795 	return GP_OK;
8796 }
8797 
8798 static int
_get_nikon_wifi_profile_prop(CONFIG_GET_ARGS)8799 _get_nikon_wifi_profile_prop(CONFIG_GET_ARGS) {
8800 	char buffer[1024];
8801 
8802 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
8803 	gp_widget_set_name (*widget, menu->name);
8804 	gp_setting_get("ptp2_wifi",menu->name,buffer);
8805 	gp_widget_set_value(*widget,buffer);
8806 	return (GP_OK);
8807 }
8808 
8809 static int
_put_nikon_wifi_profile_prop(CONFIG_PUT_ARGS)8810 _put_nikon_wifi_profile_prop(CONFIG_PUT_ARGS) {
8811 	char *string, *name;
8812 	CR (gp_widget_get_value(widget, &string));
8813 	gp_widget_get_name(widget,(const char**)&name);
8814 	gp_setting_set("ptp2_wifi",name,string);
8815 	return (GP_OK);
8816 }
8817 
8818 static int
_get_nikon_wifi_profile_channel(CONFIG_GET_ARGS)8819 _get_nikon_wifi_profile_channel(CONFIG_GET_ARGS) {
8820 	char buffer[1024];
8821 	float val;
8822 
8823 	gp_widget_new (GP_WIDGET_RANGE, _(menu->label), widget);
8824 	gp_widget_set_name (*widget, menu->name);
8825 	gp_setting_get("ptp2_wifi", menu->name, buffer);
8826 	val = (float)atoi(buffer);
8827 	gp_widget_set_range(*widget, 1.0, 11.0, 1.0);
8828 	if (!val)
8829 		val = 1.0;
8830 	gp_widget_set_value(*widget, &val);
8831 
8832 	return (GP_OK);
8833 }
8834 
8835 static int
_put_nikon_wifi_profile_channel(CONFIG_PUT_ARGS)8836 _put_nikon_wifi_profile_channel(CONFIG_PUT_ARGS) {
8837 	char *name;
8838 	float val;
8839 	char buffer[16];
8840 	CR (gp_widget_get_value(widget, &val));
8841 	gp_widget_get_name(widget,(const char**)&name);
8842 
8843 	snprintf(buffer, 16, "%d", (int)val);
8844 	gp_setting_set("ptp2_wifi",name,buffer);
8845 	return GP_OK;
8846 }
8847 
8848 static char* encryption_values[] = {
8849 N_("None"),
8850 N_("WEP 64-bit"),
8851 N_("WEP 128-bit"),
8852 NULL
8853 };
8854 
8855 static int
_get_nikon_wifi_profile_encryption(CONFIG_GET_ARGS)8856 _get_nikon_wifi_profile_encryption(CONFIG_GET_ARGS) {
8857 	char buffer[1024];
8858 	int i;
8859 	int val;
8860 
8861 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8862 	gp_widget_set_name (*widget, menu->name);
8863 	gp_setting_get("ptp2_wifi", menu->name, buffer);
8864 	val = atoi(buffer);
8865 
8866 	for (i = 0; encryption_values[i]; i++) {
8867 		gp_widget_add_choice(*widget, _(encryption_values[i]));
8868 		if (i == val)
8869 			gp_widget_set_value(*widget, _(encryption_values[i]));
8870 	}
8871 
8872 	return (GP_OK);
8873 }
8874 
8875 static int
_put_nikon_wifi_profile_encryption(CONFIG_PUT_ARGS)8876 _put_nikon_wifi_profile_encryption(CONFIG_PUT_ARGS) {
8877 	char *string, *name;
8878 	int i;
8879 	char buffer[16];
8880 	CR (gp_widget_get_value(widget, &string));
8881 	gp_widget_get_name(widget,(const char**)&name);
8882 
8883 	for (i = 0; encryption_values[i]; i++) {
8884 		if (!strcmp(_(encryption_values[i]), string)) {
8885 			snprintf(buffer, 16, "%d", i);
8886 			gp_setting_set("ptp2_wifi",name,buffer);
8887 			return GP_OK;
8888 		}
8889 	}
8890 
8891 	return GP_ERROR_BAD_PARAMETERS;
8892 }
8893 
8894 static char* accessmode_values[] = {
8895 N_("Managed"),
8896 N_("Ad-hoc"),
8897 NULL
8898 };
8899 
8900 static int
_get_nikon_wifi_profile_accessmode(CONFIG_GET_ARGS)8901 _get_nikon_wifi_profile_accessmode(CONFIG_GET_ARGS) {
8902 	char buffer[1024];
8903 	int i;
8904 	int val;
8905 
8906 	gp_widget_new (GP_WIDGET_RADIO, _(menu->label), widget);
8907 	gp_widget_set_name (*widget, menu->name);
8908 	gp_setting_get("ptp2_wifi", menu->name, buffer);
8909 	val = atoi(buffer);
8910 
8911 	for (i = 0; accessmode_values[i]; i++) {
8912 		gp_widget_add_choice(*widget, _(accessmode_values[i]));
8913 		if (i == val)
8914 			gp_widget_set_value(*widget, _(accessmode_values[i]));
8915 	}
8916 
8917 	return (GP_OK);
8918 }
8919 
8920 static int
_put_nikon_wifi_profile_accessmode(CONFIG_PUT_ARGS)8921 _put_nikon_wifi_profile_accessmode(CONFIG_PUT_ARGS) {
8922 	char *string, *name;
8923 	int i;
8924 	char buffer[16];
8925 	CR (gp_widget_get_value(widget, &string));
8926 	gp_widget_get_name(widget,(const char**)&name);
8927 
8928 	for (i = 0; accessmode_values[i]; i++) {
8929 		if (!strcmp(_(accessmode_values[i]), string)) {
8930 			snprintf(buffer, 16, "%d", i);
8931 			gp_setting_set("ptp2_wifi",name,buffer);
8932 			return GP_OK;
8933 		}
8934 	}
8935 
8936 	return GP_ERROR_BAD_PARAMETERS;
8937 }
8938 
8939 static int
_get_nikon_wifi_profile_write(CONFIG_GET_ARGS)8940 _get_nikon_wifi_profile_write(CONFIG_GET_ARGS) {
8941 	gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget);
8942 	gp_widget_set_name (*widget, menu->name);
8943 	gp_widget_set_value(*widget, 0);
8944 	return (GP_OK);
8945 }
8946 
8947 static int
_put_nikon_wifi_profile_write(CONFIG_PUT_ARGS)8948 _put_nikon_wifi_profile_write(CONFIG_PUT_ARGS) {
8949 	char buffer[1024];
8950 	char keypart[3];
8951 	char* pos, *endptr;
8952 	int value, i;
8953 	CR (gp_widget_get_value(widget, &value));
8954 	if (value) {
8955 		struct in_addr inp;
8956 		PTPNIKONWifiProfile profile;
8957 		memset(&profile, 0, sizeof(PTPNIKONWifiProfile));
8958 		profile.icon_type = 1;
8959 		profile.key_nr = 1;
8960 
8961 		gp_setting_get("ptp2_wifi","name",buffer);
8962 		strncpy(profile.profile_name, buffer, 16);
8963 		gp_setting_get("ptp2_wifi","essid",buffer);
8964 		strncpy(profile.essid, buffer, 32);
8965 
8966 		gp_setting_get("ptp2_wifi","accessmode",buffer);
8967 		profile.access_mode = atoi(buffer);
8968 
8969 		gp_setting_get("ptp2_wifi","ipaddr",buffer);
8970 /* fixme: replacement on win32 where we do not have this helper */
8971 #ifdef HAVE_INET_ATON
8972 		if (buffer[0] != 0) { /* No DHCP */
8973 			C_PARAMS_MSG (inet_aton (buffer, &inp), "failed to scan for addr in %s.", buffer);
8974 			profile.ip_address = inp.s_addr;
8975 			gp_setting_get("ptp2_wifi","netmask",buffer);
8976 			C_PARAMS_MSG (inet_aton (buffer, &inp), "failed to scan for netmask in %s.", buffer);
8977 			inp.s_addr = be32toh(inp.s_addr); /* Reverse bytes so we can use the code below. */
8978 			profile.subnet_mask = 32;
8979 			while (((inp.s_addr >> (32-profile.subnet_mask)) & 0x01) == 0) {
8980 				profile.subnet_mask--;
8981 				C_PARAMS_MSG (profile.subnet_mask > 0, "Invalid subnet mask %s: no zeros.", buffer);
8982 			}
8983 			/* Check there is only ones left */
8984 			C_PARAMS_MSG ((inp.s_addr | ((0x01 << (32-profile.subnet_mask)) - 1)) == 0xFFFFFFFF,
8985 				"Invalid subnet mask %s: misplaced zeros.", buffer);
8986 
8987 			/* Gateway (never tested) */
8988 			gp_setting_get("ptp2_wifi","gw",buffer);
8989 			if (*buffer) {
8990 				C_PARAMS_MSG (inet_aton (buffer, &inp), "failed to scan for gw in %s", buffer);
8991 				profile.gateway_address = inp.s_addr;
8992 			}
8993 		}
8994 		else
8995 #endif
8996 		{ /* DHCP */
8997 			/* Never use mode 2, as mode 3 switches to mode 2
8998 			 * if it gets no DHCP answer. */
8999 			profile.address_mode = 3;
9000 		}
9001 
9002 		gp_setting_get("ptp2_wifi","channel",buffer);
9003 		profile.wifi_channel = atoi(buffer);
9004 
9005 		/* Encryption */
9006 		gp_setting_get("ptp2_wifi","encryption",buffer);
9007 		profile.encryption = atoi(buffer);
9008 
9009 		if (profile.encryption != 0) {
9010 			gp_setting_get("ptp2_wifi","key",buffer);
9011 			i = 0;
9012 			pos = buffer;
9013 			keypart[2] = 0;
9014 			while (*pos) {
9015 				C_PARAMS_MSG (*(pos+1), "Bad key: '%s'", buffer);
9016 				keypart[0] = *(pos++);
9017 				keypart[1] = *(pos++);
9018 				profile.key[i++] = strtol(keypart, &endptr, 16);
9019 				C_PARAMS_MSG (endptr == keypart+2, "Bad key: '%s', '%s' is not a number.", buffer, keypart);
9020 				if (*pos == ':')
9021 					pos++;
9022 			}
9023 			if (profile.encryption == 1) /* WEP 64-bit */
9024 				C_PARAMS_MSG (i == 5, "Bad key: '%s', %d bit length, should be 40 bit.", buffer, i*8); /* 5*8 = 40 bit + 24 bit (IV) = 64 bit */
9025 			else if (profile.encryption == 2) /* WEP 128-bit */
9026 				C_PARAMS_MSG (i == 13, "Bad key: '%s', %d bit length, should be 104 bit.", buffer, i*8); /* 13*8 = 104 bit + 24 bit (IV) = 128 bit */
9027 		}
9028 
9029 		ptp_nikon_writewifiprofile(&(camera->pl->params), &profile);
9030 	}
9031 	return (GP_OK);
9032 }
9033 
9034 static struct submenu create_wifi_profile_submenu[] = {
9035 	{ N_("Profile name"),                   "name",         0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_prop,       _put_nikon_wifi_profile_prop },
9036 	{ N_("WIFI ESSID"),                     "essid",        0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_prop,       _put_nikon_wifi_profile_prop },
9037 	{ N_("IP address (empty for DHCP)"),    "ipaddr",       0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_prop,       _put_nikon_wifi_profile_prop },
9038 	{ N_("Network mask"),                   "netmask",      0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_prop,       _put_nikon_wifi_profile_prop },
9039 	{ N_("Default gateway"),                "gw",           0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_prop,       _put_nikon_wifi_profile_prop },
9040 	{ N_("Access mode"),                    "accessmode",   0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_accessmode, _put_nikon_wifi_profile_accessmode },
9041 	{ N_("WIFI channel"),                   "channel",      0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_channel,    _put_nikon_wifi_profile_channel },
9042 	{ N_("Encryption"),                     "encryption",   0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_encryption, _put_nikon_wifi_profile_encryption },
9043 	{ N_("Encryption key (hex)"),           "key",          0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_prop,       _put_nikon_wifi_profile_prop },
9044 	{ N_("Write"),                          "write",        0,  PTP_VENDOR_NIKON,   0,  _get_nikon_wifi_profile_write,      _put_nikon_wifi_profile_write },
9045 	{ 0,0,0,0,0,0,0 },
9046 };
9047 
9048 static int
_get_nikon_create_wifi_profile(CONFIG_GET_ARGS)9049 _get_nikon_create_wifi_profile (CONFIG_GET_ARGS)
9050 {
9051 	int submenuno, ret;
9052 	CameraWidget *subwidget;
9053 
9054 	gp_widget_new (GP_WIDGET_SECTION, _(menu->label), widget);
9055 	gp_widget_set_name (*widget, menu->name);
9056 
9057 	for (submenuno = 0; create_wifi_profile_submenu[submenuno].name ; submenuno++ ) {
9058 		struct submenu *cursub = create_wifi_profile_submenu+submenuno;
9059 
9060 		ret = cursub->getfunc (camera, &subwidget, cursub, NULL);
9061 		if (ret == GP_OK)
9062 			gp_widget_append (*widget, subwidget);
9063 	}
9064 
9065 	return GP_OK;
9066 }
9067 
9068 static int
_put_nikon_create_wifi_profile(CONFIG_PUT_ARGS)9069 _put_nikon_create_wifi_profile (CONFIG_PUT_ARGS)
9070 {
9071 	int submenuno, ret;
9072 	CameraWidget *subwidget;
9073 
9074 	for (submenuno = 0; create_wifi_profile_submenu[submenuno].name ; submenuno++ ) {
9075 		struct submenu *cursub = create_wifi_profile_submenu+submenuno;
9076 
9077 		ret = gp_widget_get_child_by_label (widget, _(cursub->label), &subwidget);
9078 		if (ret != GP_OK)
9079 			continue;
9080 
9081 		if (!gp_widget_changed (subwidget))
9082 			continue;
9083 
9084 	        gp_widget_set_changed (subwidget, FALSE);
9085 
9086 		ret = cursub->putfunc (camera, subwidget, NULL, NULL);
9087 	}
9088 
9089 	return GP_OK;
9090 }
9091 
9092 static struct submenu wifi_profiles_menu[] = {
9093 	/* wifi */
9094 	{ N_("List Wifi profiles"), "list", 0, PTP_VENDOR_NIKON, 0, _get_nikon_list_wifi_profiles, _put_nikon_list_wifi_profiles },
9095 	{ N_("Create Wifi profile"), "new", 0, PTP_VENDOR_NIKON, 0, _get_nikon_create_wifi_profile, _put_nikon_create_wifi_profile },
9096 	{ 0,0,0,0,0,0,0 },
9097 };
9098 
9099 /* Wifi profiles menu is a non-standard menu, because putfunc is always
9100  * called on each submenu, whether or not the value has been changed. */
9101 static int
_get_wifi_profiles_menu(CONFIG_MENU_GET_ARGS)9102 _get_wifi_profiles_menu (CONFIG_MENU_GET_ARGS)
9103 {
9104 	CameraWidget *subwidget;
9105 	int submenuno, ret;
9106 
9107 	if (camera->pl->params.deviceinfo.VendorExtensionID != PTP_VENDOR_NIKON)
9108 		return (GP_ERROR_NOT_SUPPORTED);
9109 
9110 	if (!ptp_operation_issupported (&camera->pl->params, PTP_OC_NIKON_GetProfileAllData))
9111 		return (GP_ERROR_NOT_SUPPORTED);
9112 
9113 	gp_widget_new (GP_WIDGET_SECTION, _(menu->label), widget);
9114 	gp_widget_set_name (*widget, menu->name);
9115 
9116 	for (submenuno = 0; wifi_profiles_menu[submenuno].name ; submenuno++ ) {
9117 		struct submenu *cursub = wifi_profiles_menu+submenuno;
9118 
9119 		ret = cursub->getfunc (camera, &subwidget, cursub, NULL);
9120 		if (ret == GP_OK)
9121 			gp_widget_append (*widget, subwidget);
9122 	}
9123 
9124 	return GP_OK;
9125 }
9126 
9127 static int
_put_wifi_profiles_menu(CONFIG_MENU_PUT_ARGS)9128 _put_wifi_profiles_menu (CONFIG_MENU_PUT_ARGS)
9129 {
9130 	int submenuno, ret;
9131 	CameraWidget *subwidget;
9132 
9133 	for (submenuno = 0; wifi_profiles_menu[submenuno].name ; submenuno++ ) {
9134 		struct submenu *cursub = wifi_profiles_menu+submenuno;
9135 
9136 		ret = gp_widget_get_child_by_label (widget, _(cursub->label), &subwidget);
9137 		if (ret != GP_OK)
9138 			continue;
9139 
9140 		ret = cursub->putfunc (camera, subwidget, NULL, NULL);
9141 	}
9142 
9143 	return GP_OK;
9144 }
9145 
9146 static int
_get_PTP_DeviceVersion_STR(CONFIG_GET_ARGS)9147 _get_PTP_DeviceVersion_STR(CONFIG_GET_ARGS) {
9148 	PTPParams	*params = &camera->pl->params;
9149 
9150 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
9151 	gp_widget_set_name (*widget, menu->name);
9152 	gp_widget_set_value (*widget,params->deviceinfo.DeviceVersion?params->deviceinfo.DeviceVersion:_("None"));
9153 	return GP_OK;
9154 }
9155 
9156 static int
_get_PTP_Model_STR(CONFIG_GET_ARGS)9157 _get_PTP_Model_STR(CONFIG_GET_ARGS) {
9158 	PTPParams	*params = &camera->pl->params;
9159 
9160 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
9161 	gp_widget_set_name (*widget, menu->name);
9162 	gp_widget_set_value (*widget,params->deviceinfo.Model?params->deviceinfo.Model:_("None"));
9163 	return GP_OK;
9164 }
9165 
9166 static int
_get_PTP_VendorExtension_STR(CONFIG_GET_ARGS)9167 _get_PTP_VendorExtension_STR(CONFIG_GET_ARGS) {
9168 	PTPParams	*params = &camera->pl->params;
9169 
9170 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
9171 	gp_widget_set_name (*widget, menu->name);
9172 	gp_widget_set_value (*widget,params->deviceinfo.VendorExtensionDesc?params->deviceinfo.VendorExtensionDesc:_("None"));
9173 	return GP_OK;
9174 }
9175 
9176 static int
_get_PTP_Serial_STR(CONFIG_GET_ARGS)9177 _get_PTP_Serial_STR(CONFIG_GET_ARGS) {
9178 	PTPParams	*params = &camera->pl->params;
9179 
9180 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
9181 	gp_widget_set_name (*widget, menu->name);
9182 	gp_widget_set_value (*widget,params->deviceinfo.SerialNumber?params->deviceinfo.SerialNumber:_("None"));
9183 	return GP_OK;
9184 }
9185 
9186 static int
_get_PTP_Manufacturer_STR(CONFIG_GET_ARGS)9187 _get_PTP_Manufacturer_STR(CONFIG_GET_ARGS) {
9188 	PTPParams	*params = &camera->pl->params;
9189 
9190 	gp_widget_new (GP_WIDGET_TEXT, _(menu->label), widget);
9191 	gp_widget_set_name (*widget, menu->name);
9192 	gp_widget_set_value (*widget,params->deviceinfo.Manufacturer?params->deviceinfo.Manufacturer:_("None"));
9193 	return GP_OK;
9194 }
9195 
9196 
9197 static struct submenu camera_actions_menu[] = {
9198 	/* { N_("Viewfinder Mode"), "viewfinder", PTP_DPC_CANON_ViewFinderMode, PTP_VENDOR_CANON, PTP_DTC_UINT32, _get_Canon_ViewFinderMode, _put_Canon_ViewFinderMode}, */
9199 	/*{ N_("Synchronize camera date and time with PC"),"syncdatetime", PTP_DPC_CANON_UnixTime, PTP_VENDOR_CANON, PTP_DTC_UINT32, _get_Canon_SyncTime, _put_Canon_SyncTime },*/
9200 	{ N_("Synchronize camera date and time with PC"),"syncdatetimeutc", PTP_DPC_CANON_EOS_UTCTime, PTP_VENDOR_CANON, PTP_DTC_UINT32, _get_Canon_SyncTime, _put_Canon_SyncTime },
9201 	{ N_("Synchronize camera date and time with PC"),"syncdatetime", PTP_DPC_CANON_EOS_CameraTime, PTP_VENDOR_CANON, PTP_DTC_UINT32, _get_Canon_SyncTime, _put_Canon_SyncTime },
9202 
9203 	{ N_("Auto-Focus"),                     "autofocus",        PTP_DPC_SONY_AutoFocus, PTP_VENDOR_SONY,   PTP_DTC_UINT16,  _get_Sony_Autofocus,            _put_Sony_Autofocus },
9204 	{ N_("Manual-Focus"),                   "manualfocus",      0xd2d2, PTP_VENDOR_SONY,   PTP_DTC_UINT16,  _get_Sony_ManualFocus,            _put_Sony_ManualFocus },
9205 	{ N_("Capture"),                        "capture",          PTP_DPC_SONY_Capture,   PTP_VENDOR_SONY,   PTP_DTC_UINT16,  _get_Sony_Capture,              _put_Sony_Capture },
9206 	{ N_("Power Down"),                     "powerdown",        0,  0,                  PTP_OC_PowerDown,                   _get_PowerDown,                 _put_PowerDown },
9207 	{ N_("Focus Lock"),                     "focuslock",        0,  PTP_VENDOR_CANON,   PTP_OC_CANON_FocusLock,             _get_Canon_FocusLock,           _put_Canon_FocusLock },
9208 	{ N_("Bulb Mode"),                      "bulb",             PTP_DPC_SONY_StillImage,PTP_VENDOR_SONY,   0,               _get_Sony_Bulb,                 _put_Sony_Bulb },
9209 	{ N_("Bulb Mode"),                      "bulb",             0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_BulbStart,         _get_Canon_EOS_Bulb,            _put_Canon_EOS_Bulb },
9210 	{ N_("Bulb Mode"),                      "bulb",             0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_TerminateCapture,      _get_Nikon_Bulb,                _put_Nikon_Bulb },
9211 	{ N_("Bulb Mode"),                      "bulb",             0,  PTP_VENDOR_GP_OLYMPUS_OMD,   PTP_OC_OLYMPUS_OMD_Capture,      _get_Olympus_OMD_Bulb,                _put_Olympus_OMD_Bulb },
9212 	{ N_("Bulb Mode"),                      "bulb",             0,  PTP_VENDOR_FUJI,    PTP_OC_InitiateCapture,             _get_Fuji_Bulb,                 _put_Fuji_Bulb },
9213 	{ N_("UI Lock"),                        "uilock",           0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_SetUILock,         _get_Canon_EOS_UILock,          _put_Canon_EOS_UILock },
9214 	{ N_("Popup Flash"),                    "popupflash",       0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_PopupBuiltinFlash, _get_Canon_EOS_PopupFlash,      _put_Canon_EOS_PopupFlash },
9215 	{ N_("Drive Nikon DSLR Autofocus"),     "autofocusdrive",   0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_AfDrive,               _get_Nikon_AFDrive,             _put_Nikon_AFDrive },
9216 	{ N_("Drive Canon DSLR Autofocus"),     "autofocusdrive",   0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_DoAf,              _get_Canon_EOS_AFDrive,         _put_Canon_EOS_AFDrive },
9217 	{ N_("Drive Fuji Autofocus"),           "autofocusdrive",   0,  PTP_VENDOR_FUJI,    0,               			_get_Fuji_AFDrive,              _put_Fuji_AFDrive },
9218 	{ N_("Drive Nikon DSLR Manual focus"),  "manualfocusdrive", 0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_MfDrive,               _get_Nikon_MFDrive,             _put_Nikon_MFDrive },
9219 	{ N_("Set Nikon Autofocus area"),       "changeafarea",     0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_ChangeAfArea,          _get_Nikon_ChangeAfArea,        _put_Nikon_ChangeAfArea },
9220 	{ N_("Set Nikon Control Mode"),         "controlmode",      0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_ChangeCameraMode,      _get_Nikon_ControlMode,         _put_Nikon_ControlMode },
9221 	{ N_("Drive Canon DSLR Manual focus"),  "manualfocusdrive", 0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_DriveLens,         _get_Canon_EOS_MFDrive,         _put_Canon_EOS_MFDrive },
9222 	{ N_("Cancel Canon DSLR Autofocus"),    "cancelautofocus",  0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_AfCancel,          _get_Canon_EOS_AFCancel,        _put_Canon_EOS_AFCancel },
9223 	{ N_("Drive Olympus OMD Manual focus"), "manualfocusdrive", 0,  PTP_VENDOR_GP_OLYMPUS_OMD, PTP_OC_OLYMPUS_OMD_MFDrive,	_get_Olympus_OMD_MFDrive,	_put_Olympus_OMD_MFDrive },
9224 	{ N_("Drive Panasonic Manual focus"),   "manualfocusdrive", 0,  PTP_VENDOR_PANASONIC, PTP_OC_PANASONIC_ManualFocusDrive,_get_Panasonic_MFDrive,		_put_Panasonic_MFDrive },
9225 	{ N_("Canon EOS Zoom"),                 "eoszoom",          0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_Zoom,              _get_Canon_EOS_Zoom,            _put_Canon_EOS_Zoom },
9226 	{ N_("Canon EOS Zoom Position"),        "eoszoomposition",  0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_ZoomPosition,      _get_Canon_EOS_ZoomPosition,    _put_Canon_EOS_ZoomPosition },
9227 	{ N_("Canon EOS Viewfinder"),           "viewfinder",       0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_GetViewFinderData, _get_Canon_EOS_ViewFinder,      _put_Canon_EOS_ViewFinder },
9228 	{ N_("Panasonic Viewfinder"),           "viewfinder",       0,  PTP_VENDOR_PANASONIC, 0, 								_get_Panasonic_ViewFinder,      _put_Panasonic_ViewFinder },
9229 	{ N_("Nikon Viewfinder"),               "viewfinder",       0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_StartLiveView,         _get_Nikon_ViewFinder,          _put_Nikon_ViewFinder },
9230 	{ N_("Canon EOS Remote Release"),       "eosremoterelease", 0,  PTP_VENDOR_CANON,   PTP_OC_CANON_EOS_RemoteReleaseOn,   _get_Canon_EOS_RemoteRelease,   _put_Canon_EOS_RemoteRelease },
9231 	{ N_("CHDK Script"),                    "chdk_script",      0,  PTP_VENDOR_CANON,   PTP_OC_CHDK,                        _get_Canon_CHDK_Script,         _put_Canon_CHDK_Script },
9232 	{ N_("Movie Capture"),                  "movie",            0,  0,                  PTP_OC_InitiateOpenCapture,         _get_OpenCapture,               _put_OpenCapture },
9233 	{ N_("Movie Capture"),                  "movie",            0,  PTP_VENDOR_NIKON,   PTP_OC_NIKON_StartMovieRecInCard,   _get_Nikon_Movie,               _put_Nikon_Movie },
9234 	{ N_("Movie Capture"),                  "movie",            0,  PTP_VENDOR_SONY,    PTP_OC_SONY_SDIOConnect,            _get_Sony_Movie,                _put_Sony_Movie },
9235 	{ N_("Movie Capture"),                  "movie",            0,  PTP_VENDOR_SONY,    PTP_OC_SONY_QX_Connect,             _get_Sony_QX_Movie,             _put_Sony_QX_Movie },
9236 	{ N_("PTP Opcode"),                     "opcode",           0,  0,                  PTP_OC_GetDeviceInfo,               _get_Generic_OPCode,            _put_Generic_OPCode },
9237 	{ 0,0,0,0,0,0,0 },
9238 };
9239 
9240 static struct submenu camera_status_menu[] = {
9241 	{ N_("Serial Number"),          "serialnumber",     0,  0,  PTP_OC_GetDeviceInfo,   _get_PTP_Serial_STR,            _put_None },
9242 	{ N_("Camera Manufacturer"),    "manufacturer",     0,  0,  PTP_OC_GetDeviceInfo,   _get_PTP_Manufacturer_STR,      _put_None },
9243 	{ N_("Camera Model"),           "cameramodel",      0,  0,  PTP_OC_GetDeviceInfo,   _get_PTP_Model_STR,             _put_None },
9244 	{ N_("Device Version"),         "deviceversion",    0,  0,  PTP_OC_GetDeviceInfo,   _get_PTP_DeviceVersion_STR,     _put_None },
9245 	{ N_("Vendor Extension"),       "vendorextension",  0,  0,  PTP_OC_GetDeviceInfo,   _get_PTP_VendorExtension_STR,   _put_None },
9246 
9247 	{ N_("Camera Model"),           "model",            PTP_DPC_CANON_CameraModel,              PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_None },
9248 	{ N_("Camera Model"),           "model",            PTP_DPC_CANON_EOS_ModelID,              PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9249 	{ N_("Firmware Version"),       "firmwareversion",  PTP_DPC_CANON_FirmwareVersion,          PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_CANON_FirmwareVersion,     _put_None },
9250 	{ N_("PTP Version"),            "ptpversion",       PTP_DPC_CANON_EOS_PTPExtensionVersion,  PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9251 	{ N_("DPOF Version"),           "dpofversion",      PTP_DPC_CANON_EOS_DPOFVersion,          PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_INT,                       _put_None },
9252 	{ N_("AC Power"),               "acpower",          PTP_DPC_NIKON_ACPower,                  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9253 	{ N_("External Flash"),         "externalflash",    PTP_DPC_NIKON_ExternalFlashAttached,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9254 	{ N_("Battery Level"),          "batterylevel",     PTP_DPC_BatteryLevel,                   0,                  PTP_DTC_UINT8,  _get_BatteryLevel,              _put_None },
9255 	{ N_("Battery Level"),          "batterylevel",     PTP_DPC_CANON_EOS_BatteryPower,         PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_BatteryLevel,    _put_None },
9256 	{ N_("Battery Level"),          "batterylevel",     PTP_DPC_SONY_BatteryLevel,              PTP_VENDOR_SONY,    PTP_DTC_INT8,   _get_SONY_BatteryLevel,         _put_None },
9257 	{ N_("Mirror Up Status"),       "mirrorupstatus",   PTP_DPC_NIKON_MirrorUpStatus,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,		_put_None },
9258 	{ N_("Mirror Up Shooting Count"),"mirrorupshootingcount", PTP_DPC_NIKON_MirrorUpReleaseShootingCount, PTP_VENDOR_NIKON, PTP_DTC_UINT8,  _get_INT,		_put_None },
9259 	{ N_("Continuous Shooting Count"),"continousshootingcount", PTP_DPC_NIKON_ContinousShootingCount, PTP_VENDOR_NIKON, PTP_DTC_UINT8,_get_INT,			_put_None },
9260 	{ N_("Camera Orientation"),     "orientation",      PTP_DPC_NIKON_CameraOrientation,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_CameraOrientation,   _put_None },
9261 	{ N_("Camera Orientation"),     "orientation2",     PTP_DPC_NIKON_AngleLevel,               PTP_VENDOR_NIKON,   PTP_DTC_INT32,  _get_Nikon_AngleLevel,		_put_None },
9262 	{ N_("Camera Orientation"),     "orientation",      PTP_DPC_CANON_RotationAngle,            PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_CameraOrientation,   _put_None },
9263 	{ N_("Flash Open"),             "flashopen",        PTP_DPC_NIKON_FlashOpen,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9264 	{ N_("Active Folder"),          "activefolder",     PTP_DPC_NIKON_ActiveFolder,             PTP_VENDOR_NIKON,   PTP_DTC_UINT16, _get_INT,         		_put_None },
9265 	{ N_("Flash Charged"),          "flashcharged",     PTP_DPC_NIKON_FlashCharged,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9266 	{ N_("Lens Name"),              "lensname",         PTP_DPC_NIKON_LensID,                   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LensID,              _put_None },
9267 	{ N_("Lens Name"),              "lensname",         PTP_DPC_CANON_EOS_LensName,             PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_None },
9268 	{ N_("Lens Name"),              "lensname",         PTP_DPC_FUJI_LensNameAndSerial,         PTP_VENDOR_FUJI,    PTP_DTC_STR,    _get_STR,                       _put_None },
9269 	{ N_("Serial Number"),          "eosserialnumber",  PTP_DPC_CANON_EOS_SerialNumber,         PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_None },
9270 	{ N_("Shutter Counter"),        "shuttercounter",   PTP_DPC_CANON_EOS_ShutterCounter,       PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9271 	{ N_("Shutter Counter"),        "shuttercounter",   PTP_DPC_FUJI_TotalShotCount,            PTP_VENDOR_FUJI,    PTP_DTC_UINT32, _get_Fuji_Totalcount,           _put_None },
9272 	{ N_("Available Shots"),        "availableshots",   PTP_DPC_CANON_EOS_AvailableShots,       PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9273 	{ N_("Available Shots"),        "availableshots",   PTP_DPC_NIKON_ExposureRemaining,        PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9274 	{ N_("Focal Length Minimum"),   "minfocallength",   PTP_DPC_NIKON_FocalLengthMin,           PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_FocalLength,         _put_None },
9275 	{ N_("Focal Length Maximum"),   "maxfocallength",   PTP_DPC_NIKON_FocalLengthMax,           PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_FocalLength,         _put_None },
9276 	{ N_("Maximum Aperture at Focal Length Minimum"), "apertureatminfocallength", PTP_DPC_NIKON_MaxApAtMinFocalLength, PTP_VENDOR_NIKON, PTP_DTC_UINT16, _get_Nikon_ApertureAtFocalLength, _put_None },
9277 	{ N_("Maximum Aperture at Focal Length Maximum"), "apertureatmaxfocallength", PTP_DPC_NIKON_MaxApAtMaxFocalLength, PTP_VENDOR_NIKON, PTP_DTC_UINT16, _get_Nikon_ApertureAtFocalLength, _put_None },
9278 	{ N_("Low Light"),              "lowlight",         PTP_DPC_NIKON_ExposureDisplayStatus,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LowLight,            _put_None },
9279 	{ N_("Light Meter"),            "lightmeter",       PTP_DPC_NIKON_LightMeter,               PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_LightMeter,          _put_None },
9280 	{ N_("Light Meter"),            "lightmeter",       PTP_DPC_NIKON_ExposureIndicateStatus,   PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Range_INT8,                _put_None },
9281 	{ N_("AF Locked"),              "aflocked",         PTP_DPC_NIKON_AFLockStatus,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9282 	{ N_("AE Locked"),              "aelocked",         PTP_DPC_NIKON_AELockStatus,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9283 	{ N_("FV Locked"),              "fvlocked",         PTP_DPC_NIKON_FVLockStatus,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_None },
9284 	{ 0,0,0,0,0,0,0 },
9285 };
9286 
9287 static struct submenu camera_settings_menu[] = {
9288 	{ N_("Camera Date and Time"),   "datetimeutc",          PTP_DPC_CANON_EOS_UTCTime,          PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_UINT32_as_time,            _put_UINT32_as_time },
9289 	{ N_("Camera Date and Time"),   "datetime",             PTP_DPC_CANON_UnixTime,             PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_UINT32_as_localtime,       _put_UINT32_as_localtime },
9290 	{ N_("Camera Date and Time"),   "datetime",             PTP_DPC_CANON_EOS_CameraTime,       PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_UINT32_as_localtime,       _put_UINT32_as_localtime },
9291 	{ N_("Camera Date and Time"),   "datetime",             PTP_DPC_DateTime,                   0,                  PTP_DTC_STR,    _get_STR_as_time,               _put_STR_as_time },
9292 	{ N_("Camera Date and Time"),   "datetime",             PTP_DPC_SONY_QX_DateTime,           PTP_VENDOR_SONY,    PTP_DTC_STR,    _get_STR_as_time,               _put_STR_as_time },
9293 	{ N_("Beep Mode"),              "beep",                 PTP_DPC_CANON_BeepMode,             PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_BeepMode,            _put_Canon_BeepMode },
9294 	{ N_("Image Comment"),          "imagecomment",         PTP_DPC_NIKON_ImageCommentString,   PTP_VENDOR_NIKON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9295 	{ N_("Image Comment"),          "imagecomment",         PTP_DPC_FUJI_Comment,               PTP_VENDOR_FUJI,    PTP_DTC_STR,    _get_STR,                       _put_STR },
9296 	{ N_("Device Name"),            "devicename",           PTP_DPC_FUJI_DeviceName,            PTP_VENDOR_FUJI,    PTP_DTC_STR,    _get_STR,                       _put_STR },
9297 	{ N_("WLAN GUID"),          	"guid",         	PTP_DPC_NIKON_GUID,   		    PTP_VENDOR_NIKON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9298 	{ N_("Enable Image Comment"),   "imagecommentenable",   PTP_DPC_NIKON_ImageCommentEnable,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_Nikon_OnOff_UINT8 },
9299 	{ N_("LCD Off Time"),           "lcdofftime",           PTP_DPC_NIKON_MonitorOff,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LCDOffTime,          _put_Nikon_LCDOffTime },
9300 	{ N_("Recording Media"),        "recordingmedia",       PTP_DPC_NIKON_RecordingMedia,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_RecordingMedia,      _put_Nikon_RecordingMedia },
9301 	{ N_("Quick Review Time"),      "reviewtime",           PTP_DPC_CANON_EOS_QuickReviewTime,  PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_QuickReviewTime, _put_Canon_EOS_QuickReviewTime },
9302 	{ N_("CSM Menu"),               "csmmenu",              PTP_DPC_NIKON_CSMMenu,              PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_Nikon_OnOff_UINT8 },
9303 	{ N_("Reverse Command Dial"),   "reversedial",          PTP_DPC_NIKON_ReverseCommandDial,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_Nikon_OnOff_UINT8 },
9304 	{ N_("Camera Output"),          "output",               PTP_DPC_CANON_CameraOutput,         PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_CameraOutput,        _put_Canon_CameraOutput },
9305 	{ N_("Camera Output"),          "output",               PTP_DPC_CANON_EOS_EVFOutputDevice,  PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_CameraOutput,    _put_Canon_EOS_CameraOutput },
9306 	{ N_("Recording Destination"),  "movierecordtarget",    PTP_DPC_CANON_EOS_EVFRecordStatus,  PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_EVFRecordTarget, _put_Canon_EOS_EVFRecordTarget },
9307 	{ N_("EVF Mode"),               "evfmode",              PTP_DPC_CANON_EOS_EVFMode,          PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_EVFMode,         _put_Canon_EOS_EVFMode },
9308 	{ N_("Owner Name"),             "ownername",            PTP_DPC_CANON_CameraOwner,          PTP_VENDOR_CANON,   PTP_DTC_AUINT8, _get_AUINT8_as_CHAR_ARRAY,      _put_AUINT8_as_CHAR_ARRAY },
9309 	{ N_("Owner Name"),             "ownername",            PTP_DPC_CANON_EOS_Owner,            PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9310 	{ N_("Artist"),                 "artist",               PTP_DPC_CANON_EOS_Artist,           PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9311 	{ N_("Artist"),                 "artist",               PTP_DPC_NIKON_ArtistName,           PTP_VENDOR_NIKON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9312 	{ N_("CCD Number"),             "ccdnumber",            PTP_DPC_NIKON_CCDNumber,            PTP_VENDOR_NIKON,   PTP_DTC_STR,    _get_STR,                       _put_None },
9313 	{ N_("Copyright"),              "copyright",            PTP_DPC_CANON_EOS_Copyright,        PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9314 	{ N_("Copyright"),              "copyright",            PTP_DPC_FUJI_Copyright,             PTP_VENDOR_FUJI,    PTP_DTC_STR,    _get_STR,                       _put_STR },
9315 	{ N_("Copyright"),              "copyright",            PTP_DPC_NIKON_CopyrightInfo,        PTP_VENDOR_NIKON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9316 	{ N_("Clean Sensor"),           "cleansensor",          PTP_DPC_NIKON_CleanImageSensor,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_CleanSensor,         _put_Nikon_CleanSensor },
9317 	{ N_("Flicker Reduction"),      "flickerreduction",     PTP_DPC_NIKON_FlickerReduction,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlickerReduction,    _put_Nikon_FlickerReduction },
9318 	{ N_("Custom Functions Ex"),    "customfuncex",         PTP_DPC_CANON_EOS_CustomFuncEx,     PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_STR },
9319 	{ N_("Focus Info"),             "focusinfo",            PTP_DPC_CANON_EOS_FocusInfoEx,      PTP_VENDOR_CANON,   PTP_DTC_STR,    _get_STR,                       _put_None },
9320 	{ N_("Focus Area"),             "focusarea",            PTP_DPC_CANON_EOS_AFSelectFocusArea,PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_INT },
9321 	{ N_("Auto Power Off"),         "autopoweroff",         PTP_DPC_CANON_EOS_AutoPowerOff,     PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_INT,                       _put_INT },
9322 	{ N_("Depth of Field"),         "depthoffield",         PTP_DPC_CANON_EOS_DepthOfFieldPreview, PTP_VENDOR_CANON,PTP_DTC_UINT32, _get_INT,                       _put_INT },
9323 	{ N_("Menus and Playback"),     "menusandplayback",     PTP_DPC_NIKON_MenusAndPlayback,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_MenusAndPlayback,    _put_Nikon_MenusAndPlayback },
9324 	{ N_("External Recording Control"),     "externalrecordingcontrol", PTP_DPC_NIKON_ExternalRecordingControl,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,    _put_Nikon_OffOn_UINT8 },
9325 	{ N_("Camera Action"),          "cameraaction", 	0xd208, 			    PTP_VENDOR_FUJI,	PTP_DTC_UINT16,	_get_Fuji_Action,		_put_Fuji_Action },
9326 
9327 /* virtual */
9328 	{ N_("Thumb Size"),		"thumbsize",    0,  PTP_VENDOR_NIKON,   0,  _get_Nikon_Thumbsize,   _put_Nikon_Thumbsize },
9329 	{ N_("Fast Filesystem"),	"fastfs",	0,  PTP_VENDOR_NIKON,   0,  _get_Nikon_FastFS,      _put_Nikon_FastFS },
9330 	{ N_("Capture Target"),		"capturetarget",0,  PTP_VENDOR_NIKON,   0,  _get_CaptureTarget,     _put_CaptureTarget },
9331 	{ N_("Autofocus"),		"autofocus",    0,  PTP_VENDOR_NIKON,   0,  _get_Autofocus,         _put_Autofocus },
9332 	{ N_("Capture Target"),		"capturetarget",0,  PTP_VENDOR_CANON,   0,  _get_CaptureTarget,     _put_CaptureTarget },
9333 	{ N_("Capture Target"),		"capturetarget",0,  PTP_VENDOR_PANASONIC,0, _get_CaptureTarget,     _put_CaptureTarget },
9334 	{ N_("Capture Target"),		"capturetarget",PTP_DPC_SONY_StillImageStoreDestination,  PTP_VENDOR_SONY,0, _get_Sony_CaptureTarget,     _put_Sony_CaptureTarget },
9335 	{ N_("CHDK"),     		"chdk",		PTP_OC_CHDK,  PTP_VENDOR_CANON,   0,  _get_CHDK,     _put_CHDK },
9336 	{ N_("Capture"),		"capture",	0,  PTP_VENDOR_CANON,   0,  _get_Canon_CaptureMode, _put_Canon_CaptureMode },
9337 	{ N_("Remote Mode"),		"remotemode",	PTP_OC_CANON_EOS_SetRemoteMode,  PTP_VENDOR_CANON,   0,  _get_Canon_RemoteMode, _put_Canon_RemoteMode },
9338 	{ 0,0,0,0,0,0,0 },
9339 };
9340 
9341 /* think of this as properties of the "film" */
9342 static struct submenu image_settings_menu[] = {
9343 	{ N_("Image Quality"),          "imagequality",         PTP_DPC_CANON_ImageQuality,             PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_Quality,             _put_Canon_Quality },
9344 	{ N_("Image Format"),           "imageformat",          PTP_DPC_OLYMPUS_ImageFormat,            PTP_VENDOR_GP_OLYMPUS_OMD,   PTP_DTC_UINT16,  _get_Olympus_Imageformat, _put_Olympus_Imageformat },
9345 	{ N_("Image Format"),           "imageformat",          PTP_DPC_CANON_FullViewFileFormat,       PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_Capture_Format,      _put_Canon_Capture_Format },
9346 	{ N_("Image Format"),           "imageformat",          PTP_DPC_CANON_EOS_ImageFormat,          PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_ImageFormat,     _put_Canon_EOS_ImageFormat },
9347 	{ N_("Image Format SD"),        "imageformatsd",        PTP_DPC_CANON_EOS_ImageFormatSD,        PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_ImageFormat,     _put_Canon_EOS_ImageFormat },
9348 	{ N_("Image Format CF"),        "imageformatcf",        PTP_DPC_CANON_EOS_ImageFormatCF,        PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_ImageFormat,     _put_Canon_EOS_ImageFormat },
9349 	{ N_("Image Format"),           "imageformat",          PTP_DPC_FUJI_Quality,                   PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_Fuji_ImageFormat,          _put_Fuji_ImageFormat },
9350 	{ N_("Image Format"),           "imageformat",          0,					PTP_VENDOR_PANASONIC,PTP_DTC_UINT16, _get_Panasonic_ImageFormat,    _put_Panasonic_ImageFormat },
9351 	{ N_("Image Format Ext HD"),    "imageformatexthd",     PTP_DPC_CANON_EOS_ImageFormatExtHD,     PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_ImageFormat,     _put_Canon_EOS_ImageFormat },
9352 	{ N_("Film Simulation"),        "filmsimulation",       PTP_DPC_FUJI_FilmSimulation,            PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_Fuji_FilmSimulation,       _put_Fuji_FilmSimulation },
9353 	{ N_("Image Size"),             "imagesize",            PTP_DPC_ImageSize,                      0,                  PTP_DTC_STR,    _get_STR_ENUMList,              _put_STR },
9354 	{ N_("Raw Image Size"),         "rawimagesize",         PTP_DPC_NIKON_RawImageSize,             PTP_VENDOR_NIKON,   PTP_DTC_STR,    _get_STR_ENUMList,              _put_STR },
9355 	{ N_("Image Size"),             "imagesize",            PTP_DPC_NIKON_1_ImageSize,              PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon1_ImageSize,          _put_Nikon1_ImageSize },
9356 	{ N_("Image Size"),             "imagesize",            PTP_DPC_SONY_ImageSize,                 PTP_VENDOR_SONY,    PTP_DTC_UINT8,  _get_Sony_ImageSize,            _put_Sony_ImageSize },
9357 	{ N_("Image Size"),             "imagesize",            PTP_DPC_CANON_ImageSize,                PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_Size,                _put_Canon_Size },
9358 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_CANON_ISOSpeed,                 PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_ISO,                 _put_Canon_ISO },
9359 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_ExposureIndex,                  PTP_VENDOR_FUJI,    PTP_DTC_INT32,  _get_INT,                       _put_INT },
9360 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_ExposureIndex,                  0,                  PTP_DTC_UINT16, _get_INT,                       _put_INT },
9361 	{ N_("Movie ISO Speed"),        "movieiso",             PTP_DPC_NIKON_MovieISO,                 PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_INT,                       _put_INT },
9362 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_CANON_EOS_ISOSpeed,             PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_ISO,                 _put_Canon_ISO },
9363 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_SONY_QX_ISO,                    PTP_VENDOR_SONY,    PTP_DTC_UINT32, _get_Sony_ISO,                  _put_Sony_QX_ISO },
9364 	/* these 2 iso will overwrite and conflicht with each other... the older Sony do not have d226, so it should pick the next entry ... */
9365 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_SONY_ISO2,                      PTP_VENDOR_SONY,    PTP_DTC_UINT32, _get_Sony_ISO,                  _put_Sony_ISO2 },
9366 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_SONY_ISO,                       PTP_VENDOR_SONY,    PTP_DTC_UINT32, _get_Sony_ISO,                  _put_Sony_ISO },
9367 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_NIKON_1_ISO,                    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_ISO,               _put_Nikon_1_ISO },
9368 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_OLYMPUS_ISO,                    PTP_VENDOR_GP_OLYMPUS_OMD, PTP_DTC_UINT16,  _get_Olympus_ISO,       _put_Olympus_ISO },
9369 	{ N_("ISO Speed"),              "iso",             	0,         		    		PTP_VENDOR_PANASONIC,   PTP_DTC_UINT32, _get_Panasonic_ISO,         _put_Panasonic_ISO },
9370 	{ N_("ISO Auto"),               "isoauto",              PTP_DPC_NIKON_ISO_Auto,                 PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_Nikon_OnOff_UINT8 },
9371 	{ N_("Auto ISO"),               "autoiso",              PTP_DPC_NIKON_ISOAuto,                  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,         _put_Nikon_OnOff_UINT8 },
9372 	{ N_("WhiteBalance"),           "whitebalance",         PTP_DPC_OLYMPUS_WhiteBalance,           PTP_VENDOR_GP_OLYMPUS_OMD, PTP_DTC_UINT16,  _get_Olympus_WhiteBalance, _put_Olympus_WhiteBalance },
9373 	{ N_("WhiteBalance"),           "whitebalance",         PTP_DPC_CANON_WhiteBalance,             PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_WhiteBalance,        _put_Canon_WhiteBalance },
9374 	{ N_("WhiteBalance"),           "whitebalance",         PTP_DPC_CANON_EOS_WhiteBalance,         PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_EOS_WhiteBalance,    _put_Canon_EOS_WhiteBalance },
9375 	{ N_("Color Temperature"),      "colortemperature",     PTP_DPC_CANON_EOS_ColorTemperature,     PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_INT },
9376 	{ N_("Color Temperature"),      "colortemperature",     PTP_DPC_FUJI_ColorTemperature,          PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_INT,                       _put_INT },
9377 	{ N_("Color Temperature"),      "colortemperature",     PTP_DPC_SONY_ColorTemp,                 PTP_VENDOR_SONY,    PTP_DTC_UINT16, _get_INT,                       _put_INT },
9378 	{ N_("WhiteBalance"),           "whitebalance",         PTP_DPC_WhiteBalance,                   0,                  PTP_DTC_UINT16, _get_WhiteBalance,              _put_WhiteBalance },
9379 	{ N_("WhiteBalance"),           "whitebalance",         PTP_DPC_NIKON_1_WhiteBalance,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_WhiteBalance,      _put_Nikon_1_WhiteBalance },
9380 	{ N_("WhiteBalance Adjust A"),  "whitebalanceadjusta",  PTP_DPC_CANON_EOS_WhiteBalanceAdjustA,  PTP_VENDOR_CANON,   PTP_DTC_INT32,  _get_Canon_EOS_WBAdjust,        _put_Canon_EOS_WBAdjust },
9381 	{ N_("WhiteBalance Adjust B"),  "whitebalanceadjustb",  PTP_DPC_CANON_EOS_WhiteBalanceAdjustB,  PTP_VENDOR_CANON,   PTP_DTC_INT32,  _get_Canon_EOS_WBAdjust,        _put_Canon_EOS_WBAdjust },
9382 	{ N_("WhiteBalance X A"),       "whitebalancexa",       PTP_DPC_CANON_EOS_WhiteBalanceXA,       PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9383 	{ N_("WhiteBalance X B"),       "whitebalancexb",       PTP_DPC_CANON_EOS_WhiteBalanceXB,       PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                       _put_None },
9384 	{ N_("Photo Effect"),           "photoeffect",          PTP_DPC_CANON_PhotoEffect,              PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_PhotoEffect,         _put_Canon_PhotoEffect },
9385 	{ N_("Color Model"),            "colormodel",           PTP_DPC_NIKON_ColorModel,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_ColorModel,          _put_Nikon_ColorModel },
9386 	{ N_("Color Space"),            "colorspace",           PTP_DPC_NIKON_ColorSpace,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_ColorSpace,          _put_Nikon_ColorSpace },
9387 	{ N_("Color Space"),            "colorspace",           PTP_DPC_CANON_EOS_ColorSpace,           PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_ColorSpace,      _put_Canon_EOS_ColorSpace },
9388 	{ N_("Color Space"),            "colorspace",           PTP_DPC_FUJI_ColorSpace,                PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_Canon_EOS_ColorSpace,      _put_Canon_EOS_ColorSpace }, /* uses 1 for sRGB, and 2 for AdobeRGB too, same as EOS */
9389 	{ N_("Video Format"),           "videoformat",          PTP_DPC_VideoFormat,                    0,                  PTP_DTC_UINT32, _get_VideoFormat,               _put_VideoFormat },
9390 	{ N_("Video Resolution"),       "videoresolution",      PTP_DPC_VideoResolution,                0,                  PTP_DTC_STR   , _get_STR_ENUMList,              _put_STR },
9391 	{ N_("Video Quality"),          "videoquality",         PTP_DPC_VideoQuality,                   0,                  PTP_DTC_UINT16, _get_INT,                       _put_INT },
9392 	{ N_("Video Framerate"),        "videoframerate",       PTP_DPC_VideoFrameRate,                 0,                  PTP_DTC_UINT32, _get_Video_Framerate,           _put_Video_Framerate },
9393 	{ N_("Video Contrast"),         "videocontrast",        PTP_DPC_VideoContrast,                  0,                  PTP_DTC_UINT32, _get_INT,                       _put_INT },
9394 	{ N_("Video Brightness"),       "videobrightness",      PTP_DPC_VideoBrightness,                0,                  PTP_DTC_UINT32, _get_INT,                       _put_INT },
9395 	{ N_("Audio Format"),           "audioformat",          PTP_DPC_AudioFormat,                    0,                  PTP_DTC_UINT32, _get_Audio_Format,              _put_Audio_Format },
9396 	{ N_("Audio Bitrate"),          "audiobitrate",         PTP_DPC_AudioBitrate,                   0,                  PTP_DTC_UINT32, _get_INT,                       _put_INT },
9397 	{ N_("Audio Sampling Rate"),    "audiosamplingrate",    PTP_DPC_AudioSamplingRate,              0,                  PTP_DTC_UINT32, _get_INT,                       _put_INT },
9398 	{ N_("Audio Bit per Sample"),   "audiobitpersample",    PTP_DPC_AudioBitPerSample,              0,                  PTP_DTC_UINT16, _get_INT,                       _put_INT },
9399 	{ N_("Audio Volume"),           "audiovolume",          PTP_DPC_AudioVolume,                    0,                  PTP_DTC_UINT32, _get_INT,                       _put_INT },
9400 	{ 0,0,0,0,0,0,0 },
9401 };
9402 
9403 static struct submenu capture_settings_menu[] = {
9404 	{ N_("Long Exp Noise Reduction"),       "longexpnr",                PTP_DPC_NIKON_LongExposureNoiseReduction, PTP_VENDOR_NIKON, PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9405 	{ N_("Long Exp Noise Reduction"),       "longexpnr",                PTP_DPC_NIKON_1_LongExposureNoiseReduction, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_OnOff_UINT8,            _put_Nikon_OnOff_UINT8 },
9406 	{ N_("Auto Focus Mode 2"),              "autofocusmode2",           PTP_DPC_NIKON_A4AFActivation,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9407 	{ N_("Zoom"),                           "zoom",                     PTP_DPC_CANON_Zoom,                     PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_ZoomRange,               _put_Canon_ZoomRange },
9408 	{ N_("Zoom"),                           "zoom",                     PTP_DPC_CANON_EOS_PowerZoomPosition,    PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                           _put_INT },
9409 	{ N_("Zoom"),                           "zoom",                     PTP_DPC_SONY_Zoom,    	            PTP_VENDOR_SONY,    PTP_DTC_UINT32, _get_Sony_Zoom,                     _put_Sony_Zoom },
9410 	{ N_("Zoom Speed"),                     "zoomspeed",                PTP_DPC_CANON_EOS_PowerZoomSpeed,       PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_INT,                           _put_INT },
9411 	{ N_("Assist Light"),                   "assistlight",              PTP_DPC_CANON_AssistLight,              PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_AssistLight,             _put_Canon_AssistLight },
9412 	{ N_("Rotation Flag"),                  "autorotation",             PTP_DPC_CANON_RotationScene,            PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_AutoRotation,            _put_Canon_AutoRotation },
9413 	{ N_("Self Timer"),                     "selftimer",                PTP_DPC_CANON_SelfTime,                 PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_SelfTimer,               _put_Canon_SelfTimer },
9414 	{ N_("Assist Light"),                   "assistlight",              PTP_DPC_NIKON_AFAssist,                 PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9415 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_OLYMPUS_ExposureCompensation,   PTP_VENDOR_GP_OLYMPUS_OMD, PTP_DTC_UINT16,  _get_Olympus_ExpCompensation,_put_Olympus_ExpCompensation },
9416 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_SONY_ExposureCompensation,      PTP_VENDOR_SONY,    PTP_DTC_INT16,  _get_ExpCompensation,               _put_Sony_ExpCompensation2 },
9417 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_SONY_QX_ExposureCompensation,   PTP_VENDOR_SONY,    PTP_DTC_INT16,  _get_ExpCompensation,               _put_ExpCompensation },
9418 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_ExposureBiasCompensation,       PTP_VENDOR_SONY,    PTP_DTC_INT16,  _get_ExpCompensation,               _put_Sony_ExpCompensation },
9419 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_ExposureBiasCompensation,       0,                  PTP_DTC_INT16,  _get_ExpCompensation,               _put_ExpCompensation },
9420 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_CANON_ExpCompensation,          PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_ExpCompensation,         _put_Canon_ExpCompensation },
9421 	{ N_("Exposure Compensation"),          "exposurecompensation",     PTP_DPC_CANON_EOS_ExpCompensation,      PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_ExpCompensation2,        _put_Canon_ExpCompensation2 },
9422 	{ N_("Exposure Compensation"),		"exposurecompensation",	    0, 					    PTP_VENDOR_PANASONIC,   PTP_DTC_INT32, _get_Panasonic_Exposure,         _put_Panasonic_Exposure },
9423 	{ N_("White Balance"),			"whitebalance",	    0, 					    	PTP_VENDOR_PANASONIC,   PTP_DTC_INT32, _get_Panasonic_Whitebalance,         _put_Panasonic_Whitebalance },
9424 	/* these cameras also have PTP_DPC_ExposureBiasCompensation, avoid overlap */
9425 	{ N_("Exposure Compensation"),          "exposurecompensation2",    PTP_DPC_NIKON_ExposureCompensation,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9426 	{ N_("Flash Compensation"),             "flashcompensation",        PTP_DPC_CANON_FlashCompensation,        PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_ExpCompensation,         _put_Canon_ExpCompensation },
9427 	{ N_("AEB Exposure Compensation"),      "aebexpcompensation",       PTP_DPC_CANON_AEBExposureCompensation,  PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_ExpCompensation,         _put_Canon_ExpCompensation },
9428 	{ N_("Flash Mode"),                     "flashmode",                PTP_DPC_CANON_FlashMode,                PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_FlashMode,               _put_Canon_FlashMode },
9429 	{ N_("Flash Mode"),                     "flashmode",                PTP_DPC_FlashMode,                      0,                  PTP_DTC_UINT16, _get_FlashMode,                     _put_FlashMode },
9430 	{ N_("Nikon Flash Mode"),               "nikonflashmode",           PTP_DPC_NIKON_FlashMode,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_InternalFlashMode,       _put_Nikon_InternalFlashMode },
9431 	{ N_("Flash Commander Mode"),           "flashcommandermode",       PTP_DPC_NIKON_FlashCommanderMode,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommanderMode,      _put_Nikon_FlashCommanderMode },
9432 	{ N_("Flash Commander Power"),          "flashcommanderpower",      PTP_DPC_NIKON_FlashModeCommanderPower,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommanderPower,     _put_Nikon_FlashCommanderPower },
9433 	{ N_("Flash Command Channel"),          "flashcommandchannel",      PTP_DPC_NIKON_FlashCommandChannel,      PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandChannel,     _put_Nikon_FlashCommandChannel },
9434 	{ N_("Flash Command Self Mode"),        "flashcommandselfmode",     PTP_DPC_NIKON_FlashCommandSelfMode,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandSelfMode,    _put_Nikon_FlashCommandSelfMode },
9435 	{ N_("Flash Command Self Compensation"), "flashcommandselfcompensation", PTP_DPC_NIKON_FlashCommandSelfCompensation, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_FlashCommandXCompensation, _put_Nikon_FlashCommandXCompensation },
9436 	{ N_("Flash Command Self Value"),       "flashcommandselfvalue",    PTP_DPC_NIKON_FlashCommandSelfValue,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandXValue,      _put_Nikon_FlashCommandXValue },
9437 	{ N_("Flash Command A Mode"),           "flashcommandamode",        PTP_DPC_NIKON_FlashCommandAMode,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandXMode,       _put_Nikon_FlashCommandXMode },
9438 	{ N_("Flash Command A Compensation"),   "flashcommandacompensation", PTP_DPC_NIKON_FlashCommandACompensation, PTP_VENDOR_NIKON, PTP_DTC_UINT8,  _get_Nikon_FlashCommandXCompensation, _put_Nikon_FlashCommandXCompensation },
9439 	{ N_("Flash Command A Value"),          "flashcommandavalue",       PTP_DPC_NIKON_FlashCommandAValue,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandXValue,      _put_Nikon_FlashCommandXValue },
9440 	{ N_("Flash Command B Mode"),           "flashcommandbmode",        PTP_DPC_NIKON_FlashCommandBMode,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandXMode,       _put_Nikon_FlashCommandXMode },
9441 	{ N_("Flash Command B Compensation"),   "flashcommandbcompensation", PTP_DPC_NIKON_FlashCommandBCompensation, PTP_VENDOR_NIKON, PTP_DTC_UINT8,  _get_Nikon_FlashCommandXCompensation, _put_Nikon_FlashCommandXCompensation },
9442 	{ N_("Flash Command B Value"),          "flashcommandbvalue",       PTP_DPC_NIKON_FlashCommandBValue,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashCommandXValue,      _put_Nikon_FlashCommandXValue },
9443 	{ N_("AF Area Illumination"),           "af-area-illumination",     PTP_DPC_NIKON_AFAreaIllumination,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_AFAreaIllum,             _put_Nikon_AFAreaIllum },
9444 	{ N_("AF Beep Mode"),                   "afbeep",                   PTP_DPC_NIKON_BeepOff,                  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,             _put_Nikon_OffOn_UINT8 },
9445 	{ N_("F-Number"),                       "f-number",                 PTP_DPC_FNumber,                        PTP_VENDOR_SONY,    PTP_DTC_UINT16, _get_FNumber,                       _put_Sony_FNumber },
9446 	{ N_("F-Number"),                       "f-number",                 PTP_DPC_SONY_QX_Aperture,               PTP_VENDOR_SONY,    PTP_DTC_UINT16, _get_FNumber,                       _put_Sony_QX_FNumber },
9447 	{ N_("F-Number"),                       "f-number",                 PTP_DPC_FNumber,                        0,                  PTP_DTC_UINT16, _get_FNumber,                       _put_FNumber },
9448 	{ N_("F-Number"),			"f-number",		    0,					    PTP_VENDOR_PANASONIC,PTP_DTC_INT32, _get_Panasonic_FNumber,             _put_Panasonic_FNumber },
9449 	{ N_("Movie F-Number"),                 "movief-number",            PTP_DPC_NIKON_MovieFNumber,             PTP_VENDOR_NIKON,   PTP_DTC_UINT16, _get_FNumber,                       _put_FNumber },
9450 	{ N_("Flexible Program"),               "flexibleprogram",          PTP_DPC_NIKON_FlexibleProgram,          PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Range_INT8,                    _put_Range_INT8 },
9451 	{ N_("Image Quality"),                  "imagequality",             PTP_DPC_CompressionSetting,             PTP_VENDOR_SONY,    PTP_DTC_UINT8,  _get_CompressionSetting,            _put_Sony_CompressionSetting },
9452 	{ N_("Image Quality"),                  "imagequality",             PTP_DPC_CompressionSetting,             0,                  PTP_DTC_UINT8,  _get_CompressionSetting,            _put_CompressionSetting },
9453 	{ N_("Focus Distance"),                 "focusdistance",            PTP_DPC_FocusDistance,                  0,                  PTP_DTC_UINT16, _get_FocusDistance,                 _put_FocusDistance },
9454 	{ N_("Focal Length"),                   "focallength",              PTP_DPC_FocalLength,                    0,                  PTP_DTC_UINT32, _get_FocalLength,                   _put_FocalLength },
9455 	{ N_("Focus Mode"),                     "focusmode",                PTP_DPC_FocusMode,                      PTP_VENDOR_SONY,    PTP_DTC_UINT16, _get_FocusMode,                     _put_Sony_FocusMode },
9456 	{ N_("Focus Mode"),                     "focusmode",                PTP_DPC_FocusMode,                      0,                  PTP_DTC_UINT16, _get_FocusMode,                     _put_FocusMode },
9457 	{ N_("Focus Mode"),                     "focusmode",                PTP_DPC_OLYMPUS_FocusMode,              PTP_VENDOR_GP_OLYMPUS_OMD,  PTP_DTC_UINT16, _get_FocusMode,             _put_FocusMode },
9458 	/* Nikon DSLR have both PTP focus mode and Nikon specific focus mode */
9459 	{ N_("Focus Mode 2"),                   "focusmode2",               PTP_DPC_NIKON_AutofocusMode,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_AFMode,                  _put_Nikon_AFMode },
9460 	{ N_("Focus Mode"),                     "focusmode",                PTP_DPC_CANON_EOS_FocusMode,            PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_FocusMode,           _put_Canon_EOS_FocusMode },
9461 	{ N_("Continuous AF"),                  "continuousaf",             PTP_DPC_CANON_EOS_ContinousAFMode,      PTP_VENDOR_CANON,   PTP_DTC_UINT32, _get_Canon_EOS_ContinousAF,         _put_Canon_EOS_ContinousAF },
9462 	{ N_("Effect Mode"),                    "effectmode",               PTP_DPC_EffectMode,                     0,                  PTP_DTC_UINT16, _get_EffectMode,                    _put_EffectMode },
9463 	{ N_("Effect Mode"),                    "effectmode",               PTP_DPC_NIKON_EffectMode,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_NIKON_EffectMode,              _put_NIKON_EffectMode },
9464 	{ N_("Exposure Program"),               "expprogram",               PTP_DPC_ExposureProgramMode,            0,                  PTP_DTC_UINT16, _get_ExposureProgram,               _put_ExposureProgram },
9465 	{ N_("Exposure Program"),               "expprogram2",              PTP_DPC_NIKON_1_Mode,                   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_NIKON_1_ExposureProgram,       _put_NIKON_1_ExposureProgram },
9466 	{ N_("Scene Mode"),                     "scenemode",                PTP_DPC_NIKON_SceneMode,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_NIKON_SceneMode,               _put_NIKON_SceneMode },
9467 	{ N_("Aspect Ratio"),                   "aspectratio",              PTP_DPC_SONY_AspectRatio,               PTP_VENDOR_SONY,    PTP_DTC_UINT8,  _get_Sony_AspectRatio,              _put_Sony_AspectRatio },
9468 	{ N_("Aspect Ratio"),                   "aspectratio",              PTP_DPC_OLYMPUS_AspectRatio,            PTP_VENDOR_GP_OLYMPUS_OMD, PTP_DTC_UINT32,  _get_Olympus_AspectRatio,   _put_Olympus_AspectRatio },
9469 	{ N_("Aspect Ratio"),                   "aspectratio",              PTP_DPC_CANON_EOS_MultiAspect,          PTP_VENDOR_CANON,   PTP_DTC_UINT32,  _get_Canon_EOS_AspectRatio,        _put_Canon_EOS_AspectRatio },
9470 	{ N_("Storage Device"),                 "storageid",                PTP_DPC_CANON_EOS_CurrentStorage,       PTP_VENDOR_CANON,   PTP_DTC_UINT32,  _get_Canon_EOS_StorageID  ,        _put_Canon_EOS_StorageID },
9471 	{ N_("High ISO Noise Reduction"),       "highisonr",		    PTP_DPC_CANON_EOS_HighISOSettingNoiseReduction, PTP_VENDOR_CANON, PTP_DTC_UINT16, _get_Canon_EOS_HighIsoNr,     _put_Canon_EOS_HighIsoNr },
9472 	{ N_("HDR Mode"),                       "hdrmode",                  PTP_DPC_NIKON_HDRMode,                  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9473 	{ N_("HDR High Dynamic"),               "hdrhighdynamic",           PTP_DPC_NIKON_HDRHighDynamic,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_HDRHighDynamic,          _put_Nikon_HDRHighDynamic },
9474 	{ N_("HDR Smoothing"),                  "hdrsmoothing",             PTP_DPC_NIKON_HDRSmoothing,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_HDRSmoothing,            _put_Nikon_HDRSmoothing },
9475 	{ N_("Still Capture Mode"),             "capturemode",              PTP_DPC_StillCaptureMode,               0,                  PTP_DTC_UINT16, _get_CaptureMode,                   _put_CaptureMode },
9476 	{ N_("Still Capture Mode"),             "capturemode",              PTP_DPC_FUJI_ReleaseMode,               PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_Fuji_ReleaseMode,              _put_Fuji_ReleaseMode },
9477 	{ N_("Canon Shooting Mode"),            "shootingmode",             PTP_DPC_CANON_ShootingMode,             PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_ShootMode,               _put_Canon_ShootMode },
9478 	{ N_("Canon Auto Exposure Mode"),       "autoexposuremode",         PTP_DPC_CANON_EOS_AutoExposureMode,     PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_AutoExposureMode,    _put_Canon_EOS_AutoExposureMode },
9479 	{ N_("Drive Mode"),                     "drivemode",                PTP_DPC_CANON_EOS_DriveMode,            PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_DriveMode,           _put_Canon_EOS_DriveMode },
9480 	{ N_("Picture Style"),                  "picturestyle",             PTP_DPC_CANON_EOS_PictureStyle,         PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_EOS_PictureStyle,        _put_Canon_EOS_PictureStyle },
9481 	{ N_("Focus Metering Mode"),            "focusmetermode",           PTP_DPC_FocusMeteringMode,              0,                  PTP_DTC_UINT16, _get_FocusMetering,                 _put_FocusMetering },
9482 	{ N_("Focus Metering Mode"),            "exposuremetermode",        PTP_DPC_OLYMPUS_ExposureMeteringMode,   PTP_VENDOR_GP_OLYMPUS_OMD, PTP_DTC_UINT16, _get_ExposureMetering,       _put_ExposureMetering },
9483 	{ N_("Exposure Metering Mode"),         "exposuremetermode",        PTP_DPC_ExposureMeteringMode,           0,                  PTP_DTC_UINT16, _get_ExposureMetering,              _put_ExposureMetering },
9484 	{ N_("Aperture"),                       "aperture",                 PTP_DPC_OLYMPUS_Aperture,               PTP_VENDOR_GP_OLYMPUS_OMD,   PTP_DTC_UINT16, _get_Olympus_Aperture,     _put_Olympus_Aperture },
9485 	{ N_("Aperture"),                       "aperture",                 PTP_DPC_CANON_Aperture,                 PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_Aperture,                _put_Canon_Aperture },
9486 	{ N_("Aperture"),                       "aperture",                 PTP_DPC_FUJI_Aperture,                  PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_Fuji_Aperture,                 _put_Fuji_Aperture },
9487 	{ N_("AV Open"),                        "avopen",                   PTP_DPC_CANON_AvOpen,                   PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_Aperture,                _put_Canon_Aperture },
9488 	{ N_("AV Max"),                         "avmax",                    PTP_DPC_CANON_AvMax,                    PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_Aperture,                _put_Canon_Aperture },
9489 	{ N_("Aperture"),                       "aperture",                 PTP_DPC_CANON_EOS_Aperture,             PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_Aperture,                _put_Canon_Aperture },
9490 	{ N_("Aperture"),                       "aperture",                 PTP_DPC_NIKON_1_FNumber,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_Aperture,              _put_Nikon_1_Aperture },
9491 	{ N_("Shutterspeed"),                   "shutterspeed2",            PTP_DPC_NIKON_1_ShutterSpeed,           PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_1_ShutterSpeedI,         _put_Nikon_1_ShutterSpeedI },
9492 	{ N_("Shutterspeed"),                   "shutterspeed2",            PTP_DPC_NIKON_1_ShutterSpeed,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_ShutterSpeedU,         _put_Nikon_1_ShutterSpeedU },
9493 	{ N_("Aperture 2"),                     "aperture2",                PTP_DPC_NIKON_1_FNumber2,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_Aperture,              _put_Nikon_1_Aperture },
9494 	{ N_("Focusing Point"),                 "focusingpoint",            PTP_DPC_CANON_FocusingPoint,            PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_FocusingPoint,           _put_Canon_FocusingPoint },
9495 	{ N_("Sharpness"),                      "sharpness",                PTP_DPC_Sharpness,                      0,                  PTP_DTC_UINT8,  _get_Sharpness,                     _put_Sharpness },
9496 	{ N_("Capture Delay"),                  "capturedelay",             PTP_DPC_CaptureDelay,                   0,                  PTP_DTC_UINT32, _get_Milliseconds,                  _put_Milliseconds },
9497 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_ExposureTime,		    PTP_VENDOR_FUJI,    PTP_DTC_UINT32,	_get_Fuji_New_ShutterSpeed,	    _put_Fuji_New_ShutterSpeed },
9498 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_ExposureTime,                   0,                  PTP_DTC_UINT32, _get_ExpTime,                       _put_ExpTime },
9499 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_CANON_ShutterSpeed,             PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_ShutterSpeed,            _put_Canon_ShutterSpeed },
9500 	{ N_("Shutter Speed"),                  "shutterspeed",             0,						PTP_VENDOR_PANASONIC,   PTP_DTC_INT32, _get_Panasonic_Shutter,         _put_Panasonic_Shutter },
9501 	/* these cameras also have PTP_DPC_ExposureTime, avoid overlap */
9502 	{ N_("Shutter Speed 2"),                "shutterspeed2",            PTP_DPC_NIKON_ExposureTime,             PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_ShutterSpeed,            _put_Nikon_ShutterSpeed },
9503 	{ N_("Movie Shutter Speed 2"),          "movieshutterspeed",        PTP_DPC_NIKON_MovieShutterSpeed,        PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_ShutterSpeed,            _put_Nikon_ShutterSpeed },
9504 	/* olympus uses also a 16 bit/16bit separation */
9505 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_OLYMPUS_Shutterspeed,           PTP_VENDOR_GP_OLYMPUS_OMD,   PTP_DTC_UINT32, _get_Olympus_ShutterSpeed, _put_Olympus_ShutterSpeed },
9506 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_CANON_EOS_ShutterSpeed,         PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_ShutterSpeed,            _put_Canon_ShutterSpeed },
9507 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_FUJI_ShutterSpeed,              PTP_VENDOR_FUJI,    PTP_DTC_INT16,  _get_Fuji_ShutterSpeed,             _put_Fuji_ShutterSpeed },
9508 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_SONY_ShutterSpeed2,             PTP_VENDOR_SONY,    PTP_DTC_UINT32,  _get_Sony_ShutterSpeed,             _put_Sony_ShutterSpeed },
9509 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_SONY_ShutterSpeed,              PTP_VENDOR_SONY,    PTP_DTC_UINT32,  _get_Sony_ShutterSpeed,             _put_Sony_ShutterSpeed },
9510 	{ N_("Shutter Speed"),                  "shutterspeed",             PTP_DPC_RICOH_ShutterSpeed,             PTP_VENDOR_PENTAX,  PTP_DTC_UINT64, _get_Ricoh_ShutterSpeed,            _put_Ricoh_ShutterSpeed },
9511 	{ N_("Metering Mode"),                  "meteringmode",             PTP_DPC_CANON_MeteringMode,             PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_MeteringMode,            _put_Canon_MeteringMode },
9512 	{ N_("Metering Mode"),                  "meteringmode",             PTP_DPC_CANON_EOS_MeteringMode,         PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_MeteringMode,            _put_Canon_MeteringMode },
9513 	{ N_("AF Distance"),                    "afdistance",               PTP_DPC_CANON_AFDistance,               PTP_VENDOR_CANON,   PTP_DTC_UINT8,  _get_Canon_AFDistance,              _put_Canon_AFDistance },
9514 	{ N_("Focus Area Wrap"),                "focusareawrap",            PTP_DPC_NIKON_FocusAreaWrap,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9515 	{ N_("Exposure Delay Mode"),            "exposuredelaymode",        PTP_DPC_NIKON_ExposureDelayMode,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9516 	{ N_("Exposure Lock"),                  "exposurelock",             PTP_DPC_NIKON_AELockMode,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9517 	{ N_("AE-L/AF-L Mode"),                 "aelaflmode",               PTP_DPC_NIKON_AELAFLMode,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_AELAFLMode,              _put_Nikon_AELAFLMode },
9518 	{ N_("Live View AF Mode"),              "liveviewafmode",           PTP_DPC_NIKON_LiveViewAFArea,           PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_LiveViewAFI,             _put_Nikon_LiveViewAFI },
9519 	{ N_("Live View AF Mode"),              "liveviewafmode",           PTP_DPC_NIKON_LiveViewAFArea,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LiveViewAFU,             _put_Nikon_LiveViewAFU },
9520 	{ N_("Live View AF Focus"),             "liveviewaffocus",          PTP_DPC_NIKON_LiveViewAFFocus,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LiveViewAFFocus,         _put_Nikon_LiveViewAFFocus },
9521 	{ N_("Live View Exposure Preview"),     "liveviewexposurepreview",  PTP_DPC_NIKON_LiveViewExposurePreview,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,             _put_Nikon_OffOn_UINT8 },
9522 	{ N_("Live View Image Zoom Ratio"),     "liveviewimagezoomratio",   PTP_DPC_NIKON_LiveViewImageZoomRatio,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LiveViewImageZoomRatio,  _put_Nikon_LiveViewImageZoomRatio },
9523 	{ N_("Live View White Balance"),        "liveviewwhitebalance",     PTP_DPC_NIKON_LiveViewWhiteBalance,     PTP_VENDOR_NIKON,   PTP_DTC_UINT16, _get_WhiteBalance,                  _put_WhiteBalance },
9524 	{ N_("Live View Size"),                 "liveviewsize",             PTP_DPC_FUJI_LiveViewImageSize,         PTP_VENDOR_FUJI,    PTP_DTC_UINT16, _get_Fuji_LiveViewSize,             _put_Fuji_LiveViewSize },
9525 	{ N_("Live View Size"),                 "liveviewsize",             PTP_DPC_SONY_QX_LiveviewResolution,     PTP_VENDOR_SONY,    PTP_DTC_UINT8,  _get_Sony_QX_LiveViewSize,          _put_Sony_QX_LiveViewSize },
9526 	{ N_("File Number Sequencing"),         "filenrsequencing",         PTP_DPC_NIKON_FileNumberSequence,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9527 	{ N_("Flash Sign"),                     "flashsign",                PTP_DPC_NIKON_FlashSign,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9528 	{ N_("Modelling Flash"),                "modelflash",               PTP_DPC_NIKON_E4ModelingFlash,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,             _put_Nikon_OffOn_UINT8 },
9529 	{ N_("Viewfinder Grid"),                "viewfindergrid",           PTP_DPC_NIKON_GridDisplay,              PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9530 	{ N_("Image Review"),                   "imagereview",              PTP_DPC_NIKON_ImageReview,              PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9531 	{ N_("Image Rotation Flag"),            "imagerotationflag",        PTP_DPC_NIKON_ImageRotation,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9532 	{ N_("Release without CF card"),        "nocfcardrelease",          PTP_DPC_NIKON_NoCFCard,                 PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9533 	{ N_("Flash Mode Manual Power"),        "flashmodemanualpower",     PTP_DPC_NIKON_FlashModeManualPower,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashModeManualPower,    _put_Nikon_FlashModeManualPower },
9534 	{ N_("Auto Focus Area"),                "autofocusarea",            PTP_DPC_NIKON_AutofocusArea,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_AutofocusArea,           _put_Nikon_AutofocusArea },
9535 	{ N_("Flash Exposure Compensation"),    "flashexposurecompensation", PTP_DPC_NIKON_FlashExposureCompensation, PTP_VENDOR_NIKON, PTP_DTC_INT8,   _get_Nikon_FlashExposureCompensation, _put_Nikon_FlashExposureCompensation },
9536 	{ N_("Bracketing"),                     "bracketing",               PTP_DPC_NIKON_Bracketing,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9537 	{ N_("Bracketing"),                     "bracketmode",              PTP_DPC_NIKON_E6ManualModeBracketing,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_ManualBracketMode,       _put_Nikon_ManualBracketMode },
9538 	{ N_("Bracket Mode"),                   "bracketmode",              PTP_DPC_CANON_EOS_BracketMode,          PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_BracketMode,             _put_Canon_BracketMode },
9539 	{ N_("EV Step"),                        "evstep",                   PTP_DPC_NIKON_EVStep,                   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_EVStep,                  _put_Nikon_EVStep },
9540 	{ N_("Bracket Set"),                    "bracketset",               PTP_DPC_NIKON_BracketSet,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_BracketSet,              _put_Nikon_BracketSet },
9541 	{ N_("Bracket Order"),                  "bracketorder",             PTP_DPC_NIKON_BracketOrder,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_BracketOrder,            _put_Nikon_BracketOrder },
9542 	{ N_("AE Bracketing Step"),             "aebracketingstep",         PTP_DPC_NIKON_AutoExposureBracketStep,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_AEBracketStep,           _put_Nikon_AEBracketStep },
9543 	{ N_("WB Bracketing Step"),             "wbbracketingstep",         PTP_DPC_NIKON_WhiteBalanceBracketStep,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_WBBracketStep,           _put_Nikon_WBBracketStep },
9544 	{ N_("AE Bracketing Pattern"),          "aebracketingpattern",      PTP_DPC_NIKON_AutoExposureBracketProgram,PTP_VENDOR_NIKON,	PTP_DTC_UINT8,  _get_Nikon_BracketPattern,          _put_Nikon_BracketPattern },
9545 	{ N_("WB Bracketing Pattern"),          "wbbracketingpattern",      PTP_DPC_NIKON_WhiteBalanceBracketProgram,PTP_VENDOR_NIKON,	PTP_DTC_UINT8,  _get_Nikon_BracketPattern,          _put_Nikon_BracketPattern },
9546 	{ N_("AE Bracketing Count"),            "aebracketingcount",        PTP_DPC_NIKON_AutoExposureBracketCount, PTP_VENDOR_NIKON,	PTP_DTC_UINT8,  _get_INT,          		    _put_None },
9547 	{ N_("ADL Bracketing Pattern"),         "adlbracketingpattern",     PTP_DPC_NIKON_ADLBracketingPattern,	    PTP_VENDOR_NIKON,	PTP_DTC_UINT8,  _get_Nikon_ADLBracketPattern,       _put_Nikon_ADLBracketPattern },
9548 	{ N_("ADL Bracketing Step"),            "adlbracketingstep",        PTP_DPC_NIKON_ADLBracketingStep,	    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_ADLBracketStep,          _put_Nikon_ADLBracketStep },
9549 	{ N_("WB Preset Comment 1"),		"wbpresetcomment1",	    PTP_DPC_NIKON_WhiteBalancePresetName1,  PTP_VENDOR_NIKON,   PTP_DTC_STR,	_get_STR,          		    _put_STR },
9550 	{ N_("WB Preset Comment 2"),		"wbpresetcomment2",	    PTP_DPC_NIKON_WhiteBalancePresetName2,  PTP_VENDOR_NIKON,   PTP_DTC_STR,	_get_STR,          		    _put_STR },
9551 	{ N_("WB Preset Comment 3"),		"wbpresetcomment3",	    PTP_DPC_NIKON_WhiteBalancePresetName3,  PTP_VENDOR_NIKON,   PTP_DTC_STR,	_get_STR,          		    _put_STR },
9552 	{ N_("WB Preset Comment 4"),		"wbpresetcomment4",	    PTP_DPC_NIKON_WhiteBalancePresetName4,  PTP_VENDOR_NIKON,   PTP_DTC_STR,	_get_STR,          		    _put_STR },
9553 	{ N_("WB Preset Comment 5"),		"wbpresetcomment5",	    PTP_DPC_NIKON_WhiteBalancePresetName5,  PTP_VENDOR_NIKON,   PTP_DTC_STR,	_get_STR,          		    _put_STR },
9554 	{ N_("WB Preset Comment 6"),		"wbpresetcomment6",	    PTP_DPC_NIKON_WhiteBalancePresetName6,  PTP_VENDOR_NIKON,   PTP_DTC_STR,	_get_STR,          		    _put_STR },
9555 	{ N_("Burst Number"),                   "burstnumber",              PTP_DPC_BurstNumber,                    0,                  PTP_DTC_UINT16, _get_INT,                           _put_INT },
9556 	{ N_("Burst Interval"),                 "burstinterval",            PTP_DPC_BurstInterval,                  0,                  PTP_DTC_UINT16, _get_Milliseconds,                  _put_Milliseconds },
9557 	{ N_("Maximum Shots"),                  "maximumshots",             PTP_DPC_NIKON_MaximumShots,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_INT,                           _put_None },
9558 
9559 	/* Newer Nikons have UINT8 ranges */
9560 	{ N_("Auto White Balance Bias"),        "autowhitebias",            PTP_DPC_NIKON_WhiteBalanceAutoBias,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9561 	{ N_("Tungsten White Balance Bias"),    "tungstenwhitebias",        PTP_DPC_NIKON_WhiteBalanceTungstenBias, PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9562 	{ N_("Fluorescent White Balance Bias"), "flourescentwhitebias",     PTP_DPC_NIKON_WhiteBalanceFluorescentBias, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9563 	{ N_("Daylight White Balance Bias"),    "daylightwhitebias",        PTP_DPC_NIKON_WhiteBalanceDaylightBias, PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9564 	{ N_("Flash White Balance Bias"),       "flashwhitebias",           PTP_DPC_NIKON_WhiteBalanceFlashBias,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9565 	{ N_("Cloudy White Balance Bias"),      "cloudywhitebias",          PTP_DPC_NIKON_WhiteBalanceCloudyBias,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9566 	{ N_("Shady White Balance Bias"),       "shadewhitebias",           PTP_DPC_NIKON_WhiteBalanceShadeBias,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_UWBBias,                 _put_Nikon_UWBBias },
9567 	{ N_("Natural light auto White Balance Bias"),	"naturallightautowhitebias",	PTP_DPC_NIKON_WhiteBalanceNaturalLightAutoBias,    PTP_VENDOR_NIKON,   PTP_DTC_UINT16,  _get_Nikon_UWBBias,	_put_Nikon_UWBBias },
9568 	/* older Nikons have INT8 ranges */
9569 	{ N_("Auto White Balance Bias"),        "autowhitebias",            PTP_DPC_NIKON_WhiteBalanceAutoBias,     PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9570 	{ N_("Tungsten White Balance Bias"),    "tungstenwhitebias",        PTP_DPC_NIKON_WhiteBalanceTungstenBias, PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9571 	{ N_("Fluorescent White Balance Bias"), "flourescentwhitebias",     PTP_DPC_NIKON_WhiteBalanceFluorescentBias, PTP_VENDOR_NIKON, PTP_DTC_INT8,  _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9572 	{ N_("Daylight White Balance Bias"),    "daylightwhitebias",        PTP_DPC_NIKON_WhiteBalanceDaylightBias, PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9573 	{ N_("Flash White Balance Bias"),       "flashwhitebias",           PTP_DPC_NIKON_WhiteBalanceFlashBias,    PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9574 	{ N_("Cloudy White Balance Bias"),      "cloudywhitebias",          PTP_DPC_NIKON_WhiteBalanceCloudyBias,   PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9575 	{ N_("Shady White Balance Bias"),       "shadewhitebias",           PTP_DPC_NIKON_WhiteBalanceShadeBias,    PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_WBBias,                  _put_Nikon_WBBias },
9576 
9577 	{ N_("White Balance Bias Preset Nr"),   "whitebiaspresetno",        PTP_DPC_NIKON_WhiteBalancePresetNo,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_WBBiasPreset,            _put_Nikon_WBBiasPreset },
9578 	{ N_("White Balance Bias Preset 0"),    "whitebiaspreset0",         PTP_DPC_NIKON_WhiteBalancePresetVal0,   PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_WBBiasPresetVal,         _put_None },
9579 	{ N_("White Balance Bias Preset 1"),    "whitebiaspreset1",         PTP_DPC_NIKON_WhiteBalancePresetVal1,   PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_WBBiasPresetVal,         _put_None },
9580 	{ N_("White Balance Bias Preset 2"),    "whitebiaspreset2",         PTP_DPC_NIKON_WhiteBalancePresetVal2,   PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_WBBiasPresetVal,         _put_None },
9581 	{ N_("White Balance Bias Preset 3"),    "whitebiaspreset3",         PTP_DPC_NIKON_WhiteBalancePresetVal3,   PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_WBBiasPresetVal,         _put_None },
9582 	{ N_("White Balance Bias Preset 4"),    "whitebiaspreset4",         PTP_DPC_NIKON_WhiteBalancePresetVal4,   PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_WBBiasPresetVal,         _put_None },
9583 	{ N_("Selftimer Delay"),                "selftimerdelay",           PTP_DPC_NIKON_SelfTimer,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_SelfTimerDelay,          _put_Nikon_SelfTimerDelay },
9584 	{ N_("Center Weight Area"),             "centerweightsize",         PTP_DPC_NIKON_CenterWeightArea,         PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_CenterWeight,            _put_Nikon_CenterWeight },
9585 	{ N_("Flash Shutter Speed"),            "flashshutterspeed",        PTP_DPC_NIKON_FlashShutterSpeed,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FlashShutterSpeed,       _put_Nikon_FlashShutterSpeed },
9586 	{ N_("Remote Timeout"),                 "remotetimeout",            PTP_DPC_NIKON_RemoteTimeout,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_RemoteTimeout,           _put_Nikon_RemoteTimeout },
9587 	{ N_("Remote Mode"),                    "remotemode",               PTP_DPC_NIKON_RemoteMode,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_RemoteMode,              _put_Nikon_RemoteMode },
9588 	{ N_("Application Mode"),               "applicationmode",          PTP_DPC_NIKON_ApplicationMode,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_ApplicationMode,         _put_Nikon_ApplicationMode },
9589 	{ N_("Optimize Image"),                 "optimizeimage",            PTP_DPC_NIKON_OptimizeImage,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OptimizeImage,           _put_Nikon_OptimizeImage },
9590 	{ N_("Sharpening"),                     "sharpening",               PTP_DPC_NIKON_ImageSharpening,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_Sharpening,              _put_Nikon_Sharpening },
9591 	{ N_("Tone Compensation"),              "tonecompensation",         PTP_DPC_NIKON_ToneCompensation,         PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_ToneCompensation,        _put_Nikon_ToneCompensation },
9592 	{ N_("Saturation"),                     "saturation",               PTP_DPC_NIKON_Saturation,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_Saturation,              _put_Nikon_Saturation },
9593 	{ N_("Hue Adjustment"),                 "hueadjustment",            PTP_DPC_NIKON_HueAdjustment,            PTP_VENDOR_NIKON,   PTP_DTC_INT8,   _get_Nikon_HueAdjustment,           _put_Nikon_HueAdjustment },
9594 	{ N_("Auto Exposure Bracketing"),       "aeb",                      PTP_DPC_CANON_EOS_AEB,                  PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_AEB,                 _put_Canon_EOS_AEB },
9595 	{ N_("Auto Lighting Optimization"),     "alomode",                  PTP_DPC_CANON_EOS_AloMode,              PTP_VENDOR_CANON,   PTP_DTC_UINT16, _get_Canon_EOS_AloMode,             _put_Canon_EOS_AloMode },
9596 	{ N_("Movie Sound"),                    "moviesound",               PTP_DPC_NIKON_MovVoice,                 PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,             _put_Nikon_OffOn_UINT8 },
9597 	{ N_("Manual Movie Setting"),           "manualmoviesetting",       PTP_DPC_NIKON_ManualMovieSetting,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9598 	{ N_("Microphone"),                     "microphone",               PTP_DPC_NIKON_MovMicrophone,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_Microphone,              _put_Nikon_Microphone },
9599 	{ N_("Reverse Indicators"),             "reverseindicators",        PTP_DPC_NIKON_IndicatorDisp,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,             _put_Nikon_OffOn_UINT8 },
9600 	{ N_("Auto Distortion Control"),        "autodistortioncontrol",    PTP_DPC_NIKON_AutoDistortionControl,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OnOff_UINT8,             _put_Nikon_OnOff_UINT8 },
9601 	{ N_("Vignette Correction"),            "vignettecorrection",       PTP_DPC_NIKON_VignetteCtrl,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_VignetteCorrection,      _put_Nikon_VignetteCorrection },
9602 	{ N_("Video Mode"),                     "videomode",                PTP_DPC_NIKON_VideoMode,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_VideoMode,               _put_Nikon_VideoMode },
9603 	{ N_("Sensor Crop"),                    "sensorcrop",               PTP_DPC_SONY_SensorCrop,                PTP_VENDOR_SONY,    PTP_DTC_UINT8,  _get_Sony_SensorCrop,               _put_Sony_SensorCrop },
9604 	{ N_("HDMI Output Data Depth"),         "hdmioutputdatadepth",      PTP_DPC_NIKON_HDMIOutputDataDepth,      PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_HDMIDataDepth,           _put_Nikon_HDMIDataDepth },
9605 	{ N_("Face Detection"),                 "facedetection",            PTP_DPC_NIKON_FaceDetection,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_FaceDetection,           _put_Nikon_FaceDetection },
9606 
9607 	{ 0,0,0,0,0,0,0 },
9608 };
9609 
9610 /* Nikon camera specific values, as unfortunately the values are handled differently
9611  * A generic fallback for the "rest" of the Nikons is in the main menu.
9612  */
9613 static struct submenu nikon_1_j3_camera_settings[] = {
9614 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_NIKON_1_ISO,                    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_J3_ISO,            _put_Nikon_1_J3_ISO },
9615 	{ 0,0,0,0,0,0,0 },
9616 };
9617 static struct submenu nikon_1_s1_camera_settings[] = {
9618 	{ N_("ISO Speed"),              "iso",                  PTP_DPC_NIKON_1_ISO,                    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_S1_ISO,            _put_Nikon_1_S1_ISO },
9619 	{ 0,0,0,0,0,0,0 },
9620 };
9621 /* Nikon D90. Marcus Meissner <marcus@jet.franken.de> */
9622 static struct submenu nikon_d90_camera_settings[] = {
9623 	{ N_("Meter Off Time"),         "meterofftime",         PTP_DPC_NIKON_MeterOff,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_MeterOffTime,        _put_Nikon_D90_MeterOffTime },
9624 	{ 0,0,0,0,0,0,0 },
9625 };
9626 
9627 /* Nikon D7000. Marcus Meissner <marcus@jet.franken.de> */
9628 static struct submenu nikon_d7000_camera_settings[] = {
9629 	{ N_("Assign Func Button"),     "funcbutton",           PTP_DPC_NIKON_F4AssignFuncButton,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7000_FuncButton,        _put_Nikon_D7000_FuncButton },
9630 	{ N_("Assign Preview Button"),  "previewbutton",        PTP_DPC_NIKON_PreviewButton,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7000_FuncButton,        _put_Nikon_D7000_FuncButton },
9631 	{ 0,0,0,0,0,0,0 },
9632 };
9633 
9634 /* Nikon D7100. Daniel Wagenaar <wagenadl@uc.edu> */
9635 static struct submenu nikon_d7100_camera_settings[] = {
9636 	{ N_("Assign Func Button"),     "funcbutton",           PTP_DPC_NIKON_F4AssignFuncButton,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7000_FuncButton,        _put_Nikon_D7000_FuncButton },
9637 	{ N_("Assign Preview Button"),  "previewbutton",        PTP_DPC_NIKON_PreviewButton,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7000_FuncButton,        _put_Nikon_D7000_FuncButton },
9638 	{ 0,0,0,0,0,0,0 },
9639 };
9640 
9641 static struct submenu nikon_d40_capture_settings[] = {
9642 	{ N_("Image Quality"),          "imagequality",         PTP_DPC_CompressionSetting,         PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D40_Compression,         _put_Nikon_D40_Compression },
9643 	{ 0,0,0,0,0,0,0 },
9644 };
9645 
9646 static struct submenu nikon_d850_capture_settings[] = {
9647 	{ N_("Image Quality"),          	"imagequality",			PTP_DPC_CompressionSetting,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D850_Compression,       _put_Nikon_D850_Compression },
9648 	{ N_("Image Rotation Flag"),            "imagerotationflag",    PTP_DPC_NIKON_ImageRotation,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_OffOn_UINT8,            _put_Nikon_OffOn_UINT8 },
9649 	{ N_("Active D-Lighting"),              "dlighting",            PTP_DPC_NIKON_ActiveDLighting,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,   _get_Nikon_D850_ActiveDLighting,   _put_Nikon_D850_ActiveDLighting },
9650 	{ N_("Continuous Shooting Speed Slow"), "shootingspeed",        PTP_DPC_NIKON_D1ShootingSpeed,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D850_ShootingSpeed,     _put_Nikon_D850_ShootingSpeed },
9651 	{ N_("Movie Resolution"),               "moviequality",         PTP_DPC_NIKON_MovScreenSize,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D850_MovieQuality,      _put_Nikon_D850_MovieQuality },
9652 	{ N_("Center Weight Area"),             "centerweightsize",     PTP_DPC_NIKON_CenterWeightArea, PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D850_CenterWeight,      _put_Nikon_D850_CenterWeight },
9653 	{ N_("Focus Metering Mode"),            "focusmetermode",       PTP_DPC_FocusMeteringMode,	PTP_VENDOR_NIKON,   PTP_DTC_UINT16, _get_Nikon_D850_FocusMetering,     _put_Nikon_D850_FocusMetering },
9654 	{ 0,0,0,0,0,0,0 },
9655 };
9656 
9657 static struct submenu nikon_d7500_capture_settings[] = {
9658 	{ N_("Image Quality"), "imagequality", PTP_DPC_CompressionSetting, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_D7500_Compression, _put_Nikon_D7500_Compression },
9659 	{ 0,0,0,0,0,0,0 },
9660 };
9661 
9662 /* D500 has the same list as the D850 */
9663 static struct submenu nikon_d500_capture_settings[] = {
9664 	{ N_("Image Quality"), "imagequality", PTP_DPC_CompressionSetting, PTP_VENDOR_NIKON, PTP_DTC_UINT8, _get_Nikon_D850_Compression, _put_Nikon_D850_Compression },
9665 	{ 0,0,0,0,0,0,0 },
9666 };
9667 
9668 static struct submenu nikon_z6_capture_settings[] = {
9669 	{ N_("Image Quality"),          	"imagequality",		PTP_DPC_CompressionSetting,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D850_Compression,	_put_Nikon_D850_Compression },
9670 	{ N_("Focus Metering Mode"),            "focusmetermode",       PTP_DPC_FocusMeteringMode,	PTP_VENDOR_NIKON,   PTP_DTC_UINT16, _get_Nikon_D850_FocusMetering,	_put_Nikon_D850_FocusMetering },
9671 	{ N_("Minimum Shutter Speed"),  	"minimumshutterspeed",  PTP_DPC_NIKON_PADVPMode,	PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_Z6_PADVPValue,		_put_Nikon_Z6_PADVPValue },
9672 	{ 0,0,0,0,0,0,0 },
9673 };
9674 
9675 static struct submenu nikon_d5100_capture_settings[] = {
9676 	{ N_("Movie Quality"),          "moviequality",         PTP_DPC_NIKON_MovScreenSize,        0,                  PTP_DTC_UINT8,  _get_Nikon_D5100_MovieQuality,      _put_Nikon_D5100_MovieQuality },
9677 	{ N_("Exposure Program"),       "expprogram",           PTP_DPC_ExposureProgramMode,        0,                  PTP_DTC_UINT16, _get_NIKON_D5100_ExposureProgram,   _put_NIKON_D5100_ExposureProgram },
9678 	{ N_("Minimum Shutter Speed"),  "minimumshutterspeed",  PTP_DPC_NIKON_PADVPMode,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_PADVPValue,          _put_Nikon_D90_PADVPValue },
9679 	{ 0,0,0,0,0,0,0 },
9680 };
9681 
9682 /* Nikon D7100. Daniel Wagenaar <wagenadl@uc.edu> */
9683 static struct submenu nikon_d7100_capture_settings[] = {
9684 	{ N_("Movie Resolution"),               "moviequality",         PTP_DPC_NIKON_MovScreenSize,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_MovieQuality,      _put_Nikon_D7100_MovieQuality },
9685 	{ N_("Movie Quality"),                  "moviequality2",        PTP_DPC_NIKON_MovQuality,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_MovieQuality2,     _put_Nikon_D7100_MovieQuality2 },
9686 	{ N_("Exposure Program"),               "expprogram",           PTP_DPC_ExposureProgramMode,    0,                  PTP_DTC_UINT16, _get_NIKON_D7100_ExposureProgram,   _put_NIKON_D7100_ExposureProgram },
9687 	{ N_("Minimum Shutter Speed"),          "minimumshutterspeed",  PTP_DPC_NIKON_PADVPMode,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_PADVPValue,        _put_Nikon_D7100_PADVPValue },
9688 	{ N_("Continuous Shooting Speed Slow"), "shootingspeed",        PTP_DPC_NIKON_D1ShootingSpeed,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_ShootingSpeed,     _put_Nikon_D7100_ShootingSpeed },
9689 	{ N_("ISO Auto Hi Limit"),              "isoautohilimit",       PTP_DPC_NIKON_ISOAutoHiLimit,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_ISOAutoHiLimit,    _put_Nikon_D7100_ISOAutoHiLimit },
9690 	{ N_("Flash Sync. Speed"),              "flashsyncspeed",       PTP_DPC_NIKON_FlashSyncSpeed,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_FlashSyncSpeed,    _put_Nikon_D7100_FlashSyncSpeed },
9691 	{ N_("Focus Metering"),                 "focusmetering",        PTP_DPC_FocusMeteringMode,      PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D7100_FocusMetering,     _put_Nikon_D7100_FocusMetering },
9692 	{ 0,0,0,0,0,0,0 },
9693 };
9694 static struct submenu nikon_d90_capture_settings[] = {
9695 	{ N_("Minimum Shutter Speed"),          "minimumshutterspeed",  PTP_DPC_NIKON_PADVPMode,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_PADVPValue,      _put_Nikon_D90_PADVPValue },
9696 	{ N_("ISO Auto Hi Limit"),              "isoautohilimit",       PTP_DPC_NIKON_ISOAutoHiLimit,   PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ISOAutoHiLimit,  _put_Nikon_D90_ISOAutoHiLimit },
9697 	{ N_("Active D-Lighting"),              "dlighting",            PTP_DPC_NIKON_ActiveDLighting,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ActiveDLighting, _put_Nikon_D90_ActiveDLighting },
9698 	{ N_("Image Quality"),                  "imagequality",         PTP_DPC_CompressionSetting,     PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_Compression,     _put_Nikon_D90_Compression },
9699 	{ N_("Continuous Shooting Speed Slow"), "shootingspeed",        PTP_DPC_NIKON_D1ShootingSpeed,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ShootingSpeed,   _put_Nikon_D90_ShootingSpeed },
9700 	{ 0,0,0,0,0,0,0 },
9701 };
9702 
9703 /* One D3s reporter is Matthias Blaicher */
9704 static struct submenu nikon_d3s_capture_settings[] = {
9705 	{ N_("Minimum Shutter Speed"),          "minimumshutterspeed",      PTP_DPC_NIKON_PADVPMode,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_PADVPValue,              _put_Nikon_D3s_PADVPValue },
9706 	{ N_("ISO Auto Hi Limit"),              "isoautohilimit",           PTP_DPC_NIKON_ISOAutoHiLimit,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_ISOAutoHiLimit,          _put_Nikon_D3s_ISOAutoHiLimit },
9707 	{ N_("Continuous Shooting Speed Slow"), "shootingspeed",            PTP_DPC_NIKON_D1ShootingSpeed,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_ShootingSpeed,           _put_Nikon_D3s_ShootingSpeed },
9708 	{ N_("Continuous Shooting Speed High"), "shootingspeedhigh",        PTP_DPC_NIKON_ContinuousSpeedHigh,      PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_ShootingSpeedHigh,       _put_Nikon_D3s_ShootingSpeedHigh },
9709 	{ N_("Flash Sync. Speed"),              "flashsyncspeed",           PTP_DPC_NIKON_FlashSyncSpeed,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_FlashSyncSpeed,          _put_Nikon_D3s_FlashSyncSpeed },
9710 	{ N_("Flash Shutter Speed"),            "flashshutterspeed",        PTP_DPC_NIKON_FlashShutterSpeed,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_FlashShutterSpeed,       _put_Nikon_D3s_FlashShutterSpeed },
9711 	{ N_("Image Quality"),                  "imagequality",             PTP_DPC_CompressionSetting,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_Compression,             _put_Nikon_D3s_Compression },
9712 	{ N_("JPEG Compression Policy"),        "jpegcompressionpolicy",    PTP_DPC_NIKON_JPEG_Compression_Policy,  PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_JPEGCompressionPolicy,   _put_Nikon_D3s_JPEGCompressionPolicy },
9713 	{ N_("AF-C Mode Priority"),             "afcmodepriority",          PTP_DPC_NIKON_A1AFCModePriority,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_AFCModePriority,         _put_Nikon_D3s_AFCModePriority },
9714 	{ N_("AF-S Mode Priority"),             "afsmodepriority",          PTP_DPC_NIKON_A2AFSModePriority,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_AFSModePriority,         _put_Nikon_D3s_AFSModePriority },
9715 	{ N_("AF Activation"),                  "afactivation",             PTP_DPC_NIKON_A4AFActivation,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_AFActivation,            _put_Nikon_D3s_AFActivation },
9716 	{ N_("Dynamic AF Area"),                "dynamicafarea",            PTP_DPC_NIKON_DynamicAFArea,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_DynamicAFArea,           _put_Nikon_D3s_DynamicAFArea },
9717 	{ N_("AF Lock On"),                     "aflockon",                 PTP_DPC_NIKON_AFLockOn,                 PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_AFLockOn,                _put_Nikon_D3s_AFLockOn },
9718 	{ N_("AF Area Point"),                  "afareapoint",              PTP_DPC_NIKON_AFAreaPoint,              PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_AFAreaPoint,             _put_Nikon_D3s_AFAreaPoint },
9719 	{ N_("AF On Button"),                   "afonbutton",               PTP_DPC_NIKON_NormalAFOn,               PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_NormalAFOn,              _put_Nikon_D3s_NormalAFOn },
9720 
9721 	/* same as D90 */
9722 	{ N_("Active D-Lighting"),              "dlighting",                PTP_DPC_NIKON_ActiveDLighting,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ActiveDLighting,         _put_Nikon_D90_ActiveDLighting },
9723 
9724 	{ 0,0,0,0,0,0,0 },
9725 };
9726 
9727 static struct submenu nikon_generic_capture_settings[] = {
9728 	/* filled in with D90 values */
9729 	{ N_("Minimum Shutter Speed"),          "minimumshutterspeed",      PTP_DPC_NIKON_PADVPMode,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_PADVPValue,          _put_Nikon_D90_PADVPValue },
9730 	{ N_("ISO Auto Hi Limit"),              "isoautohilimit",           PTP_DPC_NIKON_ISOAutoHiLimit,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ISOAutoHiLimit,      _put_Nikon_D90_ISOAutoHiLimit },
9731 	{ N_("Active D-Lighting"),              "dlighting",                PTP_DPC_NIKON_ActiveDLighting,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ActiveDLighting,     _put_Nikon_D90_ActiveDLighting },
9732 	{ N_("High ISO Noise Reduction"),       "highisonr",                PTP_DPC_NIKON_NrHighISO,                PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_HighISONR,           _put_Nikon_D90_HighISONR },
9733 	{ N_("Movie High ISO Noise Reduction"), "moviehighisonr",           PTP_DPC_NIKON_MovieNrHighISO,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_HighISONR,           _put_Nikon_D90_HighISONR },
9734 	{ N_("Continuous Shooting Speed Slow"), "shootingspeed",            PTP_DPC_NIKON_D1ShootingSpeed,          PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D90_ShootingSpeed,       _put_Nikon_D90_ShootingSpeed },
9735 	{ N_("Maximum continuous release"),     "maximumcontinousrelease",  PTP_DPC_NIKON_D2MaximumShots,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Range_UINT8,                   _put_Range_UINT8 },
9736 	{ N_("Movie Quality"),                  "moviequality",             PTP_DPC_NIKON_MovScreenSize,            PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_MovieQuality,            _put_Nikon_MovieQuality },
9737 	{ N_("Movie Quality"),                  "moviequality",             PTP_DPC_NIKON_1_MovQuality,             PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_MovieQuality,          _put_Nikon_1_MovieQuality },
9738 	{ N_("Movie Loop Length"),              "movielooplength",          PTP_DPC_NIKON_MovieLoopLength,          PTP_VENDOR_NIKON,   PTP_DTC_UINT32, _get_Nikon_MovieLoopLength,         _put_Nikon_MovieLoopLength },
9739 	{ N_("High ISO Noise Reduction"),       "highisonr",                PTP_DPC_NIKON_1_HiISONoiseReduction,    PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_HighISONR,             _put_Nikon_1_HighISONR },
9740 
9741 	{ N_("Raw Compression"),                "rawcompression",           PTP_DPC_NIKON_RawCompression,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_RawCompression,          _put_Nikon_RawCompression },
9742 
9743 	{ N_("Image Quality 2"),                "imagequality2",            PTP_DPC_NIKON_1_ImageCompression,       PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_1_Compression,           _put_Nikon_1_Compression },
9744 	{ N_("Image Quality"),                  "imagequality",             PTP_DPC_SONY_QX_CompressionSetting,     PTP_VENDOR_SONY,    PTP_DTC_UINT8,  _get_Sony_QX_Compression,           _put_Sony_QX_Compression },
9745 
9746 	/* And some D3s values */
9747 	{ N_("Continuous Shooting Speed High"), "shootingspeedhigh",        PTP_DPC_NIKON_ContinuousSpeedHigh,      PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_ShootingSpeedHigh,   _put_Nikon_D3s_ShootingSpeedHigh },
9748 	{ N_("Flash Sync. Speed"),              "flashsyncspeed",           PTP_DPC_NIKON_FlashSyncSpeed,           PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_FlashSyncSpeed,      _put_Nikon_D3s_FlashSyncSpeed },
9749 	{ N_("Flash Shutter Speed"),            "flashshutterspeed",        PTP_DPC_NIKON_FlashShutterSpeed,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_D3s_FlashShutterSpeed,   _put_Nikon_D3s_FlashShutterSpeed },
9750 
9751 	{ N_("Live View Size"),                 "liveviewsize",             PTP_DPC_NIKON_LiveViewImageSize,        PTP_VENDOR_NIKON,   PTP_DTC_UINT8,  _get_Nikon_LiveViewSize,            _put_Nikon_LiveViewSize },
9752 
9753 	{ 0,0,0,0,0,0,0 },
9754 };
9755 
9756 
9757 static struct menu menus[] = {
9758 	{ N_("Camera Actions"),             "actions",          0,      0,      camera_actions_menu,            NULL,   NULL },
9759 
9760 	{ N_("Camera Settings"),            "settings",         0x4b0,  0x0428, nikon_d7000_camera_settings,    NULL,   NULL },
9761 	{ N_("Camera Settings"),            "settings",         0x4b0,  0x0430, nikon_d7100_camera_settings,    NULL,   NULL },
9762 	{ N_("Camera Settings"),            "settings",         0x4b0,  0x0421, nikon_d90_camera_settings,      NULL,   NULL },
9763 	{ N_("Camera Settings"),            "settings",         0x4b0,  0x0606, nikon_1_s1_camera_settings,     NULL,   NULL },
9764 	{ N_("Camera Settings"),            "settings",         0x4b0,  0x0605, nikon_1_j3_camera_settings,     NULL,   NULL },
9765 	{ N_("Camera Settings"),            "settings",         0,      0,      camera_settings_menu,           NULL,   NULL },
9766 
9767 	{ N_("Camera Status Information"),  "status",           0,      0,      camera_status_menu,             NULL,   NULL },
9768 	{ N_("Image Settings"),             "imgsettings",      0,      0,      image_settings_menu,            NULL,   NULL },
9769 
9770 
9771 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0421, nikon_d90_capture_settings,     NULL,   NULL },
9772 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x043c, nikon_d500_capture_settings,    NULL,   NULL },
9773 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0426, nikon_d3s_capture_settings,     NULL,   NULL },
9774 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0429, nikon_d5100_capture_settings,   NULL,   NULL },
9775 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0430, nikon_d7100_capture_settings,   NULL,   NULL },
9776 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0440, nikon_d7500_capture_settings,   NULL,   NULL },
9777 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0414, nikon_d40_capture_settings,     NULL,   NULL },
9778 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0441, nikon_d850_capture_settings,    NULL,   NULL },
9779 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0442, nikon_z6_capture_settings,      NULL,   NULL },	/* Z7 */
9780 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0x0443, nikon_z6_capture_settings,      NULL,   NULL }, /* Z6 */
9781 	{ N_("Capture Settings"),           "capturesettings",  0x4b0,  0,      nikon_generic_capture_settings, NULL,   NULL },
9782 	{ N_("Capture Settings"),           "capturesettings",  0,      0,      capture_settings_menu,          NULL,   NULL },
9783 
9784 	{ N_("WIFI profiles"),              "wifiprofiles",     0,      0,      NULL,                           _get_wifi_profiles_menu, _put_wifi_profiles_menu },
9785 };
9786 
9787 /*
9788  * Can do 3 things:
9789  * - get the whole widget dialog tree (confname = NULL, list = NULL, widget = rootwidget)
9790  * - get the named single widget  (confname = the specified property, widget = property widget, list = NULL)
9791  * - get a flat ascii list of configuration names (confname = NULL, widget = NULL, list = list to fill in)
9792  */
9793 static int
_get_config(Camera * camera,const char * confname,CameraWidget ** outwidget,CameraList * list,GPContext * context)9794 _get_config (Camera *camera, const char *confname, CameraWidget **outwidget, CameraList *list, GPContext *context)
9795 {
9796 	CameraWidget	*section, *widget, *window;
9797 	unsigned int	menuno, submenuno;
9798 	int 		ret;
9799 	uint16_t	*setprops = NULL;
9800 	unsigned int	i;
9801 	int		nrofsetprops = 0;
9802 	PTPParams	*params = &camera->pl->params;
9803 	CameraAbilities	ab;
9804 
9805 	enum {
9806 		MODE_GET,
9807 		MODE_LIST,
9808 		MODE_SINGLE_GET
9809 	} mode = MODE_GET;
9810 
9811 	if (confname)
9812 		mode = MODE_SINGLE_GET;
9813 	if (list) {
9814 		gp_list_reset (list);
9815 		mode = MODE_LIST;
9816 	}
9817 
9818 	SET_CONTEXT(camera, context);
9819 	memset (&ab, 0, sizeof(ab));
9820 	gp_camera_get_abilities (camera, &ab);
9821 	if (	(params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
9822 		(ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteRelease) ||
9823 		 ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn)
9824 		)
9825 	) {
9826 		if (!params->eos_captureenabled)
9827 			camera_prepare_capture (camera, context);
9828 		ptp_check_eos_events (params);
9829 		/* Otherwise the camera will auto-shutdown */
9830 		if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_KeepDeviceOn))
9831 			C_PTP (ptp_canon_eos_keepdeviceon (params));
9832 	}
9833 
9834 	if (mode == MODE_GET) {
9835 		gp_widget_new (GP_WIDGET_WINDOW, _("Camera and Driver Configuration"), &window);
9836 		gp_widget_set_name (window, "main");
9837 		*outwidget = window;
9838 	}
9839 
9840 	for (menuno = 0; menuno < sizeof(menus)/sizeof(menus[0]) ; menuno++ ) {
9841 		if (!menus[menuno].submenus) { /* Custom menu */
9842 			if (mode == MODE_GET) {
9843 				struct menu *cur = menus+menuno;
9844 				ret = cur->getfunc(camera, &section, cur);
9845 				if (ret == GP_OK)
9846 					gp_widget_append(window, section);
9847 			} /* else ... not supported in single get and list */
9848 			continue;
9849 		}
9850 		if ((menus[menuno].usb_vendorid != 0) && (ab.port == GP_PORT_USB)) {
9851 			if (menus[menuno].usb_vendorid != ab.usb_vendor)
9852 				continue;
9853 			if (	menus[menuno].usb_productid &&
9854 				(menus[menuno].usb_productid != ab.usb_product)
9855 			)
9856 				continue;
9857 			GP_LOG_D ("usb vendor/product specific path entered");
9858 		}
9859 
9860 		if (mode == MODE_GET) {
9861 			/* Standard menu with submenus */
9862 			ret = gp_widget_get_child_by_label (window, _(menus[menuno].label), &section);
9863 			if (ret != GP_OK) {
9864 				gp_widget_new (GP_WIDGET_SECTION, _(menus[menuno].label), &section);
9865 				gp_widget_set_name (section, menus[menuno].name);
9866 				gp_widget_append (window, section);
9867 			}
9868 		}
9869 		for (submenuno = 0; menus[menuno].submenus[submenuno].name ; submenuno++ ) {
9870 			struct submenu *cursub = menus[menuno].submenus+submenuno;
9871 			widget = NULL;
9872 
9873 			if (	have_prop(camera,cursub->vendorid,cursub->propid) ||
9874 				((cursub->propid == 0) && have_prop(camera,cursub->vendorid,cursub->type))
9875 			) {
9876 				int			j;
9877 
9878 				/* Do not handle a property we have already handled.
9879 				 * needed for the vendor specific but different configs.
9880 				 */
9881 				if (cursub->propid) {
9882 					for (j=0;j<nrofsetprops;j++)
9883 						if (setprops[j] == cursub->propid)
9884 							break;
9885 					if (j<nrofsetprops) {
9886 						GP_LOG_D ("Property '%s' / 0x%04x already handled before, skipping.", cursub->label, cursub->propid );
9887 						continue;
9888 					}
9889 					if (nrofsetprops)
9890 						C_MEM (setprops = realloc(setprops,sizeof(setprops[0])*(nrofsetprops+1)));
9891 					else
9892 						C_MEM (setprops = malloc(sizeof(setprops[0])));
9893 					setprops[nrofsetprops++] = cursub->propid;
9894 				}
9895 				/* ok, looking good */
9896 				if (	((cursub->propid & 0x7000) == 0x5000) ||
9897 					(NIKON_1(params) && ((cursub->propid & 0xf000) == 0xf000))
9898 				) {
9899 					PTPDevicePropDesc	dpd;
9900 
9901 					if ((mode == MODE_SINGLE_GET) && strcmp (cursub->name, confname))
9902 						continue;
9903 					if (mode == MODE_LIST) {
9904 						gp_list_append (list, cursub->name, NULL);
9905 						continue;
9906 					}
9907 
9908 					GP_LOG_D ("Getting property '%s' / 0x%04x", cursub->label, cursub->propid );
9909 					memset(&dpd,0,sizeof(dpd));
9910 					ret = LOG_ON_PTP_E(ptp_generic_getdevicepropdesc(params,cursub->propid,&dpd));
9911 					if (ret != PTP_RC_OK)
9912 						continue;
9913 
9914 					if (cursub->type != dpd.DataType) {
9915 						GP_LOG_E ("Type of property '%s' expected: 0x%04x got: 0x%04x", cursub->label, cursub->type, dpd.DataType );
9916 						/* str is incompatible to all others */
9917 						if ((PTP_DTC_STR == cursub->type) || (PTP_DTC_STR == dpd.DataType))
9918 							continue;
9919 						/* array is not compatible to non-array */
9920 						if (((cursub->type ^ dpd.DataType) & PTP_DTC_ARRAY_MASK) == PTP_DTC_ARRAY_MASK)
9921 							continue;
9922 						/* FIXME: continue to search here instead of below? */
9923 					}
9924 					ret = cursub->getfunc (camera, &widget, cursub, &dpd);
9925 					if ((ret == GP_OK) && (dpd.GetSet == PTP_DPGS_Get))
9926 						gp_widget_set_readonly (widget, 1);
9927 					ptp_free_devicepropdesc(&dpd);
9928 
9929 					if (ret != GP_OK) {
9930 						/* the type might not have matched, try the next */
9931 						GP_LOG_E ("Widget get of property '%s' failed, trying to see if we have another...", cursub->label);
9932 						nrofsetprops--;
9933 						continue;
9934 					}
9935 					if (mode == MODE_SINGLE_GET) {
9936 						*outwidget = widget;
9937 						free (setprops);
9938 						return GP_OK;
9939 					}
9940 				} else {
9941 					/* if it is a OPC, check for its presence. Otherwise just create the widget. */
9942 					if (	((cursub->type & 0x7000) != 0x1000) ||
9943 						 ptp_operation_issupported(params, cursub->type)
9944 					) {
9945 						if ((mode == MODE_SINGLE_GET) && strcmp (cursub->name, confname))
9946 							continue;
9947 						if (mode == MODE_LIST) {
9948 							gp_list_append (list, cursub->name, NULL);
9949 							continue;
9950 						}
9951 
9952 						GP_LOG_D ("Getting function prop '%s' / 0x%04x", cursub->label, cursub->type );
9953 						ret = cursub->getfunc (camera, &widget, cursub, NULL);
9954 						if (mode == MODE_SINGLE_GET) {
9955 							*outwidget = widget;
9956 							free (setprops);
9957 							return GP_OK;
9958 						}
9959 					} else
9960 						continue;
9961 				}
9962 				if (ret != GP_OK) {
9963 					GP_LOG_D ("Failed to parse value of property '%s' / 0x%04x: error code %d", cursub->label, cursub->propid, ret);
9964 					continue;
9965 				}
9966 				if (mode == MODE_GET)
9967 					gp_widget_append (section, widget);
9968 				continue;
9969 			}
9970 			if (have_eos_prop(params,cursub->vendorid,cursub->propid)) {
9971 				PTPDevicePropDesc	dpd;
9972 
9973 				if ((mode == MODE_SINGLE_GET) && strcmp (cursub->name, confname))
9974 					continue;
9975 				if (mode == MODE_LIST) {
9976 					gp_list_append (list, cursub->name, NULL);
9977 					continue;
9978 				}
9979 				GP_LOG_D ("Getting property '%s' / 0x%04x", cursub->label, cursub->propid );
9980 				memset(&dpd,0,sizeof(dpd));
9981 				ptp_canon_eos_getdevicepropdesc (params,cursub->propid, &dpd);
9982 				ret = cursub->getfunc (camera, &widget, cursub, &dpd);
9983 				ptp_free_devicepropdesc(&dpd);
9984 				if (ret != GP_OK) {
9985 					GP_LOG_D ("Failed to parse value of property '%s' / 0x%04x: error code %d", cursub->label, cursub->propid, ret);
9986 					continue;
9987 				}
9988 				if (mode == MODE_SINGLE_GET) {
9989 					*outwidget = widget;
9990 					free (setprops);
9991 					return GP_OK;
9992 				}
9993 				if (mode == MODE_GET)
9994 					gp_widget_append (section, widget);
9995 				continue;
9996 			}
9997 		}
9998 	}
9999 
10000 	if (!params->deviceinfo.DevicePropertiesSupported_len) {
10001 		free (setprops);
10002 		return GP_OK;
10003 	}
10004 
10005 	if (mode == MODE_GET) {
10006 		/* Last menu is "Other", a generic property fallback window. */
10007 		gp_widget_new (GP_WIDGET_SECTION, _("Other PTP Device Properties"), &section);
10008 		gp_widget_set_name (section, "other");
10009 		gp_widget_append (window, section);
10010 	}
10011 
10012 	for (i=0;i<params->deviceinfo.DevicePropertiesSupported_len;i++) {
10013 		uint16_t		propid = params->deviceinfo.DevicePropertiesSupported[i];
10014 		char			buf[21], *label;
10015 		PTPDevicePropDesc	dpd;
10016 		CameraWidgetType	type;
10017 
10018 #if 0 /* enable this for suppression of generic properties for already decoded ones */
10019 		int j;
10020 
10021 		for (j=0;j<nrofsetprops;j++)
10022 			if (setprops[j] == propid)
10023 				break;
10024 		if (j<nrofsetprops) {
10025 			GP_LOG_D ("Property 0x%04x already handled before, skipping.", propid );
10026 			continue;
10027 		}
10028 #endif
10029 
10030 		sprintf(buf,"%04x", propid);
10031 		if ((mode == MODE_SINGLE_GET) && strcmp (buf, confname))
10032 			continue;
10033 		if (mode == MODE_LIST) {
10034 			gp_list_append (list, buf, NULL);
10035 			continue;
10036 		}
10037 
10038 		ret = ptp_generic_getdevicepropdesc (params,propid,&dpd);
10039 		if (ret != PTP_RC_OK)
10040 			continue;
10041 
10042 		label = (char*)ptp_get_property_description(params, propid);
10043 		if (!label) {
10044 			sprintf (buf, N_("PTP Property 0x%04x"), propid);
10045 			label = buf;
10046 		}
10047 		switch (dpd.FormFlag) {
10048 		case PTP_DPFF_None:
10049 			type = GP_WIDGET_TEXT;
10050 			break;
10051 		case PTP_DPFF_Range:
10052 			type = GP_WIDGET_RANGE;
10053 			switch (dpd.DataType) {
10054 			/* simple ranges might just be enumerations */
10055 #define X(dtc,val) 							\
10056 			case dtc: 					\
10057 				if (	((dpd.FORM.Range.MaximumValue.val - dpd.FORM.Range.MinimumValue.val) < 128) &&	\
10058 					(dpd.FORM.Range.StepSize.val == 1)) {						\
10059 					type = GP_WIDGET_MENU;								\
10060 				} \
10061 				break;
10062 
10063 		X(PTP_DTC_INT8,i8)
10064 		X(PTP_DTC_UINT8,u8)
10065 		X(PTP_DTC_INT16,i16)
10066 		X(PTP_DTC_UINT16,u16)
10067 		X(PTP_DTC_INT32,i32)
10068 		X(PTP_DTC_UINT32,u32)
10069 #undef X
10070 			default:break;
10071 			}
10072 			break;
10073 		case PTP_DPFF_Enumeration:
10074 			type = GP_WIDGET_MENU;
10075 			break;
10076 		default:
10077 			type = GP_WIDGET_TEXT;
10078 			break;
10079 		}
10080 		gp_widget_new (type, _(label), &widget);
10081 		sprintf(buf,"%04x", propid);
10082 		gp_widget_set_name (widget, buf);
10083 		switch (dpd.FormFlag) {
10084 		case PTP_DPFF_None: break;
10085 		case PTP_DPFF_Range:
10086 			switch (dpd.DataType) {
10087 #define X(dtc,val,vartype,format) 										\
10088 			case dtc: 								\
10089 				if (type == GP_WIDGET_RANGE) {					\
10090 					gp_widget_set_range ( widget, (float) dpd.FORM.Range.MinimumValue.val, (float) dpd.FORM.Range.MaximumValue.val, (float) dpd.FORM.Range.StepSize.val);\
10091 				} else {							\
10092 					vartype k;							\
10093 					for (k=dpd.FORM.Range.MinimumValue.val;k<=dpd.FORM.Range.MaximumValue.val;k+=dpd.FORM.Range.StepSize.val) { \
10094 						sprintf (buf, #format, k); 			\
10095 						gp_widget_add_choice (widget, buf);		\
10096 						if (dpd.FORM.Range.StepSize.val == 0) break;	\
10097 					}							\
10098 				} 								\
10099 				break;
10100 
10101 		X(PTP_DTC_INT8,i8,int8_t,%d)
10102 		X(PTP_DTC_UINT8,u8,uint8_t,%u)
10103 		X(PTP_DTC_INT16,i16,int16_t,%d)
10104 		X(PTP_DTC_UINT16,u16,uint16_t,%u)
10105 		X(PTP_DTC_INT32,i32,int32_t,%d)
10106 		X(PTP_DTC_UINT32,u32,uint32_t,%u)
10107 		X(PTP_DTC_INT64,i64,int64_t,%ld)
10108 		X(PTP_DTC_UINT64,u64,uint64_t,%lu)
10109 #undef X
10110 			default:break;
10111 			}
10112 			break;
10113 		case PTP_DPFF_Enumeration:
10114 			switch (dpd.DataType) {
10115 #define X(dtc,val,fmt) 									\
10116 			case dtc: { 							\
10117 				int k;							\
10118 				for (k=0;k<dpd.FORM.Enum.NumberOfValues;k++) {		\
10119 					sprintf (buf, fmt, dpd.FORM.Enum.SupportedValue[k].val); \
10120 					gp_widget_add_choice (widget, buf);		\
10121 				}							\
10122 				break;							\
10123 			}
10124 
10125 		X(PTP_DTC_INT8,i8,"%d")
10126 		X(PTP_DTC_UINT8,u8,"%d")
10127 		X(PTP_DTC_INT16,i16,"%d")
10128 		X(PTP_DTC_UINT16,u16,"%d")
10129 		X(PTP_DTC_INT32,i32,"%d")
10130 		X(PTP_DTC_UINT32,u32,"%d")
10131 		X(PTP_DTC_INT64,i64,"%ld")
10132 		X(PTP_DTC_UINT64,u64,"%ld")
10133 #undef X
10134 			case PTP_DTC_STR: {
10135 				int k;
10136 				for (k=0;k<dpd.FORM.Enum.NumberOfValues;k++)
10137 					gp_widget_add_choice (widget, dpd.FORM.Enum.SupportedValue[k].str);
10138 				break;
10139 			}
10140 			default:break;
10141 			}
10142 			break;
10143 		}
10144 		switch (dpd.DataType) {
10145 #define X(dtc,val,fmt) 							\
10146 		case dtc:						\
10147 			if (type == GP_WIDGET_RANGE) {			\
10148 				float f = dpd.CurrentValue.val;		\
10149 				gp_widget_set_value (widget, &f);	\
10150 			} else {					\
10151 				sprintf (buf, fmt, dpd.CurrentValue.val);	\
10152 				gp_widget_set_value (widget, buf);	\
10153 			}\
10154 			break;
10155 
10156 		X(PTP_DTC_INT8,i8,"%d")
10157 		X(PTP_DTC_UINT8,u8,"%d")
10158 		X(PTP_DTC_INT16,i16,"%d")
10159 		X(PTP_DTC_UINT16,u16,"%d")
10160 		X(PTP_DTC_INT32,i32,"%d")
10161 		X(PTP_DTC_UINT32,u32,"%d")
10162 		X(PTP_DTC_INT64,i64,"%ld")
10163 		X(PTP_DTC_UINT64,u64,"%ld")
10164 #undef X
10165 		case PTP_DTC_STR:
10166 			gp_widget_set_value (widget, dpd.CurrentValue.str);
10167 			break;
10168 		default:
10169 			break;
10170 		}
10171 		if (dpd.GetSet == PTP_DPGS_Get)
10172 			gp_widget_set_readonly (widget, 1);
10173 		ptp_free_devicepropdesc(&dpd);
10174 		if (mode == MODE_GET)
10175 			gp_widget_append (section, widget);
10176 		if (mode == MODE_SINGLE_GET) {
10177 			*outwidget = widget;
10178 			free (setprops);
10179 			return GP_OK;
10180 		}
10181 	}
10182 	free (setprops);
10183 	if (mode == MODE_SINGLE_GET) {
10184 		/* if we get here, we have not found anything */
10185 		/*gp_context_error (context, _("Property '%s' not found."), confname);*/
10186 		return GP_ERROR_BAD_PARAMETERS;
10187 	}
10188 	return GP_OK;
10189 }
10190 
10191 int
camera_get_config(Camera * camera,CameraWidget ** window,GPContext * context)10192 camera_get_config (Camera *camera, CameraWidget **window, GPContext *context)
10193 {
10194 	return _get_config (camera, NULL, window, NULL, context);
10195 }
10196 
10197 int
camera_list_config(Camera * camera,CameraList * list,GPContext * context)10198 camera_list_config (Camera *camera, CameraList *list, GPContext *context)
10199 {
10200 	return _get_config (camera, NULL, NULL, list, context);
10201 }
10202 
10203 int
camera_get_single_config(Camera * camera,const char * confname,CameraWidget ** widget,GPContext * context)10204 camera_get_single_config (Camera *camera, const char *confname, CameraWidget **widget, GPContext *context)
10205 {
10206 	return _get_config (camera, confname, widget, NULL, context);
10207 }
10208 
10209 
10210 static int
_set_config(Camera * camera,const char * confname,CameraWidget * window,GPContext * context)10211 _set_config (Camera *camera, const char *confname, CameraWidget *window, GPContext *context)
10212 {
10213 	CameraWidget		*section, *widget = window, *subwindow;
10214 	uint16_t		ret_ptp;
10215 	unsigned int		menuno, submenuno;
10216 	int			ret;
10217 	PTPParams		*params = &camera->pl->params;
10218 	PTPPropertyValue	propval;
10219 	unsigned int		i;
10220 	CameraAbilities		ab;
10221 	enum {
10222 		MODE_SET, MODE_SINGLE_SET
10223 	} mode = MODE_SET;
10224 
10225 	if (confname) mode = MODE_SINGLE_SET;
10226 
10227 	SET_CONTEXT(camera, context);
10228 	memset (&ab, 0, sizeof(ab));
10229 	gp_camera_get_abilities (camera, &ab);
10230 
10231 	camera->pl->checkevents = TRUE;
10232 	if (	(params->deviceinfo.VendorExtensionID == PTP_VENDOR_CANON) &&
10233 		(ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteRelease) ||
10234 		 ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn)
10235 		)
10236 	) {
10237 		if (!params->eos_captureenabled)
10238 			camera_prepare_capture (camera, context);
10239 		ptp_check_eos_events (params);
10240 	}
10241 
10242 	if (mode == MODE_SET)
10243 		CR (gp_widget_get_child_by_label (window, _("Camera and Driver Configuration"), &subwindow));
10244 	for (menuno = 0; menuno < sizeof(menus)/sizeof(menus[0]) ; menuno++ ) {
10245 		if (mode == MODE_SET) {
10246 			ret = gp_widget_get_child_by_label (subwindow, _(menus[menuno].label), &section);
10247 			if (ret != GP_OK)
10248 				continue;
10249 		}
10250 
10251 		if (!menus[menuno].submenus) { /* Custom menu */
10252 			if (mode == MODE_SET)
10253 				menus[menuno].putfunc(camera, section);
10254 			continue;
10255 		}
10256 		if ((menus[menuno].usb_vendorid != 0) && (ab.port == GP_PORT_USB)) {
10257 			if (menus[menuno].usb_vendorid != ab.usb_vendor)
10258 				continue;
10259 			if (	menus[menuno].usb_productid &&
10260 				(menus[menuno].usb_productid != ab.usb_product)
10261 			)
10262 				continue;
10263 			GP_LOG_D ("usb vendor/product specific path entered");
10264 		}
10265 
10266 		/* Standard menu with submenus */
10267 		for (submenuno = 0; menus[menuno].submenus[submenuno].label ; submenuno++ ) {
10268 			struct submenu *cursub = menus[menuno].submenus+submenuno;
10269 
10270 			ret = GP_OK;
10271 			if (mode == MODE_SET) {
10272 				ret = gp_widget_get_child_by_label (section, _(cursub->label), &widget);
10273 				if (ret != GP_OK)
10274 					continue;
10275 
10276 				if (!gp_widget_changed (widget))
10277 					continue;
10278 
10279 				/* restore the "changed flag" */
10280 				gp_widget_set_changed (widget, TRUE);
10281 			}
10282 
10283 			if (	have_prop(camera,cursub->vendorid,cursub->propid) ||
10284 				((cursub->propid == 0) && have_prop(camera,cursub->vendorid,cursub->type))
10285 			) {
10286 				if ((mode == MODE_SINGLE_SET) && strcmp (confname, cursub->name))
10287 					continue;
10288 
10289 				gp_widget_set_changed (widget, FALSE); /* clear flag */
10290 				GP_LOG_D ("Setting property '%s' / 0x%04x", cursub->label, cursub->propid );
10291 				if (	((cursub->propid & 0x7000) == 0x5000) ||
10292 					(NIKON_1(params) && ((cursub->propid & 0xf000) == 0xf000))
10293 				){
10294 					PTPDevicePropDesc dpd;
10295 
10296 					memset(&dpd,0,sizeof(dpd));
10297 					memset(&propval,0,sizeof(propval));
10298 
10299 					C_PTP (ptp_generic_getdevicepropdesc(params,cursub->propid,&dpd));
10300 					if (cursub->type != dpd.DataType) {
10301 						GP_LOG_E ("Type of property '%s' expected: 0x%04x got: 0x%04x", cursub->label, cursub->type, dpd.DataType );
10302 						/* str is incompatible to all others */
10303 						if ((PTP_DTC_STR == cursub->type) || (PTP_DTC_STR == dpd.DataType))
10304 							continue;
10305 						/* array is not compatible to non-array */
10306 						if (((cursub->type ^ dpd.DataType) & PTP_DTC_ARRAY_MASK) == PTP_DTC_ARRAY_MASK)
10307 							continue;
10308 						/* FIXME: continue to search here perhaps instead of below? */
10309 					}
10310 					if (dpd.GetSet == PTP_DPGS_GetSet) {
10311 						ret = cursub->putfunc (camera, widget, &propval, &dpd);
10312 					} else {
10313 						gp_context_error (context, _("Sorry, the property '%s' / 0x%04x is currently read-only."), _(cursub->label), cursub->propid);
10314 						ret = GP_ERROR_NOT_SUPPORTED;
10315 					}
10316 					if (ret == GP_OK) {
10317 						ret_ptp = LOG_ON_PTP_E (ptp_generic_setdevicepropvalue (params, cursub->propid, &propval, cursub->type));
10318 						if (ret_ptp != PTP_RC_OK) {
10319 							gp_context_error (context, _("The property '%s' / 0x%04x was not set (0x%04x: %s)"),
10320 									  _(cursub->label), cursub->propid, ret_ptp, _(ptp_strerror(ret_ptp, params->deviceinfo.VendorExtensionID)));
10321 							ret = translate_ptp_result (ret_ptp);
10322 						}
10323 						ptp_free_devicepropvalue (cursub->type, &propval);
10324 					}
10325 					ptp_free_devicepropdesc(&dpd);
10326 					if (ret != GP_OK) continue; /* see if we have another match */
10327 				} else {
10328 					ret = cursub->putfunc (camera, widget, NULL, NULL);
10329 				}
10330 				if (mode == MODE_SINGLE_SET)
10331 					return ret;
10332 			}
10333 			if (have_eos_prop(params,cursub->vendorid,cursub->propid)) {
10334 				PTPDevicePropDesc	dpd;
10335 
10336 				if ((mode == MODE_SINGLE_SET) && strcmp (confname, cursub->name))
10337 					continue;
10338 				gp_widget_set_changed (widget, FALSE); /* clear flag */
10339 				if ((cursub->propid & 0x7000) == 0x5000) {
10340 					GP_LOG_D ("Setting property '%s' / 0x%04x", cursub->label, cursub->propid);
10341 					memset(&dpd,0,sizeof(dpd));
10342 					ptp_canon_eos_getdevicepropdesc (params,cursub->propid, &dpd);
10343 					ret = cursub->putfunc (camera, widget, &propval, &dpd);
10344 					if (ret == GP_OK) {
10345 						ret_ptp = LOG_ON_PTP_E (ptp_canon_eos_setdevicepropvalue (params, cursub->propid, &propval, cursub->type));
10346 						if (ret_ptp != PTP_RC_OK) {
10347 							gp_context_error (context, _("The property '%s' / 0x%04x was not set (0x%04x: %s)."),
10348 									  _(cursub->label), cursub->propid, ret_ptp, _(ptp_strerror(ret_ptp, params->deviceinfo.VendorExtensionID)));
10349 							ret = translate_ptp_result (ret_ptp);
10350 						}
10351 						ptp_free_devicepropvalue(cursub->type, &propval);
10352 					} else
10353 						gp_context_error (context, _("Parsing the value of widget '%s' / 0x%04x failed with %d."), _(cursub->label), cursub->propid, ret);
10354 					ptp_free_devicepropdesc(&dpd);
10355 				} else {
10356 					GP_LOG_D ("Setting virtual property '%s' / 0x%04x", cursub->label, cursub->propid);
10357 					/* if it is a OPC, check for its presence. Otherwise just use the widget. */
10358 					if (	((cursub->type & 0x7000) != 0x1000) ||
10359 						 ptp_operation_issupported(params, cursub->type)
10360 					)
10361 						ret = cursub->putfunc (camera, widget, &propval, &dpd);
10362 					else
10363 						continue;
10364 				}
10365 				if (mode == MODE_SINGLE_SET)
10366 					return ret;
10367 			}
10368 			if (ret != GP_OK)
10369 				return ret;
10370 		}
10371 	}
10372 	if (!params->deviceinfo.DevicePropertiesSupported_len)
10373 		return GP_OK;
10374 
10375 	if (mode == MODE_SET)
10376 		CR (gp_widget_get_child_by_label (subwindow, _("Other PTP Device Properties"), &section));
10377 	/* Generic property setter */
10378 	for (i=0;i<params->deviceinfo.DevicePropertiesSupported_len;i++) {
10379 		uint16_t		propid = params->deviceinfo.DevicePropertiesSupported[i];
10380 		CameraWidgetType	type;
10381 		char			buf[20], *label, *xval;
10382 		PTPDevicePropDesc	dpd;
10383 
10384 		if (mode == MODE_SINGLE_SET) {
10385 			sprintf(buf,"%04x", propid);
10386 			if (strcmp (confname, buf))
10387 				continue;
10388 		}
10389 		label = (char*)ptp_get_property_description(params, propid);
10390 		if (!label) {
10391 			sprintf (buf, N_("PTP Property 0x%04x"), propid);
10392 			label = buf;
10393 		}
10394 		if (mode == MODE_SET) {
10395 			ret = gp_widget_get_child_by_label (section, _(label), &widget);
10396 			if (ret != GP_OK)
10397 				continue;
10398 			if (!gp_widget_changed (widget))
10399 				continue;
10400 			gp_widget_set_changed (widget, FALSE);
10401 		}
10402 
10403 		gp_widget_get_type (widget, &type);
10404 
10405 		memset (&dpd,0,sizeof(dpd));
10406 		memset (&propval,0,sizeof(propval));
10407 		ret = ptp_generic_getdevicepropdesc (params,propid,&dpd);
10408 		if (ret != PTP_RC_OK)
10409 			continue;
10410 		if (dpd.GetSet != PTP_DPGS_GetSet) {
10411 			gp_context_error (context, _("Sorry, the property '%s' / 0x%04x is currently read-only."), _(label), propid);
10412 			return GP_ERROR_NOT_SUPPORTED;
10413 		}
10414 
10415 		switch (dpd.DataType) {
10416 #define X(dtc,val) 							\
10417 		case dtc:						\
10418 			if (type == GP_WIDGET_RANGE) {			\
10419 				float f;				\
10420 				gp_widget_get_value (widget, &f);	\
10421 				propval.val = f;			\
10422 			} else {					\
10423 				long x;					\
10424 				ret = gp_widget_get_value (widget, &xval);	\
10425 				sscanf (xval, "%ld", &x);		\
10426 				propval.val = x;			\
10427 			}\
10428 			break;
10429 
10430 		X(PTP_DTC_INT8,i8)
10431 		X(PTP_DTC_UINT8,u8)
10432 		X(PTP_DTC_INT16,i16)
10433 		X(PTP_DTC_UINT16,u16)
10434 		X(PTP_DTC_INT32,i32)
10435 		X(PTP_DTC_UINT32,u32)
10436 		X(PTP_DTC_INT64,i64)
10437 		X(PTP_DTC_UINT64,u64)
10438 #undef X
10439 		case PTP_DTC_STR: {
10440 			char *val;
10441 			gp_widget_get_value (widget, &val);
10442 			C_MEM (propval.str = strdup(val));
10443 			break;
10444 		}
10445 		default:
10446 			break;
10447 		}
10448 
10449 		/* TODO: ret is ignored here, this is inconsistent with the code above */
10450 		ret = LOG_ON_PTP_E (ptp_generic_setdevicepropvalue (params, propid, &propval, dpd.DataType));
10451 		if (ret != PTP_RC_OK) {
10452 			gp_context_error (context, _("The property '%s' / 0x%04x was not set (0x%04x: %s)."),
10453 					  _(label), propid, ret, _(ptp_strerror(ret, params->deviceinfo.VendorExtensionID)));
10454 			ret = GP_ERROR;
10455 		}
10456 		ptp_free_devicepropvalue (dpd.DataType, &propval);
10457 		ptp_free_devicepropdesc (&dpd);
10458 		if (mode == MODE_SINGLE_SET)
10459 			return GP_OK;
10460 	}
10461 	if (mode == MODE_SINGLE_SET) {
10462 		/* if we get here, we have not found anything */
10463 		gp_context_error (context, _("Property '%s' not found."), confname);
10464 		return GP_ERROR_BAD_PARAMETERS;
10465 	}
10466 	return GP_OK;
10467 }
10468 
10469 int
camera_set_config(Camera * camera,CameraWidget * window,GPContext * context)10470 camera_set_config (Camera *camera, CameraWidget *window, GPContext *context)
10471 {
10472 	return _set_config (camera, NULL, window, context);
10473 }
10474 
10475 int
camera_set_single_config(Camera * camera,const char * confname,CameraWidget * widget,GPContext * context)10476 camera_set_single_config (Camera *camera, const char *confname, CameraWidget *widget, GPContext *context)
10477 {
10478 	return _set_config (camera, confname, widget, context);
10479 }
10480