9#define PTP_CHDK_VERSION_MAJOR 2   
   10#define PTP_CHDK_VERSION_MINOR 6   
   27#define PTP_OC_CHDK 0x9999 
   31enum PTP_CHDK_Command {
 
   40  PTP_CHDK_CallFunction,    
 
   45  PTP_CHDK_DownloadFile,    
 
   47  PTP_CHDK_ExecuteScript,   
 
   52  PTP_CHDK_ScriptStatus,    
 
   57  PTP_CHDK_ScriptSupport,   
 
   60  PTP_CHDK_ReadScriptMsg,   
 
   69  PTP_CHDK_WriteScriptMsg,  
 
   74  PTP_CHDK_GetDisplayData,  
 
   84  PTP_CHDK_RemoteCaptureIsReady, 
 
   90  PTP_CHDK_RemoteCaptureGetData  
 
   99enum ptp_chdk_script_data_type {
 
  100  PTP_CHDK_TYPE_UNSUPPORTED = 0, 
 
  102  PTP_CHDK_TYPE_BOOLEAN,
 
  103  PTP_CHDK_TYPE_INTEGER,
 
  104  PTP_CHDK_TYPE_STRING, 
 
  111#define PTP_CHDK_TD_DOWNLOAD  0x1   
  112#define PTP_CHDK_TD_CLEAR     0x2   
  118#define PTP_CHDK_SL_LUA    0 
  119#define PTP_CHDK_SL_UBASIC 1 
  120#define PTP_CHDK_SL_MASK 0xFF 
  123#define PTP_CHDK_LUA_SERIALIZE "\n\ 
  124serialize_r = function(v,opts,r,seen,depth)\n\ 
  125        local vt = type(v)\n\ 
  126        if vt == 'nil' or  vt == 'boolean' or vt == 'number' then\n\ 
  127                table.insert(r,tostring(v))\n\ 
  130        if vt == 'string' then\n\ 
  131                table.insert(r,string.format('%%q',v))\n\ 
  134        if vt == 'table' then\n\ 
  138                if depth >= opts.maxdepth then\n\ 
  139                        error('serialize: max depth')\n\ 
  143                elseif seen[v] then\n\ 
  144                        if opts.err_cycle then\n\ 
  145                                error('serialize: cycle')\n\ 
  147                                table.insert(r,'\"cycle:'..tostring(v)..'\"')\n\ 
  152                table.insert(r,'{')\n\ 
  153                for k,v1 in pairs(v) do\n\ 
  154                        if opts.pretty then\n\ 
  155                                table.insert(r,'\\n'..string.rep(' ',depth))\n\ 
  157                        if type(k) == 'string' and string.match(k,'^[_%%a][%%a%%d_]*$') then\n\ 
  160                                table.insert(r,'[')\n\ 
  161                                serialize_r(k,opts,r,seen,depth+1)\n\ 
  162                                table.insert(r,']')\n\ 
  164                        table.insert(r,'=')\n\ 
  165                        serialize_r(v1,opts,r,seen,depth+1)\n\ 
  166                        table.insert(r,',')\n\ 
  168                if opts.pretty then\n\ 
  169                        table.insert(r,'\\n'..string.rep(' ',depth-1))\n\ 
  171                table.insert(r,'}')\n\ 
  174        if opts.err_type then\n\ 
  175                error('serialize: unsupported type ' .. vt, 2)\n\ 
  177                table.insert(r,'\"'..tostring(v)..'\"')\n\ 
  180serialize_defaults = {\n\ 
  186function serialize(v,opts)\n\ 
  188                for k,v in pairs(serialize_defaults) do\n\ 
  189                        if not opts[k] then\n\ 
  194                opts=serialize_defaults\n\ 
  197        serialize_r(v,opts,r)\n\ 
  198        return table.concat(r)\n\ 
  201#define PTP_CHDK_LUA_SERIALIZE_SIMPLEQUOTE "\n\ 
  202serialize_r = function(v,opts,r,seen,depth)\n\ 
  203        local vt = type(v)\n\ 
  204        if vt == 'nil' or  vt == 'boolean' or vt == 'number' then\n\ 
  205                table.insert(r,tostring(v))\n\ 
  208        if vt == 'string' then\n\ 
  209                table.insert(r,string.format('%q',v))\n\ 
  212        if vt == 'table' then\n\ 
  216                if depth >= opts.maxdepth then\n\ 
  217                        error('serialize: max depth')\n\ 
  221                elseif seen[v] then\n\ 
  222                        if opts.err_cycle then\n\ 
  223                                error('serialize: cycle')\n\ 
  225                                table.insert(r,'\"cycle:'..tostring(v)..'\"')\n\ 
  230                table.insert(r,'{')\n\ 
  231                for k,v1 in pairs(v) do\n\ 
  232                        if opts.pretty then\n\ 
  233                                table.insert(r,'\\n'..string.rep(' ',depth))\n\ 
  235                        if type(k) == 'string' and string.match(k,'^[_%a][%a%d_]*$') then\n\ 
  238                                table.insert(r,'[')\n\ 
  239                                serialize_r(k,opts,r,seen,depth+1)\n\ 
  240                                table.insert(r,']')\n\ 
  242                        table.insert(r,'=')\n\ 
  243                        serialize_r(v1,opts,r,seen,depth+1)\n\ 
  244                        table.insert(r,',')\n\ 
  246                if opts.pretty then\n\ 
  247                        table.insert(r,'\\n'..string.rep(' ',depth-1))\n\ 
  249                table.insert(r,'}')\n\ 
  252        if opts.err_type then\n\ 
  253                error('serialize: unsupported type ' .. vt, 2)\n\ 
  255                table.insert(r,'\"'..tostring(v)..'\"')\n\ 
  258serialize_defaults = {\n\ 
  264function serialize(v,opts)\n\ 
  266                for k,v in pairs(serialize_defaults) do\n\ 
  267                        if not opts[k] then\n\ 
  272                opts=serialize_defaults\n\ 
  275        serialize_r(v,opts,r)\n\ 
  276        return table.concat(r)\n\ 
  279#define PTP_CHDK_LUA_SERIALIZE_MSGS \ 
  280PTP_CHDK_LUA_SERIALIZE\ 
  281"usb_msg_table_to_string=serialize\n" 
  283#define PTP_CHDK_LUA_SERIALIZE_MSGS_SIMPLEQUOTE \ 
  284PTP_CHDK_LUA_SERIALIZE_SIMPLEQUOTE\ 
  285"usb_msg_table_to_string=serialize\n" 
  287#define PTP_CHDK_LUA_EXTEND_TABLE \ 
  288"function extend_table(target,source,deep)\n\ 
  289        if type(target) ~= 'table' then\n\ 
  290                error('extend_table: target not table')\n\ 
  292        if source == nil then\n\ 
  295        if type(source) ~= 'table' then \n\ 
  296                error('extend_table: source not table')\n\ 
  298        if source == target then\n\ 
  299                error('extend_table: source == target')\n\ 
  302                return extend_table_r(target, source)\n\ 
  304                for k,v in pairs(source) do\n\ 
  311#define PTP_CHDK_LUA_MSG_BATCHER        \ 
  312PTP_CHDK_LUA_SERIALIZE_MSGS \ 
  313PTP_CHDK_LUA_EXTEND_TABLE \ 
  314"function msg_batcher(opts)\n\ 
  315        local t = extend_table({\n\ 
  323                t.init_free = get_meminfo().free_block_max_size\n\ 
  324                t.init_count = collectgarbage('count')\n\ 
  326        t.write=function(self,val)\n\ 
  328                self.data[self.n]=val\n\ 
  329                if self.n >= self.batchsize then\n\ 
  330                        return self:flush()\n\ 
  334        t.flush = function(self)\n\ 
  335                if self.n > 0 then\n\ 
  336                        if self.dbgmem then\n\ 
  337                                local count=collectgarbage('count')\n\ 
  338                                local free=get_meminfo().free_block_max_size\n\ 
  339                                self.data._dbg=string.format(\"count %%d (%%d) free %%d (%%d)\",\n\ 
  340                                        count, count - self.init_count, free, self.init_free-free)\n\ 
  342                        if not write_usb_msg(self.data,self.timeout) then\n\ 
  347                        if self.batchgc then\n\ 
  348                                collectgarbage(self.batchgc)\n\ 
  350                        if self.batchpause then\n\ 
  351                                sleep(self.batchpause)\n\ 
  359#define PTP_CHDK_LUA_LS_SIMPLE \ 
  360PTP_CHDK_LUA_MSG_BATCHER  \ 
  361"function ls_simple(path)\n\ 
  362        local b=msg_batcher()\n\ 
  363        local t,err=os.listdir(path)\n\ 
  367        for i,v in ipairs(t) do\n\ 
  368                if not b:write(v) then\n\ 
  375#define PTP_CHDK_LUA_JOINPATH \ 
  376"function joinpath(...)\n\ 
  378        if #parts < 2 then\n\ 
  379                error('joinpath requires at least 2 parts',2)\n\ 
  382        for i = 2, #parts do\n\ 
  383                local v = string.gsub(parts[i],'^/','')\n\ 
  384                if not string.match(r,'/$') then\n\ 
  392#define PTP_CHDK_LUA_LS \ 
  393PTP_CHDK_LUA_MSG_BATCHER \ 
  394PTP_CHDK_LUA_JOINPATH \ 
  395"function ls_single(opts,b,path,v)\n\ 
  396        if not opts.match or string.match(v,opts.match) then\n\ 
  398                        local st,msg=os.stat(joinpath(path,v))\n\ 
  402                        if opts.stat == '/' then\n\ 
  408                        elseif opts.stat == '*' then\n\ 
  419function ls(path,opts_in)\n\ 
  422                msgtimeout=100000,\n\ 
  426                for k,v in pairs(opts_in) do\n\ 
  430        local st, err = os.stat(path)\n\ 
  435        local b=msg_batcher{\n\ 
  436                batchsize=opts.msglimit,\n\ 
  437                timeout=opts.msgtimeout\n\ 
  440        if not st.is_dir then\n\ 
  441                if opts.dirsonly then\n\ 
  442                        return false, 'not a directory'\n\ 
  444                if opts.stat == '*' then\n\ 
  455                for v in os.idir(path,opts.listall) do\n\ 
  456                        local status,err=ls_single(opts,b,path,v)\n\ 
  457                        if not status then\n\ 
  462                local t,msg=os.listdir(path,opts.listall)\n\ 
  466                for i,v in ipairs(t) do\n\ 
  467                        local status,err=ls_single(opts,b,path,v)\n\ 
  468                        if not status then\n\ 
  477#define PTP_CHDK_LUA_RLIB_SHOOT_COMMON \ 
  478"function rlib_shoot_init_exp(opts)     \n\ 
  480                set_tv96_direct(opts.tv)\n\ 
  486                if type(sv96_market_to_real) ~= 'function' then\n\ 
  487                        error('svm not supported')\n\ 
  489                set_sv96(sv96_market_to_real(opts.svm))\n\ 
  491        if opts.isomode then\n\ 
  492                set_iso_mode(opts.isomode)\n\ 
  495                set_av96_direct(opts.av)\n\ 
  498                set_nd_filter(opts.nd)\n\ 
  501                set_focus(opts.sd)\n\ 
  505#define PTP_CHDK_LUA_RLIB_SHOOT \ 
  506PTP_CHDK_LUA_RLIB_SHOOT_COMMON \ 
  507"function rlib_shoot(opts)\n\ 
  508        local rec,vid = get_mode()\n\ 
  510                return false,'not in rec mode'\n\ 
  513        rlib_shoot_init_exp(opts)\n\ 
  517                save_raw=get_raw()\n\ 
  522                save_dng=get_config_value(226)\n\ 
  523                set_config_value(226,opts.dng)\n\ 
  529                        dir=get_image_dir(),\n\ 
  530                        exp=get_exp_count(),\n\ 
  531                        raw=(get_raw() == 1),\n\ 
  534                        r.raw_in_dir = (get_config_value(35) == 1)\n\ 
  535                        r.raw_pfx = get_config_value(36)\n\ 
  536                        r.raw_ext = get_config_value(37)\n\ 
  537                        r.dng = (get_config_value(226) == 1)\n\ 
  539                                r.use_dng_ext = (get_config_value(234) == 1)\n\ 
  549                set_config_value(226,save_dng)\n\ 
  557#define PTP_CHDK_SCRIPT_FL_NOKILL           0x100  
  558#define PTP_CHDK_SCRIPT_FL_FLUSH_CAM_MSGS   0x200  
  559#define PTP_CHDK_SCRIPT_FL_FLUSH_HOST_MSGS  0x400  
  562#define PTP_CHDK_SCRIPT_STATUS_RUN   0x1  
  563#define PTP_CHDK_SCRIPT_STATUS_MSG   0x2  
  565#define PTP_CHDK_SCRIPT_SUPPORT_LUA  0x1 
  573#define PTP_CHDK_CAPTURE_JPG    0x1  
  579#define PTP_CHDK_CAPTURE_RAW    0x2 
  599#define PTP_CHDK_CAPTURE_DNGHDR 0x4   
  602#define PTP_CHDK_CAPTURE_NOTSET 0x10000000 
  605enum ptp_chdk_script_msg_type {
 
  606    PTP_CHDK_S_MSGTYPE_NONE = 0, 
 
  607    PTP_CHDK_S_MSGTYPE_ERR,      
 
  608    PTP_CHDK_S_MSGTYPE_RET,      
 
  609    PTP_CHDK_S_MSGTYPE_USER,     
 
  614enum ptp_chdk_script_error_type {
 
  615    PTP_CHDK_S_ERRTYPE_NONE = 0,
 
  616    PTP_CHDK_S_ERRTYPE_COMPILE,
 
  617    PTP_CHDK_S_ERRTYPE_RUN,
 
  619    PTP_CHDK_S_ERR_SCRIPTRUNNING = 0x1000, 
 
  623enum ptp_chdk_script_msg_status {
 
  624    PTP_CHDK_S_MSGSTATUS_OK = 0, 
 
  625    PTP_CHDK_S_MSGSTATUS_NOTRUN, 
 
  626    PTP_CHDK_S_MSGSTATUS_QFULL,  
 
  627    PTP_CHDK_S_MSGSTATUS_BADID,