From c58709da1fb2f1cda70b69f6078c846e24dd7560 Mon Sep 17 00:00:00 2001 From: Joep Jansen Date: Fri, 9 Aug 2024 20:57:36 +0200 Subject: [PATCH] Support the SetModeDialDisable opcode for Canon cameras (#991) * Add PTP_OC_CANON_SetModeDialDisable opcode * Unlock software setting of modedial for supported canon cameras in camera_init, re-enable the modedial in camera_exit * Add "disablemodedial" command to camera actions for supported canon cameras --- camlibs/ptp2/config.c | 21 +++++++++++++++++++++ camlibs/ptp2/library.c | 8 ++++++++ camlibs/ptp2/ptp.c | 1 + camlibs/ptp2/ptp.h | 11 +++++++++++ 4 files changed, 41 insertions(+) diff --git a/camlibs/ptp2/config.c b/camlibs/ptp2/config.c index 4f17b1528..a9384e173 100644 --- a/camlibs/ptp2/config.c +++ b/camlibs/ptp2/config.c @@ -10221,6 +10221,26 @@ _put_CHDK(CONFIG_PUT_ARGS) { return GP_OK; } +static int +_get_Canon_SetModeDialDisable(CONFIG_GET_ARGS) { + gp_widget_new (GP_WIDGET_TOGGLE, _(menu->label), widget); + gp_widget_set_name (*widget,menu->name); + int val = 0; + gp_widget_set_value (*widget, &val); + return GP_OK; +} + +static int +_put_Canon_SetModeDialDisable(CONFIG_PUT_ARGS) { + PTPParams *params = &(camera->pl->params); + int val; + if (!ptp_operation_issupported(params, PTP_OC_CANON_SetModeDialDisable)) + return (GP_ERROR_NOT_SUPPORTED); + CR (gp_widget_get_value(widget, &val)); + C_PTP (ptp_canon_setmodedialdisable(params, val)); + return GP_OK; +} + static struct { char *name; char *label; @@ -10823,6 +10843,7 @@ static struct submenu camera_actions_menu[] = { { N_("Remote Key Down"), "remotekeydown", PTP_DPC_SONY_RemoteKeyDown, PTP_VENDOR_SONY, PTP_DTC_UINT16, _get_Sony_FocusMagnifyProp, _put_Sony_FocusMagnifyProp }, { N_("Remote Key Left"), "remotekeyleft", PTP_DPC_SONY_RemoteKeyLeft, PTP_VENDOR_SONY, PTP_DTC_UINT16, _get_Sony_FocusMagnifyProp, _put_Sony_FocusMagnifyProp }, { N_("Remote Key Right"), "remotekeyright",PTP_DPC_SONY_RemoteKeyRight, PTP_VENDOR_SONY, PTP_DTC_UINT16, _get_Sony_FocusMagnifyProp,_put_Sony_FocusMagnifyProp }, + { N_("Canon Disable Mode Dial"), "disablemodedial", 0, PTP_VENDOR_CANON, PTP_OC_CANON_SetModeDialDisable, _get_Canon_SetModeDialDisable, _put_Canon_SetModeDialDisable }, { N_("PTP Opcode"), "opcode", 0, 0, PTP_OC_GetDeviceInfo, _get_Generic_OPCode, _put_Generic_OPCode }, { 0,0,0,0,0,0,0 }, }; diff --git a/camlibs/ptp2/library.c b/camlibs/ptp2/library.c index 5ae3c9cdf..7c4be6103 100644 --- a/camlibs/ptp2/library.c +++ b/camlibs/ptp2/library.c @@ -3245,6 +3245,10 @@ camera_exit (Camera *camera, GPContext *context) if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_SetRemoteMode)) { C_PTP (ptp_canon_eos_setremotemode(params, 1)); } + /* re-enable the mode dial (it may fail with PTP general error 0x2002 )*/ + if (ptp_operation_issupported(params, PTP_OC_CANON_SetModeDialDisable)) { + ptp_canon_setmodedialdisable(params, 0); + } break; case PTP_VENDOR_NIKON: if (ptp_operation_issupported(params, PTP_OC_NIKON_EndLiveView)) @@ -10097,6 +10101,10 @@ camera_init (Camera *camera, GPContext *context) C_PTP (ptp_canon_eos_setremotemode(params, 1)); } } + /* enable software setting of the mode dial (ignore potential error) */ + if (ptp_operation_issupported(params, PTP_OC_CANON_SetModeDialDisable)) { + ptp_canon_setmodedialdisable(params, 1); + } break; case PTP_VENDOR_NIKON: if (ptp_operation_issupported(params, PTP_OC_NIKON_CurveDownload)) diff --git a/camlibs/ptp2/ptp.c b/camlibs/ptp2/ptp.c index b35ddea1f..e12f6f8c0 100644 --- a/camlibs/ptp2/ptp.c +++ b/camlibs/ptp2/ptp.c @@ -8971,6 +8971,7 @@ ptp_opcode_trans_t ptp_opcode_canon_trans[] = { {PTP_OC_CANON_EOS_NotifySaveComplete,"EOS_NotifySaveComplete"}, {PTP_OC_CANON_EOS_GetObjectURL,"EOS_GetObjectURL"}, {PTP_OC_CANON_SetRemoteShootingMode,"SetRemoteShootingMode"}, + {PTP_OC_CANON_SetModeDialDisable,"SetModeDialDisable"}, {PTP_OC_CANON_EOS_SetFELock,"EOS_SetFELock"}, {PTP_OC_CANON_DeleteWebServiceData,"DeleteWebServiceData"}, {PTP_OC_CANON_GetGpsMobilelinkObjectInfo,"GetGpsMobilelinkObjectInfo"}, diff --git a/camlibs/ptp2/ptp.h b/camlibs/ptp2/ptp.h index ab9c3c95d..1e7e771c8 100644 --- a/camlibs/ptp2/ptp.h +++ b/camlibs/ptp2/ptp.h @@ -329,6 +329,7 @@ typedef struct _PTPIPHeader PTPIPHeader; #define PTP_OC_CANON_RequestTranscodeCancel 0x9079 /* 1 arg: oid? */ #define PTP_OC_CANON_SetRemoteShootingMode 0x9086 +#define PTP_OC_CANON_SetModeDialDisable 0x9088 /* 9101: no args, 8 byte data (01 00 00 00 00 00 00 00), no resp data. */ #define PTP_OC_CANON_EOS_GetStorageIDs 0x9101 @@ -4290,6 +4291,16 @@ uint16_t ptp_canon_checkevent (PTPParams* params, * **/ #define ptp_canon_initiatecaptureinmemory(params) ptp_generic_no_data(params,PTP_OC_CANON_InitiateCaptureInMemory,0) +/** + * ptp_canon_setmodedialdisable: + * + * This operation allows software setting of the mode dial. THe software setting is disabled by default. + * The operation has one parameter, with the value 0 or 1. + * Parameter 0 disables the software setting of the mode dial, 1 allows software setting of the mode dial. + * When software setting is allowed the physical mode dial is disabled. This situation remains until the camera is + * powered off, or the camera is disconnected. + */ +#define ptp_canon_setmodedialdisable(params, onoff) ptp_generic_no_data(params,PTP_OC_CANON_SetModeDialDisable,1, onoff) /** * ptp_canon_eos_requestdevicepropvalue: *